Subversion Repositories Kolibri OS

Rev

Rev 5363 | 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. ; Reset the xcvr interface and turn on heartbeat.
  598.         cmp     [ebx + device.id], DC21041
  599.         jne     @f
  600.         set_io  [ebx + device.io_addr], 0
  601.         set_io  [ebx + device.io_addr], CSR13
  602.         xor     eax, eax
  603.         out     dx, eax
  604.         set_io  [ebx + device.io_addr], CSR14
  605.         dec     eax
  606.         out     dx, eax
  607.         set_io  [ebx + device.io_addr], CSR15
  608.         inc     eax
  609.         mov     al, 8
  610.         out     dx, eax
  611.         set_io  [ebx + device.io_addr], CSR6
  612.         in      eax, dx
  613.         or      ax, CSR6_ST
  614.         out     dx, eax
  615.         set_io  [ebx + device.io_addr], CSR13
  616.         xor     eax, eax
  617.         mov     ax, 0xEF05
  618.         out     dx, eax
  619.         jmp     .reset_done
  620.   @@:
  621.         cmp     [ebx + device.id], DC21040
  622.         jne     @f
  623.         set_io  [ebx + device.io_addr], 0
  624.         set_io  [ebx + device.io_addr], CSR13
  625.         xor     eax, eax
  626.         out     dx, eax
  627.         mov     al, 4
  628.         out     dx, eax
  629.         jmp     .reset_done
  630.   @@:
  631.         cmp     [ebx + device.id], DC21140
  632.         jne     @f
  633.         set_io  [ebx + device.io_addr], 0
  634.         set_io  [ebx + device.io_addr], CSR12
  635.         mov     eax, 0x100
  636.         out     dx, eax
  637.         jmp     .reset_done
  638.   @@:
  639.         cmp     [ebx + device.id], DC21142
  640.         jne     @f
  641.         ; if tp->mii_cnt
  642.         set_io  [ebx + device.io_addr], 0
  643.         set_io  [ebx + device.io_addr], CSR6
  644.         mov     eax, 0x82020000
  645.         out     dx, eax
  646.         set_io  [ebx + device.io_addr], CSR13
  647.         xor     eax, eax
  648.         out     dx, eax
  649.         set_io  [ebx + device.io_addr], CSR14
  650.         out     dx, eax
  651.         set_io  [ebx + device.io_addr], CSR6
  652.         mov     eax, 0x820E0000
  653.         out     dx, eax
  654.         jmp     .reset_done
  655.         ;;;; TODO
  656.   @@:
  657.         cmp     [ebx + device.id], LC82C168
  658.         jne     @f
  659.         ; TODO
  660.   @@:
  661.         cmp     [ebx + device.id], MX98713
  662.         jne     @f
  663.         ; TODO
  664.   @@:
  665.  
  666.   .reset_done:
  667.  
  668.  
  669. ; OPEN
  670.  
  671. ; Reset chip
  672.         set_io  [ebx + device.io_addr], 0
  673.         set_io  [ebx + device.io_addr], CSR0
  674.         mov     eax, CSR0_RESET
  675.         out     dx, eax
  676.  
  677. ; wait at least 50 PCI cycles
  678.         mov     esi, 100
  679.         invoke  Sleep
  680.  
  681. ;-----------------------------------
  682. ; Read mac from eeprom to driver ram
  683.  
  684.         call    read_mac_eeprom
  685.  
  686. ;--------------------------------
  687. ; insert irq handler on given irq
  688.  
  689.         movzx   eax, [ebx + device.irq_line]
  690.         DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
  691.         invoke  AttachIntHandler, eax, int_handler, ebx
  692.         test    eax, eax
  693.         jnz     @f
  694.         DEBUGF  2,"Could not attach int handler!\n"
  695.         or      eax, -1
  696.         ret
  697.   @@:
  698.  
  699. ;----------------
  700. ; Set cache modes
  701.  
  702.         set_io  [ebx + device.io_addr], 0
  703.         set_io  [ebx + device.io_addr], CSR0
  704.         mov     eax, 0x01A00000 or 0x4800 ; CSR0_DEFAULT
  705.         out     dx, eax
  706.  
  707.         ; wait at least 50 PCI cycles
  708.         mov     esi, 100
  709.         invoke  Sleep
  710.  
  711. ;---------------------------
  712. ; Initialize RX and TX rings
  713.  
  714.         call    init_ring
  715.         test    eax, eax
  716.         jnz     .err
  717.  
  718. ;-------------------
  719. ; Set receive filter
  720.  
  721.         call    create_setup_frame
  722.  
  723. ;--------------------------------------------
  724. ; setup CSR3 & CSR4 (pointers to descriptors)
  725.  
  726.         lea     eax, [ebx + device.rx_ring]
  727.         invoke  GetPhysAddr
  728.         DEBUGF  1,"RX descriptor base address: %x\n", eax
  729.         set_io  [ebx + device.io_addr], 0
  730.         set_io  [ebx + device.io_addr], CSR3
  731.         out     dx, eax
  732.  
  733.         lea     eax, [ebx + device.tx_ring]
  734.         invoke  GetPhysAddr
  735.         DEBUGF  1,"TX descriptor base address: %x\n", eax
  736.         set_io  [ebx + device.io_addr], CSR4
  737.         out     dx, eax
  738.  
  739. ; Select media
  740.         push    [ebx + device.if_port]
  741.         pop     [ebx + device.saved_if_port]
  742.         cmp     [ebx + device.if_port], 0
  743.         jne     @f
  744.         push    [ebx + device.default_port]
  745.         pop     [ebx + device.if_port]
  746.   @@:
  747.         cmp     [ebx + device.id], DC21041
  748.         jne     @f
  749.         cmp     [ebx + device.if_port], 4
  750.         jbe     @f
  751.         ; invalid port, select inital TP, autosense, autonegotiate
  752.         mov     [ebx + device.if_port], 4                               ; CHECKME
  753.   @@:
  754.  
  755. ; Allow selecting a default media
  756.         cmp     [ebx + device.mtable], 0
  757.         je      .media_picked
  758.  
  759.         cmp     [ebx + device.if_port], 0
  760.         je      @f
  761.         ;; TODO
  762.         jmp     .media_picked
  763.   @@:
  764.  
  765.   .media_picked:
  766.         mov     [ebx + device.csr6], 0
  767.  
  768.         cmp     [ebx + device.id], DC21142
  769.         jne     @f
  770.         cmp     [ebx + device.if_port], 0
  771.         jne     @f
  772.         ;; TODO
  773.         mov     [ebx + device.csr6], 0x82420200
  774.         mov     [ebx + device.if_port], 11
  775.         set_io  [ebx + device.io_addr], 0
  776.         set_io  [ebx + device.io_addr], CSR14
  777.         mov     eax, 0x0003FFF
  778.         out     dx, eax
  779.         set_io  [ebx + device.io_addr], CSR15
  780.         xor     eax, eax
  781.         mov     al, 8
  782.         out     dx, eax
  783.         set_io  [ebx + device.io_addr], CSR13
  784.         mov     al, 1
  785.         out     dx, eax
  786.         set_io  [ebx + device.io_addr], CSR12
  787.         mov     ax, 0x1301
  788.         out     dx, eax
  789.  
  790.   @@:
  791.         cmp     [ebx + device.id], LC82C168
  792.         jne     @f
  793.         ;; TODO
  794.   @@:
  795.         cmp     [ebx + device.id], MX98713
  796.         jne     @f
  797.  
  798.   @@:
  799. ;; wait a bit
  800. ;        mov     esi, 500
  801. ;        invoke  Sleep
  802.  
  803. ; else:
  804.         xor     eax, eax
  805.         inc     eax
  806.         call    select_media
  807.  
  808. ; Start the chip's tx to process setup frame
  809.         set_io  [ebx + device.io_addr], 0
  810.         set_io  [ebx + device.io_addr], CSR6
  811.         mov     eax, [ebx + device.csr6]
  812.         out     dx, eax
  813.         or      ax, CSR6_ST
  814.         out     dx, eax
  815.  
  816. ; Enable interrupts by setting the interrupt mask.
  817.         set_io  [ebx + device.io_addr], CSR5
  818.         mov     eax, [ebx + device.csr7]
  819.         DEBUGF  1, "Setting CSR7 to 0x%x\n", eax
  820.         out     dx, eax
  821.         set_io  [ebx + device.io_addr], CSR7
  822.         out     dx, eax
  823.  
  824. ; Enable receiver
  825.         set_io  [ebx + device.io_addr], CSR6
  826.         mov     eax, [ebx + device.csr6]
  827.         or      eax, 0x2002 + CSR6_RA
  828.         out     dx, eax
  829.  
  830. ; RX poll demand
  831.         set_io  [ebx + device.io_addr], CSR2
  832.         xor     eax, eax
  833.         out     dx, eax
  834.  
  835. ; Set the mtu, kernel will be able to send now
  836.         mov     [ebx + device.mtu], 1514
  837.  
  838. ; Set link state to unknown
  839.         mov     [ebx + device.state], ETH_LINK_UNKNOWN
  840.  
  841.         DEBUGF  1,"Reset completed\n"
  842. ;        xor     eax, eax
  843.         ret
  844.  
  845.   .err:
  846.         DEBUGF  2,"Reset failed\n"
  847.         or      eax, -1
  848.         ret
  849.  
  850.  
  851.  
  852. align 4
  853. init_ring:
  854.  
  855.         DEBUGF  1,"Init ring\n"
  856.  
  857. ;---------------------
  858. ; Setup RX descriptors
  859.  
  860.         lea     eax, [ebx + device.rx_ring]
  861.         invoke  GetPhysAddr
  862.         mov     edx, eax
  863.         push    eax
  864.         lea     edi, [ebx + device.rx_ring]
  865.         mov     ecx, RX_RING_SIZE
  866.   .loop_rx_des:
  867.         DEBUGF  1,"RX descriptor 0x%x\n", edi
  868.         add     edx, sizeof.desc
  869.         mov     [edi + desc.status], DES0_OWN
  870.         mov     [edi + desc.length], 1514
  871.         push    edx edi ecx
  872.         invoke  NetAlloc, 1514+NET_BUFF.data
  873.         pop     ecx edi edx
  874.         test    eax, eax
  875.         jz      .out_of_mem
  876.         mov     [edi + RX_RING_SIZE*sizeof.desc], eax
  877.         push    edx
  878.         invoke  GetPhysAddr
  879.         add     eax, NET_BUFF.data
  880.         pop     edx
  881.         mov     [edi + desc.buffer1], eax
  882.         mov     [edi + desc.buffer2], edx
  883.         add     edi, sizeof.desc
  884.         dec     ecx
  885.         jnz     .loop_rx_des
  886.  
  887. ; set last descriptor as LAST
  888.         or      [edi - sizeof.desc + desc.length], RDES1_RER           ; EndOfRing
  889.         pop     [edi - sizeof.desc + desc.buffer2]                     ; point it to the first descriptor
  890.  
  891. ;---------------------
  892. ; Setup TX descriptors
  893.  
  894.         lea     eax, [ebx + device.tx_ring]
  895.         invoke  GetPhysAddr
  896.         mov     edx, eax
  897.         push    eax
  898.         lea     edi, [ebx + device.tx_ring]
  899.         mov     ecx, TX_RING_SIZE
  900.   .loop_tx_des:
  901.         DEBUGF  1,"TX descriptor 0x%x\n", edi
  902.         add     edx, sizeof.desc
  903.         mov     [edi + desc.status], 0                                  ; owned by driver
  904.         mov     [edi + desc.length], 0
  905.         mov     [edi + desc.buffer1], 0
  906.         mov     [edi + desc.buffer2], edx                               ; pointer to next descr
  907.         add     edi, sizeof.desc
  908.         dec     ecx
  909.         jnz     .loop_tx_des
  910. ; set last descriptor as LAST
  911.         or      [edi - sizeof.desc + desc.length], TDES1_TER            ; EndOfRing
  912.         pop     [edi - sizeof.desc + desc.buffer2]                      ; point it to the first descriptor
  913.  
  914. ;------------------
  915. ; Reset descriptors
  916.  
  917.         xor     eax, eax
  918.         mov     [ebx + device.cur_tx], eax
  919.         mov     [ebx + device.last_tx], eax
  920.         mov     [ebx + device.cur_rx], eax
  921.  
  922. ;        xor     eax, eax
  923.         ret
  924.  
  925.   .out_of_mem:
  926.         DEBUGF  2, "Out of memory!\n"
  927.         pop     eax
  928.         or      eax, -1
  929.         ret
  930.  
  931.  
  932. ; IN: eax = startup
  933. align 4
  934. select_media:
  935.  
  936.         DEBUGF  1, "Selecting media\n"
  937.  
  938.         cmp     [ebx + device.mtable], 0
  939.         je      .no_mtable
  940.         DEBUGF  1, "Device has a media table\n"
  941.  
  942.  
  943. ; default:
  944.         mov     eax, 0x020E0000
  945.         jmp     .update_csr6
  946.  
  947.   .no_mtable:
  948.         DEBUGF  1, "Device has no media table\n"
  949.  
  950.         cmp     [ebx + device.id], DC21041
  951.         jne     .not_41
  952.         DEBUGF  1, "DC21041\n"
  953.  
  954.         set_io  [ebx + device.io_addr], 0
  955.         set_io  [ebx + device.io_addr], CSR13
  956.         xor     eax, eax
  957.         out     dx, eax         ; reset serial interface
  958.         set_io  [ebx + device.io_addr], CSR14
  959.         mov     eax, 0x7F3F     ;0x7F3F     ;0x7F3D     ; 10T-FD
  960.         out     dx, eax
  961.         set_io  [ebx + device.io_addr], CSR15
  962.         mov     eax, 0x0008     ;0x0008     ;0x0008     ; 10T-FD
  963.         out     dx, eax
  964.         set_io  [ebx + device.io_addr], CSR13
  965.         mov     eax, 0xEF05     ;0xEF01     ;0xEF09     ; 10T-FD
  966.         out     dx, eax
  967.         mov     eax, 0x80020000
  968.         jmp     .update_csr6
  969.   .not_41:
  970.         cmp     [ebx + device.id], LC82C168
  971.         jne     .not_LC
  972.         DEBUGF  1, "LC82C168\n"
  973.  
  974.         ;; TODO
  975.  
  976.         mov     eax, 0x812C0000
  977.         jmp     .update_csr6
  978.   .not_LC:
  979.         cmp     [ebx + device.id], DC21040
  980.         jne     .not_40
  981.         DEBUGF  1, "DC21040\n"
  982.  
  983.         set_io  [ebx + device.io_addr], 0
  984.         set_io  [ebx + device.io_addr], CSR11
  985.         mov     eax, FULL_DUPLEX_MAGIC
  986.         out     dx, eax
  987.         ; reset serial interface
  988.         set_io  [ebx + device.io_addr], CSR13
  989.         xor     eax, eax
  990.         out     dx, eax
  991.  
  992.         set_io  [ebx + device.io_addr], CSR13
  993.         xor     eax, eax
  994.         cmp     [ebx + device.if_port], 0
  995.         je      @f
  996.         mov     al, 0xc
  997.         out     dx, eax
  998.         mov     eax, 0x01860000
  999.         jmp     .update_csr6
  1000.   @@:
  1001.         mov     al, 4
  1002.         out     dx, eax
  1003.         mov     eax, 0x00420000
  1004.         jmp     .update_csr6
  1005.  
  1006.   .not_40:
  1007.         DEBUGF  1, "Unkown chip with no media table\n"
  1008.  
  1009.         cmp     [ebx + device.default_port], 0
  1010.         jne     .not_0
  1011.         cmp     [ebx + device.mii_cnt], 0
  1012.         je      @f
  1013.         mov     [ebx + device.if_port], 11
  1014.         jmp     .not_0
  1015.   @@:
  1016.         mov     [ebx + device.if_port], 3
  1017.   .not_0:
  1018.         mov     eax, 0x020E0000 ;;;;;
  1019.  
  1020.   .update_csr6:
  1021.         and     [ebx + device.csr6], 0xfdff
  1022.         or      ax, 0x0200                     ;; FULL DUPLEX
  1023.         or      [ebx + device.csr6], eax
  1024.         DEBUGF  1, "new CSR6: 0x%x\n", [ebx + device.csr6]
  1025.  
  1026.         ret
  1027.  
  1028.  
  1029. align 4
  1030. start_link:
  1031.  
  1032.         DEBUGF  1,"Starting link\n"
  1033.  
  1034.         ; TODO: write working code here
  1035.  
  1036.         ret
  1037.  
  1038. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1039. ;;                                         ;;
  1040. ;; Send setup packet                       ;;
  1041. ;;                                         ;;
  1042. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1043.  
  1044. align 4
  1045. create_setup_frame:
  1046.  
  1047.         DEBUGF  1,"Creating setup packet\n"
  1048.  
  1049.         invoke  NetAlloc, 192 + NET_BUFF.data
  1050.         test    eax, eax
  1051.         jz      .err
  1052.         mov     [eax + NET_BUFF.device], ebx
  1053.         mov     [eax + NET_BUFF.length], 192
  1054.  
  1055.         push    eax
  1056.  
  1057.         lea     edi, [eax + NET_BUFF.data]
  1058.         xor     eax, eax
  1059.         dec     ax
  1060.         stosd
  1061.         stosd
  1062.         stosd
  1063.  
  1064.         mov     ecx, 15
  1065.   .loop:
  1066.         lea     esi, [ebx + device.mac]
  1067.         lodsw
  1068.         stosd
  1069.         dec     ecx
  1070.         jnz     .loop
  1071.  
  1072.         pop     eax
  1073.  
  1074. ; setup descriptor
  1075.         lea     edi, [ebx + device.tx_ring]
  1076.         DEBUGF  1, "attaching setup packet 0x%x to descriptor 0x%x\n", eax, edi
  1077.         mov     [edi + TX_RING_SIZE*sizeof.desc], eax
  1078.         invoke  GetPhysAddr
  1079.         add     eax, NET_BUFF.data
  1080.         mov     [edi + desc.buffer1], eax
  1081.         mov     [edi + desc.length], TDES1_SET or 192       ; size must be EXACTLY 192 bytes + TDES1_IC
  1082.         mov     [edi + desc.status], DES0_OWN
  1083.         DEBUGF  1, "descriptor 0x%x\n", edi
  1084.  
  1085. ; go to next descriptor
  1086.         inc     [ebx + device.cur_tx]
  1087.         and     [ebx + device.cur_tx], TX_RING_SIZE-1
  1088.  
  1089.         xor     eax, eax
  1090.         ret
  1091.  
  1092.   .err:
  1093.         DEBUGF  2, "Out of memory!\n"
  1094.         or      eax, -1
  1095.         ret
  1096.  
  1097.  
  1098.  
  1099. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1100. ;;                                         ;;
  1101. ;; Transmit                                ;;
  1102. ;;                                         ;;
  1103. ;; In:  ebx = pointer to device structure  ;;
  1104. ;; Out: eax = 0 on success                 ;;
  1105. ;;                                         ;;
  1106. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1107.  
  1108. proc transmit stdcall bufferptr
  1109.  
  1110.         pushf
  1111.         cli
  1112.  
  1113.         mov     esi, [bufferptr]
  1114.         DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
  1115.         lea     eax, [esi + NET_BUFF.data]
  1116.         DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
  1117.         [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
  1118.         [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
  1119.         [eax+13]:2,[eax+12]:2
  1120.  
  1121.         cmp     [esi + NET_BUFF.length], 1514
  1122.         ja      .fail
  1123.         cmp     [esi + NET_BUFF.length], 60
  1124.         jb      .fail
  1125.  
  1126.         mov     eax, [ebx + device.cur_tx]
  1127.         mov     edx, sizeof.desc
  1128.         mul     edx
  1129.         lea     edi, [ebx + device.tx_ring + eax]
  1130.         test    [edi + desc.status], DES0_OWN
  1131.         jnz     .fail
  1132.  
  1133.         mov     eax, [bufferptr]
  1134.         mov     [edi + TX_RING_SIZE*sizeof.desc], eax
  1135.         add     eax, [eax + NET_BUFF.offset]
  1136.         invoke  GetPhysAddr
  1137.         mov     [edi + desc.buffer1], eax
  1138.  
  1139. ; set packet size
  1140.         mov     eax, [edi + desc.length]
  1141.         and     eax, TDES1_TER                          ; preserve 'End of Ring' bit
  1142.         or      eax, [esi + NET_BUFF.length]            ; set size
  1143.         or      eax, TDES1_FS or TDES1_LS or TDES1_IC   ; first descr, last descr, interrupt on complete
  1144.         mov     [edi + desc.length], eax
  1145.  
  1146. ; set descriptor status
  1147.         mov     [edi + desc.status], DES0_OWN            ; say it is now owned by the 21x4x
  1148.  
  1149. ; Check if transmitter is running
  1150.         set_io  [ebx + device.io_addr], 0
  1151.         set_io  [ebx + device.io_addr], CSR6
  1152.         in      eax, dx
  1153.         test    eax, CSR6_ST                            ; if NOT started, start now
  1154.         jnz     .already_started
  1155.         or      eax, CSR6_ST
  1156.         DEBUGF  1,"(Re) starting TX\n"
  1157.         jmp     .do_it
  1158.   .already_started:
  1159.  
  1160. ; Trigger immediate transmit demand
  1161.         set_io  [ebx + device.io_addr], CSR1
  1162.         xor     eax, eax
  1163.   .do_it:
  1164.         out     dx, eax
  1165.  
  1166. ; Update stats
  1167.         inc     [ebx + device.packets_tx]
  1168.         mov     ecx, [esi + NET_BUFF.length]
  1169.         add     dword [ebx + device.bytes_tx], ecx
  1170.         adc     dword [ebx + device.bytes_tx + 4], 0
  1171.  
  1172. ; go to next descriptor
  1173.         inc     [ebx + device.cur_tx]
  1174.         and     [ebx + device.cur_tx], TX_RING_SIZE-1
  1175.  
  1176.         DEBUGF  1,"Transmit ok\n"
  1177.         popf
  1178.         xor     eax, eax
  1179.         ret
  1180.  
  1181.   .fail:
  1182.         DEBUGF  1,"Transmit failed\n"
  1183.         invoke  NetFree, [bufferptr]
  1184.         popf
  1185.         or      eax, -1
  1186.         ret
  1187.  
  1188. endp
  1189.  
  1190. ;;;;;;;;;;;;;;;;;;;;;;;
  1191. ;;                   ;;
  1192. ;; Interrupt handler ;;
  1193. ;;                   ;;
  1194. ;;;;;;;;;;;;;;;;;;;;;;;
  1195.  
  1196. align 4
  1197. int_handler:
  1198.  
  1199.         push    ebx esi edi
  1200.  
  1201.         DEBUGF  1,"INT\n"
  1202.  
  1203. ; find pointer of device wich made IRQ occur
  1204.  
  1205.         mov     ecx, [devices]
  1206.         test    ecx, ecx
  1207.         jz      .nothing
  1208.         mov     esi, device_list
  1209.   .nextdevice:
  1210.         mov     ebx, [esi]
  1211.  
  1212.         set_io  [ebx + device.io_addr], 0
  1213.         set_io  [ebx + device.io_addr], CSR5
  1214.         in      eax, dx
  1215.         and     eax, 0x0001ffff
  1216.         out     dx, eax                                 ; send it back to ACK
  1217.         jnz     .got_it
  1218.   .continue:
  1219.         add     esi, 4
  1220.         dec     ecx
  1221.         jnz     .nextdevice
  1222.   .nothing:
  1223.         pop     edi esi ebx
  1224.         xor     eax, eax
  1225.  
  1226.         ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
  1227.  
  1228.   .got_it:
  1229.         DEBUGF  1,"Device: %x CSR5: %x\n", ebx, eax
  1230.  
  1231. ;----------------------------------
  1232. ; TX ok?
  1233.  
  1234.         test    eax, CSR5_TI
  1235.         jz      .not_tx
  1236.  
  1237.         push    eax esi ecx
  1238.         DEBUGF  1,"TX ok!\n"
  1239.       .loop_tx:
  1240.         ; get last descriptor
  1241.         mov     eax, [ebx + device.last_tx]
  1242.         mov     edx, sizeof.desc
  1243.         mul     edx
  1244.         lea     eax, [ebx + device.tx_ring + eax]
  1245.  
  1246.         DEBUGF  1,"descriptor 0x%x\n", eax
  1247.         test    [eax + desc.status], DES0_OWN           ; owned by the card?
  1248.         jnz     .end_tx
  1249.         cmp     [eax + desc.buffer1], 0                 ; empty descriptor?
  1250.         je      .end_tx
  1251.  
  1252.         mov     [eax + desc.buffer1], 0
  1253.         DEBUGF  1, "Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc]
  1254.         invoke  NetFree, [eax + TX_RING_SIZE*sizeof.desc]
  1255.  
  1256.         ; advance to next descriptor
  1257.         inc     [ebx + device.last_tx]
  1258.         and     [ebx + device.last_tx], TX_RING_SIZE-1
  1259.  
  1260.         jmp     .loop_tx
  1261.   .end_tx:
  1262.         pop     ecx esi eax
  1263.   .not_tx:
  1264.  
  1265. ;----------------------------------
  1266. ; RX irq
  1267.         test    eax, CSR5_RI
  1268.         jz      .not_rx
  1269.         push    eax esi ecx
  1270.  
  1271.         DEBUGF 1,"RX ok!\n"
  1272.  
  1273.         push    ebx
  1274.   .rx_loop:
  1275.         pop     ebx
  1276.  
  1277.         ; get current descriptor
  1278.         mov     eax, [ebx + device.cur_rx]
  1279.         mov     edx, sizeof.desc
  1280.         mul     edx
  1281.         lea     edi, [ebx + device.rx_ring + eax]
  1282.  
  1283.         ; now check status
  1284.         mov     eax, [edi + desc.status]
  1285.  
  1286.         test    eax, DES0_OWN
  1287.         jnz     .end_rx                                 ; current desc is busy, nothing to do
  1288.         test    eax, RDES0_FS
  1289.         jz      .end_rx                                 ; current desc is NOT first packet, ERROR!
  1290.         test    eax, RDES0_LS                           ; if not last desc of packet, error for now
  1291.         jz      .end_rx
  1292.         test    eax, RDES0_ES
  1293.         jnz     .end_rx
  1294.  
  1295. ; Calculate length
  1296.         mov     ecx, [edi + desc.status]
  1297.         shr     ecx, RDES0_FL_SH
  1298.         and     ecx, RDES0_FL_MASK
  1299.         sub     ecx, 4                                  ; throw away the CRC
  1300.         DEBUGF  1,"got %u bytes\n", ecx
  1301.  
  1302. ; Push arguments for EthInput (and some more...)
  1303.         push    ebx
  1304.         push    .rx_loop                                ; return addr
  1305.         mov     eax, dword[edi + RX_RING_SIZE*sizeof.desc]
  1306.         push    eax
  1307.         mov     [eax + NET_BUFF.length], ecx
  1308.         mov     [eax + NET_BUFF.device], ebx
  1309.         mov     [eax + NET_BUFF.offset], NET_BUFF.data
  1310.  
  1311. ; update statistics
  1312.         inc     [ebx + device.packets_rx]
  1313.         add     dword[ebx + device.bytes_rx], ecx
  1314.         adc     dword[ebx + device.bytes_rx + 4], 0
  1315.  
  1316. ; Allocate new descriptor
  1317.         push    edi ebx
  1318.         invoke  NetAlloc, 1514 + NET_BUFF.data          ; Allocate a buffer to put packet into
  1319.         pop     ebx edi
  1320.         jz      .fail
  1321.         mov     [edi + RX_RING_SIZE*sizeof.desc], eax
  1322.         invoke  GetPhysAddr
  1323.         add     eax, NET_BUFF.data
  1324.         mov     [edi + desc.buffer1], eax
  1325.         mov     [edi + desc.status], DES0_OWN           ; mark descriptor as being free
  1326.  
  1327. ; Move to next rx desc
  1328.         inc     [ebx + device.cur_rx]                   ; next descriptor
  1329.         and     [ebx + device.cur_rx], RX_RING_SIZE-1
  1330.  
  1331.         jmp     [EthInput]
  1332.   .end_rx:
  1333.   .fail:
  1334.         pop     ecx esi eax
  1335.   .not_rx:
  1336.  
  1337.         pop     edi esi ebx
  1338.         ret
  1339.  
  1340.  
  1341.  
  1342. align 4
  1343. write_mac:      ; in: mac pushed onto stack (as 3 words)
  1344.  
  1345.         DEBUGF  1,"Writing MAC\n"
  1346.  
  1347. ; write data into driver cache
  1348.         mov     esi, esp
  1349.         lea     edi, [ebx + device.mac]
  1350.         movsd
  1351.         movsw
  1352.         add     esp, 6
  1353.        
  1354. ;; send setup packet (only if driver is started)
  1355. ;;        call    Create_Setup_Packet
  1356.  
  1357. align 4
  1358. read_mac_eeprom:
  1359.  
  1360.         DEBUGF  1,"Reading MAC from eeprom\n"
  1361.  
  1362.         lea     edi, [ebx + device.mac]
  1363.         mov     esi, 20/2               ; read words, start address is 20
  1364.      .loop:
  1365.         push    esi edi
  1366.         call    SROM_Read_Word
  1367.         pop     edi esi
  1368.         stosw
  1369.         inc     esi
  1370.         cmp     esi, 26/2
  1371.         jb      .loop
  1372.  
  1373.         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
  1374.  
  1375.         ret
  1376.  
  1377.  
  1378. align 4
  1379. SROM_GetWidth:  ; should be 6 or 8 according to some manuals (returns in ecx)
  1380.  
  1381. ;        DEBUGF 1,"SROM_GetWidth\n"
  1382.  
  1383.         call    SROM_Idle
  1384.         call    SROM_EnterAccessMode
  1385.  
  1386. ;        set_io  [ebx + device.io_addr], 0
  1387. ;        set_io  [ebx + device.io_addr], CSR9
  1388.  
  1389.         ; send 110b
  1390.  
  1391.         in      eax, dx
  1392.         or      eax, CSR9_SROM_DI
  1393.         call    SROM_out
  1394.  
  1395.         in      eax, dx
  1396.         or      eax, CSR9_SROM_DI
  1397.         call    SROM_out
  1398.  
  1399.         in      eax, dx
  1400.         and     eax, not (CSR9_SROM_DI)
  1401.         call    SROM_out
  1402.        
  1403.         mov     ecx,1
  1404.   .loop2:
  1405.         Bit_Set CSR9_SROM_CK
  1406.         SROM_Delay
  1407.        
  1408.         in      eax, dx
  1409.         and     eax, CSR9_SROM_DO
  1410.         jnz     .not_zero
  1411.  
  1412.         Bit_Clear CSR9_SROM_CK
  1413.         SROM_Delay
  1414.         jmp     .end_loop2
  1415.   .not_zero:
  1416.        
  1417.         Bit_Clear CSR9_SROM_CK
  1418.         SROM_Delay
  1419.        
  1420.         inc     ecx
  1421.         cmp     ecx, 12
  1422.         jbe     .loop2
  1423.   .end_loop2:
  1424.        
  1425.         DEBUGF  1,"SROM width=%u\n", ecx
  1426.        
  1427.         call    SROM_Idle
  1428.         call    SROM_EnterAccessMode
  1429.         call    SROM_Idle
  1430.        
  1431.         ret
  1432.  
  1433.  
  1434. align 4
  1435. SROM_out:
  1436.  
  1437.         out     dx, eax
  1438.         SROM_Delay
  1439.         Bit_Set CSR9_SROM_CK
  1440.         SROM_Delay
  1441.         Bit_Clear CSR9_SROM_CK
  1442.         SROM_Delay
  1443.  
  1444.         ret
  1445.  
  1446.  
  1447.  
  1448. align 4
  1449. SROM_EnterAccessMode:
  1450.  
  1451. ;        DEBUGF 1,"SROM_EnterAccessMode\n"
  1452.  
  1453.         set_io  [ebx + device.io_addr], 0
  1454.         set_io  [ebx + device.io_addr], CSR9
  1455.         mov     eax, CSR9_SR
  1456.         out     dx, eax
  1457.         SROM_Delay
  1458.  
  1459.         Bit_Set CSR9_RD
  1460.         SROM_Delay
  1461.  
  1462.         Bit_Clear CSR9_SROM_CK
  1463.         SROM_Delay
  1464.  
  1465.         Bit_Set CSR9_SROM_CS
  1466.         SROM_Delay
  1467.        
  1468.         ret
  1469.  
  1470.  
  1471.  
  1472. align 4
  1473. SROM_Idle:
  1474.  
  1475. ;        DEBUGF 1,"SROM_Idle\n"
  1476.  
  1477.         call    SROM_EnterAccessMode
  1478.        
  1479. ;        set_io  [ebx + device.io_addr], 0
  1480. ;        set_io  [ebx + device.io_addr], CSR9
  1481.        
  1482.         mov     ecx, 25
  1483.      .loop_clk:
  1484.  
  1485.         Bit_Clear CSR9_SROM_CK
  1486.         SROM_Delay
  1487.         Bit_Set CSR9_SROM_CK
  1488.         SROM_Delay
  1489.        
  1490.         dec     ecx
  1491.         jnz     .loop_clk
  1492.  
  1493.        
  1494.         Bit_Clear CSR9_SROM_CK
  1495.         SROM_Delay
  1496.         Bit_Clear CSR9_SROM_CS
  1497.         SROM_Delay
  1498.        
  1499.         xor     eax, eax
  1500.         out     dx, eax
  1501.        
  1502.         ret
  1503.  
  1504.  
  1505. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1506. ;;                                                                      ;;
  1507. ;; Read serial EEprom word                                              ;;
  1508. ;;                                                                      ;;
  1509. ;; In: esi = read address                                               ;;
  1510. ;; OUT: ax = data word                                                  ;;
  1511. ;;                                                                      ;;
  1512. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1513. align 4
  1514. SROM_Read_Word:
  1515.  
  1516. ;        DEBUGF 1,"SROM_Read_word at: %x\n", esi
  1517.  
  1518.         set_io  [ebx + device.io_addr], 0
  1519.         set_io  [ebx + device.io_addr], CSR9
  1520.  
  1521. ; enter access mode
  1522.         mov     eax, CSR9_SR + CSR9_RD
  1523.         out     dx , eax
  1524.         or      eax, CSR9_SROM_CS
  1525.         out     dx , eax
  1526.  
  1527.         ; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
  1528.        
  1529. ; send read command "110b" + address to read from
  1530.         and     esi, 111111b
  1531.         or      esi, 110b shl 6
  1532.        
  1533.         mov     ecx, 1 shl 9
  1534.   .loop_cmd:
  1535.         mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
  1536.         test    esi, ecx
  1537.         jz      @f
  1538.         or      eax, CSR9_SROM_DI
  1539.        @@:
  1540.         out     dx , eax
  1541.         SROM_Delay
  1542.         or      eax, CSR9_SROM_CK
  1543.         out     dx , eax
  1544.         SROM_Delay
  1545.        
  1546.         shr     ecx, 1
  1547.         jnz     .loop_cmd
  1548.  
  1549. ; read data from SROM
  1550.  
  1551.         xor     esi, esi
  1552.         mov     ecx, 17 ;;; TODO: figure out why 17, not 16
  1553.   .loop_read:
  1554.        
  1555.         mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
  1556.         out     dx , eax
  1557.         SROM_Delay
  1558.        
  1559.         in      eax, dx
  1560.         and     eax, CSR9_SROM_DO
  1561.         shr     eax, 3
  1562.         shl     esi, 1
  1563.         or      esi, eax
  1564.        
  1565.         mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
  1566.         out     dx , eax
  1567.         SROM_Delay
  1568.        
  1569.         dec     ecx
  1570.         jnz     .loop_read
  1571.        
  1572.         mov     eax, esi
  1573.  
  1574. ;        DEBUGF 1,"%x\n", ax
  1575.  
  1576.         ret
  1577.  
  1578.  
  1579.  
  1580. ;*********************************************************************
  1581. ;* Media Descriptor Code                                             *
  1582. ;*********************************************************************
  1583.  
  1584. ; MII transceiver control section.
  1585. ; Read and write the MII registers using software-generated serial
  1586. ; MDIO protocol.  See the MII specifications or DP83840A data sheet
  1587. ; for details.
  1588.  
  1589. ; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
  1590. ; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
  1591. ; "overclocking" issues or future 66Mhz PCI.
  1592.  
  1593. ; Read and write the MII registers using software-generated serial
  1594. ; MDIO protocol.  It is just different enough from the EEPROM protocol
  1595. ; to not share code.  The maxium data clock rate is 2.5 Mhz.
  1596.  
  1597. MDIO_SHIFT_CLK          = 0x10000
  1598. MDIO_DATA_WRITE0        = 0x00000
  1599. MDIO_DATA_WRITE1        = 0x20000
  1600. MDIO_ENB                = 0x00000       ; Ignore the 0x02000 databook setting.
  1601. MDIO_ENB_IN             = 0x40000
  1602. MDIO_DATA_READ          = 0x80000
  1603.  
  1604. ; MII transceiver control section.
  1605. ; Read and write the MII registers using software-generated serial
  1606. ; MDIO protocol.  See the MII specifications or DP83840A data sheet
  1607. ; for details.
  1608.  
  1609. align 4
  1610. mdio_read:      ; phy_id:edx, location:esi
  1611.  
  1612.         DEBUGF  1,"mdio read, phy=%x, location=%x\n", edx, esi
  1613.  
  1614.         shl     edx, 5
  1615.         or      esi, edx
  1616.         or      esi, 0xf6 shl 10
  1617.  
  1618.         set_io  [ebx + device.io_addr], 0
  1619.         set_io  [ebx + device.io_addr], CSR9
  1620.  
  1621. ;    if (tp->chip_id == LC82C168) {
  1622. ;        int i = 1000;
  1623. ;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
  1624. ;        inl(ioaddr + 0xA0);
  1625. ;        inl(ioaddr + 0xA0);
  1626. ;        while (--i > 0)
  1627. ;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
  1628. ;                return retval & 0xffff;
  1629. ;        return 0xffff;
  1630. ;    }
  1631. ;
  1632. ;    if (tp->chip_id == COMET) {
  1633. ;        if (phy_id == 1) {
  1634. ;            if (location < 7)
  1635. ;                return inl(ioaddr + 0xB4 + (location<<2));
  1636. ;            else if (location == 17)
  1637. ;                return inl(ioaddr + 0xD0);
  1638. ;            else if (location >= 29 && location <= 31)
  1639. ;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
  1640. ;        }
  1641. ;        return 0xffff;
  1642. ;    }
  1643.  
  1644. ; Establish sync by sending at least 32 logic ones.
  1645.  
  1646.         mov     ecx, 32
  1647.   .loop:
  1648.         mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
  1649.         out     dx, eax
  1650.         MDIO_Delay
  1651.  
  1652.         or      eax, MDIO_SHIFT_CLK
  1653.         out     dx, eax
  1654.         MDIO_Delay
  1655.  
  1656.         dec     ecx
  1657.         jnz     .loop
  1658.  
  1659.  
  1660. ; Shift the read command bits out.
  1661.  
  1662.         mov     ecx, 1 shl 15
  1663.   .loop2:
  1664.         mov     eax, MDIO_ENB
  1665.         test    esi, ecx
  1666.         jz      @f
  1667.         or      eax, MDIO_DATA_WRITE1
  1668.        @@:
  1669.         out     dx, eax
  1670.         MDIO_Delay
  1671.  
  1672.         or      eax, MDIO_SHIFT_CLK
  1673.         out     dx, eax
  1674.         MDIO_Delay
  1675.  
  1676.         shr     ecx, 1
  1677.         jnz     .loop2
  1678.  
  1679.  
  1680. ; Read the two transition, 16 data, and wire-idle bits.
  1681.  
  1682.         xor     esi, esi
  1683.         mov     ecx, 19
  1684.   .loop3:
  1685.         mov     eax, MDIO_ENB_IN
  1686.         out     dx, eax
  1687.         MDIO_Delay
  1688.  
  1689.         shl     esi, 1
  1690.         in      eax, dx
  1691.         test    eax, MDIO_DATA_READ
  1692.         jz      @f
  1693.         inc     esi
  1694.        @@:
  1695.  
  1696.         mov     eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
  1697.         out     dx, eax
  1698.         MDIO_Delay
  1699.  
  1700.         dec     ecx
  1701.         jnz     .loop3
  1702.  
  1703.         shr     esi, 1
  1704.         movzx   eax, si
  1705.  
  1706.         DEBUGF  1,"data=%x\n", ax
  1707.  
  1708.         ret
  1709.  
  1710.  
  1711.  
  1712.  
  1713. align 4
  1714. mdio_write:     ;int phy_id: edx, int location: edi, int value: ax)
  1715.  
  1716.         DEBUGF  1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
  1717.  
  1718.         shl     edi, 18
  1719.         or      edi, 0x5002 shl 16
  1720.         shl     edx, 23
  1721.         or      edi, edx
  1722.         mov     di, ax
  1723.  
  1724.         set_io  [ebx + device.io_addr], 0
  1725.         set_io  [ebx + device.io_addr], CSR9
  1726.  
  1727. ;    if (tp->chip_id == LC82C168) {
  1728. ;        int i = 1000;
  1729. ;        outl(cmd, ioaddr + 0xA0);
  1730. ;        do
  1731. ;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
  1732. ;                break;
  1733. ;        while (--i > 0);
  1734. ;        return;
  1735. ;    }
  1736.  
  1737. ;    if (tp->chip_id == COMET) {
  1738. ;        if (phy_id != 1)
  1739. ;            return;
  1740. ;        if (location < 7)
  1741. ;            outl(value, ioaddr + 0xB4 + (location<<2));
  1742. ;        else if (location == 17)
  1743. ;            outl(value, ioaddr + 0xD0);
  1744. ;        else if (location >= 29 && location <= 31)
  1745. ;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
  1746. ;        return;
  1747. ;    }
  1748.  
  1749.  
  1750. ; Establish sync by sending at least 32 logic ones.
  1751.  
  1752.         mov     ecx, 32
  1753.   .loop:
  1754.         mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
  1755.         out     dx, eax
  1756.         MDIO_Delay
  1757.  
  1758.         or      eax, MDIO_SHIFT_CLK
  1759.         out     dx, eax
  1760.         MDIO_Delay
  1761.  
  1762.         dec     ecx
  1763.         jnz     .loop
  1764.  
  1765.  
  1766. ; Shift the command bits out.
  1767.  
  1768.         mov     ecx, 1 shl 31
  1769.   .loop2:
  1770.         mov     eax, MDIO_ENB
  1771.         test    edi, ecx
  1772.         jz      @f
  1773.         or      eax, MDIO_DATA_WRITE1
  1774.        @@:
  1775.         out     dx, eax
  1776.         MDIO_Delay
  1777.  
  1778.         or      eax, MDIO_SHIFT_CLK
  1779.         out     dx, eax
  1780.         MDIO_Delay
  1781.  
  1782.         shr     ecx, 1
  1783.         jnz     .loop2
  1784.  
  1785.  
  1786. ; Clear out extra bits.
  1787.  
  1788.         mov     ecx, 2
  1789.   .loop3:
  1790.         mov     eax, MDIO_ENB
  1791.         out     dx, eax
  1792.         MDIO_Delay
  1793.  
  1794.         or      eax, MDIO_SHIFT_CLK
  1795.         out     dx, eax
  1796.         MDIO_Delay
  1797.  
  1798.         dec     ecx
  1799.         jnz     .loop3
  1800.  
  1801.         ret
  1802.  
  1803.  
  1804.  
  1805.  
  1806.  
  1807.  
  1808. ; End of code
  1809.  
  1810. data fixups
  1811. end data
  1812.  
  1813. include '../peimport.inc'
  1814.  
  1815. my_service    db 'DEC21X4X',0                    ; max 16 chars include zero
  1816.  
  1817. chiplist:
  1818. ;   PCI id's , chip ,IO size, CSR7      , name  ,  flags
  1819. dd 0x00021011, DC21040,  128, 0x0001ebef, sz_040,  0
  1820. dd 0x00141011, DC21041,  128, 0x0001ebef, sz_041,  FLAG_HAS_MEDIA_TABLE
  1821. dd 0x00091011, DC21140,  128, 0x0001ebef, sz_140,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
  1822. dd 0x00191011, DC21143,  128, 0x0001ebef, sz_143,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_ALWAYS_CHECK_MII or FLAG_HAS_ACPI
  1823. dd 0x000211AD, LC82C168, 256, 0x0801fbff, sz_lite, FLAG_HAS_MII
  1824. dd 0x051210D9, MX98713,  128, 0x0001ebef, sz_m512, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE
  1825. dd 0x053110D9, MX98715,  256, 0x0001ebef, sz_m513, FLAG_HAS_MEDIA_TABLE
  1826. dd 0x1400125B, MX98725,  128, 0x0001fbff, sz_asix, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
  1827. dd 0
  1828.  
  1829. sz_040  db "Digital DC21040 Tulip", 0
  1830. sz_041  db "Digital DC21041 Tulip", 0
  1831. sz_140  db "Digital DS21140 Tulip", 0
  1832. sz_143  db "Digital DS21143 Tulip", 0
  1833. sz_lite db "Lite-On 82c168 PNIC", 0
  1834. sz_m512 db "Macronix 98713 PMAC", 0
  1835. sz_m513 db "Macronix 987x5 PMAC", 0
  1836. sz_asix db "ASIX AX88140", 0
  1837.  
  1838. include_debug_strings                           ; All data wich FDO uses will be included here
  1839.  
  1840. align 4
  1841. devices         dd 0
  1842. device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling