Subversion Repositories Kolibri OS

Rev

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