Subversion Repositories Kolibri OS

Rev

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