Subversion Repositories Kolibri OS

Rev

Rev 1173 | Go to most recent revision | Details | Compare with Previous | 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
 
1173 clevermous 152
	IRQ_MASK		  equ ISR_PRX ; + ISR_PTX + ISR_TXE
1159 hidnplayr 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
1177 clevermous 196
		add	edx, addr - LAST_IO
1159 hidnplayr 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
1177 clevermous 237
proc service_proc ;stdcall, ioctl:dword
238
	push	ebp
1159 hidnplayr 239
 
1177 clevermous 240
	mov	edx, [esp+8];[ioctl]
241
	mov	eax, [edx+IOCTL.io_code]
1159 hidnplayr 242
 
243
;------------------------------------------------------
244
		       ;---------------
245
	cmp	eax, 0 ;SRV_GETVERSION
246
	jne	@F     ;---------------
247
 
248
	cmp	[edx+IOCTL.out_size], 4
249
	jl	.fail
250
	mov	eax, [edx+IOCTL.output]
251
	mov	[eax], dword API_VERSION
252
 
253
	xor	eax, eax
1177 clevermous 254
	pop	ebp
255
	ret	4
1159 hidnplayr 256
 
257
;------------------------------------------------------
258
  @@:		       ;---------
259
	cmp	eax, 1 ;SRV_HOOK
260
	jne	@F     ;---------
261
 
262
	DEBUGF	2,"Checking if device is already listed..\n"
263
 
264
	mov	eax, [edx+IOCTL.input]
265
 
266
	cmp	[edx+IOCTL.inp_size], 3
267
	jl	.fail
268
	cmp	byte [eax], 1
269
	je	.pci
270
 
271
	cmp	[edx+IOCTL.inp_size], 4
272
	jl	.fail
273
	cmp	byte [eax], 0
274
	je	.isa
275
 
276
	jmp	.fail
277
 
278
  .pci:
279
 
280
	mov	esi, ne2000_LIST
281
	mov	ecx, [ne2000_DEV]
282
	test	ecx, ecx
283
	jz	.firstdevice_pci
284
	mov	bx , [eax+1]
285
  .nextdevice:
286
	lodsd
287
	cmp	bx , word [eax + device.pci_bus] ; compare with pci and device num in ne2000 list
288
	je	find_device_num
289
	loop	.nextdevice
290
 
291
  .firstdevice_pci:
292
	call	create_new_struct
293
 
294
	mov	eax, [edx+IOCTL.input]	       ; save the pci bus and device numbers
295
	mov	cx , [eax+1]			 ;
296
	mov	[ebx+device.pci_bus], cl       ;
297
	mov	[ebx+device.pci_dev], ch       ;
298
 
299
	mov	edx, PCI_BASE_ADDRESS_0        ; find the base io address
300
  .sb_reg_check:
301
  ;
302
	movzx	eax, byte [ebx+device.pci_bus] ;
303
	movzx	ecx, byte [ebx+device.pci_dev] ;
304
					       ;
305
	push	edx ecx
306
	stdcall PciRead16, eax ,ecx ,edx       ;
307
	pop	ecx edx
308
					       ;
309
	mov	[ebx+device.io_addr], ax       ;
310
	and	eax, PCI_BASE_ADDRESS_IO_MASK  ;
311
	test	eax, eax		       ;
312
	jz	.sb_inc_reg		       ;
313
	movzx	eax, [ebx+device.io_addr]      ;
314
	and	eax, PCI_BASE_ADDRESS_SPACE_IO ;
315
	test	eax, eax		       ;
316
	jz	.sb_inc_reg		       ;
317
					       ;
318
	movzx	eax, [ebx+device.io_addr]      ;
319
	and	eax, PCI_BASE_ADDRESS_IO_MASK  ;
320
	mov	[ebx+device.io_addr], ax       ;
321
					       ;
322
	jmp	.got_io 		       ;
323
					       ;
324
  .sb_inc_reg:				   ;
325
	add	edx, 4			       ;
326
	cmp	edx, PCI_BASE_ADDRESS_5        ;
327
	jbe	.sb_reg_check		       ;
328
 
329
  .got_io:
330
	movzx	eax, byte [ebx+device.pci_bus] ; find IRQ line
331
	movzx	ecx, byte [ebx+device.pci_dev] ;
332
	push	ebx
333
	stdcall PciRead8, eax ,ecx ,0x3c       ; 0x3c is the offset where irq can be found
334
	pop	ebx
335
	mov	byte [ebx+device.irq_line], al ;
336
 
337
	jmp	.hook
338
 
339
  .isa:
340
 
341
	mov	esi, ne2000_LIST
342
	mov	ecx, [ne2000_DEV]
343
	test	ecx, ecx
344
	jz	.firstdevice_isa
345
	mov	bx , [eax+1]
346
	mov	dl , [eax+3]
347
  .nextdevice_isa:
348
	lodsd
349
	cmp	bx , [eax + device.io_addr]
350
	jne	.maybenext
351
	cmp	dl , [eax + device.irq_line]
352
	je	find_device_num
353
  .maybenext:
354
	loop	.nextdevice_isa
355
 
356
 
357
 
358
  .firstdevice_isa:
359
	call	create_new_struct
360
 
361
	mov	eax, [edx+IOCTL.input]
362
	mov	cx , [eax+1]
363
	mov	[ebx+device.io_addr], cx
364
	mov	cl, [eax+3]
365
	mov	[ebx+device.irq_line], cl
366
 
367
  .hook:
368
 
369
	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
370
 
371
	call	probe							; this function will output in eax
372
	test	eax, eax
373
	jnz	.err							; If an error occured, exit
374
 
375
	mov	eax, [ne2000_DEV]
376
	mov	[ne2000_LIST+4*eax], ebx
377
	inc	[ne2000_DEV]
378
 
1177 clevermous 379
	call	EthRegDev				     ; Register the device to kernel (ebx points to device struct)
380
	cmp	eax, -1
381
	jz	.err
382
	pop	ebp
383
	ret	4
1159 hidnplayr 384
 
385
  .err:
386
	stdcall KernelFree, ebx
387
 
388
	jmp	.fail
389
 
390
;------------------------------------------------------
391
  @@:
392
.fail:
393
	or	eax, -1
1177 clevermous 394
	pop	ebp
395
	ret	4
1159 hidnplayr 396
 
397
;------------------------------------------------------
398
endp
399
 
400
 
401
create_new_struct:
402
 
403
	cmp	[ne2000_DEV], MAX_ne2000
404
	jge	.fail
405
 
406
	push	edx
407
	stdcall KernelAlloc, device.size
408
	pop	edx
409
	test	eax, eax
410
	jz	.fail
411
	mov	ebx, eax
412
 
413
	mov	dword [ebx+device.reset], reset
414
	mov	dword [ebx+device.transmit], transmit
415
	mov	dword [ebx+device.get_MAC], read_mac
416
	mov	dword [ebx+device.set_MAC], write_mac
417
	mov	dword [ebx+device.unload], unload
418
 
419
	ret
420
 
421
.fail:
422
	add	esp, 4
423
	or	eax, -1
424
	ret
425
 
426
find_device_num:
427
 
428
	DEBUGF	1,"Trying to find device number of already registered device\n"
429
	mov	ebx, eax
430
	call	EthStruc2Dev						; This kernel procedure converts a pointer to device struct in ebx
431
									; into a device number in edi
432
	mov	eax, edi						; Application wants it in eax instead
433
	DEBUGF	1,"Kernel says: %u\n", eax
434
	ret
435
 
436
 
437
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
438
;;                                                                        ;;
439
;;        Actual Hardware dependent code starts here                      ;;
440
;;                                                                        ;;
441
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
442
 
443
 
444
unload:   ; TODO
445
	or	eax, -1
446
	ret
447
 
448
 
449
 
450
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
451
;;
452
;;  probe: enables the device and clears the rx buffer
453
;;
454
;;  Destroys: eax, ebx, ecx, edx
455
;;
456
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
457
 
458
probe:
459
	mov	ebp, ebx	;---
460
 
461
	mov	[ebp + device.vendor], VENDOR_NONE
462
	mov	[ebp + device.bmem], 0
463
	mov	ax, [ebp + device.io_addr]
464
	add	ax, NE_ASIC_OFFSET
465
	mov	[ebp + device.asic_base], ax
466
 
467
	DEBUGF	2,"Trying 16-bit mode\n"
468
 
1173 clevermous 469
	or	[ebp + device.flags], FLAG_16BIT or FLAG_PIO
1159 hidnplayr 470
	mov	[ebp + device.memsize], MEM_32768
471
	mov	[ebp + device.tx_start], 64
1177 clevermous 472
	mov	[ebp + device.rx_start], TXBUF_SIZE + 64
1159 hidnplayr 473
 
474
	set_io	0
475
	set_io	P0_DCR
476
	mov	al, DCR_WTS + DCR_FT1 + DCR_LS
477
	out	dx, al
478
 
479
	set_io	P0_PSTART
480
	mov	al, MEM_16384
481
	out	dx, al
482
 
483
	set_io	P0_PSTOP
484
	mov	al, MEM_32768
485
	out	dx, al
486
 
487
	mov	esi, test_data
488
	mov	bx, 16384
489
	mov	cx, 14
490
	call	eth_pio_write
491
 
492
	mov	bx, 16384
493
	mov	cx, 14
494
	lea	edi, [ebp + device.romdata]
495
	call	eth_pio_read
496
 
497
	lea	esi, [ebp + device.romdata]
498
	mov	edi, test_data
499
	mov	ecx, 13
500
 
501
     repz    cmpsb
502
     jz      ep_set_vendor
503
 
504
 
505
	DEBUGF	2,"Trying 8-bit mode\n"
506
 
507
	mov	[ebp + device.flags], FLAG_PIO
508
	mov	[ebp + device.memsize], MEM_16384
509
	mov	[ebp + device.tx_start], 32
510
	mov	[ebp + device.rx_start], TXBUF_SIZE + 32
511
 
512
	mov	dx, [ebp + device.asic_base]
513
	add	dx, NE_RESET
514
 
515
	in	al, dx
516
	out	dx, al
517
 
518
	in	al, 0x84
519
 
520
	set_io	0
521
	mov	al, CMD_RD2 + CMD_STP
522
	out	dx, al
523
 
524
	set_io	P0_RCR
525
	mov	al, RCR_MON
526
	out	dx, al
527
 
528
	set_io	P0_DCR
529
	mov	al, DCR_FT1 + DCR_LS
530
	out	dx, al
531
 
532
	set_io	P0_PSTART
533
	mov	al, MEM_8192
534
	out	dx, al
535
 
536
	set_io	P0_PSTOP
537
	mov	al, MEM_16384
538
	out	dx, al
539
 
540
	mov	esi, test_data
541
	mov	bx, 8192
542
	mov	cx, 14
543
	call	eth_pio_write
544
 
545
	mov	bx, 8192
546
	mov	cx, 14
547
	lea	edi, [ebp + device.romdata]
548
	call	eth_pio_read
549
 
550
	mov	esi, test_data
551
	lea	edi, [ebp + device.romdata]
552
	mov	ecx, 13
553
 
554
    repz      cmpsb
555
    jz	      ep_set_vendor
556
 
557
	DEBUGF	2,"This is not a valid ne2000 device!\n"
558
	or	eax, -1
559
	ret
560
 
561
 
562
ep_set_vendor:
563
 
564
	cmp	[ebp + device.io_addr], ISA_MAX_ADDR
565
	jbe	ep_001
566
 
567
	DEBUGF	2,"Card is using PCI bus\n"
568
 
569
;;;        or      [ebp + device.flags], FLAG_16BIT
570
 
571
ep_001:
572
	mov	[ebp + device.vendor], VENDOR_NOVELL
573
 
574
ep_check_have_vendor:
575
 
576
	mov	ebx, ebp	;----
577
 
578
	mov	al, [ebp + device.vendor]
579
	cmp	al, VENDOR_NONE
580
  ;;;;      je      rtl8029_exit
581
 
582
	cmp	al, VENDOR_3COM
583
	je	reset
584
 
585
	mov	eax, [ebp + device.bmem]
586
	mov	[ebp + device.rmem], eax
587
 
588
	;-- hack
589
	mov	ebx, ebp
590
	call	read_mac
591
 
592
 
593
	push	.hack
594
	sub	esp, 6
595
	mov	edi, esp
596
	lea	esi, [ebp + device.mac]
597
	movsd
598
	movsw
599
 
600
	jmp	write_mac
601
       .hack:
602
	;--- hack
603
 
604
 
605
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
606
;;
607
;;   reset: Place the chip into a virgin state
608
;;
609
;;   Destroys: eax, ebx, ecx, edx
610
;;
611
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
612
 
613
reset:
614
	mov	ebp, ebx	;---
615
 
616
 
617
	DEBUGF	2,"Resetting rtl8029\n"
618
 
619
; attach int handler
620
	movzx	eax, [ebp+device.irq_line]
621
	DEBUGF	1,"Attaching int handler to irq %x\n",eax:1
622
	stdcall AttachIntHandler, eax, int_handler, dword 0
623
 
624
; Stop mode
625
 
626
	set_io	0
627
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STP
628
	out	dx, al
629
 
630
	set_io	P0_DCR
631
	test	[ebp + device.flags], FLAG_16BIT
632
	jz	nsr_001
633
 
634
	mov	al, 0x49
635
	jmp	nsr_002
636
 
637
nsr_001:
638
	mov	al, 0x48
639
 
640
nsr_002:
641
	out	dx, al
642
 
643
 
644
;clear remote bytes count
645
	set_io	0
646
 
647
	xor	al, al
648
 
649
	set_io	P0_RBCR0
650
	out	dx, al
651
 
652
	set_io	P0_RBCR1
653
	out	dx, al
654
 
655
 
656
;initialize Receive configuration register
657
	set_io	P0_RCR
658
	mov	al, 0x20	; monitor mode
659
	out	dx, al
660
 
661
 
662
; transmit configuration register
663
	set_io	P0_TCR
664
	mov	al, 2		; internal loopback
665
	out	dx, al
666
 
667
 
668
; transmit page stuff
669
	set_io	P0_TPSR
670
	mov	al, [ebp + device.tx_start]
671
	out	dx, al
672
 
673
; set receive control register ;;;;
674
	set_io	P0_RCR
675
	mov	al, 4		; accept broadcast
676
	out	dx, al
677
 
678
; pagestart
679
	set_io	P0_PSTART
680
	mov	al, [ebp + device.rx_start]
681
	out	dx, al
682
 
683
; pagestop
684
	set_io	P0_PSTOP
685
	mov	al, [ebp + device.memsize]
686
	out	dx, al
687
 
688
; page boundary
689
	set_io	P0_BOUND
690
	mov	al, [ebp + device.memsize]
691
	dec	al
692
	out	dx, al
693
 
694
 
695
;;clear IRQ mask
696
;        set_io  P0_IMR
697
;        xor     al, al
698
;        out     dx, al
699
 
700
	set_io	0
701
	mov	al, CMD_PS1 + CMD_RD2 + CMD_STP ; page 1, stop mode
702
	out	dx, al
703
 
704
	set_io	P1_CURR
705
	mov	al, [ebp + device.rx_start]
706
	out	dx, al
707
 
708
	set_io	0
709
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STA ; go to page 0
710
	out	dx, al
711
 
712
; Read MAC address
713
	mov	ebx, ebp	;----
714
	call	read_mac
715
 
716
; clear interupt status
1173 clevermous 717
	set_io	0
1159 hidnplayr 718
	set_io	P0_ISR
719
	mov	al, 0xff
720
	out	dx, al
721
 
722
; set IRQ mask
723
	set_io	P0_IMR
724
	mov	al, IRQ_MASK
725
	out	dx, al
726
 
727
;; start mode
728
;        set_io  0
729
;        mov     al, CMD_STA
730
;        out     dx, al
731
 
732
; clear transmit control register
733
	set_io	P0_TCR
734
	mov	al, 0		; no loopback
735
	out	dx, al
736
 
737
 
738
; Indicate that we have successfully reset the card
739
	DEBUGF	2,"Done!\n"
740
	xor	eax, eax
741
 
742
	mov	ebx, ebp	;------
743
 
744
	ret
745
 
746
 
747
 
748
;***************************************************************************
749
;   Function
750
;      transmit
751
; buffer in [esp], size in [esp+4], pointer to device struct in ebx
752
;***************************************************************************
753
 
754
align 4
755
transmit:
756
	mov	ebp, ebx
757
 
758
	mov	esi, [esp]
759
	mov	ecx, [esp + 4]
760
	DEBUGF	2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx
761
	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
762
 
763
	cmp	dword [esp+4], ETH_FRAME_LEN
764
	jg	.finish ; packet is too long
765
	cmp	dword [esp+4], 60
766
	jl	.finish ; packet is too short
767
 
768
	xor	bl, bl
769
	mov	bh, [ebp + device.tx_start]
770
	push	cx
771
	call	eth_pio_write
772
	pop	cx
773
 
774
	set_io	0
775
	mov	al, CMD_PS0 + CMD_RD2 + CMD_STA
776
	out	dx, al
777
 
778
	set_io	P0_TPSR
779
	mov	al, [ebp + device.tx_start]
780
	out	dx, al
781
 
782
	set_io	P0_TBCR0
783
	mov	al, cl
784
	out	dx, al
785
 
786
	set_io	P0_TBCR1
787
	mov	al, ch
788
	out	dx, al
789
 
790
	set_io	0
791
	mov	al, CMD_PS0 + CMD_TXP + CMD_RD2 + CMD_STA
792
	out	dx, al
793
 
794
	DEBUGF	2," - Packet Sent!\n"
795
.finish:
796
	mov	ebx, ebp
797
 
798
	call	KernelFree
799
	add	esp, 4 ; pop (balance stack)
800
	xor	eax, eax
801
 
802
	ret
803
 
804
 
805
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
806
;
807
; Interrupt handler
808
;
809
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
810
align 4
811
int_handler:
812
 
813
	DEBUGF	2,"IRQ %x ",eax:2
814
 
815
; find pointer of device wich made INT occur
816
	mov	esi, ne2000_LIST
817
	mov	ecx, [ne2000_DEV]
818
.nextdevice:
819
	mov	ebp, dword [esi]
820
 
821
	set_io	0		; We chould check ISR instead..
822
	set_io	P0_ISR
823
	in	al, dx
824
 
825
	DEBUGF	2,"isr %x ",eax:2
826
 
827
	test	al, ISR_PRX
828
	jnz	.rx
829
 
830
	add	esi, 4
831
 
832
	loop	.nextdevice
833
	ret
834
 
835
; looks like we've found it!
836
.rx:
837
 
838
 
839
	sub	esp, 14+8			  ; allocate memory for temp variables in stack
840
 
841
	eth_type	equ esp
842
	pkthdr		equ esp + 2
843
	pktoff		equ esp + 6
844
	eth_rx_data_ptr equ esp + 8
845
	eth_tmp_len	equ esp + 12
846
 
847
	pointer 	equ esp + 14
848
	size		equ esp + 18
849
 
850
	stdcall KernelAlloc, ETH_FRAME_LEN
851
	mov	[pointer], eax
852
	mov	[eth_rx_data_ptr], eax
853
 
854
	set_io	P0_BOUND
855
	in	al, dx
856
	inc	al
857
 
858
	cmp	al, [ebp + device.memsize]
859
	jb	.nsp_001
860
 
861
	mov	al, [ebp + device.rx_start]
862
 
863
.nsp_001:
864
	mov	ch, al
865
 
866
	set_io	0
867
	mov	al, CMD_PS1
868
	out	dx, al
869
 
870
	set_io	P1_CURR
871
	in	al, dx		     ; get current page
872
	mov	cl, al
873
 
874
	set_io	0
875
	mov	al, CMD_PS0
876
	out	dx, al
877
 
878
	cmp	cl, [ebp + device.memsize]
879
	jb	.nsp_002
880
 
881
	mov	cl, [ebp + device.rx_start]
882
 
883
.nsp_002:
884
	cmp	cl, ch
885
	je	.fail
886
 
887
	xor	ax, ax
888
	mov	ah, ch
889
 
890
	mov	[pktoff], ax
891
 
892
	mov	al, [ebp + device.flags]
893
	test	al, FLAG_PIO
894
	jz	.nsp_003
895
 
896
	mov	bx, word [pktoff]
897
	lea	edi, [pkthdr]
898
	mov	cx, 4
899
	call	eth_pio_read
900
	jmp	.nsp_004
901
 
902
.nsp_003:
903
	mov	edi, [ebp + device.rmem]
904
	movzx	eax, word [pktoff]
905
	add	edi, eax
906
	mov	eax, [edi]
907
	mov	[pkthdr], eax
908
 
909
.nsp_004:
910
	add	word[pktoff] , 4
911
 
912
	xor	eax, eax
913
	mov	ax, [pkthdr + 2]
914
	sub	ax, 4
915
 
916
	DEBUGF	2,"Received %u bytes\n",eax
917
 
918
	mov	[eth_tmp_len], ax
919
	mov	dword[size], eax
920
 
921
	cmp	ax, ETH_ZLEN
922
	jb	.fail
923
 
924
	cmp	ax, ETH_FRAME_LEN
925
	ja	.fail
926
 
927
	mov	al, [pkthdr]
928
	test	al, RSTAT_PRX
929
	jz	.fail
930
 
931
   ; Right, we can now get the data
932
 
933
	mov	bh, [ebp + device.memsize]
934
	sub	bx, [pktoff]
935
 
936
	cmp	[eth_tmp_len], bx
937
	jbe	.nsp_005
938
 
939
	mov	al, [ebp + device.flags]
940
	test	al, FLAG_PIO
941
	jz	.nsp_006
942
 
943
	push	bx
944
	mov	cx, bx
945
	mov	bx, [pktoff]
946
	mov	edi, [eth_rx_data_ptr]
947
	call	eth_pio_read
948
	pop	bx
949
	jmp	.nsp_007
950
 
951
.nsp_006:
952
   ; Not implemented, as we are using PIO mode on this card
953
 
954
.nsp_007:
955
	xor	al, al
956
	mov	ah, [ebp + device.rx_start]
957
	mov	[pktoff], ax
958
 
959
	add	[eth_rx_data_ptr], ebx
960
 
961
	mov	ax, [eth_tmp_len]
962
	sub	ax, bx
963
	mov	[eth_tmp_len], ax
964
 
965
.nsp_005:
966
	test	[ebp + device.flags], FLAG_PIO
967
	jz	.nsp_008
968
 
969
	xor	ebx, ebx
970
	mov	bx, [pktoff]
971
	xor	ecx, ecx
972
	mov	cx, [eth_tmp_len]
973
	mov	edi, [eth_rx_data_ptr]
974
	call	eth_pio_read
975
	jmp	.nsp_009
976
 
977
.nsp_008:
978
   ; Not implemented, as we are using PIO mode on this card
979
 
980
.nsp_009:
981
	mov	al, [pkthdr+1]
982
	cmp	al, [ebp + device.rx_start]
983
	jne	.nsp_010
984
 
985
	mov	al, [ebp + device.memsize]
986
 
987
.nsp_010:
988
	set_io	0
989
	set_io	P0_BOUND
990
	dec	al
991
	out	dx, al
992
 
993
	add	esp, 14
994
 
995
	mov	ebx, ebp
996
	jmp	EthReceiver	;;;
997
 
998
.fail:
999
	add	esp, 14+8
1000
	DEBUGF	2,"done\n"
1001
ret
1002
 
1003
 
1004
 
1005
 
1006
 
1007
;;;;;;;;;;;;;;;;;;;;;;;
1008
;;                   ;;
1009
;; Write MAC address ;;
1010
;;                   ;;
1011
;;;;;;;;;;;;;;;;;;;;;;;
1012
 
1013
align 4
1014
write_mac:	; in: mac on stack
1015
 
1016
	mov	ebp, ebx	;---
1017
 
1018
	DEBUGF	1,"Writing MAC: "
1019
 
1020
	set_io	0
1021
	mov	al, CMD_PS1; + CMD_RD2 + CMD_STP
1022
	out	dx, al
1023
 
1024
	set_io	P1_PAR0
1025
	mov	esi, esp
1026
	mov	cx, 6
1027
 @@:
1028
	lodsb
1029
	out	dx, al
1030
	inc	dx
1031
	loopw	@r
1032
 
1033
	add	esp, 6
1034
 
1035
	mov	ebx, ebp	;---
1036
 
1037
; Notice this procedure does not ret, but continues to read_mac instead.
1038
 
1039
;;;;;;;;;;;;;;;;;;;;;;
1040
;;                  ;;
1041
;; Read MAC address ;;
1042
;;                  ;;
1043
;;;;;;;;;;;;;;;;;;;;;;
1044
 
1045
read_mac:
1046
 
1047
	mov	ebp, ebx	;-----
1048
 
1049
	DEBUGF	1,"Reading MAC: "
1050
 
1051
;        set_io  0
1052
;        mov     al, CMD_PS1; + CMD_RD2 + CMD_STP ; select page 1
1053
;        out     dx, al
1054
;
1055
;        set_io  P1_PAR0
1056
;        lea     edi, [ebp + device.mac]
1057
;
1058
;        mov     cx, 6
1059
; .loop:
1060
;        in      al, dx
1061
;        stosb
1062
;        inc     dx
1063
;        loopw   .loop
1064
;
1065
;        lea     edi, [ebp + device.mac]
1066
;        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
1067
;
1068
;        set_io  0
1069
;        mov     al, CMD_PS0; + CMD_RD2 + CMD_STA  ; set page back to 0
1070
;        out     dx, al
1071
 
1072
 
1073
	mov	bx, 0
1074
	mov	cx, 16
1075
	lea	edi, [ebp + device.romdata]
1076
	call	eth_pio_read
1077
 
1078
	lea	esi, [ebp + device.romdata]
1079
	lea	edi, [ebp + device.mac]
1080
	mov	ecx, 6
1081
 
1082
  .loop:
1083
	movsb
1084
	test	[ebp + device.flags], FLAG_16BIT
1085
	jz	.8bit
1086
	inc	esi
1087
  .8bit:
1088
	loop	.loop
1089
 
1090
 
1091
	mov	ebx, ebp	;---
1092
 
1093
	ret
1094
 
1095
 
1096
;***************************************************************************
1097
;   Function
1098
;      eth_pio_read
1099
;
1100
;   Description
1101
;       Read a frame from the ethernet card via Programmed I/O
1102
;      src in bx
1103
;      cnt in cx
1104
;       dst in edi
1105
;***************************************************************************
1106
eth_pio_read:
1107
 
1108
	DEBUGF	1,"Eth PIO Read from %x to %x, %u bytes ",bx,edi,cx
1109
 
1110
	set_io	0
1111
	mov	al, CMD_RD2 + CMD_STA
1112
	out	dx, al
1113
 
1114
	mov	al, cl
1115
	set_io	P0_RBCR0
1116
	out	dx, al
1117
 
1118
	mov	al, ch
1119
	set_io	P0_RBCR1
1120
	out	dx, al
1121
 
1122
	mov	al, bl
1123
	set_io	P0_RSAR0
1124
	out	dx, al
1125
 
1126
	mov	al, bh
1127
	set_io	P0_RSAR1
1128
	out	dx, al
1129
 
1130
	mov	al, CMD_RD0 + CMD_STA
1131
	set_io	0
1132
	out	dx, al
1133
 
1134
	mov	dx, [ebp + device.asic_base]
1135
 
1136
	test	[ebp+device.flags], FLAG_16BIT
1137
	jz	epr_003
1138
 
1139
	DEBUGF	1,"in 16-bits mode"
1140
 
1141
	shr	cx, 1	; note that if the number was odd, carry flag will be set
1142
	pushf		; save the flags for later
1143
 
1144
epr_002:
1145
	in	ax, dx
1146
	stosw
1147
	loopw	epr_002
1148
 
1149
	inc	cx
1150
	popf
1151
	jnc	epr_004
1152
 
1153
epr_003:
1154
	in	al, dx
1155
	stosb
1156
	loopw	epr_003
1157
 
1158
 
1159
epr_004:
1160
	set_io	0
1161
	set_io	P0_ISR
1162
 
1163
epr_005:				; Wait for Remote DMA Complete
1164
	in	al, dx
1165
	test	al, ISR_RDC
1166
	jz	epr_005
1167
;        and     al, not ISR_RDC
1168
	out	dx, al			; clear the bit
1169
 
1170
 
1171
	DEBUGF	1,"\n"
1172
	ret
1173
 
1174
 
1175
 
1176
 
1177
;***************************************************************************
1178
;   Function
1179
;      eth_pio_write
1180
;
1181
;   Description
1182
;       writes a frame to the ethernet card via Programmed I/O
1183
;      dst in bx
1184
;      cnt in cx
1185
;       src in esi
1186
;***************************************************************************
1187
eth_pio_write:
1188
 
1189
	DEBUGF	1,"Eth PIO Write from %x to %x, %u bytes ",esi,bx,cx
1190
 
1191
	set_io	0
1192
	mov	al, CMD_RD2 + CMD_STA
1193
	out	dx, al
1194
 
1195
	set_io	P0_ISR
1196
	mov	al, ISR_RDC
1197
	out	dx, al
1198
 
1199
	set_io	P0_RBCR0
1200
	mov	al, cl
1201
	out	dx, al
1202
 
1203
	set_io	P0_RBCR1
1204
	mov	al, ch
1205
	out	dx, al
1206
 
1207
	set_io	P0_RSAR0
1208
	mov	al,   bl
1209
	out	dx, al
1210
 
1211
	set_io	P0_RSAR1
1212
	mov	al,   bh
1213
	out	dx, al
1214
 
1215
	set_io	0
1216
	mov	al, CMD_RD1 + CMD_STA
1217
	out	dx, al
1218
 
1219
	mov	dx, [ebp + device.asic_base]
1220
	test	[ebp + device.flags], FLAG_16BIT
1221
	jz	epw_003
1222
 
1223
	DEBUGF	1,"in 16-bits mode"
1224
 
1225
	shr	cx, 1	; note that if the number was odd, carry flag will be set
1226
	pushf		; save the flags for later
1227
 
1228
epw_002:
1229
	lodsw
1230
	out	dx, ax
1231
	loopw	epw_002
1232
 
1233
	popf
1234
	jnc	epw_004
1235
	inc	cx
1236
 
1237
epw_003:
1238
	lodsb
1239
	out	dx, al
1240
	loopw	epw_003
1241
 
1242
epw_004:
1243
	set_io	0
1244
	set_io	P0_ISR
1245
 
1246
epw_005:				; Wait for Remote DMA Complete
1247
	in	al, dx
1248
	test	al, ISR_RDC
1249
	jz	epw_005
1250
;        and     al, not ISR_RDC
1251
	out	dx, al			; clear the bit
1252
 
1253
 
1254
	DEBUGF	1,"\n"
1255
	ret
1256
 
1257
 
1258
 
1259
;all initialized data place here
1260
align 4
1261
 
1262
ne2000_DEV	dd 0
1263
version 	dd (5 shl 16) or (API_VERSION and 0xFFFF)
1264
my_service	db 'ne2000',0  ;max 16 chars include zero
1265
devicename	db 'Realtek 8029',0
1266
		db 'Realtek 8019',0
1267
		db 'Realtek 8019AS',0
1268
		db 'ne2000',0
1269
		db 'DP8390',0
1270
 
1271
test_data	db 'NE*000 memory',0
1272
;test_buffer     db '             ',0
1273
 
1274
include_debug_strings
1275
 
1276
section '.data' data readable writable align 16
1277
 
1278
;place all uninitialized data place here
1279
 
1280
ne2000_LIST:
1281
rd MAX_ne2000
1282