Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                    ;;
  3. ;;  PCNET32.INC                                                       ;;
  4. ;;                                                                    ;;
  5. ;;  Ethernet driver for Menuet OS                                     ;;
  6. ;;                                                                    ;;
  7. ;;  Version 1.0  31 July 2004                                         ;;
  8. ;;                                                                    ;;
  9. ;;  This driver is based on the PCNet32 driver from                   ;;
  10. ;;  the etherboot 5.0.6 project. The copyright statement is           ;;
  11. ;;                                                                    ;;
  12. ;;          GNU GENERAL PUBLIC LICENSE                                ;;
  13. ;;             Version 2, June 1991                                   ;;
  14. ;;                                                                    ;;
  15. ;;  remaining parts Copyright 2004 Jarek Pelczar,                     ;;
  16. ;;   jpelczar@interia.pl                                              ;;
  17. ;;                                                                    ;;
  18. ;;  See file COPYING for details                                      ;;
  19. ;;                                                                    ;;
  20. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  21. ;macro PutStr X
  22. ;{
  23. ; local .__xyz1
  24. ; local .__xyz2
  25. ; push esi
  26. ; mov esi,.__xyz1
  27. ; call sys_msg_board_str
  28. ; push eax
  29. ; mov eax,1
  30. ; call delay_hs
  31. ; pop eax
  32. ; jmp .__xyz2
  33. ;.__xyz1:
  34. ; db X
  35. ; db 13,10,0
  36. ;.__xyz2:
  37. ; pop esi
  38. ;}
  39. PCNET32_PORT_AUI      equ 0x00
  40. PCNET32_PORT_10BT     equ 0x01
  41. PCNET32_PORT_GPSI     equ 0x02
  42. PCNET32_PORT_MII      equ 0x03
  43. PCNET32_PORT_PORTSEL  equ 0x03
  44. PCNET32_PORT_ASEL     equ 0x04
  45. PCNET32_PORT_100      equ 0x40
  46. PCNET32_PORT_FD       equ 0x80
  47. PCNET32_DMA_MASK      equ 0xffffffff
  48. PCNET32_LOG_TX_BUFFERS  equ 1
  49. PCNET32_LOG_RX_BUFFERS  equ 2
  50. PCNET32_TX_RING_SIZE            equ (1 shl PCNET32_LOG_TX_BUFFERS)
  51. PCNET32_TX_RING_MOD_MASK        equ (PCNET32_TX_RING_SIZE-1)
  52. PCNET32_TX_RING_LEN_BITS        equ 0
  53. PCNET32_RX_RING_SIZE            equ (1 shl PCNET32_LOG_RX_BUFFERS)
  54. PCNET32_RX_RING_MOD_MASK        equ (PCNET32_RX_RING_SIZE-1)
  55. PCNET32_RX_RING_LEN_BITS        equ (PCNET32_LOG_RX_BUFFERS shl 4)
  56. PCNET32_PKT_BUF_SZ              equ 1544
  57. PCNET32_PKT_BUF_SZ_NEG          equ 0xf9f8
  58. pcnet32_txb equ (eth_data_start)
  59. pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
  60. pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
  61. pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
  62. virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
  63. pcnet32_private:
  64. .mode                   dw ?
  65. .tlen_rlen              dw ?
  66. .phys_addr              db ?,?,?,?,?,?
  67. .reserved               dw ?
  68. .filter                 dd ?,?
  69. .rx_ring                dd ?
  70. .tx_ring                dd ?
  71. .cur_rx                 dd ?
  72. .cur_tx                 dd ?
  73. .dirty_rx               dd ?
  74. .dirty_tx               dd ?
  75. .tx_full                db ?
  76. .options                dd ?
  77. .full_duplex            db ?
  78. .chip_version           dd ?
  79. .mii                    db ?
  80. .ltint                  db ?
  81. .dxsuflo                db ?
  82. .fset                   db ?
  83. .fdx                    db ?
  84. end virtual
  85. virtual at 0
  86. pcnet32_rx_head:
  87. .base           dd ?
  88. .buf_length     dw ?
  89. .status         dw ?
  90. .msg_length     dd ?
  91. .reserved       dd ?
  92. end virtual
  93. virtual at 0
  94. pcnet32_tx_head:
  95. .base           dd ?
  96. .length         dw ?
  97. .status         dw ?
  98. .misc           dd ?
  99. .reserved       dd ?
  100. end virtual
  101.  
  102. uglobal
  103. pcnet32_access:
  104. .read_csr               dd ?
  105. .write_csr              dd ?
  106. .read_bcr               dd ?
  107. .write_bcr              dd ?
  108. .read_rap               dd ?
  109. .write_rap              dd ?
  110. .reset                  dd ?
  111. endg
  112.  
  113. iglobal
  114. pcnet32_options_mapping:
  115. dd PCNET32_PORT_ASEL    ;  0 Auto-select
  116. dd PCNET32_PORT_AUI     ;  1 BNC/AUI
  117. dd PCNET32_PORT_AUI     ;  2 AUI/BNC
  118. dd PCNET32_PORT_ASEL    ;  3 not supported
  119. dd PCNET32_PORT_10BT or PCNET32_PORT_FD ;  4 10baseT-FD
  120. dd PCNET32_PORT_ASEL    ;  5 not supported
  121. dd PCNET32_PORT_ASEL    ;  6 not supported
  122. dd PCNET32_PORT_ASEL    ;  7 not supported
  123. dd PCNET32_PORT_ASEL    ;  8 not supported
  124. dd PCNET32_PORT_MII     ;  9 MII 10baseT
  125. dd PCNET32_PORT_MII or PCNET32_PORT_FD  ; 10 MII 10baseT-FD
  126. dd PCNET32_PORT_MII     ; 11 MII (autosel)
  127. dd PCNET32_PORT_10BT    ; 12 10BaseT
  128. dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx
  129. dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD      ; 14 MII 100BaseTx-FD
  130. dd PCNET32_PORT_ASEL    ; 15 not supported
  131. endg
  132.  
  133. PCNET32_WIO_RDP         equ 0x10
  134. PCNET32_WIO_RAP         equ 0x12
  135. PCNET32_WIO_RESET       equ 0x14
  136. PCNET32_WIO_BDP         equ 0x16
  137. PCNET32_DWIO_RDP        equ 0x10
  138. PCNET32_DWIO_RAP        equ 0x14
  139. PCNET32_DWIO_RESET      equ 0x18
  140. PCNET32_DWIO_BDP        equ 0x1C
  141. PCNET32_TOTAL_SIZE      equ 0x20
  142. ; ebx - index
  143. ; return:
  144. ; eax - data
  145. pcnet32_wio_read_csr:
  146.     push edx
  147.     lea edx,[ebp+PCNET32_WIO_RAP]
  148.     mov ax,bx
  149.     out dx,ax
  150.     lea edx,[ebp+PCNET32_WIO_RDP]
  151.     in ax,dx
  152.     and eax,0xffff
  153.     pop edx
  154.     ret
  155. ; eax - data
  156. ; ebx - index
  157. pcnet32_wio_write_csr:
  158.     push edx
  159.     lea edx,[ebp+PCNET32_WIO_RAP]
  160.     xchg eax,ebx
  161.     out dx,ax
  162.     xchg eax,ebx
  163.     lea edx,[ebp+PCNET32_WIO_RDP]
  164.     out dx,ax
  165.     pop edx
  166.     ret
  167. ; ebx - index
  168. ; return:
  169. ; eax - data
  170. pcnet32_wio_read_bcr:
  171.     push edx
  172.     lea edx,[ebp+PCNET32_WIO_RAP]
  173.     mov ax,bx
  174.     out dx,ax
  175.     lea edx,[ebp+PCNET32_WIO_BDP]
  176.     in ax,dx
  177.     and eax,0xffff
  178.     pop edx
  179.     ret
  180. ; eax - data
  181. ; ebx - index
  182. pcnet32_wio_write_bcr:
  183.     push edx
  184.     lea edx,[ebp+PCNET32_WIO_RAP]
  185.     xchg eax,ebx
  186.     out dx,ax
  187.     xchg eax,ebx
  188.     lea edx,[ebp+PCNET32_WIO_BDP]
  189.     out dx,ax
  190.     pop edx
  191.     ret
  192. pcnet32_wio_read_rap:
  193.     push edx
  194.     lea edx,[ebp+PCNET32_WIO_RAP]
  195.     in ax,dx
  196.     and eax,0xffff
  197.     pop edx
  198.     ret
  199. ; eax - val
  200. pcnet32_wio_write_rap:
  201.     push edx
  202.     lea edx,[ebp+PCNET32_WIO_RAP]
  203.     out dx,ax
  204.     pop edx
  205.     ret
  206. pcnet32_wio_reset:
  207.     push edx
  208.     push eax
  209.     lea edx,[ebp+PCNET32_WIO_RESET]
  210.     in ax,dx
  211.     pop eax
  212.     pop edx
  213.     ret
  214. pcnet32_wio_check:
  215.     push edx
  216.     mov ax,88
  217.     lea edx,[ebp+PCNET32_WIO_RAP]
  218.     out dx,ax
  219.     nop
  220.     nop
  221.     in ax,dx
  222.     cmp ax,88
  223.     sete al
  224.     pop edx
  225.     ret
  226.  
  227. iglobal
  228. pcnet32_wio:
  229.     dd pcnet32_wio_read_csr
  230.     dd pcnet32_wio_write_csr
  231.     dd pcnet32_wio_read_bcr
  232.     dd pcnet32_wio_write_bcr
  233.     dd pcnet32_wio_read_rap
  234.     dd pcnet32_wio_write_rap
  235.     dd pcnet32_wio_reset
  236. endg
  237.  
  238. ; ebx - index
  239. ; return:
  240. ; eax - data
  241. pcnet32_dwio_read_csr:
  242.     push edx
  243.     lea edx,[ebp+PCNET32_DWIO_RAP]
  244.     mov ebx,eax
  245.     out dx,eax
  246.     lea edx,[ebp+PCNET32_DWIO_RDP]
  247.     in eax,dx
  248.     and eax,0xffff
  249.     pop edx
  250.     ret
  251. ; ebx - index
  252. ; eax - data
  253. pcnet32_dwio_write_csr:
  254.     push edx
  255.     lea edx,[ebp+PCNET32_DWIO_RAP]
  256.     xchg eax,ebx
  257.     out dx,eax
  258.     lea edx,[ebp+PCNET32_DWIO_RDP]
  259.     xchg eax,ebx
  260.     out dx,eax
  261.     pop edx
  262.     ret
  263. ; ebx - index
  264. ; return:
  265. ; eax - data
  266. pcnet32_dwio_read_bcr:
  267.     push edx
  268.     lea edx,[ebp+PCNET32_DWIO_RAP]
  269.     mov ebx,eax
  270.     out dx,eax
  271.     lea edx,[ebp+PCNET32_DWIO_BDP]
  272.     in eax,dx
  273.     and eax,0xffff
  274.     pop edx
  275.     ret
  276. ; ebx - index
  277. ; eax - data
  278. pcnet32_dwio_write_bcr:
  279.     push edx
  280.     lea edx,[ebp+PCNET32_DWIO_RAP]
  281.     xchg eax,ebx
  282.     out dx,eax
  283.     lea edx,[ebp+PCNET32_DWIO_BDP]
  284.     xchg eax,ebx
  285.     out dx,eax
  286.     pop edx
  287.     ret
  288. pcnet32_dwio_read_rap:
  289.     push edx
  290.     lea edx,[ebp+PCNET32_DWIO_RAP]
  291.     in eax,dx
  292.     and eax,0xffff
  293.     pop edx
  294.     ret
  295. ; eax - val
  296. pcnet32_dwio_write_rap:
  297.     push edx
  298.     lea edx,[ebp+PCNET32_DWIO_RAP]
  299.     out dx,eax
  300.     pop edx
  301.     ret
  302. pcnet32_dwio_reset:
  303.     push edx
  304.     push eax
  305.     lea edx,[ebp+PCNET32_DWIO_RESET]
  306.     in eax,dx
  307.     pop eax
  308.     pop edx
  309.     ret
  310. pcnet32_dwio_check:
  311.     push edx
  312.     lea edx,[PCNET32_DWIO_RAP]
  313.     mov eax,88
  314.     out dx,eax
  315.     nop
  316.     nop
  317.     in eax,dx
  318.     and eax,0xffff
  319.     cmp eax,88
  320.     sete al
  321.     pop edx
  322.     ret
  323.  
  324. iglobal
  325. pcnet32_dwio:
  326.     dd pcnet32_dwio_read_csr
  327.     dd pcnet32_dwio_write_csr
  328.     dd pcnet32_dwio_read_bcr
  329.     dd pcnet32_dwio_write_bcr
  330.     dd pcnet32_dwio_read_rap
  331.     dd pcnet32_dwio_write_rap
  332.     dd pcnet32_dwio_reset
  333. endg
  334.  
  335. pcnet32_init_ring:
  336.     mov [pcnet32_private.tx_full],0
  337.     mov [pcnet32_private.cur_rx],0
  338.     mov [pcnet32_private.cur_tx],0
  339.     mov [pcnet32_private.dirty_rx],0
  340.     mov [pcnet32_private.dirty_tx],0
  341.     mov edi,pcnet32_rx_ring
  342.     mov ecx,PCNET32_RX_RING_SIZE
  343.     mov ebx,pcnet32_rxb
  344. .rx_init:
  345.     mov [edi+pcnet32_rx_head.base],ebx
  346.     mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
  347.     mov [edi+pcnet32_rx_head.status],word 0x8000
  348.     add ebx,PCNET32_PKT_BUF_SZ
  349. ;    inc ebx
  350.     add edi,16
  351.     loop .rx_init
  352.     mov edi,pcnet32_tx_ring
  353.     mov ecx,PCNET32_TX_RING_SIZE
  354. .tx_init:
  355.     mov [edi+pcnet32_tx_head.base],dword 0
  356.     mov [edi+pcnet32_tx_head.status],word 0
  357.     add edi,16
  358.     loop .tx_init
  359.     mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
  360.     mov esi,node_addr
  361.     mov edi,pcnet32_private.phys_addr
  362.     cld
  363.     movsd
  364.     movsw
  365.     mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
  366.     mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
  367.     ret
  368. pcnet32_reset:
  369.     ; Reset PCNET32
  370.     mov ebp,[io_addr]
  371.     call dword [pcnet32_access.reset]
  372.     ; set 32bit mode
  373.     mov ebx,20
  374.     mov eax,2
  375.     call dword [pcnet32_access.write_bcr]
  376.     ; set/reset autoselect bit
  377.     mov ebx,2
  378.     call dword [pcnet32_access.read_bcr]
  379.     and eax,not 2
  380.     test [pcnet32_private.options],PCNET32_PORT_ASEL
  381.     jz .L1
  382.     or eax,2
  383. .L1:
  384.     call dword [pcnet32_access.write_bcr]
  385.     ; Handle full duplex setting
  386.     cmp byte [pcnet32_private.full_duplex],0
  387.     je .L2
  388.     mov ebx,9
  389.     call dword [pcnet32_access.read_bcr]
  390.     and eax,not 3
  391.     test [pcnet32_private.options],PCNET32_PORT_FD
  392.     jz .L3
  393.     or eax,1
  394.     cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI
  395.     jne .L4
  396.     or eax,2
  397.     jmp .L4
  398. .L3:
  399.     test [pcnet32_private.options],PCNET32_PORT_ASEL
  400.     jz .L4
  401.     cmp [pcnet32_private.chip_version],0x2627
  402.     jne .L4
  403.     or eax,3
  404. .L4:
  405.     mov ebx,9
  406.     call dword [pcnet32_access.write_bcr]
  407. .L2:
  408.     ; set/reset GPSI bit
  409.     mov ebx,124
  410.     call dword [pcnet32_access.read_csr]
  411.     mov ecx,[pcnet32_private.options]
  412.     and ecx,PCNET32_PORT_PORTSEL
  413.     cmp ecx,PCNET32_PORT_GPSI
  414.     jne .L5
  415.     or eax,0x10
  416. .L5:
  417.     call dword [pcnet32_access.write_csr]
  418.     cmp [pcnet32_private.mii],0
  419.     je .L6
  420.     test [pcnet32_private.options],PCNET32_PORT_ASEL
  421.     jnz .L6
  422.     mov ebx,32
  423.     call dword [pcnet32_access.read_bcr]
  424.     and eax,not 0x38
  425.     test [pcnet32_private.options],PCNET32_PORT_FD
  426.     jz .L7
  427.     or eax,0x10
  428. .L7:
  429.     test [pcnet32_private.options],PCNET32_PORT_100
  430.     jz .L8
  431.     or eax,0x08
  432. .L8:
  433.     call dword [pcnet32_access.write_bcr]
  434.     jmp .L9
  435. .L6:
  436.     test [pcnet32_private.options],PCNET32_PORT_ASEL
  437.     jz .L9
  438.     mov ebx,32
  439. ;    PutStr "ASEL, enable auto-negotiation"
  440.     call dword [pcnet32_access.read_bcr]
  441.     and eax,not 0x98
  442.     or eax,0x20
  443.     call dword [pcnet32_access.write_bcr]
  444. .L9:
  445.     cmp [pcnet32_private.ltint],0
  446.     je .L10
  447.     mov ebx,5
  448.     call dword [pcnet32_access.read_csr]
  449.     or eax,(1 shl 14)
  450.     call dword [pcnet32_access.write_csr]
  451. .L10:
  452.     mov eax,[pcnet32_private.options]
  453.     and eax,PCNET32_PORT_PORTSEL
  454.     shl eax,7
  455.     mov [pcnet32_private.mode],ax
  456.     mov [pcnet32_private.filter],dword 0xffffffff
  457.     mov [pcnet32_private.filter+4],dword 0xffffffff
  458.     call pcnet32_init_ring
  459.     mov ebx,1
  460.     mov eax,pcnet32_private
  461.     and eax,0xffff
  462.     call dword [pcnet32_access.write_csr]
  463.     mov eax,pcnet32_private
  464.     mov ebx,2
  465.     shr eax,16
  466.     call dword [pcnet32_access.write_csr]
  467.     mov ebx,4
  468.     mov eax,0x0915
  469.     call dword [pcnet32_access.write_csr]
  470.     mov ebx,0
  471.     mov eax,1
  472.     call dword [pcnet32_access.write_csr]
  473.     mov ecx,100
  474. .L11:
  475.     xor ebx,ebx
  476.     call dword [pcnet32_access.read_csr]
  477.     test ax,0x100
  478.     jnz .L12
  479.     loop .L11
  480. .L12:
  481. ;    PutStr "hardware reset"
  482.     xor ebx,ebx
  483.     mov eax,0x0002
  484.     call dword [pcnet32_access.write_csr]
  485.     xor ebx,ebx
  486.     call dword [pcnet32_access.read_csr]
  487. ;    PutStr "PCNET reset complete"
  488.     ret
  489. pcnet32_adjust_pci_device:
  490.    ;*******Get current setting************************
  491.    mov     al, 2                                        ;read a word
  492.    mov     bh, [pci_dev]
  493.    mov     ah, [pci_bus]
  494.    mov     bl, 0x04                                 ;from command Register
  495.    call    pci_read_reg
  496.    ;******see if its already set as bus master********
  497.    mov      bx, ax
  498.    and      bx,5
  499.    cmp      bx,5
  500.    je       pcnet32_adjust_pci_device_Latency
  501.    ;******Make card a bus master*******
  502.    mov      cx, ax                              ;value to write
  503.    mov     bh, [pci_dev]
  504.    mov     al, 2                                ;write a word
  505.    or       cx,5
  506.    mov     ah, [pci_bus]
  507.    mov     bl, 0x04                             ;to command register
  508.    call    pci_write_reg
  509.    ;******Check latency setting***********
  510. pcnet32_adjust_pci_device_Latency:
  511.    ;*******Get current latency setting************************
  512. ;   mov     al, 1                                       ;read a byte
  513. ;   mov     bh, [pci_dev]
  514. ;   mov     ah, [pci_bus]
  515. ;   mov     bl, 0x0D                                ;from Lantency Timer Register
  516. ;   call    pci_read_reg
  517.    ;******see if its aat least 64 clocks********
  518. ;   cmp      ax,64
  519. ;   jge      pcnet32_adjust_pci_device_Done
  520.    ;******Set latency to 32 clocks*******
  521. ;   mov     cx, 64                              ;value to write
  522. ;   mov     bh, [pci_dev]
  523. ;   mov     al, 1                               ;write a byte
  524. ;   mov     ah, [pci_bus]
  525. ;   mov     bl, 0x0D                            ;to Lantency Timer Register
  526. ;   call    pci_write_reg
  527.    ;******Check latency setting***********
  528. pcnet32_adjust_pci_device_Done:
  529.    ret
  530. pcnet32_probe:
  531.     mov ebp,[io_addr]
  532.     call pcnet32_wio_reset
  533.     xor ebx,ebx
  534.     call pcnet32_wio_read_csr
  535.     cmp eax,4
  536.     jne .try_dwio
  537.     call pcnet32_wio_check
  538.     and al,al
  539.     jz .try_dwio
  540. ;    PutStr "Using WIO"
  541.     mov esi,pcnet32_wio
  542.     jmp .L1
  543. .try_dwio:
  544.     call pcnet32_dwio_reset
  545.     xor ebx,ebx
  546.     call pcnet32_dwio_read_csr
  547.     cmp eax,4
  548.     jne .no_dev
  549.     call pcnet32_dwio_check
  550.     and al,al
  551.     jz .no_dev
  552. ;    PutStr "Using DWIO"
  553.     mov esi,pcnet32_dwio
  554.     jmp .L1
  555. .no_dev:
  556. ;    PutStr "PCNET32 not found"
  557.     ret
  558. .L1:
  559.     mov edi,pcnet32_access
  560.     mov ecx,7
  561.     cld
  562.     rep movsd
  563.     mov ebx,88
  564.     call dword [pcnet32_access.read_csr]
  565.     mov ecx,eax
  566.     mov ebx,89
  567.     call dword [pcnet32_access.read_csr]
  568.     shl eax,16
  569.     or eax,ecx
  570.     mov ecx,eax
  571.     and ecx,0xfff
  572.     cmp ecx,3
  573.     jne .no_dev
  574.     shr eax,12
  575.     and eax,0xffff
  576.     mov [pcnet32_private.chip_version],eax
  577. ;    PutStr "PCNET32 chip version OK"
  578.     mov [pcnet32_private.fdx],0
  579.     mov [pcnet32_private.mii],0
  580.     mov [pcnet32_private.fset],0
  581.     mov [pcnet32_private.dxsuflo],0
  582.     mov [pcnet32_private.ltint],0
  583.     mov eax,[pcnet32_private.chip_version]
  584.     cmp eax,0x2420
  585.     je .L2
  586.     cmp eax,0x2430
  587.     je .L3
  588.     cmp eax,0x2621
  589.     je .L4
  590.     cmp eax,0x2623
  591.     je .L5
  592.     cmp eax,0x2624
  593.     je .L6
  594.     cmp eax,0x2625
  595.     je .L7
  596.     cmp eax,0x2626
  597.     je .L8
  598.     cmp eax,0x2627
  599.     je .L9
  600. ;    PutStr "Invalid chip rev"
  601.     jmp .no_dev
  602. .L2:
  603. ;    PutStr "PCnet/PCI 79C970"
  604.     jmp .L10
  605. .L3:
  606. ;    PutStr "PCnet/PCI 79C970"
  607.     jmp .L10
  608. .L4:
  609. ;    PutStr "PCnet/PCI II 79C970A"
  610.     mov [pcnet32_private.fdx],1
  611.     jmp .L10
  612. .L5:
  613. ;    PutStr "PCnet/FAST 79C971"
  614.     mov [pcnet32_private.fdx],1
  615.     mov [pcnet32_private.mii],1
  616.     mov [pcnet32_private.fset],1
  617.     mov [pcnet32_private.ltint],1
  618.     jmp .L10
  619. .L6:
  620. ;    PutStr "PCnet/FAST+ 79C972"
  621.     mov [pcnet32_private.fdx],1
  622.     mov [pcnet32_private.mii],1
  623.     mov [pcnet32_private.fset],1
  624.     jmp .L10
  625. .L7:
  626. ;    PutStr "PCnet/FAST III 79C973"
  627.     mov [pcnet32_private.fdx],1
  628.     mov [pcnet32_private.mii],1
  629.     jmp .L10
  630. .L8:
  631. ;    PutStr "PCnet/Home 79C978"
  632.     mov [pcnet32_private.fdx],1
  633.     mov ebx,49
  634.     call dword [pcnet32_access.read_bcr]
  635.     call dword [pcnet32_access.write_bcr]
  636.     jmp .L10
  637. .L9:
  638. ;    PutStr "PCnet/FAST III 79C975"
  639.     mov [pcnet32_private.fdx],1
  640.     mov [pcnet32_private.mii],1
  641. .L10:
  642.     cmp [pcnet32_private.fset],1
  643.     jne .L11
  644.     mov ebx,18
  645.     call dword [pcnet32_access.read_bcr]
  646.     or eax,0x800
  647.     call dword [pcnet32_access.write_bcr]
  648.     mov ebx,80
  649.     call dword [pcnet32_access.read_csr]
  650.     and eax,0xc00
  651.     or eax,0xc00
  652.     call dword [pcnet32_access.write_csr]
  653.     mov [pcnet32_private.dxsuflo],1
  654.     mov [pcnet32_private.ltint],1
  655. .L11:
  656.     ; read MAC
  657.     mov edi,node_addr
  658.     mov edx,ebp
  659.     mov ecx,6
  660. .Lmac:
  661.     in al,dx
  662.     stosb
  663.     inc edx
  664.     loop .Lmac
  665. ;    PutStr "MAC read"
  666.     call pcnet32_adjust_pci_device
  667. ;    PutStr "PCI done"
  668.     mov eax,PCNET32_PORT_ASEL
  669.     mov [pcnet32_private.options],eax
  670.     mov [pcnet32_private.mode],word 0x0003
  671.     mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
  672.     mov esi,node_addr
  673.     mov edi,pcnet32_private.phys_addr
  674.     cld
  675.     movsd
  676.     movsw
  677.     mov [pcnet32_private.filter],dword 0
  678.     mov [pcnet32_private.filter+4],dword 0
  679.     mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
  680.     mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
  681. ;    PutStr "Switching to 32"
  682.     mov ebx,20
  683.     mov eax,2
  684.     call dword [pcnet32_access.write_bcr]
  685.     mov ebx,1
  686.     mov eax,(pcnet32_private and 0xffff)
  687.     call dword [pcnet32_access.write_csr]
  688.     mov ebx,2
  689.     mov eax,(pcnet32_private shr 16) and 0xffff
  690.     call dword [pcnet32_access.write_csr]
  691.     mov ebx,0
  692.     mov eax,1
  693.     call dword [pcnet32_access.write_csr]
  694.     mov esi,1
  695.     call delay_ms
  696.     call pcnet32_reset
  697.     mov eax, [pci_data]
  698.     mov [eth_status], eax
  699.     ret
  700. pcnet32_poll:
  701.     xor eax,eax
  702.     mov [eth_rx_data_len],ax
  703.     mov eax,[pcnet32_private.cur_rx]
  704.     and eax,PCNET32_RX_RING_MOD_MASK
  705.     mov ebx,eax
  706.     imul esi,eax,PCNET32_PKT_BUF_SZ
  707.     add esi,pcnet32_rxb
  708.     shl ebx,4
  709.     add ebx,pcnet32_rx_ring
  710.     mov cx,[ebx+pcnet32_rx_head.status]
  711.     test cx,0x8000
  712.     jnz .L1
  713.     cmp ch,3
  714.     jne .L1
  715. ;    PutStr "PCNETRX"
  716.     mov ecx,[ebx+pcnet32_rx_head.msg_length]
  717.     and ecx,0xfff
  718.     sub ecx,4
  719.     mov [eth_rx_data_len],cx
  720.     push ecx
  721.     shr ecx,2
  722.     mov edi,Ether_buffer
  723.     cld
  724.     rep movsd
  725.     pop ecx
  726.     and ecx,3
  727.     rep movsb
  728.     mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
  729.     or [ebx+pcnet32_rx_head.status],word 0x8000
  730.     inc [pcnet32_private.cur_rx]
  731. .L1:
  732.     ret
  733. ;         Pointer to 48 bit destination address in edi
  734. ;         Type of packet in bx
  735. ;         size of packet in ecx
  736. ;         pointer to packet data in esi
  737. pcnet32_xmit:
  738.     push edi
  739.     push esi
  740.     push ebx
  741.     push ecx
  742. ;    PutStr "PCNETTX"
  743.     mov esi,edi
  744.     mov edi,[pcnet32_private.cur_tx]
  745.     imul edi,PCNET32_PKT_BUF_SZ
  746.     add edi,pcnet32_txb ; edi=ptxb
  747.     mov eax,edi
  748.     cld         ; copy MAC
  749.     movsd
  750.     movsw
  751.     mov esi,node_addr
  752.     cld
  753.     movsd
  754.     movsw
  755.     mov [edi],bx
  756.     add edi,2
  757.     mov esi,[esp+8]
  758.     mov ecx,[esp]
  759.     push ecx
  760.     shr ecx,2
  761.     cld
  762.     rep movsd
  763.     pop ecx
  764.     and ecx,3
  765.     rep movsb
  766. ;    mov ecx,[esp]
  767. ;    add ecx,14 ; ETH_HLEN
  768. ;    xor eax,eax
  769. ; pad to min length (60=ETH_ZLEN)
  770. ;    cmp ecx,60
  771. ;    jae .L1
  772. ;    sub ecx,60
  773. ;    cld
  774. ;    rep stosb
  775. ;.L1:
  776.     mov edi,pcnet32_tx_ring+0   ; entry=0
  777.     mov ecx,[esp]
  778.     add ecx,14
  779.     cmp cx,60
  780.     jae .L1
  781.     mov cx,60
  782. .L1:
  783.     neg cx
  784.     mov [edi+pcnet32_tx_head.length],cx
  785.     mov [edi+pcnet32_tx_head.misc],dword 0
  786.     mov [edi+pcnet32_tx_head.base],eax
  787.     mov [edi+pcnet32_tx_head.status],word 0x8300
  788.     ; trigger an immediate send poll
  789.     mov ebx,0
  790.     mov eax,0x0008      ; 0x0048
  791.     mov ebp,[io_addr]
  792.     call dword [pcnet32_access.write_csr]
  793.     mov dword [pcnet32_private.cur_tx],0
  794.     ; wait for TX to complete
  795.     mov ecx,[timer_ticks];[0xfdf0]
  796.     add ecx,100
  797. .L2:
  798.     mov ax,[edi+pcnet32_tx_head.status]
  799.     test ax,0x8000
  800.     jz .L3
  801.     cmp ecx,[timer_ticks];[0xfdf0]
  802.     jb .L4
  803.     mov esi,10
  804.     call delay_ms
  805.     jnz .L2
  806. .L4:
  807. ;    PutStr "PCNET: Send timeout"
  808. .L3:
  809.     mov dword [edi+pcnet32_tx_head.base],0
  810.     pop ecx
  811.     pop ebx
  812.     pop esi
  813.     pop edi
  814.     ret
  815.