Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1502 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1519 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
1502 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
1519 hidnplayr 6
;;  DEC 21x4x driver for KolibriOS                                 ;;
1502 hidnplayr 7
;;                                                                 ;;
8
;;  Based on dec21140.Asm from Solar OS by                         ;;
9
;;     Eugen Brasoveanu,                                           ;;
10
;;       Ontanu Bogdan Valentin                                    ;;
11
;;                                                                 ;;
1519 hidnplayr 12
;;  Written by hidnplayr@kolibrios.org                             ;;
1502 hidnplayr 13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
19
format MS COFF
20
 
21
	API_VERSION		equ 0x01000100
1519 hidnplayr 22
	DRIVER_VERSION		equ 5
1502 hidnplayr 23
 
1519 hidnplayr 24
	MAX_DEVICES		equ 16
25
 
1502 hidnplayr 26
	DEBUG			equ 1
27
	__DEBUG__		equ 1
28
	__DEBUG_LEVEL__ 	equ 1
29
 
30
include 'proc32.inc'
31
include 'imports.inc'
32
include 'fdo.inc'
33
include 'netdrv.inc'
34
 
35
public START
36
public service_proc
37
public version
38
 
39
virtual at ebx
40
 
41
	device:
42
 
43
	ETH_DEVICE
44
 
1519 hidnplayr 45
	.rx_p_des	  dd ?	; descriptors ring with received packets
46
	.tx_p_des	  dd ?	; descriptors ring with 'to transmit' packets
47
	.tx_free_des	  dd ?	; Tx descriptors available
48
	.tx_wr_des	  dd ?	; Tx current descriptor to write data to
49
	.tx_rd_des	  dd ?	; Tx current descriptor to read TX completion
50
	.rx_crt_des	  dd ?	; Rx current descriptor
1502 hidnplayr 51
 
1519 hidnplayr 52
	.io_addr	  dd ?
53
	.pci_bus	  db ?
54
	.pci_dev	  db ?
55
	.irq_line	  db ?
1502 hidnplayr 56
 
1519 hidnplayr 57
	.size = $ - device
1502 hidnplayr 58
 
59
end virtual
60
 
61
;-------------------------------------------
62
; configuration registers
63
;-------------------------------------------
64
CFCS	equ	4	; configuration and status register
65
 
66
CSR0	equ	0x00	 ; Bus mode
67
CSR1	equ	0x08	 ; Transmit Poll Command
68
CSR2	equ	0x10	 ; Receive Poll Command
69
CSR3	equ	0x18	 ; Receive list base address
70
CSR4	equ	0x20	 ; Transmit list base address
71
CSR5	equ	0x28	 ; Status
72
CSR6	equ	0x30	 ; Operation mode
73
CSR7	equ	0x38	 ; Interrupt enable
74
CSR8	equ	0x40	 ; Missed frames and overflow counter
75
CSR9	equ	0x48	 ; Boot ROM, serial ROM, and MII management
76
CSR10	equ	0x50	 ; Boot ROM programming address
1503 hidnplayr 77
CSR11	equ	0x58	 ; General-purpose timer
1502 hidnplayr 78
CSR12	equ	0x60	 ; General-purpose port
79
CSR13	equ	0x68
1503 hidnplayr 80
CSR14	equ	0x70
81
CSR15	equ	0x78	 ; Watchdog timer
1502 hidnplayr 82
 
83
;--------bits/commands of CSR0-------------------
84
CSR0_RESET		equ	1b
85
 
86
CSR0_WIE		equ	1 SHL 24	; Write and Invalidate Enable
87
CSR0_RLE		equ	1 SHL 23	; PCI Read Line Enable
88
CSR0_RML		equ	1 SHL 21	; PCI Read Multiple
89
 
90
CSR0_CACHEALIGN_NONE	equ	00b SHL 14
91
CSR0_CACHEALIGN_32	equ	01b SHL 14
92
CSR0_CACHEALIGN_64	equ	10b SHL 14
93
CSR0_CACHEALIGN_128	equ	11b SHL 14
94
 
95
; using values from linux driver.. :P
96
CSR0_DEFAULT		equ	CSR0_WIE+CSR0_RLE+CSR0_RML+CSR0_CACHEALIGN_NONE ;32
97
 
98
;------- CSR5 -STATUS- bits --------------------------------
99
CSR5_TI 		equ	1 SHL 0 	; Transmit interupt - frame transmition completed
100
CSR5_TPS		equ	1 SHL 1 	; Transmit process stopped
101
CSR5_TU 		equ	1 SHL 2 	; Transmit Buffer unavailable
102
CSR5_TJT		equ	1 SHL 3 	; Transmit Jabber Timeout (transmitter had been excessively active)
103
CSR5_UNF		equ	1 SHL 5 	; Transmit underflow - FIFO underflow
104
CSR5_RI 		equ	1 SHL 6 	; Receive Interrupt
105
CSR5_RU 		equ	1 SHL 7 	; Receive Buffer unavailable
106
CSR5_RPS		equ	1 SHL 8 	; Receive Process stopped
107
CSR5_RWT		equ	1 SHL 9 	; Receive Watchdow Timeout
108
CSR5_ETI		equ	1 SHL 10	; Early transmit Interrupt
109
CSR5_GTE		equ	1 SHL 11	; General Purpose Timer Expired
110
CSR5_FBE		equ	1 SHL 13	; Fatal bus error
111
CSR5_ERI		equ	1 SHL 14	; Early receive Interrupt
112
CSR5_AIS		equ	1 SHL 15	; Abnormal interrupt summary
113
CSR5_NIS		equ	1 SHL 16	; normal interrupt summary
114
CSR5_RS_SH		equ	1 SHL 17	; Receive process state  -shift
115
CSR5_RS_MASK		equ	111b		;                        -mask
116
CSR5_TS_SH		equ	1 SHL 20	; Transmit process state -shift
117
CSR5_TS_MASK		equ	111b		;                        -mask
118
CSR5_EB_SH		equ	1 SHL 23	; Error bits             -shift
119
CSR5_EB_MASK		equ	111b		; Error bits             -mask
120
 
121
;CSR5 TS values
122
CSR5_TS_STOPPED 	       equ     000b
123
CSR5_TS_RUNNING_FETCHING_DESC  equ     001b
124
CSR5_TS_RUNNING_WAITING_TX     equ     010b
125
CSR5_TS_RUNNING_READING_BUFF   equ     011b
126
CSR5_TS_RUNNING_SETUP_PCKT     equ     101b
127
CSR5_TS_SUSPENDED	       equ     110b
128
CSR5_TS_RUNNING_CLOSING_DESC   equ     111b
129
 
130
;------- CSR6 -OPERATION MODE- bits --------------------------------
131
CSR6_HP 		equ	1 SHL 0 	; Hash/Perfect Receive Filtering mode
132
CSR6_SR 		equ	1 SHL 1 	; Start/Stop receive
133
CSR6_HO 		equ	1 SHL 2 	; Hash only Filtering mode
134
CSR6_PB 		equ	1 SHL 3 	; Pass bad frames
135
CSR6_IF 		equ	1 SHL 4 	; Inverse filtering
136
CSR6_SB 		equ	1 SHL 5 	; Start/Stop backoff counter
137
CSR6_PR 		equ	1 SHL 6 	; Promiscuos mode -default after reset
138
CSR6_PM 		equ	1 SHL 7 	; Pass all multicast
139
CSR6_F			equ	1 SHL 9 	; Full Duplex mode
140
CSR6_OM_SH		equ	1 SHL 10	; Operating Mode -shift
141
CSR6_OM_MASK		equ	11b		;                -mask
142
CSR6_FC 		equ	1 SHL 12	; Force Collision Mode
143
CSR6_ST 		equ	1 SHL 13	; Start/Stop Transmission Command
144
CSR6_TR_SH		equ	1 SHL 14	; Threshold Control      -shift
145
CSR6_TR_MASK		equ	11b		;                        -mask
146
CSR6_CA 		equ	1 SHL 17	; Capture Effect Enable
147
CSR6_PS 		equ	1 SHL 18	; Port select SRL / MII/SYM
148
CSR6_HBD		equ	1 SHL 19	; Heartbeat Disable
149
CSR6_SF 		equ	1 SHL 21	; Store and Forward -transmit full packet only
150
CSR6_TTM		equ	1 SHL 22	; Transmit Threshold Mode -
151
CSR6_PCS		equ	1 SHL 23	; PCS active and MII/SYM port operates in symbol mode
152
CSR6_SCR		equ	1 SHL 24	; Scrambler Mode
153
CSR6_MBO		equ	1 SHL 25	; Must Be One
154
CSR6_RA 		equ	1 SHL 30	; Receive All
155
CSR6_SC 		equ	1 SHL 31	; Special Capture Effect Enable
156
 
157
 
158
;------- CSR7 -INTERRUPT ENABLE- bits --------------------------------
159
CSR7_TI 		equ	1 SHL 0 	; transmit Interrupt Enable (set with CSR7<16> & CSR5<0> )
160
CSR7_TS 		equ	1 SHL 1 	; transmit Stopped Enable (set with CSR7<15> & CSR5<1> )
161
CSR7_TU 		equ	1 SHL 2 	; transmit buffer underrun Enable (set with CSR7<16> & CSR5<2> )
162
CSR7_TJ 		equ	1 SHL 3 	; transmit jabber timeout enable (set with CSR7<15> & CSR5<3> )
163
CSR7_UN 		equ	1 SHL 5 	; underflow Interrupt enable (set with CSR7<15> & CSR5<5> )
164
CSR7_RI 		equ	1 SHL 6 	; receive Interrupt enable (set with CSR7<16> & CSR5<5> )
165
CSR7_RU 		equ	1 SHL 7 	; receive buffer unavailable enable (set with CSR7<15> & CSR5<7> )
166
CSR7_RS 		equ	1 SHL 8 	; Receive stopped enable (set with CSR7<15> & CSR5<8> )
167
CSR7_RW 		equ	1 SHL 9 	; receive watchdog timeout enable (set with CSR7<15> & CSR5<9> )
168
CSR7_ETE		equ	1 SHL 10	; Early transmit Interrupt enable (set with CSR7<15> & CSR5<10> )
169
CSR7_GPT		equ	1 SHL 11	; general purpose timer enable (set with CSR7<15> & CSR5<11> )
170
CSR7_FBE		equ	1 SHL 13	; Fatal bus error enable (set with CSR7<15> & CSR5<13> )
171
CSR7_ERE		equ	1 SHL 14	; Early receive enable (set with CSR7<16> & CSR5<14> )
172
CSR7_AI 		equ	1 SHL 15	; Abnormal Interrupt Summary Enable (enables CSR5<0,3,7,8,9,10,13>)
173
CSR7_NI 		equ	1 SHL 16	; Normal Interrup Enable (enables CSR5<0,2,6,11,14>)
174
CSR7_DEFAULT		equ	CSR7_TI+CSR7_TS+CSR7_RI+CSR7_RS+CSR7_TU+CSR7_TJ+CSR7_UN+\
175
					CSR7_RU+CSR7_RW+CSR7_FBE+CSR7_AI+CSR7_NI
176
 
177
;----------- descriptor structure ---------------------
178
struc DES {
179
	.DES0	 DD	 ?	 ; bit 31 is 'own' and rest is 'status'
180
	.DES1	 DD	 ?	 ; control bits + bytes-count buffer 1 + bytes-count buffer 2
181
	.DES2	 DD	 ?	 ; pointer to buffer1
182
	.DES3	 DD	 ?	 ; pointer to buffer2 or in this case to next descriptor, as we use a chained structure
183
	.realaddr dd ?
184
	.size = 64
185
}
186
 
187
virtual at 0
188
	DES DES
189
end virtual
190
 
191
;common to Rx and Tx
192
DES0_OWN	equ	1 SHL 31	; if set, the NIC controls the descriptor, otherwise driver 'owns' the descriptors
193
 
194
;receive
195
RDES0_ZER	equ	1 SHL 0 	; must be 0 if legal length :D
196
RDES0_CE	equ	1 SHL 1 	; CRC error, valid only on last desc (RDES0<8>=1)
197
RDES0_DB	equ	1 SHL 2 	; dribbling bit - not multiple of 8 bits, valid only on last desc (RDES0<8>=1)
198
RDES0_RE	equ	1 SHL 3 	; Report on MII error.. i dont realy know what this means :P
199
RDES0_RW	equ	1 SHL 4 	; received watchdog timer expiration - must set CSR5<9>, valid only on last desc (RDES0<8>=1)
200
RDES0_FT	equ	1 SHL 5 	; frame type: 0->IEEE802.0 (len<1500) 1-> ETHERNET frame (len>1500), valid only on last desc (RDES0<8>=1)
201
RDES0_CS	equ	1 SHL 6 	; Collision seen, valid only on last desc (RDES0<8>=1)
202
RDES0_TL	equ	1 SHL 7 	; Too long(>1518)-NOT AN ERROR, valid only on last desc (RDES0<8>=1)
203
RDES0_LS	equ	1 SHL 8 	; Last descriptor of current frame
204
RDES0_FS	equ	1 SHL 9 	; First descriptor of current frame
205
RDES0_MF	equ	1 SHL 10	; Multicast frame, valid only on last desc (RDES0<8>=1)
206
RDES0_RF	equ	1 SHL 11	; Runt frame, valid only on last desc (RDES0<8>=1) and id overflow
207
RDES0_DT_SERIAL equ	00b SHL 12	; Data type-Serial recv frame, valid only on last desc (RDES0<8>=1)
208
RDES0_DT_INTERNAL equ	01b SHL 12	; Data type-Internal loopback recv frame, valid only on last desc (RDES0<8>=1)
209
RDES0_DT_EXTERNAL equ	11b SHL 12	; Data type-External loopback recv frame, valid only on last desc (RDES0<8>=1)
210
RDES0_DE	equ	1 SHL 14	; Descriptor error - cant own a new desc and frame doesnt fit, valid only on last desc (RDES0<8>=1)
211
RDES0_ES	equ	1 SHL 15	; Error Summmary - bits 1+6+11+14, valid only on last desc (RDES0<8>=1)
212
RDES0_FL_SH	equ	16		; Field length shift, valid only on last desc (RDES0<8>=1)
213
RDES0_FL_MASK	equ	11111111111111b ; Field length mask (+CRC), valid only on last desc (RDES0<8>=1)
214
RDES0_FF	equ	1 SHL 30	; Filtering fail-frame failed address recognition test(must CSR6<30>=1), valid only on last desc (RDES0<8>=1)
215
 
216
RDES1_RBS1_MASK equ	11111111111b	; firsd buffer size MASK
217
RDES1_RBS2_SH	equ	1 SHL 11	; second buffer size SHIFT
218
RDES1_RBS2_MASK equ	11111111111b	; second buffer size MASK
219
RDES1_RCH	equ	1 SHL 24	; Second address chained - second address (buffer) is next desc address
220
RDES1_RER	equ	1 SHL 25	; Receive End of Ring - final descriptor, NIC must return to first desc
221
 
222
;transmition
223
TDES0_DE	equ	1 SHL 0 	; Deffered
224
TDES0_UF	equ	1 SHL 1 	; Underflow error
225
TDES0_LF	equ	1 SHL 2 	; Link fail report (only if CSR6<23>=1)
226
TDES0_CC_SH	equ	3		; Collision Count shift - no of collision before transmition
227
TDES0_CC_MASK	equ	1111b		; Collision Count mask
228
TDES0_HF	equ	1 SHL 7 	; Heartbeat fail
229
TDES0_EC	equ	1 SHL 8 	; Excessive Collisions - >16 collisions
230
TDES0_LC	equ	1 SHL 9 	; Late collision
231
TDES0_NC	equ	1 SHL 10	; No carrier
232
TDES0_LO	equ	1 SHL 11	; Loss of carrier
233
TDES0_TO	equ	1 SHL 14	; Transmit Jabber Timeout
234
TDES0_ES	equ	1 SHL 15	; Error summary TDES0<1+8+9+10+11+14>=1
235
 
236
TDES1_TBS1_MASK equ	11111111111b	; Buffer 1 size mask
237
TDES1_TBS2_SH	equ	11		; Buffer 2 size shift
238
TDES1_TBS2_MASK equ	11111111111b	; Buffer 2 size mask
239
TDES1_FT0	equ	1 SHL 22	; Filtering type 0
240
TDES1_DPD	equ	1 SHL 23	; Disabled padding for packets <64bytes, no padding
241
TDES1_TCH	equ	1 SHL 24	; Second address chained - second buffer pointer is to next desc
242
TDES1_TER	equ	1 SHL 25	; Transmit end of ring - final descriptor
243
TDES1_AC	equ	1 SHL 26	; Add CRC disable -pretty obvious
244
TDES1_SET	equ	1 SHL 27	; Setup packet
245
TDES1_FT1	equ	1 SHL 28	; Filtering type 1
246
TDES1_FS	equ	1 SHL 29	; First segment - buffer is first segment of frame
247
TDES1_LS	equ	1 SHL 30	; Last segment
248
TDES1_IC	equ	1 SHL 31	; Interupt on completion (CSR5<0>=1) valid when TDES1<30>=1
249
 
250
MAX_ETH_FRAME_SIZE	equ	1514
251
 
252
RX_DES_COUNT		equ	4	       ; no of RX descriptors, must be power of 2
253
RX_BUFF_SIZE		equ	2048		; size of buffer for each descriptor, must be multiple of 4 and <= 2048 TDES1_TBS1_MASK
254
TX_DES_COUNT		equ	4	       ; no of TX descriptors, must be power of 2
255
TX_BUFF_SIZE		equ	2048		; size of buffer for each descriptor, used for memory allocation only
256
 
257
RX_MEM_TOTAL_SIZE	equ	RX_DES_COUNT*(DES.size+RX_BUFF_SIZE)
258
TX_MEM_TOTAL_SIZE	equ	TX_DES_COUNT*(DES.size+TX_BUFF_SIZE)
259
 
260
;=============================================================================
261
; serial ROM operations
262
;=============================================================================
263
CSR9_SR 		equ	1 SHL 11	; SROM Select
264
CSR9_RD 		equ	1 SHL 14	; ROM Read Operation
265
CSR9_SROM_DO		equ	1 SHL 3 	; Data Out for SROM
266
CSR9_SROM_DI		equ	1 SHL 2 	; Data In to SROM
267
CSR9_SROM_CK		equ	1 SHL 1 	; clock for SROM
268
CSR9_SROM_CS		equ	1 SHL 0 	; chip select.. always needed
269
 
1503 hidnplayr 270
; assume dx is CSR9
1502 hidnplayr 271
macro SROM_Delay {
272
	push	eax
273
	in	eax, dx
274
	in	eax, dx
275
	in	eax, dx
276
	in	eax, dx
277
	in	eax, dx
278
	in	eax, dx
279
	in	eax, dx
280
	in	eax, dx
281
	in	eax, dx
282
	in	eax, dx
283
	pop	eax
284
}
285
 
1503 hidnplayr 286
; assume dx is CSR9
287
macro MDIO_Delay {
288
	push	eax
289
	in	eax, dx
290
	pop	eax
291
}
292
 
1502 hidnplayr 293
macro Bit_Set a_bit {
294
	in	eax, dx
295
	or	eax, a_bit
296
	out	dx , eax
297
}
298
 
299
macro Bit_Clear a_bit {
300
	in	eax, dx
301
	and	eax, NOT (a_bit)
302
	out	dx , eax
303
}
304
 
305
 
306
section '.flat' code readable align 16
307
 
308
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
309
;;                        ;;
310
;; proc START             ;;
311
;;                        ;;
312
;; (standard driver proc) ;;
313
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
314
 
315
align 4
316
proc START stdcall, state:dword
317
 
318
	cmp [state], 1
319
	jne .exit
320
 
321
  .entry:
322
 
323
	DEBUGF	2,"Loading dec21x4x driver\n"
324
	stdcall RegService, my_service, service_proc
325
	ret
326
 
327
  .fail:
328
  .exit:
329
	xor eax, eax
330
	ret
331
 
332
endp
333
 
334
 
335
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
336
;;                        ;;
337
;; proc SERVICE_PROC      ;;
338
;;                        ;;
339
;; (standard driver proc) ;;
340
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
341
 
342
align 4
343
proc service_proc stdcall, ioctl:dword
344
 
345
	mov	edx, [ioctl]
346
	mov	eax, [IOCTL.io_code]
347
 
348
;------------------------------------------------------
349
 
350
	cmp	eax, 0 ;SRV_GETVERSION
351
	jne	@F
352
 
353
	cmp	[IOCTL.out_size], 4
354
	jl	.fail
355
	mov	eax, [IOCTL.output]
356
	mov	[eax], dword API_VERSION
357
 
358
	xor	eax, eax
359
	ret
360
 
361
;------------------------------------------------------
362
  @@:
363
	cmp	eax, 1 ;SRV_HOOK
364
	jne	.fail
365
 
366
	cmp	[IOCTL.inp_size], 3			; Data input must be at least 3 bytes
367
	jl	.fail
368
 
369
	mov	eax, [IOCTL.input]
370
	cmp	byte [eax], 1				; 1 means device number and bus number (pci) are given
371
	jne	.fail					; other types arent supported for this card yet
372
 
373
; check if the device is already listed
374
 
1519 hidnplayr 375
	mov	esi, device_list
1502 hidnplayr 376
	mov	ecx, [devices]
377
	test	ecx, ecx
378
	jz	.firstdevice
379
 
380
;        mov     eax, [IOCTL.input]                     ; get the pci bus and device numbers
381
	mov	ax , [eax+1]				;
382
  .nextdevice:
383
	mov	ebx, [esi]
384
	cmp	ax , word [device.pci_bus]		; compare with pci and device num in device list (notice the usage of word instead of byte)
385
	je	.find_devicenum 			; Device is already loaded, let's find it's device number
386
	add	esi, 4
387
	loop	.nextdevice
388
 
389
 
390
; This device doesnt have its own eth_device structure yet, lets create one
391
  .firstdevice:
392
	cmp	[devices], MAX_DEVICES			; First check if the driver can handle one more card
393
	jge	.fail
394
 
395
	push	edx
396
	stdcall KernelAlloc, dword device.size		; Allocate the buffer for eth_device structure
397
	pop	edx
398
	test	eax, eax
399
	jz	.fail
400
	mov	ebx, eax				; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
401
 
402
; Fill in the direct call addresses into the struct
403
 
404
	mov	[device.reset], reset
405
	mov	[device.transmit], transmit
406
	mov	[device.get_MAC], read_mac
407
	mov	[device.set_MAC], write_mac
408
	mov	[device.unload], unload
409
	mov	[device.name], my_service
410
 
411
; save the pci bus and device numbers
412
 
413
	mov	eax, [IOCTL.input]
414
	mov	cl , [eax+1]
415
	mov	[device.pci_bus], cl
416
	mov	cl , [eax+2]
417
	mov	[device.pci_dev], cl
418
 
419
; Now, it's time to find the base io addres of the PCI device
420
 
421
	find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
422
 
423
; We've found the io address, find IRQ now
424
 
425
	find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
426
 
427
	DEBUGF	2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
428
	[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:8
429
 
430
	allocate_and_clear [device.rx_p_des], RX_DES_COUNT*(DES.size+RX_BUFF_SIZE), .err
431
	allocate_and_clear [device.tx_p_des], TX_DES_COUNT*(DES.size+TX_BUFF_SIZE), .err
432
 
433
; Ok, the eth_device structure is ready, let's probe the device
434
; Because initialization fires IRQ, IRQ handler must be aware of this device
435
	mov	eax, [devices]						; Add the device structure to our device list
1519 hidnplayr 436
	mov	[device_list+4*eax], ebx				; (IRQ handler uses this list to find device)
1502 hidnplayr 437
	inc	[devices]						;
438
 
439
	call	probe							; this function will output in eax
440
	test	eax, eax
441
	jnz	.err2							; If an error occured, exit
442
 
1514 hidnplayr 443
 
444
	mov	[device.type], NET_TYPE_ETH
445
	call	NetRegDev
446
 
1502 hidnplayr 447
	cmp	eax, -1
448
	je	.destroy
449
 
450
	ret
451
 
452
; If the device was already loaded, find the device number and return it in eax
453
 
454
  .find_devicenum:
455
	DEBUGF	2,"Trying to find device number of already registered device\n"
456
	mov	ebx, eax
1514 hidnplayr 457
	call	NetPtrToNum						; This kernel procedure converts a pointer to device struct in ebx
1502 hidnplayr 458
									; into a device number in edi
459
	mov	eax, edi						; Application wants it in eax instead
460
	DEBUGF	2,"Kernel says: %u\n", eax
461
	ret
462
 
463
; If an error occured, remove all allocated data and exit (returning -1 in eax)
464
 
465
  .destroy:
466
	; todo: reset device into virgin state
467
 
468
  .err2:
469
	dec	[devices]
470
  .err:
471
	DEBUGF	2,"removing device structure\n"
472
	stdcall KernelFree, [device.rx_p_des]
473
	stdcall KernelFree, [device.tx_p_des]
474
	stdcall KernelFree, ebx
475
 
476
 
477
  .fail:
478
	or	eax, -1
479
	ret
480
 
481
;------------------------------------------------------
482
endp
483
 
484
 
485
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
486
;;                                                                        ;;
487
;;        Actual Hardware dependent code starts here                      ;;
488
;;                                                                        ;;
489
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
490
 
491
 
492
 
493
align 4
494
unload:
495
	; TODO: (in this particular order)
496
	;
497
	; - Stop the device
498
	; - Detach int handler
499
	; - Remove device from local list (RTL8139_LIST)
500
	; - call unregister function in kernel
501
	; - Remove all allocated structures and buffers the card used
502
 
503
	or	eax,-1
504
 
505
ret
506
 
507
 
508
macro status {
509
	set_io	CSR5
510
	in	eax, dx
511
	DEBUGF	1,"CSR5: %x\n", eax
512
}
513
 
514
 
515
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
516
;;                                         ;;
517
;; Probe                                   ;;
518
;;                                         ;;
519
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
520
 
521
align 4
522
probe:
523
 
524
	DEBUGF	2,"Probing dec21x4x device: "
525
 
526
	make_bus_master [device.pci_bus], [device.pci_dev]
527
 
528
	movzx	eax, [device.pci_bus]
529
	movzx	ecx, [device.pci_dev]
530
	stdcall PciRead32, eax ,ecx ,0				      ; get device/vendor id
531
 
532
	DEBUGF	1,"Vendor id: 0x%x\n", ax
533
 
534
	cmp	ax , 0x1011
535
	jne	.notfound
536
	shr	eax, 16
537
 
538
	DEBUGF	1,"Vendor ok!, device id: 0x%x\n", ax		      ; TODO: use another method to detect chip!
539
 
540
	cmp	ax , 0x0009
541
	je	.supported_device
542
 
543
	cmp	ax , 0x0019
544
	je	.supported_device2
545
 
546
  .notfound:
547
	DEBUGF	1,"Device not supported!\n"
548
	or	eax, -1
549
	ret
550
 
551
  .supported_device2:
552
 
553
	; wake up the 21143
554
 
555
	movzx	ecx, [device.pci_bus]
556
	movzx	edx, [device.pci_dev]
557
	xor	eax, eax
558
	stdcall PciWrite32, ecx, edx, 0x40, eax
559
 
560
 
561
  .supported_device:
562
	call	SROM_GetWidth		; TODO: use this value returned in ecx
563
					; in the read_word routine!
564
 
565
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
566
;;                                         ;;
567
;; Reset                                   ;;
568
;;                                         ;;
569
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
570
 
571
align 4
572
reset:
573
 
574
	DEBUGF	2,"Resetting dec21x4x\n"
575
 
576
;-----------------------------------------------------------
577
; board software reset - if fails, dont do nothing else
578
 
579
	set_io	0
580
	status
581
	set_io	CSR0
582
	mov	eax, CSR0_RESET
583
	out	dx , eax
584
 
585
; wait at least 50 PCI cycles
586
	mov	esi, 1000
587
	call	Sleep
588
 
589
;-----------
590
; setup CSR0
591
 
592
	set_io	0
593
	status
594
	set_io	CSR0
595
	mov	eax, CSR0_DEFAULT
596
	out	dx , eax
597
 
598
 
599
; wait at least 50 PCI cycles
600
	mov	esi, 1000
601
	call	Sleep
602
 
603
;-----------------------------------
604
; Read mac from eeprom to driver ram
605
 
606
	call	read_mac_eeprom
607
 
608
;--------------------------------
609
; insert irq handler on given irq
610
 
611
	movzx	eax, [device.irq_line]
612
	DEBUGF	1,"Attaching int handler to irq %x\n", eax:1
613
	stdcall AttachIntHandler, eax, int_handler, dword 0
614
	test	eax, eax
615
	jnz	@f
616
	DEBUGF	1,"\nCould not attach int handler!\n"
617
;        or      eax, -1
618
;        ret
619
  @@:
620
 
621
	set_io	0
622
	status
623
 
624
;------------------------------------------
625
; Setup RX descriptors (use chained method)
626
 
627
	mov	eax, [device.rx_p_des]
628
	call	GetPgAddr
629
	mov	edx, eax
630
	lea	esi, [eax + RX_DES_COUNT*(DES.size)]	; jump over RX descriptors
631
 
632
	mov	eax, [device.rx_p_des]
633
	add	eax, RX_DES_COUNT*(DES.size)		; jump over RX descriptors
634
 
635
	mov	edi, [device.rx_p_des]
636
	mov	ecx, RX_DES_COUNT
637
 
638
	push	edx		       ;;
639
  .loop_rx_des:
640
	add	edx, DES.size
641
	mov	[edi+DES.DES0], DES0_OWN			; hardware owns buffer
642
	mov	[edi+DES.DES1], 1984+RDES1_RCH			; only size of first buffer, chained buffers
643
	mov	[edi+DES.DES2], esi				; hw buffer address
644
	mov	[edi+DES.DES3], edx				; pointer to next descriptor
645
	mov	[edi+DES.realaddr], eax 			; virtual buffer address
646
 
647
	DEBUGF	1,"RX desc %u, buff addr: %x, next desc: %x, real buff addr: %x, real descr addr: %x \n", ecx, esi, edx, eax, edi
648
 
649
	add	esi, RX_BUFF_SIZE
650
	add	eax, RX_BUFF_SIZE
651
	add	edi, DES.size
652
	dec	ecx
653
	jnz	.loop_rx_des
654
 
655
; set last descriptor as LAST
656
	sub	edi, DES.size
657
	or	[edi+DES.DES1], RDES1_RER	; EndOfRing
658
	pop	edx			;;
659
	mov	[edi+DES.DES3], edx	;;
660
 
661
;---------------------
662
; Setup TX descriptors
663
 
664
	mov	eax, [device.tx_p_des]
665
	call	GetPgAddr
666
	mov	edx, eax
667
	lea	esi, [eax + TX_DES_COUNT*(DES.size)]	; jump over TX descriptors
668
 
669
	mov	eax, [device.tx_p_des]
670
	add	eax, TX_DES_COUNT*(DES.size)	; jump over TX descriptors
671
 
672
	mov	edi, [device.tx_p_des]
673
	mov	ecx, TX_DES_COUNT
674
 
675
	push	edx		       ;;
676
  .loop_tx_des:
677
	add	edx, DES.size
678
	mov	[edi+DES.DES0], 0		; owned by driver
679
	mov	[edi+DES.DES1], TDES1_TCH	; chained method
680
	mov	[edi+DES.DES2], esi		; pointer to buffer
681
	mov	[edi+DES.DES3], edx		; pointer to next descr
682
	mov	[edi+DES.realaddr], eax
683
 
684
	DEBUGF	1,"TX desc %u, buff addr: %x, next desc: %x, real buff addr: %x, real descr addr: %x \n", ecx, esi, edx, eax, edi
685
 
686
	add	esi, TX_BUFF_SIZE
687
	add	eax, TX_BUFF_SIZE
688
	add	edi, DES.size
689
	dec	ecx
690
	jnz	.loop_tx_des
691
 
692
; set last descriptor as LAST
693
	sub	edi, DES.size
694
	or	[edi+DES.DES1], TDES1_TER	; EndOfRing
695
	pop	edx			       ;;;
696
	mov	[edi+DES.DES3], edx	       ;;;
697
 
698
;------------------
699
; Reset descriptors
700
 
701
	mov	[device.tx_wr_des], 0
702
	mov	[device.tx_rd_des], 0
703
	mov	[device.rx_crt_des], 0
704
	mov	[device.tx_free_des], TX_DES_COUNT
705
 
706
;--------------------------------------------
707
; setup CSR3 & CSR4 (pointers to descriptors)
708
 
709
	set_io	0
710
	status
711
	set_io	CSR3
712
	mov	eax, [device.rx_p_des]
713
	call	GetPgAddr
714
	DEBUGF	1,"RX descriptor base address: %x\n", eax
715
	out	dx , eax
716
 
717
	set_io	CSR4
718
	mov	eax, [device.tx_p_des]
719
	call	GetPgAddr
720
	DEBUGF	1,"TX descriptor base address: %x\n", eax
721
	out	dx , eax
722
 
723
;-------------------------------------------------------
724
; setup interrupt mask register -expect IRQs from now on
725
 
726
	status
727
	DEBUGF	1,"Enabling interrupts\n"
728
	set_io	CSR7
729
	mov	eax, CSR7_DEFAULT
730
	out	dx , eax
731
	status
732
 
733
;----------
734
; enable RX
735
 
736
	set_io	0
737
	status
738
	DEBUGF	1,"Enable RX\n"
739
 
740
	set_io	CSR6
741
	Bit_Set CSR6_SR; or CSR6_PR or CSR6_ST
742
	DEBUGF	1,"CSR6: %x\n", eax
743
 
744
	status
745
 
1503 hidnplayr 746
	call	start_link
1502 hidnplayr 747
 
1503 hidnplayr 748
 
1502 hidnplayr 749
; wait a bit
750
	mov	esi, 3000
751
	call	Sleep
752
 
753
;----------------------------------------------------
754
; send setup packet to notify the board about the MAC
755
 
756
	call	Send_Setup_Packet
757
 
1503 hidnplayr 758
	xor	eax, eax
759
; clear packet/byte counters
1502 hidnplayr 760
 
1503 hidnplayr 761
	lea	edi, [device.bytes_tx]
762
	mov	ecx, 6
763
	rep	stosd
764
 
1519 hidnplayr 765
; Set the mtu, kernel will be able to send now
766
	mov	[device.mtu], 1514
767
 
1502 hidnplayr 768
	DEBUGF	1,"Reset done\n"
769
 
770
	ret
771
 
1503 hidnplayr 772
 
773
align 4
774
start_link:
775
 
776
	; TODO: write working code here
777
 
778
	ret
779
 
1502 hidnplayr 780
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
781
;;                                         ;;
782
;; Send setup packet                       ;;
783
;;                                         ;;
784
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
785
 
786
align 4
787
Send_Setup_Packet:
788
 
789
	DEBUGF	1,"Sending setup packet\n"
790
 
791
; if no descriptors available, out
792
	mov	ecx, 1000
793
@@loop_wait_desc:
794
	cmp	[device.tx_free_des], 0
795
	jne	@f
796
 
797
	dec	ecx
798
	jnz	@@loop_wait_desc
799
 
800
	mov	eax, -1
801
	ret
802
      @@:
803
 
804
; go to current send descriptor
805
	mov	edi, [device.tx_p_des]
806
	mov	eax, [device.tx_wr_des]
807
	DEBUGF	1,"Got free descriptor: %u (%x)", eax, edi
808
	mov	edx, DES.size
809
	mul	edx
810
	add	edi, eax
811
	DEBUGF	1,"=>%x\n",  edi
812
 
813
; if NOT sending FIRST setup packet, must set current descriptor to 0 size for both buffers,
814
;  and go to next descriptor for real setup packet...            ;; TODO: check if 2 descriptors are available
815
 
816
;       cmp     [device.tx_packets], 0
817
;       je      .not_first
818
;
819
;       and     [edi+DES.des1], 0
820
;       mov     [edi+DES.des0], DES0_OWN
821
;
822
; go to next descriptor
823
;        inc     [device.tx_wr_des]
824
;        and     [device.tx_wr_des], TX_DES_COUNT-1
825
;
826
; dec free descriptors count
827
;        cmp     [device.tx_free_des], 0
828
;        jz      @f
829
;        dec     [device.tx_free_des]
830
;       @@:
831
;
832
;       ; recompute pointer to current descriptor
833
;       mov     edi, [device.tx_p_des]
834
;       mov     eax, [device.tx_wr_des]
835
;       mov     edx, DES.size
836
;       mul     edx
837
;       add     edi, eax
838
 
839
  .not_first:
840
 
841
	push	edi
842
; copy setup packet to current descriptor
843
	mov	edi, [edi+DES.realaddr]
844
; copy once the address
845
	lea	esi, [device.mac]
846
	DEBUGF	1,"copying packet to %x from %x\n", edi, esi
847
	mov	ecx, 3	; mac is 6 bytes thus 3 words
848
     .loop:
849
	DEBUGF	1,"%x ", [esi]:4
850
	movsw
851
	dec	esi
852
	dec	esi
853
	movsw
854
	dec	ecx
855
	jnz	.loop
856
 
857
	DEBUGF	1,"\n"
858
 
859
; copy 15 times the broadcast address
860
	mov	ecx, 3*15
861
	mov	eax, 0xffffffff
862
	rep	stosd
863
 
864
	pop	edi
865
 
866
; setup descriptor
867
	DEBUGF	1,"setting up descriptor\n"
868
	mov	[edi+DES.DES1], TDES1_IC+TDES1_SET+TDES1_TCH+192	; size must be EXACTLY 192 bytes
869
	mov	[edi+DES.DES0], DES0_OWN
870
 
871
	DEBUGF	1,"TDES0: %x\n", [edi+DES.DES0]:8
872
	DEBUGF	1,"TDES1: %x\n", [edi+DES.DES1]:8
873
	DEBUGF	1,"TDES2: %x\n", [edi+DES.DES2]:8
874
	DEBUGF	1,"TDES3: %x\n", [edi+DES.DES3]:8
875
 
876
; go to next descriptor
877
	inc	[device.tx_wr_des]
878
	and	[device.tx_wr_des], TX_DES_COUNT-1
879
 
880
; dec free descriptors count
881
	cmp	[device.tx_free_des], 0
882
	jz	@f
883
	dec	[device.tx_free_des]
884
       @@:
885
 
886
; start tx
887
	set_io	0
888
	status
889
	set_io	CSR6
890
	in	eax, dx
891
	test	eax, CSR6_ST		; if NOT started, start now
892
	jnz	.already_started
893
	or	eax, CSR6_ST
894
	DEBUGF	1,"Starting TX\n"
895
	jmp	.do_it
896
  .already_started:
897
					; if already started, issue a Transmit Poll command
898
	set_io	CSR1
899
	mov	eax, 0
900
	DEBUGF	1,"Issuing transmit poll command\n"
901
  .do_it:
902
	out	dx , eax
903
	status
904
 
905
	DEBUGF	1,"Sending setup packet, completed!\n"
906
 
907
	ret
908
 
909
 
910
 
911
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
912
;;                                         ;;
913
;; Transmit                                ;;
914
;;                                         ;;
915
;; In: buffer pointer in [esp+4]           ;;
916
;;     size of buffer in [esp+8]           ;;
917
;;     pointer to device structure in ebx  ;;
918
;;                                         ;;
919
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
920
 
921
align 4
922
transmit:
923
 
924
	DEBUGF	1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
925
	mov	eax, [esp+4]
926
	DEBUGF	1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
927
	[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
928
	[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
929
	[eax+13]:2,[eax+12]:2
930
 
931
	cmp	dword [esp+8], MAX_ETH_FRAME_SIZE
932
	ja	.fail
933
 
934
	cmp	[device.tx_free_des], 0
935
	je	.fail
936
 
937
;--------------------------
938
; copy packet to crt buffer
939
 
940
	mov	eax, [device.tx_wr_des]
941
	mov	edx, DES.size
942
	mul	edx
943
	add	eax, [device.tx_p_des]
944
	mov	edi, [eax+DES.realaddr] 		; pointer to buffer
945
	mov	esi, [esp+4]
946
	mov	ecx, [esp+8]
947
	DEBUGF	1,"copying %u bytes from %x to %x\n", ecx, esi, edi
948
	rep	movsb
949
 
950
; set packet size
951
	mov	ecx, [eax+DES.DES1]
952
	and	ecx, TDES1_TER				; preserve 'End of Ring' bit
953
	or	ecx, [esp+8]				; set size
954
	or	ecx, TDES1_FS or TDES1_LS or TDES1_IC or TDES1_TCH    ; first descr, last descr, interrupt on complete, chained modus
955
	mov	[eax+DES.DES1], ecx
956
 
957
; set descriptor info
958
	mov	[eax+DES.DES0], DES0_OWN		; say it is now owned by the 21x4x
959
 
960
; start tx
961
	set_io	0
962
	status
963
	set_io	CSR6
964
	in	eax, dx
965
	test	eax, CSR6_ST		; if NOT started, start now
966
	jnz	.already_started
967
	or	eax, CSR6_ST
968
	DEBUGF	1,"Starting TX\n"
969
	jmp	.do_it
970
  .already_started:
971
					; if already started, issues a Transmit Poll command
972
	set_io	CSR1
973
	mov	eax, -1
974
  .do_it:
975
	out	dx , eax
976
 
1503 hidnplayr 977
; Update stats
1502 hidnplayr 978
 
1503 hidnplayr 979
	inc	[device.packets_tx]
980
	mov	eax, [esp+8]
981
	add	dword [device.bytes_tx], eax
982
	adc	dword [device.bytes_tx + 4], 0
1502 hidnplayr 983
 
984
; go to next descriptor
985
	inc	[device.tx_wr_des]
986
	and	[device.tx_wr_des], TX_DES_COUNT-1
987
 
988
; dec free descriptors count
989
	test	[device.tx_free_des], -1
990
	jz	.end
991
	dec	[device.tx_free_des]
992
  .end:
993
	status
994
 
995
	DEBUGF	1,"transmit ok\n"
996
	xor	eax, eax
1541 hidnplayr 997
	stdcall KernelFree, [esp+4]
998
	ret	8
1502 hidnplayr 999
 
1000
  .fail:
1001
	DEBUGF	1,"transmit failed\n"
1002
	or	eax, -1
1541 hidnplayr 1003
	stdcall KernelFree, [esp+4]
1004
	ret	8
1502 hidnplayr 1005
 
1006
 
1007
;;;;;;;;;;;;;;;;;;;;;;;
1008
;;                   ;;
1009
;; Interrupt handler ;;
1010
;;                   ;;
1011
;;;;;;;;;;;;;;;;;;;;;;;
1012
 
1013
align 4
1014
int_handler:
1015
 
1016
	DEBUGF	1,"IRQ %x ",eax:2			; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
1017
 
1018
; find pointer of device wich made IRQ occur
1019
 
1020
	mov	ecx, [devices]
1021
	test	ecx, ecx
1022
	jz	.fail
1519 hidnplayr 1023
	mov	esi, device_list
1502 hidnplayr 1024
  .nextdevice:
1025
	mov	ebx, dword [esi]
1026
 
1027
	set_io	0
1028
	set_io	CSR5
1029
	in	eax, dx
1030
	out	dx , eax				; send it back to ACK
1031
 
1032
	and	eax, CSR7_DEFAULT			; int mask
1033
	test	eax, eax
1034
	jnz	.got_it
1035
 
1036
  .continue:
1037
	add	esi, 4
1038
	dec	ecx
1039
	jnz	.nextdevice
1040
 
1041
	ret						; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1042
 
1043
  .got_it:
1044
 
1045
	DEBUGF	1,"CSR7: %x ", eax
1046
 
1047
; looks like we've found it!
1048
 
1049
; Lets found out why the irq occured then..
1050
 
1051
;----------------------------------
1052
; TX ok?
1053
 
1054
	test	eax, CSR5_TI
1055
	jz	.not_tx
1056
	push	ax esi ecx
1057
 
1058
	DEBUGF 1,"TX ok!\n"
1059
 
1060
	; go to current descriptor
1061
	mov	edi, [device.tx_p_des]
1062
 
1063
	mov	eax, [device.tx_rd_des]
1064
	mov	edx, DES.size
1065
	mul	edx
1066
	add	edi, eax
1067
 
1068
      .loop_tx:
1069
 
1070
	; done if all desc are free
1071
	cmp	[device.tx_free_des], TX_DES_COUNT
1072
	jz	.end_tx
1073
 
1074
	mov	eax, [edi+DES.DES0]
1075
 
1076
	; we stop at first desc that is owned be NIC
1077
	test	eax, DES0_OWN
1078
	jnz	.end_tx
1079
 
1080
	; detect is setup packet
1081
	cmp	eax, (0ffffffffh - DES0_OWN)		; all other bits are 1
1082
	jne	.not_setup_packet
1083
	DEBUGF	1,"Setup Packet detected\n"
1084
      .not_setup_packet:
1085
 
1086
	DEBUGF	1,"packet status: %x\n", eax
1087
 
1088
	; next descriptor
1089
	add	edi, DES.size
1090
	inc	[device.tx_rd_des]
1091
	and	[device.tx_rd_des], TX_DES_COUNT-1
1092
 
1093
	; inc free desc
1094
	inc	[device.tx_free_des]
1095
	cmp	[device.tx_free_des], TX_DES_COUNT
1096
	jle	@f
1097
	mov	[device.tx_free_des], TX_DES_COUNT
1098
       @@:
1099
 
1100
	jmp	.loop_tx
1101
      .end_tx:
1102
 
1103
	;------------------------------------------------------
1104
	; here must be called standard Ethernet Tx Irq Handler
1105
	;------------------------------------------------------
1106
 
1107
	pop	ecx esi ax
1108
 
1109
;----------------------------------
1110
; RX irq
1111
  .not_tx:
1112
	test	eax, CSR5_RI
1113
	jz	.not_rx
1114
	push	ax esi ecx
1115
 
1116
	DEBUGF 1,"RX ok!\n"
1117
 
1118
	;go to current descriptor
1119
	mov	edi, [device.rx_p_des]
1120
 
1121
	mov	eax, [device.rx_crt_des]
1122
	mov	edx, DES.size
1123
	mul	edx
1124
	add	edi, eax
1125
 
1126
      .loop_rx_start_of_packet:
1127
	mov	eax, [edi+DES.DES0]
1128
 
1129
	test	eax, DES0_OWN
1130
	jnz	.end_rx 				; current desc is busy, nothing to do
1131
 
1132
	test	eax, RDES0_FS
1133
	jz	.end_rx 				; current desc is NOT first packet, ERROR!
1134
 
1135
	test	eax, RDES0_LS				; if not last desc of packet, error for now
1136
	jz	.end_rx
1137
 
1138
;        .IF     ZERO?
1139
;                ODS2 <"Net_Interrupt: packet > 1 descriptor, not supported yet :P">
1140
;                jmp     @@end_rx
1141
;        .ENDIF
1142
 
1143
	test	eax, RDES0_ES
1144
	jnz	.end_rx
1145
 
1146
;        .IF     !ZERO?
1147
;                ODS2 <"Net_Interrupt: RX error">
1148
;                jmp     @@end_rx
1149
;        .ENDIF
1150
 
1151
	mov	esi, [edi+DES.realaddr]
1152
	mov	ecx, [edi+DES.DES0]
1153
	shr	ecx, RDES0_FL_SH
1154
	and	ecx, RDES0_FL_MASK
1155
	sub	ecx, 4					 ; crc
1156
 
1157
	DEBUGF	1,"Received packet!, size=%u, addr:%x\n", ecx, esi
1158
 
1159
	push	esi edi ecx
1160
	stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
1161
	pop	ecx edi esi
1162
	test	eax, eax
1163
	jz	.fail
1164
 
1165
	push	edi
1166
	push	dword .continue_rx
1167
	push	ecx eax
1168
	mov	edi, eax
1169
 
1170
; update statistics
1171
	inc	[device.packets_rx]
1172
 
1173
	add	dword [device.bytes_rx], ecx
1174
	adc	dword [device.bytes_rx + 4], 0
1175
 
1176
; copy packet data
1177
	shr	cx , 1
1178
	jnc	.nb
1179
	movsb
1180
  .nb:
1181
	shr	cx , 1
1182
	jnc	.nw
1183
	movsw
1184
  .nw:
1185
	rep	movsd
1186
 
1187
	jmp	EthReceiver
1188
 
1189
    .continue_rx:
1190
	pop	edi
1191
 
1192
	; free descriptor
1193
	mov	[edi+DES.DES0], DES0_OWN
1194
 
1195
	; next descriptor
1196
	add	edi, DES.size
1197
 
1198
	inc	[device.rx_crt_des]
1199
	and	[device.rx_crt_des], RX_DES_COUNT-1
1200
 
1201
	jmp	.loop_rx_start_of_packet
1202
 
1203
      .end_rx:
1204
      .fail:
1205
	pop	ecx esi ax
1206
      .not_rx:
1207
 
1208
	jmp	.continue
1209
 
1210
 
1211
 
1212
align 4
1213
write_mac:	; in: mac pushed onto stack (as 3 words)
1214
 
1215
	DEBUGF	2,"Writing MAC: "
1216
 
1217
; write data into driver cache
1218
	mov	esi, esp
1219
	lea	edi, [device.mac]
1220
	movsd
1221
	movsw
1222
	add	esp, 6
1223
 
1224
; send setup packet (only if driver is started)
1225
	call	Send_Setup_Packet
1226
 
1227
align 4
1228
read_mac:
1229
 
1230
	DEBUGF 1,"Read_mac\n"
1231
 
1232
	ret
1233
 
1234
 
1235
 
1236
align 4
1237
read_mac_eeprom:
1238
 
1239
	DEBUGF 1,"Read_mac_eeprom\n"
1240
 
1241
	lea	edi, [device.mac]
1242
	mov	esi, 20/2		; read words, start address is 20
1243
     .loop:
1244
	push	esi edi
1245
	call	SROM_Read_Word
1246
	pop	edi esi
1247
	stosw
1248
	inc	esi
1249
	cmp	esi, 26/2
1250
	jl	.loop
1251
 
1252
	DEBUGF	2,"%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
1253
 
1254
	ret
1255
 
1256
align 4
1257
write_mac_eeprom:
1258
 
1259
	DEBUGF 1,"Write_mac_eeprom\n"
1260
 
1261
	ret
1262
 
1263
 
1264
align 4
1265
SROM_GetWidth:	; should be 6 or 8 according to some manuals (returns in ecx)
1266
 
1267
	DEBUGF 1,"SROM_GetWidth\n"
1268
 
1269
	call	SROM_Idle
1270
	call	SROM_EnterAccessMode
1271
 
1272
;        set_io  0
1273
;        set_io  CSR9
1274
 
1275
	; send 110b
1276
 
1277
	in	eax, dx
1278
	or	eax, CSR9_SROM_DI
1279
	call	SROM_out
1280
 
1281
	in	eax, dx
1282
	or	eax, CSR9_SROM_DI
1283
	call	SROM_out
1284
 
1285
	in	eax, dx
1286
	and	eax, not (CSR9_SROM_DI)
1287
	call	SROM_out
1288
 
1289
	mov	ecx,1
1290
  .loop2:
1291
	Bit_Set CSR9_SROM_CK
1292
	SROM_Delay
1293
 
1294
	in	eax, dx
1295
	and	eax, CSR9_SROM_DO
1296
	jnz	.not_zero
1297
 
1298
	Bit_Clear CSR9_SROM_CK
1299
	SROM_Delay
1300
	jmp	.end_loop2
1301
  .not_zero:
1302
 
1303
	Bit_Clear CSR9_SROM_CK
1304
	SROM_Delay
1305
 
1306
	inc	ecx
1307
	cmp	ecx, 12
1308
	jle	.loop2
1309
  .end_loop2:
1310
 
1311
	DEBUGF 1,"Srom width=%u\n", ecx
1312
 
1313
	call	SROM_Idle
1314
	call	SROM_EnterAccessMode
1315
	call	SROM_Idle
1316
 
1317
	ret
1318
 
1319
 
1320
align 4
1321
SROM_out:
1322
 
1323
	out	dx, eax
1324
	SROM_Delay
1325
	Bit_Set CSR9_SROM_CK
1326
	SROM_Delay
1327
	Bit_Clear CSR9_SROM_CK
1328
	SROM_Delay
1329
 
1330
	ret
1331
 
1332
 
1333
 
1334
align 4
1335
SROM_EnterAccessMode:
1336
 
1337
	DEBUGF 1,"SROM_EnterAccessMode\n"
1338
 
1339
	set_io	0
1340
	set_io	CSR9
1341
	mov	eax, CSR9_SR
1342
	out	dx, eax
1343
	SROM_Delay
1344
 
1345
	Bit_Set CSR9_RD
1346
	SROM_Delay
1347
 
1348
	Bit_Clear CSR9_SROM_CK
1349
	SROM_Delay
1350
 
1351
	Bit_Set CSR9_SROM_CS
1352
	SROM_Delay
1353
 
1354
	ret
1355
 
1356
 
1357
 
1358
align 4
1359
SROM_Idle:
1360
 
1361
	DEBUGF 1,"SROM_Idle\n"
1362
 
1363
	call	SROM_EnterAccessMode
1364
 
1365
;        set_io  0
1366
;        set_io  CSR9
1367
 
1368
	mov	ecx, 25
1369
     .loop_clk:
1370
 
1371
	Bit_Clear CSR9_SROM_CK
1372
	SROM_Delay
1373
	Bit_Set CSR9_SROM_CK
1374
	SROM_Delay
1375
 
1376
	dec	ecx
1377
	jnz	.loop_clk
1378
 
1379
 
1380
	Bit_Clear CSR9_SROM_CK
1381
	SROM_Delay
1382
	Bit_Clear CSR9_SROM_CS
1383
	SROM_Delay
1384
 
1385
	xor	eax, eax
1386
	out	dx, eax
1387
 
1388
	ret
1389
 
1390
 
1391
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1392
;;                                                                      ;;
1393
;; Read serial EEprom word                                              ;;
1394
;;                                                                      ;;
1395
;; In: esi = read address                                               ;;
1396
;; OUT: ax = data word                                                  ;;
1397
;;                                                                      ;;
1398
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1399
align 4
1400
SROM_Read_Word:
1401
 
1402
	DEBUGF 1,"SROM_Read_word at: %x result: ", esi
1403
 
1404
	set_io	0
1405
	set_io	CSR9
1406
 
1407
; enter access mode
1408
	mov	eax, CSR9_SR + CSR9_RD
1409
	out	dx , eax
1410
	or	eax, CSR9_SROM_CS
1411
	out	dx , eax
1412
 
1413
	; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
1414
 
1415
; send read command "110b" + address to read from
1416
	and	esi, 111111b
1417
	or	esi, 110b shl 6
1418
 
1419
	mov	ecx, 1 shl 9
1420
  .loop_cmd:
1421
	mov	eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1422
	test	esi, ecx
1423
	jz	@f
1424
	or	eax, CSR9_SROM_DI
1425
       @@:
1426
	out	dx , eax
1427
	SROM_Delay
1428
	or	eax, CSR9_SROM_CK
1429
	out	dx , eax
1430
	SROM_Delay
1431
 
1432
	shr	ecx, 1
1433
	jnz	.loop_cmd
1434
 
1435
; read data from SROM
1436
 
1437
	xor	esi, esi
1438
	mov	ecx, 17 ;;; TODO: figure out why 17, not 16
1439
  .loop_read:
1440
 
1441
	mov	eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
1442
	out	dx , eax
1443
	SROM_Delay
1444
 
1445
	in	eax, dx
1446
	and	eax, CSR9_SROM_DO
1447
	shr	eax, 3
1448
	shl	esi, 1
1449
	or	esi, eax
1450
 
1451
	mov	eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1452
	out	dx , eax
1453
	SROM_Delay
1454
 
1455
	dec	ecx
1456
	jnz	.loop_read
1457
 
1458
	mov	eax, esi
1459
 
1460
	DEBUGF 1,"%x\n", ax
1461
 
1462
	ret
1463
 
1464
 
1503 hidnplayr 1465
 
1466
 
1467
 
1468
 
1469
 
1470
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1471
 
1472
 
1473
 
1474
;*********************************************************************
1475
;* Media Descriptor Code                                             *
1476
;*********************************************************************
1477
 
1478
; MII transceiver control section.
1479
; Read and write the MII registers using software-generated serial
1480
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1481
; for details.
1482
 
1483
; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
1484
; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
1485
; "overclocking" issues or future 66Mhz PCI.
1486
 
1487
; Read and write the MII registers using software-generated serial
1488
; MDIO protocol.  It is just different enough from the EEPROM protocol
1489
; to not share code.  The maxium data clock rate is 2.5 Mhz.
1490
 
1491
MDIO_SHIFT_CLK		equ	0x10000
1492
MDIO_DATA_WRITE0	equ	0x00000
1493
MDIO_DATA_WRITE1	equ	0x20000
1494
MDIO_ENB		equ	0x00000 	; Ignore the 0x02000 databook setting.
1495
MDIO_ENB_IN		equ	0x40000
1496
MDIO_DATA_READ		equ	0x80000
1497
 
1498
; MII transceiver control section.
1499
; Read and write the MII registers using software-generated serial
1500
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1501
; for details.
1502
 
1503
align 4
1504
mdio_read:	; phy_id:edx, location:esi
1505
 
1506
	DEBUGF	1,"mdio read, phy=%x, location=%x", edx, esi
1507
 
1508
	shl	edx, 5
1509
	or	esi, edx
1510
	or	esi, 0xf6 shl 10
1511
 
1512
	set_io	0
1513
	set_io	CSR9
1514
 
1515
;    if (tp->chip_id == LC82C168) {
1516
;        int i = 1000;
1517
;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
1518
;        inl(ioaddr + 0xA0);
1519
;        inl(ioaddr + 0xA0);
1520
;        while (--i > 0)
1521
;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
1522
;                return retval & 0xffff;
1523
;        return 0xffff;
1524
;    }
1525
;
1526
;    if (tp->chip_id == COMET) {
1527
;        if (phy_id == 1) {
1528
;            if (location < 7)
1529
;                return inl(ioaddr + 0xB4 + (location<<2));
1530
;            else if (location == 17)
1531
;                return inl(ioaddr + 0xD0);
1532
;            else if (location >= 29 && location <= 31)
1533
;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
1534
;        }
1535
;        return 0xffff;
1536
;    }
1537
 
1538
; Establish sync by sending at least 32 logic ones.
1539
 
1540
	mov	ecx, 32
1541
  .loop:
1542
	mov	eax, MDIO_ENB or MDIO_DATA_WRITE1
1543
	out	dx, eax
1544
	MDIO_Delay
1545
 
1546
	or	eax, MDIO_SHIFT_CLK
1547
	out	dx, eax
1548
	MDIO_Delay
1549
 
1550
	dec	ecx
1551
	jnz	.loop
1552
 
1553
 
1554
; Shift the read command bits out.
1555
 
1556
	mov	ecx, 1 shl 15
1557
  .loop2:
1558
	mov	eax, MDIO_ENB
1559
	test	esi, ecx
1560
	jz	@f
1561
	or	eax, MDIO_DATA_WRITE1
1562
       @@:
1563
	out	dx, eax
1564
	MDIO_Delay
1565
 
1566
	or	eax, MDIO_SHIFT_CLK
1567
	out	dx, eax
1568
	MDIO_Delay
1569
 
1570
	shr	ecx, 1
1571
	jnz	.loop2
1572
 
1573
 
1574
; Read the two transition, 16 data, and wire-idle bits.
1575
 
1576
	xor	esi, esi
1577
	mov	ecx, 19
1578
  .loop3:
1579
	mov	eax, MDIO_ENB_IN
1580
	out	dx, eax
1581
	MDIO_Delay
1582
 
1583
	shl	esi, 1
1584
	in	eax, dx
1585
	test	eax, MDIO_DATA_READ
1586
	jz	@f
1587
	inc	esi
1588
       @@:
1589
 
1590
	mov	eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
1591
	out	dx, eax
1592
	MDIO_Delay
1593
 
1594
	dec	ecx
1595
	jnz	.loop3
1596
 
1597
	shr	esi, 1
1598
	movzx	eax, si
1599
 
1600
	DEBUGF	1,", data=%x\n", ax
1601
 
1602
	ret
1603
 
1604
 
1605
 
1606
 
1607
align 4
1608
mdio_write:	;int phy_id: edx, int location: edi, int value: ax)
1609
 
1610
	DEBUGF	1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
1611
 
1612
	shl	edi, 18
1613
	or	edi, 0x5002 shl 16
1614
	shl	edx, 23
1615
	or	edi, edx
1616
	mov	di, ax
1617
 
1618
	set_io	0
1619
	set_io	CSR9
1620
 
1621
;    if (tp->chip_id == LC82C168) {
1622
;        int i = 1000;
1623
;        outl(cmd, ioaddr + 0xA0);
1624
;        do
1625
;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
1626
;                break;
1627
;        while (--i > 0);
1628
;        return;
1629
;    }
1630
 
1631
;    if (tp->chip_id == COMET) {
1632
;        if (phy_id != 1)
1633
;            return;
1634
;        if (location < 7)
1635
;            outl(value, ioaddr + 0xB4 + (location<<2));
1636
;        else if (location == 17)
1637
;            outl(value, ioaddr + 0xD0);
1638
;        else if (location >= 29 && location <= 31)
1639
;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
1640
;        return;
1641
;    }
1642
 
1643
 
1644
; Establish sync by sending at least 32 logic ones.
1645
 
1646
	mov	ecx, 32
1647
  .loop:
1648
	mov	eax, MDIO_ENB or MDIO_DATA_WRITE1
1649
	out	dx, eax
1650
	MDIO_Delay
1651
 
1652
	or	eax, MDIO_SHIFT_CLK
1653
	out	dx, eax
1654
	MDIO_Delay
1655
 
1656
	dec	ecx
1657
	jnz	.loop
1658
 
1659
 
1660
; Shift the command bits out.
1661
 
1662
	mov	ecx, 1 shl 31
1663
  .loop2:
1664
	mov	eax, MDIO_ENB
1665
	test	edi, ecx
1666
	jz	@f
1667
	or	eax, MDIO_DATA_WRITE1
1668
       @@:
1669
	out	dx, eax
1670
	MDIO_Delay
1671
 
1672
	or	eax, MDIO_SHIFT_CLK
1673
	out	dx, eax
1674
	MDIO_Delay
1675
 
1676
	shr	ecx, 1
1677
	jnz	.loop2
1678
 
1679
 
1680
; Clear out extra bits.
1681
 
1682
	mov	ecx, 2
1683
  .loop3:
1684
	mov	eax, MDIO_ENB
1685
	out	dx, eax
1686
	MDIO_Delay
1687
 
1688
	or	eax, MDIO_SHIFT_CLK
1689
	out	dx, eax
1690
	MDIO_Delay
1691
 
1692
	dec	ecx
1693
	jnz	.loop3
1694
 
1695
	ret
1696
 
1697
 
1502 hidnplayr 1698
; End of code
1699
align 4 					; Place all initialised data here
1700
 
1701
devices       dd 0
1519 hidnplayr 1702
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1502 hidnplayr 1703
my_service    db 'DEC21X4X',0			 ; max 16 chars include zero
1704
 
1705
include_debug_strings				; All data wich FDO uses will be included here
1706
 
1707
section '.data' data readable writable align 16 ; place all uninitialized data place here
1708
 
1519 hidnplayr 1709
device_list rd MAX_DEVICES		       ; This list contains all pointers to device structures the driver is handling
1502 hidnplayr 1710
 
1711