Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 425 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                                    ;;
  4. ;;  PCNET32.INC                                                       ;;
  5. ;;                                                                    ;;
  6. ;;  Ethernet driver for Menuet OS                                     ;;
  7. ;;                                                                    ;;
  8. ;;  Version 1.0  31 July 2004                                         ;;
  9. ;;                                                                    ;;
  10. ;;  This driver is based on the PCNet32 driver from                   ;;
  11. ;;  the etherboot 5.0.6 project. The copyright statement is           ;;
  12. ;;                                                                    ;;
  13. ;;          GNU GENERAL PUBLIC LICENSE                                ;;
  14. ;;             Version 2, June 1991                                   ;;
  15. ;;                                                                    ;;
  16. ;;  remaining parts Copyright 2004 Jarek Pelczar,                     ;;
  17. ;;   jpelczar@interia.pl                                              ;;
  18. ;;                                                                    ;;
  19. ;;  See file COPYING for details                                      ;;
  20. ;;                                                                    ;;
  21. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22. ;macro PutStr X
  23. ;{
  24. ; local .__xyz1
  25. ; local .__xyz2
  26. ; push esi
  27. ; mov esi,.__xyz1
  28. ; call sys_msg_board_str
  29. ; push eax
  30. ; mov eax,1
  31. ; call delay_hs
  32. ; pop eax
  33. ; jmp .__xyz2
  34. ;.__xyz1:
  35. ; db X
  36. ; db 13,10,0
  37. ;.__xyz2:
  38. ; pop esi
  39. ;}
  40. PCNET32_PORT_AUI      equ 0x00
  41. PCNET32_PORT_10BT     equ 0x01
  42. PCNET32_PORT_GPSI     equ 0x02
  43. PCNET32_PORT_MII      equ 0x03
  44. PCNET32_PORT_PORTSEL  equ 0x03
  45. PCNET32_PORT_ASEL     equ 0x04
  46. PCNET32_PORT_100      equ 0x40
  47. PCNET32_PORT_FD       equ 0x80
  48. PCNET32_DMA_MASK      equ 0xffffffff
  49. PCNET32_LOG_TX_BUFFERS  equ 1
  50. PCNET32_LOG_RX_BUFFERS  equ 2
  51. PCNET32_TX_RING_SIZE            equ (1 shl PCNET32_LOG_TX_BUFFERS)
  52. PCNET32_TX_RING_MOD_MASK        equ (PCNET32_TX_RING_SIZE-1)
  53. PCNET32_TX_RING_LEN_BITS        equ 0
  54. PCNET32_RX_RING_SIZE            equ (1 shl PCNET32_LOG_RX_BUFFERS)
  55. PCNET32_RX_RING_MOD_MASK        equ (PCNET32_RX_RING_SIZE-1)
  56. PCNET32_RX_RING_LEN_BITS        equ (PCNET32_LOG_RX_BUFFERS shl 4)
  57. PCNET32_PKT_BUF_SZ              equ 1544
  58. PCNET32_PKT_BUF_SZ_NEG          equ 0xf9f8
  59. pcnet32_txb equ (eth_data_start)
  60. pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
  61. pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
  62. pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
  63. virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
  64. pcnet32_private:
  65. .mode                   dw ?
  66. .tlen_rlen              dw ?
  67. .phys_addr              db ?,?,?,?,?,?
  68. .reserved               dw ?
  69. .filter                 dd ?,?
  70. .rx_ring                dd ?
  71. .tx_ring                dd ?
  72. .cur_rx                 dd ?
  73. .cur_tx                 dd ?
  74. .dirty_rx               dd ?
  75. .dirty_tx               dd ?
  76. .tx_full                db ?
  77. .options                dd ?
  78. .full_duplex            db ?
  79. .chip_version           dd ?
  80. .mii                    db ?
  81. .ltint                  db ?
  82. .dxsuflo                db ?
  83. .fset                   db ?
  84. .fdx                    db ?
  85. end virtual
  86. virtual at 0
  87. pcnet32_rx_head:
  88. .base           dd ?
  89. .buf_length     dw ?
  90. .status         dw ?
  91. .msg_length     dd ?
  92. .reserved       dd ?
  93. end virtual
  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. pcnet32_init_ring:
  337.     mov [pcnet32_private.tx_full],0
  338.     mov [pcnet32_private.cur_rx],0
  339.     mov [pcnet32_private.cur_tx],0
  340.     mov [pcnet32_private.dirty_rx],0
  341.     mov [pcnet32_private.dirty_tx],0
  342.     mov edi,pcnet32_rx_ring
  343.     mov ecx,PCNET32_RX_RING_SIZE
  344.     mov ebx,pcnet32_rxb
  345. .rx_init:
  346.     mov [edi+pcnet32_rx_head.base],ebx
  347.     mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
  348.     mov [edi+pcnet32_rx_head.status],word 0x8000
  349.     add ebx,PCNET32_PKT_BUF_SZ
  350. ;    inc ebx
  351.     add edi,16
  352.     loop .rx_init
  353.     mov edi,pcnet32_tx_ring
  354.     mov ecx,PCNET32_TX_RING_SIZE
  355. .tx_init:
  356.     mov [edi+pcnet32_tx_head.base],dword 0
  357.     mov [edi+pcnet32_tx_head.status],word 0
  358.     add edi,16
  359.     loop .tx_init
  360.     mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
  361.     mov esi,node_addr
  362.     mov edi,pcnet32_private.phys_addr
  363.     cld
  364.     movsd
  365.     movsw
  366.     mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
  367.     mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
  368.     ret
  369. pcnet32_reset:
  370.     ; Reset PCNET32
  371.     mov ebp,[io_addr]
  372.     call dword [pcnet32_access.reset]
  373.     ; set 32bit mode
  374.     mov ebx,20
  375.     mov eax,2
  376.     call dword [pcnet32_access.write_bcr]
  377.     ; set/reset autoselect bit
  378.     mov ebx,2
  379.     call dword [pcnet32_access.read_bcr]
  380.     and eax,not 2
  381.     test [pcnet32_private.options],PCNET32_PORT_ASEL
  382.     jz .L1
  383.     or eax,2
  384. .L1:
  385.     call dword [pcnet32_access.write_bcr]
  386.     ; Handle full duplex setting
  387.     cmp byte [pcnet32_private.full_duplex],0
  388.     je .L2
  389.     mov ebx,9
  390.     call dword [pcnet32_access.read_bcr]
  391.     and eax,not 3
  392.     test [pcnet32_private.options],PCNET32_PORT_FD
  393.     jz .L3
  394.     or eax,1
  395.     cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI
  396.     jne .L4
  397.     or eax,2
  398.     jmp .L4
  399. .L3:
  400.     test [pcnet32_private.options],PCNET32_PORT_ASEL
  401.     jz .L4
  402.     cmp [pcnet32_private.chip_version],0x2627
  403.     jne .L4
  404.     or eax,3
  405. .L4:
  406.     mov ebx,9
  407.     call dword [pcnet32_access.write_bcr]
  408. .L2:
  409.     ; set/reset GPSI bit
  410.     mov ebx,124
  411.     call dword [pcnet32_access.read_csr]
  412.     mov ecx,[pcnet32_private.options]
  413.     and ecx,PCNET32_PORT_PORTSEL
  414.     cmp ecx,PCNET32_PORT_GPSI
  415.     jne .L5
  416.     or eax,0x10
  417. .L5:
  418.     call dword [pcnet32_access.write_csr]
  419.     cmp [pcnet32_private.mii],0
  420.     je .L6
  421.     test [pcnet32_private.options],PCNET32_PORT_ASEL
  422.     jnz .L6
  423.     mov ebx,32
  424.     call dword [pcnet32_access.read_bcr]
  425.     and eax,not 0x38
  426.     test [pcnet32_private.options],PCNET32_PORT_FD
  427.     jz .L7
  428.     or eax,0x10
  429. .L7:
  430.     test [pcnet32_private.options],PCNET32_PORT_100
  431.     jz .L8
  432.     or eax,0x08
  433. .L8:
  434.     call dword [pcnet32_access.write_bcr]
  435.     jmp .L9
  436. .L6:
  437.     test [pcnet32_private.options],PCNET32_PORT_ASEL
  438.     jz .L9
  439.     mov ebx,32
  440. ;    PutStr "ASEL, enable auto-negotiation"
  441.     call dword [pcnet32_access.read_bcr]
  442.     and eax,not 0x98
  443.     or eax,0x20
  444.     call dword [pcnet32_access.write_bcr]
  445. .L9:
  446.     cmp [pcnet32_private.ltint],0
  447.     je .L10
  448.     mov ebx,5
  449.     call dword [pcnet32_access.read_csr]
  450.     or eax,(1 shl 14)
  451.     call dword [pcnet32_access.write_csr]
  452. .L10:
  453.     mov eax,[pcnet32_private.options]
  454.     and eax,PCNET32_PORT_PORTSEL
  455.     shl eax,7
  456.     mov [pcnet32_private.mode],ax
  457.     mov [pcnet32_private.filter],dword 0xffffffff
  458.     mov [pcnet32_private.filter+4],dword 0xffffffff
  459.     call pcnet32_init_ring
  460.     mov ebx,1
  461.     mov eax,pcnet32_private
  462.     and eax,0xffff
  463.     call dword [pcnet32_access.write_csr]
  464.     mov eax,pcnet32_private
  465.     mov ebx,2
  466.     shr eax,16
  467.     call dword [pcnet32_access.write_csr]
  468.     mov ebx,4
  469.     mov eax,0x0915
  470.     call dword [pcnet32_access.write_csr]
  471.     mov ebx,0
  472.     mov eax,1
  473.     call dword [pcnet32_access.write_csr]
  474.     mov ecx,100
  475. .L11:
  476.     xor ebx,ebx
  477.     call dword [pcnet32_access.read_csr]
  478.     test ax,0x100
  479.     jnz .L12
  480.     loop .L11
  481. .L12:
  482. ;    PutStr "hardware reset"
  483.     xor ebx,ebx
  484.     mov eax,0x0002
  485.     call dword [pcnet32_access.write_csr]
  486.     xor ebx,ebx
  487.     call dword [pcnet32_access.read_csr]
  488. ;    PutStr "PCNET reset complete"
  489.     ret
  490. pcnet32_adjust_pci_device:
  491.    ;*******Get current setting************************
  492.    mov     al, 2                                        ;read a word
  493.    mov     bh, [pci_dev]
  494.    mov     ah, [pci_bus]
  495.    mov     bl, 0x04                                 ;from command Register
  496.    call    pci_read_reg
  497.    ;******see if its already set as bus master********
  498.    mov      bx, ax
  499.    and      bx,5
  500.    cmp      bx,5
  501.    je       pcnet32_adjust_pci_device_Latency
  502.    ;******Make card a bus master*******
  503.    mov      cx, ax                              ;value to write
  504.    mov     bh, [pci_dev]
  505.    mov     al, 2                                ;write a word
  506.    or       cx,5
  507.    mov     ah, [pci_bus]
  508.    mov     bl, 0x04                             ;to command register
  509.    call    pci_write_reg
  510.    ;******Check latency setting***********
  511. pcnet32_adjust_pci_device_Latency:
  512.    ;*******Get current latency setting************************
  513. ;   mov     al, 1                                       ;read a byte
  514. ;   mov     bh, [pci_dev]
  515. ;   mov     ah, [pci_bus]
  516. ;   mov     bl, 0x0D                                ;from Lantency Timer Register
  517. ;   call    pci_read_reg
  518.    ;******see if its aat least 64 clocks********
  519. ;   cmp      ax,64
  520. ;   jge      pcnet32_adjust_pci_device_Done
  521.    ;******Set latency to 32 clocks*******
  522. ;   mov     cx, 64                              ;value to write
  523. ;   mov     bh, [pci_dev]
  524. ;   mov     al, 1                               ;write a byte
  525. ;   mov     ah, [pci_bus]
  526. ;   mov     bl, 0x0D                            ;to Lantency Timer Register
  527. ;   call    pci_write_reg
  528.    ;******Check latency setting***********
  529. pcnet32_adjust_pci_device_Done:
  530.    ret
  531. pcnet32_probe:
  532.     mov ebp,[io_addr]
  533.     call pcnet32_wio_reset
  534.     xor ebx,ebx
  535.     call pcnet32_wio_read_csr
  536.     cmp eax,4
  537.     jne .try_dwio
  538.     call pcnet32_wio_check
  539.     and al,al
  540.     jz .try_dwio
  541. ;    PutStr "Using WIO"
  542.     mov esi,pcnet32_wio
  543.     jmp .L1
  544. .try_dwio:
  545.     call pcnet32_dwio_reset
  546.     xor ebx,ebx
  547.     call pcnet32_dwio_read_csr
  548.     cmp eax,4
  549.     jne .no_dev
  550.     call pcnet32_dwio_check
  551.     and al,al
  552.     jz .no_dev
  553. ;    PutStr "Using DWIO"
  554.     mov esi,pcnet32_dwio
  555.     jmp .L1
  556. .no_dev:
  557. ;    PutStr "PCNET32 not found"
  558.     ret
  559. .L1:
  560.     mov edi,pcnet32_access
  561.     mov ecx,7
  562.     cld
  563.     rep movsd
  564.     mov ebx,88
  565.     call dword [pcnet32_access.read_csr]
  566.     mov ecx,eax
  567.     mov ebx,89
  568.     call dword [pcnet32_access.read_csr]
  569.     shl eax,16
  570.     or eax,ecx
  571.     mov ecx,eax
  572.     and ecx,0xfff
  573.     cmp ecx,3
  574.     jne .no_dev
  575.     shr eax,12
  576.     and eax,0xffff
  577.     mov [pcnet32_private.chip_version],eax
  578. ;    PutStr "PCNET32 chip version OK"
  579.     mov [pcnet32_private.fdx],0
  580.     mov [pcnet32_private.mii],0
  581.     mov [pcnet32_private.fset],0
  582.     mov [pcnet32_private.dxsuflo],0
  583.     mov [pcnet32_private.ltint],0
  584.     mov eax,[pcnet32_private.chip_version]
  585.     cmp eax,0x2420
  586.     je .L2
  587.     cmp eax,0x2430
  588.     je .L3
  589.     cmp eax,0x2621
  590.     je .L4
  591.     cmp eax,0x2623
  592.     je .L5
  593.     cmp eax,0x2624
  594.     je .L6
  595.     cmp eax,0x2625
  596.     je .L7
  597.     cmp eax,0x2626
  598.     je .L8
  599.     cmp eax,0x2627
  600.     je .L9
  601. ;    PutStr "Invalid chip rev"
  602.     jmp .no_dev
  603. .L2:
  604. ;    PutStr "PCnet/PCI 79C970"
  605.     jmp .L10
  606. .L3:
  607. ;    PutStr "PCnet/PCI 79C970"
  608.     jmp .L10
  609. .L4:
  610. ;    PutStr "PCnet/PCI II 79C970A"
  611.     mov [pcnet32_private.fdx],1
  612.     jmp .L10
  613. .L5:
  614. ;    PutStr "PCnet/FAST 79C971"
  615.     mov [pcnet32_private.fdx],1
  616.     mov [pcnet32_private.mii],1
  617.     mov [pcnet32_private.fset],1
  618.     mov [pcnet32_private.ltint],1
  619.     jmp .L10
  620. .L6:
  621. ;    PutStr "PCnet/FAST+ 79C972"
  622.     mov [pcnet32_private.fdx],1
  623.     mov [pcnet32_private.mii],1
  624.     mov [pcnet32_private.fset],1
  625.     jmp .L10
  626. .L7:
  627. ;    PutStr "PCnet/FAST III 79C973"
  628.     mov [pcnet32_private.fdx],1
  629.     mov [pcnet32_private.mii],1
  630.     jmp .L10
  631. .L8:
  632. ;    PutStr "PCnet/Home 79C978"
  633.     mov [pcnet32_private.fdx],1
  634.     mov ebx,49
  635.     call dword [pcnet32_access.read_bcr]
  636.     call dword [pcnet32_access.write_bcr]
  637.     jmp .L10
  638. .L9:
  639. ;    PutStr "PCnet/FAST III 79C975"
  640.     mov [pcnet32_private.fdx],1
  641.     mov [pcnet32_private.mii],1
  642. .L10:
  643.     cmp [pcnet32_private.fset],1
  644.     jne .L11
  645.     mov ebx,18
  646.     call dword [pcnet32_access.read_bcr]
  647.     or eax,0x800
  648.     call dword [pcnet32_access.write_bcr]
  649.     mov ebx,80
  650.     call dword [pcnet32_access.read_csr]
  651.     and eax,0xc00
  652.     or eax,0xc00
  653.     call dword [pcnet32_access.write_csr]
  654.     mov [pcnet32_private.dxsuflo],1
  655.     mov [pcnet32_private.ltint],1
  656. .L11:
  657.     ; read MAC
  658.     mov edi,node_addr
  659.     mov edx,ebp
  660.     mov ecx,6
  661. .Lmac:
  662.     in al,dx
  663.     stosb
  664.     inc edx
  665.     loop .Lmac
  666. ;    PutStr "MAC read"
  667.     call pcnet32_adjust_pci_device
  668. ;    PutStr "PCI done"
  669.     mov eax,PCNET32_PORT_ASEL
  670.     mov [pcnet32_private.options],eax
  671.     mov [pcnet32_private.mode],word 0x0003
  672.     mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
  673.     mov esi,node_addr
  674.     mov edi,pcnet32_private.phys_addr
  675.     cld
  676.     movsd
  677.     movsw
  678.     mov [pcnet32_private.filter],dword 0
  679.     mov [pcnet32_private.filter+4],dword 0
  680.     mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
  681.     mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
  682. ;    PutStr "Switching to 32"
  683.     mov ebx,20
  684.     mov eax,2
  685.     call dword [pcnet32_access.write_bcr]
  686.     mov ebx,1
  687.     mov eax,(pcnet32_private and 0xffff)
  688.     call dword [pcnet32_access.write_csr]
  689.     mov ebx,2
  690.     mov eax,(pcnet32_private shr 16) and 0xffff
  691.     call dword [pcnet32_access.write_csr]
  692.     mov ebx,0
  693.     mov eax,1
  694.     call dword [pcnet32_access.write_csr]
  695.     mov esi,1
  696.     call delay_ms
  697.     call pcnet32_reset
  698.     mov eax, [pci_data]
  699.     mov [eth_status], eax
  700.     ret
  701. pcnet32_poll:
  702.     xor eax,eax
  703.     mov [eth_rx_data_len],ax
  704.     mov eax,[pcnet32_private.cur_rx]
  705.     and eax,PCNET32_RX_RING_MOD_MASK
  706.     mov ebx,eax
  707.     imul esi,eax,PCNET32_PKT_BUF_SZ
  708.     add esi,pcnet32_rxb
  709.     shl ebx,4
  710.     add ebx,pcnet32_rx_ring
  711.     mov cx,[ebx+pcnet32_rx_head.status]
  712.     test cx,0x8000
  713.     jnz .L1
  714.     cmp ch,3
  715.     jne .L1
  716. ;    PutStr "PCNETRX"
  717.     mov ecx,[ebx+pcnet32_rx_head.msg_length]
  718.     and ecx,0xfff
  719.     sub ecx,4
  720.     mov [eth_rx_data_len],cx
  721.     push ecx
  722.     shr ecx,2
  723.     mov edi,Ether_buffer
  724.     cld
  725.     rep movsd
  726.     pop ecx
  727.     and ecx,3
  728.     rep movsb
  729.     mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
  730.     or [ebx+pcnet32_rx_head.status],word 0x8000
  731.     inc [pcnet32_private.cur_rx]
  732. .L1:
  733.     ret
  734. ;         Pointer to 48 bit destination address in edi
  735. ;         Type of packet in bx
  736. ;         size of packet in ecx
  737. ;         pointer to packet data in esi
  738. pcnet32_xmit:
  739.     push edi
  740.     push esi
  741.     push ebx
  742.     push ecx
  743. ;    PutStr "PCNETTX"
  744.     mov esi,edi
  745.     mov edi,[pcnet32_private.cur_tx]
  746.     imul edi,PCNET32_PKT_BUF_SZ
  747.     add edi,pcnet32_txb ; edi=ptxb
  748.     mov eax,edi
  749.     cld         ; copy MAC
  750.     movsd
  751.     movsw
  752.     mov esi,node_addr
  753.     cld
  754.     movsd
  755.     movsw
  756.     mov [edi],bx
  757.     add edi,2
  758.     mov esi,[esp+8]
  759.     mov ecx,[esp]
  760.     push ecx
  761.     shr ecx,2
  762.     cld
  763.     rep movsd
  764.     pop ecx
  765.     and ecx,3
  766.     rep movsb
  767. ;    mov ecx,[esp]
  768. ;    add ecx,14 ; ETH_HLEN
  769. ;    xor eax,eax
  770. ; pad to min length (60=ETH_ZLEN)
  771. ;    cmp ecx,60
  772. ;    jae .L1
  773. ;    sub ecx,60
  774. ;    cld
  775. ;    rep stosb
  776. ;.L1:
  777.     mov edi,pcnet32_tx_ring+0   ; entry=0
  778.     mov ecx,[esp]
  779.     add ecx,14
  780.     cmp cx,60
  781.     jae .L1
  782.     mov cx,60
  783. .L1:
  784.     neg cx
  785.     mov [edi+pcnet32_tx_head.length],cx
  786.     mov [edi+pcnet32_tx_head.misc],dword 0
  787.     mov [edi+pcnet32_tx_head.base],eax
  788.     mov [edi+pcnet32_tx_head.status],word 0x8300
  789.     ; trigger an immediate send poll
  790.     mov ebx,0
  791.     mov eax,0x0008      ; 0x0048
  792.     mov ebp,[io_addr]
  793.     call dword [pcnet32_access.write_csr]
  794.     mov dword [pcnet32_private.cur_tx],0
  795.     ; wait for TX to complete
  796.     mov ecx,[timer_ticks];[0xfdf0]
  797.     add ecx,100
  798. .L2:
  799.     mov ax,[edi+pcnet32_tx_head.status]
  800.     test ax,0x8000
  801.     jz .L3
  802.     cmp ecx,[timer_ticks];[0xfdf0]
  803.     jb .L4
  804.     mov esi,10
  805.     call delay_ms
  806.     jnz .L2
  807. .L4:
  808. ;    PutStr "PCNET: Send timeout"
  809. .L3:
  810.     mov dword [edi+pcnet32_tx_head.base],0
  811.     pop ecx
  812.     pop ebx
  813.     pop esi
  814.     pop edi
  815.     ret
  816.