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
;;                                                                 ;;
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
 
344
	push	edx
345
	stdcall KernelAlloc, device.size
346
	pop	edx
347
	test	eax, eax
348
	jz	.fail
349
	mov	ebx, eax
350
 
1492 hidnplayr 351
	mov	[device.reset], reset
352
	mov	[device.transmit], transmit
353
	mov	[device.get_MAC], read_mac
354
	mov	[device.set_MAC], write_mac
355
	mov	[device.unload], unload
356
	mov	[device.name], my_service
1159 hidnplayr 357
 
358
	ret
359
 
360
.fail:
361
	add	esp, 4
362
	or	eax, -1
363
	ret
364
 
365
find_device_num:
366
 
367
	DEBUGF	1,"Trying to find device number of already registered device\n"
368
	mov	ebx, eax
1514 hidnplayr 369
	call	NetPtrToNum						; This kernel procedure converts a pointer to device struct in ebx
1159 hidnplayr 370
									; into a device number in edi
371
	mov	eax, edi						; Application wants it in eax instead
372
	DEBUGF	1,"Kernel says: %u\n", eax
373
	ret
374
 
375
 
376
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
377
;;                                                                        ;;
378
;;        Actual Hardware dependent code starts here                      ;;
379
;;                                                                        ;;
380
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
381
 
382
 
383
unload:   ; TODO
384
	or	eax, -1
385
	ret
386
 
387
 
388
 
389
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
390
;;
391
;;  probe: enables the device and clears the rx buffer
392
;;
393
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
394
 
395
probe:
1492 hidnplayr 396
	mov	[device.vendor], VENDOR_NONE
397
	mov	[device.bmem], 0
398
	mov	eax,[device.io_addr]
399
	add	eax, NE_ASIC_OFFSET
400
	mov	[device.asic_base], ax
1159 hidnplayr 401
 
402
	DEBUGF	2,"Trying 16-bit mode\n"
403
 
1492 hidnplayr 404
	or	[device.flags], FLAG_16BIT or FLAG_PIO
405
	mov	[device.memsize], MEM_32768
406
	mov	[device.tx_start], 64
407
	mov	[device.rx_start], TXBUF_SIZE + 64
1159 hidnplayr 408
 
409
	set_io	0
410
	set_io	P0_DCR
411
	mov	al, DCR_WTS + DCR_FT1 + DCR_LS
412
	out	dx, al
413
 
414
	set_io	P0_PSTART
415
	mov	al, MEM_16384
416
	out	dx, al
417
 
418
	set_io	P0_PSTOP
419
	mov	al, MEM_32768
420
	out	dx, al
421
 
422
	mov	esi, test_data
1492 hidnplayr 423
	mov	di, 16384
1159 hidnplayr 424
	mov	cx, 14
425
	call	eth_pio_write
426
 
1492 hidnplayr 427
	mov	si, 16384
1159 hidnplayr 428
	mov	cx, 14
1492 hidnplayr 429
	lea	edi, [device.romdata]
1159 hidnplayr 430
	call	eth_pio_read
431
 
1492 hidnplayr 432
	lea	esi, [device.romdata]
1159 hidnplayr 433
	mov	edi, test_data
434
	mov	ecx, 13
435
 
436
     repz    cmpsb
437
     jz      ep_set_vendor
438
 
439
 
440
	DEBUGF	2,"Trying 8-bit mode\n"
441
 
1492 hidnplayr 442
	mov	[device.flags], FLAG_PIO
443
	mov	[device.memsize], MEM_16384
444
	mov	[device.tx_start], 32
445
	mov	[device.rx_start], TXBUF_SIZE + 32
1159 hidnplayr 446
 
1492 hidnplayr 447
	mov	dx, [device.asic_base]
1159 hidnplayr 448
	add	dx, NE_RESET
449
 
450
	in	al, dx
451
	out	dx, al
452
 
453
	in	al, 0x84
454
 
455
	set_io	0
456
	mov	al, CMD_RD2 + CMD_STP
457
	out	dx, al
458
 
459
	set_io	P0_RCR
460
	mov	al, RCR_MON
461
	out	dx, al
462
 
463
	set_io	P0_DCR
464
	mov	al, DCR_FT1 + DCR_LS
465
	out	dx, al
466
 
467
	set_io	P0_PSTART
468
	mov	al, MEM_8192
469
	out	dx, al
470
 
471
	set_io	P0_PSTOP
472
	mov	al, MEM_16384
473
	out	dx, al
474
 
475
	mov	esi, test_data
1492 hidnplayr 476
	mov	di, 8192
1159 hidnplayr 477
	mov	cx, 14
478
	call	eth_pio_write
479
 
1492 hidnplayr 480
	mov	si, 8192
1159 hidnplayr 481
	mov	cx, 14
1492 hidnplayr 482
	lea	edi, [device.romdata]
1159 hidnplayr 483
	call	eth_pio_read
484
 
485
	mov	esi, test_data
1492 hidnplayr 486
	lea	edi, [device.romdata]
1159 hidnplayr 487
	mov	ecx, 13
488
 
489
    repz      cmpsb
490
    jz	      ep_set_vendor
491
 
492
	DEBUGF	2,"This is not a valid ne2000 device!\n"
493
	or	eax, -1
494
	ret
495
 
496
 
497
ep_set_vendor:
498
 
1492 hidnplayr 499
	cmp	[device.io_addr], ISA_MAX_ADDR
1159 hidnplayr 500
	jbe	ep_001
501
 
502
	DEBUGF	2,"Card is using PCI bus\n"
503
 
1492 hidnplayr 504
;        or      [flags], FLAG_16BIT
1159 hidnplayr 505
 
506
ep_001:
1492 hidnplayr 507
	mov	[device.vendor], VENDOR_NOVELL
1159 hidnplayr 508
 
509
ep_check_have_vendor:
510
 
511
 
1492 hidnplayr 512
	mov	al, [device.vendor]
1159 hidnplayr 513
	cmp	al, VENDOR_NONE
1492 hidnplayr 514
;        je      rtl8029_exit
1159 hidnplayr 515
 
516
	cmp	al, VENDOR_3COM
517
	je	reset
518
 
1492 hidnplayr 519
	mov	eax, [device.bmem]
520
	mov	[device.rmem], eax
1159 hidnplayr 521
 
522
	call	read_mac
523
 
524
	push	.hack
525
	sub	esp, 6
526
	mov	edi, esp
1492 hidnplayr 527
	lea	esi, [device.mac]
1159 hidnplayr 528
	movsd
529
	movsw
530
	jmp	write_mac
531
       .hack:
532
 
533
 
534
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
535
;;
536
;;   reset: Place the chip into a virgin state
537
;;
538
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
539
 
540
reset:
1178 hidnplayr 541
	DEBUGF	2,"Resetting device\n"
1159 hidnplayr 542
 
543
; attach int handler
1492 hidnplayr 544
	movzx	eax, [device.irq_line]
1159 hidnplayr 545
	DEBUGF	1,"Attaching int handler to irq %x\n",eax:1
546
	stdcall AttachIntHandler, eax, int_handler, dword 0
547
 
548
; Stop mode
549
 
550
	set_io	0
551
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STP
552
	out	dx, al
553
 
554
	set_io	P0_DCR
1492 hidnplayr 555
	test	[device.flags], FLAG_16BIT
1159 hidnplayr 556
	jz	nsr_001
557
 
558
	mov	al, 0x49
559
	jmp	nsr_002
560
 
561
nsr_001:
562
	mov	al, 0x48
563
 
564
nsr_002:
565
	out	dx, al
566
 
1519 hidnplayr 567
; clear remote bytes count
1159 hidnplayr 568
	set_io	0
569
 
570
	xor	al, al
571
 
572
	set_io	P0_RBCR0
573
	out	dx, al
574
 
575
	set_io	P0_RBCR1
576
	out	dx, al
577
 
578
 
1519 hidnplayr 579
; initialize Receive configuration register
1159 hidnplayr 580
	set_io	P0_RCR
581
	mov	al, 0x20	; monitor mode
582
	out	dx, al
583
 
584
 
585
; transmit configuration register
586
	set_io	P0_TCR
587
	mov	al, 2		; internal loopback
588
	out	dx, al
589
 
590
 
591
; transmit page stuff
592
	set_io	P0_TPSR
1492 hidnplayr 593
	mov	al, [device.tx_start]
1159 hidnplayr 594
	out	dx, al
595
 
596
; set receive control register ;;;;
597
	set_io	P0_RCR
598
	mov	al, 4		; accept broadcast
599
	out	dx, al
600
 
601
; pagestart
602
	set_io	P0_PSTART
1492 hidnplayr 603
	mov	al, [device.rx_start]
1159 hidnplayr 604
	out	dx, al
605
 
606
; pagestop
607
	set_io	P0_PSTOP
1492 hidnplayr 608
	mov	al, [device.memsize]
1159 hidnplayr 609
	out	dx, al
610
 
611
; page boundary
612
	set_io	P0_BOUND
1492 hidnplayr 613
	mov	al, [device.memsize]
1159 hidnplayr 614
	dec	al
615
	out	dx, al
616
 
617
 
618
;;clear IRQ mask
619
;        set_io  P0_IMR
620
;        xor     al, al
621
;        out     dx, al
622
 
623
	set_io	0
624
	mov	al, CMD_PS1 + CMD_RD2 + CMD_STP ; page 1, stop mode
625
	out	dx, al
626
 
627
	set_io	P1_CURR
1492 hidnplayr 628
	mov	al, [device.rx_start]
1159 hidnplayr 629
	out	dx, al
630
 
631
	set_io	0
632
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STA ; go to page 0
633
	out	dx, al
634
 
635
; Read MAC address
636
	call	read_mac
637
 
638
; clear interupt status
1173 clevermous 639
	set_io	0
1159 hidnplayr 640
	set_io	P0_ISR
641
	mov	al, 0xff
642
	out	dx, al
643
 
644
; set IRQ mask
645
	set_io	P0_IMR
646
	mov	al, IRQ_MASK
647
	out	dx, al
648
 
649
;; start mode
650
;        set_io  0
651
;        mov     al, CMD_STA
652
;        out     dx, al
653
 
654
; clear transmit control register
655
	set_io	P0_TCR
656
	mov	al, 0		; no loopback
657
	out	dx, al
658
 
1178 hidnplayr 659
; clear packet/byte counters
1492 hidnplayr 660
	xor	eax, eax
661
	lea	edi, [device.bytes_tx]
1178 hidnplayr 662
	mov	ecx, 6
663
	rep	stosd
664
 
1519 hidnplayr 665
; Set the mtu, kernel will be able to send now
666
	mov	[device.mtu], 1514
667
 
1159 hidnplayr 668
; Indicate that we have successfully reset the card
669
	DEBUGF	2,"Done!\n"
670
 
671
	ret
672
 
673
 
674
 
675
;***************************************************************************
676
;   Function
677
;      transmit
1254 hidnplayr 678
; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx
1159 hidnplayr 679
;***************************************************************************
680
 
1492 hidnplayr 681
; TODO: use a RING-buffer
682
 
1159 hidnplayr 683
align 4
684
transmit:
685
 
1254 hidnplayr 686
	mov	esi, [esp + 4]
687
	mov	ecx, [esp + 8]
1159 hidnplayr 688
	DEBUGF	2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx
689
	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
690
 
1492 hidnplayr 691
	cmp	ecx, ETH_FRAME_LEN
692
	jg	.err ; packet is too long
693
	cmp	ecx, 60
694
	jl	.err ; packet is too short
1159 hidnplayr 695
 
1492 hidnplayr 696
	movzx	edi, [device.tx_start]
697
	shl	edi, 8
1159 hidnplayr 698
	push	cx
699
	call	eth_pio_write
700
	pop	cx
701
 
702
	set_io	0
703
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STA
704
	out	dx, al
705
 
706
	set_io	P0_TPSR
1492 hidnplayr 707
	mov	al, [device.tx_start]
1159 hidnplayr 708
	out	dx, al
709
 
710
	set_io	P0_TBCR0
711
	mov	al, cl
712
	out	dx, al
713
 
714
	set_io	P0_TBCR1
715
	mov	al, ch
716
	out	dx, al
717
 
718
	set_io	0
719
	mov	al, CMD_PS0 + CMD_TXP + CMD_RD2 + CMD_STA
720
	out	dx, al
721
 
722
	DEBUGF	2," - Packet Sent!\n"
1178 hidnplayr 723
 
1492 hidnplayr 724
	inc	[device.packets_tx]
1254 hidnplayr 725
	mov	eax, [esp + 8]			 ; Get packet size in eax
1178 hidnplayr 726
 
1492 hidnplayr 727
	add	dword [device.bytes_tx], eax
728
	adc	dword [device.bytes_tx + 4], 0
729
 
1159 hidnplayr 730
.finish:
1519 hidnplayr 731
	call	Kernelfree
732
	add	esp, 4
1159 hidnplayr 733
	xor	eax, eax
1492 hidnplayr 734
	ret
1159 hidnplayr 735
 
1492 hidnplayr 736
.err:
1519 hidnplayr 737
	call	Kernelfree
738
	add	esp, 4
1492 hidnplayr 739
	or	eax, -1
1159 hidnplayr 740
	ret
741
 
742
 
743
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
744
;
745
; Interrupt handler
746
;
747
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
748
align 4
749
int_handler:
750
 
751
	DEBUGF	2,"IRQ %x ",eax:2
752
 
753
; find pointer of device wich made INT occur
1519 hidnplayr 754
	mov	esi, device_list
755
	mov	ecx, [devices]
1159 hidnplayr 756
.nextdevice:
1492 hidnplayr 757
	mov	ebx, [esi]
1159 hidnplayr 758
 
1178 hidnplayr 759
	set_io	0
1159 hidnplayr 760
	set_io	P0_ISR
761
	in	al, dx
762
 
763
	DEBUGF	2,"isr %x ",eax:2
764
 
1178 hidnplayr 765
	test	al, ISR_PRX    ; packet received ok ?
1159 hidnplayr 766
	jnz	.rx
767
 
768
	add	esi, 4
769
 
770
	loop	.nextdevice
771
	ret
772
 
1178 hidnplayr 773
 
774
 
775
; looks like we've found a device wich received a packet..
1159 hidnplayr 776
.rx:
1178 hidnplayr 777
	stdcall KernelAlloc, ETH_FRAME_LEN  ; size doesnt really matter as packet size is smaller then kernel's page size
778
	test	eax, eax
779
	jz	.fail_2
1159 hidnplayr 780
 
1178 hidnplayr 781
;--------------------------------------
782
; allocate memory for temp variables in stack
1159 hidnplayr 783
 
1178 hidnplayr 784
	sub	esp, 14+8
1159 hidnplayr 785
 
786
	eth_type	equ esp
787
	pkthdr		equ esp + 2
788
	pktoff		equ esp + 6
789
	eth_rx_data_ptr equ esp + 8
790
	eth_tmp_len	equ esp + 12
791
 
1178 hidnplayr 792
; These will be used by eth_receiver when the packet gets there
793
 
1159 hidnplayr 794
	pointer 	equ esp + 14
795
	size		equ esp + 18
796
 
1178 hidnplayr 797
;-------------------------------------
798
 
1159 hidnplayr 799
	mov	[pointer], eax
800
	mov	[eth_rx_data_ptr], eax
801
 
802
	set_io	P0_BOUND
803
	in	al, dx
804
	inc	al
805
 
1492 hidnplayr 806
	cmp	al, [device.memsize]
1159 hidnplayr 807
	jb	.nsp_001
808
 
1492 hidnplayr 809
	mov	al, [device.rx_start]
1159 hidnplayr 810
 
811
.nsp_001:
812
	mov	ch, al
813
 
814
	set_io	0
815
	mov	al, CMD_PS1
816
	out	dx, al
817
 
818
	set_io	P1_CURR
819
	in	al, dx		     ; get current page
820
	mov	cl, al
821
 
822
	set_io	0
823
	mov	al, CMD_PS0
824
	out	dx, al
825
 
1492 hidnplayr 826
	cmp	cl, [device.memsize]
1159 hidnplayr 827
	jb	.nsp_002
828
 
1492 hidnplayr 829
	mov	cl, [device.rx_start]
1159 hidnplayr 830
 
831
.nsp_002:
832
	cmp	cl, ch
833
	je	.fail
834
 
835
	xor	ax, ax
836
	mov	ah, ch
837
 
838
	mov	[pktoff], ax
839
 
1492 hidnplayr 840
	mov	al, [device.flags]
1159 hidnplayr 841
	test	al, FLAG_PIO
842
	jz	.nsp_003
843
 
1492 hidnplayr 844
	mov	si, word [pktoff]
1159 hidnplayr 845
	lea	edi, [pkthdr]
846
	mov	cx, 4
847
	call	eth_pio_read
848
	jmp	.nsp_004
849
 
850
.nsp_003:
1492 hidnplayr 851
	mov	edi, [device.rmem]
1159 hidnplayr 852
	movzx	eax, word [pktoff]
853
	add	edi, eax
854
	mov	eax, [edi]
855
	mov	[pkthdr], eax
856
 
857
.nsp_004:
858
	add	word[pktoff] , 4
859
 
860
	xor	eax, eax
1178 hidnplayr 861
	mov	ax , [pkthdr + 2]
862
	sub	ax , 4
1159 hidnplayr 863
 
864
	DEBUGF	2,"Received %u bytes\n",eax
865
 
1492 hidnplayr 866
	add	dword [device.bytes_rx], eax  ; Update stats
867
	adc	dword [device.bytes_rx + 4], 0
868
	inc	dword [device.packets_rx]     ;
1178 hidnplayr 869
 
1159 hidnplayr 870
	mov	[eth_tmp_len], ax
871
	mov	dword[size], eax
872
 
873
	cmp	ax, ETH_ZLEN
874
	jb	.fail
875
 
1178 hidnplayr 876
	cmp	ax , ETH_FRAME_LEN
1159 hidnplayr 877
	ja	.fail
878
 
1178 hidnplayr 879
	mov	al , [pkthdr]
880
	test	al , RSTAT_PRX
1159 hidnplayr 881
	jz	.fail
882
 
883
   ; Right, we can now get the data
884
 
1492 hidnplayr 885
	movzx	esi, [device.memsize]
886
	sub	si , [pktoff]
1159 hidnplayr 887
 
1492 hidnplayr 888
	cmp	[eth_tmp_len], si
1159 hidnplayr 889
	jbe	.nsp_005
890
 
1187 hidnplayr 891
	DEBUGF	2,"WRAP!\n"
1178 hidnplayr 892
 
1492 hidnplayr 893
	mov	al , [device.flags]
1178 hidnplayr 894
	test	al , FLAG_PIO
1159 hidnplayr 895
	jz	.nsp_006
896
 
1492 hidnplayr 897
	push	esi
898
	mov	cx , si
899
	mov	si , [pktoff+4]
1178 hidnplayr 900
	mov	edi, [eth_rx_data_ptr+4]
1159 hidnplayr 901
	call	eth_pio_read
1492 hidnplayr 902
	pop	esi
1159 hidnplayr 903
	jmp	.nsp_007
904
 
905
.nsp_006:
1178 hidnplayr 906
	DEBUGF	2,"PIO mode not supported by HW!\n"
1159 hidnplayr 907
   ; Not implemented, as we are using PIO mode on this card
908
 
909
.nsp_007:
910
	xor	al, al
1492 hidnplayr 911
	mov	ah, [device.rx_start]
1159 hidnplayr 912
	mov	[pktoff], ax
913
 
1492 hidnplayr 914
	add	[eth_rx_data_ptr], esi
915
	sub	[eth_tmp_len], si
1159 hidnplayr 916
 
917
.nsp_005:
1492 hidnplayr 918
	test	[device.flags], FLAG_PIO
1159 hidnplayr 919
	jz	.nsp_008
920
 
1492 hidnplayr 921
	movzx	esi, word [pktoff]
922
	movzx	ecx, word [eth_tmp_len]
1159 hidnplayr 923
	mov	edi, [eth_rx_data_ptr]
924
	call	eth_pio_read
925
	jmp	.nsp_009
926
 
927
.nsp_008:
1178 hidnplayr 928
	DEBUGF	2,"PIO mode not supported by HW!\n"
1159 hidnplayr 929
   ; Not implemented, as we are using PIO mode on this card
930
 
931
.nsp_009:
932
	mov	al, [pkthdr+1]
1492 hidnplayr 933
	cmp	al, [device.rx_start]
1159 hidnplayr 934
	jne	.nsp_010
935
 
1492 hidnplayr 936
	mov	al, [device.memsize]
1159 hidnplayr 937
 
938
.nsp_010:
939
	set_io	0
940
	set_io	P0_BOUND
941
	dec	al
942
	out	dx, al
943
 
944
	add	esp, 14
1178 hidnplayr 945
	jmp	EthReceiver	; send it to the kernel
1159 hidnplayr 946
 
947
.fail:
948
	add	esp, 14+8
1178 hidnplayr 949
.fail_2:
1159 hidnplayr 950
	DEBUGF	2,"done\n"
951
ret
952
 
953
 
954
 
955
 
956
 
957
;;;;;;;;;;;;;;;;;;;;;;;
958
;;                   ;;
959
;; Write MAC address ;;
960
;;                   ;;
961
;;;;;;;;;;;;;;;;;;;;;;;
962
 
963
align 4
1178 hidnplayr 964
write_mac:	; in: mac on stack (6 bytes)
1159 hidnplayr 965
 
966
	DEBUGF	1,"Writing MAC: "
967
 
968
	set_io	0
969
	mov	al, CMD_PS1; + CMD_RD2 + CMD_STP
970
	out	dx, al
971
 
972
	set_io	P1_PAR0
973
	mov	esi, esp
974
	mov	cx, 6
975
 @@:
976
	lodsb
977
	out	dx, al
978
	inc	dx
979
	loopw	@r
980
 
981
	add	esp, 6
982
 
983
; Notice this procedure does not ret, but continues to read_mac instead.
984
 
985
;;;;;;;;;;;;;;;;;;;;;;
986
;;                  ;;
987
;; Read MAC address ;;
988
;;                  ;;
989
;;;;;;;;;;;;;;;;;;;;;;
990
 
991
read_mac:
992
 
993
	DEBUGF	1,"Reading MAC: "
994
 
995
;        set_io  0
996
;        mov     al, CMD_PS1; + CMD_RD2 + CMD_STP ; select page 1
997
;        out     dx, al
998
;
999
;        set_io  P1_PAR0
1492 hidnplayr 1000
;        lea     edi, [mac]
1159 hidnplayr 1001
;
1002
;        mov     cx, 6
1003
; .loop:
1004
;        in      al, dx
1005
;        stosb
1006
;        inc     dx
1007
;        loopw   .loop
1008
;
1009
;        set_io  0
1010
;        mov     al, CMD_PS0; + CMD_RD2 + CMD_STA  ; set page back to 0
1011
;        out     dx, al
1012
 
1492 hidnplayr 1013
	mov	si, 0
1159 hidnplayr 1014
	mov	cx, 16
1492 hidnplayr 1015
	lea	edi, [device.romdata]
1159 hidnplayr 1016
	call	eth_pio_read
1017
 
1492 hidnplayr 1018
	lea	esi, [device.romdata]
1019
	lea	edi, [device.mac]
1159 hidnplayr 1020
	mov	ecx, 6
1021
 
1022
  .loop:
1023
	movsb
1492 hidnplayr 1024
	test	[device.flags], FLAG_16BIT
1159 hidnplayr 1025
	jz	.8bit
1026
	inc	esi
1027
  .8bit:
1028
	loop	.loop
1029
 
1178 hidnplayr 1030
	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 1031
 
1032
	ret
1033
 
1034
 
1035
;***************************************************************************
1036
;   Function
1037
;      eth_pio_read
1038
;
1039
;   Description
1040
;       Read a frame from the ethernet card via Programmed I/O
1492 hidnplayr 1041
;      src in si
1159 hidnplayr 1042
;      cnt in cx
1043
;       dst in edi
1044
;***************************************************************************
1045
eth_pio_read:
1046
 
1492 hidnplayr 1047
	DEBUGF	1,"Eth PIO Read from %x to %x, %u bytes ",si,edi,cx
1159 hidnplayr 1048
 
1049
	set_io	0
1050
	mov	al, CMD_RD2 + CMD_STA
1051
	out	dx, al
1052
 
1053
	mov	al, cl
1054
	set_io	P0_RBCR0
1055
	out	dx, al
1056
 
1057
	mov	al, ch
1058
	set_io	P0_RBCR1
1059
	out	dx, al
1060
 
1492 hidnplayr 1061
	mov	ax, si
1159 hidnplayr 1062
	set_io	P0_RSAR0
1063
	out	dx, al
1492 hidnplayr 1064
	shr	ax, 8
1159 hidnplayr 1065
	set_io	P0_RSAR1
1066
	out	dx, al
1067
 
1068
	mov	al, CMD_RD0 + CMD_STA
1069
	set_io	0
1070
	out	dx, al
1071
 
1492 hidnplayr 1072
	mov	dx, [device.asic_base]
1159 hidnplayr 1073
 
1492 hidnplayr 1074
	test	[device.flags], FLAG_16BIT
1159 hidnplayr 1075
	jz	epr_003
1076
 
1077
	DEBUGF	1,"in 16-bits mode"
1078
 
1079
	shr	cx, 1	; note that if the number was odd, carry flag will be set
1080
	pushf		; save the flags for later
1081
 
1082
epr_002:
1083
	in	ax, dx
1084
	stosw
1085
	loopw	epr_002
1086
 
1087
	inc	cx
1088
	popf
1089
	jnc	epr_004
1090
 
1091
epr_003:
1092
	in	al, dx
1093
	stosb
1094
	loopw	epr_003
1095
 
1096
 
1097
epr_004:
1098
	set_io	0
1099
	set_io	P0_ISR
1100
 
1101
epr_005:				; Wait for Remote DMA Complete
1102
	in	al, dx
1103
	test	al, ISR_RDC
1104
	jz	epr_005
1105
;        and     al, not ISR_RDC
1106
	out	dx, al			; clear the bit
1107
 
1108
 
1109
	DEBUGF	1,"\n"
1110
	ret
1111
 
1112
 
1113
 
1114
 
1115
;***************************************************************************
1116
;   Function
1117
;      eth_pio_write
1118
;
1119
;   Description
1120
;       writes a frame to the ethernet card via Programmed I/O
1492 hidnplayr 1121
;      dst in di
1159 hidnplayr 1122
;      cnt in cx
1123
;       src in esi
1124
;***************************************************************************
1125
eth_pio_write:
1126
 
1492 hidnplayr 1127
	DEBUGF	1,"Eth PIO Write from %x to %x, %u bytes ",esi,di,cx
1159 hidnplayr 1128
 
1129
	set_io	0
1130
	mov	al, CMD_RD2 + CMD_STA
1131
	out	dx, al
1132
 
1133
	set_io	P0_ISR
1134
	mov	al, ISR_RDC
1135
	out	dx, al
1136
 
1137
	set_io	P0_RBCR0
1138
	mov	al, cl
1139
	out	dx, al
1140
 
1141
	set_io	P0_RBCR1
1142
	mov	al, ch
1143
	out	dx, al
1144
 
1492 hidnplayr 1145
	mov	ax, di
1159 hidnplayr 1146
	set_io	P0_RSAR0
1147
	out	dx, al
1492 hidnplayr 1148
	shr	ax, 8
1159 hidnplayr 1149
	set_io	P0_RSAR1
1150
	out	dx, al
1151
 
1152
	set_io	0
1153
	mov	al, CMD_RD1 + CMD_STA
1154
	out	dx, al
1155
 
1492 hidnplayr 1156
	mov	dx, [device.asic_base]
1157
	test	[device.flags], FLAG_16BIT
1159 hidnplayr 1158
	jz	epw_003
1159
 
1160
	DEBUGF	1,"in 16-bits mode"
1161
 
1162
	shr	cx, 1	; note that if the number was odd, carry flag will be set
1163
	pushf		; save the flags for later
1164
 
1165
epw_002:
1166
	lodsw
1167
	out	dx, ax
1168
	loopw	epw_002
1169
 
1170
	popf
1171
	jnc	epw_004
1172
	inc	cx
1173
 
1174
epw_003:
1175
	lodsb
1176
	out	dx, al
1177
	loopw	epw_003
1178
 
1179
epw_004:
1180
	set_io	0
1181
	set_io	P0_ISR
1182
 
1183
epw_005:				; Wait for Remote DMA Complete
1184
	in	al, dx
1185
	test	al, ISR_RDC
1186
	jz	epw_005
1187
;        and     al, not ISR_RDC
1188
	out	dx, al			; clear the bit
1189
 
1190
 
1191
	DEBUGF	1,"\n"
1192
	ret
1193
 
1194
 
1195
 
1196
;all initialized data place here
1197
align 4
1198
 
1519 hidnplayr 1199
devices 	dd 0
1200
version 	dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1178 hidnplayr 1201
my_service	db 'RTL8029/ne2000',0  ;max 16 chars include zero
1159 hidnplayr 1202
 
1178 hidnplayr 1203
device_1	db 'Realtek 8029',0
1204
device_2	db 'Realtek 8019',0
1205
device_3	db 'Realtek 8019AS',0
1206
device_4	db 'ne2000',0
1207
device_5	db 'DP8390',0
1208
 
1159 hidnplayr 1209
test_data	db 'NE*000 memory',0
1210
 
1211
include_debug_strings
1212
 
1178 hidnplayr 1213
section '.data' data readable writable align 16  ;place all uninitialized data place here
1159 hidnplayr 1214
 
1519 hidnplayr 1215
device_list	rd MAX_DEVICES
1159 hidnplayr 1216