Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                  ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. 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: 2465 $
  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.