Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1554 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  RTL8169 driver for KolibriOS                                   ;;
7
;;                                                                 ;;
8
;;  Copyright 2007 mike.dld,                                       ;;
9
;;   mike.dld@gmail.com                                            ;;
10
;;                                                                 ;;
11
;;  Version 0.1  11 February 2007                                  ;;
12
;;  Version 0.2  3 August 2010 - port to net branch by hidnplayr   ;;
13
;;                                                                 ;;
14
;;  References:                                                    ;;
15
;;    r8169.c - linux driver (etherboot project)                   ;;
16
;;                                                                 ;;
17
;;          GNU GENERAL PUBLIC LICENSE                             ;;
18
;;             Version 2, June 1991                                ;;
19
;;                                                                 ;;
20
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21
 
22
format MS COFF
23
 
24
	API_VERSION		equ 0x01000100
25
	DRIVER_VERSION		equ 5
26
 
27
	MAX_DEVICES		equ 16
28
 
29
	DEBUG			equ 1
30
	__DEBUG__		equ 1
31
	__DEBUG_LEVEL__ 	equ 1
32
 
33
	NUM_TX_DESC		equ 4
34
	NUM_RX_DESC		equ 4
35
 
36
include 'proc32.inc'
37
include 'imports.inc'
38
include 'fdo.inc'
39
include 'netdrv.inc'
40
 
41
public START
42
public service_proc
43
public version
44
 
45
 
46
	REG_MAC0	       equ 0x0 ; Ethernet hardware address
47
	REG_MAR0	       equ 0x8 ; Multicast filter
48
	REG_TxDescStartAddr    equ 0x20
49
	REG_TxHDescStartAddr   equ 0x28
50
	REG_FLASH	       equ 0x30
51
	REG_ERSR	       equ 0x36
52
	REG_ChipCmd	       equ 0x37
53
	REG_TxPoll	       equ 0x38
54
	REG_IntrMask	       equ 0x3C
55
	REG_IntrStatus	       equ 0x3E
56
	REG_TxConfig	       equ 0x40
57
	REG_RxConfig	       equ 0x44
58
	REG_RxMissed	       equ 0x4C
59
	REG_Cfg9346	       equ 0x50
60
	REG_Config0	       equ 0x51
61
	REG_Config1	       equ 0x52
62
	REG_Config2	       equ 0x53
63
	REG_Config3	       equ 0x54
64
	REG_Config4	       equ 0x55
65
	REG_Config5	       equ 0x56
66
	REG_MultiIntr	       equ 0x5C
67
	REG_PHYAR	       equ 0x60
68
	REG_TBICSR	       equ 0x64
69
	REG_TBI_ANAR	       equ 0x68
70
	REG_TBI_LPAR	       equ 0x6A
71
	REG_PHYstatus	       equ 0x6C
72
	REG_RxMaxSize	       equ 0xDA
73
	REG_CPlusCmd	       equ 0xE0
74
	REG_RxDescStartAddr    equ 0xE4
75
	REG_ETThReg	       equ 0xEC
76
	REG_FuncEvent	       equ 0xF0
77
	REG_FuncEventMask      equ 0xF4
78
	REG_FuncPresetState    equ 0xF8
79
	REG_FuncForceEvent     equ 0xFC
80
 
81
	; InterruptStatusBits
82
	ISB_SYSErr	       equ 0x8000
83
	ISB_PCSTimeout	       equ 0x4000
84
	ISB_SWInt	       equ 0x0100
85
	ISB_TxDescUnavail      equ 0x80
86
	ISB_RxFIFOOver	       equ 0x40
87
	ISB_LinkChg	       equ 0x20
88
	ISB_RxOverflow	       equ 0x10
89
	ISB_TxErr	       equ 0x08
90
	ISB_TxOK	       equ 0x04
91
	ISB_RxErr	       equ 0x02
92
	ISB_RxOK	       equ 0x01
93
 
94
	; RxStatusDesc
95
	SD_RxRES	       equ 0x00200000
96
	SD_RxCRC	       equ 0x00080000
97
	SD_RxRUNT	       equ 0x00100000
98
	SD_RxRWT	       equ 0x00400000
99
 
100
	; ChipCmdBits
101
	CMD_Reset	       equ 0x10
102
	CMD_RxEnb	       equ 0x08
103
	CMD_TxEnb	       equ 0x04
104
	CMD_RxBufEmpty	       equ 0x01
105
 
106
	; Cfg9346Bits
107
	CFG_9346_Lock	       equ 0x00
108
	CFG_9346_Unlock        equ 0xC0
109
 
110
	; rx_mode_bits
111
	RXM_AcceptErr	       equ 0x20
112
	RXM_AcceptRunt	       equ 0x10
113
	RXM_AcceptBroadcast    equ 0x08
114
	RXM_AcceptMulticast    equ 0x04
115
	RXM_AcceptMyPhys       equ 0x02
116
	RXM_AcceptAllPhys      equ 0x01
117
 
118
	; RxConfigBits
119
	RXC_FIFOShift	       equ 13
120
	RXC_DMAShift	       equ 8
121
 
122
	; TxConfigBits
123
	TXC_InterFrameGapShift equ 24
124
	TXC_DMAShift	       equ 8	; DMA burst value (0-7) is shift this many bits
125
 
126
	; PHYstatus
127
	PHYS_TBI_Enable        equ 0x80
128
	PHYS_TxFlowCtrl        equ 0x40
129
	PHYS_RxFlowCtrl        equ 0x20
130
	PHYS_1000bpsF	       equ 0x10
131
	PHYS_100bps	       equ 0x08
132
	PHYS_10bps	       equ 0x04
133
	PHYS_LinkStatus        equ 0x02
134
	PHYS_FullDup	       equ 0x01
135
 
136
	; GIGABIT_PHY_registers
137
	PHY_CTRL_REG	       equ 0
138
	PHY_STAT_REG	       equ 1
139
	PHY_AUTO_NEGO_REG      equ 4
140
	PHY_1000_CTRL_REG      equ 9
141
 
142
	; GIGABIT_PHY_REG_BIT
143
	PHY_Restart_Auto_Nego  equ 0x0200
144
	PHY_Enable_Auto_Nego   equ 0x1000
145
 
146
	; PHY_STAT_REG = 1;
147
	PHY_Auto_Neco_Comp     equ 0x0020
148
 
149
	; PHY_AUTO_NEGO_REG = 4;
150
	PHY_Cap_10_Half        equ 0x0020
151
	PHY_Cap_10_Full        equ 0x0040
152
	PHY_Cap_100_Half       equ 0x0080
153
	PHY_Cap_100_Full       equ 0x0100
154
 
155
	; PHY_1000_CTRL_REG = 9;
156
	PHY_Cap_1000_Full      equ 0x0200
157
	PHY_Cap_1000_Half      equ 0x0100
158
 
159
	PHY_Cap_PAUSE	       equ 0x0400
160
	PHY_Cap_ASYM_PAUSE     equ 0x0800
161
 
162
	PHY_Cap_Null	       equ 0x0
163
 
164
	; _MediaType
165
	MT_10_Half	       equ 0x01
166
	MT_10_Full	       equ 0x02
167
	MT_100_Half	       equ 0x04
168
	MT_100_Full	       equ 0x08
169
	MT_1000_Full	       equ 0x10
170
 
171
	; _TBICSRBit
172
	TBI_LinkOK	       equ 0x02000000
173
 
174
	; _DescStatusBit
175
	DSB_OWNbit	       equ 0x80000000
176
	DSB_EORbit	       equ 0x40000000
177
	DSB_FSbit	       equ 0x20000000
178
	DSB_LSbit	       equ 0x10000000
179
 
180
	RX_BUF_SIZE		equ 1536    ; Rx Buffer size
181
 
182
 
183
ETH_ALEN	       equ 6
184
ETH_HLEN	       equ (2 * ETH_ALEN + 2)
185
ETH_ZLEN	       equ 60 ; 60 + 4bytes auto payload for
186
				      ; mininmum 64bytes frame length
187
 
188
; MAC address length
189
MAC_ADDR_LEN	    equ 6
190
 
191
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4)
192
MAX_ETH_FRAME_SIZE  equ 1536
193
 
194
TX_FIFO_THRESH	    equ 256	; In bytes
195
 
196
RX_FIFO_THRESH	    equ 7	; 7 means NO threshold, Rx buffer level before first PCI xfer
197
RX_DMA_BURST	    equ 7	; Maximum PCI burst, '6' is 1024
198
TX_DMA_BURST	    equ 7	; Maximum PCI burst, '6' is 1024
199
ETTh		    equ 0x3F	; 0x3F means NO threshold
200
 
201
EarlyTxThld	    equ 0x3F	; 0x3F means NO early transmit
202
RxPacketMaxSize     equ 0x0800	; Maximum size supported is 16K-1
203
InterFrameGap	    equ 0x03	; 3 means InterFrameGap = the shortest one
204
 
205
HZ		    equ 1000
206
 
207
RTL_MIN_IO_SIZE     equ 0x80
208
TX_TIMEOUT	    equ (6*HZ)
209
 
210
TIMER_EXPIRE_TIME equ 100
211
 
212
ETH_HDR_LEN	    equ 14
213
DEFAULT_MTU	    equ 1500
214
DEFAULT_RX_BUF_LEN  equ 1536
215
 
216
 
217
;#ifdef JUMBO_FRAME_SUPPORT
218
;#define MAX_JUMBO_FRAME_MTU    ( 10000 )
219
;#define MAX_RX_SKBDATA_SIZE    ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN )
220
;#else
221
MAX_RX_SKBDATA_SIZE equ 1600
222
;#endif                         //end #ifdef JUMBO_FRAME_SUPPORT
223
 
224
MCFG_METHOD_01	     equ 0x01
225
MCFG_METHOD_02	     equ 0x02
226
MCFG_METHOD_03	     equ 0x03
227
MCFG_METHOD_04	     equ 0x04
228
MCFG_METHOD_05	     equ 0x05
229
MCFG_METHOD_11	     equ 0x0b
230
MCFG_METHOD_12	     equ 0x0c
231
MCFG_METHOD_13	     equ 0x0d
232
MCFG_METHOD_14	     equ 0x0e
233
MCFG_METHOD_15	     equ 0x0f
234
 
235
PCFG_METHOD_1	    equ 0x01	; PHY Reg 0x03 bit0-3 == 0x0000
236
PCFG_METHOD_2	    equ 0x02	; PHY Reg 0x03 bit0-3 == 0x0001
237
PCFG_METHOD_3	    equ 0x03	; PHY Reg 0x03 bit0-3 == 0x0002
238
 
239
virtual at 0
240
  tx_desc:
241
  .status    dd ?
242
  .vlan_tag  dd ?
1557 hidnplayr 243
  .buf_addr  dq ?
1554 hidnplayr 244
  .size = $
1557 hidnplayr 245
  rb	(NUM_TX_DESC-1)*tx_desc.size
246
  .buf_soft_addr	dd ?
1554 hidnplayr 247
end virtual
248
 
249
virtual at 0
250
  rx_desc:
251
  .status    dd ?
252
  .vlan_tag  dd ?
1557 hidnplayr 253
  .buf_addr  dq ?
1554 hidnplayr 254
  .size = $
1557 hidnplayr 255
  rb	(NUM_RX_DESC-1)*rx_desc.size
256
  .buf_soft_addr	dd ?
1554 hidnplayr 257
end virtual
258
 
259
virtual at ebx
260
 
261
	device:
262
 
263
	ETH_DEVICE
264
 
265
	.io_addr	dd ?
266
	.pci_bus	db ?
267
	.pci_dev	db ?
268
	.irq_line	db ?
269
 
270
	tpc:
271
	.mmio_addr	dd ? ; memory map physical address
272
	.chipset	dd ?
273
	.pcfg		dd ?
274
	.mcfg		dd ?
275
	.cur_rx 	dd ? ; Index into the Rx descriptor buffer of next Rx pkt
276
	.cur_tx 	dd ? ; Index into the Tx descriptor buffer of next Rx pkt
277
	.TxDescArrays	dd ? ; Index of Tx Descriptor buffer
278
	.RxDescArrays	dd ? ; Index of Rx Descriptor buffer
279
	.TxDescArray	dd ? ; Index of 256-alignment Tx Descriptor buffer
280
	.RxDescArray	dd ? ; Index of 256-alignment Rx Descriptor buffer
281
 
1557 hidnplayr 282
	rb 256-(($ - device) and 255)		   ;        align 256
283
	tx_ring rb NUM_TX_DESC * tx_desc.size * 2
1554 hidnplayr 284
 
1557 hidnplayr 285
	rb 256-(($ - device) and 255)		   ;        align 256
286
	rx_ring rb NUM_RX_DESC * rx_desc.size * 2
1554 hidnplayr 287
 
288
	device_size = $ - device
289
 
290
end virtual
291
 
292
intr_mask = ISB_LinkChg or ISB_RxOverflow or ISB_RxFIFOOver or ISB_TxErr or ISB_TxOK or ISB_RxErr or ISB_RxOK
293
rx_config = (RX_FIFO_THRESH shl RXC_FIFOShift) or (RX_DMA_BURST shl RXC_DMAShift) or 0x0000000E
294
 
295
 
296
macro	udelay msec {
297
 
298
	push	esi
299
	mov	esi, msec
300
	call	Sleep
301
	pop	esi
302
 
303
}
304
 
305
macro	WRITE_GMII_REG	RegAddr, value {
306
 
307
	set_io	REG_PHYAR
308
	if	value eq ax
309
	and	eax, 0x0000ffff
310
	or	eax, 0x80000000 + (RegAddr shl 16)
311
	else
312
	mov	eax, 0x80000000 + (RegAddr shl 16) + value
313
	end if
314
	out	dx, eax
315
 
316
	call	PHY_WAIT
317
}
318
 
319
macro	READ_GMII_REG  RegAddr {
320
 
321
local	.error, .done
322
 
1557 hidnplayr 323
	set_io	REG_PHYAR
1554 hidnplayr 324
	mov	eax, RegAddr shl 16
1557 hidnplayr 325
	out	dx, eax
1554 hidnplayr 326
 
327
	call	PHY_WAIT
328
	jz	.error
329
 
330
	in	eax, dx
331
	and	eax, 0xFFFF
332
	jmp	.done
333
 
334
  .error:
335
	or	eax, -1
336
  .done:
337
}
338
 
339
align 4
340
PHY_WAIT:	; io addr must already be set to REG_PHYAR
341
 
342
	udelay	1	 ;;;1000
343
 
344
	push	ecx
345
	mov	ecx, 2000
1557 hidnplayr 346
	; Check if the RTL8169 has completed writing/reading to the specified MII register
1554 hidnplayr 347
    @@:
348
	in	eax, dx
349
	test	eax, 0x80000000
350
	jz	.exit
351
	udelay	1	 ;;;100
352
	loop	@b
353
  .exit:
354
	pop	ecx
355
	ret
356
 
357
 
358
 
359
section '.flat' code readable align 16
360
 
361
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
362
;;                        ;;
363
;; proc START             ;;
364
;;                        ;;
365
;; (standard driver proc) ;;
366
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
367
 
368
align 4
369
proc START stdcall, state:dword
370
 
371
	cmp [state], 1
372
	jne .exit
373
 
374
  .entry:
375
 
376
	DEBUGF	2,"Loading rtl8169 driver\n"
377
	stdcall RegService, my_service, service_proc
378
	ret
379
 
380
  .fail:
381
  .exit:
382
	xor eax, eax
383
	ret
384
 
385
endp
386
 
387
 
388
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
389
;;                        ;;
390
;; proc SERVICE_PROC      ;;
391
;;                        ;;
392
;; (standard driver proc) ;;
393
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
394
 
395
align 4
396
proc service_proc stdcall, ioctl:dword
397
 
398
	mov	edx, [ioctl]
399
	mov	eax, [IOCTL.io_code]
400
 
401
;------------------------------------------------------
402
 
403
	cmp	eax, 0 ;SRV_GETVERSION
404
	jne	@F
405
 
406
	cmp	[IOCTL.out_size], 4
407
	jl	.fail
408
	mov	eax, [IOCTL.output]
409
	mov	[eax], dword API_VERSION
410
 
411
	xor	eax, eax
412
	ret
413
 
414
;------------------------------------------------------
415
  @@:
416
	cmp	eax, 1 ;SRV_HOOK
417
	jne	.fail
418
 
419
	cmp	[IOCTL.inp_size], 3			; Data input must be at least 3 bytes
420
	jl	.fail
421
 
422
	mov	eax, [IOCTL.input]
423
	cmp	byte [eax], 1				; 1 means device number and bus number (pci) are given
424
	jne	.fail					; other types arent supported for this card yet
425
 
426
; check if the device is already listed
427
 
428
	mov	esi, device_list
429
	mov	ecx, [devices]
430
	test	ecx, ecx
431
	jz	.firstdevice
432
 
433
;        mov     eax, [IOCTL.input]                     ; get the pci bus and device numbers
434
	mov	ax , [eax+1]				;
435
  .nextdevice:
436
	mov	ebx, [esi]
437
	cmp	ax , word [device.pci_bus]		; compare with pci and device num in device list (notice the usage of word instead of byte)
438
	je	.find_devicenum 			; Device is already loaded, let's find it's device number
439
	add	esi, 4
440
	loop	.nextdevice
441
 
442
 
443
; This device doesnt have its own eth_device structure yet, lets create one
444
  .firstdevice:
445
	cmp	[devices], MAX_DEVICES			; First check if the driver can handle one more card
446
	jge	.fail
447
 
1557 hidnplayr 448
	allocate_and_clear ebx, device_size, .fail	; Allocate memory to put the device structure in
1554 hidnplayr 449
 
450
; Fill in the direct call addresses into the struct
451
 
452
	mov	[device.reset], reset
453
	mov	[device.transmit], transmit
454
	mov	[device.get_MAC], read_mac
455
	mov	[device.set_MAC], write_mac
456
	mov	[device.unload], unload
457
	mov	[device.name], my_service
458
 
459
; save the pci bus and device numbers
460
 
461
	mov	eax, [IOCTL.input]
462
	mov	cl , [eax+1]
463
	mov	[device.pci_bus], cl
464
	mov	cl , [eax+2]
465
	mov	[device.pci_dev], cl
466
 
467
; Now, it's time to find the base io addres of the PCI device
468
 
469
	find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
470
	mov	eax, [device.io_addr]
471
	mov	[tpc.mmio_addr], eax
472
 
473
; We've found the io address, find IRQ now
474
 
475
	find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
476
 
477
	DEBUGF	2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
478
	[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:8
479
 
480
; Ok, the eth_device structure is ready, let's probe the device
481
; Because initialization fires IRQ, IRQ handler must be aware of this device
482
	mov	eax, [devices]						; Add the device structure to our device list
483
	mov	[device_list+4*eax], ebx				; (IRQ handler uses this list to find device)
484
	inc	[devices]						;
485
 
486
	call	probe							; this function will output in eax
487
	test	eax, eax
488
	jnz	.err2							; If an error occured, exit
489
 
490
 
491
	mov	[device.type], NET_TYPE_ETH
492
	call	NetRegDev
493
 
494
	cmp	eax, -1
495
	je	.destroy
496
 
497
	ret
498
 
499
; If the device was already loaded, find the device number and return it in eax
500
 
501
  .find_devicenum:
502
	DEBUGF	2,"Trying to find device number of already registered device\n"
503
	mov	ebx, eax
504
	call	NetPtrToNum						; This kernel procedure converts a pointer to device struct in ebx
505
									; into a device number in edi
506
	mov	eax, edi						; Application wants it in eax instead
507
	DEBUGF	2,"Kernel says: %u\n", eax
508
	ret
509
 
510
; If an error occured, remove all allocated data and exit (returning -1 in eax)
511
 
512
  .destroy:
513
	; todo: reset device into virgin state
514
 
515
  .err2:
516
	dec	[devices]
517
  .err:
518
	DEBUGF	2,"removing device structure\n"
519
	stdcall KernelFree, ebx
520
 
521
 
522
  .fail:
523
	or	eax, -1
524
	ret
525
 
526
;------------------------------------------------------
527
endp
528
 
529
 
530
align 4
531
unload:
532
 
533
	ret
534
 
535
 
536
align 4
537
init_board:
538
 
539
	DEBUGF	1,"init_board\n"
540
 
541
	make_bus_master [device.pci_bus], [device.pci_dev]
542
 
543
	; Soft reset the chip
544
	set_io	0
545
	set_io	REG_ChipCmd
546
	mov	al, CMD_Reset
547
	out	dx, al
548
 
549
	; Check that the chip has finished the reset
550
	mov	ecx, 1000
551
	set_io	REG_ChipCmd
552
    @@: in	al, dx
553
	test	al, CMD_Reset
554
	jz	@f
555
	udelay	10
556
	loop	@b
557
    @@:
558
	; identify config method
559
	set_io	REG_TxConfig
560
	in	eax, dx
561
	and	eax, 0x7c800000
562
	DEBUGF	1,"init_board: TxConfig & 0x7c800000 = 0x%x\n", eax
563
	mov	esi, mac_info-8
564
    @@: add	esi, 8
565
	mov	ecx, eax
566
	and	ecx, [esi]
567
	cmp	ecx, [esi]
568
	jne	@b
569
	mov	eax, [esi+4]
570
	mov	[tpc.mcfg], eax
571
 
572
	mov	[tpc.pcfg], PCFG_METHOD_3
573
	READ_GMII_REG 3
574
	and	al, 0x0f
575
	or	al, al
576
	jnz	@f
577
	mov	[tpc.pcfg], PCFG_METHOD_1
578
	jmp	.pconf
579
    @@: dec	al
580
	jnz	.pconf
581
	mov	[tpc.pcfg], PCFG_METHOD_2
582
  .pconf:
583
 
584
	; identify chip attached to board
585
	mov	ecx, 10
586
	mov	eax, [tpc.mcfg]
587
    @@: dec	ecx
588
	js	@f
589
	cmp	eax, [rtl_chip_info+ecx*8]
590
	jne	@b
591
	mov	[tpc.chipset], ecx
592
	jmp	.match
593
    @@:
594
	; if unknown chip, assume array element #0, original RTL-8169 in this case
595
	DEBUGF	1,"init_board: PCI device: unknown chip version, assuming RTL-8169\n"
596
	set_io	REG_TxConfig
597
	in	eax, dx
598
	DEBUGF	1,"init_board: PCI device: TxConfig = 0x%x\n", eax
599
 
600
	mov	[tpc.chipset],	0
601
 
602
	xor	eax, eax
603
	inc	eax
604
	ret
605
 
606
  .match:
607
	xor	eax,eax
608
	ret
609
 
610
 
611
 
612
;***************************************************************************
613
;   Function
614
;      probe
615
;   Description
616
;      Searches for an ethernet card, enables it and clears the rx buffer
617
;      If a card was found, it enables the ethernet -> TCPIP link
618
;   Destroyed registers
619
;      eax, ebx, ecx, edx
620
;
621
;***************************************************************************
622
align 4
623
probe:
624
 
625
	DEBUGF	1,"probe\n"
626
 
627
	call	init_board
628
 
629
	call	read_mac
630
 
631
	call	PHY_config
632
 
633
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
634
	set_io	0
635
	set_io	0x82
636
	mov	al, 0x01
637
	out	dx, al
638
	cmp	[tpc.mcfg], MCFG_METHOD_03
639
	jae	@f
640
;       DEBUGF  1,"K :   Set PCI Latency=0x40\n"
641
;       stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
642
   @@:
643
	cmp	[tpc.mcfg], MCFG_METHOD_02
644
	jne	@f
645
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
646
	set_io	0x82
647
	mov	al, 0x01
648
	out	dx, al
649
;       DEBUGF  1,"K :   Set PHY Reg 0x0bh = 0x00h\n"
650
	WRITE_GMII_REG 0x0b, 0x0000	 ; w 0x0b 15 0 0
651
    @@:
652
	; if TBI is not enabled
653
	set_io	0
654
	set_io	REG_PHYstatus
655
	in	al, dx
656
	test	al, PHYS_TBI_Enable
657
	jz	.tbi_dis
658
	READ_GMII_REG PHY_AUTO_NEGO_REG
659
 
660
	; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
661
	and	eax, 0x0C1F
662
	or	eax, PHY_Cap_10_Half or PHY_Cap_10_Full or PHY_Cap_100_Half or PHY_Cap_100_Full
663
	WRITE_GMII_REG PHY_AUTO_NEGO_REG, ax
664
 
665
	; enable 1000 Full Mode
666
	WRITE_GMII_REG PHY_1000_CTRL_REG, PHY_Cap_1000_Full or PHY_Cap_1000_Half ; rtl8168
667
 
668
	; Enable auto-negotiation and restart auto-nigotiation
669
	WRITE_GMII_REG PHY_CTRL_REG, PHY_Enable_Auto_Nego or PHY_Restart_Auto_Nego
670
 
671
	udelay	100
672
	mov	ecx, 10000
673
	; wait for auto-negotiation process
674
    @@: dec	ecx
675
	jz	@f
1557 hidnplayr 676
	set_io	0
1554 hidnplayr 677
	READ_GMII_REG PHY_STAT_REG
678
	udelay	100
679
	test	eax, PHY_Auto_Neco_Comp
680
	jz	@b
681
	set_io	REG_PHYstatus
682
	in	al, dx
683
	jmp	@f
684
  .tbi_dis:
685
	udelay	100
686
    @@:
687
 
688
 
689
;***************************************************************************
690
;   Function
691
;      rt8169_reset
692
;   Description
693
;      Place the chip (ie, the ethernet card) into a virgin state
694
;   Destroyed registers
695
;      eax, ebx, ecx, edx
696
;
697
;***************************************************************************
698
align 4
699
reset:
700
 
701
	DEBUGF	1,"reset\n"
702
 
703
	lea	eax, [tx_ring]
704
	mov	[tpc.TxDescArrays], eax
705
	mov	[tpc.TxDescArray], eax
706
 
707
	lea	eax, [rx_ring]
708
	mov	[tpc.RxDescArrays], eax
709
	mov	[tpc.RxDescArray], eax
710
 
711
	call	init_ring
712
	call	hw_start
713
 
714
	mov	[device.mtu], 1500
715
 
716
	xor	eax, eax
717
	ret
718
 
719
 
720
 
721
 
722
 
723
align 4
724
PHY_config:
725
 
726
	DEBUGF	1,"hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[tpc.mcfg],[tpc.pcfg]
727
 
728
	cmp	[tpc.mcfg], MCFG_METHOD_04
729
	jne	.not_4
1557 hidnplayr 730
	set_io	0
1554 hidnplayr 731
;       WRITE_GMII_REG 0x1F, 0x0001
732
;       WRITE_GMII_REG 0x1b, 0x841e
733
;       WRITE_GMII_REG 0x0e, 0x7bfb
734
;       WRITE_GMII_REG 0x09, 0x273a
735
	WRITE_GMII_REG 0x1F, 0x0002
736
	WRITE_GMII_REG 0x01, 0x90D0
737
	WRITE_GMII_REG 0x1F, 0x0000
738
	jmp	.exit
739
  .not_4:
740
	cmp	[tpc.mcfg], MCFG_METHOD_02
741
	je	@f
742
	cmp	[tpc.mcfg], MCFG_METHOD_03
743
	jne	.not_2_or_3
1557 hidnplayr 744
    @@:
745
	set_io	0
746
	WRITE_GMII_REG 0x1F, 0x0001
1554 hidnplayr 747
	WRITE_GMII_REG 0x15, 0x1000
748
	WRITE_GMII_REG 0x18, 0x65C7
749
	WRITE_GMII_REG 0x04, 0x0000
750
	WRITE_GMII_REG 0x03, 0x00A1
751
	WRITE_GMII_REG 0x02, 0x0008
752
	WRITE_GMII_REG 0x01, 0x1020
753
	WRITE_GMII_REG 0x00, 0x1000
754
	WRITE_GMII_REG 0x04, 0x0800
755
	WRITE_GMII_REG 0x04, 0x0000
756
	WRITE_GMII_REG 0x04, 0x7000
757
	WRITE_GMII_REG 0x03, 0xFF41
758
	WRITE_GMII_REG 0x02, 0xDE60
759
	WRITE_GMII_REG 0x01, 0x0140
760
	WRITE_GMII_REG 0x00, 0x0077
761
	WRITE_GMII_REG 0x04, 0x7800
762
	WRITE_GMII_REG 0x04, 0x7000
763
	WRITE_GMII_REG 0x04, 0xA000
764
	WRITE_GMII_REG 0x03, 0xDF01
765
	WRITE_GMII_REG 0x02, 0xDF20
766
	WRITE_GMII_REG 0x01, 0xFF95
767
	WRITE_GMII_REG 0x00, 0xFA00
768
	WRITE_GMII_REG 0x04, 0xA800
769
	WRITE_GMII_REG 0x04, 0xA000
770
	WRITE_GMII_REG 0x04, 0xB000
771
	WRITE_GMII_REG 0x03, 0xFF41
772
	WRITE_GMII_REG 0x02, 0xDE20
773
	WRITE_GMII_REG 0x01, 0x0140
774
	WRITE_GMII_REG 0x00, 0x00BB
775
	WRITE_GMII_REG 0x04, 0xB800
776
	WRITE_GMII_REG 0x04, 0xB000
777
	WRITE_GMII_REG 0x04, 0xF000
778
	WRITE_GMII_REG 0x03, 0xDF01
779
	WRITE_GMII_REG 0x02, 0xDF20
780
	WRITE_GMII_REG 0x01, 0xFF95
781
	WRITE_GMII_REG 0x00, 0xBF00
782
	WRITE_GMII_REG 0x04, 0xF800
783
	WRITE_GMII_REG 0x04, 0xF000
784
	WRITE_GMII_REG 0x04, 0x0000
785
	WRITE_GMII_REG 0x1F, 0x0000
786
	WRITE_GMII_REG 0x0B, 0x0000
787
	jmp	.exit
788
  .not_2_or_3:
789
	DEBUGF	1,"tpc.mcfg=%d, discard hw PHY config\n", [tpc.mcfg]
790
  .exit:
791
	ret
792
 
793
 
794
 
795
align 4
796
set_rx_mode:
797
 
798
	DEBUGF	1,"set_rx_mode\n"
799
 
800
	; IFF_ALLMULTI
801
	; Too many to filter perfectly -- accept all multicasts
802
	set_io	0
803
	set_io	REG_RxConfig
804
	in	eax, dx
805
	mov	ecx, [tpc.chipset]
806
	and	eax, [rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
807
	or	eax, rx_config or (RXM_AcceptBroadcast or RXM_AcceptMulticast or RXM_AcceptMyPhys)
808
	out	dx, eax
809
 
810
	; Multicast hash filter
811
	set_io	REG_MAR0 + 0
812
	or	eax, -1
813
	out	dx, eax
814
	set_io	REG_MAR0 + 4
815
	out	dx, eax
816
 
817
	ret
818
 
819
 
820
align 4
821
init_ring:
822
 
823
	DEBUGF	1,"init_ring\n"
824
 
825
	xor	eax, eax
826
	mov	[tpc.cur_rx], eax
827
	mov	[tpc.cur_tx], eax
828
 
829
	lea	edi, [tx_ring]
830
	mov	ecx, (NUM_TX_DESC * tx_desc.size) / 4
831
	rep	stosd
832
 
833
	lea	edi, [rx_ring]
834
	mov	ecx, (NUM_RX_DESC * rx_desc.size) / 4
835
	rep	stosd
836
 
837
	mov	edi, [tpc.RxDescArray]
838
	mov	ecx, NUM_RX_DESC
1557 hidnplayr 839
  .loop:
840
	push	ecx
841
	stdcall KernelAlloc, RX_BUF_SIZE
842
	mov	[edi + rx_desc.buf_soft_addr], eax
843
	call	GetPgAddr
844
	mov	dword [edi + rx_desc.buf_addr], eax
1554 hidnplayr 845
	mov	[edi + rx_desc.status], DSB_OWNbit or RX_BUF_SIZE
846
	add	edi, rx_desc.size
1557 hidnplayr 847
	pop	ecx
848
	loop	.loop
1554 hidnplayr 849
	or	[edi - rx_desc.size + rx_desc.status], DSB_EORbit
850
 
851
	ret
852
 
853
 
854
align 4
855
hw_start:
856
 
857
	DEBUGF	1,"hw_start\n"
858
 
1556 hidnplayr 859
; attach int handler
860
	movzx	eax, [device.irq_line]
861
	DEBUGF	1,"Attaching int handler to irq %x\n", eax:1
862
	stdcall AttachIntHandler, eax, int_handler, dword 0
863
 
1554 hidnplayr 864
	; Soft reset the chip
865
	set_io	0
866
	set_io	REG_ChipCmd
867
	mov	al, CMD_Reset
868
	out	dx, al
869
 
870
	; Check that the chip has finished the reset
871
	mov	ecx, 1000
872
	set_io	REG_ChipCmd
873
    @@: in	al, dx
874
	test	al, CMD_Reset
875
	jz	@f
876
	udelay	10
877
	loop	@b
878
    @@:
879
 
880
	set_io	REG_Cfg9346
881
	mov	al, CFG_9346_Unlock
882
	out	dx, al
883
 
884
	set_io	REG_ChipCmd
885
	mov	al, CMD_TxEnb or CMD_RxEnb
886
	out	dx, al
887
 
888
	set_io	REG_ETThReg
889
	mov	al, ETTh
890
	out	dx, al
891
 
892
	; For gigabit rtl8169
893
	set_io	REG_RxMaxSize
894
	mov	ax, RxPacketMaxSize
895
	out	dx, ax
896
 
897
	; Set Rx Config register
898
	set_io	REG_RxConfig
899
	in	ax, dx
900
	mov	ecx, [tpc.chipset]
901
	and	eax, [rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
902
	or	eax, rx_config
903
	out	dx, eax
904
 
905
	; Set DMA burst size and Interframe Gap Time
906
	set_io	REG_TxConfig
907
	mov	eax, (TX_DMA_BURST shl TXC_DMAShift) or (InterFrameGap shl TXC_InterFrameGapShift)
908
	out	dx, eax
909
 
910
	set_io	REG_CPlusCmd
911
	in	ax, dx
912
	out	dx, ax
913
 
914
	in	ax, dx
915
	or	ax, 1 shl 3
916
	cmp	[tpc.mcfg], MCFG_METHOD_02
917
	jne	@f
918
	cmp	[tpc.mcfg], MCFG_METHOD_03
919
	jne	@f
920
	or	ax,1 shl 14
921
	DEBUGF	1,"Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
922
	jmp	.set
923
    @@:
924
	DEBUGF	1," Set MAC Reg C+CR Offset 0xE0: bit-3\n"
925
  .set:
926
	set_io	REG_CPlusCmd
927
	out	dx, ax
928
 
929
	set_io	0xE2
930
;        mov     ax, 0x1517
931
;        out     dx, ax
932
;        mov     ax, 0x152a
933
;        out     dx, ax
934
;        mov     ax, 0x282a
935
;        out     dx, ax
936
	xor	ax, ax
937
	out	dx, ax
938
 
939
	xor	eax, eax
940
	mov	[tpc.cur_rx], eax
941
	lea	eax, [tx_ring]
942
	GetRealAddr
943
	set_io	REG_TxDescStartAddr
944
	out	dx, eax
945
 
946
	lea	eax, [rx_ring]
947
	GetRealAddr
948
	set_io	REG_RxDescStartAddr
949
	out	dx, eax
950
 
951
	set_io	REG_Cfg9346
952
	mov	al, CFG_9346_Lock
953
	out	dx, al
954
 
955
	udelay	10
956
 
957
	xor	eax, eax
958
	set_io	REG_RxMissed
959
	out	dx, eax
960
 
961
	call	set_rx_mode
962
 
1557 hidnplayr 963
	set_io	0
1554 hidnplayr 964
	; no early-rx interrupts
965
	set_io	REG_MultiIntr
966
	in	ax, dx
967
	and	ax, 0xF000
968
	out	dx, ax
969
 
970
	; set interrupt mask
971
	set_io	REG_IntrMask
972
	mov	ax, intr_mask
973
	out	dx, ax
974
 
975
	xor	eax, eax
976
	ret
977
 
978
 
979
align 4
980
read_mac:
981
 
982
	set_io	0
983
	set_io	REG_MAC0
984
	xor	ecx, ecx
1557 hidnplayr 985
	lea	edi, [device.mac]
1554 hidnplayr 986
	mov	ecx, MAC_ADDR_LEN
987
 
988
	; Get MAC address. FIXME: read EEPROM
989
    @@: in	al, dx
990
	stosb
991
	inc	edx
992
	loop	@r
993
 
994
	DEBUGF	1,"MAC = %x-%x-%x-%x-%x-%x\n",[device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
995
 
996
	ret
997
 
998
align 4
999
write_mac:
1000
 
1001
	ret	6
1002
 
1003
 
1004
 
1005
 
1006
 
1007
;***************************************************************************
1008
;   Function
1009
;      transmit
1010
;   Description
1011
;      Transmits a packet of data via the ethernet card
1012
;
1013
;   Destroyed registers
1014
;      eax, edx, esi, edi
1015
;
1016
;***************************************************************************
1017
align 4
1018
transmit:
1019
 
1020
	DEBUGF	1,"Transmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
1021
	mov	eax, [esp+4]
1022
	DEBUGF	1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1023
	[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1024
	[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1025
	[eax+13]:2,[eax+12]:2
1026
 
1027
	cmp	dword [esp+8], MAX_ETH_FRAME_SIZE
1028
	ja	.fail
1029
 
1030
;----------------------------------
1031
; Find currentTX descriptor address
1032
 
1033
	mov	eax, tx_desc.size
1034
	mul	[tpc.cur_tx]
1035
	lea	esi, [eax + tx_ring]
1036
 
1037
;---------------------------
1038
; Program the packet pointer
1039
 
1557 hidnplayr 1040
	mov	eax, [esp + 4]
1041
	mov	[esi + tx_desc.buf_soft_addr], eax
1554 hidnplayr 1042
	GetRealAddr
1557 hidnplayr 1043
	mov	dword [esi + tx_desc.buf_addr], eax
1554 hidnplayr 1044
 
1045
;------------------------
1046
; Program the packet size
1047
 
1557 hidnplayr 1048
	mov	eax, [esp + 8]
1554 hidnplayr 1049
    @@: or	eax, DSB_OWNbit or DSB_FSbit or DSB_LSbit
1050
	cmp	[tpc.cur_tx], NUM_TX_DESC - 1
1051
	jne	@f
1052
	or	eax, DSB_EORbit
1053
    @@: mov	[esi + tx_desc.status], eax
1054
 
1055
;----------------------------------------
1056
; Set the polling bit (start transmission
1057
 
1058
	set_io	0
1059
	set_io	REG_TxPoll
1060
	mov	al, 0x40     ; set polling bit
1061
	out	dx, al
1062
 
1063
;-----------------------
1064
; Update TX descriptor
1065
 
1066
	inc	[tpc.cur_tx]
1067
	and	[tpc.cur_tx], NUM_TX_DESC - 1
1068
	ret	8
1069
 
1070
  .fail:
1071
	DEBUGF	1,"transmit failed\n"
1072
	or	eax, -1
1073
	stdcall KernelFree, [esp+4]
1074
	ret	8
1075
 
1076
 
1077
;;;DSB_OWNbit
1078
 
1079
 
1080
;;;;;;;;;;;;;;;;;;;;;;;
1081
;;                   ;;
1082
;; Interrupt handler ;;
1083
;;                   ;;
1084
;;;;;;;;;;;;;;;;;;;;;;;
1085
 
1086
align 4
1087
int_handler:
1088
 
1089
	DEBUGF	1,"IRQ %x ",eax:2
1090
 
1091
; find pointer of device wich made IRQ occur
1092
 
1093
	mov	ecx, [devices]
1094
	test	ecx, ecx
1095
	jz	.fail
1096
	mov	esi, device_list
1097
  .nextdevice:
1098
	mov	ebx, dword [esi]
1099
 
1557 hidnplayr 1100
	set_io	0
1554 hidnplayr 1101
	set_io	REG_IntrStatus
1102
	in	ax, dx
1103
 
1104
	test	ax, ax
1105
	jnz	.got_it
1106
 
1107
  .continue:
1108
	add	esi, 4
1109
	dec	ecx
1110
	jnz	.nextdevice
1111
 
1112
	ret						; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1113
 
1114
  .got_it:
1115
	DEBUGF	1,"IntrStatus = 0x%x\n",ax
1116
 
1117
	cmp	ax, 0xFFFF	; if so, hardware is no longer present
1118
	je	.fail
1119
 
1120
;--------
1121
; Receive
1122
 
1123
	test	ax, ISB_RxOK
1124
	jz	.no_rx
1125
 
1126
	push	ax
1127
 
1128
	mov	eax, rx_desc.size
1129
	mul	[tpc.cur_rx]
1130
	lea	esi, [eax + rx_ring]
1131
 
1132
	DEBUGF	1,"RxDesc.status = 0x%x\n", [esi + rx_desc.status]
1133
 
1557 hidnplayr 1134
	mov	eax, [esi + rx_desc.status]
1135
	test	eax, DSB_OWNbit ;;;
1554 hidnplayr 1136
	jnz	.rx_return
1137
 
1138
	DEBUGF	1,"tpc.cur_rx = %u\n", [tpc.cur_rx]
1139
 
1140
	test	eax, SD_RxRES
1141
	jnz	.rx_return	;;;;; RX error!
1142
 
1143
	push	.rx_return
1144
	and	eax, 0x00001FFF
1145
	add	eax, -4 			; we dont need CRC
1146
	push	eax
1147
	DEBUGF	1,"data length = %u\n", ax
1148
 
1557 hidnplayr 1149
	push	[esi + rx_desc.buf_soft_addr]
1554 hidnplayr 1150
 
1557 hidnplayr 1151
;----------------------
1152
; Allocate a new buffer
1153
 
1154
	stdcall KernelAlloc, RX_BUF_SIZE
1155
	mov	[esi + rx_desc.buf_soft_addr], eax
1156
	GetRealAddr
1157
	mov	dword [esi + rx_desc.buf_addr], eax
1158
 
1554 hidnplayr 1159
;---------------
1160
; re set OWN bit
1161
 
1162
	mov	eax, DSB_OWNbit or RX_BUF_SIZE
1163
	cmp	[tpc.cur_rx], NUM_RX_DESC - 1
1164
	jne	@f
1165
	or	eax, DSB_EORbit
1166
    @@: mov	[esi + rx_desc.status], eax
1167
 
1168
;--------------
1169
; Update rx ptr
1170
 
1171
	inc	[tpc.cur_rx]
1172
	and	[tpc.cur_rx], NUM_RX_DESC - 1
1173
 
1174
	jmp	EthReceiver
1175
  .rx_return:
1176
 
1177
	pop	ax
1178
  .no_rx:
1179
 
1180
;---------
1181
; Transmit
1182
 
1183
	test	ax, ISB_TxOK
1184
	jz	.no_tx
1185
	push	ax
1186
 
1187
	DEBUGF	1,"TX ok!\n"
1188
	; TODO: free buffers
1189
 
1190
	pop	ax
1191
  .no_tx:
1192
 
1193
;-------
1194
; Finish
1195
 
1196
	set_io	0
1197
	set_io	REG_IntrStatus
1198
	out	dx, ax			; ACK all interrupts
1199
 
1200
  .fail:
1201
	ret
1202
 
1203
 
1204
 
1205
 
1206
 
1207
 
1208
 
1209
 
1210
 
1211
; End of code
1212
align 4 					; Place all initialised data here
1213
 
1214
devices       dd 0
1215
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1216
my_service    db 'RTL8169',0			; max 16 chars include zero
1217
 
1218
include_debug_strings				; All data wich FDO uses will be included here
1219
 
1220
rtl_chip_info dd \
1221
  MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169
1222
  MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s
1223
  MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s
1224
  MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb
1225
  MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc
1226
  MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
1227
  MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
1228
  MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e         // PCI-E 8139
1229
  MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e         // PCI-E 8139
1230
  MCFG_METHOD_15, 0xff7e1880	; RTL8100e         // PCI-E 8139
1231
 
1232
mac_info dd \
1233
  0x38800000, MCFG_METHOD_15, \
1234
  0x38000000, MCFG_METHOD_12, \
1235
  0x34000000, MCFG_METHOD_13, \
1236
  0x30800000, MCFG_METHOD_14, \
1237
  0x30000000, MCFG_METHOD_11, \
1238
  0x18000000, MCFG_METHOD_05, \
1239
  0x10000000, MCFG_METHOD_04, \
1240
  0x04000000, MCFG_METHOD_03, \
1241
  0x00800000, MCFG_METHOD_02, \
1242
  0x00000000, MCFG_METHOD_01	; catch-all
1243
 
1244
section '.data' data readable writable align 16 ; place all uninitialized data place here
1245
 
1246
device_list rd MAX_DEVICES		       ; This list contains all pointers to device structures the driver is handling
1247