Subversion Repositories Kolibri OS

Rev

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