Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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