Subversion Repositories Kolibri OS

Rev

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