Subversion Repositories Kolibri OS

Rev

Rev 425 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. $Revision: 431 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                              ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9. ;; Copyright (c) 2004, Endre Kozma <endre.kozma@axelero.hu>
  10. ;; All rights reserved.
  11. ;;
  12. ;; Redistribution  and  use  in  source  and  binary  forms, with or without
  13. ;; modification, are permitted provided  that  the following  conditions are
  14. ;; met:
  15. ;;
  16. ;; 1. Redistributions of source code must retain the above  copyright notice,
  17. ;;    this list of conditions and the following disclaimer.
  18. ;;
  19. ;; 2. Redistributions  in  binary form  must  reproduce  the above copyright
  20. ;;    notice, this  list of conditions  and the  following disclaimer in the
  21. ;;    documentation and/or other  materials  provided with  the distribution.
  22. ;;
  23. ;; 3. The name of the author may not be used to  endorse or promote products
  24. ;;    derived from this software without  specific prior  written permission.
  25. ;;
  26. ;; THIS SOFTWARE IS  PROVIDED  BY  THE  AUTHOR  ``AS IS'' AND ANY EXPRESS OR
  27. ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  28. ;; OF  MERCHANTABILITY AND FITNESS  FOR A PARTICULAR  PURPOSE ARE DISCLAIMED.
  29. ;; IN  NO  EVENT  SHALL  THE  AUTHOR  BE  LIABLE  FOR  ANY  DIRECT, INDIRECT,
  30. ;; INCIDENTAL, SPECIAL, EXEMPLARY, OR  CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  31. ;; NOT LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. ;; DATA, OR  PROFITS; OR  BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON ANY
  33. ;; THEORY OF  LIABILITY, WHETHER IN  CONTRACT,  STRICT  LIABILITY,  OR  TORT
  34. ;; (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT OF THE USE OF
  35. ;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36.  
  37. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  38. ;;                                                                         ;;
  39. ;;  3C59X.INC                                                              ;;
  40. ;;                                                                         ;;
  41. ;;  Ethernet driver for Menuet OS                                          ;;
  42. ;;                                                                         ;;
  43. ;;  Driver for 3Com fast etherlink 3c59x and                               ;;
  44. ;;         etherlink XL 3c900 and 3c905 cards                              ;;
  45. ;;  References:                                                            ;;
  46. ;;    www.3Com.com - data sheets                                           ;;
  47. ;;    DP83840A.pdf - ethernet physical layer                               ;;
  48. ;;    3c59x.c - linux driver                                               ;;
  49. ;;    ethernet driver template by Mike Hibbett                             ;;
  50. ;;                                                                         ;;
  51. ;;  Credits                                                                ;;
  52. ;;   Mike Hibbett,                                                         ;;
  53. ;;         who kindly supplied me with a 3Com905C-TX-M card                ;;
  54. ;;                                                                         ;;
  55. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  56. ;;  History
  57. ;;  =======
  58. ;;  $Log: 3C59X.INC,v $
  59. ;;  Revision 1.3  2004/07/11 12:21:12  kozma
  60. ;;  Support of vortex chips (3c59x) added.
  61. ;;  Support of 3c920 and 3c982 added.
  62. ;;  Corrections.
  63. ;;
  64. ;;  Revision 1.2  2004/06/12 19:40:20  kozma
  65. ;;  Function e3c59x_set_available_media added in order to set
  66. ;;  the default media in case auto detection finds no valid link.
  67. ;;  Incorrect mii check removed (3c900 Cyclone works now).
  68. ;;  Cleanups.
  69. ;;
  70. ;;  Revision 1.1  2004/06/12 18:27:15  kozma
  71. ;;  Initial revision
  72. ;;
  73. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  74.  
  75. ; comment the next line out if you don't want debug info printed
  76. ; on the debug board. This option adds a lot of bytes to the driver
  77. ; so it's worth to comment it out.
  78. ;        E3C59X_DEBUG    equ 1
  79.  
  80. ; forcing full duplex mode makes sense at some cards and link types
  81.         E3C59X_FORCE_FD equ 1
  82.  
  83. macro virt_to_dma reg
  84. {
  85. if defined E3C59X_LINUX
  86.         sub     reg, [virt_addr]
  87.         add     reg, [dma_addr]
  88. end if
  89. }
  90.  
  91. macro dma_to_virt reg
  92. {
  93. if defined E3C59X_LINUX
  94.         sub     reg, [dma_addr]
  95.         add     reg, [virt_addr]
  96. end if
  97. }
  98.  
  99. macro zero_to_virt reg
  100. {
  101. if defined E3C59X_LINUX
  102.         add     reg, [virt_addr]
  103. end if
  104. }
  105.  
  106. macro virt_to_zero reg
  107. {
  108. if defined E3C59X_LINUX
  109.         sub     reg, [virt_addr]
  110. end if
  111. }
  112.  
  113. macro zero_to_dma reg
  114. {
  115. if defined E3C59X_LINUX
  116.         add     reg, [dma_addr]
  117. end if
  118. }
  119.  
  120. macro dma_to_zero reg
  121. {
  122. if defined E3C59X_LINUX
  123.         sub     reg, [dma_addr]
  124. end if
  125. }
  126.  
  127. macro strtbl name, [string]
  128. {
  129. common
  130.         label name dword
  131. forward
  132.         local label
  133.         dd label
  134. forward
  135.         label db string, 0
  136. }
  137.  
  138. ; Ethernet frame symbols
  139.         ETH_ALEN                       equ 6
  140.         ETH_HLEN                       equ (2*ETH_ALEN+2)
  141.         ETH_ZLEN                       equ 60 ; 60 + 4bytes auto payload for
  142.                                               ; mininmum 64bytes frame length
  143. ; PCI programming
  144.         PCI_REG_COMMAND               equ 0x4 ; command register
  145.         PCI_REG_STATUS                 equ 0x6 ; status register
  146.         PCI_REG_LATENCY               equ 0xd ; latency timer register
  147.         PCI_REG_CAP_PTR               equ 0x34 ; capabilities pointer
  148.         PCI_REG_CAPABILITY_ID         equ 0x0 ; capapility ID in pm register block
  149.         PCI_REG_PM_STATUS             equ 0x4 ; power management status register
  150.         PCI_REG_PM_CTRL               equ 0x4 ; power management control register
  151.         PCI_BIT_PIO                   equ 0 ; bit0: io space control
  152.         PCI_BIT_MMIO                   equ 1 ; bit1: memory space control
  153.         PCI_BIT_MASTER                 equ 2 ; bit2: device acts as a PCI master
  154. ; Registers
  155.         E3C59X_REG_POWER_MGMT_CTRL     equ 0x7c
  156.         E3C59X_REG_UP_LIST_PTR         equ 0x38
  157.         E3C59X_REG_UP_PKT_STATUS       equ 0x30
  158.         E3C59X_REG_TX_FREE_THRESH     equ 0x2f
  159.         E3C59X_REG_DN_LIST_PTR         equ 0x24
  160.         E3C59X_REG_DMA_CTRL           equ 0x20
  161.         E3C59X_REG_TX_STATUS           equ 0x1b
  162.         E3C59X_REG_RX_STATUS           equ 0x18
  163.         E3C59X_REG_TX_DATA             equ 0x10
  164. ; Common window registers
  165.         E3C59X_REG_INT_STATUS         equ 0xe
  166.         E3C59X_REG_COMMAND             equ 0xe
  167. ; Register window 7
  168.         E3C59X_REG_MASTER_STATUS       equ 0xc
  169.         E3C59X_REG_POWER_MGMT_EVENT   equ 0xc
  170.         E3C59X_REG_MASTER_LEN         equ 0x6
  171.         E3C59X_REG_VLAN_ETHER_TYPE     equ 0x4
  172.         E3C59X_REG_VLAN_MASK           equ 0x0
  173.         E3C59X_REG_MASTER_ADDRESS     equ 0x0
  174. ; Register window 6
  175.         E3C59X_REG_BYTES_XMITTED_OK   equ 0xc
  176.         E3C59X_REG_BYTES_RCVD_OK       equ 0xa
  177.         E3C59X_REG_UPPER_FRAMES_OK     equ 0x9
  178.         E3C59X_REG_FRAMES_DEFERRED     equ 0x8
  179.         E3C59X_REG_FRAMES_RCVD_OK     equ 0x7
  180.         E3C59X_REG_FRAMES_XMITTED_OK   equ 0x6
  181.         E3C59X_REG_RX_OVERRUNS         equ 0x5
  182.         E3C59X_REG_LATE_COLLISIONS     equ 0x4
  183.         E3C59X_REG_SINGLE_COLLISIONS   equ 0x3
  184.         E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2
  185.         E3C59X_REG_SQE_ERRORS         equ 0x1
  186.         E3C59X_REG_CARRIER_LOST       equ 0x0
  187. ; Register window 5
  188.         E3C59X_REG_INDICATION_ENABLE   equ 0xc
  189.         E3C59X_REG_INTERRUPT_ENABLE   equ 0xa
  190.         E3C59X_REG_TX_RECLAIM_THRESH   equ 0x9
  191.         E3C59X_REG_RX_FILTER           equ 0x8
  192.         E3C59X_REG_RX_EARLY_THRESH     equ 0x6
  193.         E3C59X_REG_TX_START_THRESH     equ 0x0
  194. ; Register window 4
  195.         E3C59X_REG_UPPER_BYTES_OK     equ 0xe
  196.         E3C59X_REG_BAD_SSD             equ 0xc
  197.         E3C59X_REG_MEDIA_STATUS       equ 0xa
  198.         E3C59X_REG_PHYSICAL_MGMT       equ 0x8
  199.         E3C59X_REG_NETWORK_DIAGNOSTIC equ 0x6
  200.         E3C59X_REG_FIFO_DIAGNOSTIC     equ 0x4
  201.         E3C59X_REG_VCO_DIAGNOSTIC     equ 0x2 ; may not supported
  202. ; Bits in register window 4
  203.         E3C59X_BIT_AUTOSELECT         equ 24
  204. ; Register window 3
  205.         E3C59X_REG_TX_FREE             equ 0xc
  206.         E3C59X_REG_RX_FREE             equ 0xa
  207.         E3C59X_REG_MEDIA_OPTIONS       equ 0x8
  208.         E3C59X_REG_MAC_CONTROL         equ 0x6
  209.         E3C59X_REG_MAX_PKT_SIZE       equ 0x4
  210.         E3C59X_REG_INTERNAL_CONFIG     equ 0x0
  211. ; Register window 2
  212.         E3C59X_REG_RESET_OPTIONS       equ 0xc
  213.         E3C59X_REG_STATION_MASK_HI     equ 0xa
  214.         E3C59X_REG_STATION_MASK_MID   equ 0x8
  215.         E3C59X_REG_STATION_MASK_LO     equ 0x6
  216.         E3C59X_REG_STATION_ADDRESS_HI equ 0x4
  217.         E3C59X_REG_STATION_ADDRESS_MID equ 0x2
  218.         E3C59X_REG_STATION_ADDRESS_LO equ 0x0
  219. ; Register window 1
  220.         E3C59X_REG_TRIGGER_BITS       equ 0xc
  221.         E3C59X_REG_SOS_BITS           equ 0xa
  222.         E3C59X_REG_WAKE_ON_TIMER       equ 0x8
  223.         E3C59X_REG_SMB_RXBYTES         equ 0x7
  224.         E3C59X_REG_SMB_DIAG           equ 0x5
  225.         E3C59X_REG_SMB_ARB             equ 0x4
  226.         E3C59X_REG_SMB_STATUS         equ 0x2
  227.         E3C59X_REG_SMB_ADDRESS         equ 0x1
  228.         E3C59X_REG_SMB_FIFO_DATA       equ 0x0
  229. ; Register window 0
  230.         E3C59X_REG_EEPROM_DATA         equ 0xc
  231.         E3C59X_REG_EEPROM_COMMAND     equ 0xa
  232.         E3C59X_REG_BIOS_ROM_DATA       equ 0x8
  233.         E3C59X_REG_BIOS_ROM_ADDR       equ 0x4
  234. ; Physical management bits
  235.         E3C59X_BIT_MGMT_DIR           equ 2 ; drive with the data written in mgmtData
  236.         E3C59X_BIT_MGMT_DATA           equ 1 ; MII management data bit
  237.         E3C59X_BIT_MGMT_CLK           equ 0 ; MII management clock
  238. ; MII commands
  239.         E3C59X_MII_CMD_MASK           equ (1111b shl 10)
  240.         E3C59X_MII_CMD_READ           equ (0110b shl 10)
  241.         E3C59X_MII_CMD_WRITE           equ (0101b shl 10)
  242. ; MII registers
  243.         E3C59X_REG_MII_BMCR           equ 0 ; basic mode control register
  244.         E3C59X_REG_MII_BMSR           equ 1 ; basic mode status register
  245.         E3C59X_REG_MII_ANAR           equ 4 ; auto negotiation advertisement register
  246.         E3C59X_REG_MII_ANLPAR         equ 5 ; auto negotiation link partner ability register
  247.         E3C59X_REG_MII_ANER           equ 6 ; auto negotiation expansion register
  248. ; MII bits
  249.         E3C59X_BIT_MII_AUTONEG_COMPLETE     equ 5 ; auto-negotiation complete
  250.         E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6
  251. ; eeprom bits and commands
  252.         E3C59X_EEPROM_CMD_READ         equ 0x80
  253.         E3C59X_EEPROM_BIT_BUSY         equ 15
  254. ; eeprom registers
  255.         E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa
  256.         E3C59X_EEPROM_REG_CAPABILITIES equ 0x10
  257. ; Commands for command register
  258.         E3C59X_SELECT_REGISTER_WINDOW equ (1 shl 11)
  259.  
  260.         IS_VORTEX                     equ 0x1
  261.         IS_BOOMERANG                   equ 0x2
  262.         IS_CYCLONE                     equ 0x4
  263.         IS_TORNADO                     equ 0x8
  264.         EEPROM_8BIT                   equ 0x10
  265.         HAS_PWR_CTRL                   equ 0x20
  266.         HAS_MII                       equ 0x40
  267.         HAS_NWAY                       equ 0x80
  268.         HAS_CB_FNS                     equ 0x100
  269.         INVERT_MII_PWR                 equ 0x200
  270.         INVERT_LED_PWR                 equ 0x400
  271.         MAX_COLLISION_RESET           equ 0x800
  272.         EEPROM_OFFSET                 equ 0x1000
  273.         HAS_HWCKSM                     equ 0x2000
  274.         EXTRA_PREAMBLE                 equ 0x4000
  275.  
  276. iglobal
  277.         align 4
  278. e3c59x_hw_versions:
  279.         dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps
  280.         dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex
  281.         dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex
  282.         dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx
  283.         dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4
  284.         dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII
  285.         dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT
  286.         dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo
  287.         dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO
  288.         dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo
  289.         dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC
  290.         dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL
  291.         dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx
  292.         dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4
  293.         dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx
  294.         dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC
  295.         dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx
  296.         dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado
  297.         dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone
  298.         dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone
  299.         dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane
  300.         dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane
  301.         dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \
  302.                               or INVERT_MII_PWR or HAS_HWCKSM ; 3c556 Laptop Tornado
  303.         dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \
  304.                               or INVERT_MII_PWR or HAS_HWCKSM ; 3c556B Laptop Hurricane
  305.         dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus
  306.         dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus
  307.         dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \
  308.                               or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE575BT Cyclone CardBus
  309.         dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
  310.                               or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CCFE575CT Tornado CardBus
  311.         dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
  312.                               or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE656 Cyclone CardBus
  313.         dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
  314.                               or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFEM656B Cyclone+Winmodem CardBus
  315.         dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
  316.                               or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CXFEM656C Tornado+Winmodem CardBus
  317.         dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado
  318.         dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado
  319.         dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A
  320.         dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B
  321.         dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4
  322.         dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado
  323. E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions
  324. endg
  325.  
  326. ; RX/TX buffers sizes
  327.         E3C59X_MAX_ETH_PKT_SIZE     equ 1536 ; max packet size
  328.         E3C59X_NUM_RX_DESC           equ 4 ; a power of 2 number
  329.         E3C59X_NUM_TX_DESC           equ 4 ; a power of 2 number
  330.         E3C59X_RX_BUFFER_SIZE       equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC)
  331.         E3C59X_TX_BUFFER_SIZE       equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC)
  332. ; Download Packet Descriptor
  333.         E3C59X_DPD_DN_NEXT_PTR       equ 0
  334.         E3C59X_DPD_FRAME_START_HDR   equ 4
  335.         E3C59X_DPD_DN_FRAG_ADDR     equ 8 ; for packet data
  336.         E3C59X_DPD_DN_FRAG_LEN       equ 12 ; for packet data
  337.         E3C59X_DPD_SIZE             equ 16 ; a power of 2 number
  338. ; Upload Packet Descriptor
  339.         E3C59X_UPD_UP_NEXT_PTR       equ 0
  340.         E3C59X_UPD_PKT_STATUS       equ 4
  341.         E3C59X_UPD_UP_FRAG_ADDR     equ 8 ; for packet data
  342.         E3C59X_UPD_UP_FRAG_LEN       equ 12 ; for packet data
  343.         E3C59X_UPD_SIZE             equ 16
  344.  
  345. ; RX/TX buffers
  346. if defined E3C59X_LINUX
  347.         E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment
  348.         e3c59x_rx_buff = 0
  349. else
  350.         E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment
  351.         e3c59x_rx_buff = eth_data_start
  352. end if
  353.  
  354.         e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE
  355.         e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE
  356.         e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC)
  357.  
  358. uglobal
  359. e3c59x_curr_upd: dd 0
  360. e3c59x_prev_dpd: dd 0
  361. e3c59x_prev_tx_frame: dd 0
  362. e3c59x_transmit_function: dd 0
  363. e3c59x_receive_function: dd 0
  364. endg
  365.  
  366. iglobal
  367. e3c59x_ver_id: db 17
  368. endg
  369. uglobal
  370. e3c59x_full_bus_master: db 0
  371. e3c59x_has_hwcksm:  db 0
  372. e3c59x_preamble: db 0
  373. e3c59x_dn_list_ptr_cleared: db 0
  374. e3c59x_self_directed_packet: rb 6
  375. endg
  376.  
  377. if defined E3C59X_DEBUG
  378. e3c59x_hw_type_str: db "Detected hardware type  : ", 0
  379. e3c59x_device_str: db  "Device ID               : 0x"
  380. e3c59x_device_id_str: db "ffff", 13, 10, 0
  381. e3c59x_vendor_str: db  "Vendor ID               : 0x"
  382. e3c59x_vendor_id_str: db "ffff", 13, 10, 0
  383. e3c59x_io_info_str: db "IO address              : 0x"
  384. e3c59x_io_addr_str: db "ffff", 13, 10, 0
  385. e3c59x_mac_info_str: db "MAC address             : "
  386. e3c59x_mac_addr_str: db "ff:ff:ff:ff:ff:ff", 13, 10, 0
  387. e3c59x_boomerang_str: db " (boomerang)", 13, 10, 0
  388. e3c59x_vortex_str: db " (vortex)", 13, 10, 0
  389. e3c59x_link_type_str: db "Established link type   : ", 0
  390. e3c59x_new_line_str: db 13, 10, 0
  391. e3c59x_link_type: dd 0
  392.  
  393. e3c59x_charset: db '0123456789abcdef'
  394.  
  395. strtbl e3c59x_link_str, \
  396.         "No valid link type detected", \
  397.         "10BASE-T half duplex", \
  398.         "10BASE-T full-duplex", \
  399.         "100BASE-TX half duplex", \
  400.         "100BASE-TX full duplex", \
  401.         "100BASE-T4", \
  402.         "100BASE-FX", \
  403.         "10Mbps AUI", \
  404.         "10Mbps COAX (BNC)", \
  405.         "miiDevice - not supported"
  406.  
  407. strtbl e3c59x_hw_str, \
  408.         "3c590 Vortex 10Mbps", \
  409.         "3c592 EISA 10Mbps Demon/Vortex", \
  410.         "3c597 EISA Fast Demon/Vortex", \
  411.         "3c595 Vortex 100baseTx", \
  412.         "3c595 Vortex 100baseT4", \
  413.         "3c595 Vortex 100base-MII", \
  414.         "3c900 Boomerang 10baseT", \
  415.         "3c900 Boomerang 10Mbps Combo", \
  416.         "3c900 Cyclone 10Mbps TPO", \
  417.         "3c900 Cyclone 10Mbps Combo", \
  418.         "3c900 Cyclone 10Mbps TPC", \
  419.         "3c900B-FL Cyclone 10base-FL", \
  420.         "3c905 Boomerang 100baseTx", \
  421.         "3c905 Boomerang 100baseT4", \
  422.         "3c905B Cyclone 100baseTx", \
  423.         "3c905B Cyclone 10/100/BNC", \
  424.         "3c905B-FX Cyclone 100baseFx", \
  425.         "3c905C Tornado", \
  426.         "3c980 Cyclone", \
  427.         "3c982 Dual Port Server Cyclone", \
  428.         "3cSOHO100-TX Hurricane", \
  429.         "3c555 Laptop Hurricane", \
  430.         "3c556 Laptop Tornado", \
  431.         "3c556B Laptop Hurricane", \
  432.         "3c575 [Megahertz] 10/100 LAN CardBus", \
  433.         "3c575 Boomerang CardBus", \
  434.         "3CCFE575BT Cyclone CardBus", \
  435.         "3CCFE575CT Tornado CardBus", \
  436.         "3CCFE656 Cyclone CardBus", \
  437.         "3CCFEM656B Cyclone+Winmodem CardBus", \
  438.         "3CXFEM656C Tornado+Winmodem CardBus", \
  439.         "3c450 HomePNA Tornado", \
  440.         "3c920 Tornado", \
  441.         "3c982 Hydra Dual Port A", \
  442.         "3c982 Hydra Dual Port B", \
  443.         "3c905B-T4", \
  444.         "3c920B-EMB-WNM Tornado"
  445.  
  446. end if ; defined E3C59X_DEBUG
  447.  
  448. ;***************************************************************************
  449. ;   Function
  450. ;      e3c59x_debug
  451. ;   Description
  452. ;      prints debug info to the debug board
  453. ;   Parameters
  454. ;      ebp - io_addr
  455. ;   Return value
  456. ;   Destroyed registers
  457. ;      eax, ebx, ecx, edx, edi, esi
  458. ;
  459. ;***************************************************************************
  460. if defined E3C59X_DEBUG
  461.         align 4
  462. e3c59x_debug:
  463.         pushad
  464. ; print device type
  465.         mov     esi, e3c59x_hw_type_str
  466.         call    sys_msg_board_str
  467.         movzx   ecx, byte [e3c59x_ver_id]
  468.         mov     esi, [e3c59x_hw_str+ecx*4]
  469.         call    sys_msg_board_str
  470.         mov     esi, e3c59x_boomerang_str
  471.         cmp     dword [e3c59x_transmit_function], e3c59x_boomerang_transmit
  472.         jz      .boomerang
  473.         mov     esi, e3c59x_vortex_str
  474. .boomerang:
  475.         call    sys_msg_board_str
  476. ; print device/vendor
  477.         mov     ax, [pci_data+2]
  478.         mov     cl, 2
  479.         mov     ebx, e3c59x_device_id_str
  480.         call    e3c59x_print_hex
  481.         mov     esi, e3c59x_device_str
  482.         call    sys_msg_board_str
  483.         mov     ax, [pci_data]
  484.         mov     cl, 2
  485.         mov     ebx, e3c59x_vendor_id_str
  486.         call    e3c59x_print_hex
  487.         mov     esi, e3c59x_vendor_str
  488.         call    sys_msg_board_str
  489. ; print io address
  490.         mov     ax, [io_addr]
  491.         mov     ebx, e3c59x_io_addr_str
  492.         mov     cl, 2
  493.         call    e3c59x_print_hex
  494.         mov     esi, e3c59x_io_info_str
  495.         call    sys_msg_board_str
  496. ; print MAC address
  497.         mov     ebx, e3c59x_mac_addr_str
  498.         xor     ecx, ecx
  499. .mac_loop:
  500.         push    ecx
  501.         mov     al, [node_addr+ecx]
  502.         mov     cl, 1
  503.         call    e3c59x_print_hex
  504.         inc     ebx
  505.         pop     ecx
  506.         inc     cl
  507.         cmp     cl, 6
  508.         jne     .mac_loop
  509.         mov     esi, e3c59x_mac_info_str
  510.         call    sys_msg_board_str
  511. ; print link type
  512.         mov     esi, e3c59x_link_type_str
  513.         call    sys_msg_board_str
  514.         xor     eax, eax
  515.         bsr     ax, word [e3c59x_link_type]
  516.         jz      @f
  517.         sub     ax, 4
  518. @@:
  519.         mov     esi, [e3c59x_link_str+eax*4]
  520.         call    sys_msg_board_str
  521.         mov     esi, e3c59x_new_line_str
  522.         call    sys_msg_board_str
  523.         popad
  524.         ret
  525.  
  526. ;***************************************************************************
  527. ;   Function
  528. ;      e3c59x_print_hex
  529. ;   Description
  530. ;      prints a hexadecimal value
  531. ;   Parameters
  532. ;      eax - value to be printed out
  533. ;      ebx - where to print
  534. ;       cl - value size (1, 2, 4)
  535. ;   Return value
  536. ;      ebx - end address after the print
  537. ;   Destroyed registers
  538. ;      eax, ebx
  539. ;
  540. ;***************************************************************************
  541.         align 4
  542. e3c59x_print_hex:
  543.         cmp     cl, 1
  544.         je      .print_byte
  545.         cmp     cl, 2
  546.         jz      .print_word
  547. .print_dword:
  548.         push    eax
  549.         bswap   eax
  550.         xchg    ah, al
  551.         call    .print_word
  552.         pop     eax
  553. .print_word:
  554.         push    eax
  555.         xchg    ah, al
  556.         call    .print_byte
  557.         pop     eax
  558. .print_byte:
  559.         movzx   eax, al
  560.         push    eax
  561.         and     al, 0xf0
  562.         shr     al, 4
  563.         mov     al, byte [eax+e3c59x_charset]
  564.         mov     [ebx], al
  565.         inc     ebx
  566.         pop     eax
  567.         and     al, 0x0f
  568.         mov     al, byte [eax+e3c59x_charset]
  569.         mov     [ebx], al
  570.         inc     ebx
  571.         ret
  572. end if ; defined E3C59X_DEBUG
  573.  
  574. ;***************************************************************************
  575. ;   Function
  576. ;      e3c59x_try_link_detect
  577. ;   Description
  578. ;      e3c59x_try_link_detect checks if link exists
  579. ;   Parameters
  580. ;      ebp - io_addr
  581. ;   Return value
  582. ;      al - 0 ; no link detected
  583. ;      al - 1 ; link detected
  584. ;   Destroyed registers
  585. ;      eax, ebx, ecx, edx, edi, esi
  586. ;
  587. ;***************************************************************************
  588.         align 4
  589. e3c59x_try_link_detect:
  590. ; download self-directed packet
  591.         mov     edi, node_addr
  592.         mov     bx, 0x0608 ; packet type
  593.         mov     esi, e3c59x_self_directed_packet
  594.         mov     ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes
  595.         call    dword [e3c59x_transmit_function]
  596. ; switch to register window 5
  597.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  598.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
  599.         out     dx, ax
  600. ; program RxFilter for promiscuous operation
  601.         mov     ax, (10000b shl 11)
  602.         lea     edx, [ebp+E3C59X_REG_RX_FILTER]
  603.         in      al, dx
  604.         or      al, 1111b
  605.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  606.         out     dx, ax
  607. ; switch to register window 4
  608.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
  609.         out     dx, ax
  610. ; check loop
  611.         xor     ebx, ebx
  612.         mov     ecx, 0xffff ; 65535 tries
  613. .loop:
  614.         push    ecx ebx
  615.         call    dword [e3c59x_receive_function]
  616.         pop     ebx ecx
  617.         test    al, al
  618.         jnz     .finish
  619. .no_packet_received:
  620. ; switch to register window 4
  621.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  622.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
  623.         out     dx, ax
  624. ; read linkbeatdetect
  625.         lea     edx, [ebp+E3C59X_REG_MEDIA_STATUS]
  626.         in      ax, dx
  627.         test    ah, 1000b ; test linkBeatDetect
  628.         jnz     .link_detected
  629.         xor     al, al
  630.         jmp     .finish
  631. .link_detected:
  632. ; test carrierSense
  633.         test    al, 100000b
  634.         jz      .no_carrier_sense
  635.         inc     ebx
  636. .no_carrier_sense:
  637.         dec     ecx
  638.         jns     .loop
  639. ; assume the link is good if 0 < ebx < 25 %
  640.         test    ebx, ebx
  641.         setnz   al
  642.         jz      .finish
  643.         cmp     ebx, 16384 ; 25%
  644.         setb    al
  645. .finish:
  646. if defined E3C59X_DEBUG
  647.         test    al, al
  648.         jz      @f
  649.         or      byte [e3c59x_link_type+1], 100b
  650. @@:
  651. end if ; defined E3C59X_DEBUG
  652.         ret
  653.  
  654. ;***************************************************************************
  655. ;   Function
  656. ;      e3c59x_try_phy
  657. ;   Description
  658. ;      e3c59x_try_phy checks the auto-negotiation function
  659. ;      in the PHY at PHY index. It can also be extended to
  660. ;      include link detection for non-IEEE 802.3u
  661. ;      auto-negotiation devices, for instance the BCM5000.
  662. ;   Parameters
  663. ;       ah - PHY index
  664. ;      ebp - io_addr
  665. ;   Return value
  666. ;      al - 0 link is auto-negotiated
  667. ;      al - 1 no link is auto-negotiated
  668. ;   Destroyed registers
  669. ;       eax, ebx, ecx, edx, esi
  670. ;
  671. ;***************************************************************************
  672.         align 4
  673. e3c59x_try_phy:
  674.         mov     al, E3C59X_REG_MII_BMCR
  675.         push    eax
  676.         call    e3c59x_mdio_read ; returns with window #4
  677.         or      ah, 0x80 ; software reset
  678.         mov     ebx, eax
  679.         pop     eax
  680.         push    eax
  681.         call    e3c59x_mdio_write ; returns with window #4
  682. ; wait for reset to complete
  683.         mov     esi, 2000 ; 2000ms = 2s
  684.         call    delay_ms
  685.         pop     eax
  686.         push    eax
  687.         call    e3c59x_mdio_read ; returns with window #4
  688.         test    ah, 0x80
  689.         jnz     .fail_finish
  690.         pop     eax
  691.         push    eax
  692. ; wait for a while after reset
  693.         mov     esi, 20 ; 20ms
  694.         call    delay_ms
  695.         pop     eax
  696.         push    eax
  697.         mov     al, E3C59X_REG_MII_BMSR
  698.         call    e3c59x_mdio_read ; returns with window #4
  699.         test    al, 1 ; extended capability supported?
  700.         jz      .no_ext_cap
  701. ; auto-neg capable?
  702.         test    al, 1000b
  703.         jz      .fail_finish ; not auto-negotiation capable
  704. ; auto-neg complete?
  705.         test    al, 100000b
  706.         jnz     .auto_neg_ok
  707. ; restart auto-negotiation
  708.         pop     eax
  709.         push    eax
  710.         mov     al, E3C59X_REG_MII_ANAR
  711.         push    eax
  712.         call    e3c59x_mdio_read ; returns with window #4
  713.         or      ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX
  714.         mov     ebx, eax
  715.         pop     eax
  716.         call    e3c59x_mdio_write ; returns with window #4
  717.         pop     eax
  718.         push    eax
  719.         call    e3c59x_mdio_read ; returns with window #4
  720.         mov     ebx, eax
  721.         or      bh, 10010b ; restart auto-negotiation
  722.         pop     eax
  723.         push    eax
  724.         call    e3c59x_mdio_write ; returns with window #4
  725.         mov     esi, 4000 ; 4000ms = 4 seconds
  726.         call    delay_ms
  727.         pop     eax
  728.         push    eax
  729.         mov     al, E3C59X_REG_MII_BMSR
  730.         call    e3c59x_mdio_read ; returns with window #4
  731.         test    al, 100000b ; auto-neg complete?
  732.         jnz     .auto_neg_ok
  733.         jmp     .fail_finish
  734. .auto_neg_ok:
  735. ; compare advertisement and link partner ability registers
  736.         pop     eax
  737.         push    eax
  738.         mov     al, E3C59X_REG_MII_ANAR
  739.         call    e3c59x_mdio_read ; returns with window #4
  740.         xchg    eax, [esp]
  741.         mov     al, E3C59X_REG_MII_ANLPAR
  742.         call    e3c59x_mdio_read ; returns with window #4
  743.         pop     ebx
  744.         and     eax, ebx
  745.         and     eax, 1111100000b
  746.         push    eax
  747. if defined E3C59X_DEBUG
  748.         mov     word [e3c59x_link_type], ax
  749. end if ; defined E3C59X_DEBUG
  750. ; switch to register window 3
  751.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  752.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  753.         out     dx, ax
  754. ; set full-duplex mode
  755.         lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
  756.         in      ax, dx
  757.         and     ax, not 0x120 ; clear full duplex and flow control
  758.         pop     ebx
  759.         test    ebx, (1010b shl 5) ; check for full-duplex
  760.         jz      .half_duplex
  761.         or      ax, 0x120 ; set full duplex and flow control
  762. .half_duplex:
  763.         out     dx, ax
  764.         mov     al, 1
  765.         ret
  766. .no_ext_cap:
  767. ; not yet implemented BCM5000
  768. .fail_finish:
  769.         pop     eax
  770.         xor     al, al
  771.         ret
  772.  
  773. ;***************************************************************************
  774. ;   Function
  775. ;      e3c59x_try_mii
  776. ;   Description
  777. ;      e3c59x_try_MII checks the on-chip auto-negotiation logic
  778. ;      or an off-chip MII PHY, depending upon what is set in
  779. ;      xcvrSelect by the caller.
  780. ;      It exits when it finds the first device with a good link.
  781. ;   Parameters
  782. ;      ebp - io_addr
  783. ;   Return value
  784. ;      al - 0
  785. ;      al - 1
  786. ;   Destroyed registers
  787. ;      eax, ebx, ecx, edx, esi
  788. ;
  789. ;***************************************************************************
  790.         align 4
  791. e3c59x_try_mii:
  792. ; switch to register window 3
  793.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  794.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  795.         out     dx, ax
  796.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  797.         in      eax, dx
  798.         and     eax, (1111b shl 20)
  799.         cmp     eax, (1000b shl 20) ; is auto-negotiation set?
  800.         jne     .mii_device
  801. ; auto-negotiation is set
  802. ; switch to register window 4
  803.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  804.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
  805.         out     dx, ax
  806. ; PHY==24 is the on-chip auto-negotiation logic
  807. ; it supports only 10base-T and 100base-TX
  808.         mov     ah, 24
  809.         call    e3c59x_try_phy
  810.         test    al, al
  811.         jz      .fail_finish
  812.         mov     cl, 24
  813.         jmp     .check_preamble
  814. .mii_device:
  815.         cmp     eax, (0110b shl 20)
  816.         jne     .fail_finish
  817.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  818.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
  819.         out     dx, ax
  820.         lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
  821.         in      ax, dx
  822.         and     al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA)
  823.         cmp     al, (1 shl E3C59X_BIT_MGMT_DATA)
  824.         je      .serch_for_phy
  825.         xor     al, al
  826.         ret
  827. .serch_for_phy:
  828. ; search for PHY
  829.         mov     cl, 31
  830. .search_phy_loop:
  831.         cmp     cl, 24
  832.         je      .next_phy
  833.         mov     ah, cl ; ah = phy
  834.         mov     al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register
  835.         push    ecx
  836.         call    e3c59x_mdio_read
  837.         pop     ecx
  838.         test    ax, ax
  839.         jz      .next_phy
  840.         cmp     ax, 0xffff
  841.         je      .next_phy
  842.         mov     ah, cl ; ah = phy
  843.         push    ecx
  844.         call    e3c59x_try_phy
  845.         pop     ecx
  846.         test    al, al
  847.         jnz     .check_preamble
  848. .next_phy:
  849.         dec     cl
  850.         jns     .search_phy_loop
  851. .fail_finish:
  852.         xor     al, al
  853.         ret
  854. ; epilog
  855. .check_preamble:
  856.         push    eax ; eax contains the return value of e3c59x_try_phy
  857. ; check hard coded preamble forcing
  858.         movzx   eax, byte [e3c59x_ver_id]
  859.         test    word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE
  860.         setnz   [e3c59x_preamble] ; force preamble
  861.         jnz     .finish
  862. ; check mii for preamble suppression
  863.         mov     ah, cl
  864.         mov     al, E3C59X_REG_MII_BMSR
  865.         call    e3c59x_mdio_read
  866.         test    al, 1000000b ; preamble suppression?
  867.         setz    [e3c59x_preamble] ; no
  868. .finish:
  869.         pop     eax
  870.         ret
  871.  
  872. ;***************************************************************************
  873. ;   Function
  874. ;      e3c59x_test_packet
  875. ;   Description
  876. ;      e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port
  877. ;   Parameters
  878. ;      ebp - io_addr
  879. ;   Return value
  880. ;      al - 0
  881. ;      al - 1
  882. ;   Destroyed registers
  883. ;      eax, ebx, ecx, edx, edi, esi
  884. ;
  885. ;***************************************************************************
  886.         align 4
  887. e3c59x_test_packet:
  888. ; switch to register window 3
  889.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  890.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  891.         out     dx, ax
  892. ; set fullDuplexEnable in MacControl register
  893.         lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
  894.         in      ax, dx
  895.         or      ax, 0x120
  896.         out     dx, ax
  897. ; switch to register window 5
  898.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  899.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
  900.         out     dx, ax
  901. ; set RxFilter to enable individual address matches
  902.         mov     ax, (10000b shl 11)
  903.         lea     edx, [ebp+E3C59X_REG_RX_FILTER]
  904.         in      al, dx
  905.         or      al, 1
  906.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  907.         out     dx, ax
  908. ; issue RxEnable and TxEnable
  909.         call    e3c59x_rx_reset
  910.         call    e3c59x_tx_reset
  911. ; download a self-directed test packet
  912.         mov     edi, node_addr
  913.         mov     bx, 0x0608 ; packet type
  914.         mov     esi, e3c59x_self_directed_packet
  915.         mov     ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes
  916.         call    dword [e3c59x_transmit_function]
  917. ; wait for 2s
  918.         mov     esi, 2000 ; 2000ms = 2s
  919.         call    delay_ms
  920. ; check if self-directed packet is received
  921.         call    dword [e3c59x_receive_function]
  922.         test    al, al
  923.         jnz     .finish
  924. ; switch to register window 3
  925.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  926.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  927.         out     dx, ax
  928. ; clear fullDuplexEnable in MacControl register
  929.         lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
  930.         in      ax, dx
  931.         and     ax, not 0x120
  932.         out     dx, ax
  933.         xor     al, al
  934. .finish:
  935.         ret
  936.  
  937. ;***************************************************************************
  938. ;   Function
  939. ;      e3c59x_try_loopback
  940. ;   Description
  941. ;      tries a loopback packet for 10BASE2 or AUI port
  942. ;   Parameters
  943. ;      al -  0: 10Mbps AUI connector
  944. ;            1: 10BASE-2
  945. ;      ebp - io_addr
  946. ;   Return value
  947. ;      al - 0
  948. ;      al - 1
  949. ;   Destroyed registers
  950. ;      eax, ebx, ecx, edx, edi, esi
  951. ;
  952. ;***************************************************************************
  953.         align 4
  954. e3c59x_try_loopback:
  955.         push    eax
  956. ; switch to register window 3
  957.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  958.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  959.         out     dx, ax
  960.         pop     eax
  961.         push    eax
  962. if defined E3C59X_DEBUG
  963.         mov     bl, al
  964.         inc     bl
  965.         shl     bl, 3
  966.         or      byte [e3c59x_link_type+1], bl
  967. end if ; defined E3C59X_DEBUG
  968.         test    al, al ; aui or coax?
  969.         jz      .complete_loopback
  970. ; enable 100BASE-2 DC-DC converter
  971.         mov     ax, (10b shl 11) ; EnableDcConverter
  972.         out     dx, ax
  973. .complete_loopback:
  974.         mov     cl, 2 ; give a port 3 chances to complete a loopback
  975. .next_try:
  976.         push    ecx
  977.         call    e3c59x_test_packet
  978.         pop     ecx
  979.         test    al, al
  980.         jnz     .finish
  981.         dec     cl
  982.         jns     .next_try
  983. .finish:
  984.         xchg    eax, [esp]
  985.         test    al, al
  986.         jz      .aui_finish
  987. ; issue DisableDcConverter command
  988.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  989.         mov     ax, (10111b shl 11)
  990.         out     dx, ax
  991. .aui_finish:
  992.         pop     eax ; al contains the result of operation
  993. if defined E3C59X_DEBUG
  994.         test    al, al
  995.         jnz     @f
  996.         and     byte [e3c59x_link_type+1], not 11000b
  997. @@:
  998. end if ; defined E3C59X_DEBUG
  999.         ret
  1000.  
  1001. ;***************************************************************************
  1002. ;   Function
  1003. ;      e3c59x_set_available_media
  1004. ;   Description
  1005. ;      sets the first available media
  1006. ;   Parameters
  1007. ;      ebp - io_addr
  1008. ;   Return value
  1009. ;      al - 0
  1010. ;      al - 1
  1011. ;   Destroyed registers
  1012. ;      eax, edx
  1013. ;
  1014. ;***************************************************************************
  1015.         align 4
  1016. e3c59x_set_available_media:
  1017. ; switch to register window 3
  1018.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1019.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  1020.         out     dx, ax
  1021.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  1022.         in      eax, dx
  1023.         push    eax
  1024.         lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
  1025.         in      ax, dx
  1026.         test    al, 10b
  1027.         jz      @f
  1028. ; baseTXAvailable
  1029.         pop     eax
  1030.         and     eax, not (1111b shl 20)
  1031.         or      eax, (100b shl 20)
  1032. if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD
  1033.         mov     word [e3c59x_link_type], (1 shl 8)
  1034. else if defined E3C59X_DEBUG
  1035.         mov     word [e3c59x_link_type], (1 shl 7)
  1036. end if
  1037.         jmp     .set_media
  1038. @@:
  1039.         test    al, 100b
  1040.         jz      @f
  1041. ; baseFXAvailable
  1042.         pop     eax
  1043.         and     eax, not (1111b shl 20)
  1044.         or      eax, (101b shl 20)
  1045. if defined E3C59X_DEBUG
  1046.         mov     word [e3c59x_link_type], (1 shl 10)
  1047. end if
  1048.         jmp     .set_media
  1049. @@:
  1050.         test    al, 1000000b
  1051.         jz      @f
  1052. ; miiDevice
  1053.         pop     eax
  1054.         and     eax, not (1111b shl 20)
  1055.         or      eax, (0110b shl 20)
  1056. if defined E3C59X_DEBUG
  1057.         mov     word [e3c59x_link_type], (1 shl 13)
  1058. end if
  1059.         jmp     .set_media
  1060. @@:
  1061.         test    al, 1000b
  1062.         jz      @f
  1063. .set_default:
  1064. ; 10bTAvailable
  1065.         pop     eax
  1066.         and     eax, not (1111b shl 20)
  1067. if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD
  1068.         mov     word [e3c59x_link_type], (1 shl 6)
  1069. else if defined E3C59X_DEBUG
  1070.         mov     word [e3c59x_link_type], (1 shl 5)
  1071. end if ; E3C59X_FORCE_FD
  1072.         jmp     .set_media
  1073. @@:
  1074.         test    al, 10000b
  1075.         jz      @f
  1076. ; coaxAvailable
  1077.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1078.         mov     ax, (10b shl 11) ; EnableDcConverter
  1079.         out     dx, ax
  1080.         pop     eax
  1081.         and     eax, not (1111b shl 20)
  1082.         or      eax, (11b shl 20)
  1083. if defined E3C59X_DEBUG
  1084.         mov     word [e3c59x_link_type], (1 shl 12)
  1085. end if ; defined E3C59X_DEBUG
  1086.         jmp     .set_media
  1087. @@:
  1088.         test    al, 10000b
  1089.         jz      .set_default
  1090. ; auiAvailable
  1091.         pop     eax
  1092.         and     eax, not (1111b shl 20)
  1093.         or      eax, (1 shl 20)
  1094. if defined E3C59X_DEBUG
  1095.         mov     word [e3c59x_link_type], (1 shl 11)
  1096. end if ; defined E3C59X_DEBUG
  1097. .set_media:
  1098.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  1099.         out     dx, eax
  1100. if defined E3C59X_FORCE_FD
  1101. ; set fullDuplexEnable in MacControl register
  1102.         lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
  1103.         in      ax, dx
  1104.         or      ax, 0x120
  1105.         out     dx, ax
  1106. end if ; E3C59X_FORCE_FD
  1107.         mov     al, 1
  1108.         ret
  1109.  
  1110. ;***************************************************************************
  1111. ;   Function
  1112. ;      e3c59x_set_active_port
  1113. ;   Description
  1114. ;      It selects the media port (transceiver) to be used
  1115. ;   Parameters:
  1116. ;      ebp - io_addr
  1117. ;   Return value:
  1118. ;   Destroyed registers
  1119. ;      eax, ebx, ecx, edx, edi, esi
  1120. ;
  1121. ;***************************************************************************
  1122.         align 4
  1123. e3c59x_set_active_port:
  1124. ; switch to register window 3
  1125.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1126.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  1127.         out     dx, ax
  1128.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  1129.         in      eax, dx
  1130.         test    eax, (1 shl 24) ; check if autoselect enable
  1131.         jz      .set_first_available_media
  1132. ; check 100BASE-TX and 10BASE-T
  1133.         lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
  1134.         in      ax, dx
  1135.         test    al, 1010b ; check whether 100BASE-TX or 10BASE-T available
  1136.         jz      .mii_device ; they are not available
  1137. ; set auto-negotiation
  1138.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  1139.         in      eax, dx
  1140.         and     eax, not (1111b shl 20)
  1141.         or      eax, (1000b shl 20)
  1142.         out     dx, eax
  1143.         call    e3c59x_try_mii
  1144.         test    al, al
  1145.         jz      .mii_device
  1146.         ret
  1147. .mii_device:
  1148. ; switch to register window 3
  1149.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1150.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  1151.         out     dx, ax
  1152. ; check for off-chip mii device
  1153.         lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
  1154.         in      ax, dx
  1155.         test    al, 1000000b ; check miiDevice
  1156.         jz      .base_fx
  1157.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  1158.         in      eax, dx
  1159.         and     eax, not (1111b shl 20)
  1160.         or      eax, (0110b shl 20) ; set MIIDevice
  1161.         out     dx, eax
  1162.         call    e3c59x_try_mii
  1163.         test    al, al
  1164.         jz      .base_fx
  1165.         ret
  1166. .base_fx:
  1167. ; switch to register window 3
  1168.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1169.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  1170.         out     dx, ax
  1171. ; check for 100BASE-FX
  1172.         lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
  1173.         in      ax, dx ; read media option register
  1174.         test    al, 100b ; check 100BASE-FX
  1175.         jz      .aui_enable
  1176.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  1177.         in      eax, dx
  1178.         and     eax, not (1111b shl 20)
  1179.         or      eax, (0101b shl 20) ; set 100base-FX
  1180.         out     dx, eax
  1181.         call    e3c59x_try_link_detect
  1182.         test    al, al
  1183.         jz      .aui_enable
  1184.         ret
  1185. .aui_enable:
  1186. ; switch to register window 3
  1187.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1188.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  1189.         out     dx, ax
  1190. ; check for 10Mbps AUI connector
  1191.         lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
  1192.         in      ax, dx ; read media option register
  1193.         test    al, 100000b ; check 10Mbps AUI connector
  1194.         jz      .coax_available
  1195.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  1196.         in      eax, dx
  1197.         and     eax, not (1111b shl 20)
  1198.         or      eax, (0001b shl 20) ; set 10Mbps AUI connector
  1199.         out     dx, eax
  1200.         xor     al, al ; try 10Mbps AUI connector
  1201.         call    e3c59x_try_loopback
  1202.         test    al, al
  1203.         jz      .coax_available
  1204.         ret
  1205. .coax_available:
  1206. ; switch to register window 3
  1207.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1208.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
  1209.         out     dx, ax
  1210. ; check for coaxial 10BASE-2 port
  1211.         lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
  1212.         in      ax, dx ; read media option register
  1213.         test    al, 10000b ; check 10BASE-2
  1214.         jz      .set_first_available_media
  1215.         lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
  1216.         in      eax, dx
  1217.         and     eax, not (1111b shl 20)
  1218.         or      eax, (0011b shl 20) ; set 10BASE-2
  1219.         out     dx, eax
  1220.         mov     al, 1
  1221.         call    e3c59x_try_loopback
  1222.         test    al, al
  1223.         jz      .set_first_available_media
  1224.         ret
  1225. .set_first_available_media:
  1226.         jmp    e3c59x_set_available_media
  1227.  
  1228. ;***************************************************************************
  1229. ;   Function
  1230. ;      e3c59x_wake_up
  1231. ;   Description
  1232. ;      set the power state to D0
  1233. ;   Destroyed registers
  1234. ;      eax, ebx, ecx, edx, edi, esi
  1235. ;
  1236. ;***************************************************************************
  1237.         align 4
  1238. e3c59x_wake_up:
  1239. ; wake up - we directly do it by programming PCI
  1240. ; check if the device is power management capable
  1241.         mov     al, 2
  1242.         mov     ah, [pci_bus]
  1243.         mov     bl, PCI_REG_STATUS
  1244.         mov     bh, [pci_dev]
  1245.         push    eax ebx
  1246.         call    pci_read_reg
  1247.         test    al, 10000b ; is there "new capabilities" linked list?
  1248.         pop     ebx eax
  1249.         jz      .device_awake
  1250. ; search for power management register
  1251.         mov     al, 1
  1252.         mov     bl, PCI_REG_CAP_PTR
  1253.         push    eax ebx
  1254.         call    pci_read_reg
  1255.         mov     cl, al
  1256.         cmp     cl, 0x3f
  1257.         pop     ebx eax
  1258.         jbe     .device_awake
  1259. ; traverse the list
  1260.         mov     al, 2
  1261. .pm_loop:
  1262.         mov     bl, cl
  1263.         push    eax ebx
  1264.         call    pci_read_reg
  1265.         cmp     al, 1
  1266.         je      .set_pm_state
  1267.         test    ah, ah
  1268.         mov     cl, ah
  1269.         pop     ebx eax
  1270.         jnz     .pm_loop
  1271.         jmp     .device_awake
  1272. ; waku up the device if necessary
  1273. .set_pm_state:
  1274.         pop     ebx eax
  1275.         add     bl, PCI_REG_PM_CTRL
  1276.         push    eax ebx
  1277.         call    pci_read_reg
  1278.         mov     cx, ax
  1279.         test    cl, 3
  1280.         pop     ebx eax
  1281.         jz      .device_awake
  1282.         and     cl, not 11b ; set state to D0
  1283.         call    pci_write_reg
  1284. .device_awake:
  1285.         ret
  1286.  
  1287. ;***************************************************************************
  1288. ;   Function
  1289. ;      e3c59x_probe
  1290. ;   Description
  1291. ;      Searches for an ethernet card, enables it and clears the rx buffer
  1292. ;      If a card was found, it enables the ethernet -> TCPIP link
  1293. ;   Destroyed registers
  1294. ;      eax, ebx, ecx, edx, edi, esi
  1295. ;
  1296. ;***************************************************************************
  1297.         align 4
  1298. e3c59x_probe:
  1299.         movzx   ebp, word [io_addr]
  1300.         mov     al, 2
  1301.         mov     ah, [pci_bus]
  1302.         mov     bh, [pci_dev]
  1303.         mov     bl, PCI_REG_COMMAND
  1304.         push    ebp eax ebx
  1305.         call    pci_read_reg
  1306.         mov     cx, ax
  1307.         or      cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO)
  1308.         and     cl, not (1 shl PCI_BIT_MMIO)
  1309.         pop     ebx eax
  1310.         call    pci_write_reg
  1311. ; wake up the card
  1312.         call    e3c59x_wake_up
  1313.         pop     ebp
  1314. ; get chip version
  1315.         mov     ax, [pci_data+2]
  1316.         mov     ecx, E3C59X_HW_VERSIONS_SIZE/4-1
  1317. .chip_ver_loop:
  1318.         cmp     ax, [e3c59x_hw_versions+ecx*4]
  1319.         jz      .chip_ver_found
  1320.         dec     ecx
  1321.         jns     .chip_ver_loop
  1322.         xor     ecx, ecx
  1323. .chip_ver_found:
  1324.         mov     [e3c59x_ver_id], cl
  1325.         test    word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM
  1326.         setnz   [e3c59x_has_hwcksm]
  1327. ; set pci latency for vortex cards
  1328.         test    word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX
  1329.         jz      .not_vortex
  1330.         mov     cx, 11111000b ; 248 = max latency
  1331.         mov     al, 1
  1332.         mov     ah, [pci_bus]
  1333.         mov     bl, PCI_REG_LATENCY
  1334.         mov     bh, [pci_dev]
  1335.         call    pci_write_reg
  1336. .not_vortex:
  1337. ; set RX/TX functions
  1338.         mov     ax, E3C59X_EEPROM_REG_CAPABILITIES
  1339.         call    e3c59x_read_eeprom
  1340.         test    al, 100000b ; full bus master?
  1341.         setnz   [e3c59x_full_bus_master]
  1342.         jnz     .boomerang_func
  1343.         mov     dword [e3c59x_transmit_function], e3c59x_vortex_transmit
  1344.         mov     dword [e3c59x_receive_function], e3c59x_vortex_poll
  1345.         jmp     @f
  1346. .boomerang_func: ; full bus master, so use boomerang functions
  1347.         mov     dword [e3c59x_transmit_function], e3c59x_boomerang_transmit
  1348.         mov     dword [e3c59x_receive_function], e3c59x_boomerang_poll
  1349. @@:
  1350. ; read MAC from eeprom
  1351.         mov     ecx, 2
  1352. .mac_loop:
  1353.         lea     ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx]
  1354.         call    e3c59x_read_eeprom
  1355.         xchg    ah, al ; htons
  1356.         mov     [node_addr+ecx*2], ax
  1357.         dec     ecx
  1358.         jns     .mac_loop
  1359.         test    byte [e3c59x_full_bus_master], 0xff
  1360.         jz      .set_preamble
  1361. ; switch to register window 2
  1362.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1363.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+2
  1364.         out     dx, ax
  1365. ; activate xcvr by setting some magic bits
  1366.         lea     edx, [ebp+E3C59X_REG_RESET_OPTIONS]
  1367.         in      ax, dx
  1368.         and     ax, not 0x4010
  1369.         movzx   ebx, byte [e3c59x_ver_id]
  1370.         test    word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR
  1371.         jz      @f
  1372.         or      al, 0x10
  1373. @@:
  1374.         test    word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR
  1375.         jz      @f
  1376.         or      ah, 0x40
  1377. @@:
  1378.         out     dx, ax
  1379. .set_preamble:
  1380. ; use preamble as default
  1381.         mov     byte [e3c59x_preamble], 1 ; enable preamble
  1382.  
  1383. ;***************************************************************************
  1384. ;   Function
  1385. ;      e3c59x_reset
  1386. ;   Description
  1387. ;      Place the chip (ie, the ethernet card) into a virgin state
  1388. ;   Destroyed registers
  1389. ;      eax, ebx, ecx, edx, edi, esi
  1390. ;
  1391. ;***************************************************************************
  1392. e3c59x_reset:
  1393. ; issue global reset
  1394.         call    e3c59x_global_reset
  1395. ; disable interrupts
  1396.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1397.         mov     ax, (1110b shl 11)
  1398.         out     dx, ax
  1399. ; enable Statistics
  1400.         mov     ax, (10101b shl 11)
  1401.         out     dx, ax
  1402. ; set indication
  1403.         mov     ax, (1111b shl 11) or 0x6c6
  1404.         out     dx, ax
  1405. ; acknowledge (clear) every interrupt indicator
  1406.         mov     ax, (1101b shl 11) or 0x661
  1407.         out     dx, ax
  1408. ; switch to register window 2
  1409.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+2
  1410.         out     dx, ax
  1411. ; write MAC addres back into the station address registers
  1412.         lea     edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO]
  1413.         mov     esi, node_addr
  1414.         cld
  1415.         outsw
  1416.         add     edx, 2
  1417.         outsw
  1418.         add     edx, 2
  1419.         outsw
  1420.         add     edx, 2
  1421. ; clear station mask
  1422.         xor     eax, eax
  1423.         out     dx, ax
  1424.         add     edx, 2
  1425.         out     dx, ax
  1426.         add     edx, 2
  1427.         out     dx, ax
  1428. ; switch to register window 6
  1429.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1430.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+6
  1431.         out     dx, ax
  1432. ; clear all statistics by reading
  1433.         lea     edx, [ebp+E3C59X_REG_CARRIER_LOST]
  1434.         mov     cl, 9
  1435. .stat_clearing_loop:
  1436.         in      al, dx
  1437.         inc     edx
  1438.         dec     cl
  1439.         jns     .stat_clearing_loop
  1440.         in      ax, dx
  1441.         add     dx, 2
  1442.         in      ax, dx
  1443. ; switch to register window 4
  1444.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1445.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
  1446.         out     dx, ax
  1447. ; clear BadSSD
  1448.         lea     edx, [ebp+E3C59X_REG_BAD_SSD]
  1449.         in      al, dx
  1450. ; clear extra statistics bit in NetworkDiagnostic
  1451.         lea     edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC]
  1452.         in      ax, dx
  1453.         or      ax,  0x0040
  1454.         out     dx, ax
  1455. ; SetRxEarlyThreshold
  1456.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1457.         mov     ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2)
  1458.         out     dx, ax
  1459.         test    byte [e3c59x_full_bus_master], 0xff
  1460.         jz      .skip_boomerang_setting
  1461. ; set upRxEarlyEnable
  1462.         lea     edx, [ebp+E3C59X_REG_DMA_CTRL]
  1463.         in      eax, dx
  1464.         or      eax, 0x20
  1465.         out     dx, eax
  1466. ; TxFreeThreshold
  1467.         lea     edx, [ebp+E3C59X_REG_TX_FREE_THRESH]
  1468.         mov     al, (E3C59X_MAX_ETH_PKT_SIZE / 256)
  1469.         out     dx, al
  1470. ; program DnListPtr
  1471.         lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
  1472.         xor     eax, eax
  1473.         out     dx, eax
  1474. .skip_boomerang_setting:
  1475. ; initialization
  1476.         call    e3c59x_rx_reset
  1477.         call    e3c59x_tx_reset
  1478.         call    e3c59x_set_active_port
  1479.         call    e3c59x_rx_reset
  1480.         call    e3c59x_tx_reset
  1481. ; switch to register window 5
  1482.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1483.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
  1484.         out     dx, ax
  1485. ; program RxFilter for promiscuous operation
  1486.         mov     ax, (10000b shl 11)
  1487.         lea     edx, [ebp+E3C59X_REG_RX_FILTER]
  1488.         in      al, dx
  1489.         or      al, 1111b
  1490.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1491.         out     dx, ax
  1492. ; switch to register window 4
  1493.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
  1494.         out     dx, ax
  1495. ; wait for linkDetect
  1496.         lea     edx, [ebp+E3C59X_REG_MEDIA_STATUS]
  1497.         mov     cl, 20 ; wait for max 2s
  1498.         mov     esi, 100 ; 100ms
  1499. .link_detect_loop:
  1500.         call    delay_ms
  1501.         in      ax, dx
  1502.         test    ah, 1000b ; linkDetect
  1503.         jnz     @f
  1504.         dec     cl
  1505.         jnz     .link_detect_loop
  1506. @@:
  1507. ; Indicate that we have successfully reset the card
  1508.         mov     eax, [pci_data]
  1509.         mov     [eth_status], eax
  1510. if defined E3C59X_DEBUG
  1511.         call    e3c59x_debug
  1512. end if ; defined E3C59X_DEBUG
  1513.         ret
  1514.  
  1515. ;***************************************************************************
  1516. ;   Function
  1517. ;      e3c59x_global_reset
  1518. ;   Description
  1519. ;      resets the device
  1520. ;   Parameters:
  1521. ;      ebp - io_addr
  1522. ;   Return value:
  1523. ;   Destroyed registers
  1524. ;      ax, ecx, edx, esi
  1525. ;
  1526. ;***************************************************************************
  1527.         align 4
  1528. e3c59x_global_reset:
  1529. ; GlobalReset
  1530.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1531.         xor     eax, eax
  1532. ;       or      al, 0x14
  1533.         out     dx, ax
  1534. ; wait for GlobalReset to complete
  1535.         mov     ecx, 64000
  1536. .global_reset_loop:
  1537.         in      ax, dx
  1538.         test    ah, 10000b ; check CmdInProgress
  1539.         jz      .finish
  1540.         dec     ecx
  1541.         jnz     .global_reset_loop
  1542. .finish:
  1543. ; wait for 2 seconds for NIC to boot
  1544.         mov     esi, 2000 ; 2000ms = 2s
  1545.         push    ebp
  1546.         call    delay_ms
  1547.         pop     ebp
  1548.         ret
  1549.  
  1550. ;***************************************************************************
  1551. ;   Function
  1552. ;      e3c59x_tx_reset
  1553. ;   Description
  1554. ;      resets and enables transmitter engine
  1555. ;   Parameters:
  1556. ;      ebp - io_addr
  1557. ;   Return value:
  1558. ;   Destroyed registers
  1559. ;      ax, ecx, edx
  1560. ;
  1561. ;***************************************************************************
  1562.         align 4
  1563. e3c59x_tx_reset:
  1564. ; TxReset
  1565.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1566.         mov     ax, (01011b shl 11)
  1567.         out     dx, ax
  1568. ; wait for TxReset to complete
  1569.         mov     ecx, 2000
  1570. .tx_reset_loop:
  1571.         in      ax, dx
  1572.         test    ah, 10000b ; check CmdInProgress
  1573.         jz      .tx_enable
  1574.         dec     ecx
  1575.         jns     .tx_reset_loop
  1576.         test    byte [e3c59x_full_bus_master], 0xff
  1577.         jz      .tx_enable
  1578. ; init last_dpd
  1579.         mov     dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE
  1580.         mov     dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE
  1581. .tx_enable:
  1582.         mov     ax, (01001b shl 11) ; TxEnable
  1583.         out     dx, ax
  1584.         ret
  1585.  
  1586. ;***************************************************************************
  1587. ;   Function
  1588. ;      e3c59x_rx_reset
  1589. ;   Description
  1590. ;      resets and enables receiver engine
  1591. ;   Parameters:
  1592. ;      ebp - io_addr
  1593. ;   Return value:
  1594. ;   Destroyed registers
  1595. ;      eax, ebx, ecx, edx, edi, esi
  1596. ;
  1597. ;***************************************************************************
  1598.         align 4
  1599. e3c59x_rx_reset:
  1600.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1601.         mov     ax, (0101b shl 11) or 0x4 ; RxReset
  1602.         out     dx, ax
  1603. ; wait for RxReset to complete
  1604.         mov     ecx, 200000
  1605. .rx_reset_loop:
  1606.         in      ax, dx
  1607.         test    ah, 10000b ; check CmdInProgress
  1608.         jz      .setup_upd
  1609.         dec     ecx
  1610.         jns     .rx_reset_loop
  1611. .setup_upd:
  1612. ; check if full bus mastering
  1613.         test    byte [e3c59x_full_bus_master], 0xff
  1614.         jz      .rx_enable
  1615. ; create upd ring
  1616.         mov     eax, e3c59x_upd_buff
  1617.         zero_to_virt eax
  1618.         mov     [e3c59x_curr_upd], eax
  1619.         mov     esi, eax
  1620.         virt_to_dma esi
  1621.         mov     edi, e3c59x_rx_buff
  1622.         zero_to_dma edi
  1623.         mov     ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE
  1624.         zero_to_virt ebx
  1625.         mov     cl, E3C59X_NUM_RX_DESC-1
  1626. .upd_loop:
  1627.         mov     [ebx+E3C59X_UPD_UP_NEXT_PTR], esi
  1628.         and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
  1629.         mov     [eax+E3C59X_UPD_UP_FRAG_ADDR], edi
  1630.         mov     dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31)
  1631.         add     edi, E3C59X_MAX_ETH_FRAME_SIZE
  1632.         add     esi, E3C59X_UPD_SIZE
  1633.         mov     ebx, eax
  1634.         add     eax, E3C59X_UPD_SIZE
  1635.         dec     cl
  1636.         jns     .upd_loop
  1637.         mov     eax, e3c59x_upd_buff
  1638.         zero_to_dma eax
  1639.         lea     edx, [ebp+E3C59X_REG_UP_LIST_PTR]
  1640.         out     dx, eax ; write E3C59X_REG_UP_LIST_PTR
  1641.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1642. .rx_enable:
  1643.         mov     ax, (00100b shl 11) ; RxEnable
  1644.         out     dx, ax
  1645.         ret
  1646.  
  1647. ;***************************************************************************
  1648. ;   Function
  1649. ;      e3c59x_write_eeprom
  1650. ;   Description
  1651. ;      reads eeprom
  1652. ;      Note : the caller must switch to the register window 0
  1653. ;             before calling this function
  1654. ;   Parameters:
  1655. ;      ax - register to be read (only the first 63 words can be read)
  1656. ;      cx - value to be read into the register
  1657. ;   Return value:
  1658. ;      ax - word read
  1659. ;   Destroyed registers
  1660. ;      ax, ebx, edx
  1661. ;
  1662. ;***************************************************************************
  1663. ;       align 4
  1664. ;e3c59x_write_eeprom:
  1665. ;       mov     edx, [io_addr]
  1666. ;       add     edx, E3C59X_REG_EEPROM_COMMAND
  1667. ;       cmp     ah, 11b
  1668. ;       ja      .finish ; address may have a value of maximal 1023
  1669. ;       shl     ax, 2
  1670. ;       shr     al, 2
  1671. ;       push    eax
  1672. ;; wait for busy
  1673. ;       mov     ebx, 0xffff
  1674. ;@@:
  1675. ;       in      ax, dx
  1676. ;       test    ah, 0x80
  1677. ;       jz      .write_enable
  1678. ;       dec     ebx
  1679. ;       jns     @r
  1680. ;; write enable
  1681. ;.write_enable:
  1682. ;       xor     eax, eax
  1683. ;       mov     eax, (11b shl 4)
  1684. ;       out     dx, ax
  1685. ;; wait for busy
  1686. ;       mov     ebx, 0xffff
  1687. ;@@:
  1688. ;       in      ax, dx
  1689. ;       test    ah, 0x80
  1690. ;       jz      .erase_loop
  1691. ;       dec     ebx
  1692. ;       jns     @r
  1693. ;.erase_loop:
  1694. ;       pop     eax
  1695. ;       push    eax
  1696. ;       or      ax, (11b shl 6) ; erase register
  1697. ;       out     dx, ax
  1698. ;       mov     ebx, 0xffff
  1699. ;@@:
  1700. ;       in      ax, dx
  1701. ;       test    ah, 0x80
  1702. ;       jz      .write_reg
  1703. ;       dec     ebx
  1704. ;       jns     @r
  1705. ;.write_reg:
  1706. ;       add     edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND
  1707. ;       mov     eax, ecx
  1708. ;       out     dx, ax
  1709. ;; write enable
  1710. ;       add     edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA
  1711. ;       xor     eax, eax
  1712. ;       mov     eax, (11b shl 4)
  1713. ;       out     dx, ax
  1714. ; wait for busy
  1715. ;       mov     ebx, 0xffff
  1716. ;@@:
  1717. ;       in      ax, dx
  1718. ;       test    ah, 0x80
  1719. ;       jz      .issue_write_reg
  1720. ;       dec     ebx
  1721. ;       jns     @r
  1722. ;.issue_write_reg:
  1723. ;       pop     eax
  1724. ;       or      ax, 01b shl 6
  1725. ;       out     dx, ax
  1726. ;.finish:
  1727. ;       ret
  1728. ;***************************************************************************
  1729. ;   Function
  1730. ;      e3c59x_read_eeprom
  1731. ;   Description
  1732. ;      reads eeprom
  1733. ;   Parameters:
  1734. ;       ax - register to be read (only the first 63 words can be read)
  1735. ;      ebp - io_addr
  1736. ;   Return value:
  1737. ;      ax - word read
  1738. ;   Destroyed registers
  1739. ;      ax, ebx, edx, ebp
  1740. ;
  1741. ;***************************************************************************
  1742.         align 4
  1743. e3c59x_read_eeprom:
  1744.         push    eax
  1745. ; switch to register window 0
  1746.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1747.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+0
  1748.         out     dx, ax
  1749.         pop     eax
  1750.         and     ax, 111111b ; take only the first 6 bits into account
  1751.         movzx   ebx, byte [e3c59x_ver_id]
  1752.         test    word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT
  1753.         jz      @f
  1754.         add     ax, 0x230 ; hardware constant
  1755.         jmp     .read
  1756. @@:
  1757.         add     ax, E3C59X_EEPROM_CMD_READ
  1758.         test    word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET
  1759.         jz      .read
  1760.         add     ax, 0x30
  1761. .read:
  1762.         lea     edx, [ebp+E3C59X_REG_EEPROM_COMMAND]
  1763.         out     dx, ax
  1764.         mov     ebx, 0xffff ; duration of about 162 us ;-)
  1765. .wait_for_reading:
  1766.         in      ax, dx
  1767.         test    ah, 0x80 ; check bit eepromBusy
  1768.         jz      .read_data
  1769.         dec     ebx
  1770.         jns     .wait_for_reading
  1771. .read_data:
  1772.         lea     edx, [ebp+E3C59X_REG_EEPROM_DATA]
  1773.         in      ax, dx
  1774.         ret
  1775.  
  1776. ;***************************************************************************
  1777. ;   Function
  1778. ;      e3c59x_mdio_sync
  1779. ;   Description
  1780. ;      initial synchronization
  1781. ;   Parameters
  1782. ;      ebp - io_addr
  1783. ;   Return value
  1784. ;   Destroyed registers
  1785. ;      ax, edx, cl
  1786. ;
  1787. ;***************************************************************************
  1788.         align 4
  1789. e3c59x_mdio_sync:
  1790. ; switch to register window 4
  1791.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  1792.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
  1793.         out     dx, ax
  1794.         cmp     byte [e3c59x_preamble], 0
  1795.         je      .no_preamble
  1796. ; send 32 logic ones
  1797.         lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
  1798.         mov     cl, 31
  1799. .loop:
  1800.         mov     ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR)
  1801.         out     dx, ax
  1802.         in      ax, dx ; delay
  1803.         mov     ax, (1 shl E3C59X_BIT_MGMT_DATA) \
  1804.                     or (1 shl E3C59X_BIT_MGMT_DIR) \
  1805.                     or (1 shl E3C59X_BIT_MGMT_CLK)
  1806.         out     dx, ax
  1807.         in      ax, dx ; delay
  1808.         dec     cl
  1809.         jns     .loop
  1810. .no_preamble:
  1811.         ret
  1812.  
  1813. ;***************************************************************************
  1814. ;   Function
  1815. ;      e3c59x_mdio_read
  1816. ;   Description
  1817. ;      read MII register
  1818. ;      see page 16 in D83840A.pdf
  1819. ;   Parameters
  1820. ;       ah - PHY addr
  1821. ;       al - register addr
  1822. ;      ebp - io_addr
  1823. ;   Return value
  1824. ;      ax - register read
  1825. ;   Destroyed registers
  1826. ;      eax, ebx, cx, edx
  1827. ;
  1828. ;***************************************************************************
  1829.         align 4
  1830. e3c59x_mdio_read:
  1831.         push    eax
  1832.         call    e3c59x_mdio_sync ; returns with window #4
  1833.         pop     eax
  1834.         lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
  1835.         shl     al, 3
  1836.         shr     ax, 3
  1837.         and     ax, not E3C59X_MII_CMD_MASK
  1838.         or      ax, E3C59X_MII_CMD_READ
  1839.         mov     ebx, eax
  1840.         xor     ecx, ecx
  1841.         mov     cl, 13
  1842. .cmd_loop:
  1843.         mov     ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii
  1844.         bt      ebx, ecx
  1845.         jnc     .zero_bit
  1846.         or      al, (1 shl E3C59X_BIT_MGMT_DATA)
  1847. .zero_bit:
  1848.         out     dx, ax
  1849.         push    eax
  1850.         in      ax, dx ; delay
  1851.         pop     eax
  1852.         or      al, (1 shl E3C59X_BIT_MGMT_CLK) ; write
  1853.         out     dx, ax
  1854.         in      ax, dx ; delay
  1855.         dec     cl
  1856.         jns     .cmd_loop
  1857. ; read data (18 bits with the two transition bits)
  1858.         mov     cl, 17
  1859.         xor     ebx, ebx
  1860. .read_loop:
  1861.         shl     ebx, 1
  1862.         xor     eax, eax ; read comand
  1863.         out     dx, ax
  1864.         in      ax, dx ; delay
  1865.         in      ax, dx
  1866.         test    al, (1 shl E3C59X_BIT_MGMT_DATA)
  1867.         jz      .dont_set
  1868.         inc     ebx
  1869. .dont_set:
  1870.         mov     ax, (1 shl E3C59X_BIT_MGMT_CLK)
  1871.         out     dx, ax
  1872.         in      ax, dx ; delay
  1873.         dec     cl
  1874.         jns     .read_loop
  1875.         mov     eax, ebx
  1876.         ret
  1877.  
  1878. ;***************************************************************************
  1879. ;   Function
  1880. ;      e3c59x_mdio_write
  1881. ;   Description
  1882. ;      write MII register
  1883. ;      see page 16 in D83840A.pdf
  1884. ;   Parameters
  1885. ;       ah - PHY addr
  1886. ;       al - register addr
  1887. ;       bx - word to be written
  1888. ;      ebp - io_addr
  1889. ;   Return value
  1890. ;      ax - register read
  1891. ;   Destroyed registers
  1892. ;      eax, ebx, cx, edx
  1893. ;
  1894. ;***************************************************************************
  1895.         align 4
  1896. e3c59x_mdio_write:
  1897.         push    eax
  1898.         call    e3c59x_mdio_sync
  1899.         pop     eax
  1900.         lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
  1901.         shl     al, 3
  1902.         shr     ax, 3
  1903.         and     ax, not E3C59X_MII_CMD_MASK
  1904.         or      ax, E3C59X_MII_CMD_WRITE
  1905.         shl     eax, 2
  1906.         or      eax, 10b ; transition bits
  1907.         shl     eax, 16
  1908.         mov     ax, bx
  1909.         mov     ebx, eax
  1910.         mov     ecx, 31
  1911. .cmd_loop:
  1912.         mov     ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii
  1913.         bt      ebx, ecx
  1914.         jnc     .zero_bit
  1915.         or      al, (1 shl E3C59X_BIT_MGMT_DATA)
  1916. .zero_bit:
  1917.         out     dx, ax
  1918.         push    eax
  1919.         in      ax, dx ; delay
  1920.         pop     eax
  1921.         or      al, (1 shl E3C59X_BIT_MGMT_CLK) ; write
  1922.         out     dx, ax
  1923.         in      ax, dx ; delay
  1924.         dec     ecx
  1925.         jns     .cmd_loop
  1926.         ret
  1927.  
  1928. ;***************************************************************************
  1929. ;   Function
  1930. ;      e3c59x_transmit
  1931. ;   Description
  1932. ;      Transmits a packet of data via the ethernet card
  1933. ;         edi - Pointer to 48 bit destination address
  1934. ;          bx - Type of packet
  1935. ;         ecx - size of packet
  1936. ;         esi - pointer to packet data
  1937. ;         ebp - io_addr
  1938. ;   Destroyed registers
  1939. ;      eax, ecx, edx, ebp
  1940. ;
  1941. ;***************************************************************************
  1942.         align 4
  1943. e3c59x_transmit:
  1944.         jmp     dword [e3c59x_transmit_function]
  1945.  
  1946. ;***************************************************************************
  1947. ;   Function
  1948. ;      e3c59x_check_tx_status
  1949. ;   Description
  1950. ;      Checks TxStatus queue.
  1951. ;   Return value
  1952. ;      al - 0 no error was found
  1953. ;      al - 1 error was found TxReset is needed
  1954. ;   Destroyed registers
  1955. ;      eax, ecx, edx, ebp
  1956. ;
  1957. ;***************************************************************************
  1958. e3c59x_check_tx_status:
  1959.         movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
  1960. ; clear TxStatus queue
  1961.         lea     edx, [ebp+E3C59X_REG_TX_STATUS]
  1962.         mov     cl, 31 ; max number of queue entries
  1963. .tx_status_loop:
  1964.         in      al, dx
  1965.         test    al, al
  1966.         jz      .finish ; no error
  1967.         test    al, 0x3f
  1968.         jnz     .finish ; error
  1969. .no_error_found:
  1970. ; clear current TxStatus entry which advances the next one
  1971.         xor     al, al
  1972.         out     dx, al
  1973.         dec     cl
  1974.         jns     .tx_status_loop
  1975. .finish:
  1976.         ret
  1977.  
  1978. ;***************************************************************************
  1979. ;   Function
  1980. ;      e3c59x_vortex_transmit
  1981. ;   Description
  1982. ;      Transmits a packet of data via the ethernet card
  1983. ;         edi - Pointer to 48 bit destination address
  1984. ;          bx - Type of packet
  1985. ;         ecx - size of packet
  1986. ;         esi - pointer to packet data
  1987. ;         ebp - io_addr
  1988. ;   Destroyed registers
  1989. ;      eax, edx, ecx, edi, esi, ebp
  1990. ;
  1991. ;***************************************************************************
  1992.         align 4
  1993. e3c59x_vortex_transmit:
  1994.         push    ecx
  1995.         call    e3c59x_check_tx_status
  1996.         pop     ecx
  1997.         test    al, al
  1998.         jz      .no_error_found
  1999.         jmp     e3c59x_tx_reset
  2000. .no_error_found:
  2001. ; switch to register window 7
  2002.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2003.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+7
  2004.         out     dx, ax
  2005. ; check for master operation in progress
  2006.         lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
  2007.         in      ax, dx
  2008.         test    ah, 0x80
  2009.         jnz     .finish ; no DMA for sending
  2010. ; dword boundary correction
  2011.         cmp     ecx, E3C59X_MAX_ETH_FRAME_SIZE
  2012.         ja      .finish ; packet is too long
  2013. ; write Frame Start Header
  2014.         mov     eax, ecx
  2015. ; add header length and extend the complete length to dword boundary
  2016.         add     eax, ETH_HLEN+3
  2017.         and     eax, not 3
  2018.         lea     edx, [ebp+E3C59X_REG_TX_DATA]
  2019.         out     dx, eax
  2020. ; prepare the complete frame
  2021.         push    esi
  2022.         mov     esi, edi
  2023.         mov     edi, e3c59x_tx_buff
  2024.         zero_to_virt edi
  2025.         cld
  2026. ; copy destination address
  2027.         movsd
  2028.         movsw
  2029. ; copy source address
  2030.         mov     esi, node_addr
  2031.         movsd
  2032.         movsw
  2033. ; copy packet type
  2034.         mov     [edi], bx
  2035.         add     edi, 2
  2036. ; copy packet data
  2037.         pop     esi
  2038.         push    ecx
  2039.         shr     ecx, 2
  2040.         rep     movsd
  2041.         pop     ecx
  2042.         and     ecx, 3
  2043.         rep     movsb
  2044.         mov     ecx, eax
  2045. ; program frame address to be sent
  2046.         lea     edx, [ebp+E3C59X_REG_MASTER_ADDRESS]
  2047.         mov     eax, e3c59x_tx_buff
  2048.         zero_to_dma eax
  2049.         out     dx, eax
  2050. ; program frame length
  2051.         lea     edx, [ebp+E3C59X_REG_MASTER_LEN]
  2052.         mov     eax, ecx
  2053.         out     dx, ax
  2054. ; start DMA Down
  2055.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2056.         mov     ax, (10100b shl 11) + 1 ; StartDMADown
  2057.         out     dx, ax
  2058. .finish:
  2059.         ret
  2060.  
  2061. ;***************************************************************************
  2062. ;   Function
  2063. ;      e3c59x_boomerang_transmit
  2064. ;   Description
  2065. ;      Transmits a packet of data via the ethernet card
  2066. ;         edi - Pointer to 48 bit destination address
  2067. ;          bx - Type of packet
  2068. ;         ecx - size of packet
  2069. ;         esi - pointer to packet data
  2070. ;         ebp - io_addr
  2071. ;   Destroyed registers
  2072. ;      eax, ebx, ecx, edx, esi, edi, ebp
  2073. ;
  2074. ;***************************************************************************
  2075.         align 4
  2076. e3c59x_boomerang_transmit:
  2077.         push    ecx
  2078.         call    e3c59x_check_tx_status
  2079.         pop     ecx
  2080.         test    al, al
  2081.         jz      .no_error_found
  2082.         jmp     e3c59x_tx_reset
  2083. .no_error_found:
  2084.         cmp     ecx, E3C59X_MAX_ETH_FRAME_SIZE
  2085.         ja      .finish ; packet is too long
  2086. ; calculate descriptor address
  2087.         mov     eax, [e3c59x_prev_dpd]
  2088.         cmp     eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE
  2089.         jb      @f
  2090. ; wrap around
  2091.         mov     eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE
  2092. @@:
  2093.         add     eax, E3C59X_DPD_SIZE
  2094.         zero_to_virt eax
  2095.         push    eax
  2096. ; check DnListPtr
  2097.         lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
  2098.         in      eax, dx
  2099. ; mark if Dn_List_Ptr is cleared
  2100.         test    eax, eax
  2101.         setz    [e3c59x_dn_list_ptr_cleared]
  2102. ; finish if no more free descriptor is available - FIXME!
  2103.         cmp     eax, [esp]
  2104.         pop     eax
  2105.         jz      .finish
  2106.         push    eax esi
  2107.         mov     esi, edi
  2108. ; calculate tx_buffer address
  2109.         mov     edi, [e3c59x_prev_tx_frame]
  2110.         cmp     edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE
  2111.         jb      @f
  2112. ; wrap around
  2113.         mov     edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE
  2114. @@:
  2115.         add     edi, E3C59X_MAX_ETH_FRAME_SIZE
  2116.         zero_to_virt edi
  2117.         mov     eax, edi
  2118.         cld
  2119. ; copy destination address
  2120.         movsd
  2121.         movsw
  2122. ; copy source address
  2123.         mov     esi, node_addr
  2124.         movsd
  2125.         movsw
  2126. ; copy packet type
  2127.         mov     [edi], bx
  2128.         add     edi, 2
  2129. ; copy packet data
  2130.         pop     esi
  2131.         push    ecx
  2132.         shr     ecx, 2
  2133.         rep     movsd
  2134.         pop     ecx
  2135.         push    ecx
  2136.         and     ecx, 3
  2137.         rep     movsb
  2138. ; padding, do we really need it?
  2139.         pop     ecx
  2140.         add     ecx, ETH_HLEN
  2141.         cmp     ecx, ETH_ZLEN
  2142.         jae     @f
  2143.         mov     ecx, ETH_ZLEN
  2144. @@:
  2145. ; calculate
  2146.         mov     ebx, ecx
  2147.         test    byte [e3c59x_has_hwcksm], 0xff
  2148.         jz      @f
  2149.         or      ebx, (1 shl 26) ; set AddTcpChecksum
  2150. @@:
  2151.         or      ebx, 0x8000 ; transmission complete notification
  2152.         or      ecx, 0x80000000 ; last fragment
  2153. ; program DPD
  2154.         mov     edi, eax
  2155.         pop     eax
  2156.         and     dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0
  2157.         mov     dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx
  2158.         virt_to_dma edi
  2159.         mov     dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi
  2160.         mov     [eax+E3C59X_DPD_DN_FRAG_LEN], ecx
  2161. ; calculate physical address
  2162.         virt_to_dma eax
  2163.         push    eax
  2164.         cmp     byte [e3c59x_dn_list_ptr_cleared], 0
  2165.         jz      .add_to_list
  2166. ; write Dn_List_Ptr
  2167.         out     dx, eax
  2168.         jmp     .finish
  2169. .add_to_list:
  2170. ; DnStall
  2171.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2172.         mov     ax, ((110b shl 11)+2)
  2173.         out     dx, ax
  2174. ; wait for DnStall to complete
  2175.         mov     ecx, 6000
  2176. .wait_for_stall:
  2177.         in      ax, dx ; read E3C59X_REG_INT_STATUS
  2178.         test    ah, 10000b
  2179.         jz      .dnstall_ok
  2180.         dec     ecx
  2181.         jnz     .wait_for_stall
  2182. .dnstall_ok:
  2183.         pop     eax
  2184.         push    eax
  2185.         mov     ebx, [e3c59x_prev_dpd]
  2186.         zero_to_virt ebx
  2187.         mov     [ebx], eax
  2188.         lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
  2189.         in      eax, dx
  2190.         test    eax, eax
  2191.         jnz     .dnunstall
  2192. ; if Dn_List_Ptr has been cleared fill it up
  2193.         pop     eax
  2194.         push    eax
  2195.         out     dx, eax
  2196. .dnunstall:
  2197. ; DnUnStall
  2198.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2199.         mov     ax, ((110b shl 11)+3)
  2200.         out     dx, ax
  2201. .finish:
  2202.         pop     eax
  2203.         dma_to_zero eax
  2204.         mov     [e3c59x_prev_dpd], eax
  2205.         dma_to_zero edi
  2206.         mov     [e3c59x_prev_tx_frame], edi
  2207.         ret
  2208.  
  2209. ;***************************************************************************
  2210. ; Function
  2211. ;    e3c59x_poll
  2212. ; Description
  2213. ;    Polls the ethernet card for a received packet
  2214. ;    Received data, if any, ends up in Ether_buffer
  2215. ; Destroyed registers
  2216. ;    eax, ebx, edx, ecx, edi, esi, ebp
  2217. ;
  2218. ;***************************************************************************
  2219.         align 4
  2220. e3c59x_poll:
  2221.         jmp     dword [e3c59x_receive_function]
  2222.  
  2223. ;***************************************************************************
  2224. ; Function
  2225. ;    e3c59x_vortex_poll
  2226. ; Description
  2227. ;    Polls the ethernet card for a received packet
  2228. ;    Received data, if any, ends up in Ether_buffer
  2229. ; Parameters
  2230. ;    ebp - io_addr
  2231. ; Return value
  2232. ;    al - 0 ; no packet received
  2233. ;    al - 1 ; packet received
  2234. ; Destroyed registers
  2235. ;    eax, ebx, edx, ecx, edi, esi, ebp
  2236. ;
  2237. ;***************************************************************************
  2238.         align 4
  2239. e3c59x_vortex_poll:
  2240.         and     word [eth_rx_data_len], 0 ; assume no packet received
  2241.         movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
  2242. .rx_status_loop:
  2243. ; examine RxStatus
  2244.         lea     edx, [ebp+E3C59X_REG_RX_STATUS]
  2245.         in      ax, dx
  2246.         test    ax, ax
  2247.         jz      .finish
  2248.         test    ah, 0x80 ; rxIncomplete
  2249.         jz      .check_error
  2250.         jmp     .finish
  2251. .check_error:
  2252.         test    ah, 0x40
  2253.         jz      .check_length
  2254. ; discard the top frame received advancing the next one
  2255.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2256.         mov     ax, (01000b shl 11)
  2257.         out     dx, ax
  2258.         jmp     .rx_status_loop
  2259. .check_length:
  2260.         and     eax, 0x1fff
  2261.         cmp     eax, E3C59X_MAX_ETH_PKT_SIZE
  2262.         ja      .discard_frame ; frame is too long discard it
  2263. .check_dma:
  2264.         push    eax
  2265. ; switch to register window 7
  2266.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2267.         mov     ax, E3C59X_SELECT_REGISTER_WINDOW+7
  2268.         out     dx, ax
  2269. ; check for master operation in progress
  2270.         lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
  2271.         in      ax, dx
  2272.         test    ah, 0x80
  2273.         jz      .read_frame ; no DMA for receiving
  2274.         pop     eax
  2275.         jmp     .finish
  2276. .read_frame:
  2277. ; program buffer address to read in
  2278.         lea     edx, [ebp+E3C59X_REG_MASTER_ADDRESS]
  2279. if defined E3C59X_LINUX
  2280.         mov     eax, e3c59x_rx_buff
  2281.         zero_to_dma eax
  2282. else
  2283.         mov     eax, Ether_buffer
  2284. end if
  2285.         out     dx, eax
  2286. ; program frame length
  2287.         lea     edx, [ebp+E3C59X_REG_MASTER_LEN]
  2288.         mov     ax, 1560
  2289.         out     dx, ax
  2290. ; start DMA Up
  2291.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2292.         mov     ax, (10100b shl 11) ; StartDMAUp
  2293.         out     dx, ax
  2294. ; check for master operation in progress
  2295. .dma_loop:
  2296.         lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
  2297.         in      ax, dx
  2298.         test    ah, 0x80
  2299.         jnz     .dma_loop
  2300. ; registrate the received packet length
  2301.         pop     eax
  2302.         mov     word [eth_rx_data_len], ax
  2303. ; discard the top frame received
  2304. .discard_frame:
  2305.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2306.         mov     ax, (01000b shl 11)
  2307.         out     dx, ax
  2308. .finish:
  2309. ; set return value
  2310.         cmp     word [eth_rx_data_len], 0
  2311.         setne   al
  2312.         ret
  2313.  
  2314. ;***************************************************************************
  2315. ; Function
  2316. ;    e3c59x_boomerang_poll
  2317. ; Description
  2318. ;    Polls the ethernet card for a received packet
  2319. ;    Received data, if any, ends up in Ether_buffer
  2320. ; Parameters
  2321. ;    ebp - io_addr
  2322. ; Return value
  2323. ;    al - 0 ; no packet received
  2324. ;    al - 1 ; packet received
  2325. ; Destroyed registers
  2326. ;    eax, edx, ecx, edi, esi, ebp
  2327. ;
  2328. ;***************************************************************************
  2329.         align 4
  2330. e3c59x_boomerang_poll:
  2331.         and     word [eth_rx_data_len], 0 ; assume no packet received
  2332.         movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
  2333. ; check if packet is uploaded
  2334.         mov     eax, [e3c59x_curr_upd]
  2335.         test    byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete
  2336.         jnz     .check_error
  2337.         jmp     .finish
  2338. ; packet is uploaded check for any error
  2339. .check_error:
  2340.         test    byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError
  2341.         jz      .copy_packet_length
  2342.         and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
  2343.         jmp     .finish
  2344. .copy_packet_length:
  2345.         mov     ecx, [eax+E3C59X_UPD_PKT_STATUS]
  2346.         and     ecx, 0x1fff
  2347.         cmp     ecx, E3C59X_MAX_ETH_PKT_SIZE
  2348.         jbe     .copy_packet
  2349.         and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
  2350.         jmp     .finish
  2351. .copy_packet:
  2352.         push    ecx
  2353.         mov     word [eth_rx_data_len], cx
  2354.         mov     esi, [eax+E3C59X_UPD_UP_FRAG_ADDR]
  2355.         dma_to_virt esi
  2356.         mov     edi, Ether_buffer
  2357.         shr     ecx, 2 ; first copy dword-wise
  2358.         cld
  2359.         rep     movsd ; copy the dwords
  2360.         pop     ecx
  2361.         and     ecx, 3
  2362.         rep     movsb ; copy the rest bytes
  2363.         mov     eax, [e3c59x_curr_upd]
  2364.         and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
  2365.         virt_to_zero eax
  2366.         cmp     eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE
  2367.         jb      .no_wrap
  2368. ; wrap around
  2369.         mov     eax, e3c59x_upd_buff-E3C59X_UPD_SIZE
  2370. .no_wrap:
  2371.         add     eax, E3C59X_UPD_SIZE
  2372.         zero_to_virt eax
  2373.         mov     [e3c59x_curr_upd], eax
  2374. .finish:
  2375. ; check if the NIC is in the upStall state
  2376.         lea     edx, [ebp+E3C59X_REG_UP_PKT_STATUS]
  2377.         in      eax, dx
  2378.         test    ah, 0x20 ; UpStalled
  2379.         jz     .noUpUnStall
  2380. ; issue upUnStall command
  2381.         lea     edx, [ebp+E3C59X_REG_COMMAND]
  2382.         mov     ax, ((110b shl 11)+1) ; upUnStall
  2383.         out     dx, ax
  2384. .noUpUnStall:
  2385. ; set return value
  2386.         cmp     word [eth_rx_data_len], 0
  2387.         setnz   al
  2388.         ret
  2389.