Subversion Repositories Kolibri OS

Rev

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

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