Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1514 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
1159 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
1519 hidnplayr 6
;;  Realtek 8139 driver for KolibriOS                              ;;
1159 hidnplayr 7
;;                                                                 ;;
1519 hidnplayr 8
;;  based on RTL8139.asm driver for menuetos                       ;;
9
;;  and realtek8139.asm for SolarOS by Eugen Brasoveanu            ;;
10
;;                                                                 ;;
1159 hidnplayr 11
;;    Written by hidnplayr@kolibrios.org                           ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
 
18
format MS COFF
19
 
20
	API_VERSION		equ 0x01000100
1519 hidnplayr 21
	DRIVER_VERSION		equ 5
1159 hidnplayr 22
 
1519 hidnplayr 23
	MAX_DEVICES		equ 16
24
 
1159 hidnplayr 25
	DEBUG			equ 1
26
	__DEBUG__		equ 1
1472 hidnplayr 27
	__DEBUG_LEVEL__ 	equ 2
1159 hidnplayr 28
 
29
include 'proc32.inc'
30
include 'imports.inc'
31
include 'fdo.inc'
1472 hidnplayr 32
include 'netdrv.inc'
1159 hidnplayr 33
 
34
public START
35
public service_proc
36
public version
37
 
38
	REG_IDR0		equ 0x00
39
	REG_MAR0		equ 0x08 ; multicast filter register 0
40
	REG_MAR4		equ 0x0c ; multicast filter register 4
41
	REG_TSD0		equ 0x10 ; transmit status of descriptor
42
	REG_TSAD0		equ 0x20 ; transmit start address of descriptor
43
	REG_RBSTART		equ 0x30 ; RxBuffer start address
44
	REG_COMMAND		equ 0x37 ; command register
45
	REG_CAPR		equ 0x38 ; current address of packet read (word) R/W
46
	REG_IMR 		equ 0x3c ; interrupt mask register
47
	REG_ISR 		equ 0x3e ; interrupt status register
48
	REG_TXCONFIG		equ 0x40 ; transmit configuration register
49
	REG_RXCONFIG		equ 0x44 ; receive configuration register 0
50
	REG_MPC 		equ 0x4c ; missed packet counter
51
	REG_9346CR		equ 0x50 ; serial eeprom 93C46 command register
52
	REG_CONFIG1		equ 0x52 ; configuration register 1
53
	REG_MSR 		equ 0x58
54
	REG_CONFIG4		equ 0x5a ; configuration register 4
55
	REG_HLTCLK		equ 0x5b ; undocumented halt clock register
56
	REG_BMCR		equ 0x62 ; basic mode control register
57
	REG_ANAR		equ 0x66 ; auto negotiation advertisement register
58
	REG_9346CR_WE		equ 11b SHL 6
59
 
60
	BIT_RUNT		equ 4 ; total packet length < 64 bytes
61
	BIT_LONG		equ 3 ; total packet length > 4k
62
	BIT_CRC 		equ 2 ; crc error occured
63
	BIT_FAE 		equ 1 ; frame alignment error occured
64
	BIT_ROK 		equ 0 ; received packet is ok
65
 
66
	BIT_RST 		equ 4 ; reset bit
67
	BIT_RE			equ 3 ; receiver enabled
68
	BIT_TE			equ 2 ; transmitter enabled
69
	BUFE			equ 1 ; rx buffer is empty, no packet stored
70
 
71
	BIT_ISR_TOK		equ 2 ; transmit ok
72
	BIT_ISR_RER		equ 1 ; receive error interrupt
73
	BIT_ISR_ROK		equ 0 ; receive ok
74
 
75
	BIT_TX_MXDMA		equ 8 ; Max DMA burst size per Tx DMA burst
76
	BIT_TXRR		equ 4 ; Tx Retry count 16+(TXRR*16)
77
 
78
	BIT_RXFTH		equ 13 ; Rx fifo threshold
79
	BIT_RBLEN		equ 11 ; Ring buffer length indicator
80
	BIT_RX_MXDMA		equ 8 ; Max DMA burst size per Rx DMA burst
81
	BIT_NOWRAP		equ 7 ; transfered data wrapping
82
	BIT_9356SEL		equ 6 ; eeprom selector 9346/9356
83
	BIT_AER 		equ 5 ; accept error packets
84
	BIT_AR			equ 4 ; accept runt packets
85
	BIT_AB			equ 3 ; accept broadcast packets
86
	BIT_AM			equ 2 ; accept multicast packets
87
	BIT_APM 		equ 1 ; accept physical match packets
88
	BIT_AAP 		equ 0 ; accept all packets
89
 
90
	BIT_93C46_EEM1		equ 7 ; RTL8139 eeprom operating mode1
91
	BIT_93C46_EEM0		equ 6 ; RTL8139 eeprom operating mode0
92
	BIT_93C46_EECS		equ 3 ; chip select
93
	BIT_93C46_EESK		equ 2 ; serial data clock
94
	BIT_93C46_EEDI		equ 1 ; serial data input
95
	BIT_93C46_EEDO		equ 0 ; serial data output
96
 
97
	BIT_LWACT		equ 4 ; see REG_CONFIG1
98
	BIT_SLEEP		equ 1 ; sleep bit at older chips
99
	BIT_PWRDWN		equ 0 ; power down bit at older chips
100
	BIT_PMEn		equ 0 ; power management enabled
101
 
102
	BIT_LWPTN		equ 2 ; see REG_CONFIG4
103
 
104
	BIT_ERTXTH		equ 16 ; early TX threshold
105
	BIT_TOK 		equ 15 ; transmit ok
106
	BIT_OWN 		equ 13 ; tx DMA operation is completed
107
 
108
	BIT_ANE 		equ 12 ; auto negotiation enable
109
 
110
	BIT_TXFD		equ 8 ; 100base-T full duplex
111
	BIT_TX			equ 7 ; 100base-T
112
	BIT_10FD		equ 6 ; 10base-T full duplex
113
	BIT_10			equ 5 ; 10base-T
114
	BIT_SELECTOR		equ 0 ; binary encoded selector CSMA/CD=00001
115
 
116
	BIT_IFG1		equ 25
117
	BIT_IFG0		equ 24
118
 
119
	RBLEN			equ 2 ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k
120
	TXRR			equ 8 ; total retries = 16+(TXRR*16)
121
	TX_MXDMA		equ 6 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=2048
122
	ERTXTH			equ 8 ; in unit of 32 bytes e.g:(8*32)=256
123
	RX_MXDMA		equ 7 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=unlimited
124
	RXFTH			equ 7 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=no threshold
125
 
126
	RX_CONFIG		equ (RBLEN shl BIT_RBLEN) or \
127
				    (RX_MXDMA shl BIT_RX_MXDMA) or \
128
				    (1 shl BIT_NOWRAP) or \
129
				    (RXFTH shl BIT_RXFTH) or\
1472 hidnplayr 130
				    (1 shl BIT_AB) or \ 		; Accept broadcast packets
131
				    (1 shl BIT_APM) or \		; Accept physical match packets
132
				    (1 shl BIT_AER) or \		; Accept error packets
133
				    (1 shl BIT_AR) or \ 		; Accept Runt packets (smaller then 64 bytes)
134
				    (1 shl BIT_AM)			; Accept multicast packets
1159 hidnplayr 135
 
1472 hidnplayr 136
	RX_BUFFER_SIZE		equ (8192 shl RBLEN);+16
1159 hidnplayr 137
	MAX_ETH_FRAME_SIZE	equ 1516 ; exactly 1514 wthout CRC
1519 hidnplayr 138
 
1159 hidnplayr 139
	NUM_TX_DESC		equ 4
140
 
141
	EE_93C46_REG_ETH_ID	equ 7 ; MAC offset
142
	EE_93C46_READ_CMD	equ (6 shl 6) ; 110b + 6bit address
143
	EE_93C56_READ_CMD	equ (6 shl 8) ; 110b + 8bit address
144
	EE_93C46_CMD_LENGTH	equ 9  ; start bit + cmd + 6bit address
145
	EE_93C56_CMD_LENGTH	equ 11 ; start bit + cmd + 8bit ddress
146
 
147
	VER_RTL8139		equ 1100000b
148
	VER_RTL8139A		equ 1110000b
149
	VER_RTL8139AG		equ 1110100b
150
	VER_RTL8139B		equ 1111000b
151
	VER_RTL8130		equ VER_RTL8139B
152
	VER_RTL8139C		equ 1110100b
153
	VER_RTL8100		equ 1111010b
154
	VER_RTL8100B		equ 1110101b
155
	VER_RTL8139D		equ VER_RTL8100B
156
	VER_RTL8139CP		equ 1110110b
157
	VER_RTL8101		equ 1110111b
158
 
159
	IDX_RTL8139		equ 0
160
	IDX_RTL8139A		equ 1
161
	IDX_RTL8139B		equ 2
162
	IDX_RTL8139C		equ 3
163
	IDX_RTL8100		equ 4
164
	IDX_RTL8139D		equ 5
165
	IDX_RTL8139D		equ 6
166
	IDX_RTL8101		equ 7
167
 
168
	ISR_SERR		equ 1 SHL 15
169
	ISR_TIMEOUT		equ 1 SHL 14
170
	ISR_LENCHG		equ 1 SHL 13
171
	ISR_FIFOOVW		equ 1 SHL 6
172
	ISR_PUN 		equ 1 SHL 5
173
	ISR_RXOVW		equ 1 SHL 4
174
	ISR_TER 		equ 1 SHL 3
175
	ISR_TOK 		equ 1 SHL 2
176
	ISR_RER 		equ 1 SHL 1
177
	ISR_ROK 		equ 1 SHL 0
178
 
179
	INTERRUPT_MASK		equ ISR_ROK or \
180
				    ISR_RXOVW or \
181
				    ISR_PUN or \
182
				    ISR_FIFOOVW or \
183
				    ISR_LENCHG or \
184
				    ISR_TOK or \
185
				    ISR_TER
186
 
187
	TSR_OWN 		equ 1 SHL 13
188
	TSR_TUN 		equ 1 SHL 14
189
	TSR_TOK 		equ 1 SHL 15
190
 
191
	TSR_CDH 		equ 1 SHL 28
192
	TSR_OWC 		equ 1 SHL 29
193
	TSR_TABT		equ 1 SHL 30
194
	TSR_CRS 		equ 1 SHL 31
195
 
196
 
1519 hidnplayr 197
virtual at ebx
1159 hidnplayr 198
 
1519 hidnplayr 199
	device:
200
 
201
	ETH_DEVICE
202
 
203
	.rx_buffer	dd ?
204
	.tx_buffer	dd ?
205
	.rx_data_offset dd ?
206
	.io_addr	dd ?
207
	.curr_tx_desc	db ?
208
	.last_tx_desc	db ?
209
	.pci_bus	db ?
210
	.pci_dev	db ?
211
	.irq_line	db ?
212
	.hw_ver_id	db ?
213
 
214
	.TX_DESC	rd NUM_TX_DESC
215
 
216
	.size = $ - device
217
 
218
end virtual
219
 
220
 
221
 
1159 hidnplayr 222
section '.flat' code readable align 16
223
 
224
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
225
;;                        ;;
226
;; proc START             ;;
227
;;                        ;;
228
;; (standard driver proc) ;;
229
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
230
 
231
align 4
232
proc START stdcall, state:dword
233
 
234
	cmp [state], 1
235
	jne .exit
236
 
237
  .entry:
238
 
1472 hidnplayr 239
	DEBUGF	2,"Loading rtl8139 driver\n"
1159 hidnplayr 240
	stdcall RegService, my_service, service_proc
241
	ret
242
 
243
  .fail:
244
  .exit:
245
	xor eax, eax
246
	ret
247
 
248
endp
249
 
250
 
251
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
252
;;                        ;;
253
;; proc SERVICE_PROC      ;;
254
;;                        ;;
255
;; (standard driver proc) ;;
256
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
257
 
258
align 4
259
proc service_proc stdcall, ioctl:dword
260
 
261
	mov	edx, [ioctl]
1472 hidnplayr 262
	mov	eax, [IOCTL.io_code]
1159 hidnplayr 263
 
264
;------------------------------------------------------
265
 
266
	cmp	eax, 0 ;SRV_GETVERSION
267
	jne	@F
268
 
1472 hidnplayr 269
	cmp	[IOCTL.out_size], 4
1159 hidnplayr 270
	jl	.fail
1472 hidnplayr 271
	mov	eax, [IOCTL.output]
1159 hidnplayr 272
	mov	[eax], dword API_VERSION
273
 
274
	xor	eax, eax
275
	ret
276
 
277
;------------------------------------------------------
278
  @@:
279
	cmp	eax, 1 ;SRV_HOOK
280
	jne	.fail
281
 
1472 hidnplayr 282
	cmp	[IOCTL.inp_size], 3		  ; Data input must be at least 3 bytes
1159 hidnplayr 283
	jl	.fail
284
 
1472 hidnplayr 285
	mov	eax, [IOCTL.input]
1159 hidnplayr 286
	cmp	byte [eax], 1				; 1 means device number and bus number (pci) are given
287
	jne	.fail					; other types arent supported for this card yet
288
 
289
; check if the device is already listed
290
 
1519 hidnplayr 291
	mov	esi, device_list
292
	mov	ecx, [devices]
1159 hidnplayr 293
	test	ecx, ecx
294
	jz	.firstdevice
1472 hidnplayr 295
 
296
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
297
	mov	ax , [eax+1]				;
1159 hidnplayr 298
  .nextdevice:
1472 hidnplayr 299
	mov	ebx, [esi]
300
	cmp	ax , word [device.pci_bus]		; compare with pci and device num in device list (notice the usage of word instead of byte)
1159 hidnplayr 301
	je	.find_devicenum 			; Device is already loaded, let's find it's device number
1472 hidnplayr 302
	add	esi, 4
1159 hidnplayr 303
	loop	.nextdevice
304
 
1472 hidnplayr 305
 
1159 hidnplayr 306
; This device doesnt have its own eth_device structure yet, lets create one
307
  .firstdevice:
1519 hidnplayr 308
	cmp	[devices], MAX_DEVICES			; First check if the driver can handle one more card
1159 hidnplayr 309
	jge	.fail
310
 
311
	push	edx
1519 hidnplayr 312
	stdcall KernelAlloc, device.size		; Allocate the buffer for eth_device structure
1159 hidnplayr 313
	pop	edx
314
	test	eax, eax
315
	jz	.fail
316
	mov	ebx, eax				; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
317
 
318
; Fill in the direct call addresses into the struct
319
 
1486 hidnplayr 320
	mov	[device.reset], reset
321
	mov	[device.transmit], transmit
322
	mov	[device.get_MAC], read_mac
323
	mov	[device.set_MAC], write_mac
324
	mov	[device.unload], unload
325
	mov	[device.name], my_service
1159 hidnplayr 326
 
327
; save the pci bus and device numbers
328
 
1472 hidnplayr 329
	mov	eax, [IOCTL.input]
1159 hidnplayr 330
	mov	cl , [eax+1]
1472 hidnplayr 331
	mov	[device.pci_bus], cl
1159 hidnplayr 332
	mov	cl , [eax+2]
1472 hidnplayr 333
	mov	[device.pci_dev], cl
1159 hidnplayr 334
 
335
; Now, it's time to find the base io addres of the PCI device
336
 
1472 hidnplayr 337
	find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
1159 hidnplayr 338
 
339
; We've found the io address, find IRQ now
340
 
1492 hidnplayr 341
	find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
1159 hidnplayr 342
 
1472 hidnplayr 343
	DEBUGF	2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
344
	[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
1159 hidnplayr 345
 
346
 
1472 hidnplayr 347
	allocate_and_clear [device.rx_buffer], (RX_BUFFER_SIZE+MAX_ETH_FRAME_SIZE), .err
1519 hidnplayr 348
   ;;     allocate_and_clear [device.tx_buffer], (TX_BUF_SIZE*NUM_TX_DESC), .err
1159 hidnplayr 349
 
350
; Ok, the eth_device structure is ready, let's probe the device
351
 
352
	call	probe							; this function will output in eax
353
	test	eax, eax
354
	jnz	.err							; If an error occured, exit
355
 
1519 hidnplayr 356
	mov	eax, [devices]						; Add the device structure to our device list
357
	mov	[device_list+4*eax], ebx				; (IRQ handler uses this list to find device)
358
	inc	[devices]						;
1159 hidnplayr 359
 
1514 hidnplayr 360
	mov	[device.type], NET_TYPE_ETH
361
	call	NetRegDev
362
 
1159 hidnplayr 363
	cmp	eax, -1
364
	je	.destroy
365
 
366
	ret
367
 
368
; If the device was already loaded, find the device number and return it in eax
369
 
370
  .find_devicenum:
1472 hidnplayr 371
	DEBUGF	2,"Trying to find device number of already registered device\n"
1514 hidnplayr 372
	call	NetPtrToNum						; This kernel procedure converts a pointer to device struct in ebx
1159 hidnplayr 373
									; into a device number in edi
374
	mov	eax, edi						; Application wants it in eax instead
1472 hidnplayr 375
	DEBUGF	2,"Kernel says: %u\n", eax
1159 hidnplayr 376
	ret
377
 
378
; If an error occured, remove all allocated data and exit (returning -1 in eax)
379
 
380
  .destroy:
381
	; todo: reset device into virgin state
382
 
383
  .err:
1472 hidnplayr 384
	stdcall KernelFree, dword [device.rx_buffer]
1519 hidnplayr 385
     ;;   stdcall KernelFree, dword [device.tx_buffer]
1159 hidnplayr 386
	stdcall KernelFree, ebx
387
 
388
 
389
  .fail:
390
	or	eax, -1
391
	ret
392
 
393
;------------------------------------------------------
394
endp
395
 
396
 
397
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
398
;;                                                                        ;;
399
;;        Actual Hardware dependent code starts here                      ;;
400
;;                                                                        ;;
401
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
402
 
403
align 4
404
unload:
405
	; TODO: (in this particular order)
406
	;
407
	; - Stop the device
408
	; - Detach int handler
409
	; - Remove device from local list (RTL8139_LIST)
410
	; - call unregister function in kernel
411
	; - Remove all allocated structures and buffers the card used
412
 
413
	or	eax,-1
414
 
415
ret
416
 
417
 
418
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
419
;;
420
;;  probe: enables the device (if it really is RTL8139)
421
;;
422
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
423
 
424
align 4
425
probe:
426
	DEBUGF	2,"Probing rtl8139 device: "
427
 
1472 hidnplayr 428
	make_bus_master [device.pci_bus], [device.pci_dev]
1159 hidnplayr 429
 
430
; get chip version
431
 
1472 hidnplayr 432
	set_io	0
433
	set_io	REG_TXCONFIG + 2
1159 hidnplayr 434
	in	ax , dx
435
	shr	ah , 2
436
	shr	ax , 6
437
	and	al , 01111111b
1514 hidnplayr 438
 
1159 hidnplayr 439
	mov	ecx, HW_VER_ARRAY_SIZE-1
440
  .chip_ver_loop:
1514 hidnplayr 441
	cmp	al , [hw_ver_array + ecx]
1159 hidnplayr 442
	je	.chip_ver_found
443
	dec	ecx
444
	jns	.chip_ver_loop
1514 hidnplayr 445
  .unknown:
446
	mov	ecx, 8
1159 hidnplayr 447
  .chip_ver_found:
1514 hidnplayr 448
	cmp	ecx, 8
449
	jg	.unknown
450
 
1472 hidnplayr 451
	mov	[device.hw_ver_id], cl
1159 hidnplayr 452
 
1514 hidnplayr 453
	mov	ecx, [crosslist + ecx*4]
1472 hidnplayr 454
	mov	[device.name], ecx
1178 hidnplayr 455
 
1514 hidnplayr 456
	DEBUGF	2,"Chip version: %s\n", ecx
1178 hidnplayr 457
 
1159 hidnplayr 458
; wake up the chip
459
 
1472 hidnplayr 460
	set_io	0
461
	set_io	REG_HLTCLK
1159 hidnplayr 462
	mov	al , 'R' ; run the clock
463
	out	dx , al
464
 
465
; unlock config and BMCR registers
466
 
1472 hidnplayr 467
	set_io	REG_9346CR
1159 hidnplayr 468
	mov	al , (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
469
	out	dx , al
470
 
471
; enable power management
472
 
1472 hidnplayr 473
	set_io	REG_CONFIG1
1159 hidnplayr 474
	in	al , dx
1472 hidnplayr 475
	cmp	[device.hw_ver_id], IDX_RTL8139B
1159 hidnplayr 476
	jl	.old_chip
477
 
478
; set LWAKE pin to active high (default value).
479
; it is for Wake-On-LAN functionality of some motherboards.
480
; this signal is used to inform the motherboard to execute a wake-up process.
481
; only at newer chips.
482
 
483
	or	al , (1 shl BIT_PMEn)
484
	and	al , not (1 shl BIT_LWACT)
485
	out	dx , al
1472 hidnplayr 486
 
487
	set_io	REG_CONFIG4
1159 hidnplayr 488
	in	al , dx
489
	and	al , not (1 shl BIT_LWPTN)
490
	out	dx , al
1472 hidnplayr 491
 
1159 hidnplayr 492
	jmp	.finish_wake_up
493
  .old_chip:
494
 
495
; wake up older chips
496
 
497
	and	al , not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN))
498
	out	dx , al
499
  .finish_wake_up:
500
 
501
; lock config and BMCR registers
502
 
503
	xor	al , al
1472 hidnplayr 504
	set_io	0
505
	set_io	REG_9346CR
1159 hidnplayr 506
	out	dx , al
507
	DEBUGF	2,"done!\n"
508
 
509
 
510
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
511
;;
512
;;   reset: Set up all registers and descriptors, clear some values
513
;;
514
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
515
 
516
reset:
517
	DEBUGF	2,"Resetting rtl8139: "
518
 
519
; attach int handler
520
 
1472 hidnplayr 521
	movzx	eax, [device.irq_line]
1159 hidnplayr 522
	DEBUGF	1,"Attaching int handler to irq %x, ",eax:1
523
	stdcall AttachIntHandler, eax, int_handler, dword 0
524
	test	eax, eax
525
	jnz	@f
526
	DEBUGF	1,"\nCould not attach int handler!\n"
527
;        or      eax, -1
528
;        ret
1519 hidnplayr 529
       @@:
1159 hidnplayr 530
 
531
; reset chip
532
 
533
	DEBUGF	1,"Resetting chip\n"
1472 hidnplayr 534
	set_io	0
535
	set_io	REG_COMMAND
1159 hidnplayr 536
	mov	al , 1 shl BIT_RST
537
	out	dx , al
538
	mov	cx , 1000		; wait no longer for the reset
539
  .wait_for_reset:
540
	in	al , dx
541
	test	al , 1 shl BIT_RST
542
	jz	.reset_completed	; RST remains 1 during reset
543
	dec	cx
544
	jns	.wait_for_reset
545
  .reset_completed:
546
 
547
; unlock config and BMCR registers
548
 
1472 hidnplayr 549
	set_io	REG_9346CR
1159 hidnplayr 550
	mov	al , (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
551
	out	dx , al
552
 
553
; initialize multicast registers (no filtering)
554
 
555
	mov	eax, 0xffffffff
1472 hidnplayr 556
	set_io	REG_MAR0
1159 hidnplayr 557
	out	dx , eax
1472 hidnplayr 558
	set_io	REG_MAR4
1159 hidnplayr 559
	out	dx , eax
560
 
561
; enable Rx/Tx
562
 
563
	mov	al , (1 shl BIT_RE) or (1 shl BIT_TE)
1472 hidnplayr 564
	set_io	REG_COMMAND
1159 hidnplayr 565
	out	dx , al
566
 
567
; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold
568
; accept broadcast packets, accept physical match packets
569
 
570
	mov	ax , RX_CONFIG
1472 hidnplayr 571
	set_io	REG_RXCONFIG
1159 hidnplayr 572
	out	dx , ax
573
 
1472 hidnplayr 574
 
1159 hidnplayr 575
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
576
 
577
	mov	eax , (TX_MXDMA shl BIT_TX_MXDMA) or (TXRR shl BIT_TXRR) or BIT_IFG1 or BIT_IFG0
1472 hidnplayr 578
	set_io	REG_TXCONFIG
1159 hidnplayr 579
	out	dx , eax
580
 
581
; enable auto negotiation
582
 
1472 hidnplayr 583
	set_io	REG_BMCR
1159 hidnplayr 584
	in	ax , dx
585
	or	ax , (1 shl BIT_ANE)
586
	out	dx , ax
587
 
588
; set auto negotiation advertisement
589
 
1472 hidnplayr 590
	set_io	REG_ANAR
1159 hidnplayr 591
	in	ax , dx
592
	or	ax , (1 shl BIT_SELECTOR) or (1 shl BIT_10) or (1 shl BIT_10FD) or (1 shl BIT_TX) or (1 shl BIT_TXFD)
593
	out	dx , ax
594
 
595
; lock config and BMCR registers
596
 
597
	xor	eax, eax
1472 hidnplayr 598
	set_io	REG_9346CR
1159 hidnplayr 599
	out	dx , al
600
 
601
; init RX/TX pointers
602
 
1472 hidnplayr 603
	mov	[device.rx_data_offset], eax
604
	mov	[device.curr_tx_desc], al
1519 hidnplayr 605
	mov	[device.last_tx_desc], al
1159 hidnplayr 606
 
1171 hidnplayr 607
; clear packet/byte counters
608
 
1472 hidnplayr 609
	lea	edi, [device.bytes_tx]
1171 hidnplayr 610
	mov	ecx, 6
611
	rep	stosd
612
 
1159 hidnplayr 613
; clear missing packet counter
614
 
1472 hidnplayr 615
	set_io	REG_MPC
1159 hidnplayr 616
	out	dx , eax
617
 
1472 hidnplayr 618
; set RxBuffer address, init RX buffer offset
1159 hidnplayr 619
 
1472 hidnplayr 620
	mov	eax, [device.rx_buffer]
1159 hidnplayr 621
	call	GetPgAddr
1472 hidnplayr 622
	set_io	0
623
	set_io	REG_RBSTART
1159 hidnplayr 624
	out	dx , eax
625
 
626
; enable interrupts
627
 
628
	mov	eax, INTERRUPT_MASK
1472 hidnplayr 629
	set_io	REG_IMR
1159 hidnplayr 630
	out	dx , ax
631
 
632
; Read MAC address
633
 
634
	call	read_mac
635
 
1519 hidnplayr 636
; Set the mtu, kernel will be able to send now
637
	mov	[device.mtu], 1514
638
 
1159 hidnplayr 639
; Indicate that we have successfully reset the card
640
 
641
	DEBUGF	2,"Done!\n"
642
	xor	eax, eax
643
 
644
	ret
645
 
646
 
647
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
648
;;                                         ;;
649
;; Transmit                                ;;
650
;;                                         ;;
1254 hidnplayr 651
;; In: buffer pointer in [esp+4]           ;;
652
;;     size of buffer in [esp+8]           ;;
1159 hidnplayr 653
;;     pointer to device structure in ebx  ;;
654
;;                                         ;;
655
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
656
align 4
657
transmit:
1254 hidnplayr 658
	DEBUGF	1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
659
	mov	eax, [esp+4]
1159 hidnplayr 660
	DEBUGF	1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
661
	[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
662
	[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
663
	[eax+13]:2,[eax+12]:2
664
 
1254 hidnplayr 665
	cmp	dword [esp+8], MAX_ETH_FRAME_SIZE
1519 hidnplayr 666
	jg	.fail
1254 hidnplayr 667
	cmp	dword [esp+8], 60
1519 hidnplayr 668
	jl	.fail
1159 hidnplayr 669
 
1519 hidnplayr 670
; check if we own the discriptor
671
	set_io	0
1472 hidnplayr 672
	movzx	ecx, [device.curr_tx_desc]
1519 hidnplayr 673
	shl	ecx, 2
674
	lea	edx, [edx+ecx+REG_TSD0]
1159 hidnplayr 675
	in	ax, dx
1519 hidnplayr 676
	test	ax, (1 shl BIT_OWN)
677
	jz	.wait_to_send
1159 hidnplayr 678
 
1519 hidnplayr 679
  .send_packet:
680
; Set the buffer address
681
	set_io	0
682
	lea	edx, [edx+ecx+REG_TSAD0]
683
	mov	eax, [esp+4]
684
	mov	[device.TX_DESC+ecx], eax
685
	GetRealAddr
686
	out	dx, eax
1159 hidnplayr 687
 
1519 hidnplayr 688
; And the size of the buffer
689
	set_io	0
690
	lea	edx, [edx+ecx+REG_TSD0]
691
	mov	eax, [esp+8]
692
;        or      eax, (ERTXTH shl BIT_ERTXTH)    ; Early threshold
693
	out	dx , eax
1159 hidnplayr 694
 
1519 hidnplayr 695
; Update stats
696
	inc	[device.packets_tx]
1472 hidnplayr 697
	add	dword [device.bytes_tx], eax
698
	adc	dword [device.bytes_tx + 4], 0
1159 hidnplayr 699
 
1519 hidnplayr 700
; get next descriptor
1472 hidnplayr 701
	inc	[device.curr_tx_desc]
702
	and	[device.curr_tx_desc], 3
1159 hidnplayr 703
 
1519 hidnplayr 704
	DEBUGF	1,"Packet Sent! "
705
	xor	eax, eax
706
	ret	8
1159 hidnplayr 707
 
1519 hidnplayr 708
  .wait_to_send:
1159 hidnplayr 709
 
1519 hidnplayr 710
	DEBUGF	1,"Waiting for timeout\n"
1159 hidnplayr 711
 
1519 hidnplayr 712
	mov	esi, 30
713
	stdcall Sleep
1159 hidnplayr 714
 
1519 hidnplayr 715
	in	ax, dx
716
	test	ax, (1 shl BIT_OWN)
717
	jnz	.send_packet
1159 hidnplayr 718
 
1519 hidnplayr 719
	pusha
720
	call	reset				 ; if chip hung, reset it
721
	popa
722
 
723
	jmp	.send_packet
724
 
725
  .fail:
726
	DEBUGF	1,"failed!\n"
727
	or	eax, -1
728
	ret	8
729
 
730
 
731
 
732
 
733
 
1159 hidnplayr 734
;;;;;;;;;;;;;;;;;;;;;;;
735
;;                   ;;
736
;; Interrupt handler ;;
737
;;                   ;;
738
;;;;;;;;;;;;;;;;;;;;;;;
739
align 4
740
int_handler:
741
 
1519 hidnplayr 742
	DEBUGF	1,"IRQ %x\n", eax:2		      ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
1159 hidnplayr 743
 
744
; find pointer of device wich made IRQ occur
745
 
1519 hidnplayr 746
	mov	esi, device_list
747
	mov	ecx, [devices]
1486 hidnplayr 748
	test	ecx, ecx
749
	jz	.fail
1159 hidnplayr 750
.nextdevice:
751
	mov	ebx, dword [esi]
752
 
1472 hidnplayr 753
	set_io	0
754
	set_io	REG_ISR
1159 hidnplayr 755
	in	ax , dx
756
	out	dx , ax 			    ; send it back to ACK
757
 
758
	add	esi, 4
759
 
760
	test	ax , ax
761
	jnz	.got_it
762
 
1486 hidnplayr 763
	dec	ecx
764
	jnz	.nextdevice
1159 hidnplayr 765
 
766
	ret					    ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
767
 
768
  .got_it:
769
 
770
; looks like we've found it!
771
 
772
; Lets found out why the irq occured then..
773
 
774
;----------------------------------------------------
775
; Received packet ok?
776
	test	ax, ISR_ROK
777
	jz	@f
778
	push	ax
779
 
780
  .receive:
1472 hidnplayr 781
	set_io	0
782
	set_io	REG_COMMAND
783
	in	al , dx
1159 hidnplayr 784
	test	al , BUFE			    ; test if RX buffer is empty
785
	jnz	.finish 			    ;
786
 
1472 hidnplayr 787
	DEBUGF	1,"RX: "
1159 hidnplayr 788
 
1472 hidnplayr 789
	mov	eax, [device.rx_buffer]
790
	add	eax, [device.rx_data_offset]
1159 hidnplayr 791
	test	byte [eax], (1 shl BIT_ROK)	    ; check if packet is ok
792
	jz	.reset_rx
1472 hidnplayr 793
 
794
; packet is ok, copy it
1159 hidnplayr 795
	movzx	ecx, word [eax+2]		    ; packet length
1472 hidnplayr 796
 
797
; Update stats
798
	add	dword [device.bytes_rx], ecx
799
	adc	dword [device.bytes_rx + 4], 0
800
	inc	dword [device.packets_rx]
801
 
1159 hidnplayr 802
	sub	ecx, 4				    ; don't copy CRC
1472 hidnplayr 803
 
1159 hidnplayr 804
	DEBUGF	1,"Received %u bytes\n", ecx
805
 
806
	push	ebx eax ecx
807
	stdcall KernelAlloc, ecx		    ; Allocate a buffer to put packet into
808
	pop	ecx
809
	test	eax, eax			    ; Test if we allocated succesfully
1472 hidnplayr 810
	jz	.abort
1159 hidnplayr 811
 
1472 hidnplayr 812
	mov	edi, eax			    ; Where we will copy too
813
 
814
	mov	esi, [esp]			    ; The buffer we will copy from
1159 hidnplayr 815
	add	esi, 4				    ; Dont copy CRC
816
 
817
	push	dword .abort			    ; Kernel will return to this address after EthReceiver
818
	push	ecx edi 			    ; Save buffer pointer and size, to pass to kernel
819
 
1472 hidnplayr 820
  .copy:
821
	shr	ecx, 1
822
	jnc	.nb
823
	movsb
824
  .nb:
825
	shr	ecx, 1
826
	jnc	.nw
827
	movsw
828
  .nw:
829
	jz	.nd
830
	rep	movsd
831
  .nd:
1159 hidnplayr 832
 
833
	jmp	EthReceiver			    ; Send it to kernel
834
 
1472 hidnplayr 835
 
1159 hidnplayr 836
  .abort:
837
	pop	eax ebx
838
						    ; update eth_data_start_offset
839
	movzx	eax, word [eax+2]		    ; packet length
1472 hidnplayr 840
	add	eax, [device.rx_data_offset]
1159 hidnplayr 841
	add	eax, 4+3			    ; packet header is 4 bytes long + dword alignment
842
	and	eax, not 3			    ; dword alignment
1472 hidnplayr 843
 
1159 hidnplayr 844
	cmp	eax, RX_BUFFER_SIZE
845
	jl	.no_wrap
1472 hidnplayr 846
	DEBUGF	2,"Wrapping"
1159 hidnplayr 847
	sub	eax, RX_BUFFER_SIZE
848
  .no_wrap:
1472 hidnplayr 849
	mov	[device.rx_data_offset], eax
850
	DEBUGF	1,"New RX ptr: %d ", eax
1159 hidnplayr 851
 
1472 hidnplayr 852
	set_io	0
853
	set_io	REG_CAPR			    ; update 'Current Address of Packet Read register'
1159 hidnplayr 854
	sub	eax, 0x10			    ; value 0x10 is a constant for CAPR
855
	out	dx , ax
856
 
857
	jmp	.receive			    ; check for multiple packets
858
 
859
  .reset_rx:
860
	test	byte [eax], (1 shl BIT_CRC)
861
	jz	.no_crc_error
862
	DEBUGF	2,"\nCRC error!\n"
863
 
864
  .no_crc_error:
865
	test	byte [eax], (1 shl BIT_FAE)
866
	jz	.no_fae_error
867
	DEBUGF	1,"\nFrame alignment error!\n"
868
 
869
  .no_fae_error:
870
	DEBUGF	1,"Reset RX\n"
871
	in	al , dx 			    ; read command register
872
	push	ax
873
 
874
	and	al , not (1 shl BIT_RE) 	    ; Clear the RE bit
875
	out	dx , al
876
 
877
	pop	ax
878
	out	dx , al 			    ; write original command back
879
 
880
	add	edx, REG_RXCONFIG - REG_COMMAND     ; Restore RX configuration
881
	mov	ax , RX_CONFIG
882
	out	dx , ax
883
 
884
  .finish:
885
	pop	ax
886
 
887
;----------------------------------------------------
888
; Transmit error ?
889
  @@:
890
	test	ax, ISR_TER
891
	jz	@f
892
 
1519 hidnplayr 893
;        push    ax
894
;        cmp     [device.curr_tx_desc], 4
895
;        jz      .notxd
896
;
897
;        set_io  0
898
;        movzx   ecx, [device.curr_tx_desc]
899
;        lea     edx, [edx+ecx*4+REG_TSD0]
900
;        in      eax, dx
901
;
902
;  .notxd:
903
;        test    eax, TSR_TUN
904
;        jz      .nobun
905
;        DEBUGF  2, "TX: FIFO Buffer underrun!\n"
906
;
907
;  .nobun:
908
;        test    eax, TSR_OWC
909
;        jz      .noowc
910
;        DEBUGF  2, "TX: OWC!\n"
911
;
912
;  .noowc:
913
;        test    eax, TSR_TABT
914
;        jz      .notabt
915
;        DEBUGF  2, "TX: TABT!\n"
916
;
917
;  .notabt:
918
;        test    eax, TSR_CRS
919
;        jz      .nocsl
920
;        DEBUGF  2, "TX: Carrier Sense Lost!\n"
921
;
922
;  .nocsl:
923
;        pop     ax
924
 
925
;----------------------------------------------------
926
; Transmit ok ?
927
  @@:
928
	test	ax, ISR_TOK
929
	jz	@f
930
 
1159 hidnplayr 931
	push	ax
1519 hidnplayr 932
	mov	si, 4
933
  .txdesloop:
934
	movzx	ecx, [device.last_tx_desc]
935
	shl	ecx, 2
1159 hidnplayr 936
 
1472 hidnplayr 937
	set_io	0
1519 hidnplayr 938
	set_io	REG_TSD0
939
	add	edx, ecx
1159 hidnplayr 940
	in	eax, dx
941
 
1519 hidnplayr 942
	test	eax, TSR_TOK
943
	jz	.notthisone
944
	mov	eax, TSR_OWN
945
	out	dx , eax
946
	DEBUGF	1,"TX OK: free buffer %x\n", [device.TX_DESC+ecx]:8
947
	stdcall KernelFree, [device.TX_DESC+ecx]
948
  .notthisone:
1159 hidnplayr 949
 
1519 hidnplayr 950
	inc	[device.last_tx_desc]
951
	and	[device.last_tx_desc], 3
1159 hidnplayr 952
 
1519 hidnplayr 953
	dec	si
954
	jnz	.txdesloop
1159 hidnplayr 955
 
1519 hidnplayr 956
  .done:
1159 hidnplayr 957
	pop	ax
958
 
959
;----------------------------------------------------
960
; Rx buffer overflow ?
961
  @@:
962
	test	ax, ISR_RXOVW
963
	jz	@f
964
 
965
	push	ax
1472 hidnplayr 966
	DEBUGF	2,"RX-buffer overflow!\n"
1159 hidnplayr 967
 
1519 hidnplayr 968
	set_io	0
969
	set_io	REG_ISR
1159 hidnplayr 970
	mov	ax , ISR_FIFOOVW or ISR_RXOVW
971
	out	dx , ax
972
	pop	ax
973
 
974
;----------------------------------------------------
1519 hidnplayr 975
; Packet underrun?
1159 hidnplayr 976
  @@:
977
	test	ax, ISR_PUN
978
	jz	@f
979
 
1472 hidnplayr 980
	DEBUGF	2,"Packet underrun!\n"
1159 hidnplayr 981
 
982
;----------------------------------------------------
983
; Receive FIFO overflow ?
984
  @@:
985
	test	ax, ISR_FIFOOVW
986
	jz	@f
987
 
988
	push	ax
1519 hidnplayr 989
	DEBUGF	2,"RX fifo overflow!\n"
1159 hidnplayr 990
 
1519 hidnplayr 991
	set_io	0
992
	set_io	REG_ISR
1159 hidnplayr 993
	mov	ax , ISR_FIFOOVW or ISR_RXOVW
994
	out	dx , ax
995
	pop	ax
996
 
997
;----------------------------------------------------
998
; Something about Cable changed ?
999
  @@:
1000
	test	ax, ISR_LENCHG
1001
	jz	.fail
1002
 
1003
	DEBUGF	2,"Cable changed!\n"
1004
	call	cable
1005
 
1006
  .fail:
1007
	ret
1008
 
1009
 
1010
 
1011
 
1012
;;;;;;;;;;;;;;;;;;;;;;;;;
1013
;;                     ;;
1014
;; Update Cable status ;;
1015
;;                     ;;
1016
;;;;;;;;;;;;;;;;;;;;;;;;;
1017
 
1018
align 4
1019
cable:
1020
	DEBUGF	1,"Checking Cable status: "
1021
 
1472 hidnplayr 1022
	mov	edx, dword [device.io_addr]
1159 hidnplayr 1023
	add	edx, REG_MSR
1024
	in	al , dx
1025
 
1026
;        test    al , 1 SHL 2     ; 0 = link ok 1 = link fail
1027
;        jnz     .notconnected
1028
 
1029
;        test    al , 1 SHL 3     ; 0 = 100 Mbps 1 = 10 Mbps
1030
;        jnz     .10mbps
1031
 
1032
	shr	al, 2
1033
	and	al, 3
1034
 
1472 hidnplayr 1035
	mov	byte [device.mode+3], al
1159 hidnplayr 1036
	DEBUGF	1,"Done!\n"
1037
ret
1038
 
1039
 
1040
 
1041
;;;;;;;;;;;;;;;;;;;;;;;
1042
;;                   ;;
1043
;; Write MAC address ;;
1044
;;                   ;;
1045
;;;;;;;;;;;;;;;;;;;;;;;
1046
 
1047
align 4
1048
write_mac:	; in: mac pushed onto stack (as 3 words)
1049
 
1472 hidnplayr 1050
	DEBUGF	2,"Writing MAC: "
1159 hidnplayr 1051
 
1052
; disable all in command registers
1053
 
1472 hidnplayr 1054
	set_io	0
1055
	set_io	REG_9346CR
1159 hidnplayr 1056
	xor	eax, eax
1057
	out	dx , al
1058
 
1472 hidnplayr 1059
	set_io	REG_IMR
1159 hidnplayr 1060
	xor	eax, eax
1061
	out	dx , ax
1062
 
1472 hidnplayr 1063
	set_io	REG_ISR
1159 hidnplayr 1064
	mov	eax, -1
1065
	out	dx , ax
1066
 
1067
; enable writing
1068
 
1472 hidnplayr 1069
	set_io	REG_9346CR
1159 hidnplayr 1070
	mov	eax, REG_9346CR_WE
1071
	out	dx , al
1072
 
1073
 ; write the mac ...
1074
 
1472 hidnplayr 1075
	set_io	REG_IDR0
1159 hidnplayr 1076
	pop	eax
1077
	out	dx , eax
1078
 
1472 hidnplayr 1079
	set_io	REG_IDR0+4
1159 hidnplayr 1080
	xor	eax, eax
1081
	pop	ax
1082
	out	dx , eax
1083
 
1084
; disable writing
1085
 
1472 hidnplayr 1086
	set_io	REG_9346CR
1159 hidnplayr 1087
	xor	eax, eax
1088
	out	dx , al
1089
 
1472 hidnplayr 1090
	DEBUGF	2,"ok!\n"
1159 hidnplayr 1091
 
1092
; Notice this procedure does not ret, but continues to read_mac instead.
1093
 
1094
 
1095
;;;;;;;;;;;;;;;;;;;;;;
1096
;;                  ;;
1097
;; Read MAC address ;;
1098
;;                  ;;
1099
;;;;;;;;;;;;;;;;;;;;;;
1100
 
1101
read_mac:
1472 hidnplayr 1102
	DEBUGF	2,"Reading MAC: "
1159 hidnplayr 1103
 
1472 hidnplayr 1104
	set_io	0
1105
	lea	edi, [device.mac]
1177 clevermous 1106
	in	eax, dx
1159 hidnplayr 1107
	stosd
1177 clevermous 1108
	add	edx, 4
1173 clevermous 1109
	in	ax, dx
1159 hidnplayr 1110
	stosw
1111
 
1472 hidnplayr 1112
	DEBUGF	2,"%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2
1173 clevermous 1113
 
1159 hidnplayr 1114
	ret
1115
 
1116
 
1117
 
1118
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1119
;;                                                                      ;;
1120
;; Read eeprom (type 93c46 and 93c56)                                   ;;
1121
;;                                                                      ;;
1122
;; In: word to be read in al (6bit in case of 93c46 and 8bit otherwise) ;;
1123
;;     pointer to device structure in ebx                               ;;
1124
;;                                                                      ;;
1125
;; OUT: word read in ax                                                 ;;
1126
;;                                                                      ;;
1127
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1128
 
1129
align 4
1130
read_eeprom:
1131
	DEBUGF	2,"Reading eeprom, "
1132
 
1472 hidnplayr 1133
	set_io	0
1159 hidnplayr 1134
	push	ebx
1135
	movzx	ebx, al
1472 hidnplayr 1136
	set_io	REG_RXCONFIG
1159 hidnplayr 1137
	in	al, dx
1138
	test	al, (1 shl BIT_9356SEL)
1139
	jz	.type_93c46
1140
;       and     bl, 01111111b ; don't care first bit
1141
	or	bx, EE_93C56_READ_CMD		; it contains start bit
1142
	mov	cx, EE_93C56_CMD_LENGTH-1	; cmd_loop counter
1143
	jmp	.read_eeprom
1144
.type_93c46:
1145
	and	bl, 00111111b
1146
	or	bx, EE_93C46_READ_CMD		; it contains start bit
1147
	mov	cx, EE_93C46_CMD_LENGTH-1	; cmd_loop counter
1148
.read_eeprom:
1472 hidnplayr 1149
	set_io	REG_9346CR
1159 hidnplayr 1150
;       mov     al, (1 shl BIT_93C46_EEM1)
1151
;       out     dx, al
1152
	mov	al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS) ; wake up the eeprom
1153
	out	dx, al
1154
.cmd_loop:
1155
	mov	al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
1156
	bt	bx, cx
1157
	jnc	.zero_bit
1158
	or	al, (1 shl BIT_93C46_EEDI)
1159
.zero_bit:
1160
	out	dx, al
1161
;       push    eax
1162
;       in      eax, dx ; eeprom delay
1163
;       pop     eax
1164
	or	al, (1 shl BIT_93C46_EESK)
1165
	out	dx, al
1166
;       in      eax, dx ; eeprom delay
1167
	dec	cx
1168
	jns	.cmd_loop
1169
;       in      eax, dx ; eeprom delay
1170
	mov	al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
1171
	out	dx, al
1172
	mov	cl, 0xf
1173
.read_loop:
1174
	shl	ebx, 1
1175
	mov	al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS) or (1 shl BIT_93C46_EESK)
1176
	out	dx, al
1177
;       in      eax, dx ; eeprom delay
1178
	in	al, dx
1179
	and	al, (1 shl BIT_93C46_EEDO)
1180
	jz	.dont_set
1181
	inc	ebx
1182
.dont_set:
1183
	mov	al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
1184
	out	dx, al
1185
;       in      eax, dx ; eeprom delay
1186
	dec	cl
1187
	jns	.read_loop
1188
	xor	al, al
1189
	out	dx, al
1190
	mov	ax, bx
1191
	pop	ebx
1192
 
1193
	ret
1194
 
1195
 
1196
; End of code
1197
 
1519 hidnplayr 1198
section '.data' data readable writable align 16 ; place all uninitialized data place here
1159 hidnplayr 1199
align 4 					; Place all initialised data here
1200
 
1519 hidnplayr 1201
devices 	dd 0
1202
version 	dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1203
my_service	db 'RTL8139',0			  ; max 16 chars include zero
1159 hidnplayr 1204
 
1519 hidnplayr 1205
device_1	db 'Realtek 8139',0
1206
device_2	db 'Realtek 8139A',0
1207
device_3	db 'Realtek 8139B',0
1208
device_4	db 'Realtek 8139C',0
1209
device_5	db 'Realtek 8100',0
1210
device_6	db 'Realtek 8139D',0
1211
device_7	db 'Realtek 8139CP',0
1212
device_8	db 'Realtek 8101',0
1213
device_unknown	db 'Unknown RTL8139 clone', 0
1178 hidnplayr 1214
 
1519 hidnplayr 1215
crosslist:
1216
	dd device_1
1217
	dd device_2
1218
	dd device_3
1219
	dd device_4
1220
	dd device_5
1221
	dd device_6
1222
	dd device_7
1223
	dd device_8
1224
	dd device_unknown
1178 hidnplayr 1225
 
1519 hidnplayr 1226
hw_ver_array:			 ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
1227
	db VER_RTL8139
1228
	db VER_RTL8139A
1229
	db VER_RTL8139B
1230
	db VER_RTL8139C
1231
	db VER_RTL8100
1232
	db VER_RTL8139D
1233
	db VER_RTL8139CP
1234
	db VER_RTL8101
1235
	db 0
1159 hidnplayr 1236
 
1237
HW_VER_ARRAY_SIZE = $-hw_ver_array
1238
 
1239
include_debug_strings				; All data wich FDO uses will be included here
1240
 
1519 hidnplayr 1241
device_list	rd MAX_DEVICES			 ; This list contains all pointers to device structures the driver is handling
1159 hidnplayr 1242