Subversion Repositories Kolibri OS

Rev

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

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