Subversion Repositories Kolibri OS

Rev

Rev 9157 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
9157 hidnplayr 3
;; Copyright (C) KolibriOS team 2010-2021. All rights reserved.    ;;
3545 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  rhine.asm                                                      ;;
7
;;                                                                 ;;
8
;;  Ethernet driver for Kolibri OS                                 ;;
9
;;                                                                 ;;
10
;;  This driver is based on the via-rhine driver from              ;;
11
;;  the etherboot 5.0.6 project. The copyright statement is        ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
16
;;    Rewritten in flat assembler by Asper (asper.85@mail.ru)      ;;
17
;;            and hidnplayr (hidnplayr@gmail.com)                  ;;
18
;;                                                                 ;;
19
;;  See file COPYING for details                                   ;;
20
;;                                                                 ;;
21
;;                                                                 ;;
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23
 
9157 hidnplayr 24
; TODO: test for RX-overrun
25
 
4606 hidnplayr 26
format PE DLL native
27
entry START
3545 hidnplayr 28
 
4642 hidnplayr 29
        CURRENT_API             = 0x0200
30
        COMPATIBLE_API          = 0x0100
31
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
3545 hidnplayr 32
 
4642 hidnplayr 33
        MAX_DEVICES             = 16
3545 hidnplayr 34
 
4642 hidnplayr 35
        __DEBUG__               = 1
36
        __DEBUG_LEVEL__         = 2     ; 1 = all, 2 = errors only
3545 hidnplayr 37
 
9157 hidnplayr 38
        TX_RING_SIZE            = 32
39
        RX_RING_SIZE            = 32
3545 hidnplayr 40
 
4642 hidnplayr 41
        ; max time out delay time
42
        W_MAX_TIMEOUT           = 0x0FFF
3545 hidnplayr 43
 
4642 hidnplayr 44
        ; Size of the in-memory receive ring.
45
        RX_BUF_LEN_IDX          = 3     ; 0==8K, 1==16K, 2==32K, 3==64K
3545 hidnplayr 46
 
4642 hidnplayr 47
        ; PCI Tuning Parameters
48
        ; Threshold is bytes transferred to chip before transmission starts.
49
        TX_FIFO_THRESH          = 256   ; In bytes, rounded down to 32 byte units.
3545 hidnplayr 50
 
4642 hidnplayr 51
        ; The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024.
52
        RX_FIFO_THRESH          = 4     ; Rx buffer level before first PCI transfer.
53
        RX_DMA_BURST            = 4     ; Maximum PCI burst, '4' is 256 bytes
54
        TX_DMA_BURST            = 4
3545 hidnplayr 55
 
56
 
4606 hidnplayr 57
section '.flat' readable writable executable
58
 
59
include '../proc32.inc'
4467 hidnplayr 60
include '../struct.inc'
61
include '../macros.inc'
3545 hidnplayr 62
include '../fdo.inc'
5074 hidnplayr 63
include '../netdrv.inc'
3545 hidnplayr 64
 
65
 
66
;**************************************************************************
67
; VIA Rhine Register Definitions
68
;**************************************************************************
4642 hidnplayr 69
byPAR0                          = 0x00
70
byRCR                           = 0x06
71
byTCR                           = 0x07
72
byCR0                           = 0x08
73
byCR1                           = 0x09
74
byISR0                          = 0x0c
75
byISR1                          = 0x0d
76
byIMR0                          = 0x0e
77
byIMR1                          = 0x0f
78
byMAR0                          = 0x10
79
byMAR1                          = 0x11
80
byMAR2                          = 0x12
81
byMAR3                          = 0x13
82
byMAR4                          = 0x14
83
byMAR5                          = 0x15
84
byMAR6                          = 0x16
85
byMAR7                          = 0x17
86
dwCurrentRxDescAddr             = 0x18
87
dwCurrentTxDescAddr             = 0x1c
88
dwCurrentRDSE0                  = 0x20
89
dwCurrentRDSE1                  = 0x24
90
dwCurrentRDSE2                  = 0x28
91
dwCurrentRDSE3                  = 0x2c
92
dwNextRDSE0                     = 0x30
93
dwNextRDSE1                     = 0x34
94
dwNextRDSE2                     = 0x38
95
dwNextRDSE3                     = 0x3c
96
dwCurrentTDSE0                  = 0x40
97
dwCurrentTDSE1                  = 0x44
98
dwCurrentTDSE2                  = 0x48
99
dwCurrentTDSE3                  = 0x4c
100
dwNextTDSE0                     = 0x50
101
dwNextTDSE1                     = 0x54
102
dwNextTDSE2                     = 0x58
103
dwNextTDSE3                     = 0x5c
104
dwCurrRxDMAPtr                  = 0x60
105
dwCurrTxDMAPtr                  = 0x64
106
byMPHY                          = 0x6c
107
byMIISR                         = 0x6d
108
byBCR0                          = 0x6e
109
byBCR1                          = 0x6f
110
byMIICR                         = 0x70
111
byMIIAD                         = 0x71
112
wMIIDATA                        = 0x72
113
byEECSR                         = 0x74
114
byTEST                          = 0x75
115
byGPIO                          = 0x76
116
byCFGA                          = 0x78
117
byCFGB                          = 0x79
118
byCFGC                          = 0x7a
119
byCFGD                          = 0x7b
120
wTallyCntMPA                    = 0x7c
121
wTallyCntCRC                    = 0x7d
122
bySTICKHW                       = 0x83
123
byWOLcrClr                      = 0xA4
124
byWOLcgClr                      = 0xA7
125
byPwrcsrClr                     = 0xAC
3545 hidnplayr 126
 
127
;---------------------  Exioaddr Definitions -------------------------
128
 
129
; Bits in the RCR register
4642 hidnplayr 130
RCR_RRFT2               = 0x80
131
RCR_RRFT1               = 0x40
132
RCR_RRFT0               = 0x20
133
RCR_PROM                = 0x10
134
RCR_AB                  = 0x08
135
RCR_AM                  = 0x04
136
RCR_AR                  = 0x02
137
RCR_SEP                 = 0x01
3545 hidnplayr 138
; Bits in the TCR register
4642 hidnplayr 139
TCR_RTSF                = 0x80
140
TCR_RTFT1               = 0x40
141
TCR_RTFT0               = 0x20
142
TCR_OFSET               = 0x08
143
TCR_LB1                 = 0x04    ; loopback[1]
144
TCR_LB0                 = 0x02    ; loopback[0]
3545 hidnplayr 145
; Bits in the CR0 register
4642 hidnplayr 146
CR0_RDMD                = 0x40    ; rx descriptor polling demand
147
CR0_TDMD                = 0x20    ; tx descriptor polling demand
148
CR0_TXON                = 0x10
149
CR0_RXON                = 0x08
150
CR0_STOP                = 0x04    ; stop NIC, default = 1
151
CR0_STRT                = 0x02    ; start NIC
152
CR0_INIT                = 0x01    ; start init process
3545 hidnplayr 153
; Bits in the CR1 register
4642 hidnplayr 154
CR1_SFRST               = 0x80    ; software reset
155
CR1_RDMD1               = 0x40    ; RDMD1
156
CR1_TDMD1               = 0x20    ; TDMD1
157
CR1_KEYPAG              = 0x10    ; turn on par/key
158
CR1_DPOLL               = 0x08    ; disable rx/tx auto polling
159
CR1_FDX                 = 0x04    ; full duplex mode
160
CR1_ETEN                = 0x02    ; early tx mode
161
CR1_EREN                = 0x01    ; early rx mode
3545 hidnplayr 162
; Bits in the CR register
4642 hidnplayr 163
CR_RDMD                 = 0x0040  ; rx descriptor polling demand
164
CR_TDMD                 = 0x0020  ; tx descriptor polling demand
165
CR_TXON                 = 0x0010
166
CR_RXON                 = 0x0008
167
CR_STOP                 = 0x0004  ; stop NIC, default = 1
168
CR_STRT                 = 0x0002  ; start NIC
169
CR_INIT                 = 0x0001  ; start init process
170
CR_SFRST                = 0x8000  ; software reset
171
CR_RDMD1                = 0x4000  ; RDMD1
172
CR_TDMD1                = 0x2000  ; TDMD1
173
CR_KEYPAG               = 0x1000  ; turn on par/key
174
CR_DPOLL                = 0x0800  ; disable rx/tx auto polling
175
CR_FDX                  = 0x0400  ; full duplex mode
176
CR_ETEN                 = 0x0200  ; early tx mode
177
CR_EREN                 = 0x0100  ; early rx mode
3545 hidnplayr 178
; Bits in the IMR0 register
4642 hidnplayr 179
IMR0_CNTM               = 0x80
180
IMR0_BEM                = 0x40
181
IMR0_RUM                = 0x20
182
IMR0_TUM                = 0x10
183
IMR0_TXEM               = 0x08
184
IMR0_RXEM               = 0x04
185
IMR0_PTXM               = 0x02
186
IMR0_PRXM               = 0x01
3545 hidnplayr 187
; define imrshadow
4642 hidnplayr 188
IMRShadow               = 0x5AFF
3545 hidnplayr 189
; Bits in the IMR1 register
4642 hidnplayr 190
IMR1_INITM              = 0x80
191
IMR1_SRCM               = 0x40
192
IMR1_NBFM               = 0x10
193
IMR1_PRAIM              = 0x08
194
IMR1_RES0M              = 0x04
195
IMR1_ETM                = 0x02
196
IMR1_ERM                = 0x01
3545 hidnplayr 197
; Bits in the ISR register
4642 hidnplayr 198
ISR_INITI               = 0x8000
199
ISR_SRCI                = 0x4000
200
ISR_ABTI                = 0x2000
201
ISR_NORBF               = 0x1000
202
ISR_PKTRA               = 0x0800
203
ISR_RES0                = 0x0400
204
ISR_ETI                 = 0x0200
205
ISR_ERI                 = 0x0100
206
ISR_CNT                 = 0x0080
207
ISR_BE                  = 0x0040
208
ISR_RU                  = 0x0020
209
ISR_TU                  = 0x0010
210
ISR_TXE                 = 0x0008
211
ISR_RXE                 = 0x0004
212
ISR_PTX                 = 0x0002
213
ISR_PRX                 = 0x0001
3545 hidnplayr 214
; Bits in the ISR0 register
4642 hidnplayr 215
ISR0_CNT                = 0x80
216
ISR0_BE                 = 0x40
217
ISR0_RU                 = 0x20
218
ISR0_TU                 = 0x10
219
ISR0_TXE                = 0x08
220
ISR0_RXE                = 0x04
221
ISR0_PTX                = 0x02
222
ISR0_PRX                = 0x01
3545 hidnplayr 223
; Bits in the ISR1 register
4642 hidnplayr 224
ISR1_INITI              = 0x80
225
ISR1_SRCI               = 0x40
226
ISR1_NORBF              = 0x10
227
ISR1_PKTRA              = 0x08
228
ISR1_ETI                = 0x02
229
ISR1_ERI                = 0x01
3545 hidnplayr 230
; ISR ABNORMAL CONDITION
4642 hidnplayr 231
ISR_ABNORMAL            = ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
3545 hidnplayr 232
; Bits in the MIISR register
4642 hidnplayr 233
MIISR_MIIERR            = 0x08
234
MIISR_MRERR             = 0x04
235
MIISR_LNKFL             = 0x02
236
MIISR_SPEED             = 0x01
3545 hidnplayr 237
; Bits in the MIICR register
4642 hidnplayr 238
MIICR_MAUTO             = 0x80
239
MIICR_RCMD              = 0x40
240
MIICR_WCMD              = 0x20
241
MIICR_MDPM              = 0x10
242
MIICR_MOUT              = 0x08
243
MIICR_MDO               = 0x04
244
MIICR_MDI               = 0x02
245
MIICR_MDC               = 0x01
3545 hidnplayr 246
; Bits in the EECSR register
4642 hidnplayr 247
EECSR_EEPR              = 0x80    ; eeprom programmed status, 73h means programmed
248
EECSR_EMBP              = 0x40    ; eeprom embedded programming
249
EECSR_AUTOLD            = 0x20    ; eeprom content reload
250
EECSR_DPM               = 0x10    ; eeprom direct programming
251
EECSR_CS                = 0x08    ; eeprom CS pin
252
EECSR_SK                = 0x04    ; eeprom SK pin
253
EECSR_DI                = 0x02    ; eeprom DI pin
254
EECSR_DO                = 0x01    ; eeprom DO pin
3545 hidnplayr 255
; Bits in the BCR0 register
4642 hidnplayr 256
BCR0_CRFT2              = 0x20
257
BCR0_CRFT1              = 0x10
258
BCR0_CRFT0              = 0x08
259
BCR0_DMAL2              = 0x04
260
BCR0_DMAL1              = 0x02
261
BCR0_DMAL0              = 0x01
3545 hidnplayr 262
; Bits in the BCR1 register
4642 hidnplayr 263
BCR1_CTSF               = 0x20
264
BCR1_CTFT1              = 0x10
265
BCR1_CTFT0              = 0x08
266
BCR1_POT2               = 0x04
267
BCR1_POT1               = 0x02
268
BCR1_POT0               = 0x01
3545 hidnplayr 269
; Bits in the CFGA register
4642 hidnplayr 270
CFGA_EELOAD             = 0x80    ; enable eeprom embedded and direct programming
271
CFGA_JUMPER             = 0x40
272
CFGA_MTGPIO             = 0x08
273
CFGA_T10EN              = 0x02
274
CFGA_AUTO               = 0x01
3545 hidnplayr 275
; Bits in the CFGB register
4642 hidnplayr 276
CFGB_PD                 = 0x80
277
CFGB_POLEN              = 0x02
278
CFGB_LNKEN              = 0x01
3545 hidnplayr 279
; Bits in the CFGC register
4642 hidnplayr 280
CFGC_M10TIO             = 0x80
281
CFGC_M10POL             = 0x40
282
CFGC_PHY1               = 0x20
283
CFGC_PHY0               = 0x10
284
CFGC_BTSEL              = 0x08
285
CFGC_BPS2               = 0x04    ; bootrom select[2]
286
CFGC_BPS1               = 0x02    ; bootrom select[1]
287
CFGC_BPS0               = 0x01    ; bootrom select[0]
3545 hidnplayr 288
; Bits in the CFGD register
4642 hidnplayr 289
CFGD_GPIOEN             = 0x80
290
CFGD_DIAG               = 0x40
291
CFGD_MAGIC              = 0x10
292
CFGD_RANDOM             = 0x08
293
CFGD_CFDX               = 0x04
294
CFGD_CEREN              = 0x02
295
CFGD_CETEN              = 0x01
3545 hidnplayr 296
; Bits in RSR
4642 hidnplayr 297
RSR_RERR                = 0x00000001
298
RSR_CRC                 = 0x00000002
299
RSR_FAE                 = 0x00000004
300
RSR_FOV                 = 0x00000008
301
RSR_LONG                = 0x00000010
302
RSR_RUNT                = 0x00000020
303
RSR_SERR                = 0x00000040
304
RSR_BUFF                = 0x00000080
305
RSR_EDP                 = 0x00000100
306
RSR_STP                 = 0x00000200
307
RSR_CHN                 = 0x00000400
308
RSR_PHY                 = 0x00000800
309
RSR_BAR                 = 0x00001000
310
RSR_MAR                 = 0x00002000
311
RSR_RXOK                = 0x00008000
312
RSR_ABNORMAL            = RSR_RERR+RSR_LONG+RSR_RUNT
3545 hidnplayr 313
; Bits in TSR
4642 hidnplayr 314
TSR_NCR0                = 0x00000001
315
TSR_NCR1                = 0x00000002
316
TSR_NCR2                = 0x00000004
317
TSR_NCR3                = 0x00000008
318
TSR_COLS                = 0x00000010
319
TSR_CDH                 = 0x00000080
320
TSR_ABT                 = 0x00000100
321
TSR_OWC                 = 0x00000200
322
TSR_CRS                 = 0x00000400
323
TSR_UDF                 = 0x00000800
324
TSR_TBUFF               = 0x00001000
325
TSR_SERR                = 0x00002000
326
TSR_JAB                 = 0x00004000
327
TSR_TERR                = 0x00008000
328
TSR_ABNORMAL            = TSR_TERR+TSR_OWC+TSR_ABT+TSR_JAB+TSR_CRS
329
TSR_OWN_BIT             = 0x80000000
3545 hidnplayr 330
 
4642 hidnplayr 331
CB_DELAY_LOOP_WAIT      = 10      ; 10ms
3545 hidnplayr 332
; enabled mask value of irq
4642 hidnplayr 333
W_IMR_MASK_VALUE        = 0x1BFF  ; initial value of IMR
3545 hidnplayr 334
 
335
; Ethernet address filter type
4642 hidnplayr 336
PKT_TYPE_DIRECTED       = 0x0001  ; obsolete, directed address is always accepted
337
PKT_TYPE_MULTICAST      = 0x0002
338
PKT_TYPE_ALL_MULTICAST  = 0x0004
339
PKT_TYPE_BROADCAST      = 0x0008
340
PKT_TYPE_PROMISCUOUS    = 0x0020
341
PKT_TYPE_LONG           = 0x2000
342
PKT_TYPE_RUNT           = 0x4000
343
PKT_TYPE_ERROR          = 0x8000  ; accept error packets, e.g. CRC error
3545 hidnplayr 344
 
345
; Loopback mode
346
 
4642 hidnplayr 347
NIC_LB_NONE             = 0x00
348
NIC_LB_INTERNAL         = 0x01
349
NIC_LB_PHY              = 0x02    ; MII or Internal-10BaseT loopback
3545 hidnplayr 350
 
5522 hidnplayr 351
PKT_BUF_SZ              = 1514
3545 hidnplayr 352
 
4642 hidnplayr 353
PCI_REG_MODE3           = 0x53
354
MODE3_MIION             = 0x04    ; in PCI_REG_MOD3 OF PCI space
3545 hidnplayr 355
 
356
; VIA Rhine revisions
4642 hidnplayr 357
VT86C100A       = 0x00
358
VTunknown0      = 0x20
359
VT6102          = 0x40
360
VT8231          = 0x50 ; Integrated MAC
361
VT8233          = 0x60 ; Integrated MAC
362
VT8235          = 0x74 ; Integrated MAC
363
VT8237          = 0x78 ; Integrated MAC
364
VTunknown1      = 0x7C
365
VT6105          = 0x80
366
VT6105_B0       = 0x83
367
VT6105L         = 0x8A
368
VT6107          = 0x8C
369
VTunknown2      = 0x8E
370
VT6105M         = 0x90
3545 hidnplayr 371
 
372
; Rx status bits
4642 hidnplayr 373
RX_SBITS_RERR                   = 1 shl 0
374
RX_SBITS_CRC_ERROR              = 1 shl 1
375
RX_SBITS_FAE                    = 1 shl 2
376
RX_SBITS_FOV                    = 1 shl 3
377
RX_SBITS_TOOLONG                = 1 shl 4
378
RX_SBITS_RUNT                   = 1 shl 5
379
RX_SBITS_SERR                   = 1 shl 6
380
RX_SBITS_BUFF                   = 1 shl 7
381
RX_SBITS_EDP                    = 1 shl 8
382
RX_SBITS_STP                    = 1 shl 9
383
RX_SBITS_CHN                    = 1 shl 10
384
RX_SBITS_PHY                    = 1 shl 11
385
RX_SBITS_BAR                    = 1 shl 12
386
RX_SBITS_MAR                    = 1 shl 13
387
RX_SBITS_RESERVED_1             = 1 shl 14
388
RX_SBITS_RXOK                   = 1 shl 15
389
RX_SBITS_FRAME_LENGTH           = 0x7FF shl 16
390
RX_SBITS_RESERVED_2             = 0xF shl 27
391
RX_SBITS_OWN_BIT                = 1 shl 31
3545 hidnplayr 392
 
393
; Rx control bits
4642 hidnplayr 394
RX_CBITS_RX_BUF_SIZE            = 0x7FF
395
RX_CBITS_EXTEND_RX_BUF_SIZE     = 0xF shl 11
396
RX_CBITS_RESERVED_1             = 0x1FFFF shl 15
3545 hidnplayr 397
 
398
; Tx status bits
4642 hidnplayr 399
TX_SBITS_NCR0                   = 1 shl 0
400
TX_SBITS_NCR1                   = 1 shl 1
401
TX_SBITS_NCR2                   = 1 shl 2
402
TX_SBITS_NCR3                   = 1 shl 3
403
TX_SBITS_COLS                   = 1 shl 4
404
TX_SBITS_RESERVED_1             = 1 shl 5
405
TX_SBITS_CDH                    = 1 shl 7
406
TX_SBITS_ABT                    = 1 shl 8
407
TX_SBITS_OWC                    = 1 shl 9
408
TX_SBITS_CRS                    = 1 shl 10
409
TX_SBITS_UDF                    = 1 shl 11
410
TX_SBITS_TBUFF                  = 1 shl 12
411
TX_SBITS_SERR                   = 1 shl 13
412
TX_SBITS_JAB                    = 1 shl 14
413
TX_SBITS_TERR                   = 1 shl 15
414
TX_SBITS_RESERVED_2             = 0x7FFF shl 16
415
TX_SBITS_OWN_BIT                = 1 shl 31
3545 hidnplayr 416
 
417
; Tx control bits
4642 hidnplayr 418
TX_CBITS_TX_BUF_SIZE            = 0x7FF
419
TX_CBITS_EXTEND_TX_BUF_SIZE     = 0xF shl 11
420
TX_CBITS_CHN                    = 1 shl 15
421
TX_CBITS_CRC                    = 1 shl 16
422
TX_CBITS_RESERVED_1             = 0xF shl 17
423
TX_CBITS_STP                    = 1 shl 21
424
TX_CBITS_EDP                    = 1 shl 22
425
TX_CBITS_IC                     = 1 shl 23
426
TX_CBITS_RESERVED_2             = 0xFF shl 24
3545 hidnplayr 427
 
428
 
429
 
430
; Offsets to the device registers.
4642 hidnplayr 431
        StationAddr             = 0x00
432
        RxConfig                = 0x06
433
        TxConfig                = 0x07
434
        ChipCmd                 = 0x08
435
        IntrStatus              = 0x0C
436
        IntrEnable              = 0x0E
437
        MulticastFilter0        = 0x10
438
        MulticastFilter1        = 0x14
439
        RxRingPtr               = 0x18
440
        TxRingPtr               = 0x1C
441
        GFIFOTest               = 0x54
442
        MIIPhyAddr              = 0x6C
443
        MIIStatus               = 0x6D
444
        PCIBusConfig            = 0x6E
445
        MIICmd                  = 0x70
446
        MIIRegAddr              = 0x71
447
        MIIData                 = 0x72
448
        MACRegEEcsr             = 0x74
449
        ConfigA                 = 0x78
450
        ConfigB                 = 0x79
451
        ConfigC                 = 0x7A
452
        ConfigD                 = 0x7B
453
        RxMissed                = 0x7C
454
        RxCRCErrs               = 0x7E
455
        MiscCmd                 = 0x81
456
        StickyHW                = 0x83
457
        IntrStatus2             = 0x84
458
        WOLcrClr                = 0xA4
459
        WOLcgClr                = 0xA7
460
        PwrcsrClr               = 0xAC
3545 hidnplayr 461
 
462
; Bits in the interrupt status/mask registers.
4642 hidnplayr 463
        IntrRxDone              = 0x0001
464
        IntrRxErr               = 0x0004
465
        IntrRxEmpty             = 0x0020
466
        IntrTxDone              = 0x0002
467
        IntrTxError             = 0x0008
468
        IntrTxUnderrun          = 0x0010
469
        IntrPCIErr              = 0x0040
470
        IntrStatsMax            = 0x0080
471
        IntrRxEarly             = 0x0100
472
        IntrRxOverflow          = 0x0400
473
        IntrRxDropped           = 0x0800
474
        IntrRxNoBuf             = 0x1000
475
        IntrTxAborted           = 0x2000
476
        IntrLinkChange          = 0x4000
477
        IntrRxWakeUp            = 0x8000
478
        IntrNormalSummary       = 0x0003
479
        IntrAbnormalSummary     = 0xC260
480
        IntrTxDescRace          = 0x080000        ; mapped from IntrStatus2
481
        IntrTxErrSummary        = 0x082218
3545 hidnplayr 482
 
4642 hidnplayr 483
        DEFAULT_INTR            = (IntrRxDone or IntrRxErr or IntrRxEmpty or IntrRxOverflow or IntrRxDropped or IntrRxNoBuf)
484
        RX_BUF_LEN              = (8192 shl RX_BUF_LEN_IDX)
3545 hidnplayr 485
 
4642 hidnplayr 486
struct  rx_head
487
        status          dd ?
488
        control         dd ?
489
        buff_addr       dd ?    ; address
490
        next_desc       dd ?    ;
3545 hidnplayr 491
 
4642 hidnplayr 492
        buff_addr_virt  dd ?
493
                        rd 3    ; alignment
4606 hidnplayr 494
ends
3545 hidnplayr 495
 
4642 hidnplayr 496
struct  tx_head
497
        status          dd ?
498
        control         dd ?
499
        buff_addr       dd ?    ; address
500
        next_desc       dd ?    ;
3545 hidnplayr 501
 
4642 hidnplayr 502
        buff_addr_virt  dd ?
503
                        rd 3    ; alignment
4606 hidnplayr 504
ends
3545 hidnplayr 505
 
4642 hidnplayr 506
struct  device          ETH_DEVICE
3545 hidnplayr 507
 
4642 hidnplayr 508
        io_addr         dd ?
509
        pci_dev         dd ?
510
        pci_bus         dd ?
511
        revision        db ?
512
        irq_line        db ?
9751 hidnplayr 513
        chip_vid        dw ?
514
        chip_did        dw ?
3545 hidnplayr 515
 
4642 hidnplayr 516
        cur_rx          dw ?
517
        cur_tx          dw ?
518
        last_tx         dw ?
3545 hidnplayr 519
 
4642 hidnplayr 520
        rb 0x100 - ($ and 0xff) ; align 256
521
        tx_ring         rb sizeof.tx_head*TX_RING_SIZE
3545 hidnplayr 522
 
4642 hidnplayr 523
        rb 0x100 - ($ and 0xff) ; align 256
524
        rx_ring         rb sizeof.rx_head*RX_RING_SIZE
3545 hidnplayr 525
 
4606 hidnplayr 526
ends
3545 hidnplayr 527
 
528
 
529
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
530
;;                        ;;
531
;; proc START             ;;
532
;;                        ;;
533
;; (standard driver proc) ;;
534
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
535
 
4606 hidnplayr 536
proc START c, reason:dword, cmdline:dword
3545 hidnplayr 537
 
4642 hidnplayr 538
        cmp     [reason], DRV_ENTRY
539
        jne     .fail
3545 hidnplayr 540
 
4642 hidnplayr 541
        DEBUGF  1,"Loading driver\n"
542
        invoke  RegService, my_service, service_proc
543
        ret
3545 hidnplayr 544
 
545
  .fail:
4642 hidnplayr 546
        xor     eax, eax
547
        ret
3545 hidnplayr 548
 
549
endp
550
 
551
 
552
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
553
;;                        ;;
554
;; proc SERVICE_PROC      ;;
555
;;                        ;;
556
;; (standard driver proc) ;;
557
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
558
 
559
proc service_proc stdcall, ioctl:dword
560
 
4642 hidnplayr 561
        mov     edx, [ioctl]
562
        mov     eax, [edx + IOCTL.io_code]
3545 hidnplayr 563
 
564
;------------------------------------------------------
565
 
4642 hidnplayr 566
        cmp     eax, 0 ;SRV_GETVERSION
567
        jne     @F
3545 hidnplayr 568
 
4642 hidnplayr 569
        cmp     [edx + IOCTL.out_size], 4
570
        jb      .fail
571
        mov     eax, [edx + IOCTL.output]
572
        mov     [eax], dword API_VERSION
3545 hidnplayr 573
 
4642 hidnplayr 574
        xor     eax, eax
575
        ret
3545 hidnplayr 576
 
577
;------------------------------------------------------
578
  @@:
4642 hidnplayr 579
        cmp     eax, 1 ;SRV_HOOK
580
        jne     .fail
3545 hidnplayr 581
 
4642 hidnplayr 582
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
583
        jb      .fail
3545 hidnplayr 584
 
4642 hidnplayr 585
        mov     eax, [edx + IOCTL.input]
586
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
587
        jne     .fail                                   ; other types aren't supported for this card yet
3545 hidnplayr 588
 
589
; check if the device is already listed
590
 
4642 hidnplayr 591
        mov     esi, device_list
592
        mov     ecx, [devices]
593
        test    ecx, ecx
594
        jz      .firstdevice
3545 hidnplayr 595
 
4470 hidnplayr 596
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
4642 hidnplayr 597
        mov     ax, [eax+1]                             ;
3545 hidnplayr 598
  .nextdevice:
4642 hidnplayr 599
        mov     ebx, [esi]
600
        cmp     al, byte[ebx + device.pci_bus]
601
        jne     @f
602
        cmp     ah, byte[ebx + device.pci_dev]
603
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
3545 hidnplayr 604
       @@:
4642 hidnplayr 605
        add     esi, 4
606
        loop    .nextdevice
3545 hidnplayr 607
 
608
 
4606 hidnplayr 609
; This device doesn't have its own eth_device structure yet, lets create one
3545 hidnplayr 610
  .firstdevice:
4642 hidnplayr 611
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
612
        jae     .fail
3545 hidnplayr 613
 
4642 hidnplayr 614
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
3545 hidnplayr 615
 
616
; Fill in the direct call addresses into the struct
617
 
4642 hidnplayr 618
        mov     [ebx + device.reset], reset
619
        mov     [ebx + device.transmit], transmit
620
        mov     [ebx + device.unload], unload
621
        mov     [ebx + device.name], my_service
3545 hidnplayr 622
 
623
; save the pci bus and device numbers
624
 
4642 hidnplayr 625
        mov     eax, [edx + IOCTL.input]
626
        movzx   ecx, byte[eax+1]
627
        mov     [ebx + device.pci_bus], ecx
628
        movzx   ecx, byte[eax+2]
629
        mov     [ebx + device.pci_dev], ecx
3545 hidnplayr 630
 
4606 hidnplayr 631
; Now, it's time to find the base io address of the PCI device
3545 hidnplayr 632
 
4642 hidnplayr 633
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
634
        mov     [ebx + device.io_addr], eax
3545 hidnplayr 635
 
636
; We've found the io address, find IRQ now
637
 
4642 hidnplayr 638
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
639
        mov     [ebx + device.irq_line], al
3545 hidnplayr 640
 
4642 hidnplayr 641
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
642
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
3545 hidnplayr 643
 
644
; Ok, the eth_device structure is ready, let's probe the device
4642 hidnplayr 645
        call    probe                                                   ; this function will output in eax
646
        test    eax, eax
647
        jnz     .err                                                    ; If an error occurred, exit
3545 hidnplayr 648
 
4642 hidnplayr 649
        mov     eax, [devices]                                          ; Add the device structure to our device list
650
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
651
        inc     [devices]                                               ;
3545 hidnplayr 652
 
4642 hidnplayr 653
        mov     [ebx + device.type], NET_TYPE_ETH
654
        invoke  NetRegDev
3545 hidnplayr 655
 
4642 hidnplayr 656
        cmp     eax, -1
657
        je      .destroy
3545 hidnplayr 658
 
4642 hidnplayr 659
        ret
3545 hidnplayr 660
 
661
; If the device was already loaded, find the device number and return it in eax
662
 
663
  .find_devicenum:
4642 hidnplayr 664
        DEBUGF  1,"Trying to find device number of already registered device\n"
665
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
666
                                                                        ; into a device number in edi
667
        mov     eax, edi                                                ; Application wants it in eax instead
668
        DEBUGF  1,"Kernel says: %u\n", eax
669
        ret
3545 hidnplayr 670
 
4606 hidnplayr 671
; If an error occurred, remove all allocated data and exit (returning -1 in eax)
3545 hidnplayr 672
 
673
  .destroy:
4642 hidnplayr 674
        ; todo: reset device into virgin state
3545 hidnplayr 675
 
676
  .err:
4642 hidnplayr 677
        invoke  KernelFree, ebx
3545 hidnplayr 678
 
679
  .fail:
4642 hidnplayr 680
        or      eax, -1
681
        ret
3545 hidnplayr 682
 
683
;------------------------------------------------------
684
endp
685
 
686
 
687
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
688
;;                                                                        ;;
689
;;        Actual Hardware dependent code starts here                      ;;
690
;;                                                                        ;;
691
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
692
 
693
 
4606 hidnplayr 694
;-------
695
;
696
; PROBE
697
;
698
;-------
3545 hidnplayr 699
probe:
700
 
4642 hidnplayr 701
        DEBUGF  1, "Probing\n"
3545 hidnplayr 702
 
703
 
4606 hidnplayr 704
; Make the device a bus master
4642 hidnplayr 705
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
706
        or      al, PCI_CMD_MASTER
707
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
4606 hidnplayr 708
 
3545 hidnplayr 709
; get device id
9751 hidnplayr 710
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.vendor_id
711
        mov     dword[ebx + device.chip_vid], eax
3545 hidnplayr 712
 
4642 hidnplayr 713
        mov     esi, chiplist
3758 hidnplayr 714
  .loop:
9751 hidnplayr 715
        cmp     dword[esi], eax
4642 hidnplayr 716
        je      .got_it
9751 hidnplayr 717
        add     esi, 2*4
718
        cmp     dword[esi], 0
719
        jne     .loop
720
        DEBUGF  2, "Unknown chip: 0x%x, continuing anyway\n", eax
721
        mov     [ebx + device.name], my_service
4642 hidnplayr 722
        jmp     .done
3758 hidnplayr 723
  .got_it:
4642 hidnplayr 724
        mov     eax, dword[esi+4]
725
        mov     [ebx + device.name], eax
726
        DEBUGF  1, "Chip type = %s\n", eax
3758 hidnplayr 727
  .done:
728
 
3545 hidnplayr 729
; get revision id.
4642 hidnplayr 730
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.revision_id
731
        mov     [ebx + device.revision], al
3545 hidnplayr 732
 
4642 hidnplayr 733
        movzx   eax, [ebx + device.revision]
734
        DEBUGF  1, "Card revision = 0x%x\n", eax
3545 hidnplayr 735
 
736
; D-Link provided reset code (with comment additions)
4642 hidnplayr 737
        cmp     al, 0x40
738
        jb      .below_x40
3545 hidnplayr 739
 
9751 hidnplayr 740
        mov     ax, [ebx + device.chip_did]
4642 hidnplayr 741
        DEBUGF  1, "Enabling Sticky Bit Workaround for Chip_id: 0x%x\n", ax
3545 hidnplayr 742
 
4642 hidnplayr 743
        ; clear sticky bit before reset & read ethernet address
744
        set_io  [ebx + device.io_addr], 0
745
        set_io  [ebx + device.io_addr], bySTICKHW
746
        in      al, dx
747
        and     al, 0xFC
748
        out     dx, al
3545 hidnplayr 749
 
4642 hidnplayr 750
        ; (bits written are cleared?)
751
        ; disable force PME-enable
752
        set_io  [ebx + device.io_addr], byWOLcgClr
753
        mov     al, 0x80
754
        out     dx, al
3545 hidnplayr 755
 
4642 hidnplayr 756
        ; disable power-event config bit
757
        mov     al, 0xFF
758
        out     dx, al
3545 hidnplayr 759
 
4642 hidnplayr 760
        ; clear power status (undocumented in vt6102 docs?)
761
        set_io  [ebx + device.io_addr], byPwrcsrClr
762
        out     dx, al
3545 hidnplayr 763
 
764
  .below_x40:
765
 
766
; Reset the chip to erase previous misconfiguration.
4642 hidnplayr 767
        set_io  [ebx + device.io_addr], 0
768
        set_io  [ebx + device.io_addr], byCR0
769
        mov     ax, CR_SFRST
770
        out     dx, ax
3545 hidnplayr 771
 
772
; if vt3043 delay after reset
4642 hidnplayr 773
        cmp     [ebx + device.revision], 0x40
774
        jae     @f
775
        mov     esi, 200 ; 2000ms
776
        invoke  Sleep
3545 hidnplayr 777
   @@:
778
 
779
; polling till software reset complete
4642 hidnplayr 780
        mov     ecx, W_MAX_TIMEOUT
3545 hidnplayr 781
   .poll_again:
4642 hidnplayr 782
        in      ax, dx
783
        test    ax, CR_SFRST
784
        jz      @f
785
        loop    .poll_again
786
        DEBUGF  1, "Soft reset timeout!\n"
3545 hidnplayr 787
   @@:
788
 
789
; issue AUTOLoad in EECSR to reload eeprom
4642 hidnplayr 790
        set_io  [ebx + device.io_addr], byEECSR
791
        mov     al, 0x20
792
        out     dx, al
3545 hidnplayr 793
 
794
; if vt3065 delay after reset
4642 hidnplayr 795
        cmp     [ebx + device.revision], 0x40
796
        jb      .not_vt3065
3545 hidnplayr 797
 
4642 hidnplayr 798
        ; delay 10ms to let MAC stable
799
        mov     esi, 1 ; 10ms
800
        invoke  Sleep
3545 hidnplayr 801
 
4642 hidnplayr 802
        ; for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
803
        ; turned on.  it makes MAC receive magic packet
804
        ; automatically. So, we turn it off. (D-Link)
3545 hidnplayr 805
 
4642 hidnplayr 806
        set_io  [ebx + device.io_addr], byCFGA
807
        in      al, dx
808
        and     al, 0xFE
809
        out     dx, al
3545 hidnplayr 810
 
4642 hidnplayr 811
        ; turn on bit2 in PCI configuration register 0x53 , only for 3065
812
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_REG_MODE3
813
        or      al, MODE3_MIION
814
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_REG_MODE3, eax
3545 hidnplayr 815
  .not_vt3065:
816
 
817
; back off algorithm, disable the right-most 4-bit off CFGD
4642 hidnplayr 818
        set_io  [ebx + device.io_addr], 0
819
        set_io  [ebx + device.io_addr], byCFGD
820
        in      al, dx
821
        and     al, not (CFGD_RANDOM or CFGD_CFDX or CFGD_CEREN or CFGD_CETEN)
822
        out     dx, al
3545 hidnplayr 823
 
824
; reload eeprom
4642 hidnplayr 825
        call    reload_eeprom
3545 hidnplayr 826
 
827
; read MAC
4642 hidnplayr 828
        call    read_mac
3545 hidnplayr 829
 
830
; restart MII auto-negotiation
4642 hidnplayr 831
        stdcall WriteMII, 0, 1 shl 9, 1
3545 hidnplayr 832
 
4642 hidnplayr 833
        DEBUGF  1, "Analyzing Media type, this may take several seconds"
3545 hidnplayr 834
 
4642 hidnplayr 835
        mov     ecx, 5
3545 hidnplayr 836
     .read_again:
4642 hidnplayr 837
        mov     esi, 1
838
        invoke  Sleep
3545 hidnplayr 839
 
4642 hidnplayr 840
        stdcall ReadMII, 1
841
        test    eax, 0x0020
842
        jnz     .read_done
843
        loop    .read_again
844
        DEBUGF  1, "timeout!\n"
3545 hidnplayr 845
     .read_done:
4642 hidnplayr 846
        DEBUGF  1, "OK\n"
3545 hidnplayr 847
 
4606 hidnplayr 848
if 0
3545 hidnplayr 849
 
4642 hidnplayr 850
        set_io  [ebx + device.io_addr], 0
851
        set_io  [ebx + device.io_addr], 0x6C
852
        in      al, dx
853
        and     eax, 0xFF
854
        DEBUGF  1, "MII : Address %x\n", ax
3545 hidnplayr 855
 
4642 hidnplayr 856
        stdcall ReadMII, 1
857
        DEBUGF  1, "status 0x%x\n", ax
3545 hidnplayr 858
 
4642 hidnplayr 859
        stdcall ReadMII, 4
860
        DEBUGF  1, "advertising 0x%x\n", ax
3545 hidnplayr 861
 
4642 hidnplayr 862
        stdcall ReadMII, 5
863
        DEBUGF  1, "link 0x%x\n", ax
3545 hidnplayr 864
 
865
end if
866
 
867
; query MII to know LineSpeed, duplex mode
4642 hidnplayr 868
        set_io  [ebx + device.io_addr], 0
869
        set_io  [ebx + device.io_addr], MIIStatus
870
        in      al, dx
871
        test    al, MIISR_SPEED
872
        jz      .100mbps
873
        DEBUGF  1, "Linespeed=10Mbs\n"
874
        jmp     @f
3545 hidnplayr 875
 
876
    .100mbps:
4642 hidnplayr 877
        DEBUGF  1, "Linespeed=100Mbs\n"
3545 hidnplayr 878
    @@:
879
 
4642 hidnplayr 880
        call    QueryAuto
3545 hidnplayr 881
 
4642 hidnplayr 882
        test    eax, 1
883
        jz      .halfduplex
3545 hidnplayr 884
 
4642 hidnplayr 885
        DEBUGF  1, "Fullduplex\n"
886
        set_io  [ebx + device.io_addr], 0
887
        set_io  [ebx + device.io_addr], byCR0
888
        mov     ax, CR_FDX
889
        out     dx, ax
890
        jmp     @f
3545 hidnplayr 891
 
892
    .halfduplex:
4642 hidnplayr 893
        DEBUGF  1, "Halfduplex\n"
3545 hidnplayr 894
    @@:
895
 
896
; set MII 10 FULL ON, only apply in vt3043
9751 hidnplayr 897
        cmp     [ebx + device.chip_did], 0x3043
4642 hidnplayr 898
        jne     @f
899
        stdcall WriteMII, 0x17, 1 shl 1, 1
3545 hidnplayr 900
    @@:
901
 
902
; turn on MII link change
4642 hidnplayr 903
        set_io  [ebx + device.io_addr], 0
904
        set_io  [ebx + device.io_addr], byMIICR
905
        in      al, dx
906
        and     al, 0x7F
907
        out     dx, al
908
        push    eax
3545 hidnplayr 909
 
4642 hidnplayr 910
        call    MIIDelay
3545 hidnplayr 911
 
4642 hidnplayr 912
        set_io  [ebx + device.io_addr], byMIIAD
913
        mov     al, 0x41
914
        out     dx, al
3545 hidnplayr 915
 
4642 hidnplayr 916
        call    MIIDelay
3545 hidnplayr 917
 
4642 hidnplayr 918
        pop     eax
919
        or      al, 0x80
920
        set_io  [ebx + device.io_addr], byMIICR
921
        out     dx, al
3545 hidnplayr 922
 
923
;**************************************************************************;
924
;* ETH_RESET - Reset adapter                                              *;
925
;**************************************************************************;
926
 
927
reset:
928
 
4642 hidnplayr 929
        DEBUGF  1, "reset\n"
3545 hidnplayr 930
 
931
; attach int handler
4642 hidnplayr 932
        movzx   eax, [ebx + device.irq_line]
933
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
934
        invoke  AttachIntHandler, eax, int_handler, ebx
935
        test    eax, eax
5522 hidnplayr 936
        jz      .err
3545 hidnplayr 937
 
938
; Soft reset the chip.
4642 hidnplayr 939
        set_io  [ebx + device.io_addr], 0
940
        set_io  [ebx + device.io_addr], byCR0
941
        mov     ax, CR_SFRST
942
        out     dx, ax
3545 hidnplayr 943
 
4642 hidnplayr 944
        call    MIIDelay
3545 hidnplayr 945
 
946
; Initialize rings
4642 hidnplayr 947
        call    init_ring
5522 hidnplayr 948
        test    eax, eax
949
        jnz     .err
3545 hidnplayr 950
 
4606 hidnplayr 951
; Set Multicast
4642 hidnplayr 952
        call    set_rx_mode
3545 hidnplayr 953
 
954
; set TCR RCR threshold to store and forward
4642 hidnplayr 955
        set_io  [ebx + device.io_addr], 0
956
        set_io  [ebx + device.io_addr], byBCR0
957
        mov     al, 0x3E
958
        out     dx, al
3545 hidnplayr 959
 
4642 hidnplayr 960
        set_io  [ebx + device.io_addr], byBCR1
961
        mov     al, 0x38
962
        out     dx, al
3545 hidnplayr 963
 
4642 hidnplayr 964
        set_io  [ebx + device.io_addr], byRCR
965
        mov     al, 0x2C
966
        out     dx, al
3545 hidnplayr 967
 
4642 hidnplayr 968
        set_io  [ebx + device.io_addr], byTCR
969
        mov     al, 0x60
970
        out     dx, al
3545 hidnplayr 971
 
972
; Set Fulldupex
4642 hidnplayr 973
        call    QueryAuto
974
        test    eax, eax        ; full duplex?
975
        jz      @f
3545 hidnplayr 976
 
4642 hidnplayr 977
        set_io  [ebx + device.io_addr], 0
978
        set_io  [ebx + device.io_addr], byCFGD
979
        mov     al, CFGD_CFDX
980
        out     dx, al
3545 hidnplayr 981
 
4642 hidnplayr 982
        set_io  [ebx + device.io_addr], byCR0
983
        mov     ax, CR_FDX
984
        out     dx, ax
3545 hidnplayr 985
    @@:
986
 
987
; ENABLE interrupts
4642 hidnplayr 988
        set_io  [ebx + device.io_addr], 0
989
        set_io  [ebx + device.io_addr], byIMR0
990
        mov     ax, DEFAULT_INTR
991
        out     dx, ax
3545 hidnplayr 992
 
993
; KICK NIC to WORK
994
 
4642 hidnplayr 995
        set_io  [ebx + device.io_addr], byCR0
996
        in      ax, dx
997
        and     ax, not CR_STOP
998
        or      ax, CR_STRT or CR_TXON or CR_RXON or CR_DPOLL
999
        out     dx, ax
3545 hidnplayr 1000
 
1001
; Set the mtu, kernel will be able to send now
4642 hidnplayr 1002
        mov     [ebx + device.mtu], 1514
3545 hidnplayr 1003
 
1004
; Set link state to unknown
4642 hidnplayr 1005
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
3545 hidnplayr 1006
 
4606 hidnplayr 1007
; say reset was successful
4642 hidnplayr 1008
        xor     eax, eax
1009
        ret
3545 hidnplayr 1010
 
5522 hidnplayr 1011
  .err:
1012
        DEBUGF  2,"Error!\n"
1013
        or      eax, -1
1014
        ret
3545 hidnplayr 1015
 
1016
 
5522 hidnplayr 1017
 
3545 hidnplayr 1018
align 4
1019
unload:
1020
 
4642 hidnplayr 1021
        call    reset
1022
        push    eax edx
1023
        DEBUGF  1, "rhine disable\n"
3545 hidnplayr 1024
 
4642 hidnplayr 1025
        ; Switch to loopback mode to avoid hardware races.
1026
        set_io  [ebx + device.io_addr], 0
1027
        set_io  [ebx + device.io_addr], byTCR
1028
        mov     al, 0x61
1029
        out     dx, al
3545 hidnplayr 1030
 
4642 hidnplayr 1031
        ; Stop the chip's Tx and Rx processes.
1032
        set_io  [ebx + device.io_addr], byCR0
1033
        mov     ax, CR_STOP
1034
        out     dx, ax
1035
        pop     edx eax
3545 hidnplayr 1036
 
4642 hidnplayr 1037
        ret
3545 hidnplayr 1038
 
1039
 
1040
 
1041
 
1042
align 4
1043
reload_eeprom:
1044
 
4642 hidnplayr 1045
        DEBUGF  1, "Reload eeprom\n"
3545 hidnplayr 1046
 
4642 hidnplayr 1047
        set_io  [ebx + device.io_addr], 0
1048
        set_io  [ebx + device.io_addr], byEECSR
1049
        mov     al, 0x20
1050
        out     dx, al
1051
        ; Typically 2 cycles to reload.
1052
        mov     ecx, 150
3545 hidnplayr 1053
  .reload:
4642 hidnplayr 1054
        in      al, dx
1055
        test    al, 0x20
1056
        jz      @f
1057
        loop    .reload
1058
        DEBUGF  2, "Reload eeprom: timeout!\n"
3545 hidnplayr 1059
  @@:
1060
 
4642 hidnplayr 1061
        ret
3545 hidnplayr 1062
 
4606 hidnplayr 1063
 
1064
 
3545 hidnplayr 1065
; Initialize the Rx and Tx rings, along with various 'dev' bits.
1066
align 4
1067
init_ring:
1068
 
4642 hidnplayr 1069
        DEBUGF  1, "Init ring\n"
3545 hidnplayr 1070
 
4642 hidnplayr 1071
        lea     edi, [ebx + device.rx_ring]
1072
        mov     eax, edi
1073
        invoke  GetPhysAddr
1074
        mov     esi, eax
1075
        push    esi
1076
        mov     ecx, RX_RING_SIZE
3545 hidnplayr 1077
   .rx_init:
4642 hidnplayr 1078
        add     esi, sizeof.rx_head
1079
        mov     [edi + rx_head.status], RX_SBITS_OWN_BIT
1080
        mov     [edi + rx_head.control], PKT_BUF_SZ
1081
        push    ecx
5522 hidnplayr 1082
        invoke  NetAlloc, PKT_BUF_SZ+NET_BUFF.data
4642 hidnplayr 1083
        pop     ecx
5522 hidnplayr 1084
        test    eax, eax
1085
        jz      .out_of_mem
4642 hidnplayr 1086
        mov     [edi + rx_head.buff_addr_virt], eax
1087
        invoke  GetPhysAddr
5522 hidnplayr 1088
        add     eax, NET_BUFF.data
4642 hidnplayr 1089
        mov     [edi + rx_head.buff_addr], eax                        ; buffer ptr
1090
        mov     [edi + rx_head.next_desc], esi                        ; next head
1091
        add     edi, sizeof.rx_head
1092
        dec     ecx
1093
        jnz     .rx_init
1094
        pop     [edi - sizeof.rx_head + rx_head.next_desc]            ; Mark the last entry as wrapping the ring.
3545 hidnplayr 1095
 
1096
 
4642 hidnplayr 1097
        lea     edi, [ebx + device.tx_ring]
1098
        mov     eax, edi
1099
        invoke  GetPhysAddr
1100
        mov     esi, eax
1101
        push    esi
1102
        mov     ecx, TX_RING_SIZE
3545 hidnplayr 1103
   .tx_init:
4642 hidnplayr 1104
        add     esi, sizeof.tx_head
1105
        mov     [edi + tx_head.status], 0
1106
        mov     [edi + tx_head.control], 0x00E08000
1107
        mov     [edi + tx_head.buff_addr], 0
1108
        mov     [edi + tx_head.next_desc], esi
1109
        mov     [edi + tx_head.buff_addr_virt], 0
1110
        add     edi, sizeof.tx_head
1111
        dec     ecx
1112
        jnz     .tx_init
1113
        pop     [edi - sizeof.tx_head + tx_head.next_desc]              ; Mark the last entry as wrapping the ring.
3545 hidnplayr 1114
 
1115
; write Descriptors to MAC
4642 hidnplayr 1116
        lea     eax, [ebx + device.rx_ring]
1117
        invoke  GetPhysAddr
1118
        set_io  [ebx + device.io_addr], 0
1119
        set_io  [ebx + device.io_addr], dwCurrentRxDescAddr
1120
        out     dx, eax
3545 hidnplayr 1121
 
4642 hidnplayr 1122
        lea     eax, [ebx + device.tx_ring]
1123
        invoke  GetPhysAddr
1124
        set_io  [ebx + device.io_addr], dwCurrentTxDescAddr
1125
        out     dx, eax
3545 hidnplayr 1126
 
4642 hidnplayr 1127
        xor     eax, eax
1128
        mov     [ebx + device.cur_rx], ax
1129
        mov     [ebx + device.cur_tx], ax
1130
        mov     [ebx + device.last_tx], ax
3545 hidnplayr 1131
 
5522 hidnplayr 1132
        xor     eax, eax
4642 hidnplayr 1133
        ret
3545 hidnplayr 1134
 
5522 hidnplayr 1135
  .out_of_mem:
1136
        add     esp, 4
1137
        or      eax, -1
1138
        ret
3545 hidnplayr 1139
 
5522 hidnplayr 1140
 
3545 hidnplayr 1141
align 4
1142
QueryAuto:
1143
 
4642 hidnplayr 1144
        DEBUGF  1, "Query Auto\n"
3545 hidnplayr 1145
 
4642 hidnplayr 1146
        push    ecx
1147
        stdcall ReadMII, 0x04   ; advertised
1148
        mov     ecx, eax
1149
        stdcall ReadMII, 0x05
1150
        and     ecx, eax
3545 hidnplayr 1151
 
4642 hidnplayr 1152
        xor     eax, eax
1153
        test    ecx, 0x100
1154
        jnz     .one
3545 hidnplayr 1155
 
4642 hidnplayr 1156
        and     ecx, 0x1C0
1157
        cmp     ecx, 0x40
1158
        jne     .zero
3545 hidnplayr 1159
   .one:
4642 hidnplayr 1160
        inc     eax
1161
        DEBUGF  1, "AutoNego OK!\n"
3545 hidnplayr 1162
   .zero:
4642 hidnplayr 1163
        pop     ecx
3545 hidnplayr 1164
 
4642 hidnplayr 1165
        ret
3545 hidnplayr 1166
 
1167
 
4642 hidnplayr 1168
proc    ReadMII stdcall, byMIIIndex:dword
3545 hidnplayr 1169
 
1170
;        DEBUGF  1, "ReadMII Index=%x\n", [byMIIIndex]
1171
 
4642 hidnplayr 1172
        push    esi ebx ecx edx
3545 hidnplayr 1173
 
4642 hidnplayr 1174
        set_io  [ebx + device.io_addr], 0
1175
        set_io  [ebx + device.io_addr], byMIIAD
1176
        in      al, dx
1177
        mov     bl, al
3545 hidnplayr 1178
 
4642 hidnplayr 1179
        set_io  [ebx + device.io_addr], byMIICR
1180
        in      al, dx
1181
        mov     bh, al
1182
        and     al, 0x7F
1183
        out     dx, al
3545 hidnplayr 1184
 
4642 hidnplayr 1185
        call    MIIDelay
3545 hidnplayr 1186
 
4642 hidnplayr 1187
        mov     al, byte [byMIIIndex]
1188
        set_io  [ebx + device.io_addr], byMIIAD
1189
        out     dx, al
3545 hidnplayr 1190
 
4642 hidnplayr 1191
        call    MIIDelay
3545 hidnplayr 1192
 
4642 hidnplayr 1193
        set_io  [ebx + device.io_addr], byMIICR
1194
        in      al, dx
1195
        or      al, 0x40
1196
        out     dx, al
3545 hidnplayr 1197
 
4642 hidnplayr 1198
        mov     ecx, 200
3545 hidnplayr 1199
  .read_again:
4642 hidnplayr 1200
        in      al, dx
1201
        test    al, 0x40
1202
        jz      @f
3545 hidnplayr 1203
 
4642 hidnplayr 1204
        mov     esi, 10
1205
        invoke  Sleep
1206
        dec     ecx
1207
        jnz     .read_again
1208
        DEBUGF  2, "ReadMII: timeout!\n"
3545 hidnplayr 1209
  @@:
1210
 
4642 hidnplayr 1211
        call    MIIDelay
3545 hidnplayr 1212
 
4642 hidnplayr 1213
        set_io  [ebx + device.io_addr], byMIIAD
1214
        in      ax, dx
3545 hidnplayr 1215
 
4642 hidnplayr 1216
        push    eax
1217
        mov     ax, bx
1218
        set_io  [ebx + device.io_addr], byMIIAD
1219
        out     dx, al
3545 hidnplayr 1220
 
4642 hidnplayr 1221
        shr     ax, 8
1222
        set_io  [ebx + device.io_addr], byMIICR
1223
        out     dx, al
3545 hidnplayr 1224
 
4642 hidnplayr 1225
        call    MIIDelay
3545 hidnplayr 1226
 
4642 hidnplayr 1227
        pop     eax
1228
        and     eax, 0xFFFF
1229
        rol     ax, 8
3545 hidnplayr 1230
 
4642 hidnplayr 1231
        pop     edx ecx ebx esi
1232
        ret
3545 hidnplayr 1233
endp
1234
 
1235
 
4606 hidnplayr 1236
 
4642 hidnplayr 1237
proc    WriteMII stdcall, byMIISetByte:dword, byMIISetBit:dword, byMIIOP:dword
4606 hidnplayr 1238
 
3545 hidnplayr 1239
;        DEBUGF  1, "WriteMII SetByte=%x SetBit=%x OP=%x\n", [byMIISetByte], [byMIISetBit], [byMIIOP]
1240
 
4642 hidnplayr 1241
        push    ebx eax ecx edx
3545 hidnplayr 1242
 
4642 hidnplayr 1243
        set_io  [ebx + device.io_addr], 0
1244
        set_io  [ebx + device.io_addr], byMIIAD
1245
        in      al, dx
1246
        mov     bl, al
3545 hidnplayr 1247
 
4642 hidnplayr 1248
        set_io  [ebx + device.io_addr], byMIICR
1249
        in      al, dx
1250
        mov     bh, al
1251
        and     al, 0x7F
1252
        out     dx, al
3545 hidnplayr 1253
 
4642 hidnplayr 1254
        call    MIIDelay
3545 hidnplayr 1255
 
4642 hidnplayr 1256
        mov     al, byte [byMIISetByte]
1257
        set_io  [ebx + device.io_addr], byMIIAD
1258
        out     dx, al
3545 hidnplayr 1259
 
4642 hidnplayr 1260
        call    MIIDelay
3545 hidnplayr 1261
 
4642 hidnplayr 1262
        set_io  [ebx + device.io_addr], byMIICR
1263
        in      al, dx
1264
        or      al, 0x40
1265
        out     dx, al
3545 hidnplayr 1266
 
4642 hidnplayr 1267
        mov     ecx, 200
3545 hidnplayr 1268
  .read_again0:
4642 hidnplayr 1269
        in      al, dx
1270
        test    al, 0x40
1271
        jz      .done
3545 hidnplayr 1272
 
4642 hidnplayr 1273
        mov     esi, 10
1274
        invoke  Sleep
1275
        dec     ecx
1276
        jnz     .read_again0
1277
        DEBUGF  2, "WriteMII: timeout (1)\n"
3545 hidnplayr 1278
  .done:
1279
 
4642 hidnplayr 1280
        call    MIIDelay
3545 hidnplayr 1281
 
4642 hidnplayr 1282
        set_io  [ebx + device.io_addr], wMIIDATA
1283
        in      ax, dx
3545 hidnplayr 1284
 
4642 hidnplayr 1285
        mov     ecx, [byMIISetBit]
1286
        rol     cx, 8
3545 hidnplayr 1287
 
4642 hidnplayr 1288
        cmp     byte [byMIIOP], 0
1289
        jne     @f
1290
        not     ecx
1291
        and     ax, cx
1292
        jmp     .end_mascarad
3545 hidnplayr 1293
     @@:
4642 hidnplayr 1294
        or      ax, cx
3545 hidnplayr 1295
     .end_mascarad:
1296
 
4642 hidnplayr 1297
        set_io  [ebx + device.io_addr], wMIIDATA
1298
        out     dx, ax
3545 hidnplayr 1299
 
4642 hidnplayr 1300
        call    MIIDelay
3545 hidnplayr 1301
 
4642 hidnplayr 1302
        set_io  [ebx + device.io_addr], byMIICR
1303
        in      al, dx
1304
        or      al, 0x20
1305
        out     dx, al
3545 hidnplayr 1306
 
4642 hidnplayr 1307
        mov     ecx, 200
3545 hidnplayr 1308
    .read_again1:
4642 hidnplayr 1309
        in      al, dx
1310
        test    al, 0x20
1311
        jz      @f
3545 hidnplayr 1312
 
4642 hidnplayr 1313
        mov     esi, 10
1314
        invoke  Sleep
1315
        dec     ecx
1316
        jnz     .read_again1
1317
        DEBUGF  2, "WriteMII timeout (2)\n"
3545 hidnplayr 1318
    @@:
1319
 
4642 hidnplayr 1320
        call    MIIDelay
3545 hidnplayr 1321
 
4642 hidnplayr 1322
        mov     ax, bx
1323
        and     al, 0x7F
1324
        set_io  [ebx + device.io_addr], byMIIAD
1325
        out     dx, al
3545 hidnplayr 1326
 
4642 hidnplayr 1327
        shr     ax, 8
1328
        set_io  [ebx + device.io_addr], byMIICR
1329
        out     dx, al
3545 hidnplayr 1330
 
4642 hidnplayr 1331
        call    MIIDelay
3545 hidnplayr 1332
 
4642 hidnplayr 1333
        pop     edx ecx eax ebx
1334
        ret
3545 hidnplayr 1335
endp
1336
 
1337
 
1338
align 4
1339
MIIDelay:
1340
 
4642 hidnplayr 1341
        mov     ecx, 0x7FFF
3545 hidnplayr 1342
    @@:
4642 hidnplayr 1343
        in      al, 0x61
1344
        in      al, 0x61
1345
        in      al, 0x61
1346
        in      al, 0x61
1347
        loop    @b
3545 hidnplayr 1348
 
4642 hidnplayr 1349
        ret
3545 hidnplayr 1350
 
1351
 
1352
align 4
1353
set_rx_mode:
1354
 
4642 hidnplayr 1355
        DEBUGF  1, "Set RX mode\n"
3545 hidnplayr 1356
 
4642 hidnplayr 1357
        ; ! IFF_PROMISC
1358
        mov     eax, 0xffffffff
1359
        set_io  [ebx + device.io_addr], 0
1360
        set_io  [ebx + device.io_addr], byMAR0
1361
        out     dx, eax
3545 hidnplayr 1362
 
4642 hidnplayr 1363
        set_io  [ebx + device.io_addr], byMAR4
1364
        out     dx, eax
3545 hidnplayr 1365
 
4642 hidnplayr 1366
        set_io  [ebx + device.io_addr], byRCR
5522 hidnplayr 1367
        mov     al, 0x6C                ; thresh or rx_mode
1368
        out     dx, al
3545 hidnplayr 1369
 
4642 hidnplayr 1370
        ret
3545 hidnplayr 1371
 
1372
 
1373
 
1374
 
1375
 
1376
; Beware of PCI posted writes
1377
macro IOSYNC
1378
{
4642 hidnplayr 1379
        set_io  [ebx + device.io_addr], StationAddr
1380
        in      al, dx
3545 hidnplayr 1381
}
1382
 
1383
 
1384
 
1385
align 4
1386
read_mac:
1387
 
4642 hidnplayr 1388
        lea     edi, [ebx + device.mac]
1389
        set_io  [ebx + device.io_addr], 0
1390
        set_io  [ebx + device.io_addr], byPAR0
1391
        mov     ecx, 6
3545 hidnplayr 1392
  .next:
4642 hidnplayr 1393
        in      al, dx
1394
        stosb
1395
        inc     edx
1396
        dec     ecx
1397
        jnz     .next
3545 hidnplayr 1398
 
4642 hidnplayr 1399
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n", \
1400
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
4470 hidnplayr 1401
 
1402
 
4642 hidnplayr 1403
        ret
3545 hidnplayr 1404
 
1405
 
1406
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1407
;;                                         ;;
1408
;; Transmit                                ;;
1409
;;                                         ;;
1410
;; In: buffer pointer in [esp+4]           ;;
1411
;;     pointer to device structure in ebx  ;;
9157 hidnplayr 1412
;; Out: eax = 0 on success                 ;;
3545 hidnplayr 1413
;;                                         ;;
1414
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9157 hidnplayr 1415
align 16
5522 hidnplayr 1416
proc transmit stdcall bufferptr
3545 hidnplayr 1417
 
9157 hidnplayr 1418
        spin_lock_irqsave
3545 hidnplayr 1419
 
5522 hidnplayr 1420
        mov     esi, [bufferptr]
1421
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
1422
        lea     eax, [esi + NET_BUFF.data]
4642 hidnplayr 1423
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1424
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1425
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1426
        [eax+13]:2,[eax+12]:2
3545 hidnplayr 1427
 
5522 hidnplayr 1428
        cmp     [esi + NET_BUFF.length], 1514
9157 hidnplayr 1429
        ja      .error
5522 hidnplayr 1430
        cmp     [esi + NET_BUFF.length], 60
9157 hidnplayr 1431
        jb      .error
3545 hidnplayr 1432
 
9157 hidnplayr 1433
; Program the descriptor
4642 hidnplayr 1434
        movzx   eax, [ebx + device.cur_tx]
1435
        mov     ecx, sizeof.tx_head
1436
        mul     ecx
1437
        lea     edi, [ebx + device.tx_ring]
1438
        add     edi, eax
3545 hidnplayr 1439
 
4642 hidnplayr 1440
        cmp     [edi + tx_head.buff_addr_virt], 0
9157 hidnplayr 1441
        jne     .overrun
3545 hidnplayr 1442
 
5522 hidnplayr 1443
        mov     eax, esi
4642 hidnplayr 1444
        mov     [edi + tx_head.buff_addr_virt], eax
5522 hidnplayr 1445
        add     eax, [eax + NET_BUFF.offset]
4642 hidnplayr 1446
        invoke  GetPhysAddr
1447
        mov     [edi + tx_head.buff_addr], eax
5522 hidnplayr 1448
        mov     ecx, [esi + NET_BUFF.length]
4642 hidnplayr 1449
        and     ecx, TX_CBITS_TX_BUF_SIZE
1450
        or      ecx,  0x00E08000
1451
        mov     [edi + tx_head.control], ecx
1452
        or      [edi + tx_head.status], TX_SBITS_OWN_BIT
3545 hidnplayr 1453
 
4642 hidnplayr 1454
        set_io  [ebx + device.io_addr], 0
1455
        set_io  [ebx + device.io_addr], byCR1
1456
        in      al, dx
1457
        or      al, CR1_TDMD1
1458
        out     dx, al
3545 hidnplayr 1459
 
4642 hidnplayr 1460
        inc     [ebx + device.cur_tx]
1461
        and     [ebx + device.cur_tx], TX_RING_SIZE-1
4606 hidnplayr 1462
 
4642 hidnplayr 1463
        ;outw(IMRShadow,byIMR0); ;
4606 hidnplayr 1464
 
3545 hidnplayr 1465
; Update stats
4642 hidnplayr 1466
        inc     [ebx + device.packets_tx]
5522 hidnplayr 1467
        mov     ecx, [esi + NET_BUFF.length]
4642 hidnplayr 1468
        add     dword [ebx + device.bytes_tx], ecx
1469
        adc     dword [ebx + device.bytes_tx + 4], 0
3545 hidnplayr 1470
 
9157 hidnplayr 1471
        spin_unlock_irqrestore
4642 hidnplayr 1472
        xor     eax, eax
1473
        ret
3545 hidnplayr 1474
 
9157 hidnplayr 1475
  .error:
1476
        DEBUGF  2, "TX packet error\n"
1477
        inc     [ebx + device.packets_tx_err]
5522 hidnplayr 1478
        invoke  NetFree, [bufferptr]
9157 hidnplayr 1479
 
1480
        spin_unlock_irqrestore
4642 hidnplayr 1481
        or      eax, -1
1482
        ret
3545 hidnplayr 1483
 
9157 hidnplayr 1484
  .overrun:
1485
        DEBUGF  2, "TX overrun\n"
1486
        inc     [ebx + device.packets_tx_ovr]
1487
        invoke  NetFree, [bufferptr]
1488
 
1489
        spin_unlock_irqrestore
1490
        or      eax, -1
1491
        ret
1492
 
1493
 
4606 hidnplayr 1494
endp
3545 hidnplayr 1495
 
1496
 
1497
 
1498
;;;;;;;;;;;;;;;;;;;;;;;
1499
;;                   ;;
1500
;; Interrupt handler ;;
1501
;;                   ;;
1502
;;;;;;;;;;;;;;;;;;;;;;;
9157 hidnplayr 1503
align 16
3545 hidnplayr 1504
int_handler:
1505
 
4642 hidnplayr 1506
        push    ebx esi edi
3545 hidnplayr 1507
 
9157 hidnplayr 1508
        mov     ebx, [esp+4*4]
1509
        DEBUGF  1,"INT for 0x%x\n", ebx
3545 hidnplayr 1510
 
4642 hidnplayr 1511
        set_io  [ebx + device.io_addr], 0
1512
        set_io  [ebx + device.io_addr], IntrStatus
1513
        in      ax, dx
1514
        test    ax, ax
9157 hidnplayr 1515
        jz      .nothing
3545 hidnplayr 1516
 
9157 hidnplayr 1517
        out     dx, ax          ; ACK interrupt
1518
        DEBUGF  1, "Status=0x%x\n", ax
3545 hidnplayr 1519
 
4642 hidnplayr 1520
        push    ax
3545 hidnplayr 1521
 
4642 hidnplayr 1522
        test    ax, IntrRxDone
1523
        jz      .not_RX
3545 hidnplayr 1524
 
4642 hidnplayr 1525
        push    ebx
3545 hidnplayr 1526
  .more_RX:
4642 hidnplayr 1527
        pop     ebx
3545 hidnplayr 1528
 
4606 hidnplayr 1529
; Get the current descriptor pointer
4642 hidnplayr 1530
        movzx   eax, [ebx + device.cur_rx]
1531
        mov     ecx, sizeof.rx_head
1532
        mul     ecx
1533
        lea     edi, [ebx + device.rx_ring]
1534
        add     edi, eax
3545 hidnplayr 1535
 
1536
; Check it's status
4642 hidnplayr 1537
        test    [edi + rx_head.status], RX_SBITS_OWN_BIT
5522 hidnplayr 1538
        jnz     .not_RX
3545 hidnplayr 1539
 
4642 hidnplayr 1540
        DEBUGF  1, "Packet status = 0x%x\n", [edi + rx_head.status]
3545 hidnplayr 1541
 
1542
; TODO: check error bits
1543
 
1544
; get length
4642 hidnplayr 1545
        mov     ecx, [edi + rx_head.status]
1546
        and     ecx, RX_SBITS_FRAME_LENGTH
1547
        shr     ecx, 16
5522 hidnplayr 1548
        sub     ecx, 4                          ; We dont want CRC
3545 hidnplayr 1549
 
1550
; Update stats
4642 hidnplayr 1551
        add     dword [ebx + device.bytes_rx], ecx
1552
        adc     dword [ebx + device.bytes_rx + 4], 0
1553
        inc     [ebx + device.packets_rx]
3545 hidnplayr 1554
 
5522 hidnplayr 1555
; Push packet pointer, kernel will need it..
4642 hidnplayr 1556
        push    ebx
5522 hidnplayr 1557
        push    .more_RX                        ; return ptr
1558
        mov     eax, [edi + rx_head.buff_addr_virt]
1559
        push    eax
1560
        mov     [eax + NET_BUFF.length], ecx
1561
        mov     [eax + NET_BUFF.device], ebx
1562
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
3545 hidnplayr 1563
 
1564
; reset the RX descriptor
4642 hidnplayr 1565
        push    edi
5522 hidnplayr 1566
        invoke  NetAlloc, PKT_BUF_SZ+NET_BUFF.data
4642 hidnplayr 1567
        pop     edi
1568
        mov     [edi + rx_head.buff_addr_virt], eax
1569
        invoke  GetPhysAddr
5522 hidnplayr 1570
        add     eax, NET_BUFF.data
4642 hidnplayr 1571
        mov     [edi + rx_head.buff_addr], eax
1572
        mov     [edi + rx_head.status], RX_SBITS_OWN_BIT
3545 hidnplayr 1573
 
1574
; Use next descriptor next time
4642 hidnplayr 1575
        inc     [ebx + device.cur_rx]
1576
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
3545 hidnplayr 1577
 
1578
; At last, send packet to kernel
5522 hidnplayr 1579
        jmp     [EthInput]
3545 hidnplayr 1580
 
1581
  .not_RX:
4642 hidnplayr 1582
        pop     ax
3545 hidnplayr 1583
 
4642 hidnplayr 1584
        test    ax, IntrTxDone
1585
        jz      .not_TX
3545 hidnplayr 1586
 
1587
      .loop_tx:
4642 hidnplayr 1588
        movzx   eax, [ebx + device.last_tx]
1589
        mov     ecx, sizeof.tx_head
1590
        mul     ecx
1591
        lea     edi, [ebx + device.tx_ring]
1592
        add     edi, eax
3545 hidnplayr 1593
 
4642 hidnplayr 1594
        test    [edi + tx_head.status], TX_SBITS_OWN_BIT
1595
        jnz     .not_TX
3545 hidnplayr 1596
 
4642 hidnplayr 1597
        cmp     [edi + tx_head.buff_addr_virt], 0
1598
        je      .not_TX
3545 hidnplayr 1599
 
4642 hidnplayr 1600
        DEBUGF  1,"Freeing buffer 0x%x\n", [edi + tx_head.buff_addr_virt]
3545 hidnplayr 1601
 
4642 hidnplayr 1602
        push    [edi + tx_head.buff_addr_virt]
1603
        mov     [edi + tx_head.buff_addr_virt], 0
5522 hidnplayr 1604
        invoke  NetFree
3545 hidnplayr 1605
 
4642 hidnplayr 1606
        inc     [ebx + device.last_tx]
1607
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
3545 hidnplayr 1608
 
4642 hidnplayr 1609
        jmp     .loop_tx
3545 hidnplayr 1610
 
1611
  .not_TX:
1612
 
4642 hidnplayr 1613
        ; On Rhine-II, Bit 3 indicates Tx descriptor write-back race.
3545 hidnplayr 1614
if 0
5522 hidnplayr 1615
        cmp     [ebx + device.chip_id], 0x3065
4642 hidnplayr 1616
        jne     @f
1617
        push    ax
1618
        xor     eax, eax
1619
        set_io  [ebx + device.io_addr], IntrStatus2
5522 hidnplayr 1620
        in      al, dx
4642 hidnplayr 1621
        shl     eax, 16
1622
        pop     ax
3545 hidnplayr 1623
    @@:
1624
end if
1625
 
1626
if 0
1627
 
4642 hidnplayr 1628
        ; Acknowledge all of the current interrupt sources ASAP.
1629
        xor     ecx, ecx
1630
        test    eax, IntrTxDescRace
1631
        jz      @f
1632
        set_io  [ebx + device.io_addr], 0
1633
        set_io  [ebx + device.io_addr], IntrStatus2
1634
        push    ax
1635
        mov     al, 0x08
1636
        out     dx, al
1637
        pop     ax
3545 hidnplayr 1638
    @@:
4642 hidnplayr 1639
        set_io  [ebx + device.io_addr], 0
1640
        set_io  [ebx + device.io_addr], IntrStatus
1641
        out     dx, ax
1642
        IOSYNC
3545 hidnplayr 1643
 
1644
end if
1645
 
4642 hidnplayr 1646
        pop     edi esi ebx
1647
        xor     eax, eax
1648
        inc     eax
3545 hidnplayr 1649
 
4642 hidnplayr 1650
        ret
3545 hidnplayr 1651
 
9157 hidnplayr 1652
  .nothing:
1653
        pop     edi esi ebx
1654
        xor     eax, eax
3545 hidnplayr 1655
 
9157 hidnplayr 1656
        ret
3545 hidnplayr 1657
 
1658
 
1659
 
9157 hidnplayr 1660
 
3545 hidnplayr 1661
; End of code
1662
 
4606 hidnplayr 1663
data fixups
1664
end data
3545 hidnplayr 1665
 
4606 hidnplayr 1666
include '../peimport.inc'
3545 hidnplayr 1667
 
4642 hidnplayr 1668
my_service      db 'RHINE',0                    ; max 16 chars including zero
4606 hidnplayr 1669
 
3758 hidnplayr 1670
chiplist:
4642 hidnplayr 1671
                dd 0x30431106, rhine_3043;, RHINE_IOTYPE, RHINE_I_IOSIZE, CanHaveMII or ReqTxAlign or HasV1TxStat
1672
                dd 0x61001106, rhine_6100;, RHINE_IOTYPE, RHINE_I_IOSIZE, CanHaveMII or ReqTxAlign or HasV1TxStat
1673
                dd 0x30651106, rhine_6102;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1674
                dd 0x31061106, rhine_6105;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
4606 hidnplayr 1675
; Duplicate entry, with 'M' features enabled.
1676
;                dd 0x31061106, rhine_6105;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL or HasIPChecksum or HasVLAN
4642 hidnplayr 1677
                dd 0x30531106, rhine_3053;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1678
                dd 0
3545 hidnplayr 1679
 
4642 hidnplayr 1680
rhine_3043      db "VIA VT3043 Rhine", 0
1681
rhine_6100      db "VIA VT86C100A Rhine", 0
1682
rhine_6102      db "VIA VT6102 Rhine-II", 0
1683
rhine_6105      db "VIA VT6105LOM Rhine-III (3106)", 0
1684
rhine_3053      db "VIA VT6105M Rhine-III (3053 prototype)", 0
3545 hidnplayr 1685
 
4642 hidnplayr 1686
include_debug_strings                           ; All data which FDO uses will be included here
3545 hidnplayr 1687
 
4606 hidnplayr 1688
align 4
4642 hidnplayr 1689
devices         dd 0
1690
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
3545 hidnplayr 1691