Subversion Repositories Kolibri OS

Rev

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

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