Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 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
4334 hidnplayr 625
        DEBUGF  2,"Could not attach int handler!\n"
3545 hidnplayr 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
3639 hidnplayr 678
        mov     esi, 500
3545 hidnplayr 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
 
3639 hidnplayr 786
        DEBUGF  1,"Starting link\n"
787
 
3545 hidnplayr 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"
4334 hidnplayr 1013
        stdcall KernelFree, [esp+4]
3545 hidnplayr 1014
        or      eax, -1
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
3639 hidnplayr 1042
        in      ax, dx
1043
        test    ax, ax
1044
        out     dx, ax                                  ; send it back to ACK
3545 hidnplayr 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