Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1519 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
;;  RTL8029/ne2000 driver for KolibriOS                            ;;
1159 hidnplayr 7
;;                                                                 ;;
1519 hidnplayr 8
;;  based on RTL8029.asm driver for menuetos                       ;;
9
;;  and realtek8029.asm for SolarOS by Eugen Brasoveanu            ;;
10
;;                                                                 ;;
1159 hidnplayr 11
;;    Written by hidnplayr@kolibrios.org                           ;;
1178 hidnplayr 12
;;     with help from CleverMouse                                  ;;
1159 hidnplayr 13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
19
format MS COFF
20
 
1519 hidnplayr 21
	API_VERSION		equ 0x01000100
22
	DRIVER_VERSION		equ 5
1159 hidnplayr 23
 
1519 hidnplayr 24
	MAX_DEVICES		equ 16
1159 hidnplayr 25
 
1519 hidnplayr 26
	DEBUG			equ 1
27
	__DEBUG__		equ 1
28
	__DEBUG_LEVEL__ 	equ 1
29
 
1159 hidnplayr 30
include 'proc32.inc'
31
include 'imports.inc'
32
include 'fdo.inc'
1492 hidnplayr 33
include 'netdrv.inc'
1159 hidnplayr 34
 
1492 hidnplayr 35
virtual at ebx
1159 hidnplayr 36
 
1519 hidnplayr 37
	device:
1159 hidnplayr 38
 
1519 hidnplayr 39
	ETH_DEVICE
1492 hidnplayr 40
 
1519 hidnplayr 41
	.io_addr	  dd ?
42
	.irq_line	  db ?
43
	.pci_bus	  db ?
44
	.pci_dev	  db ?
1159 hidnplayr 45
 
1519 hidnplayr 46
	.flags		  db ?
47
	.vendor 	  db ?
48
	.asic_base	  dw ?
49
	.memsize	  db ?
50
	.rx_start	  db ?
51
	.tx_start	  db ?
52
	.bmem		  dd ?
53
	.rmem		  dd ?
54
	.romdata	  rb 16
1159 hidnplayr 55
 
1519 hidnplayr 56
	.size = $ - device
1159 hidnplayr 57
 
58
end virtual
59
 
1492 hidnplayr 60
 
1159 hidnplayr 61
public START
62
public service_proc
63
public version
64
 
65
	P0_PSTART		  equ 0x01
66
	P0_PSTOP		  equ 0x02
67
	P0_BOUND		  equ 0x03
68
	P0_TSR			  equ 0x04
69
	P0_TPSR 		  equ 0x04
70
	P0_TBCR0		  equ 0x05
71
	P0_TBCR1		  equ 0x06
72
	P0_ISR			  equ 0x07
73
	P0_RSAR0		  equ 0x08
74
	P0_RSAR1		  equ 0x09
75
	P0_RBCR0		  equ 0x0A
76
	P0_RBCR1		  equ 0x0B
77
	P0_RSR			  equ 0x0C
78
	P0_RCR			  equ 0x0C
79
	P0_TCR			  equ 0x0D
80
	P0_DCR			  equ 0x0E
81
	P0_IMR			  equ 0x0F
82
 
83
	P1_PAR0 		  equ 0x01
84
	P1_PAR1 		  equ 0x02
85
	P1_PAR2 		  equ 0x03
86
	P1_PAR3 		  equ 0x04
87
	P1_PAR4 		  equ 0x05
88
	P1_PAR5 		  equ 0x06
89
	P1_CURR 		  equ 0x07
90
	P1_MAR0 		  equ 0x08
91
 
92
	CMD_PS0 		  equ 0x00	  ;  Page 0 select
93
	CMD_PS1 		  equ 0x40	  ;  Page 1 select
94
	CMD_PS2 		  equ 0x80	  ;  Page 2 select
95
	CMD_RD2 		  equ 0x20	  ;  Remote DMA control
96
	CMD_RD1 		  equ 0x10
97
	CMD_RD0 		  equ 0x08
98
	CMD_TXP 		  equ 0x04	  ;  transmit packet
99
	CMD_STA 		  equ 0x02	  ;  start
100
	CMD_STP 		  equ 0x01	  ;  stop
101
 
102
	RCR_MON 		  equ 0x20	  ;  monitor mode
103
 
104
	DCR_FT1 		  equ 0x40
105
	DCR_LS			  equ 0x08	  ;  Loopback select
106
	DCR_WTS 		  equ 0x01	  ;  Word transfer select
107
 
108
	ISR_PRX 		  equ 0x01	  ;  successful recv
109
	ISR_PTX 		  equ 0x02	  ;  successful xmit
110
	ISR_RXE 		  equ 0x04	  ;  receive error
111
	ISR_TXE 		  equ 0x08	  ;  transmit error
112
	ISR_OVW 		  equ 0x10	  ;  Overflow
113
	ISR_CNT 		  equ 0x20	  ;  Counter overflow
114
	ISR_RDC 		  equ 0x40	  ;  Remote DMA complete
115
	ISR_RST 		  equ 0x80	  ;  reset
116
 
1173 clevermous 117
	IRQ_MASK		  equ ISR_PRX ; + ISR_PTX + ISR_TXE
1159 hidnplayr 118
 
119
	RSTAT_PRX		  equ 0x01	  ;  successful recv
120
	RSTAT_CRC		  equ 0x02	  ;  CRC error
121
	RSTAT_FAE		  equ 0x04	  ;  Frame alignment error
122
	RSTAT_OVER		  equ 0x08	  ;  FIFO overrun
123
 
124
	TXBUF_SIZE		  equ 6
125
	RXBUF_END		  equ 32
126
	PAGE_SIZE		  equ 256
127
 
128
	ETH_ALEN		  equ 6
129
	ETH_HLEN		  equ 14
130
	ETH_ZLEN		  equ 60
131
	ETH_FRAME_LEN		  equ 1514
132
 
133
	FLAG_PIO		  equ 0x01
134
	FLAG_16BIT		  equ 0x02
135
	ASIC_PIO		  equ 0
136
 
137
	VENDOR_NONE		  equ 0
138
	VENDOR_WD		  equ 1
139
	VENDOR_NOVELL		  equ 2
140
	VENDOR_3COM		  equ 3
141
 
142
	NE_ASIC_OFFSET		  equ 0x10
143
	NE_RESET		  equ 0x0F	  ; Used to reset card
144
	NE_DATA 		  equ 0x00	  ; Used to read/write NIC mem
145
 
146
	MEM_8192		  equ 32
147
	MEM_16384		  equ 64
148
	MEM_32768		  equ 128
149
 
150
	ISA_MAX_ADDR		  equ 0x400
151
 
152
 
153
 
154
section '.flat' code readable align 16
155
 
156
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
157
;;
158
;; proc START
159
;;
160
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
161
 
1492 hidnplayr 162
align 4
1159 hidnplayr 163
proc START stdcall, state:dword
164
 
165
	cmp	[state], 1
166
	jne	.exit
167
  .entry:
168
	DEBUGF 2,"Registering rtl8029 service \n"
169
	stdcall RegService, my_service, service_proc
170
	ret
171
  .fail:
172
  .exit:
173
	xor	eax, eax
174
	ret
175
 
176
endp
177
 
178
 
179
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
180
;;
181
;; proc SERVICE_PROC
182
;;
183
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1492 hidnplayr 184
 
1159 hidnplayr 185
align 4
1492 hidnplayr 186
proc service_proc stdcall, ioctl:dword
1159 hidnplayr 187
 
1492 hidnplayr 188
	mov	edx, [ioctl]
189
	mov	eax, [IOCTL.io_code]
1159 hidnplayr 190
 
191
;------------------------------------------------------
192
		       ;---------------
193
	cmp	eax, 0 ;SRV_GETVERSION
194
	jne	@F     ;---------------
195
 
1492 hidnplayr 196
	cmp	[IOCTL.out_size], 4
1159 hidnplayr 197
	jl	.fail
1492 hidnplayr 198
	mov	eax, [IOCTL.output]
1159 hidnplayr 199
	mov	[eax], dword API_VERSION
200
 
201
	xor	eax, eax
1177 clevermous 202
	ret	4
1159 hidnplayr 203
 
204
;------------------------------------------------------
205
  @@:		       ;---------
206
	cmp	eax, 1 ;SRV_HOOK
207
	jne	@F     ;---------
208
 
209
	DEBUGF	2,"Checking if device is already listed..\n"
210
 
1492 hidnplayr 211
	mov	eax, [IOCTL.input]
1159 hidnplayr 212
 
1492 hidnplayr 213
	cmp	[IOCTL.inp_size], 3
1159 hidnplayr 214
	jl	.fail
215
	cmp	byte [eax], 1
216
	je	.pci
217
 
1492 hidnplayr 218
	cmp	[IOCTL.inp_size], 4
1159 hidnplayr 219
	jl	.fail
220
	cmp	byte [eax], 0
221
	je	.isa
222
 
223
	jmp	.fail
224
 
225
  .pci:
226
 
1492 hidnplayr 227
; check if the device is already listed
228
 
1519 hidnplayr 229
	mov	esi, device_list
230
	mov	ecx, [devices]
1159 hidnplayr 231
	test	ecx, ecx
232
	jz	.firstdevice_pci
1492 hidnplayr 233
 
234
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
235
	mov	ax , [eax+1]				;
1159 hidnplayr 236
  .nextdevice:
1492 hidnplayr 237
	mov	ebx, [esi]
238
	cmp	ax , word [device.pci_bus]		; compare with pci and device num in device list (notice the usage of word instead of byte)
239
	je	.find_devicenum 			; Device is already loaded, let's find it's device number
240
	add	esi, 4
1159 hidnplayr 241
	loop	.nextdevice
242
 
243
  .firstdevice_pci:
244
	call	create_new_struct
245
 
1492 hidnplayr 246
	mov	eax, [IOCTL.input]
247
	mov	cl , [eax+1]
248
	mov	[device.pci_bus], cl
249
	mov	cl , [eax+2]
250
	mov	[device.pci_dev], cl
1159 hidnplayr 251
 
1492 hidnplayr 252
; Now, it's time to find the base io addres of the PCI device
1178 hidnplayr 253
 
1492 hidnplayr 254
	find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
1159 hidnplayr 255
 
1492 hidnplayr 256
; We've found the io address, find IRQ now
1159 hidnplayr 257
 
1492 hidnplayr 258
	find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
259
 
1159 hidnplayr 260
	jmp	.hook
261
 
262
  .isa:
263
 
1519 hidnplayr 264
	mov	esi, device_list
265
	mov	ecx, [devices]
1159 hidnplayr 266
	test	ecx, ecx
267
	jz	.firstdevice_isa
1492 hidnplayr 268
	mov	al , [eax+3]
269
	movzx	edi, word [eax+1]
1159 hidnplayr 270
  .nextdevice_isa:
1492 hidnplayr 271
	mov	ebx, [esi]
272
	cmp	edi, [device.io_addr]
1159 hidnplayr 273
	jne	.maybenext
1492 hidnplayr 274
	cmp	al , [device.irq_line]
1159 hidnplayr 275
	je	find_device_num
276
  .maybenext:
1492 hidnplayr 277
	add	esi, 4
1159 hidnplayr 278
	loop	.nextdevice_isa
279
 
280
 
281
 
282
  .firstdevice_isa:
283
	call	create_new_struct
284
 
1492 hidnplayr 285
	mov	eax, [IOCTL.input]
286
	movzx	ecx , word [eax+1]
287
	mov	[device.io_addr], ecx
1159 hidnplayr 288
	mov	cl, [eax+3]
1492 hidnplayr 289
	mov	[device.irq_line], cl
1159 hidnplayr 290
 
291
  .hook:
292
 
1492 hidnplayr 293
	DEBUGF	2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
294
	[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
1159 hidnplayr 295
 
296
	call	probe							; this function will output in eax
297
	test	eax, eax
298
	jnz	.err							; If an error occured, exit
299
 
1519 hidnplayr 300
	mov	eax, [devices]
301
	mov	[device_list+4*eax], ebx
302
	inc	[devices]
1159 hidnplayr 303
 
1514 hidnplayr 304
	mov	[device.type], NET_TYPE_ETH
305
	call	NetRegDev
306
 
1177 clevermous 307
	cmp	eax, -1
308
	jz	.err
309
	ret	4
1159 hidnplayr 310
 
1492 hidnplayr 311
 
312
; If the device was already loaded, find the device number and return it in eax
313
 
314
  .find_devicenum:
315
	DEBUGF	1,"Trying to find device number of already registered device\n"
316
	mov	ebx, eax
1514 hidnplayr 317
	call	NetPtrToNum						; This kernel procedure converts a pointer to device struct in ebx
1492 hidnplayr 318
									; into a device number in edi
319
	mov	eax, edi						; Application wants it in eax instead
320
	DEBUGF	1,"Kernel says: %u\n", eax
321
	ret
322
 
1159 hidnplayr 323
  .err:
1492 hidnplayr 324
	DEBUGF	1,"Failed, removing device structure\n"
1159 hidnplayr 325
	stdcall KernelFree, ebx
326
 
327
	jmp	.fail
328
 
329
;------------------------------------------------------
330
  @@:
331
.fail:
332
	or	eax, -1
1177 clevermous 333
	ret	4
1159 hidnplayr 334
 
335
;------------------------------------------------------
336
endp
337
 
338
 
339
create_new_struct:
340
 
1519 hidnplayr 341
	cmp	[devices], MAX_DEVICES
1159 hidnplayr 342
	jge	.fail
343
 
1527 hidnplayr 344
	allocate_and_clear ebx, device.size, .fail	; Allocate the buffer for device structure
1159 hidnplayr 345
 
1492 hidnplayr 346
	mov	[device.reset], reset
347
	mov	[device.transmit], transmit
348
	mov	[device.get_MAC], read_mac
349
	mov	[device.set_MAC], write_mac
350
	mov	[device.unload], unload
351
	mov	[device.name], my_service
1159 hidnplayr 352
 
353
	ret
354
 
1527 hidnplayr 355
  .fail:
356
	add	esp, 4		; return to caller of 'hook'
1159 hidnplayr 357
	or	eax, -1
358
	ret
359
 
360
find_device_num:
361
 
362
	DEBUGF	1,"Trying to find device number of already registered device\n"
363
	mov	ebx, eax
1514 hidnplayr 364
	call	NetPtrToNum						; This kernel procedure converts a pointer to device struct in ebx
1159 hidnplayr 365
									; into a device number in edi
366
	mov	eax, edi						; Application wants it in eax instead
367
	DEBUGF	1,"Kernel says: %u\n", eax
368
	ret
369
 
370
 
371
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
372
;;                                                                        ;;
373
;;        Actual Hardware dependent code starts here                      ;;
374
;;                                                                        ;;
375
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
376
 
377
 
378
unload:   ; TODO
379
	or	eax, -1
380
	ret
381
 
382
 
383
 
384
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
385
;;
386
;;  probe: enables the device and clears the rx buffer
387
;;
388
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
389
 
390
probe:
1492 hidnplayr 391
	mov	[device.vendor], VENDOR_NONE
392
	mov	[device.bmem], 0
393
	mov	eax,[device.io_addr]
394
	add	eax, NE_ASIC_OFFSET
395
	mov	[device.asic_base], ax
1159 hidnplayr 396
 
397
	DEBUGF	2,"Trying 16-bit mode\n"
398
 
1492 hidnplayr 399
	or	[device.flags], FLAG_16BIT or FLAG_PIO
400
	mov	[device.memsize], MEM_32768
401
	mov	[device.tx_start], 64
402
	mov	[device.rx_start], TXBUF_SIZE + 64
1159 hidnplayr 403
 
404
	set_io	0
405
	set_io	P0_DCR
406
	mov	al, DCR_WTS + DCR_FT1 + DCR_LS
407
	out	dx, al
408
 
409
	set_io	P0_PSTART
410
	mov	al, MEM_16384
411
	out	dx, al
412
 
413
	set_io	P0_PSTOP
414
	mov	al, MEM_32768
415
	out	dx, al
416
 
417
	mov	esi, test_data
1492 hidnplayr 418
	mov	di, 16384
1159 hidnplayr 419
	mov	cx, 14
420
	call	eth_pio_write
421
 
1492 hidnplayr 422
	mov	si, 16384
1159 hidnplayr 423
	mov	cx, 14
1492 hidnplayr 424
	lea	edi, [device.romdata]
1159 hidnplayr 425
	call	eth_pio_read
426
 
1492 hidnplayr 427
	lea	esi, [device.romdata]
1159 hidnplayr 428
	mov	edi, test_data
429
	mov	ecx, 13
430
 
431
     repz    cmpsb
432
     jz      ep_set_vendor
433
 
434
 
435
	DEBUGF	2,"Trying 8-bit mode\n"
436
 
1492 hidnplayr 437
	mov	[device.flags], FLAG_PIO
438
	mov	[device.memsize], MEM_16384
439
	mov	[device.tx_start], 32
440
	mov	[device.rx_start], TXBUF_SIZE + 32
1159 hidnplayr 441
 
1492 hidnplayr 442
	mov	dx, [device.asic_base]
1159 hidnplayr 443
	add	dx, NE_RESET
444
 
445
	in	al, dx
446
	out	dx, al
447
 
448
	in	al, 0x84
449
 
450
	set_io	0
451
	mov	al, CMD_RD2 + CMD_STP
452
	out	dx, al
453
 
454
	set_io	P0_RCR
455
	mov	al, RCR_MON
456
	out	dx, al
457
 
458
	set_io	P0_DCR
459
	mov	al, DCR_FT1 + DCR_LS
460
	out	dx, al
461
 
462
	set_io	P0_PSTART
463
	mov	al, MEM_8192
464
	out	dx, al
465
 
466
	set_io	P0_PSTOP
467
	mov	al, MEM_16384
468
	out	dx, al
469
 
470
	mov	esi, test_data
1492 hidnplayr 471
	mov	di, 8192
1159 hidnplayr 472
	mov	cx, 14
473
	call	eth_pio_write
474
 
1492 hidnplayr 475
	mov	si, 8192
1159 hidnplayr 476
	mov	cx, 14
1492 hidnplayr 477
	lea	edi, [device.romdata]
1159 hidnplayr 478
	call	eth_pio_read
479
 
480
	mov	esi, test_data
1492 hidnplayr 481
	lea	edi, [device.romdata]
1159 hidnplayr 482
	mov	ecx, 13
483
 
484
    repz      cmpsb
485
    jz	      ep_set_vendor
486
 
487
	DEBUGF	2,"This is not a valid ne2000 device!\n"
488
	or	eax, -1
489
	ret
490
 
491
 
492
ep_set_vendor:
493
 
1492 hidnplayr 494
	cmp	[device.io_addr], ISA_MAX_ADDR
1159 hidnplayr 495
	jbe	ep_001
496
 
497
	DEBUGF	2,"Card is using PCI bus\n"
498
 
1492 hidnplayr 499
;        or      [flags], FLAG_16BIT
1159 hidnplayr 500
 
501
ep_001:
1492 hidnplayr 502
	mov	[device.vendor], VENDOR_NOVELL
1159 hidnplayr 503
 
504
ep_check_have_vendor:
505
 
506
 
1492 hidnplayr 507
	mov	al, [device.vendor]
1159 hidnplayr 508
	cmp	al, VENDOR_NONE
1492 hidnplayr 509
;        je      rtl8029_exit
1159 hidnplayr 510
 
511
	cmp	al, VENDOR_3COM
512
	je	reset
513
 
1492 hidnplayr 514
	mov	eax, [device.bmem]
515
	mov	[device.rmem], eax
1159 hidnplayr 516
 
517
	call	read_mac
518
 
519
	push	.hack
520
	sub	esp, 6
521
	mov	edi, esp
1492 hidnplayr 522
	lea	esi, [device.mac]
1159 hidnplayr 523
	movsd
524
	movsw
525
	jmp	write_mac
526
       .hack:
527
 
528
 
529
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
530
;;
531
;;   reset: Place the chip into a virgin state
532
;;
533
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
534
 
535
reset:
1178 hidnplayr 536
	DEBUGF	2,"Resetting device\n"
1159 hidnplayr 537
 
538
; attach int handler
1492 hidnplayr 539
	movzx	eax, [device.irq_line]
1159 hidnplayr 540
	DEBUGF	1,"Attaching int handler to irq %x\n",eax:1
541
	stdcall AttachIntHandler, eax, int_handler, dword 0
542
 
543
; Stop mode
544
 
545
	set_io	0
546
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STP
547
	out	dx, al
548
 
549
	set_io	P0_DCR
1492 hidnplayr 550
	test	[device.flags], FLAG_16BIT
1159 hidnplayr 551
	jz	nsr_001
552
 
553
	mov	al, 0x49
554
	jmp	nsr_002
555
 
556
nsr_001:
557
	mov	al, 0x48
558
 
559
nsr_002:
560
	out	dx, al
561
 
1519 hidnplayr 562
; clear remote bytes count
1159 hidnplayr 563
	set_io	0
564
 
565
	xor	al, al
566
 
567
	set_io	P0_RBCR0
568
	out	dx, al
569
 
570
	set_io	P0_RBCR1
571
	out	dx, al
572
 
573
 
1519 hidnplayr 574
; initialize Receive configuration register
1159 hidnplayr 575
	set_io	P0_RCR
576
	mov	al, 0x20	; monitor mode
577
	out	dx, al
578
 
579
 
580
; transmit configuration register
581
	set_io	P0_TCR
582
	mov	al, 2		; internal loopback
583
	out	dx, al
584
 
585
 
586
; transmit page stuff
587
	set_io	P0_TPSR
1492 hidnplayr 588
	mov	al, [device.tx_start]
1159 hidnplayr 589
	out	dx, al
590
 
591
; set receive control register ;;;;
592
	set_io	P0_RCR
593
	mov	al, 4		; accept broadcast
594
	out	dx, al
595
 
596
; pagestart
597
	set_io	P0_PSTART
1492 hidnplayr 598
	mov	al, [device.rx_start]
1159 hidnplayr 599
	out	dx, al
600
 
601
; pagestop
602
	set_io	P0_PSTOP
1492 hidnplayr 603
	mov	al, [device.memsize]
1159 hidnplayr 604
	out	dx, al
605
 
606
; page boundary
607
	set_io	P0_BOUND
1492 hidnplayr 608
	mov	al, [device.memsize]
1159 hidnplayr 609
	dec	al
610
	out	dx, al
611
 
612
 
613
;;clear IRQ mask
614
;        set_io  P0_IMR
615
;        xor     al, al
616
;        out     dx, al
617
 
618
	set_io	0
619
	mov	al, CMD_PS1 + CMD_RD2 + CMD_STP ; page 1, stop mode
620
	out	dx, al
621
 
622
	set_io	P1_CURR
1492 hidnplayr 623
	mov	al, [device.rx_start]
1159 hidnplayr 624
	out	dx, al
625
 
626
	set_io	0
627
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STA ; go to page 0
628
	out	dx, al
629
 
630
; Read MAC address
631
	call	read_mac
632
 
633
; clear interupt status
1173 clevermous 634
	set_io	0
1159 hidnplayr 635
	set_io	P0_ISR
636
	mov	al, 0xff
637
	out	dx, al
638
 
639
; set IRQ mask
640
	set_io	P0_IMR
641
	mov	al, IRQ_MASK
642
	out	dx, al
643
 
644
;; start mode
645
;        set_io  0
646
;        mov     al, CMD_STA
647
;        out     dx, al
648
 
649
; clear transmit control register
650
	set_io	P0_TCR
651
	mov	al, 0		; no loopback
652
	out	dx, al
653
 
1178 hidnplayr 654
; clear packet/byte counters
1492 hidnplayr 655
	xor	eax, eax
656
	lea	edi, [device.bytes_tx]
1178 hidnplayr 657
	mov	ecx, 6
658
	rep	stosd
659
 
1519 hidnplayr 660
; Set the mtu, kernel will be able to send now
661
	mov	[device.mtu], 1514
662
 
1159 hidnplayr 663
; Indicate that we have successfully reset the card
664
	DEBUGF	2,"Done!\n"
665
 
666
	ret
667
 
668
 
669
 
670
;***************************************************************************
671
;   Function
672
;      transmit
1254 hidnplayr 673
; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx
1159 hidnplayr 674
;***************************************************************************
675
 
676
align 4
677
transmit:
678
 
1254 hidnplayr 679
	mov	esi, [esp + 4]
680
	mov	ecx, [esp + 8]
1159 hidnplayr 681
	DEBUGF	2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx
682
	DEBUGF	2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2
683
 
1492 hidnplayr 684
	cmp	ecx, ETH_FRAME_LEN
685
	jg	.err ; packet is too long
686
	cmp	ecx, 60
687
	jl	.err ; packet is too short
1159 hidnplayr 688
 
1492 hidnplayr 689
	movzx	edi, [device.tx_start]
690
	shl	edi, 8
1159 hidnplayr 691
	push	cx
692
	call	eth_pio_write
693
	pop	cx
694
 
695
	set_io	0
696
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STA
697
	out	dx, al
698
 
699
	set_io	P0_TPSR
1492 hidnplayr 700
	mov	al, [device.tx_start]
1159 hidnplayr 701
	out	dx, al
702
 
703
	set_io	P0_TBCR0
704
	mov	al, cl
705
	out	dx, al
706
 
707
	set_io	P0_TBCR1
708
	mov	al, ch
709
	out	dx, al
710
 
711
	set_io	0
712
	mov	al, CMD_PS0 + CMD_TXP + CMD_RD2 + CMD_STA
713
	out	dx, al
714
 
715
	DEBUGF	2," - Packet Sent!\n"
1178 hidnplayr 716
 
1492 hidnplayr 717
	inc	[device.packets_tx]
1254 hidnplayr 718
	mov	eax, [esp + 8]			 ; Get packet size in eax
1178 hidnplayr 719
 
1492 hidnplayr 720
	add	dword [device.bytes_tx], eax
721
	adc	dword [device.bytes_tx + 4], 0
722
 
723
.err:
724
	or	eax, -1
1527 hidnplayr 725
.finish:
726
	stdcall KernelFree, [esp+4]
727
	ret	8
1159 hidnplayr 728
 
729
 
1527 hidnplayr 730
 
1159 hidnplayr 731
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
732
;
733
; Interrupt handler
734
;
735
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
736
align 4
737
int_handler:
738
 
739
	DEBUGF	2,"IRQ %x ",eax:2
740
 
741
; find pointer of device wich made INT occur
1519 hidnplayr 742
	mov	esi, device_list
743
	mov	ecx, [devices]
1159 hidnplayr 744
.nextdevice:
1492 hidnplayr 745
	mov	ebx, [esi]
1159 hidnplayr 746
 
1178 hidnplayr 747
	set_io	0
1159 hidnplayr 748
	set_io	P0_ISR
749
	in	al, dx
750
 
751
	DEBUGF	2,"isr %x ",eax:2
752
 
1178 hidnplayr 753
	test	al, ISR_PRX    ; packet received ok ?
1159 hidnplayr 754
	jnz	.rx
755
 
756
	add	esi, 4
757
 
758
	loop	.nextdevice
759
	ret
760
 
1178 hidnplayr 761
 
762
; looks like we've found a device wich received a packet..
1159 hidnplayr 763
.rx:
1178 hidnplayr 764
	stdcall KernelAlloc, ETH_FRAME_LEN  ; size doesnt really matter as packet size is smaller then kernel's page size
765
	test	eax, eax
766
	jz	.fail_2
1159 hidnplayr 767
 
1178 hidnplayr 768
;--------------------------------------
769
; allocate memory for temp variables in stack
1159 hidnplayr 770
 
1178 hidnplayr 771
	sub	esp, 14+8
1159 hidnplayr 772
 
773
	eth_type	equ esp
774
	pkthdr		equ esp + 2
775
	pktoff		equ esp + 6
776
	eth_rx_data_ptr equ esp + 8
777
	eth_tmp_len	equ esp + 12
778
 
1178 hidnplayr 779
; These will be used by eth_receiver when the packet gets there
780
 
1159 hidnplayr 781
	pointer 	equ esp + 14
782
	size		equ esp + 18
783
 
1178 hidnplayr 784
;-------------------------------------
785
 
1159 hidnplayr 786
	mov	[pointer], eax
787
	mov	[eth_rx_data_ptr], eax
788
 
789
	set_io	P0_BOUND
790
	in	al, dx
791
	inc	al
792
 
1492 hidnplayr 793
	cmp	al, [device.memsize]
1159 hidnplayr 794
	jb	.nsp_001
795
 
1492 hidnplayr 796
	mov	al, [device.rx_start]
1159 hidnplayr 797
 
798
.nsp_001:
799
	mov	ch, al
800
 
801
	set_io	0
802
	mov	al, CMD_PS1
803
	out	dx, al
804
 
805
	set_io	P1_CURR
806
	in	al, dx		     ; get current page
807
	mov	cl, al
808
 
809
	set_io	0
810
	mov	al, CMD_PS0
811
	out	dx, al
812
 
1492 hidnplayr 813
	cmp	cl, [device.memsize]
1159 hidnplayr 814
	jb	.nsp_002
815
 
1492 hidnplayr 816
	mov	cl, [device.rx_start]
1159 hidnplayr 817
 
818
.nsp_002:
819
	cmp	cl, ch
820
	je	.fail
821
 
822
	xor	ax, ax
823
	mov	ah, ch
824
 
825
	mov	[pktoff], ax
826
 
1492 hidnplayr 827
	mov	al, [device.flags]
1159 hidnplayr 828
	test	al, FLAG_PIO
829
	jz	.nsp_003
830
 
1492 hidnplayr 831
	mov	si, word [pktoff]
1159 hidnplayr 832
	lea	edi, [pkthdr]
833
	mov	cx, 4
834
	call	eth_pio_read
835
	jmp	.nsp_004
836
 
837
.nsp_003:
1492 hidnplayr 838
	mov	edi, [device.rmem]
1159 hidnplayr 839
	movzx	eax, word [pktoff]
840
	add	edi, eax
841
	mov	eax, [edi]
842
	mov	[pkthdr], eax
843
 
844
.nsp_004:
845
	add	word[pktoff] , 4
846
 
847
	xor	eax, eax
1178 hidnplayr 848
	mov	ax , [pkthdr + 2]
849
	sub	ax , 4
1159 hidnplayr 850
 
851
	DEBUGF	2,"Received %u bytes\n",eax
852
 
1492 hidnplayr 853
	add	dword [device.bytes_rx], eax  ; Update stats
854
	adc	dword [device.bytes_rx + 4], 0
855
	inc	dword [device.packets_rx]     ;
1178 hidnplayr 856
 
1159 hidnplayr 857
	mov	[eth_tmp_len], ax
858
	mov	dword[size], eax
859
 
860
	cmp	ax, ETH_ZLEN
861
	jb	.fail
862
 
1178 hidnplayr 863
	cmp	ax , ETH_FRAME_LEN
1159 hidnplayr 864
	ja	.fail
865
 
1178 hidnplayr 866
	mov	al , [pkthdr]
867
	test	al , RSTAT_PRX
1159 hidnplayr 868
	jz	.fail
869
 
870
   ; Right, we can now get the data
871
 
1492 hidnplayr 872
	movzx	esi, [device.memsize]
873
	sub	si , [pktoff]
1159 hidnplayr 874
 
1492 hidnplayr 875
	cmp	[eth_tmp_len], si
1159 hidnplayr 876
	jbe	.nsp_005
877
 
1187 hidnplayr 878
	DEBUGF	2,"WRAP!\n"
1178 hidnplayr 879
 
1492 hidnplayr 880
	mov	al , [device.flags]
1178 hidnplayr 881
	test	al , FLAG_PIO
1159 hidnplayr 882
	jz	.nsp_006
883
 
1492 hidnplayr 884
	push	esi
885
	mov	cx , si
886
	mov	si , [pktoff+4]
1178 hidnplayr 887
	mov	edi, [eth_rx_data_ptr+4]
1159 hidnplayr 888
	call	eth_pio_read
1492 hidnplayr 889
	pop	esi
1159 hidnplayr 890
	jmp	.nsp_007
891
 
892
.nsp_006:
1178 hidnplayr 893
	DEBUGF	2,"PIO mode not supported by HW!\n"
1159 hidnplayr 894
   ; Not implemented, as we are using PIO mode on this card
895
 
896
.nsp_007:
897
	xor	al, al
1492 hidnplayr 898
	mov	ah, [device.rx_start]
1159 hidnplayr 899
	mov	[pktoff], ax
900
 
1492 hidnplayr 901
	add	[eth_rx_data_ptr], esi
902
	sub	[eth_tmp_len], si
1159 hidnplayr 903
 
904
.nsp_005:
1492 hidnplayr 905
	test	[device.flags], FLAG_PIO
1159 hidnplayr 906
	jz	.nsp_008
907
 
1492 hidnplayr 908
	movzx	esi, word [pktoff]
909
	movzx	ecx, word [eth_tmp_len]
1159 hidnplayr 910
	mov	edi, [eth_rx_data_ptr]
911
	call	eth_pio_read
912
	jmp	.nsp_009
913
 
914
.nsp_008:
1178 hidnplayr 915
	DEBUGF	2,"PIO mode not supported by HW!\n"
1159 hidnplayr 916
   ; Not implemented, as we are using PIO mode on this card
917
 
918
.nsp_009:
919
	mov	al, [pkthdr+1]
1492 hidnplayr 920
	cmp	al, [device.rx_start]
1159 hidnplayr 921
	jne	.nsp_010
922
 
1492 hidnplayr 923
	mov	al, [device.memsize]
1159 hidnplayr 924
 
925
.nsp_010:
926
	set_io	0
927
	set_io	P0_BOUND
928
	dec	al
929
	out	dx, al
930
 
931
	add	esp, 14
1178 hidnplayr 932
	jmp	EthReceiver	; send it to the kernel
1159 hidnplayr 933
 
934
.fail:
935
	add	esp, 14+8
1178 hidnplayr 936
.fail_2:
1159 hidnplayr 937
	DEBUGF	2,"done\n"
938
ret
939
 
940
 
941
 
942
 
943
 
944
;;;;;;;;;;;;;;;;;;;;;;;
945
;;                   ;;
946
;; Write MAC address ;;
947
;;                   ;;
948
;;;;;;;;;;;;;;;;;;;;;;;
949
 
950
align 4
1178 hidnplayr 951
write_mac:	; in: mac on stack (6 bytes)
1159 hidnplayr 952
 
953
	DEBUGF	1,"Writing MAC: "
954
 
955
	set_io	0
956
	mov	al, CMD_PS1; + CMD_RD2 + CMD_STP
957
	out	dx, al
958
 
959
	set_io	P1_PAR0
960
	mov	esi, esp
961
	mov	cx, 6
962
 @@:
963
	lodsb
964
	out	dx, al
965
	inc	dx
966
	loopw	@r
967
 
968
	add	esp, 6
969
 
970
; Notice this procedure does not ret, but continues to read_mac instead.
971
 
972
;;;;;;;;;;;;;;;;;;;;;;
973
;;                  ;;
974
;; Read MAC address ;;
975
;;                  ;;
976
;;;;;;;;;;;;;;;;;;;;;;
977
 
978
read_mac:
979
 
980
	DEBUGF	1,"Reading MAC: "
981
 
982
;        set_io  0
983
;        mov     al, CMD_PS1; + CMD_RD2 + CMD_STP ; select page 1
984
;        out     dx, al
985
;
986
;        set_io  P1_PAR0
1492 hidnplayr 987
;        lea     edi, [mac]
1159 hidnplayr 988
;
989
;        mov     cx, 6
990
; .loop:
991
;        in      al, dx
992
;        stosb
993
;        inc     dx
994
;        loopw   .loop
995
;
996
;        set_io  0
997
;        mov     al, CMD_PS0; + CMD_RD2 + CMD_STA  ; set page back to 0
998
;        out     dx, al
999
 
1492 hidnplayr 1000
	mov	si, 0
1159 hidnplayr 1001
	mov	cx, 16
1492 hidnplayr 1002
	lea	edi, [device.romdata]
1159 hidnplayr 1003
	call	eth_pio_read
1004
 
1492 hidnplayr 1005
	lea	esi, [device.romdata]
1006
	lea	edi, [device.mac]
1159 hidnplayr 1007
	mov	ecx, 6
1008
 
1009
  .loop:
1010
	movsb
1492 hidnplayr 1011
	test	[device.flags], FLAG_16BIT
1159 hidnplayr 1012
	jz	.8bit
1013
	inc	esi
1014
  .8bit:
1015
	loop	.loop
1016
 
1178 hidnplayr 1017
	DEBUGF	1,"%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
1159 hidnplayr 1018
 
1019
	ret
1020
 
1021
 
1022
;***************************************************************************
1023
;   Function
1024
;      eth_pio_read
1025
;
1026
;   Description
1027
;       Read a frame from the ethernet card via Programmed I/O
1492 hidnplayr 1028
;      src in si
1159 hidnplayr 1029
;      cnt in cx
1030
;       dst in edi
1031
;***************************************************************************
1032
eth_pio_read:
1033
 
1492 hidnplayr 1034
	DEBUGF	1,"Eth PIO Read from %x to %x, %u bytes ",si,edi,cx
1159 hidnplayr 1035
 
1036
	set_io	0
1037
	mov	al, CMD_RD2 + CMD_STA
1038
	out	dx, al
1039
 
1040
	mov	al, cl
1041
	set_io	P0_RBCR0
1042
	out	dx, al
1043
 
1044
	mov	al, ch
1045
	set_io	P0_RBCR1
1046
	out	dx, al
1047
 
1492 hidnplayr 1048
	mov	ax, si
1159 hidnplayr 1049
	set_io	P0_RSAR0
1050
	out	dx, al
1492 hidnplayr 1051
	shr	ax, 8
1159 hidnplayr 1052
	set_io	P0_RSAR1
1053
	out	dx, al
1054
 
1055
	mov	al, CMD_RD0 + CMD_STA
1056
	set_io	0
1057
	out	dx, al
1058
 
1492 hidnplayr 1059
	mov	dx, [device.asic_base]
1159 hidnplayr 1060
 
1492 hidnplayr 1061
	test	[device.flags], FLAG_16BIT
1159 hidnplayr 1062
	jz	epr_003
1063
 
1064
	DEBUGF	1,"in 16-bits mode"
1065
 
1066
	shr	cx, 1	; note that if the number was odd, carry flag will be set
1067
	pushf		; save the flags for later
1068
 
1069
epr_002:
1070
	in	ax, dx
1071
	stosw
1072
	loopw	epr_002
1073
 
1074
	inc	cx
1075
	popf
1076
	jnc	epr_004
1077
 
1078
epr_003:
1079
	in	al, dx
1080
	stosb
1081
	loopw	epr_003
1082
 
1083
 
1084
epr_004:
1085
	set_io	0
1086
	set_io	P0_ISR
1087
 
1088
epr_005:				; Wait for Remote DMA Complete
1089
	in	al, dx
1090
	test	al, ISR_RDC
1091
	jz	epr_005
1092
;        and     al, not ISR_RDC
1093
	out	dx, al			; clear the bit
1094
 
1095
 
1096
	DEBUGF	1,"\n"
1097
	ret
1098
 
1099
 
1100
 
1101
 
1102
;***************************************************************************
1103
;   Function
1104
;      eth_pio_write
1105
;
1106
;   Description
1107
;       writes a frame to the ethernet card via Programmed I/O
1492 hidnplayr 1108
;      dst in di
1159 hidnplayr 1109
;      cnt in cx
1110
;       src in esi
1111
;***************************************************************************
1112
eth_pio_write:
1113
 
1492 hidnplayr 1114
	DEBUGF	1,"Eth PIO Write from %x to %x, %u bytes ",esi,di,cx
1159 hidnplayr 1115
 
1116
	set_io	0
1117
	mov	al, CMD_RD2 + CMD_STA
1118
	out	dx, al
1119
 
1120
	set_io	P0_ISR
1121
	mov	al, ISR_RDC
1122
	out	dx, al
1123
 
1124
	set_io	P0_RBCR0
1125
	mov	al, cl
1126
	out	dx, al
1127
 
1128
	set_io	P0_RBCR1
1129
	mov	al, ch
1130
	out	dx, al
1131
 
1492 hidnplayr 1132
	mov	ax, di
1159 hidnplayr 1133
	set_io	P0_RSAR0
1134
	out	dx, al
1492 hidnplayr 1135
	shr	ax, 8
1159 hidnplayr 1136
	set_io	P0_RSAR1
1137
	out	dx, al
1138
 
1139
	set_io	0
1140
	mov	al, CMD_RD1 + CMD_STA
1141
	out	dx, al
1142
 
1492 hidnplayr 1143
	mov	dx, [device.asic_base]
1144
	test	[device.flags], FLAG_16BIT
1159 hidnplayr 1145
	jz	epw_003
1146
 
1147
	DEBUGF	1,"in 16-bits mode"
1148
 
1149
	shr	cx, 1	; note that if the number was odd, carry flag will be set
1150
	pushf		; save the flags for later
1151
 
1152
epw_002:
1153
	lodsw
1154
	out	dx, ax
1155
	loopw	epw_002
1156
 
1157
	popf
1158
	jnc	epw_004
1159
	inc	cx
1160
 
1161
epw_003:
1162
	lodsb
1163
	out	dx, al
1164
	loopw	epw_003
1165
 
1166
epw_004:
1167
	set_io	0
1168
	set_io	P0_ISR
1169
 
1170
epw_005:				; Wait for Remote DMA Complete
1171
	in	al, dx
1172
	test	al, ISR_RDC
1173
	jz	epw_005
1174
;        and     al, not ISR_RDC
1175
	out	dx, al			; clear the bit
1176
 
1177
 
1178
	DEBUGF	1,"\n"
1179
	ret
1180
 
1181
 
1182
 
1183
;all initialized data place here
1184
align 4
1185
 
1519 hidnplayr 1186
devices 	dd 0
1187
version 	dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1178 hidnplayr 1188
my_service	db 'RTL8029/ne2000',0  ;max 16 chars include zero
1159 hidnplayr 1189
 
1178 hidnplayr 1190
device_1	db 'Realtek 8029',0
1191
device_2	db 'Realtek 8019',0
1192
device_3	db 'Realtek 8019AS',0
1193
device_4	db 'ne2000',0
1194
device_5	db 'DP8390',0
1195
 
1159 hidnplayr 1196
test_data	db 'NE*000 memory',0
1197
 
1198
include_debug_strings
1199
 
1178 hidnplayr 1200
section '.data' data readable writable align 16  ;place all uninitialized data place here
1159 hidnplayr 1201
 
1519 hidnplayr 1202
device_list	rd MAX_DEVICES
1159 hidnplayr 1203