Subversion Repositories Kolibri OS

Rev

Rev 5184 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  DEC 21x4x driver for KolibriOS                                 ;;
  7. ;;                                                                 ;;
  8. ;;  Based on dec21140.Asm from Solar OS by                         ;;
  9. ;;     Eugen Brasoveanu,                                           ;;
  10. ;;       Ontanu Bogdan Valentin                                    ;;
  11. ;;                                                                 ;;
  12. ;;  Written by hidnplayr@kolibrios.org                             ;;
  13. ;;                                                                 ;;
  14. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  15. ;;             Version 2, June 1991                                ;;
  16. ;;                                                                 ;;
  17. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  18.  
  19. format PE DLL native
  20. entry START
  21.  
  22.         CURRENT_API             = 0x0200
  23.         COMPATIBLE_API          = 0x0100
  24.         API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
  25.  
  26.         MAX_DEVICES             = 16
  27.  
  28.         TX_RING_SIZE            = 4
  29.         RX_RING_SIZE            = 4
  30.  
  31.         __DEBUG__               = 1
  32.         __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
  33.  
  34. section '.flat' readable writable executable
  35.  
  36. include '../proc32.inc'
  37. include '../struct.inc'
  38. include '../macros.inc'
  39. include '../fdo.inc'
  40. include '../netdrv.inc'
  41.  
  42. ; Capability flags used in chiplist
  43.         FLAG_HAS_MII            = 1 shl 0
  44.         FLAG_HAS_MEDIA_TABLE    = 1 shl 1
  45.         FLAG_CSR12_IN_SROM      = 1 shl 2
  46.         FLAG_ALWAYS_CHECK_MII   = 1 shl 3
  47.         FLAG_HAS_ACPI           = 1 shl 4
  48.  
  49. ; Chip id's
  50.         DC21040                 = 0
  51.         DC21041                 = 1
  52.         DC21140                 = 2
  53.         DC21142                 = 3
  54.         DC21143                 = 3
  55.         LC82C168                = 4
  56.         MX98713                 = 5
  57.         MX98715                 = 6
  58.         MX98725                 = 7
  59.  
  60. ;-------------------------------------------
  61. ; configuration registers
  62. ;-------------------------------------------
  63. CFCS                    = 4             ; configuration and status register
  64.  
  65. CSR0                    = 0x00          ; Bus mode
  66. CSR1                    = 0x08          ; Transmit Poll Command
  67. CSR2                    = 0x10          ; Receive Poll Command
  68. CSR3                    = 0x18          ; Receive list base address
  69. CSR4                    = 0x20          ; Transmit list base address
  70. CSR5                    = 0x28          ; Status
  71. CSR6                    = 0x30          ; Operation mode
  72. CSR7                    = 0x38          ; Interrupt enable
  73. CSR8                    = 0x40          ; Missed frames and overflow counter
  74. CSR9                    = 0x48          ; Boot ROM, serial ROM, and MII management
  75. CSR10                   = 0x50          ; Boot ROM programming address
  76. CSR11                   = 0x58          ; General-purpose timer
  77. CSR12                   = 0x60          ; General-purpose port
  78. CSR13                   = 0x68
  79. CSR14                   = 0x70
  80. CSR15                   = 0x78          ; Watchdog timer
  81.  
  82. ;--------bits/commands of CSR0-------------------
  83. CSR0_RESET              = 1b
  84.  
  85. CSR0_WIE                = 1 shl 24      ; Write and Invalidate Enable
  86. CSR0_RLE                = 1 shl 23      ; PCI Read Line Enable
  87. CSR0_RML                = 1 shl 21      ; PCI Read Multiple
  88.  
  89. CSR0_CACHEALIGN_NONE    = 00b shl 14
  90. CSR0_CACHEALIGN_32      = 01b shl 14
  91. CSR0_CACHEALIGN_64      = 10b shl 14
  92. CSR0_CACHEALIGN_128     = 11b shl 14
  93.  
  94. ; using values from linux driver..
  95. CSR0_DEFAULT            = CSR0_WIE + CSR0_RLE + CSR0_RML + CSR0_CACHEALIGN_NONE
  96.  
  97. ;------- CSR5 -STATUS- bits --------------------------------
  98. CSR5_TI                 = 0x00000001    ;1 shl 0        ; Transmit interupt - frame transmition completed
  99. CSR5_TPS                = 0x00000002    ;1 shl 1        ; Transmit process stopped
  100. CSR5_TU                 = 0x00000004    ;1 shl 2        ; Transmit Buffer unavailable
  101. CSR5_TJT                = 0x00000008    ;1 shl 3        ; Transmit Jabber Timeout (transmitter had been excessively active)
  102. CSR5_LP                 = 0x00000010    ;1 shl 4        ; Link pass
  103. CSR5_UNF                = 0x00000020    ;1 shl 5        ; Transmit underflow - FIFO underflow
  104. CSR5_RI                 = 0x00000040    ;1 shl 6        ; Receive Interrupt
  105. CSR5_RU                 = 0x00000080    ;1 shl 7        ; Receive Buffer unavailable
  106. CSR5_RPS                = 0x00000100    ;1 shl 8        ; Receive Process stopped
  107. CSR5_RWT                = 0x00000200    ;1 shl 9        ; Receive Watchdow Timeout
  108. CSR5_ETI                = 0x00000400    ;1 shl 10       ; Early transmit Interrupt
  109. CSR5_GTE                = 0x00000800    ;1 shl 11       ; General Purpose Timer Expired
  110. CSR5_LF                 = 0x00001000    ;1 shl 12       ; Link Fail
  111. CSR5_FBE                = 0x00002000    ;1 shl 13       ; Fatal bus error
  112. CSR5_ERI                = 0x00004000    ;1 shl 14       ; Early receive Interrupt
  113. CSR5_AIS                = 0x00008000    ;1 shl 15       ; Abnormal interrupt summary
  114. CSR5_NIS                = 0x00010000    ;1 shl 16       ; normal interrupt summary
  115. CSR5_RS_SH              = 17            ; Receive process state  -shift
  116. CSR5_RS_MASK            = 111b          ;                        -mask
  117. CSR5_TS_SH              = 20            ; Transmit process state -shift
  118. CSR5_TS_MASK            = 111b          ;                        -mask
  119. CSR5_EB_SH              = 23            ; Error bits             -shift
  120. CSR5_EB_MASK            = 111b          ; Error bits             -mask
  121.  
  122. ;CSR5 TS values
  123. CSR5_TS_STOPPED                 = 000b
  124. CSR5_TS_RUNNING_FETCHING_DESC   = 001b
  125. CSR5_TS_RUNNING_WAITING_TX      = 010b
  126. CSR5_TS_RUNNING_READING_BUFF    = 011b
  127. CSR5_TS_RUNNING_SETUP_PCKT      = 101b
  128. CSR5_TS_SUSPENDED               = 110b
  129. CSR5_TS_RUNNING_CLOSING_DESC    = 111b
  130.  
  131. ;------- CSR6 -OPERATION MODE- bits --------------------------------
  132. CSR6_HP                 = 1 shl 0       ; Hash/Perfect Receive Filtering mode
  133. CSR6_SR                 = 1 shl 1       ; Start/Stop receive
  134. CSR6_HO                 = 1 shl 2       ; Hash only Filtering mode
  135. CSR6_PB                 = 1 shl 3       ; Pass bad frames
  136. CSR6_IF                 = 1 shl 4       ; Inverse filtering
  137. CSR6_SB                 = 1 shl 5       ; Start/Stop backoff counter
  138. CSR6_PR                 = 1 shl 6       ; Promiscuous mode -default after reset
  139. CSR6_PM                 = 1 shl 7       ; Pass all multicast
  140. CSR6_F                  = 1 shl 9       ; Full Duplex mode
  141. CSR6_OM_SH              = 10            ; Operating Mode -shift
  142. CSR6_OM_MASK            = 11b           ;                -mask
  143. CSR6_FC                 = 1 shl 12      ; Force Collision Mode
  144. CSR6_ST                 = 1 shl 13      ; Start/Stop Transmission Command
  145. CSR6_TR_SH              = 14            ; Threshold Control      -shift
  146. CSR6_TR_MASK            = 11b           ;                        -mask
  147. CSR6_CA                 = 1 shl 17      ; Capture Effect Enable
  148. CSR6_PS                 = 1 shl 18      ; Port select SRL / MII/SYM
  149. CSR6_HBD                = 1 shl 19      ; Heartbeat Disable
  150. CSR6_SF                 = 1 shl 21      ; Store and Forward -transmit full packet only
  151. CSR6_TTM                = 1 shl 22      ; Transmit Threshold Mode -
  152. CSR6_PCS                = 1 shl 23      ; PCS active and MII/SYM port operates in symbol mode
  153. CSR6_SCR                = 1 shl 24      ; Scrambler Mode
  154. CSR6_MBO                = 1 shl 25      ; Must Be One
  155. CSR6_RA                 = 1 shl 30      ; Receive All
  156. CSR6_SC                 = 1 shl 31      ; Special Capture Effect Enable
  157.  
  158.  
  159. ;------- CSR7 -INTERRUPT ENABLE- bits --------------------------------
  160. CSR7_TI                 = 1 shl 0       ; transmit Interrupt Enable (set with CSR7<16> & CSR5<0> )
  161. CSR7_TS                 = 1 shl 1       ; transmit Stopped Enable (set with CSR7<15> & CSR5<1> )
  162. CSR7_TU                 = 1 shl 2       ; transmit buffer underrun Enable (set with CSR7<16> & CSR5<2> )
  163. CSR7_TJ                 = 1 shl 3       ; transmit jabber timeout enable (set with CSR7<15> & CSR5<3> )
  164. CSR7_UN                 = 1 shl 5       ; underflow Interrupt enable (set with CSR7<15> & CSR5<5> )
  165. CSR7_RI                 = 1 shl 6       ; receive Interrupt enable (set with CSR7<16> & CSR5<5> )
  166. CSR7_RU                 = 1 shl 7       ; receive buffer unavailable enable (set with CSR7<15> & CSR5<7> )
  167. CSR7_RS                 = 1 shl 8       ; Receive stopped enable (set with CSR7<15> & CSR5<8> )
  168. CSR7_RW                 = 1 shl 9       ; receive watchdog timeout enable (set with CSR7<15> & CSR5<9> )
  169. CSR7_ETE                = 1 shl 10      ; Early transmit Interrupt enable (set with CSR7<15> & CSR5<10> )
  170. CSR7_GPT                = 1 shl 11      ; general purpose timer enable (set with CSR7<15> & CSR5<11> )
  171. CSR7_FBE                = 1 shl 13      ; Fatal bus error enable (set with CSR7<15> & CSR5<13> )
  172. CSR7_ERE                = 1 shl 14      ; Early receive enable (set with CSR7<16> & CSR5<14> )
  173. CSR7_AI                 = 1 shl 15      ; Abnormal Interrupt Summary Enable (enables CSR5<0,3,7,8,9,10,13>)
  174. CSR7_NI                 = 1 shl 16      ; Normal Interrup Enable (enables CSR5<0,2,6,11,14>)
  175.  
  176. CSR7_DEFAULT            = CSR7_TI + CSR7_TS + CSR7_RI + CSR7_RS + CSR7_TU + CSR7_TJ + CSR7_UN + \
  177.                                         CSR7_RU + CSR7_RW + CSR7_FBE + CSR7_AI + CSR7_NI
  178. ;common to Rx and Tx
  179. DES0_OWN                = 1 shl 31              ; if set, the NIC controls the descriptor, otherwise driver 'owns' the descriptors
  180.  
  181. ;receive
  182. RDES0_ZER               = 1 shl 0               ; must be 0 if legal length :D
  183. RDES0_CE                = 1 shl 1               ; CRC error, valid only on last desc (RDES0<8>=1)
  184. RDES0_DB                = 1 shl 2               ; dribbling bit - not multiple of 8 bits, valid only on last desc (RDES0<8>=1)
  185. RDES0_RE                = 1 shl 3               ; Report on MII error.. i dont realy know what this means :P
  186. RDES0_RW                = 1 shl 4               ; received watchdog timer expiration - must set CSR5<9>, valid only on last desc (RDES0<8>=1)
  187. RDES0_FT                = 1 shl 5               ; frame type: 0->IEEE802.0 (len<1500) 1-> ETHERNET frame (len>1500), valid only on last desc (RDES0<8>=1)
  188. RDES0_CS                = 1 shl 6               ; Collision seen, valid only on last desc (RDES0<8>=1)
  189. RDES0_TL                = 1 shl 7               ; Too long(>1518)-NOT AN ERROR, valid only on last desc (RDES0<8>=1)
  190. RDES0_LS                = 1 shl 8               ; Last descriptor of current frame
  191. RDES0_FS                = 1 shl 9               ; First descriptor of current frame
  192. RDES0_MF                = 1 shl 10              ; Multicast frame, valid only on last desc (RDES0<8>=1)
  193. RDES0_RF                = 1 shl 11              ; Runt frame, valid only on last desc (RDES0<8>=1) and id overflow
  194. RDES0_DT_SERIAL         = 00b shl 12            ; Data type-Serial recv frame, valid only on last desc (RDES0<8>=1)
  195. RDES0_DT_INTERNAL       = 01b shl 12            ; Data type-Internal loopback recv frame, valid only on last desc (RDES0<8>=1)
  196. RDES0_DT_EXTERNAL       = 11b shl 12            ; Data type-External loopback recv frame, valid only on last desc (RDES0<8>=1)
  197. RDES0_DE                = 1 shl 14              ; Descriptor error - cant own a new desc and frame doesnt fit, valid only on last desc (RDES0<8>=1)
  198. RDES0_ES                = 1 shl 15              ; Error Summmary - bits 1+6+11+14, valid only on last desc (RDES0<8>=1)
  199. RDES0_FL_SH             = 16                    ; Field length shift, valid only on last desc (RDES0<8>=1)
  200. RDES0_FL_MASK           = 11111111111111b       ; Field length mask (+CRC), valid only on last desc (RDES0<8>=1)
  201. RDES0_FF                = 1 shl 30              ; Filtering fail-frame failed address recognition test(must CSR6<30>=1), valid only on last desc (RDES0<8>=1)
  202.  
  203. RDES1_RBS1_MASK         = 11111111111b          ; first buffer size MASK
  204. RDES1_RBS2_SH           = 11                    ; second buffer size SHIFT
  205. RDES1_RBS2_MASK         = 11111111111b          ; second buffer size MASK
  206. RDES1_RCH               = 1 shl 24              ; Second address chained - second address (buffer) is next desc address
  207. RDES1_RER               = 1 shl 25              ; Receive End of Ring - final descriptor, NIC must return to first desc
  208.  
  209. ;transmition
  210. TDES0_DE                = 1 shl 0               ; Deffered
  211. TDES0_UF                = 1 shl 1               ; Underflow error
  212. TDES0_LF                = 1 shl 2               ; Link fail report (only if CSR6<23>=1)
  213. TDES0_CC_SH             = 3                     ; Collision Count shift - no of collision before transmition
  214. TDES0_CC_MASK           = 1111b                 ; Collision Count mask
  215. TDES0_HF                = 1 shl 7               ; Heartbeat fail
  216. TDES0_EC                = 1 shl 8               ; Excessive Collisions - >16 collisions
  217. TDES0_LC                = 1 shl 9               ; Late collision
  218. TDES0_NC                = 1 shl 10              ; No carrier
  219. TDES0_LO                = 1 shl 11              ; Loss of carrier
  220. TDES0_TO                = 1 shl 14              ; Transmit Jabber Timeout
  221. TDES0_ES                = 1 shl 15              ; Error summary TDES0<1+8+9+10+11+14>=1
  222.  
  223. TDES1_TBS1_MASK         = 11111111111b          ; Buffer 1 size mask
  224. TDES1_TBS2_SH           = 11                    ; Buffer 2 size shift
  225. TDES1_TBS2_MASK         = 11111111111b          ; Buffer 2 size mask
  226. TDES1_FT0               = 1 shl 22              ; Filtering type 0
  227. TDES1_DPD               = 1 shl 23              ; Disabled padding for packets <64bytes, no padding
  228. TDES1_TCH               = 1 shl 24              ; Second address chained - second buffer pointer is to next desc
  229. TDES1_TER               = 1 shl 25              ; Transmit end of ring - final descriptor
  230. TDES1_AC                = 1 shl 26              ; Add CRC disable -pretty obvious
  231. TDES1_SET               = 1 shl 27              ; Setup packet
  232. TDES1_FT1               = 1 shl 28              ; Filtering type 1
  233. TDES1_FS                = 1 shl 29              ; First segment - buffer is first segment of frame
  234. TDES1_LS                = 1 shl 30              ; Last segment
  235. TDES1_IC                = 1 shl 31              ; Interupt on completion (CSR5<0>=1) valid when TDES1<30>=1
  236.  
  237. FULL_DUPLEX_MAGIC       = 0x6969
  238. ;MAX_ETH_FRAME_SIZE      = 1514
  239.  
  240. struct  device          ETH_DEVICE
  241.  
  242.         io_addr         dd ?
  243.         pci_bus         dd ?
  244.         pci_dev         dd ?
  245.         irq_line        db ?
  246.                         rb 3    ; alignment
  247.  
  248.         id              dd ?    ; identification number
  249.         io_size         dd ?
  250.         flags           dd ?
  251.         csr6            dd ?
  252.         csr7            dd ?
  253.         if_port         dd ?
  254.         saved_if_port   dd ?
  255.         default_port    dd ?
  256.         mtable          dd ?
  257.         mii_cnt         dd ?
  258.  
  259.         cur_rx          dd ?
  260.         cur_tx          dd ?    ; Tx current descriptor to write data to
  261.         last_tx         dd ?    ; Tx current descriptor to read TX completion
  262.  
  263.         rb 0x100-($ and 0xff)   ; align 256
  264.         rx_ring         rb RX_RING_SIZE*2*sizeof.desc
  265.  
  266.         rb 0x100-($ and 0xff)   ; align 256
  267.         tx_ring         rb TX_RING_SIZE*2*sizeof.desc
  268.  
  269. ends
  270.  
  271. ;----------- descriptor structure ---------------------
  272. struct  desc
  273.         status          dd ?    ; bit 31 is 'own' and rest is 'status'
  274.         length          dd ?    ; control bits + bytes-count buffer 1 + bytes-count buffer 2
  275.         buffer1         dd ?    ; pointer to buffer1
  276.         buffer2         dd ?    ; pointer to buffer2
  277. ends
  278.  
  279. ;=============================================================================
  280. ; serial ROM operations
  281. ;=============================================================================
  282. CSR9_SR                 = 1 shl 11        ; SROM Select
  283. CSR9_RD                 = 1 shl 14        ; ROM Read Operation
  284. CSR9_SROM_DO            = 1 shl 3         ; Data Out for SROM
  285. CSR9_SROM_DI            = 1 shl 2         ; Data In to SROM
  286. CSR9_SROM_CK            = 1 shl 1         ; clock for SROM
  287. CSR9_SROM_CS            = 1 shl 0         ; chip select.. always needed
  288.  
  289. ; assume dx is CSR9
  290. macro SROM_Delay {
  291.         push    eax
  292.         in      eax, dx
  293.         in      eax, dx
  294.         in      eax, dx
  295.         in      eax, dx
  296.         in      eax, dx
  297.         in      eax, dx
  298.         in      eax, dx
  299.         in      eax, dx
  300.         in      eax, dx
  301.         in      eax, dx
  302.         pop     eax
  303. }
  304.  
  305. ; assume dx is CSR9
  306. macro MDIO_Delay {
  307.         push    eax
  308.         in      eax, dx
  309.         pop     eax
  310. }
  311.  
  312. macro Bit_Set a_bit {
  313.         in      eax, dx
  314.         or      eax, a_bit
  315.         out     dx , eax
  316. }
  317.  
  318. macro Bit_Clear a_bit {
  319.         in      eax, dx
  320.         and     eax, not (a_bit)
  321.         out     dx, eax
  322. }
  323.  
  324.  
  325. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  326. ;;                        ;;
  327. ;; proc START             ;;
  328. ;;                        ;;
  329. ;; (standard driver proc) ;;
  330. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  331.  
  332. proc START c, reason:dword, cmdline:dword
  333.  
  334.         cmp     [reason], DRV_ENTRY
  335.         jne     .fail
  336.  
  337.         DEBUGF  2,"Loading driver\n"
  338.         invoke  RegService, my_service, service_proc
  339.         ret
  340.  
  341.   .fail:
  342.         xor     eax, eax
  343.         ret
  344.  
  345. endp
  346.  
  347.  
  348. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  349. ;;                        ;;
  350. ;; proc SERVICE_PROC      ;;
  351. ;;                        ;;
  352. ;; (standard driver proc) ;;
  353. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  354.  
  355. align 4
  356. proc service_proc stdcall, ioctl:dword
  357.  
  358.         mov     edx, [ioctl]
  359.         mov     eax, [edx + IOCTL.io_code]
  360.  
  361. ;------------------------------------------------------
  362.  
  363.         cmp     eax, 0 ;SRV_GETVERSION
  364.         jne     @F
  365.  
  366.         cmp     [edx + IOCTL.out_size], 4
  367.         jb      .fail
  368.         mov     eax, [edx + IOCTL.output]
  369.         mov     [eax], dword API_VERSION
  370.  
  371.         xor     eax, eax
  372.         ret
  373.  
  374. ;------------------------------------------------------
  375.   @@:
  376.         cmp     eax, 1 ;SRV_HOOK
  377.         jne     .fail
  378.  
  379.         cmp     [edx + IOCTL.inp_size], 3                               ; Data input must be at least 3 bytes
  380.         jb      .fail
  381.  
  382.         mov     eax, [edx + IOCTL.input]
  383.         cmp     byte [eax], 1                                           ; 1 means device number and bus number (pci) are given
  384.         jne     .fail                                                   ; other types arent supported for this card yet
  385.  
  386. ; check if the device is already listed
  387.  
  388.         mov     esi, device_list
  389.         mov     ecx, [devices]
  390.         test    ecx, ecx
  391.         jz      .firstdevice
  392.  
  393. ;        mov     eax, [edx + IOCTL.input]                                ; get the pci bus and device numbers
  394.         mov     ax, [eax+1]                                             ;
  395.   .nextdevice:
  396.         mov     ebx, [esi]
  397.         cmp     al, byte[ebx + device.pci_bus]
  398.         jne     @f
  399.         cmp     ah, byte[ebx + device.pci_dev]
  400.         je      .find_devicenum                                         ; Device is already loaded, let's find it's device number
  401.        @@:
  402.         add     esi, 4
  403.         loop    .nextdevice
  404.  
  405.  
  406. ; This device doesnt have its own eth_device structure yet, lets create one
  407.   .firstdevice:
  408.         cmp     [devices], MAX_DEVICES                                  ; First check if the driver can handle one more card
  409.         jae     .fail
  410.  
  411.         allocate_and_clear ebx, sizeof.device, .fail
  412.  
  413. ; Fill in the direct call addresses into the struct
  414.         mov     [ebx + device.reset], reset
  415.         mov     [ebx + device.transmit], transmit
  416.         mov     [ebx + device.unload], unload
  417.         mov     [ebx + device.name], my_service
  418.  
  419. ; save the pci bus and device numbers
  420.         mov     eax, [edx + IOCTL.input]
  421.         movzx   ecx, byte[eax+1]
  422.         mov     [ebx + device.pci_bus], ecx
  423.         movzx   ecx, byte[eax+2]
  424.         mov     [ebx + device.pci_dev], ecx
  425.  
  426. ; Now, it's time to find the base io addres of the PCI device
  427.         stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
  428.         mov     [ebx + device.io_addr], eax
  429.  
  430. ; We've found the io address, find IRQ now
  431.         invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
  432.         mov     [ebx + device.irq_line], al
  433.  
  434.         DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
  435.         [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8
  436.  
  437. ; Ok, the eth_device structure is ready, let's probe the device
  438. ; Because initialization fires IRQ, IRQ handler must be aware of this device
  439.         mov     eax, [devices]                                          ; Add the device structure to our device list
  440.         mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
  441.         inc     [devices]                                               ;
  442.  
  443.         call    probe                                                   ; this function will output in eax
  444.         test    eax, eax
  445.         jnz     .err2                                                   ; If an error occured, exit
  446.  
  447.         mov     [ebx + device.type], NET_TYPE_ETH
  448.         invoke  NetRegDev
  449.  
  450.         cmp     eax, -1
  451.         je      .destroy
  452.  
  453.         ret
  454.  
  455. ; If the device was already loaded, find the device number and return it in eax
  456.  
  457.   .find_devicenum:
  458.         DEBUGF  2,"Trying to find device number of already registered device\n"
  459.         invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
  460.                                                                         ; into a device number in edi
  461.         mov     eax, edi                                                ; Application wants it in eax instead
  462.         DEBUGF  2,"Kernel says: %u\n", eax
  463.         ret
  464.  
  465. ; If an error occured, remove all allocated data and exit (returning -1 in eax)
  466.  
  467.   .destroy:
  468.         ; todo: reset device into virgin state
  469.  
  470.   .err2:
  471.         dec     [devices]
  472.   .err:
  473.         DEBUGF  2,"removing device structure\n"
  474.         invoke  KernelFree, ebx
  475.  
  476.   .fail:
  477.         or      eax, -1
  478.         ret
  479.  
  480. ;------------------------------------------------------
  481. endp
  482.  
  483.  
  484. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  485. ;;                                                                        ;;
  486. ;;        Actual Hardware dependent code starts here                      ;;
  487. ;;                                                                        ;;
  488. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  489.  
  490.  
  491.  
  492. align 4
  493. unload:
  494.         ; TODO: (in this particular order)
  495.         ;
  496.         ; - Stop the device
  497.         ; - Detach int handler
  498.         ; - Remove device from local list
  499.         ; - call unregister function in kernel
  500.         ; - Remove all allocated structures and buffers the card used
  501.  
  502.         or      eax, -1
  503.         ret
  504.  
  505. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  506. ;;                                         ;;
  507. ;; Probe                                   ;;
  508. ;;                                         ;;
  509. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  510.  
  511. align 4
  512. probe:
  513.  
  514.         DEBUGF  2,"Probing\n"
  515.  
  516.         invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0        ; get device/vendor id
  517.         mov     esi, chiplist
  518.   .loop:
  519.         cmp     dword[esi], eax
  520.         je      .got_it
  521.         add     esi, 6*4
  522.         cmp     dword[esi], 0
  523.         jne     .loop
  524.         DEBUGF  2, "Unknown chip: 0x%x aborting\n", eax
  525.  
  526.         or      eax, -1
  527.         ret
  528.  
  529.   .got_it:
  530.         lodsd
  531.         lodsd
  532.         mov     [ebx + device.id], eax
  533.         lodsd
  534.         mov     [ebx + device.io_size], eax
  535.         lodsd
  536.         mov     [ebx + device.csr7], eax
  537.         lodsd
  538.         mov     [ebx + device.name], eax
  539.         DEBUGF  1, "Detected chip = %s\n", eax
  540.         lodsd
  541.         mov     [ebx + device.flags], eax
  542.  
  543. ; PROBE1
  544.  
  545.         test    [ebx + device.flags], FLAG_HAS_ACPI
  546.         jz      .no_acpi
  547.         DEBUGF  1, "Device has ACPI capabilities, time to wake it up\n"
  548.         xor     eax, eax
  549.         invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x40, eax       ; wake up the 21143
  550.   .no_acpi:
  551.  
  552.         call    SROM_GetWidth           ; TODO: use this value returned in ecx in the read_word routine!
  553.  
  554. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  555. ;;                                         ;;
  556. ;; Reset                                   ;;
  557. ;;                                         ;;
  558. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  559.  
  560. align 4
  561. reset:
  562.  
  563.         DEBUGF  2,"Reset\n"
  564.  
  565. ; Make the device a bus master
  566.         invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
  567.         or      al, PCI_CMD_MASTER
  568.         invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
  569.  
  570. ; Stop TX and RX
  571.         set_io  [ebx + device.io_addr], 0
  572.         set_io  [ebx + device.io_addr], CSR6
  573.         in      eax, dx
  574.         and     eax, not (CSR6_ST or CSR6_SR)
  575.         out     dx, eax
  576.  
  577. ; Clear missed packet counter
  578.         set_io  [ebx + device.io_addr], CSR8
  579.         in      eax, dx
  580.  
  581. ;; wait at least 50 PCI cycles
  582. ;        mov     esi, 1000
  583. ;        invoke  Sleep
  584.  
  585.         cmp     [ebx + device.id], DC21041
  586.         jne     @f
  587. ;        set_io  [ebx + device.io_addr], 0
  588.         set_io  [ebx + device.io_addr], CSR9
  589.         in      eax, dx
  590.         test    eax, 0x8000
  591.         jz      @f
  592.         DEBUGF  1, "21040 compatibility mode\n"
  593.         mov     [ebx + device.id], DC21040
  594.   @@:
  595.  
  596.  
  597. ;;; Find connected mii xceivers? 993-1043
  598.  
  599. ; Reset the xcvr interface and turn on heartbeat.
  600.         cmp     [ebx + device.id], DC21041
  601.         jne     @f
  602.         set_io  [ebx + device.io_addr], 0
  603.         set_io  [ebx + device.io_addr], CSR13
  604.         xor     eax, eax
  605.         out     dx, eax
  606.         set_io  [ebx + device.io_addr], CSR14
  607.         dec     eax
  608.         out     dx, eax
  609.         set_io  [ebx + device.io_addr], CSR15
  610.         inc     eax
  611.         mov     al, 8
  612.         out     dx, eax
  613.         set_io  [ebx + device.io_addr], CSR6
  614.         in      eax, dx
  615.         or      ax, CSR6_ST
  616.         out     dx, eax
  617.         set_io  [ebx + device.io_addr], CSR13
  618.         xor     eax, eax
  619.         mov     ax, 0xEF05
  620.         out     dx, eax
  621.         jmp     .reset_done
  622.   @@:
  623.         cmp     [ebx + device.id], DC21040
  624.         jne     @f
  625.         set_io  [ebx + device.io_addr], 0
  626.         set_io  [ebx + device.io_addr], CSR13
  627.         xor     eax, eax
  628.         out     dx, eax
  629.         mov     al, 4
  630.         out     dx, eax
  631.         jmp     .reset_done
  632.   @@:
  633.         cmp     [ebx + device.id], DC21140
  634.         jne     @f
  635.         set_io  [ebx + device.io_addr], 0
  636.         set_io  [ebx + device.io_addr], CSR12
  637.         mov     eax, 0x100
  638.         out     dx, eax
  639.         jmp     .reset_done
  640.   @@:
  641.         cmp     [ebx + device.id], DC21142
  642.         jne     @f
  643.         ; if tp->mii_cnt
  644.         set_io  [ebx + device.io_addr], 0
  645.         set_io  [ebx + device.io_addr], CSR6
  646.         mov     eax, 0x82020000
  647.         out     dx, eax
  648.         set_io  [ebx + device.io_addr], CSR13
  649.         xor     eax, eax
  650.         out     dx, eax
  651.         set_io  [ebx + device.io_addr], CSR14
  652.         out     dx, eax
  653.         set_io  [ebx + device.io_addr], CSR6
  654.         mov     eax, 0x820E0000
  655.         out     dx, eax
  656.         jmp     .reset_done
  657.         ;;;; TODO
  658.   @@:
  659.         cmp     [ebx + device.id], LC82C168
  660.         jne     @f
  661.         ; TODO
  662.   @@:
  663.         cmp     [ebx + device.id], MX98713
  664.         jne     @f
  665.         ; TODO
  666.   @@:
  667.  
  668.   .reset_done:
  669.  
  670.  
  671. ; OPEN
  672.  
  673. ; Reset chip
  674.         set_io  [ebx + device.io_addr], 0
  675.         set_io  [ebx + device.io_addr], CSR0
  676.         mov     eax, CSR0_RESET
  677.         out     dx, eax
  678.  
  679. ; wait at least 50 PCI cycles
  680.         mov     esi, 100
  681.         invoke  Sleep
  682.  
  683. ;-----------------------------------
  684. ; Read mac from eeprom to driver ram
  685.  
  686.         call    read_mac_eeprom
  687.  
  688. ;--------------------------------
  689. ; insert irq handler on given irq
  690.  
  691.         movzx   eax, [ebx + device.irq_line]
  692.         DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
  693.         invoke  AttachIntHandler, eax, int_handler, ebx
  694.         test    eax, eax
  695.         jnz     @f
  696.         DEBUGF  2,"Could not attach int handler!\n"
  697.         or      eax, -1
  698.         ret
  699.   @@:
  700.  
  701. ;----------------
  702. ; Set cache modes
  703.  
  704.         set_io  [ebx + device.io_addr], 0
  705.         set_io  [ebx + device.io_addr], CSR0
  706.         mov     eax, 0x01A00000 or 0x4800 ; CSR0_DEFAULT
  707.         out     dx, eax
  708.  
  709.         ; wait at least 50 PCI cycles
  710.         mov     esi, 100
  711.         invoke  Sleep
  712.  
  713. ;---------------------------
  714. ; Initialize RX and TX rings
  715.  
  716.         call    init_ring
  717.         test    eax, eax
  718.         jnz     .err
  719.  
  720. ;-------------------
  721. ; Set receive filter
  722.  
  723.         call    create_setup_frame
  724.  
  725. ;--------------------------------------------
  726. ; setup CSR3 & CSR4 (pointers to descriptors)
  727.  
  728.         lea     eax, [ebx + device.rx_ring]
  729.         invoke  GetPhysAddr
  730.         DEBUGF  1,"RX descriptor base address: %x\n", eax
  731.         set_io  [ebx + device.io_addr], 0
  732.         set_io  [ebx + device.io_addr], CSR3
  733.         out     dx, eax
  734.  
  735.         lea     eax, [ebx + device.tx_ring]
  736.         invoke  GetPhysAddr
  737.         DEBUGF  1,"TX descriptor base address: %x\n", eax
  738.         set_io  [ebx + device.io_addr], CSR4
  739.         out     dx, eax
  740.  
  741. ; Select media
  742.         push    [ebx + device.if_port]
  743.         pop     [ebx + device.saved_if_port]
  744.         cmp     [ebx + device.if_port], 0
  745.         jne     @f
  746.         push    [ebx + device.default_port]
  747.         pop     [ebx + device.if_port]
  748.   @@:
  749.         cmp     [ebx + device.id], DC21041
  750.         jne     @f
  751.         cmp     [ebx + device.if_port], 4
  752.         jbe     @f
  753.         ; invalid port, select inital TP, autosense, autonegotiate
  754.         mov     [ebx + device.if_port], 4                               ; CHECKME
  755.   @@:
  756.  
  757. ; Allow selecting a default media
  758.         cmp     [ebx + device.mtable], 0
  759.         je      .media_picked
  760.  
  761.         cmp     [ebx + device.if_port], 0
  762.         je      @f
  763.         ;; TODO
  764.         jmp     .media_picked
  765.   @@:
  766.  
  767.   .media_picked:
  768.         mov     [ebx + device.csr6], 0
  769.  
  770.         cmp     [ebx + device.id], DC21142
  771.         jne     @f
  772.         cmp     [ebx + device.if_port], 0
  773.         jne     @f
  774.         ;; TODO
  775.         mov     [ebx + device.csr6], 0x82420200
  776.         mov     [ebx + device.if_port], 11
  777.         set_io  [ebx + device.io_addr], 0
  778.         set_io  [ebx + device.io_addr], CSR14
  779.         mov     eax, 0x0003FFF
  780.         out     dx, eax
  781.         set_io  [ebx + device.io_addr], CSR15
  782.         xor     eax, eax
  783.         mov     al, 8
  784.         out     dx, eax
  785.         set_io  [ebx + device.io_addr], CSR13
  786.         mov     al, 1
  787.         out     dx, eax
  788.         set_io  [ebx + device.io_addr], CSR12
  789.         mov     ax, 0x1301
  790.         out     dx, eax
  791.  
  792.   @@:
  793.         cmp     [ebx + device.id], LC82C168
  794.         jne     @f
  795.         ;; TODO
  796.   @@:
  797.         cmp     [ebx + device.id], MX98713
  798.         jne     @f
  799.  
  800.   @@:
  801. ;; wait a bit
  802. ;        mov     esi, 500
  803. ;        invoke  Sleep
  804.  
  805. ; else:
  806.         xor     eax, eax
  807.         inc     eax
  808.         call    select_media
  809.  
  810. ; Start the chip's tx to process setup frame
  811.         set_io  [ebx + device.io_addr], 0
  812.         set_io  [ebx + device.io_addr], CSR6
  813.         mov     eax, [ebx + device.csr6]
  814.         out     dx, eax
  815.         or      ax, CSR6_ST
  816.         out     dx, eax
  817.  
  818. ; Enable interrupts by setting the interrupt mask.
  819.         set_io  [ebx + device.io_addr], CSR5
  820.         mov     eax, [ebx + device.csr7]
  821.         DEBUGF  1, "Setting CSR7 to 0x%x\n", eax
  822.         out     dx, eax
  823.         set_io  [ebx + device.io_addr], CSR7
  824.         out     dx, eax
  825.  
  826. ; Enable receiver
  827.         set_io  [ebx + device.io_addr], CSR6
  828.         mov     eax, [ebx + device.csr6]
  829.         or      eax, 0x2002 + CSR6_RA
  830.         out     dx, eax
  831.  
  832. ; RX poll demand
  833.         set_io  [ebx + device.io_addr], CSR2
  834.         xor     eax, eax
  835.         out     dx, eax
  836.  
  837. ; Set the mtu, kernel will be able to send now
  838.         mov     [ebx + device.mtu], 1514
  839.  
  840. ; Set link state to unknown
  841.         mov     [ebx + device.state], ETH_LINK_UNKNOWN
  842.  
  843.         DEBUGF  1,"Reset completed\n"
  844. ;        xor     eax, eax
  845.         ret
  846.  
  847.   .err:
  848.         DEBUGF  2,"Reset failed\n"
  849.         or      eax, -1
  850.         ret
  851.  
  852.  
  853.  
  854. align 4
  855. init_ring:
  856.  
  857.         DEBUGF  1,"Init ring\n"
  858.  
  859. ;---------------------
  860. ; Setup RX descriptors
  861.  
  862.         lea     eax, [ebx + device.rx_ring]
  863.         invoke  GetPhysAddr
  864.         mov     edx, eax
  865.         push    eax
  866.         lea     edi, [ebx + device.rx_ring]
  867.         mov     ecx, RX_RING_SIZE
  868.   .loop_rx_des:
  869.         DEBUGF  1,"RX descriptor 0x%x\n", edi
  870.         add     edx, sizeof.desc
  871.         mov     [edi + desc.status], DES0_OWN
  872.         mov     [edi + desc.length], 1536
  873.         push    edx edi ecx
  874.         invoke  KernelAlloc, 1536
  875.         pop     ecx edi edx
  876.         test    eax, eax
  877.         jz      .out_of_mem
  878.         mov     [edi + RX_RING_SIZE*sizeof.desc], eax
  879.         invoke  GetPhysAddr
  880.         mov     [edi + desc.buffer1], eax
  881.         mov     [edi + desc.buffer2], edx
  882.         add     edi, sizeof.desc
  883.         dec     ecx
  884.         jnz     .loop_rx_des
  885. ; set last descriptor as LAST
  886.         or      [edi - sizeof.desc + desc.length], RDES1_RER           ; EndOfRing
  887.         pop     [edi - sizeof.desc + desc.buffer2]                     ; point it to the first descriptor
  888.  
  889. ;---------------------
  890. ; Setup TX descriptors
  891.  
  892.         lea     eax, [ebx + device.tx_ring]
  893.         invoke  GetPhysAddr
  894.         mov     edx, eax
  895.         push    eax
  896.         lea     edi, [ebx + device.tx_ring]
  897.         mov     ecx, TX_RING_SIZE
  898.   .loop_tx_des:
  899.         DEBUGF  1,"TX descriptor 0x%x\n", edi
  900.         add     edx, sizeof.desc
  901.         mov     [edi + desc.status], 0                                  ; owned by driver
  902.         mov     [edi + desc.length], 0
  903.         mov     [edi + desc.buffer1], 0
  904.         mov     [edi + desc.buffer2], edx                               ; pointer to next descr
  905.         add     edi, sizeof.desc
  906.         dec     ecx
  907.         jnz     .loop_tx_des
  908. ; set last descriptor as LAST
  909.         or      [edi - sizeof.desc + desc.length], TDES1_TER            ; EndOfRing
  910.         pop     [edi - sizeof.desc + desc.buffer2]                      ; point it to the first descriptor
  911.  
  912. ;------------------
  913. ; Reset descriptors
  914.  
  915.         xor     eax, eax
  916.         mov     [ebx + device.cur_tx], eax
  917.         mov     [ebx + device.last_tx], eax
  918.         mov     [ebx + device.cur_rx], eax
  919.  
  920.         ret
  921.  
  922.   .out_of_mem:
  923.         DEBUGF  2, "Out of memory!\n"
  924.         pop     eax
  925.         or      eax, -1
  926.         ret
  927.  
  928.  
  929. ; IN: eax = startup
  930. align 4
  931. select_media:
  932.  
  933.         DEBUGF  1, "Selecting media\n"
  934.  
  935.         cmp     [ebx + device.mtable], 0
  936.         je      .no_mtable
  937.         DEBUGF  1, "Device has a media table\n"
  938.  
  939.  
  940. ; default:
  941.         mov     eax, 0x020E0000
  942.         jmp     .update_csr6
  943.  
  944.   .no_mtable:
  945.         DEBUGF  1, "Device has no media table\n"
  946.  
  947.         cmp     [ebx + device.id], DC21041
  948.         jne     .not_41
  949.         DEBUGF  1, "DC21041\n"
  950.  
  951.         set_io  [ebx + device.io_addr], 0
  952.         set_io  [ebx + device.io_addr], CSR13
  953.         xor     eax, eax
  954.         out     dx, eax         ; reset serial interface
  955.         set_io  [ebx + device.io_addr], CSR14
  956.         mov     eax, 0x7F3F     ;0x7F3F     ;0x7F3D     ; 10T-FD
  957.         out     dx, eax
  958.         set_io  [ebx + device.io_addr], CSR15
  959.         mov     eax, 0x0008     ;0x0008     ;0x0008     ; 10T-FD
  960.         out     dx, eax
  961.         set_io  [ebx + device.io_addr], CSR13
  962.         mov     eax, 0xEF05     ;0xEF01     ;0xEF09     ; 10T-FD
  963.         out     dx, eax
  964.         mov     eax, 0x80020000
  965.         jmp     .update_csr6
  966.   .not_41:
  967.         cmp     [ebx + device.id], LC82C168
  968.         jne     .not_LC
  969.         DEBUGF  1, "LC82C168\n"
  970.  
  971.         ;; TODO
  972.  
  973.         mov     eax, 0x812C0000
  974.         jmp     .update_csr6
  975.   .not_LC:
  976.         cmp     [ebx + device.id], DC21040
  977.         jne     .not_40
  978.         DEBUGF  1, "DC21040\n"
  979.  
  980.         set_io  [ebx + device.io_addr], 0
  981.         set_io  [ebx + device.io_addr], CSR11
  982.         mov     eax, FULL_DUPLEX_MAGIC
  983.         out     dx, eax
  984.         ; reset serial interface
  985.         set_io  [ebx + device.io_addr], CSR13
  986.         xor     eax, eax
  987.         out     dx, eax
  988.  
  989.         set_io  [ebx + device.io_addr], CSR13
  990.         xor     eax, eax
  991.         cmp     [ebx + device.if_port], 0
  992.         je      @f
  993.         mov     al, 0xc
  994.         out     dx, eax
  995.         mov     eax, 0x01860000
  996.         jmp     .update_csr6
  997.   @@:
  998.         mov     al, 4
  999.         out     dx, eax
  1000.         mov     eax, 0x00420000
  1001.         jmp     .update_csr6
  1002.  
  1003.   .not_40:
  1004.         DEBUGF  1, "Unkown chip with no media table\n"
  1005.  
  1006.         cmp     [ebx + device.default_port], 0
  1007.         jne     .not_0
  1008.         cmp     [ebx + device.mii_cnt], 0
  1009.         je      @f
  1010.         mov     [ebx + device.if_port], 11
  1011.         jmp     .not_0
  1012.   @@:
  1013.         mov     [ebx + device.if_port], 3
  1014.   .not_0:
  1015.         mov     eax, 0x020E0000 ;;;;;
  1016.  
  1017.   .update_csr6:
  1018.         and     [ebx + device.csr6], 0xfdff
  1019.         or      ax, 0x0200                     ;; FULL DUPLEX
  1020.         or      [ebx + device.csr6], eax
  1021.         DEBUGF  1, "new CSR6: 0x%x\n", [ebx + device.csr6]
  1022.  
  1023.         ret
  1024.  
  1025.  
  1026. align 4
  1027. start_link:
  1028.  
  1029.         DEBUGF  1,"Starting link\n"
  1030.  
  1031.         ; TODO: write working code here
  1032.  
  1033.         ret
  1034.  
  1035. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1036. ;;                                         ;;
  1037. ;; Send setup packet                       ;;
  1038. ;;                                         ;;
  1039. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1040.  
  1041. align 4
  1042. create_setup_frame:
  1043.  
  1044.         DEBUGF  1,"Creating setup packet\n"
  1045.  
  1046.         invoke  KernelAlloc, 192
  1047.         test    eax, eax
  1048.         jz      .err
  1049.  
  1050.         push    eax
  1051.  
  1052.         mov     edi, eax
  1053.         xor     eax, eax
  1054.         dec     ax
  1055.         stosd
  1056.         stosd
  1057.         stosd
  1058.  
  1059.         mov     ecx, 15
  1060.   .loop:
  1061.         lea     esi, [ebx + device.mac]
  1062.         lodsw
  1063.         stosd
  1064.         dec     ecx
  1065.         jnz     .loop
  1066.  
  1067.         pop     eax
  1068.  
  1069. ; setup descriptor
  1070.         lea     edi, [ebx + device.tx_ring]
  1071.         DEBUGF  1, "attaching setup packet 0x%x to descriptor 0x%x\n", eax, edi
  1072.         mov     [edi + TX_RING_SIZE*sizeof.desc], eax
  1073.         invoke  GetPhysAddr
  1074.         mov     [edi + desc.buffer1], eax
  1075.         mov     [edi + desc.length], TDES1_SET + 192        ; size must be EXACTLY 192 bytes + TDES1_IC
  1076.         mov     [edi + desc.status], DES0_OWN
  1077.         DEBUGF  1, "descriptor 0x%x\n", edi
  1078.  
  1079. ; go to next descriptor
  1080.         inc     [ebx + device.cur_tx]
  1081.  
  1082.         ret
  1083.  
  1084.   .err:
  1085.         DEBUGF  2, "Out of memory!\n"
  1086.         ret
  1087.  
  1088.  
  1089.  
  1090. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1091. ;;                                         ;;
  1092. ;; Transmit                                ;;
  1093. ;;                                         ;;
  1094. ;; In: buffer pointer in [esp+4]           ;;
  1095. ;;     size of buffer in [esp+8]           ;;
  1096. ;;     pointer to device structure in ebx  ;;
  1097. ;;                                         ;;
  1098. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1099.  
  1100. proc transmit stdcall bufferptr, buffersize
  1101.  
  1102.         pushf
  1103.         cli
  1104.  
  1105.         DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
  1106.         mov     eax, [bufferptr]
  1107.         DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
  1108.         [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
  1109.         [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
  1110.         [eax+13]:2,[eax+12]:2
  1111.  
  1112.         cmp     [buffersize], 1514
  1113.         ja      .fail
  1114.  
  1115.         mov     eax, [ebx + device.cur_tx]
  1116.         mov     edx, sizeof.desc
  1117.         mul     edx
  1118.         lea     esi, [ebx + device.tx_ring + eax]
  1119.         test    [esi + desc.status], DES0_OWN
  1120.         jnz     .fail
  1121.  
  1122.         DEBUGF  1, "Descriptor is free\n"
  1123.  
  1124.         mov     eax, [bufferptr]
  1125.         mov     [esi + TX_RING_SIZE*sizeof.desc], eax
  1126.         invoke  GetPhysAddr
  1127.         mov     [esi + desc.buffer1], eax
  1128.  
  1129. ; set packet size
  1130.         mov     eax, [esi + desc.length]
  1131.         and     eax, TDES1_TER                          ; preserve 'End of Ring' bit
  1132.         or      eax, [buffersize]                       ; set size
  1133.         or      eax, TDES1_FS or TDES1_LS or TDES1_IC   ; first descr, last descr, interrupt on complete
  1134.         mov     [esi + desc.length], eax
  1135.  
  1136. ; set descriptor status
  1137.         mov     [esi + desc.status], DES0_OWN           ; say it is now owned by the 21x4x
  1138.  
  1139. ; Check if transmitter is running
  1140.         set_io  [ebx + device.io_addr], 0
  1141.         set_io  [ebx + device.io_addr], CSR6
  1142.         in      eax, dx
  1143.         test    eax, CSR6_ST                            ; if NOT started, start now
  1144.         jnz     .already_started
  1145.         or      eax, CSR6_ST
  1146.         DEBUGF  1,"(Re) starting TX\n"
  1147.         jmp     .do_it
  1148.   .already_started:
  1149.  
  1150. ; Trigger immediate transmit demand
  1151.         set_io  [ebx + device.io_addr], CSR1
  1152.         xor     eax, eax
  1153.   .do_it:
  1154.         out     dx, eax
  1155.  
  1156. ; Update stats
  1157.         inc     [ebx + device.packets_tx]
  1158.         mov     eax, [buffersize]
  1159.         add     dword [ebx + device.bytes_tx], eax
  1160.         adc     dword [ebx + device.bytes_tx + 4], 0
  1161.  
  1162. ; go to next descriptor
  1163.         inc     [ebx + device.cur_tx]
  1164.         and     [ebx + device.cur_tx], TX_RING_SIZE-1
  1165.  
  1166.         DEBUGF  1,"Transmit ok\n"
  1167.         popf
  1168.         xor     eax, eax
  1169.         ret
  1170.  
  1171.   .fail:
  1172.         DEBUGF  2,"Transmit failed\n"
  1173.         invoke  KernelFree, [bufferptr]
  1174.         popf
  1175.         or      eax, -1
  1176.         ret
  1177.  
  1178. endp
  1179.  
  1180. ;;;;;;;;;;;;;;;;;;;;;;;
  1181. ;;                   ;;
  1182. ;; Interrupt handler ;;
  1183. ;;                   ;;
  1184. ;;;;;;;;;;;;;;;;;;;;;;;
  1185.  
  1186. align 4
  1187. int_handler:
  1188.  
  1189.         push    ebx esi edi
  1190.  
  1191.         DEBUGF  1,"INT\n"
  1192.  
  1193. ; find pointer of device wich made IRQ occur
  1194.  
  1195.         mov     ecx, [devices]
  1196.         test    ecx, ecx
  1197.         jz      .nothing
  1198.         mov     esi, device_list
  1199.   .nextdevice:
  1200.         mov     ebx, [esi]
  1201.  
  1202.         set_io  [ebx + device.io_addr], 0
  1203.         set_io  [ebx + device.io_addr], CSR5
  1204.         in      eax, dx
  1205.         and     eax, 0x0001ffff
  1206.         out     dx, eax                                 ; send it back to ACK
  1207.         jnz     .got_it
  1208.   .continue:
  1209.         add     esi, 4
  1210.         dec     ecx
  1211.         jnz     .nextdevice
  1212.   .nothing:
  1213.         pop     edi esi ebx
  1214.         xor     eax, eax
  1215.  
  1216.         ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
  1217.  
  1218.   .got_it:
  1219.         DEBUGF  1,"Device: %x CSR5: %x\n", ebx, eax
  1220.  
  1221. ;----------------------------------
  1222. ; TX ok?
  1223.  
  1224.         test    eax, CSR5_TI
  1225.         jz      .not_tx
  1226.  
  1227.         push    eax esi ecx
  1228.         DEBUGF  1,"TX ok!\n"
  1229.       .loop_tx:
  1230.         ; get last descriptor
  1231.         mov     eax, [ebx + device.last_tx]
  1232.         mov     edx, sizeof.desc
  1233.         mul     edx
  1234.         lea     eax, [ebx + device.tx_ring + eax]
  1235.  
  1236.         DEBUGF  1,"descriptor 0x%x\n", eax
  1237.         test    [eax + desc.status], DES0_OWN           ; owned by the card?
  1238.         jnz     .end_tx
  1239.         cmp     [eax + desc.buffer1], 0                 ; empty descriptor?
  1240.         je      .end_tx
  1241.  
  1242.         mov     [eax + desc.buffer1], 0
  1243.         DEBUGF  1,"Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc]
  1244.         invoke  KernelFree, [eax + TX_RING_SIZE*sizeof.desc]
  1245.  
  1246.         ; advance to next descriptor
  1247.         inc     [ebx + device.last_tx]
  1248.         and     [ebx + device.last_tx], TX_RING_SIZE-1
  1249.  
  1250.         jmp     .loop_tx
  1251.   .end_tx:
  1252.         pop     ecx esi eax
  1253.   .not_tx:
  1254.  
  1255. ;----------------------------------
  1256. ; RX irq
  1257.  
  1258.         test    eax, CSR5_RI
  1259.         jz      .not_rx
  1260.         push    eax esi ecx
  1261.  
  1262.         DEBUGF 1,"RX ok!\n"
  1263.  
  1264.         push    ebx
  1265.   .rx_loop:
  1266.         pop     ebx
  1267.  
  1268. ; get current descriptor
  1269.         mov     eax, [ebx + device.cur_rx]
  1270.         mov     edx, sizeof.desc
  1271.         mul     edx
  1272.         lea     edi, [ebx + device.rx_ring + eax]
  1273.  
  1274. ; Check current RX descriptor status
  1275.         mov     eax, [edi + desc.status]
  1276.  
  1277.         test    eax, DES0_OWN
  1278.         jnz     .end_rx                                 ; current desc is busy, nothing to do
  1279.         test    eax, RDES0_FS
  1280.         jz      .end_rx                                 ; current desc is NOT first packet, ERROR!
  1281.         test    eax, RDES0_LS                           ; if not last desc of packet, error for now
  1282.         jz      .end_rx
  1283.         test    eax, RDES0_ES
  1284.         jnz     .end_rx
  1285.  
  1286. ; Calculate length
  1287.         mov     ecx, [edi + desc.status]
  1288.         shr     ecx, RDES0_FL_SH
  1289.         and     ecx, RDES0_FL_MASK
  1290.         sub     ecx, 4                                  ; throw away the CRC
  1291.         DEBUGF  1,"got %u bytes\n", ecx
  1292.  
  1293. ; Push arguments for Eth_input (and some more...)
  1294.         push    ebx
  1295.         push    .rx_loop                                ; return addr
  1296.         push    ecx                                     ; packet size
  1297.         push    dword[edi + RX_RING_SIZE*sizeof.desc]   ; packet ptr
  1298.  
  1299. ; update statistics
  1300.         inc     [ebx + device.packets_rx]
  1301.         add     dword[ebx + device.bytes_rx], ecx
  1302.         adc     dword[ebx + device.bytes_rx + 4], 0
  1303.  
  1304. ; Allocate new descriptor
  1305.         push    edi ebx
  1306.         invoke  KernelAlloc, 1536                       ; Allocate a buffer to put packet into
  1307.         pop     ebx edi
  1308.         mov     [edi + RX_RING_SIZE*sizeof.desc], eax
  1309.         invoke  GetPhysAddr
  1310.         mov     [edi + desc.buffer1], eax
  1311.         mov     [edi + desc.status], DES0_OWN           ; mark descriptor as being free
  1312.  
  1313. ; Move to next rx desc
  1314.         inc     [ebx + device.cur_rx]                   ; next descriptor
  1315.         and     [ebx + device.cur_rx], RX_RING_SIZE-1
  1316.  
  1317.         jmp     [Eth_input]
  1318.   .end_rx:
  1319.   .not_rx:
  1320.  
  1321.         pop     edi esi ebx
  1322.         ret
  1323.  
  1324.  
  1325.  
  1326. align 4
  1327. write_mac:      ; in: mac pushed onto stack (as 3 words)
  1328.  
  1329.         DEBUGF  1,"Writing MAC\n"
  1330.  
  1331. ; write data into driver cache
  1332.         mov     esi, esp
  1333.         lea     edi, [ebx + device.mac]
  1334.         movsd
  1335.         movsw
  1336.         add     esp, 6
  1337.        
  1338. ;; send setup packet (only if driver is started)
  1339. ;;        call    Create_Setup_Packet
  1340.  
  1341. align 4
  1342. read_mac_eeprom:
  1343.  
  1344.         DEBUGF  1,"Reading MAC from eeprom\n"
  1345.  
  1346.         lea     edi, [ebx + device.mac]
  1347.         mov     esi, 20/2               ; read words, start address is 20
  1348.      .loop:
  1349.         push    esi edi
  1350.         call    SROM_Read_Word
  1351.         pop     edi esi
  1352.         stosw
  1353.         inc     esi
  1354.         cmp     esi, 26/2
  1355.         jb      .loop
  1356.  
  1357.         DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2
  1358.  
  1359.         ret
  1360.  
  1361.  
  1362. align 4
  1363. SROM_GetWidth:  ; should be 6 or 8 according to some manuals (returns in ecx)
  1364.  
  1365. ;        DEBUGF 1,"SROM_GetWidth\n"
  1366.  
  1367.         call    SROM_Idle
  1368.         call    SROM_EnterAccessMode
  1369.  
  1370. ;        set_io  [ebx + device.io_addr], 0
  1371. ;        set_io  [ebx + device.io_addr], CSR9
  1372.  
  1373.         ; send 110b
  1374.  
  1375.         in      eax, dx
  1376.         or      eax, CSR9_SROM_DI
  1377.         call    SROM_out
  1378.  
  1379.         in      eax, dx
  1380.         or      eax, CSR9_SROM_DI
  1381.         call    SROM_out
  1382.  
  1383.         in      eax, dx
  1384.         and     eax, not (CSR9_SROM_DI)
  1385.         call    SROM_out
  1386.        
  1387.         mov     ecx,1
  1388.   .loop2:
  1389.         Bit_Set CSR9_SROM_CK
  1390.         SROM_Delay
  1391.        
  1392.         in      eax, dx
  1393.         and     eax, CSR9_SROM_DO
  1394.         jnz     .not_zero
  1395.  
  1396.         Bit_Clear CSR9_SROM_CK
  1397.         SROM_Delay
  1398.         jmp     .end_loop2
  1399.   .not_zero:
  1400.        
  1401.         Bit_Clear CSR9_SROM_CK
  1402.         SROM_Delay
  1403.        
  1404.         inc     ecx
  1405.         cmp     ecx, 12
  1406.         jbe     .loop2
  1407.   .end_loop2:
  1408.        
  1409.         DEBUGF  1,"SROM width=%u\n", ecx
  1410.        
  1411.         call    SROM_Idle
  1412.         call    SROM_EnterAccessMode
  1413.         call    SROM_Idle
  1414.        
  1415.         ret
  1416.  
  1417.  
  1418. align 4
  1419. SROM_out:
  1420.  
  1421.         out     dx, eax
  1422.         SROM_Delay
  1423.         Bit_Set CSR9_SROM_CK
  1424.         SROM_Delay
  1425.         Bit_Clear CSR9_SROM_CK
  1426.         SROM_Delay
  1427.  
  1428.         ret
  1429.  
  1430.  
  1431.  
  1432. align 4
  1433. SROM_EnterAccessMode:
  1434.  
  1435. ;        DEBUGF 1,"SROM_EnterAccessMode\n"
  1436.  
  1437.         set_io  [ebx + device.io_addr], 0
  1438.         set_io  [ebx + device.io_addr], CSR9
  1439.         mov     eax, CSR9_SR
  1440.         out     dx, eax
  1441.         SROM_Delay
  1442.  
  1443.         Bit_Set CSR9_RD
  1444.         SROM_Delay
  1445.  
  1446.         Bit_Clear CSR9_SROM_CK
  1447.         SROM_Delay
  1448.  
  1449.         Bit_Set CSR9_SROM_CS
  1450.         SROM_Delay
  1451.        
  1452.         ret
  1453.  
  1454.  
  1455.  
  1456. align 4
  1457. SROM_Idle:
  1458.  
  1459. ;        DEBUGF 1,"SROM_Idle\n"
  1460.  
  1461.         call    SROM_EnterAccessMode
  1462.        
  1463. ;        set_io  [ebx + device.io_addr], 0
  1464. ;        set_io  [ebx + device.io_addr], CSR9
  1465.        
  1466.         mov     ecx, 25
  1467.      .loop_clk:
  1468.  
  1469.         Bit_Clear CSR9_SROM_CK
  1470.         SROM_Delay
  1471.         Bit_Set CSR9_SROM_CK
  1472.         SROM_Delay
  1473.        
  1474.         dec     ecx
  1475.         jnz     .loop_clk
  1476.  
  1477.        
  1478.         Bit_Clear CSR9_SROM_CK
  1479.         SROM_Delay
  1480.         Bit_Clear CSR9_SROM_CS
  1481.         SROM_Delay
  1482.        
  1483.         xor     eax, eax
  1484.         out     dx, eax
  1485.        
  1486.         ret
  1487.  
  1488.  
  1489. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1490. ;;                                                                      ;;
  1491. ;; Read serial EEprom word                                              ;;
  1492. ;;                                                                      ;;
  1493. ;; In: esi = read address                                               ;;
  1494. ;; OUT: ax = data word                                                  ;;
  1495. ;;                                                                      ;;
  1496. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1497. align 4
  1498. SROM_Read_Word:
  1499.  
  1500. ;        DEBUGF 1,"SROM_Read_word at: %x\n", esi
  1501.  
  1502.         set_io  [ebx + device.io_addr], 0
  1503.         set_io  [ebx + device.io_addr], CSR9
  1504.  
  1505. ; enter access mode
  1506.         mov     eax, CSR9_SR + CSR9_RD
  1507.         out     dx , eax
  1508.         or      eax, CSR9_SROM_CS
  1509.         out     dx , eax
  1510.  
  1511.         ; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
  1512.        
  1513. ; send read command "110b" + address to read from
  1514.         and     esi, 111111b
  1515.         or      esi, 110b shl 6
  1516.        
  1517.         mov     ecx, 1 shl 9
  1518.   .loop_cmd:
  1519.         mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
  1520.         test    esi, ecx
  1521.         jz      @f
  1522.         or      eax, CSR9_SROM_DI
  1523.        @@:
  1524.         out     dx , eax
  1525.         SROM_Delay
  1526.         or      eax, CSR9_SROM_CK
  1527.         out     dx , eax
  1528.         SROM_Delay
  1529.        
  1530.         shr     ecx, 1
  1531.         jnz     .loop_cmd
  1532.  
  1533. ; read data from SROM
  1534.  
  1535.         xor     esi, esi
  1536.         mov     ecx, 17 ;;; TODO: figure out why 17, not 16
  1537.   .loop_read:
  1538.        
  1539.         mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
  1540.         out     dx , eax
  1541.         SROM_Delay
  1542.        
  1543.         in      eax, dx
  1544.         and     eax, CSR9_SROM_DO
  1545.         shr     eax, 3
  1546.         shl     esi, 1
  1547.         or      esi, eax
  1548.        
  1549.         mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
  1550.         out     dx , eax
  1551.         SROM_Delay
  1552.        
  1553.         dec     ecx
  1554.         jnz     .loop_read
  1555.        
  1556.         mov     eax, esi
  1557.  
  1558. ;        DEBUGF 1,"%x\n", ax
  1559.  
  1560.         ret
  1561.  
  1562.  
  1563.  
  1564. ;*********************************************************************
  1565. ;* Media Descriptor Code                                             *
  1566. ;*********************************************************************
  1567.  
  1568. ; MII transceiver control section.
  1569. ; Read and write the MII registers using software-generated serial
  1570. ; MDIO protocol.  See the MII specifications or DP83840A data sheet
  1571. ; for details.
  1572.  
  1573. ; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
  1574. ; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
  1575. ; "overclocking" issues or future 66Mhz PCI.
  1576.  
  1577. ; Read and write the MII registers using software-generated serial
  1578. ; MDIO protocol.  It is just different enough from the EEPROM protocol
  1579. ; to not share code.  The maxium data clock rate is 2.5 Mhz.
  1580.  
  1581. MDIO_SHIFT_CLK          = 0x10000
  1582. MDIO_DATA_WRITE0        = 0x00000
  1583. MDIO_DATA_WRITE1        = 0x20000
  1584. MDIO_ENB                = 0x00000       ; Ignore the 0x02000 databook setting.
  1585. MDIO_ENB_IN             = 0x40000
  1586. MDIO_DATA_READ          = 0x80000
  1587.  
  1588. ; MII transceiver control section.
  1589. ; Read and write the MII registers using software-generated serial
  1590. ; MDIO protocol.  See the MII specifications or DP83840A data sheet
  1591. ; for details.
  1592.  
  1593. align 4
  1594. mdio_read:      ; phy_id:edx, location:esi
  1595.  
  1596.         DEBUGF  1,"mdio read, phy=%x, location=%x\n", edx, esi
  1597.  
  1598.         shl     edx, 5
  1599.         or      esi, edx
  1600.         or      esi, 0xf6 shl 10
  1601.  
  1602.         set_io  [ebx + device.io_addr], 0
  1603.         set_io  [ebx + device.io_addr], CSR9
  1604.  
  1605. ;    if (tp->chip_id == LC82C168) {
  1606. ;        int i = 1000;
  1607. ;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
  1608. ;        inl(ioaddr + 0xA0);
  1609. ;        inl(ioaddr + 0xA0);
  1610. ;        while (--i > 0)
  1611. ;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
  1612. ;                return retval & 0xffff;
  1613. ;        return 0xffff;
  1614. ;    }
  1615. ;
  1616. ;    if (tp->chip_id == COMET) {
  1617. ;        if (phy_id == 1) {
  1618. ;            if (location < 7)
  1619. ;                return inl(ioaddr + 0xB4 + (location<<2));
  1620. ;            else if (location == 17)
  1621. ;                return inl(ioaddr + 0xD0);
  1622. ;            else if (location >= 29 && location <= 31)
  1623. ;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
  1624. ;        }
  1625. ;        return 0xffff;
  1626. ;    }
  1627.  
  1628. ; Establish sync by sending at least 32 logic ones.
  1629.  
  1630.         mov     ecx, 32
  1631.   .loop:
  1632.         mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
  1633.         out     dx, eax
  1634.         MDIO_Delay
  1635.  
  1636.         or      eax, MDIO_SHIFT_CLK
  1637.         out     dx, eax
  1638.         MDIO_Delay
  1639.  
  1640.         dec     ecx
  1641.         jnz     .loop
  1642.  
  1643.  
  1644. ; Shift the read command bits out.
  1645.  
  1646.         mov     ecx, 1 shl 15
  1647.   .loop2:
  1648.         mov     eax, MDIO_ENB
  1649.         test    esi, ecx
  1650.         jz      @f
  1651.         or      eax, MDIO_DATA_WRITE1
  1652.        @@:
  1653.         out     dx, eax
  1654.         MDIO_Delay
  1655.  
  1656.         or      eax, MDIO_SHIFT_CLK
  1657.         out     dx, eax
  1658.         MDIO_Delay
  1659.  
  1660.         shr     ecx, 1
  1661.         jnz     .loop2
  1662.  
  1663.  
  1664. ; Read the two transition, 16 data, and wire-idle bits.
  1665.  
  1666.         xor     esi, esi
  1667.         mov     ecx, 19
  1668.   .loop3:
  1669.         mov     eax, MDIO_ENB_IN
  1670.         out     dx, eax
  1671.         MDIO_Delay
  1672.  
  1673.         shl     esi, 1
  1674.         in      eax, dx
  1675.         test    eax, MDIO_DATA_READ
  1676.         jz      @f
  1677.         inc     esi
  1678.        @@:
  1679.  
  1680.         mov     eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
  1681.         out     dx, eax
  1682.         MDIO_Delay
  1683.  
  1684.         dec     ecx
  1685.         jnz     .loop3
  1686.  
  1687.         shr     esi, 1
  1688.         movzx   eax, si
  1689.  
  1690.         DEBUGF  1,"data=%x\n", ax
  1691.  
  1692.         ret
  1693.  
  1694.  
  1695.  
  1696.  
  1697. align 4
  1698. mdio_write:     ;int phy_id: edx, int location: edi, int value: ax)
  1699.  
  1700.         DEBUGF  1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
  1701.  
  1702.         shl     edi, 18
  1703.         or      edi, 0x5002 shl 16
  1704.         shl     edx, 23
  1705.         or      edi, edx
  1706.         mov     di, ax
  1707.  
  1708.         set_io  [ebx + device.io_addr], 0
  1709.         set_io  [ebx + device.io_addr], CSR9
  1710.  
  1711. ;    if (tp->chip_id == LC82C168) {
  1712. ;        int i = 1000;
  1713. ;        outl(cmd, ioaddr + 0xA0);
  1714. ;        do
  1715. ;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
  1716. ;                break;
  1717. ;        while (--i > 0);
  1718. ;        return;
  1719. ;    }
  1720.  
  1721. ;    if (tp->chip_id == COMET) {
  1722. ;        if (phy_id != 1)
  1723. ;            return;
  1724. ;        if (location < 7)
  1725. ;            outl(value, ioaddr + 0xB4 + (location<<2));
  1726. ;        else if (location == 17)
  1727. ;            outl(value, ioaddr + 0xD0);
  1728. ;        else if (location >= 29 && location <= 31)
  1729. ;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
  1730. ;        return;
  1731. ;    }
  1732.  
  1733.  
  1734. ; Establish sync by sending at least 32 logic ones.
  1735.  
  1736.         mov     ecx, 32
  1737.   .loop:
  1738.         mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
  1739.         out     dx, eax
  1740.         MDIO_Delay
  1741.  
  1742.         or      eax, MDIO_SHIFT_CLK
  1743.         out     dx, eax
  1744.         MDIO_Delay
  1745.  
  1746.         dec     ecx
  1747.         jnz     .loop
  1748.  
  1749.  
  1750. ; Shift the command bits out.
  1751.  
  1752.         mov     ecx, 1 shl 31
  1753.   .loop2:
  1754.         mov     eax, MDIO_ENB
  1755.         test    edi, ecx
  1756.         jz      @f
  1757.         or      eax, MDIO_DATA_WRITE1
  1758.        @@:
  1759.         out     dx, eax
  1760.         MDIO_Delay
  1761.  
  1762.         or      eax, MDIO_SHIFT_CLK
  1763.         out     dx, eax
  1764.         MDIO_Delay
  1765.  
  1766.         shr     ecx, 1
  1767.         jnz     .loop2
  1768.  
  1769.  
  1770. ; Clear out extra bits.
  1771.  
  1772.         mov     ecx, 2
  1773.   .loop3:
  1774.         mov     eax, MDIO_ENB
  1775.         out     dx, eax
  1776.         MDIO_Delay
  1777.  
  1778.         or      eax, MDIO_SHIFT_CLK
  1779.         out     dx, eax
  1780.         MDIO_Delay
  1781.  
  1782.         dec     ecx
  1783.         jnz     .loop3
  1784.  
  1785.         ret
  1786.  
  1787.  
  1788.  
  1789.  
  1790.  
  1791.  
  1792. ; End of code
  1793.  
  1794. data fixups
  1795. end data
  1796.  
  1797. include '../peimport.inc'
  1798.  
  1799. my_service    db 'DEC21X4X',0                    ; max 16 chars include zero
  1800.  
  1801. chiplist:
  1802. ;   PCI id's , chip ,IO size, CSR7      , name  ,  flags
  1803. dd 0x00021011, DC21040,  128, 0x0001ebef, sz_040,  0
  1804. dd 0x00141011, DC21041,  128, 0x0001ebef, sz_041,  FLAG_HAS_MEDIA_TABLE
  1805. dd 0x00091011, DC21140,  128, 0x0001ebef, sz_140,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
  1806. dd 0x00191011, DC21143,  128, 0x0001ebef, sz_143,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_ALWAYS_CHECK_MII or FLAG_HAS_ACPI
  1807. dd 0x000211AD, LC82C168, 256, 0x0801fbff, sz_lite, FLAG_HAS_MII
  1808. dd 0x051210D9, MX98713,  128, 0x0001ebef, sz_m512, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE
  1809. dd 0x053110D9, MX98715,  256, 0x0001ebef, sz_m513, FLAG_HAS_MEDIA_TABLE
  1810. dd 0x1400125B, MX98725,  128, 0x0001fbff, sz_asix, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
  1811. dd 0
  1812.  
  1813. sz_040  db "Digital DC21040 Tulip", 0
  1814. sz_041  db "Digital DC21041 Tulip", 0
  1815. sz_140  db "Digital DS21140 Tulip", 0
  1816. sz_143  db "Digital DS21143 Tulip", 0
  1817. sz_lite db "Lite-On 82c168 PNIC", 0
  1818. sz_m512 db "Macronix 98713 PMAC", 0
  1819. sz_m513 db "Macronix 987x5 PMAC", 0
  1820. sz_asix db "ASIX AX88140", 0
  1821.  
  1822. include_debug_strings                           ; All data wich FDO uses will be included here
  1823.  
  1824. align 4
  1825. devices         dd 0
  1826. device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling