Subversion Repositories Kolibri OS

Rev

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

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