Subversion Repositories Kolibri OS

Rev

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

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