Subversion Repositories Kolibri OS

Rev

Rev 5046 | Rev 5180 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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