Subversion Repositories Kolibri OS

Rev

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

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