Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
4467 hidnplayr 3
;; Copyright (C) KolibriOS team 2010-2014. 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
 
4606 hidnplayr 27
	CURRENT_API		= 0x0200
28
	COMPATIBLE_API		= 0x0100
29
	API_VERSION		= (COMPATIBLE_API shl 16) + CURRENT_API
3545 hidnplayr 30
 
4606 hidnplayr 31
	MAX_DEVICES		= 16
3545 hidnplayr 32
 
4606 hidnplayr 33
	__DEBUG__		= 1
34
	__DEBUG_LEVEL__ 	= 1	; 1 = all, 2 = errors only
3545 hidnplayr 35
 
4606 hidnplayr 36
	TX_RING_SIZE		= 4
37
	RX_RING_SIZE		= 4
3545 hidnplayr 38
 
4606 hidnplayr 39
	; max time out delay time
40
	W_MAX_TIMEOUT		= 0x0FFF
3545 hidnplayr 41
 
4606 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
 
4606 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
 
4606 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'
4606 hidnplayr 61
include '../netdrv_pe.inc'
3545 hidnplayr 62
 
63
 
64
;**************************************************************************
65
; VIA Rhine Register Definitions
66
;**************************************************************************
4606 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
4606 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
4606 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
4606 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
4606 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
4606 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
4606 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
4606 hidnplayr 186
IMRShadow		= 0x5AFF
3545 hidnplayr 187
; Bits in the IMR1 register
4606 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
4606 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
4606 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
4606 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
4606 hidnplayr 229
ISR_ABNORMAL		= ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
3545 hidnplayr 230
; Bits in the MIISR register
4606 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
4606 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
4606 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
4606 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
4606 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
4606 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
4606 hidnplayr 274
CFGB_PD 		= 0x80
275
CFGB_POLEN		= 0x02
276
CFGB_LNKEN		= 0x01
3545 hidnplayr 277
; Bits in the CFGC register
4606 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
4606 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
4606 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
4606 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
 
4606 hidnplayr 329
CB_DELAY_LOOP_WAIT	= 10	  ; 10ms
3545 hidnplayr 330
; enabled mask value of irq
4606 hidnplayr 331
W_IMR_MASK_VALUE	= 0x1BFF  ; initial value of IMR
3545 hidnplayr 332
 
333
; Ethernet address filter type
4606 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
 
4606 hidnplayr 345
NIC_LB_NONE		= 0x00
346
NIC_LB_INTERNAL 	= 0x01
347
NIC_LB_PHY		= 0x02	  ; MII or Internal-10BaseT loopback
3545 hidnplayr 348
 
4606 hidnplayr 349
PKT_BUF_SZ		= 1536	  ; Size of each temporary Rx buffer.
3545 hidnplayr 350
 
4606 hidnplayr 351
PCI_REG_MODE3		= 0x53
352
MODE3_MIION		= 0x04	  ; in PCI_REG_MOD3 OF PCI space
3545 hidnplayr 353
 
354
; VIA Rhine revisions
4606 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
4606 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
4606 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
4606 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
4606 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.
4606 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.
4606 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
 
4606 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
 
4606 hidnplayr 484
struct	rx_head
485
	status		dd ?
486
	control 	dd ?
487
	buff_addr	dd ?	; address
488
	next_desc	dd ?	;
3545 hidnplayr 489
 
4606 hidnplayr 490
	buff_addr_virt	dd ?
491
			rd 3	; alignment
492
ends
3545 hidnplayr 493
 
4606 hidnplayr 494
struct	tx_head
495
	status		dd ?
496
	control 	dd ?
497
	buff_addr	dd ?	; address
498
	next_desc	dd ?	;
3545 hidnplayr 499
 
4606 hidnplayr 500
	buff_addr_virt	dd ?
501
			rd 3	; alignment
502
ends
3545 hidnplayr 503
 
4606 hidnplayr 504
struct	device		ETH_DEVICE
3545 hidnplayr 505
 
4606 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
 
4606 hidnplayr 513
	cur_rx		dw ?
514
	cur_tx		dw ?
515
	last_tx 	dw ?
3545 hidnplayr 516
 
4606 hidnplayr 517
	rb 0x100 - ($ and 0xff) ; align 256
518
	tx_ring 	rb sizeof.tx_head*TX_RING_SIZE
3545 hidnplayr 519
 
4606 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
 
4606 hidnplayr 535
	cmp	[reason], DRV_ENTRY
536
	jne	.fail
3545 hidnplayr 537
 
4606 hidnplayr 538
	DEBUGF	1,"Loading driver\n"
539
	invoke	RegService, my_service, service_proc
540
	ret
3545 hidnplayr 541
 
542
  .fail:
4606 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
 
4606 hidnplayr 558
	mov	edx, [ioctl]
559
	mov	eax, [edx + IOCTL.io_code]
3545 hidnplayr 560
 
561
;------------------------------------------------------
562
 
4606 hidnplayr 563
	cmp	eax, 0 ;SRV_GETVERSION
564
	jne	@F
3545 hidnplayr 565
 
4606 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
 
4606 hidnplayr 571
	xor	eax, eax
572
	ret
3545 hidnplayr 573
 
574
;------------------------------------------------------
575
  @@:
4606 hidnplayr 576
	cmp	eax, 1 ;SRV_HOOK
577
	jne	.fail
3545 hidnplayr 578
 
4606 hidnplayr 579
	cmp	[edx + IOCTL.inp_size], 3		; Data input must be at least 3 bytes
580
	jb	.fail
3545 hidnplayr 581
 
4606 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
 
4606 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
4606 hidnplayr 594
	mov	ax, [eax+1]				;
3545 hidnplayr 595
  .nextdevice:
4606 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
       @@:
4606 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:
4606 hidnplayr 608
	cmp	[devices], MAX_DEVICES			; First check if the driver can handle one more card
609
	jae	.fail
3545 hidnplayr 610
 
4606 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
 
4606 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
 
4606 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
 
4606 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
 
4606 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
 
4606 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
4606 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
 
4606 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
 
4606 hidnplayr 650
	mov	[ebx + device.type], NET_TYPE_ETH
651
	invoke	NetRegDev
3545 hidnplayr 652
 
4606 hidnplayr 653
	cmp	eax, -1
654
	je	.destroy
3545 hidnplayr 655
 
4606 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:
4606 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:
4606 hidnplayr 671
	; todo: reset device into virgin state
3545 hidnplayr 672
 
673
  .err:
4606 hidnplayr 674
	invoke	KernelFree, ebx
3545 hidnplayr 675
 
676
  .fail:
4606 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
 
4606 hidnplayr 698
	DEBUGF	1, "Probing\n"
3545 hidnplayr 699
 
700
 
4606 hidnplayr 701
; Make the device a bus master
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
705
 
3545 hidnplayr 706
; get device id
4606 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
 
4606 hidnplayr 710
	mov	esi, chiplist
3758 hidnplayr 711
  .loop:
4606 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:
4606 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.
4606 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
 
4606 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)
4606 hidnplayr 733
	cmp	al, 0x40
734
	jb	.below_x40
3545 hidnplayr 735
 
4606 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
 
4606 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
 
4606 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
 
4606 hidnplayr 752
	; disable power-event config bit
753
	mov	al, 0xFF
754
	out	dx, al
3545 hidnplayr 755
 
4606 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.
4606 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
4606 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
4606 hidnplayr 776
	mov	ecx, W_MAX_TIMEOUT
3545 hidnplayr 777
   .poll_again:
4606 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
4606 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
4606 hidnplayr 791
	cmp	[ebx + device.revision], 0x40
792
	jb	.not_vt3065
3545 hidnplayr 793
 
4606 hidnplayr 794
	; delay 10ms to let MAC stable
795
	mov	esi, 1 ; 10ms
796
	invoke	Sleep
3545 hidnplayr 797
 
4606 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
 
4606 hidnplayr 802
	set_io	[ebx + device.io_addr], byCFGA
803
	in	al, dx
804
	and	al, 0xFE
805
	out	dx, al
3545 hidnplayr 806
 
4606 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
4606 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
4606 hidnplayr 821
	call	reload_eeprom
3545 hidnplayr 822
 
823
; read MAC
4606 hidnplayr 824
	call	read_mac
3545 hidnplayr 825
 
826
; restart MII auto-negotiation
4606 hidnplayr 827
	stdcall WriteMII, 0, 1 shl 9, 1
3545 hidnplayr 828
 
4606 hidnplayr 829
	DEBUGF	1, "Analyzing Media type, this may take several seconds"
3545 hidnplayr 830
 
4606 hidnplayr 831
	mov	ecx, 5
3545 hidnplayr 832
     .read_again:
4606 hidnplayr 833
	mov	esi, 1
834
	invoke	Sleep
3545 hidnplayr 835
 
4606 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:
4606 hidnplayr 842
	DEBUGF	1, "OK\n"
3545 hidnplayr 843
 
4606 hidnplayr 844
if 0
3545 hidnplayr 845
 
4606 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
 
4606 hidnplayr 852
	stdcall ReadMII, 1
853
	DEBUGF	1, "status 0x%x\n", ax
3545 hidnplayr 854
 
4606 hidnplayr 855
	stdcall ReadMII, 4
856
	DEBUGF	1, "advertising 0x%x\n", ax
3545 hidnplayr 857
 
4606 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
4606 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:
4606 hidnplayr 873
	DEBUGF	1, "Linespeed=100Mbs\n"
3545 hidnplayr 874
    @@:
875
 
4606 hidnplayr 876
	call	QueryAuto
3545 hidnplayr 877
 
4606 hidnplayr 878
	test	eax, 1
879
	jz	.halfduplex
3545 hidnplayr 880
 
4606 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:
4606 hidnplayr 889
	DEBUGF	1, "Halfduplex\n"
3545 hidnplayr 890
    @@:
891
 
892
; set MII 10 FULL ON, only apply in vt3043
4606 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
4606 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
 
4606 hidnplayr 906
	call	MIIDelay
3545 hidnplayr 907
 
4606 hidnplayr 908
	set_io	[ebx + device.io_addr], byMIIAD
909
	mov	al, 0x41
910
	out	dx, al
3545 hidnplayr 911
 
4606 hidnplayr 912
	call	MIIDelay
3545 hidnplayr 913
 
4606 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
 
4606 hidnplayr 925
	DEBUGF	1, "reset\n"
3545 hidnplayr 926
 
927
; attach int handler
4606 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.
4606 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
 
4606 hidnplayr 944
	call	MIIDelay
3545 hidnplayr 945
 
946
; Initialize rings
4606 hidnplayr 947
	call	init_ring
3545 hidnplayr 948
 
4606 hidnplayr 949
; Set Multicast
950
	call	set_rx_mode
3545 hidnplayr 951
 
952
; set TCR RCR threshold to store and forward
4606 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
 
4606 hidnplayr 958
	set_io	[ebx + device.io_addr], byBCR1
959
	mov	al, 0x38
960
	out	dx, al
3545 hidnplayr 961
 
4606 hidnplayr 962
	set_io	[ebx + device.io_addr], byRCR
963
	mov	al, 0x2C
964
	out	dx, al
3545 hidnplayr 965
 
4606 hidnplayr 966
	set_io	[ebx + device.io_addr], byTCR
967
	mov	al, 0x60
968
	out	dx, al
3545 hidnplayr 969
 
970
; Set Fulldupex
971
 
4606 hidnplayr 972
	call	QueryAuto
973
	test	eax, eax	; full duplex?
974
	jz	@f
3545 hidnplayr 975
 
4606 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
 
4606 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
4606 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
 
4606 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
4606 hidnplayr 1001
	mov	[ebx + device.mtu], 1514
3545 hidnplayr 1002
 
1003
; Set link state to unknown
4606 hidnplayr 1004
	mov	[ebx + device.state], ETH_LINK_UNKNOWN
3545 hidnplayr 1005
 
4606 hidnplayr 1006
; say reset was successful
1007
	xor	eax, eax
1008
	ret
3545 hidnplayr 1009
 
1010
 
1011
 
1012
align 4
1013
unload:
1014
 
4606 hidnplayr 1015
	call	reset
1016
	push	eax edx
1017
	DEBUGF	1, "rhine disable\n"
3545 hidnplayr 1018
 
4606 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
 
4606 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
 
4606 hidnplayr 1031
	ret
3545 hidnplayr 1032
 
1033
 
1034
 
1035
 
1036
align 4
1037
reload_eeprom:
1038
 
4606 hidnplayr 1039
	DEBUGF	1, "Reload eeprom\n"
3545 hidnplayr 1040
 
4606 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:
4606 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
 
4606 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
 
4606 hidnplayr 1063
	DEBUGF	1, "Init ring\n"
3545 hidnplayr 1064
 
4606 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:
4606 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
 
4606 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:
4606 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
4606 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
 
4606 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
 
4606 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
 
4606 hidnplayr 1123
	ret
3545 hidnplayr 1124
 
1125
 
1126
align 4
1127
QueryAuto:
1128
 
4606 hidnplayr 1129
	DEBUGF	1, "Query Auto\n"
3545 hidnplayr 1130
 
4606 hidnplayr 1131
	push	ecx
1132
	stdcall ReadMII, 0x04	; advertised
1133
	mov	ecx, eax
1134
	stdcall ReadMII, 0x05
1135
	and	ecx, eax
3545 hidnplayr 1136
 
4606 hidnplayr 1137
	xor	eax, eax
1138
	test	ecx, 0x100
1139
	jnz	.one
3545 hidnplayr 1140
 
4606 hidnplayr 1141
	and	ecx, 0x1C0
1142
	cmp	ecx, 0x40
1143
	jne	.zero
3545 hidnplayr 1144
   .one:
4606 hidnplayr 1145
	inc	eax
1146
	DEBUGF	1, "AutoNego OK!\n"
3545 hidnplayr 1147
   .zero:
4606 hidnplayr 1148
	pop	ecx
3545 hidnplayr 1149
 
4606 hidnplayr 1150
	ret
3545 hidnplayr 1151
 
1152
 
4606 hidnplayr 1153
proc	ReadMII stdcall, byMIIIndex:dword
3545 hidnplayr 1154
 
1155
;        DEBUGF  1, "ReadMII Index=%x\n", [byMIIIndex]
1156
 
4606 hidnplayr 1157
	push	esi ebx ecx edx
3545 hidnplayr 1158
 
4606 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
 
4606 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
 
4606 hidnplayr 1170
	call	MIIDelay
3545 hidnplayr 1171
 
4606 hidnplayr 1172
	mov	al, byte [byMIIIndex]
1173
	set_io	[ebx + device.io_addr], byMIIAD
1174
	out	dx, al
3545 hidnplayr 1175
 
4606 hidnplayr 1176
	call	MIIDelay
3545 hidnplayr 1177
 
4606 hidnplayr 1178
	set_io	[ebx + device.io_addr], byMIICR
1179
	in	al, dx
1180
	or	al, 0x40
1181
	out	dx, al
3545 hidnplayr 1182
 
4606 hidnplayr 1183
	mov	ecx, 200
3545 hidnplayr 1184
  .read_again:
4606 hidnplayr 1185
	in	al, dx
1186
	test	al, 0x40
1187
	jz	@f
3545 hidnplayr 1188
 
4606 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
 
4606 hidnplayr 1196
	call	MIIDelay
3545 hidnplayr 1197
 
4606 hidnplayr 1198
	set_io	[ebx + device.io_addr], byMIIAD
1199
	in	ax, dx
3545 hidnplayr 1200
 
4606 hidnplayr 1201
	push	eax
1202
	mov	ax, bx
1203
	set_io	[ebx + device.io_addr], byMIIAD
1204
	out	dx, al
3545 hidnplayr 1205
 
4606 hidnplayr 1206
	shr	ax, 8
1207
	set_io	[ebx + device.io_addr], byMIICR
1208
	out	dx, al
3545 hidnplayr 1209
 
4606 hidnplayr 1210
	call	MIIDelay
3545 hidnplayr 1211
 
4606 hidnplayr 1212
	pop	eax
1213
	and	eax, 0xFFFF
1214
	rol	ax, 8
3545 hidnplayr 1215
 
4606 hidnplayr 1216
	pop	edx ecx ebx esi
1217
	ret
3545 hidnplayr 1218
endp
1219
 
1220
 
4606 hidnplayr 1221
 
1222
proc	WriteMII stdcall, byMIISetByte:dword, byMIISetBit:dword, byMIIOP:dword
1223
 
3545 hidnplayr 1224
;        DEBUGF  1, "WriteMII SetByte=%x SetBit=%x OP=%x\n", [byMIISetByte], [byMIISetBit], [byMIIOP]
1225
 
4606 hidnplayr 1226
	push	ebx eax ecx edx
3545 hidnplayr 1227
 
4606 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
 
4606 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
 
4606 hidnplayr 1239
	call	MIIDelay
3545 hidnplayr 1240
 
4606 hidnplayr 1241
	mov	al, byte [byMIISetByte]
1242
	set_io	[ebx + device.io_addr], byMIIAD
1243
	out	dx, al
3545 hidnplayr 1244
 
4606 hidnplayr 1245
	call	MIIDelay
3545 hidnplayr 1246
 
4606 hidnplayr 1247
	set_io	[ebx + device.io_addr], byMIICR
1248
	in	al, dx
1249
	or	al, 0x40
1250
	out	dx, al
3545 hidnplayr 1251
 
4606 hidnplayr 1252
	mov	ecx, 200
3545 hidnplayr 1253
  .read_again0:
4606 hidnplayr 1254
	in	al, dx
1255
	test	al, 0x40
1256
	jz	.done
3545 hidnplayr 1257
 
4606 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
 
4606 hidnplayr 1265
	call	MIIDelay
3545 hidnplayr 1266
 
4606 hidnplayr 1267
	set_io	[ebx + device.io_addr], wMIIDATA
1268
	in	ax, dx
3545 hidnplayr 1269
 
4606 hidnplayr 1270
	mov	ecx, [byMIISetBit]
1271
	rol	cx, 8
3545 hidnplayr 1272
 
4606 hidnplayr 1273
	cmp	byte [byMIIOP], 0
1274
	jne	@f
1275
	not	ecx
1276
	and	ax, cx
1277
	jmp	.end_mascarad
3545 hidnplayr 1278
     @@:
4606 hidnplayr 1279
	or	ax, cx
3545 hidnplayr 1280
     .end_mascarad:
1281
 
4606 hidnplayr 1282
	set_io	[ebx + device.io_addr], wMIIDATA
1283
	out	dx, ax
3545 hidnplayr 1284
 
4606 hidnplayr 1285
	call	MIIDelay
3545 hidnplayr 1286
 
4606 hidnplayr 1287
	set_io	[ebx + device.io_addr], byMIICR
1288
	in	al, dx
1289
	or	al, 0x20
1290
	out	dx, al
3545 hidnplayr 1291
 
4606 hidnplayr 1292
	mov	ecx, 200
3545 hidnplayr 1293
    .read_again1:
4606 hidnplayr 1294
	in	al, dx
1295
	test	al, 0x20
1296
	jz	@f
3545 hidnplayr 1297
 
4606 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
 
4606 hidnplayr 1305
	call	MIIDelay
3545 hidnplayr 1306
 
4606 hidnplayr 1307
	mov	ax, bx
1308
	and	al, 0x7F
1309
	set_io	[ebx + device.io_addr], byMIIAD
1310
	out	dx, al
3545 hidnplayr 1311
 
4606 hidnplayr 1312
	shr	ax, 8
1313
	set_io	[ebx + device.io_addr], byMIICR
1314
	out	dx, al
3545 hidnplayr 1315
 
4606 hidnplayr 1316
	call	MIIDelay
3545 hidnplayr 1317
 
4606 hidnplayr 1318
	pop	edx ecx eax ebx
1319
	ret
3545 hidnplayr 1320
endp
1321
 
1322
 
1323
align 4
1324
MIIDelay:
1325
 
4606 hidnplayr 1326
	mov	ecx, 0x7FFF
3545 hidnplayr 1327
    @@:
4606 hidnplayr 1328
	in	al, 0x61
1329
	in	al, 0x61
1330
	in	al, 0x61
1331
	in	al, 0x61
1332
	loop	@b
3545 hidnplayr 1333
 
4606 hidnplayr 1334
	ret
3545 hidnplayr 1335
 
1336
 
1337
align 4
1338
set_rx_mode:
1339
 
4606 hidnplayr 1340
	DEBUGF	1, "Set RX mode\n"
3545 hidnplayr 1341
 
4606 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
 
4606 hidnplayr 1348
	set_io	[ebx + device.io_addr], byMAR4
1349
	out	dx, eax
3545 hidnplayr 1350
 
4606 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
 
4606 hidnplayr 1355
	ret
3545 hidnplayr 1356
 
1357
 
1358
 
1359
 
1360
 
1361
; Beware of PCI posted writes
1362
macro IOSYNC
1363
{
4606 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
 
4606 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:
4606 hidnplayr 1378
	in	al, dx
1379
	stosb
1380
	inc	edx
1381
	dec	ecx
1382
	jnz	.next
3545 hidnplayr 1383
 
4606 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
 
4606 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
 
4606 hidnplayr 1403
	pushf
1404
	cli
3545 hidnplayr 1405
 
4606 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
 
4606 hidnplayr 1413
	cmp	[buffersize], 1514
1414
	ja	.fail
1415
	cmp	[buffersize], 60
1416
	jb	.fail
3545 hidnplayr 1417
 
4606 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
 
4606 hidnplayr 1424
	cmp	[edi + tx_head.buff_addr_virt], 0
1425
	jne	.fail
3545 hidnplayr 1426
 
4606 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
 
4606 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
 
4606 hidnplayr 1443
	inc	[ebx + device.cur_tx]
1444
	and	[ebx + device.cur_tx], TX_RING_SIZE-1
1445
 
1446
	;outw(IMRShadow,byIMR0); ;
1447
 
3545 hidnplayr 1448
; Update stats
4606 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
 
4606 hidnplayr 1454
	DEBUGF	1,"Transmit OK\n"
1455
	popf
1456
	xor	eax, eax
1457
	ret
3545 hidnplayr 1458
 
1459
  .fail:
4606 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
 
4606 hidnplayr 1479
	push	ebx esi edi
3545 hidnplayr 1480
 
4606 hidnplayr 1481
	DEBUGF	1,"INT\n"
3545 hidnplayr 1482
 
4606 hidnplayr 1483
; Find pointer of device which made IRQ occur
3545 hidnplayr 1484
 
4606 hidnplayr 1485
	mov	ecx, [devices]
1486
	test	ecx, ecx
1487
	jz	.nothing
1488
	mov	esi, device_list
3545 hidnplayr 1489
  .nextdevice:
4606 hidnplayr 1490
	mov	ebx, [esi]
3545 hidnplayr 1491
 
4606 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:
4606 hidnplayr 1499
	add	esi, 4
1500
	dec	ecx
1501
	jnz	.nextdevice
3545 hidnplayr 1502
  .nothing:
4606 hidnplayr 1503
	pop	edi esi ebx
1504
	xor	eax, eax
3545 hidnplayr 1505
 
4606 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
 
4606 hidnplayr 1512
	DEBUGF	1, "status=0x%x\n", ax
3545 hidnplayr 1513
 
4606 hidnplayr 1514
	push	ax
3545 hidnplayr 1515
 
4606 hidnplayr 1516
	test	ax, IntrRxDone
1517
	jz	.not_RX
3545 hidnplayr 1518
 
4606 hidnplayr 1519
	push	ebx
3545 hidnplayr 1520
  .more_RX:
4606 hidnplayr 1521
	pop	ebx
3545 hidnplayr 1522
 
4606 hidnplayr 1523
; Get the current descriptor pointer
3545 hidnplayr 1524
 
4606 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
 
4606 hidnplayr 1533
	test	[edi + rx_head.status], RX_SBITS_OWN_BIT
1534
	jnz	.not_bit_own
3545 hidnplayr 1535
 
4606 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
 
4606 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
 
4606 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
 
4606 hidnplayr 1555
	push	ebx
1556
	push	.more_RX	; return ptr
3545 hidnplayr 1557
 
4606 hidnplayr 1558
	push	ecx		; full packet size
1559
	push	[edi + rx_head.buff_addr_virt]
3545 hidnplayr 1560
 
1561
; reset the RX descriptor
1562
 
4606 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
 
4606 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
 
4606 hidnplayr 1578
	jmp	[Eth_input]
3545 hidnplayr 1579
 
1580
  .not_bit_own:
1581
  .not_RX:
1582
 
4606 hidnplayr 1583
	pop	ax
3545 hidnplayr 1584
 
4606 hidnplayr 1585
	test	ax, IntrTxDone
1586
	jz	.not_TX
3545 hidnplayr 1587
 
1588
      .loop_tx:
4606 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
 
4606 hidnplayr 1595
	test	[edi + tx_head.status], TX_SBITS_OWN_BIT
1596
	jnz	.not_TX
3545 hidnplayr 1597
 
4606 hidnplayr 1598
	cmp	[edi + tx_head.buff_addr_virt], 0
1599
	je	.not_TX
3545 hidnplayr 1600
 
4606 hidnplayr 1601
	DEBUGF	1,"Freeing buffer 0x%x\n", [edi + tx_head.buff_addr_virt]
3545 hidnplayr 1602
 
4606 hidnplayr 1603
	push	[edi + tx_head.buff_addr_virt]
1604
	mov	[edi + tx_head.buff_addr_virt], 0
1605
	invoke	KernelFree
3545 hidnplayr 1606
 
4606 hidnplayr 1607
	inc	[ebx + device.last_tx]
1608
	and	[ebx + device.last_tx], TX_RING_SIZE - 1
3545 hidnplayr 1609
 
4606 hidnplayr 1610
	jmp	.loop_tx
3545 hidnplayr 1611
 
1612
  .not_TX:
1613
 
4606 hidnplayr 1614
	; On Rhine-II, Bit 3 indicates Tx descriptor write-back race.
3545 hidnplayr 1615
if 0
4606 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
 
4606 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
    @@:
4606 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
 
4606 hidnplayr 1647
	pop	edi esi ebx
1648
	xor	eax, eax
1649
	inc	eax
3545 hidnplayr 1650
 
4606 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
 
4606 hidnplayr 1664
my_service	db 'RHINE',0			; max 16 chars including zero
1665
 
3758 hidnplayr 1666
chiplist:
4606 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
1671
; Duplicate entry, with 'M' features enabled.
1672
;                dd 0x31061106, rhine_6105;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL or HasIPChecksum or HasVLAN
1673
		dd 0x30531106, rhine_3053;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1674
		dd 0
3545 hidnplayr 1675
 
4606 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
 
4606 hidnplayr 1682
include_debug_strings				; All data which FDO uses will be included here
3545 hidnplayr 1683
 
4606 hidnplayr 1684
align 4
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