Subversion Repositories Kolibri OS

Rev

Rev 3201 | Blame | Last modification | View Log | Download | RSS feed

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