Subversion Repositories Kolibri OS

Rev

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

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