Subversion Repositories Kolibri OS

Rev

Rev 2220 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2220 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2313 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
2220 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;; i8255x (Intel eepro 100) driver for KolibriOS                   ;;
7
;;                                                                 ;;
8
;;    Written by hidnplayr@kolibrios.org                           ;;
9
;;                                                                 ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
11
;;             Version 2, June 1991                                ;;
12
;;                                                                 ;;
13
;;                                                                 ;;
14
;; Good read about how to program this family of devices:          ;;
15
;; http://www.intel.com/design/network/manuals/8255x_opensdm.htm   ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
19
 
20
format MS COFF
21
 
22
	API_VERSION		equ 0x01000100
2313 hidnplayr 23
	DRIVER_VERSION		equ 5
2220 hidnplayr 24
 
25
	MAX_DEVICES		equ 16
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
include 'netdrv.inc'
35
 
36
public START
37
public service_proc
38
public version
39
 
40
virtual at ebx
41
 
42
	device:
43
 
44
	ETH_DEVICE
45
 
46
	.io_addr	dd ?
47
	.pci_bus	db ?
48
	.pci_dev	db ?
49
	.irq_line	db ?
50
 
51
	.rx_buffer	dd ?
52
	.tx_buffer	dd ?
53
 
54
	.ee_bus_width	dd ?
55
 
2313 hidnplayr 56
	rb 5+8 ;;;; align
57
 
2220 hidnplayr 58
	rxfd:
59
	.status 	dw ?
60
	.command	dw ?
61
	.link		dd ?
62
	.rx_buf_addr	dd ?
63
	.count		dw ?
64
	.size		dw ?
65
	.packet 	dd ?
66
 
2313 hidnplayr 67
	rb 12 ;;;;
68
 
2220 hidnplayr 69
	txfd:
70
	.status 	dw ?
71
	.command	dw ?
72
	.link		dd ?
73
	.tx_desc_addr	dd ?
74
	.count		dd ?
75
	.tx_buf_addr0	dd ?
76
	.tx_buf_size0	dd ?
77
	.tx_buf_addr1	dd ?
78
	.tx_buf_size1	dd ?
79
 
80
	confcmd:
81
	.status:	dw ?
82
	.command:	dw ?
83
	.link:		dd ?
84
	.data		rb 64
85
 
86
	lstats:
87
	tx_good_frames		dd ?
88
	tx_coll16_errs		dd ?
89
	tx_late_colls		dd ?
90
	tx_underruns		dd ?
91
	tx_lost_carrier 	dd ?
92
	tx_deferred		dd ?
93
	tx_one_colls		dd ?
94
	tx_multi_colls		dd ?
95
	tx_total_colls		dd ?
96
 
97
	rx_good_frames		dd ?
98
	rx_crc_errs		dd ?
99
	rx_align_errs		dd ?
100
	rx_resource_errs	dd ?
101
	rx_overrun_errs 	dd ?
102
	rx_colls_errs		dd ?
103
	rx_runt_errs		dd ?
104
 
105
	device_size = $ - device
106
 
107
end virtual
108
 
109
 
110
; Serial EEPROM
111
 
112
EE_SK		equ 1 shl 16   ; serial clock
113
EE_CS		equ 1 shl 17   ; chip select
114
EE_DI		equ 1 shl 18   ; data in
115
EE_DO		equ 1 shl 19   ; data out
116
 
117
EE_READ 	equ 110b
118
EE_WRITE	equ 101b
119
EE_ERASE	equ 111b
120
 
121
; The SCB accepts the following controls for the Tx and Rx units:
122
 
123
CU_START	equ 0x0010
124
CU_RESUME	equ 0x0020
125
CU_STATSADDR	equ 0x0040
126
CU_SHOWSTATS	equ 0x0050   ; Dump statistics counters.
127
CU_CMD_BASE	equ 0x0060   ; Base address to add to add CU commands.
128
CU_DUMPSTATS	equ 0x0070   ; Dump then reset stats counters.
129
 
130
RX_START	equ 0x0001
131
RX_RESUME	equ 0x0002
132
RX_ABORT	equ 0x0004
133
RX_ADDR_LOAD	equ 0x0006
134
RX_RESUMENR	equ 0x0007
135
INT_MASK	equ 0x0100
136
DRVR_INT	equ 0x0200   ; Driver generated interrupt
137
 
138
CmdIASetup	equ 0x0001
139
CmdConfigure	equ 0x0002
140
CmdTx		equ 0x0004 ;;;;
141
CmdTxFlex	equ 0x0008 ;;;
142
Cmdsuspend	equ 0x4000
143
 
144
 
145
reg_scb_status	equ 0
146
reg_scb_cmd	equ 2
147
reg_scb_ptr	equ 4
148
reg_port	equ 8
149
reg_eeprom_ctrl equ 12
150
reg_eeprom	equ 14
151
reg_mdi_ctrl	equ 16
152
 
153
 
154
macro delay {
155
	push	eax
156
	in	eax, dx
157
	in	eax, dx
158
	in	eax, dx
159
	in	eax, dx
160
	in	eax, dx
161
	in	eax, dx
162
	in	eax, dx
163
	in	eax, dx
164
	in	eax, dx
165
	in	eax, dx
166
	pop	eax
167
}
168
 
169
section '.flat' code readable align 16
170
 
171
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
172
;;                        ;;
173
;; proc START             ;;
174
;;                        ;;
175
;; (standard driver proc) ;;
176
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
177
 
178
proc START stdcall, state:dword
179
 
180
	cmp [state], 1
181
	jne .exit
182
 
183
  .entry:
184
 
2313 hidnplayr 185
	DEBUGF 1,"Loading i8255x driver\n"
2220 hidnplayr 186
	stdcall RegService, my_service, service_proc
187
	ret
188
 
189
  .fail:
190
  .exit:
191
	xor eax, eax
192
	ret
193
 
194
endp
195
 
196
 
197
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
198
;;                        ;;
199
;; proc SERVICE_PROC      ;;
200
;;                        ;;
201
;; (standard driver proc) ;;
202
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
203
 
204
align 4
205
proc service_proc stdcall, ioctl:dword
206
 
207
	mov	edx, [ioctl]
208
	mov	eax, [IOCTL.io_code]
209
 
210
;------------------------------------------------------
211
 
212
	cmp	eax, 0 ;SRV_GETVERSION
213
	jne	@F
214
 
2313 hidnplayr 215
	cmp	[IOCTL.out_size], 4
2220 hidnplayr 216
	jl	.fail
2313 hidnplayr 217
	mov	eax, [IOCTL.output]
2220 hidnplayr 218
	mov	[eax], dword API_VERSION
219
 
220
	xor	eax, eax
221
	ret
222
 
223
;------------------------------------------------------
224
  @@:
225
	cmp	eax, 1 ;SRV_HOOK
226
	jne	.fail
227
 
2313 hidnplayr 228
	cmp	[IOCTL.inp_size], 3		  ; Data input must be at least 3 bytes
2220 hidnplayr 229
	jl	.fail
230
 
2313 hidnplayr 231
	mov	eax, [IOCTL.input]
2220 hidnplayr 232
	cmp	byte [eax], 1				; 1 means device number and bus number (pci) are given
233
	jne	.fail					; other types arent supported for this card yet
234
 
235
; check if the device is already listed
236
 
237
	mov	esi, device_list
238
	mov	ecx, [devices]
239
	test	ecx, ecx
240
	jz	.firstdevice
241
 
242
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
243
	mov	ax , [eax+1]				;
244
  .nextdevice:
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
249
	loop	.nextdevice
250
 
251
 
252
; This device doesnt have its own eth_device structure yet, lets create one
253
  .firstdevice:
254
	cmp	[devices], MAX_DEVICES			; First check if the driver can handle one more card
255
	jge	.fail
256
 
257
	push	edx
258
	stdcall KernelAlloc, device_size
259
	pop	edx
260
	test	eax, eax
261
	jz	.fail
262
	mov	ebx, eax				; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
263
 
264
; Fill in the direct call addresses into the struct
265
 
266
	mov	[device.reset], reset
267
	mov	[device.transmit], transmit
268
;        mov     [device.get_MAC], read_mac
269
	mov	[device.set_MAC], MAC_write
270
	mov	[device.unload], unload
271
	mov	[device.name], my_service
272
 
273
; save the pci bus and device numbers
274
 
275
	mov	eax, [IOCTL.input]
276
	mov	cl , [eax+1]
277
	mov	[device.pci_bus], cl
278
	mov	cl , [eax+2]
279
	mov	[device.pci_dev], cl
280
 
281
; Now, it's time to find the base io addres of the PCI device
282
 
283
	find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
284
 
285
; We've found the io address, find IRQ now
286
 
287
	find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
288
 
289
	DEBUGF	2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
290
	[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
291
 
292
	allocate_and_clear [device.rx_buffer], (4096), .err
293
	allocate_and_clear [device.tx_buffer], (4096), .err
294
 
295
; Ok, the eth_device structure is ready, let's probe the device
296
 
297
	call	probe							; this function will output in eax
298
	test	eax, eax
299
	jnz	.err							; If an error occured, exit
300
 
301
	mov	eax, [devices]						; Add the device structure to our device list
302
	mov	[device_list+4*eax], ebx				; (IRQ handler uses this list to find device)
303
	inc	[devices]						;
304
 
305
 
306
	mov	[device.type], NET_TYPE_ETH
307
	call	NetRegDev
308
 
309
	cmp	eax, -1
310
	je	.err
311
 
312
	ret
313
 
314
; If the device was already loaded, find the device number and return it in eax
315
 
316
  .find_devicenum:
317
	DEBUGF	2,"Trying to find device number of already registered device\n"
318
	call	NetPtrToNum						; This kernel procedure converts a pointer to device struct in ebx
319
									; into a device number in edi
320
	mov	eax, edi						; Application wants it in eax instead
321
	DEBUGF	2,"Kernel says: %u\n", eax
322
	ret
323
 
324
; If an error occured, remove all allocated data and exit (returning -1 in eax)
325
 
326
  .err:
327
	stdcall KernelFree, [device.rx_buffer]
328
	stdcall KernelFree, [device.tx_buffer]
329
	stdcall KernelFree, ebx
330
 
331
  .fail:
332
	or	eax, -1
333
	ret
334
 
335
;------------------------------------------------------
336
endp
337
 
338
 
339
 
340
 
341
 
342
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
343
;;                                                                        ;;
344
;;        Actual Hardware dependent code starts here                      ;;
345
;;                                                                        ;;
346
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
347
 
348
 
349
unload:
350
	; TODO: (in this particular order)
351
	;
352
	; - Stop the device
353
	; - Detach int handler
2313 hidnplayr 354
	; - Remove device from local list (device_list)
2220 hidnplayr 355
	; - call unregister function in kernel
356
	; - Remove all allocated structures and buffers the card used
357
 
358
	or	eax,-1
359
 
360
ret
361
 
362
 
363
;-------------
364
;
365
; Probe
366
;
367
;-------------
368
 
369
align 4
370
probe:
371
 
372
	DEBUGF	1,"Probing i8255x\n"
373
 
374
	make_bus_master [device.pci_bus], [device.pci_dev]
375
 
376
;---------------------------
377
; First, identify the device
378
 
379
	movzx	ecx, [device.pci_bus]
380
	movzx	edx, [device.pci_dev]
381
	stdcall PciRead32, ecx ,edx ,0				      ; get device/vendor id
382
 
2313 hidnplayr 383
	DEBUGF	1,"Vendor_id=0x%x\n", ax
2220 hidnplayr 384
 
2313 hidnplayr 385
	cmp	ax, 0x8086
2220 hidnplayr 386
	jne	.notfound
387
	shr	eax, 16
388
 
2313 hidnplayr 389
	DEBUGF	1,"Device_id=0x%x\n", ax
2220 hidnplayr 390
 
391
	mov	ecx, DEVICE_IDs
2313 hidnplayr 392
	mov	edi, device_id_list
2220 hidnplayr 393
	repne	scasw
394
	jne	.notfound
395
	jmp	.found
396
 
397
  .notfound:
2313 hidnplayr 398
	DEBUGF	1,"ERROR: Unsupported device!\n"
2220 hidnplayr 399
	or	eax, -1
400
	ret
401
 
402
  .found:
403
 
404
	call	ee_get_width
405
	call	MAC_read_eeprom
406
 
407
	;;; TODO: detect phy
408
 
409
 
410
 
411
;----------
412
;
413
;  Reset
414
;
415
;----------
416
 
417
align 4
418
reset:
419
 
420
;---------------
421
; reset the card
422
 
423
	set_io	0
424
	set_io	reg_port
425
	xor	eax, eax	; Software Reset
426
	out	dx, eax
427
 
428
	mov	esi, 10
429
	call	Sleep		; Give the card time to warm up.
430
 
431
;---------------------------------
432
; Tell device where to store stats
433
 
434
	lea	eax, [lstats]
435
	GetRealAddr
436
	set_io	reg_scb_ptr
437
	out	dx, eax
438
 
439
	mov	ax, INT_MASK + CU_STATSADDR
440
	set_io	reg_scb_cmd
441
	out	dx, ax
442
	call	cmd_wait
443
 
444
;-----------------
445
; Set CU base to 0
446
 
447
	xor	eax, eax
448
	set_io	reg_scb_ptr
449
	out	dx, eax
450
 
451
	mov	ax, INT_MASK + RX_ADDR_LOAD
452
	set_io	reg_scb_cmd
453
	out	dx, ax
454
	call	cmd_wait
455
 
456
;---------------------
457
; build rxfd structure
458
 
459
	mov	ax, 0x0001
460
	mov	[rxfd.status], ax
461
	mov	ax, 0x0000
462
	mov	[rxfd.command], ax
463
 
464
	lea	eax, [rxfd.status]
465
	GetRealAddr
466
	mov	[rxfd.link], eax
467
 
468
	lea	eax, [device.rx_buffer]
469
	GetRealAddr
470
	mov	[rxfd.rx_buf_addr], eax
471
 
472
	xor	ax, ax
473
	mov	[rxfd.count], ax
474
 
475
	mov	ax, 1528
476
	mov	[rxfd.size], ax
477
 
478
;-------------------------------
479
; Set ptr to first command block
480
 
481
	set_io	reg_scb_ptr
482
	lea	eax, [rxfd]
483
	GetRealAddr
484
	out	dx, eax
485
 
486
	set_io	reg_scb_cmd
487
	mov	ax, INT_MASK + RX_START
488
	out	dx, ax
489
	call	cmd_wait
490
 
491
;-------------------
492
; start the receiver
493
 
494
	mov	[rxfd.status], 0
495
	mov	[rxfd.command], 0xc000
496
 
497
	set_io	reg_scb_ptr
498
	lea	eax, [rxfd]
499
	GetRealAddr
500
	out	dx, eax
501
 
502
	set_io	reg_scb_cmd
503
	mov	ax, INT_MASK + RX_START
504
	out	dx, ax
505
	call	cmd_wait
506
 
507
;-----------------
508
; set CU base to 0
509
 
510
	set_io	reg_scb_ptr
511
	xor	eax, eax
512
	out	dx, eax
513
 
514
	set_io	reg_scb_cmd
515
	mov	ax, INT_MASK + CU_CMD_BASE
516
	out	dx, ax
517
	call	cmd_wait
518
 
519
;--------------------
520
; Set TX Base address
521
 
522
; First, set up confcmd values
523
 
524
	mov	[txfd.command], CmdIASetup
525
	mov	[txfd.status], 0
526
	lea	eax, [confcmd]
527
	GetRealAddr
528
	mov	[txfd.link], eax
529
 
530
	mov	word [confcmd.command], Cmdsuspend + CmdConfigure
531
	mov	word [confcmd.status], 0
532
	lea	eax, [txfd]
533
	GetRealAddr
534
	mov	[confcmd.link], eax
535
 
536
	mov	byte [confcmd.data + 1], 0x88  ; fifo of 8 each
537
	mov	byte [confcmd.data + 4], 0
538
	mov	byte [confcmd.data + 5], 0x80
539
	mov	byte [confcmd.data + 15], 0x48
540
	mov	byte [confcmd.data + 19], 0x80
541
	mov	byte [confcmd.data + 21], 0x05
542
 
543
 
544
; CU start
545
 
546
;        lea     eax, [txfd]
547
;        GetRealAddr
548
	set_io	0
549
	set_io	reg_scb_ptr
550
	out	dx, eax
551
 
552
	mov	ax, INT_MASK + CU_START
553
	set_io	reg_scb_cmd
554
	out	dx, ax
555
	call	cmd_wait
556
 
557
; wait for thing to start
558
 
559
;  drp004:
560
;
561
;        cmp     [txfd.status], 0
562
;        jz      drp004
563
 
564
; Indicate that we have successfully reset the card
565
 
566
 
567
;;; enable interrupts
568
 
569
	xor	eax, eax
570
 
571
	ret
572
 
573
 
574
 
575
 
576
 
577
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
578
;;                                         ;;
579
;; Transmit                                ;;
580
;;                                         ;;
2313 hidnplayr 581
;; In: buffer pointer in [esp+4]           ;;
582
;;     size of buffer in [esp+8]           ;;
2220 hidnplayr 583
;;     pointer to device structure in ebx  ;;
584
;;                                         ;;
585
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
586
 
587
align 4
588
transmit:
589
 
2313 hidnplayr 590
	DEBUGF	1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
591
	mov	eax, [esp+4]
2220 hidnplayr 592
	DEBUGF	1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
593
	[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
594
	[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
595
	[eax+13]:2,[eax+12]:2
596
 
2313 hidnplayr 597
	cmp	dword [esp+8], 1500
2220 hidnplayr 598
	jg	.finish 			; packet is too long
2313 hidnplayr 599
	cmp	dword [esp+8], 60
2220 hidnplayr 600
	jl	.finish 			; packet is too short
601
 
602
	set_io	0
603
	in	ax, dx
604
	and	ax, 0xfc00
605
	out	dx, ax
606
 
607
	mov	[txfd.status], 0
608
	mov	[txfd.command], Cmdsuspend + CmdTx + CmdTxFlex
609
	lea	eax, [txfd]
610
	GetRealAddr
611
	mov	[txfd.link], eax
612
	mov	[txfd.count], 0x02208000
613
	lea	eax, [txfd.tx_buf_addr0]
614
	GetRealAddr
615
	mov	[txfd.tx_desc_addr], eax
616
 
2313 hidnplayr 617
	mov	eax, [esp+4]
2220 hidnplayr 618
	mov	[txfd.tx_buf_addr0], eax
2313 hidnplayr 619
	mov	eax, [esp+8]
2220 hidnplayr 620
	mov	[txfd.tx_buf_size0], eax
621
 
622
	; Copy the buffer address and size in
623
	mov	[txfd.tx_buf_addr1], 0
624
	mov	[txfd.tx_buf_size1], 0
625
 
626
	lea	eax, [txfd]
627
	GetRealAddr
628
	set_io	reg_scb_ptr
629
	out	dx, eax
630
 
631
	mov	ax, INT_MASK + CU_START
632
	set_io	reg_scb_cmd
633
	out	dx, ax
634
 
635
	call	cmd_wait
636
 
637
	in	ax, dx
638
 
639
  .I8t_001:
640
	cmp	[txfd.status], 0
641
	je	.I8t_001
642
 
643
	in	ax, dx
644
 
645
  .finish:
2313 hidnplayr 646
	ret	8
2220 hidnplayr 647
 
648
 
649
 
650
;;;;;;;;;;;;;;;;;;;;;;;
651
;;                   ;;
652
;; Interrupt handler ;;
653
;;                   ;;
654
;;;;;;;;;;;;;;;;;;;;;;;
655
 
656
align 4
657
int_handler:
658
 
659
	DEBUGF	1,"IRQ %x ",eax:2		    ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
660
 
661
; find pointer of device wich made IRQ occur
662
 
663
	mov	esi, device_list
664
	mov	ecx, [devices]
665
	test	ecx, ecx
666
	jz	.fail
667
.nextdevice:
668
	mov	ebx, dword [esi]
669
 
670
	set_io	0
671
  ;;      set_io  REG_ISR
672
   ;;     in      ax , dx
673
    ;;    out     dx , ax                             ; send it back to ACK
674
 
675
	add	esi, 4
676
 
677
	test	ax , ax
678
	jnz	.got_it
679
 
680
	dec	ecx
681
	jnz	.nextdevice
682
 
683
	ret					    ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
684
 
685
  .got_it:
686
 
687
 
688
       ;;; receive
689
 
690
	cmp	[rxfd.status], 0
691
	je	.nodata
692
 
693
	mov	[rxfd.status], 0
694
	mov	[rxfd.command], 0xc000
695
 
696
	set_io	reg_scb_ptr
697
	lea	eax, [rxfd.status]
698
	GetRealAddr
699
	out	dx, eax
700
 
701
	set_io	reg_scb_cmd
702
	mov	ax, INT_MASK + RX_START
703
	out	dx, ax
704
 
705
	call	cmd_wait
706
 
707
	movzx	ecx, [rxfd.count]
708
	and	ecx, 0x3fff
709
 
710
	stdcall KernelAlloc, ecx	; Allocate a buffer to put packet into
711
	push	ecx
712
	push	eax
713
 
714
	lea	esi, [device.rx_buffer]
715
 
716
  .copy:
717
	shr	ecx, 1
718
	jnc	.nb
719
	movsb
720
  .nb:
721
	shr	ecx, 1
722
	jnc	.nw
723
	movsw
724
  .nw:
725
	jz	.nd
726
	rep	movsd
727
  .nd:
728
 
729
	jmp	EthReceiver			    ; Send it to kernel
730
 
731
  .nodata:
732
  .fail:
733
 
734
	ret
735
 
736
 
737
 
738
 
739
align 4
740
cmd_wait:
741
 
2313 hidnplayr 742
	in	al, dx
743
	test	al, al
2220 hidnplayr 744
	jnz	cmd_wait
745
 
746
	ret
747
 
748
 
749
 
750
 
751
 
752
 
753
align 4
754
ee_read:	; esi = address to read
755
 
756
	set_io	0
757
	set_io	reg_eeprom
758
 
759
;-----------------------------------------------------
760
; Prepend start bit + read opcode to the address field
761
; and shift it to the very left bits of esi
762
 
763
	mov	ecx, 32
764
	sub	ecx, [device.ee_bus_width]
765
	shl	esi, cl
766
	or	esi, EE_READ shl 28
767
 
768
	mov	ecx, [device.ee_bus_width]
769
	add	ecx, 3
770
 
771
;-----------------------
772
; Write this to the chip
773
 
774
  .loop:
775
	mov	eax, EE_CS
776
	shl	esi, 1
777
	jnc	@f
778
	or	eax, EE_DI
779
       @@:
780
	out	dx , eax
781
	delay
782
 
783
	or	eax, EE_SK
784
	out	dx , eax
785
	delay
786
 
787
	loop	.loop
788
 
789
;------------------------------
790
; Now read the data from eeprom
791
 
792
	xor	esi, esi
793
	mov	ecx, 16
794
 
795
  .loop2:
796
	mov	eax, EE_CS + EE_SK
797
	out	dx , eax
798
	delay
799
 
800
	in	eax, dx
801
	test	eax, EE_DO
802
	jz	@f
803
	inc	esi
804
       @@:
805
	shl	esi, 1
806
 
807
	mov	eax, EE_CS
808
	out	dx , eax
809
	delay
810
 
811
	loop	.loop2
812
 
813
;-----------------------
814
; de-activate the eeprom
815
 
816
	xor	eax, eax
817
	out	dx, eax
818
 
819
 
820
	DEBUGF	1,"data=%x\n", esi
821
	ret
822
 
823
 
824
 
825
align 4
826
ee_write:	; esi = address to write to, di = data
827
 
828
	set_io	0
829
	set_io	reg_eeprom
830
 
831
;-----------------------------------------------------
832
; Prepend start bit + write opcode to the address field
833
; and shift it to the very left bits of esi
834
 
835
	mov	ecx, 32
836
	sub	ecx, [device.ee_bus_width]
837
	shl	esi, cl
838
	or	esi, EE_WRITE shl 28
839
 
840
	mov	ecx, [device.ee_bus_width]
841
	add	ecx, 3
842
 
843
;-----------------------
844
; Write this to the chip
845
 
846
  .loop:
847
	mov	eax, EE_CS
848
	shl	esi, 1
849
	jnc	@f
850
	or	eax, EE_DI
851
       @@:
852
	out	dx , eax
853
	delay
854
 
855
	or	eax, EE_SK
856
	out	dx , eax
857
	delay
858
 
859
	loop	.loop
860
 
861
;-----------------------------
862
; Now write the data to eeprom
863
 
864
	mov	ecx, 16
865
 
866
  .loop2:
867
	mov	eax, EE_CS
868
	shl	di , 1
869
	jnc	@f
870
	or	eax, EE_DI
871
       @@:
872
	out	dx , eax
873
	delay
874
 
875
	or	eax, EE_SK
876
	out	dx , eax
877
	delay
878
 
879
	loop	.loop2
880
 
881
;-----------------------
882
; de-activate the eeprom
883
 
884
	xor	eax, eax
885
	out	dx, eax
886
 
887
 
888
	ret
889
 
890
 
891
 
892
align 4
893
ee_get_width:
894
 
895
	set_io	0
896
	set_io	reg_eeprom
897
 
898
	mov	esi, EE_READ shl 28
899
	xor	ecx, ecx
900
 
901
  .loop:
902
	mov	eax, EE_CS
903
	out	dx , eax
904
	delay
905
 
906
	or	eax, EE_SK
907
	out	dx , eax
908
	delay
909
 
910
	inc	ecx
911
 
912
	in	eax, dx
913
	test	eax, EE_DO
914
	jnz	.loop
915
 
916
	mov	[device.ee_bus_width], ecx
917
 
918
;------------------------------
919
; Now read the data from eeprom
920
 
921
	mov	ecx, 16
922
  .loop2:
2313 hidnplayr 923
	mov	eax, EE_CS + EE_SK
2220 hidnplayr 924
	out	dx , eax
925
	delay
926
 
2313 hidnplayr 927
	mov	eax, EE_CS
2220 hidnplayr 928
	out	dx , eax
929
	delay
930
	loop	.loop2
931
 
932
;-----------------------
933
; de-activate the eeprom
934
 
935
	xor	eax, eax
936
	out	dx, eax
937
 
938
	ret
939
 
940
 
941
 
942
; cx = phy addr
943
; dx = phy reg addr
944
 
945
; ax = data
946
 
947
align 4
948
mdio_read:
949
 
950
	shl	ecx, 21 		; PHY addr
951
	shl	edx, 16 		; PHY reg addr
952
 
953
	mov	eax, ecx
954
	or	eax, edx
955
	or	eax, 10b shl 26 	; read opcode
956
 
957
	set_io	0
958
	set_io	reg_mdi_ctrl
959
	out	dx, eax
960
 
961
  .wait:
962
	delay
963
	in	eax, dx
964
	test	eax, 1 shl 28		; ready bit
965
	jz	.wait
966
 
967
	ret
968
 
969
; ax = data
970
; cx = phy addr
971
; dx = phy reg addr
972
 
973
; ax = data
974
 
975
align 4
976
mdio_write:
977
 
978
	and	eax, 0xffff
979
 
980
	shl	ecx, 21 		; PHY addr
981
	shl	edx, 16 		; PHY reg addr
982
 
983
	or	eax, ecx
984
	or	eax, edx
985
	or	eax, 01b shl 26 	; write opcode
986
 
987
	set_io	0
988
	set_io	reg_mdi_ctrl
989
	out	dx, eax
990
 
991
  .wait:
992
	delay
993
	in	eax, dx
994
	test	eax, 1 shl 28		; ready bit
995
	jz	.wait
996
 
997
	ret
998
 
999
 
1000
 
1001
align 4
1002
MAC_read_eeprom:
1003
 
1004
;;;;
1005
 
1006
	ret
1007
 
1008
 
1009
align 4
1010
MAC_write:
1011
 
1012
;;;;
1013
 
1014
	ret
1015
 
1016
 
1017
 
1018
 
1019
; End of code
1020
 
1021
align 4 					; Place all initialised data here
1022
 
1023
devices       dd 0				; number of currently running devices
1024
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1025
my_service    db 'i8255x',0			; max 16 chars include zero
1026
devicename    db 'Intel Etherexpress pro/100',0
1027
 
1028
 
1029
device_id_list:
1030
 
1031
	dw 0x1029
1032
	dw 0x1030
1033
	dw 0x1031
1034
	dw 0x1032
1035
	dw 0x1033
1036
	dw 0x1034
1037
	dw 0x1038
1038
	dw 0x1039
1039
	dw 0x103A
1040
	dw 0x103B
1041
	dw 0x103C
1042
	dw 0x103D
1043
	dw 0x103E
1044
	dw 0x1050
1045
	dw 0x1051
1046
	dw 0x1052
1047
	dw 0x1053
1048
	dw 0x1054
1049
	dw 0x1055
1050
	dw 0x1056
1051
	dw 0x1057
1052
	dw 0x1059
1053
	dw 0x1064
1054
	dw 0x1065
1055
	dw 0x1066
1056
	dw 0x1067
1057
	dw 0x1068
1058
	dw 0x1069
1059
	dw 0x106A
1060
	dw 0x106B
1061
	dw 0x1091
1062
	dw 0x1092
1063
	dw 0x1093
1064
	dw 0x1094
1065
	dw 0x1095
1066
	dw 0x10fe
1067
	dw 0x1209
1068
	dw 0x1229
1069
	dw 0x2449
1070
	dw 0x2459
1071
	dw 0x245D
1072
	dw 0x27DC
1073
 
1074
DEVICE_IDs = ($ - device_id_list) / 2
1075
 
1076
mac_82557_D100_A  = 0
1077
mac_82557_D100_B  = 1
1078
mac_82557_D100_C  = 2
1079
mac_82558_D101_A4 = 4
1080
mac_82558_D101_B0 = 5
1081
mac_82559_D101M   = 8
1082
mac_82559_D101S   = 9
1083
mac_82550_D102	  = 12
1084
mac_82550_D102_C  = 13
1085
mac_82551_E	  = 14
1086
mac_82551_F	  = 15
1087
mac_82551_10	  = 16
1088
mac_unknown	  = 0xFF
1089
 
1090
phy_100a     = 0x000003E0
1091
phy_100c     = 0x035002A8
1092
phy_82555_tx = 0x015002A8
1093
phy_nsc_tx   = 0x5C002000
1094
phy_82562_et = 0x033002A8
1095
phy_82562_em = 0x032002A8
1096
phy_82562_ek = 0x031002A8
1097
phy_82562_eh = 0x017002A8
1098
phy_82552_v  = 0xd061004d
1099
phy_unknown  = 0xFFFFFFFF
1100
 
1101
 
1102
include_debug_strings				; All data wich FDO uses will be included here
1103
 
1104
section '.data' data readable writable align 16 ; place all uninitialized data place here
1105
 
1106
device_list   rd MAX_DEVICES			; This list contains all pointers to device structures the driver is handling
1107