Subversion Repositories Kolibri OS

Rev

Rev 1187 | 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: 1206 $
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
761
; buffer in [esp], size in [esp+4], pointer to device struct in ebx
762
;***************************************************************************
763
 
764
align 4
765
transmit:
766
	mov	ebp, ebx
767
 
768
	mov	esi, [esp]
769
	mov	ecx, [esp + 4]
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
 
773
	cmp	dword [esp+4], ETH_FRAME_LEN
774
	jg	.finish ; packet is too long
775
	cmp	dword [esp+4], 60
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] 	 ;
807
	mov	eax, [esp+4]			 ; Get packet size in eax
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
 
814
	call	KernelFree
815
	add	esp, 4 ; pop (balance stack)
816
	xor	eax, eax
817
 
818
	ret
819
 
820
 
821
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
822
;
823
; Interrupt handler
824
;
825
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
826
align 4
827
int_handler:
828
 
829
	DEBUGF	2,"IRQ %x ",eax:2
830
 
831
; find pointer of device wich made INT occur
832
	mov	esi, ne2000_LIST
833
	mov	ecx, [ne2000_DEV]
834
.nextdevice:
835
	mov	ebp, dword [esi]
836
 
1178 hidnplayr 837
	set_io	0
1159 hidnplayr 838
	set_io	P0_ISR
839
	in	al, dx
840
 
841
	DEBUGF	2,"isr %x ",eax:2
842
 
1178 hidnplayr 843
	test	al, ISR_PRX    ; packet received ok ?
1159 hidnplayr 844
	jnz	.rx
845
 
846
	add	esi, 4
847
 
848
	loop	.nextdevice
849
	ret
850
 
1178 hidnplayr 851
 
852
 
853
; looks like we've found a device wich received a packet..
1159 hidnplayr 854
.rx:
1178 hidnplayr 855
	stdcall KernelAlloc, ETH_FRAME_LEN  ; size doesnt really matter as packet size is smaller then kernel's page size
856
	test	eax, eax
857
	jz	.fail_2
1159 hidnplayr 858
 
1178 hidnplayr 859
;--------------------------------------
860
; allocate memory for temp variables in stack
1159 hidnplayr 861
 
1178 hidnplayr 862
	sub	esp, 14+8
1159 hidnplayr 863
 
864
	eth_type	equ esp
865
	pkthdr		equ esp + 2
866
	pktoff		equ esp + 6
867
	eth_rx_data_ptr equ esp + 8
868
	eth_tmp_len	equ esp + 12
869
 
1178 hidnplayr 870
; These will be used by eth_receiver when the packet gets there
871
 
1159 hidnplayr 872
	pointer 	equ esp + 14
873
	size		equ esp + 18
874
 
1178 hidnplayr 875
;-------------------------------------
876
 
1159 hidnplayr 877
	mov	[pointer], eax
878
	mov	[eth_rx_data_ptr], eax
879
 
880
	set_io	P0_BOUND
881
	in	al, dx
882
	inc	al
883
 
884
	cmp	al, [ebp + device.memsize]
885
	jb	.nsp_001
886
 
887
	mov	al, [ebp + device.rx_start]
888
 
889
.nsp_001:
890
	mov	ch, al
891
 
892
	set_io	0
893
	mov	al, CMD_PS1
894
	out	dx, al
895
 
896
	set_io	P1_CURR
897
	in	al, dx		     ; get current page
898
	mov	cl, al
899
 
900
	set_io	0
901
	mov	al, CMD_PS0
902
	out	dx, al
903
 
904
	cmp	cl, [ebp + device.memsize]
905
	jb	.nsp_002
906
 
907
	mov	cl, [ebp + device.rx_start]
908
 
909
.nsp_002:
910
	cmp	cl, ch
911
	je	.fail
912
 
913
	xor	ax, ax
914
	mov	ah, ch
915
 
916
	mov	[pktoff], ax
917
 
918
	mov	al, [ebp + device.flags]
919
	test	al, FLAG_PIO
920
	jz	.nsp_003
921
 
922
	mov	bx, word [pktoff]
923
	lea	edi, [pkthdr]
924
	mov	cx, 4
925
	call	eth_pio_read
926
	jmp	.nsp_004
927
 
928
.nsp_003:
929
	mov	edi, [ebp + device.rmem]
930
	movzx	eax, word [pktoff]
931
	add	edi, eax
932
	mov	eax, [edi]
933
	mov	[pkthdr], eax
934
 
935
.nsp_004:
936
	add	word[pktoff] , 4
937
 
938
	xor	eax, eax
1178 hidnplayr 939
	mov	ax , [pkthdr + 2]
940
	sub	ax , 4
1159 hidnplayr 941
 
942
	DEBUGF	2,"Received %u bytes\n",eax
943
 
1178 hidnplayr 944
	add	dword [ebp + device.bytes_rx], eax  ; Update stats
945
	adc	dword [ebp + device.bytes_rx + 4], 0
946
	inc	dword [ebp + device.packets_rx]     ;
947
 
1159 hidnplayr 948
	mov	[eth_tmp_len], ax
949
	mov	dword[size], eax
950
 
951
	cmp	ax, ETH_ZLEN
952
	jb	.fail
953
 
1178 hidnplayr 954
	cmp	ax , ETH_FRAME_LEN
1159 hidnplayr 955
	ja	.fail
956
 
1178 hidnplayr 957
	mov	al , [pkthdr]
958
	test	al , RSTAT_PRX
1159 hidnplayr 959
	jz	.fail
960
 
961
   ; Right, we can now get the data
962
 
1178 hidnplayr 963
	xor	ebx, ebx
964
	mov	bh , [ebp + device.memsize]
965
	sub	bx , [pktoff]
1159 hidnplayr 966
 
967
	cmp	[eth_tmp_len], bx
968
	jbe	.nsp_005
969
 
1187 hidnplayr 970
	DEBUGF	2,"WRAP!\n"
1178 hidnplayr 971
 
972
	mov	al , [ebp + device.flags]
973
	test	al , FLAG_PIO
1159 hidnplayr 974
	jz	.nsp_006
975
 
1178 hidnplayr 976
	push	ebx
977
	mov	cx , bx
978
	mov	bx , [pktoff+4]
979
	mov	edi, [eth_rx_data_ptr+4]
1159 hidnplayr 980
	call	eth_pio_read
1178 hidnplayr 981
	pop	ebx
1159 hidnplayr 982
	jmp	.nsp_007
983
 
984
.nsp_006:
1178 hidnplayr 985
	DEBUGF	2,"PIO mode not supported by HW!\n"
1159 hidnplayr 986
   ; Not implemented, as we are using PIO mode on this card
987
 
988
.nsp_007:
989
	xor	al, al
990
	mov	ah, [ebp + device.rx_start]
991
	mov	[pktoff], ax
992
 
993
	add	[eth_rx_data_ptr], ebx
1187 hidnplayr 994
	sub	[eth_tmp_len], bx
1159 hidnplayr 995
 
996
.nsp_005:
997
	test	[ebp + device.flags], FLAG_PIO
998
	jz	.nsp_008
999
 
1000
	xor	ebx, ebx
1001
	mov	bx, [pktoff]
1002
	xor	ecx, ecx
1003
	mov	cx, [eth_tmp_len]
1004
	mov	edi, [eth_rx_data_ptr]
1005
	call	eth_pio_read
1006
	jmp	.nsp_009
1007
 
1008
.nsp_008:
1178 hidnplayr 1009
	DEBUGF	2,"PIO mode not supported by HW!\n"
1159 hidnplayr 1010
   ; Not implemented, as we are using PIO mode on this card
1011
 
1012
.nsp_009:
1013
	mov	al, [pkthdr+1]
1014
	cmp	al, [ebp + device.rx_start]
1015
	jne	.nsp_010
1016
 
1017
	mov	al, [ebp + device.memsize]
1018
 
1019
.nsp_010:
1020
	set_io	0
1021
	set_io	P0_BOUND
1022
	dec	al
1023
	out	dx, al
1024
 
1178 hidnplayr 1025
	mov	ebx, ebp
1159 hidnplayr 1026
	add	esp, 14
1027
 
1028
	mov	ebx, ebp
1178 hidnplayr 1029
	jmp	EthReceiver	; send it to the kernel
1159 hidnplayr 1030
 
1031
.fail:
1032
	add	esp, 14+8
1178 hidnplayr 1033
.fail_2:
1159 hidnplayr 1034
	DEBUGF	2,"done\n"
1035
ret
1036
 
1037
 
1038
 
1039
 
1040
 
1041
;;;;;;;;;;;;;;;;;;;;;;;
1042
;;                   ;;
1043
;; Write MAC address ;;
1044
;;                   ;;
1045
;;;;;;;;;;;;;;;;;;;;;;;
1046
 
1047
align 4
1178 hidnplayr 1048
write_mac:	; in: mac on stack (6 bytes)
1159 hidnplayr 1049
 
1050
	mov	ebp, ebx	;---
1051
 
1052
	DEBUGF	1,"Writing MAC: "
1053
 
1054
	set_io	0
1055
	mov	al, CMD_PS1; + CMD_RD2 + CMD_STP
1056
	out	dx, al
1057
 
1058
	set_io	P1_PAR0
1059
	mov	esi, esp
1060
	mov	cx, 6
1061
 @@:
1062
	lodsb
1063
	out	dx, al
1064
	inc	dx
1065
	loopw	@r
1066
 
1067
	add	esp, 6
1068
 
1069
	mov	ebx, ebp	;---
1070
 
1071
; Notice this procedure does not ret, but continues to read_mac instead.
1072
 
1073
;;;;;;;;;;;;;;;;;;;;;;
1074
;;                  ;;
1075
;; Read MAC address ;;
1076
;;                  ;;
1077
;;;;;;;;;;;;;;;;;;;;;;
1078
 
1079
read_mac:
1080
 
1081
	mov	ebp, ebx	;-----
1082
 
1083
	DEBUGF	1,"Reading MAC: "
1084
 
1085
;        set_io  0
1086
;        mov     al, CMD_PS1; + CMD_RD2 + CMD_STP ; select page 1
1087
;        out     dx, al
1088
;
1089
;        set_io  P1_PAR0
1090
;        lea     edi, [ebp + device.mac]
1091
;
1092
;        mov     cx, 6
1093
; .loop:
1094
;        in      al, dx
1095
;        stosb
1096
;        inc     dx
1097
;        loopw   .loop
1098
;
1099
;        set_io  0
1100
;        mov     al, CMD_PS0; + CMD_RD2 + CMD_STA  ; set page back to 0
1101
;        out     dx, al
1102
 
1103
 
1104
	mov	bx, 0
1105
	mov	cx, 16
1106
	lea	edi, [ebp + device.romdata]
1107
	call	eth_pio_read
1108
 
1109
	lea	esi, [ebp + device.romdata]
1110
	lea	edi, [ebp + device.mac]
1111
	mov	ecx, 6
1112
 
1113
  .loop:
1114
	movsb
1115
	test	[ebp + device.flags], FLAG_16BIT
1116
	jz	.8bit
1117
	inc	esi
1118
  .8bit:
1119
	loop	.loop
1120
 
1178 hidnplayr 1121
	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 1122
 
1123
	mov	ebx, ebp	;---
1124
 
1125
	ret
1126
 
1127
 
1128
;***************************************************************************
1129
;   Function
1130
;      eth_pio_read
1131
;
1132
;   Description
1133
;       Read a frame from the ethernet card via Programmed I/O
1134
;      src in bx
1135
;      cnt in cx
1136
;       dst in edi
1137
;***************************************************************************
1138
eth_pio_read:
1139
 
1140
	DEBUGF	1,"Eth PIO Read from %x to %x, %u bytes ",bx,edi,cx
1141
 
1142
	set_io	0
1143
	mov	al, CMD_RD2 + CMD_STA
1144
	out	dx, al
1145
 
1146
	mov	al, cl
1147
	set_io	P0_RBCR0
1148
	out	dx, al
1149
 
1150
	mov	al, ch
1151
	set_io	P0_RBCR1
1152
	out	dx, al
1153
 
1154
	mov	al, bl
1155
	set_io	P0_RSAR0
1156
	out	dx, al
1157
 
1158
	mov	al, bh
1159
	set_io	P0_RSAR1
1160
	out	dx, al
1161
 
1162
	mov	al, CMD_RD0 + CMD_STA
1163
	set_io	0
1164
	out	dx, al
1165
 
1166
	mov	dx, [ebp + device.asic_base]
1167
 
1168
	test	[ebp+device.flags], FLAG_16BIT
1169
	jz	epr_003
1170
 
1171
	DEBUGF	1,"in 16-bits mode"
1172
 
1173
	shr	cx, 1	; note that if the number was odd, carry flag will be set
1174
	pushf		; save the flags for later
1175
 
1176
epr_002:
1177
	in	ax, dx
1178
	stosw
1179
	loopw	epr_002
1180
 
1181
	inc	cx
1182
	popf
1183
	jnc	epr_004
1184
 
1185
epr_003:
1186
	in	al, dx
1187
	stosb
1188
	loopw	epr_003
1189
 
1190
 
1191
epr_004:
1192
	set_io	0
1193
	set_io	P0_ISR
1194
 
1195
epr_005:				; Wait for Remote DMA Complete
1196
	in	al, dx
1197
	test	al, ISR_RDC
1198
	jz	epr_005
1199
;        and     al, not ISR_RDC
1200
	out	dx, al			; clear the bit
1201
 
1202
 
1203
	DEBUGF	1,"\n"
1204
	ret
1205
 
1206
 
1207
 
1208
 
1209
;***************************************************************************
1210
;   Function
1211
;      eth_pio_write
1212
;
1213
;   Description
1214
;       writes a frame to the ethernet card via Programmed I/O
1215
;      dst in bx
1216
;      cnt in cx
1217
;       src in esi
1218
;***************************************************************************
1219
eth_pio_write:
1220
 
1221
	DEBUGF	1,"Eth PIO Write from %x to %x, %u bytes ",esi,bx,cx
1222
 
1223
	set_io	0
1224
	mov	al, CMD_RD2 + CMD_STA
1225
	out	dx, al
1226
 
1227
	set_io	P0_ISR
1228
	mov	al, ISR_RDC
1229
	out	dx, al
1230
 
1231
	set_io	P0_RBCR0
1232
	mov	al, cl
1233
	out	dx, al
1234
 
1235
	set_io	P0_RBCR1
1236
	mov	al, ch
1237
	out	dx, al
1238
 
1239
	set_io	P0_RSAR0
1240
	mov	al,   bl
1241
	out	dx, al
1242
 
1243
	set_io	P0_RSAR1
1244
	mov	al,   bh
1245
	out	dx, al
1246
 
1247
	set_io	0
1248
	mov	al, CMD_RD1 + CMD_STA
1249
	out	dx, al
1250
 
1251
	mov	dx, [ebp + device.asic_base]
1252
	test	[ebp + device.flags], FLAG_16BIT
1253
	jz	epw_003
1254
 
1255
	DEBUGF	1,"in 16-bits mode"
1256
 
1257
	shr	cx, 1	; note that if the number was odd, carry flag will be set
1258
	pushf		; save the flags for later
1259
 
1260
epw_002:
1261
	lodsw
1262
	out	dx, ax
1263
	loopw	epw_002
1264
 
1265
	popf
1266
	jnc	epw_004
1267
	inc	cx
1268
 
1269
epw_003:
1270
	lodsb
1271
	out	dx, al
1272
	loopw	epw_003
1273
 
1274
epw_004:
1275
	set_io	0
1276
	set_io	P0_ISR
1277
 
1278
epw_005:				; Wait for Remote DMA Complete
1279
	in	al, dx
1280
	test	al, ISR_RDC
1281
	jz	epw_005
1282
;        and     al, not ISR_RDC
1283
	out	dx, al			; clear the bit
1284
 
1285
 
1286
	DEBUGF	1,"\n"
1287
	ret
1288
 
1289
 
1290
 
1291
;all initialized data place here
1292
align 4
1293
 
1294
ne2000_DEV	dd 0
1295
version 	dd (5 shl 16) or (API_VERSION and 0xFFFF)
1178 hidnplayr 1296
my_service	db 'RTL8029/ne2000',0  ;max 16 chars include zero
1159 hidnplayr 1297
 
1178 hidnplayr 1298
device_1	db 'Realtek 8029',0
1299
device_2	db 'Realtek 8019',0
1300
device_3	db 'Realtek 8019AS',0
1301
device_4	db 'ne2000',0
1302
device_5	db 'DP8390',0
1303
 
1159 hidnplayr 1304
test_data	db 'NE*000 memory',0
1305
 
1306
include_debug_strings
1307
 
1178 hidnplayr 1308
section '.data' data readable writable align 16  ;place all uninitialized data place here
1159 hidnplayr 1309
 
1178 hidnplayr 1310
ne2000_LIST	rd MAX_ne2000
1159 hidnplayr 1311