Subversion Repositories Kolibri OS

Rev

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