Subversion Repositories Kolibri OS

Rev

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