Subversion Repositories Kolibri OS

Rev

Rev 1502 | 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
 
452
	call	EthRegDev
453
	cmp	eax, -1
454
	je	.destroy
455
 
456
	ret
457
 
458
; If the device was already loaded, find the device number and return it in eax
459
 
460
  .find_devicenum:
461
	DEBUGF	2,"Trying to find device number of already registered device\n"
462
	mov	ebx, eax
463
	call	EthStruc2Dev						; This kernel procedure converts a pointer to device struct in ebx
464
									; into a device number in edi
465
	mov	eax, edi						; Application wants it in eax instead
466
	DEBUGF	2,"Kernel says: %u\n", eax
467
	ret
468
 
469
; If an error occured, remove all allocated data and exit (returning -1 in eax)
470
 
471
  .destroy:
472
	; todo: reset device into virgin state
473
 
474
  .err2:
475
	dec	[devices]
476
  .err:
477
	DEBUGF	2,"removing device structure\n"
478
	stdcall KernelFree, [device.rx_p_des]
479
	stdcall KernelFree, [device.tx_p_des]
480
	stdcall KernelFree, ebx
481
 
482
 
483
  .fail:
484
	or	eax, -1
485
	ret
486
 
487
;------------------------------------------------------
488
endp
489
 
490
 
491
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
492
;;                                                                        ;;
493
;;        Actual Hardware dependent code starts here                      ;;
494
;;                                                                        ;;
495
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
496
 
497
 
498
 
499
align 4
500
unload:
501
	; TODO: (in this particular order)
502
	;
503
	; - Stop the device
504
	; - Detach int handler
505
	; - Remove device from local list (RTL8139_LIST)
506
	; - call unregister function in kernel
507
	; - Remove all allocated structures and buffers the card used
508
 
509
	or	eax,-1
510
 
511
ret
512
 
513
 
514
macro status {
515
	set_io	CSR5
516
	in	eax, dx
517
	DEBUGF	1,"CSR5: %x\n", eax
518
}
519
 
520
 
521
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
522
;;                                         ;;
523
;; Probe                                   ;;
524
;;                                         ;;
525
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
526
 
527
align 4
528
probe:
529
 
530
	DEBUGF	2,"Probing dec21x4x device: "
531
 
532
	make_bus_master [device.pci_bus], [device.pci_dev]
533
 
534
	movzx	eax, [device.pci_bus]
535
	movzx	ecx, [device.pci_dev]
536
	stdcall PciRead32, eax ,ecx ,0				      ; get device/vendor id
537
 
538
	DEBUGF	1,"Vendor id: 0x%x\n", ax
539
 
540
	cmp	ax , 0x1011
541
	jne	.notfound
542
	shr	eax, 16
543
 
544
	DEBUGF	1,"Vendor ok!, device id: 0x%x\n", ax		      ; TODO: use another method to detect chip!
545
 
546
	cmp	ax , 0x0009
547
	je	.supported_device
548
 
549
	cmp	ax , 0x0019
550
	je	.supported_device2
551
 
552
  .notfound:
553
	DEBUGF	1,"Device not supported!\n"
554
	or	eax, -1
555
	ret
556
 
557
  .supported_device2:
558
 
559
	; wake up the 21143
560
 
561
	movzx	ecx, [device.pci_bus]
562
	movzx	edx, [device.pci_dev]
563
	xor	eax, eax
564
	stdcall PciWrite32, ecx, edx, 0x40, eax
565
 
566
 
567
  .supported_device:
568
	call	SROM_GetWidth		; TODO: use this value returned in ecx
569
					; in the read_word routine!
570
 
571
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
572
;;                                         ;;
573
;; Reset                                   ;;
574
;;                                         ;;
575
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
576
 
577
align 4
578
reset:
579
 
580
	DEBUGF	2,"Resetting dec21x4x\n"
581
 
582
;-----------------------------------------------------------
583
; board software reset - if fails, dont do nothing else
584
 
585
	set_io	0
586
	status
587
	set_io	CSR0
588
	mov	eax, CSR0_RESET
589
	out	dx , eax
590
 
591
; wait at least 50 PCI cycles
592
	mov	esi, 1000
593
	call	Sleep
594
 
595
;-----------
596
; setup CSR0
597
 
598
	set_io	0
599
	status
600
	set_io	CSR0
601
	mov	eax, CSR0_DEFAULT
602
	out	dx , eax
603
 
604
 
605
; wait at least 50 PCI cycles
606
	mov	esi, 1000
607
	call	Sleep
608
 
609
;-----------------------------------
610
; Read mac from eeprom to driver ram
611
 
612
	call	read_mac_eeprom
613
 
614
;--------------------------------
615
; insert irq handler on given irq
616
 
617
	movzx	eax, [device.irq_line]
618
	DEBUGF	1,"Attaching int handler to irq %x\n", eax:1
619
	stdcall AttachIntHandler, eax, int_handler, dword 0
620
	test	eax, eax
621
	jnz	@f
622
	DEBUGF	1,"\nCould not attach int handler!\n"
623
;        or      eax, -1
624
;        ret
625
  @@:
626
 
627
	set_io	0
628
	status
629
 
630
;------------------------------------------
631
; Setup RX descriptors (use chained method)
632
 
633
	mov	eax, [device.rx_p_des]
634
	call	GetPgAddr
635
	mov	edx, eax
636
	lea	esi, [eax + RX_DES_COUNT*(DES.size)]	; jump over RX descriptors
637
 
638
	mov	eax, [device.rx_p_des]
639
	add	eax, RX_DES_COUNT*(DES.size)		; jump over RX descriptors
640
 
641
	mov	edi, [device.rx_p_des]
642
	mov	ecx, RX_DES_COUNT
643
 
644
	push	edx		       ;;
645
  .loop_rx_des:
646
	add	edx, DES.size
647
	mov	[edi+DES.DES0], DES0_OWN			; hardware owns buffer
648
	mov	[edi+DES.DES1], 1984+RDES1_RCH			; only size of first buffer, chained buffers
649
	mov	[edi+DES.DES2], esi				; hw buffer address
650
	mov	[edi+DES.DES3], edx				; pointer to next descriptor
651
	mov	[edi+DES.realaddr], eax 			; virtual buffer address
652
 
653
	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
654
 
655
	add	esi, RX_BUFF_SIZE
656
	add	eax, RX_BUFF_SIZE
657
	add	edi, DES.size
658
	dec	ecx
659
	jnz	.loop_rx_des
660
 
661
; set last descriptor as LAST
662
	sub	edi, DES.size
663
	or	[edi+DES.DES1], RDES1_RER	; EndOfRing
664
	pop	edx			;;
665
	mov	[edi+DES.DES3], edx	;;
666
 
667
;---------------------
668
; Setup TX descriptors
669
 
670
	mov	eax, [device.tx_p_des]
671
	call	GetPgAddr
672
	mov	edx, eax
673
	lea	esi, [eax + TX_DES_COUNT*(DES.size)]	; jump over TX descriptors
674
 
675
	mov	eax, [device.tx_p_des]
676
	add	eax, TX_DES_COUNT*(DES.size)	; jump over TX descriptors
677
 
678
	mov	edi, [device.tx_p_des]
679
	mov	ecx, TX_DES_COUNT
680
 
681
	push	edx		       ;;
682
  .loop_tx_des:
683
	add	edx, DES.size
684
	mov	[edi+DES.DES0], 0		; owned by driver
685
	mov	[edi+DES.DES1], TDES1_TCH	; chained method
686
	mov	[edi+DES.DES2], esi		; pointer to buffer
687
	mov	[edi+DES.DES3], edx		; pointer to next descr
688
	mov	[edi+DES.realaddr], eax
689
 
690
	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
691
 
692
	add	esi, TX_BUFF_SIZE
693
	add	eax, TX_BUFF_SIZE
694
	add	edi, DES.size
695
	dec	ecx
696
	jnz	.loop_tx_des
697
 
698
; set last descriptor as LAST
699
	sub	edi, DES.size
700
	or	[edi+DES.DES1], TDES1_TER	; EndOfRing
701
	pop	edx			       ;;;
702
	mov	[edi+DES.DES3], edx	       ;;;
703
 
704
;------------------
705
; Reset descriptors
706
 
707
	mov	[device.tx_wr_des], 0
708
	mov	[device.tx_rd_des], 0
709
	mov	[device.rx_crt_des], 0
710
	mov	[device.tx_free_des], TX_DES_COUNT
711
 
712
;--------------------------------------------
713
; setup CSR3 & CSR4 (pointers to descriptors)
714
 
715
	set_io	0
716
	status
717
	set_io	CSR3
718
	mov	eax, [device.rx_p_des]
719
	call	GetPgAddr
720
	DEBUGF	1,"RX descriptor base address: %x\n", eax
721
	out	dx , eax
722
 
723
	set_io	CSR4
724
	mov	eax, [device.tx_p_des]
725
	call	GetPgAddr
726
	DEBUGF	1,"TX descriptor base address: %x\n", eax
727
	out	dx , eax
728
 
729
;-------------------------------------------------------
730
; setup interrupt mask register -expect IRQs from now on
731
 
732
	status
733
	DEBUGF	1,"Enabling interrupts\n"
734
	set_io	CSR7
735
	mov	eax, CSR7_DEFAULT
736
	out	dx , eax
737
	status
738
 
739
;----------
740
; enable RX
741
 
742
	set_io	0
743
	status
744
	DEBUGF	1,"Enable RX\n"
745
 
746
	set_io	CSR6
747
	Bit_Set CSR6_SR; or CSR6_PR or CSR6_ST
748
	DEBUGF	1,"CSR6: %x\n", eax
749
 
750
	status
751
 
1503 hidnplayr 752
	call	start_link
1502 hidnplayr 753
 
1503 hidnplayr 754
 
1502 hidnplayr 755
; wait a bit
756
	mov	esi, 3000
757
	call	Sleep
758
 
759
;----------------------------------------------------
760
; send setup packet to notify the board about the MAC
761
 
762
	call	Send_Setup_Packet
763
 
1503 hidnplayr 764
	xor	eax, eax
765
; clear packet/byte counters
1502 hidnplayr 766
 
1503 hidnplayr 767
	lea	edi, [device.bytes_tx]
768
	mov	ecx, 6
769
	rep	stosd
770
 
1502 hidnplayr 771
	DEBUGF	1,"Reset done\n"
772
 
773
	ret
774
 
1503 hidnplayr 775
 
776
align 4
777
start_link:
778
 
779
	; TODO: write working code here
780
 
781
	ret
782
 
1502 hidnplayr 783
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
784
;;                                         ;;
785
;; Send setup packet                       ;;
786
;;                                         ;;
787
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
788
 
789
align 4
790
Send_Setup_Packet:
791
 
792
	DEBUGF	1,"Sending setup packet\n"
793
 
794
; if no descriptors available, out
795
	mov	ecx, 1000
796
@@loop_wait_desc:
797
	cmp	[device.tx_free_des], 0
798
	jne	@f
799
 
800
	dec	ecx
801
	jnz	@@loop_wait_desc
802
 
803
	mov	eax, -1
804
	ret
805
      @@:
806
 
807
; go to current send descriptor
808
	mov	edi, [device.tx_p_des]
809
	mov	eax, [device.tx_wr_des]
810
	DEBUGF	1,"Got free descriptor: %u (%x)", eax, edi
811
	mov	edx, DES.size
812
	mul	edx
813
	add	edi, eax
814
	DEBUGF	1,"=>%x\n",  edi
815
 
816
; if NOT sending FIRST setup packet, must set current descriptor to 0 size for both buffers,
817
;  and go to next descriptor for real setup packet...            ;; TODO: check if 2 descriptors are available
818
 
819
;       cmp     [device.tx_packets], 0
820
;       je      .not_first
821
;
822
;       and     [edi+DES.des1], 0
823
;       mov     [edi+DES.des0], DES0_OWN
824
;
825
; go to next descriptor
826
;        inc     [device.tx_wr_des]
827
;        and     [device.tx_wr_des], TX_DES_COUNT-1
828
;
829
; dec free descriptors count
830
;        cmp     [device.tx_free_des], 0
831
;        jz      @f
832
;        dec     [device.tx_free_des]
833
;       @@:
834
;
835
;       ; recompute pointer to current descriptor
836
;       mov     edi, [device.tx_p_des]
837
;       mov     eax, [device.tx_wr_des]
838
;       mov     edx, DES.size
839
;       mul     edx
840
;       add     edi, eax
841
 
842
  .not_first:
843
 
844
	push	edi
845
; copy setup packet to current descriptor
846
	mov	edi, [edi+DES.realaddr]
847
; copy once the address
848
	lea	esi, [device.mac]
849
	DEBUGF	1,"copying packet to %x from %x\n", edi, esi
850
	mov	ecx, 3	; mac is 6 bytes thus 3 words
851
     .loop:
852
	DEBUGF	1,"%x ", [esi]:4
853
	movsw
854
	dec	esi
855
	dec	esi
856
	movsw
857
	dec	ecx
858
	jnz	.loop
859
 
860
	DEBUGF	1,"\n"
861
 
862
; copy 15 times the broadcast address
863
	mov	ecx, 3*15
864
	mov	eax, 0xffffffff
865
	rep	stosd
866
 
867
	pop	edi
868
 
869
; setup descriptor
870
	DEBUGF	1,"setting up descriptor\n"
871
	mov	[edi+DES.DES1], TDES1_IC+TDES1_SET+TDES1_TCH+192	; size must be EXACTLY 192 bytes
872
	mov	[edi+DES.DES0], DES0_OWN
873
 
874
	DEBUGF	1,"TDES0: %x\n", [edi+DES.DES0]:8
875
	DEBUGF	1,"TDES1: %x\n", [edi+DES.DES1]:8
876
	DEBUGF	1,"TDES2: %x\n", [edi+DES.DES2]:8
877
	DEBUGF	1,"TDES3: %x\n", [edi+DES.DES3]:8
878
 
879
; go to next descriptor
880
	inc	[device.tx_wr_des]
881
	and	[device.tx_wr_des], TX_DES_COUNT-1
882
 
883
; dec free descriptors count
884
	cmp	[device.tx_free_des], 0
885
	jz	@f
886
	dec	[device.tx_free_des]
887
       @@:
888
 
889
; start tx
890
	set_io	0
891
	status
892
	set_io	CSR6
893
	in	eax, dx
894
	test	eax, CSR6_ST		; if NOT started, start now
895
	jnz	.already_started
896
	or	eax, CSR6_ST
897
	DEBUGF	1,"Starting TX\n"
898
	jmp	.do_it
899
  .already_started:
900
					; if already started, issue a Transmit Poll command
901
	set_io	CSR1
902
	mov	eax, 0
903
	DEBUGF	1,"Issuing transmit poll command\n"
904
  .do_it:
905
	out	dx , eax
906
	status
907
 
908
	DEBUGF	1,"Sending setup packet, completed!\n"
909
 
910
	ret
911
 
912
 
913
 
914
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
915
;;                                         ;;
916
;; Transmit                                ;;
917
;;                                         ;;
918
;; In: buffer pointer in [esp+4]           ;;
919
;;     size of buffer in [esp+8]           ;;
920
;;     pointer to device structure in ebx  ;;
921
;;                                         ;;
922
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
923
 
924
align 4
925
transmit:
926
 
927
	DEBUGF	1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
928
	mov	eax, [esp+4]
929
	DEBUGF	1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
930
	[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
931
	[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
932
	[eax+13]:2,[eax+12]:2
933
 
934
	cmp	dword [esp+8], MAX_ETH_FRAME_SIZE
935
	ja	.fail
936
 
937
	cmp	[device.tx_free_des], 0
938
	je	.fail
939
 
940
;--------------------------
941
; copy packet to crt buffer
942
 
943
	mov	eax, [device.tx_wr_des]
944
	mov	edx, DES.size
945
	mul	edx
946
	add	eax, [device.tx_p_des]
947
	mov	edi, [eax+DES.realaddr] 		; pointer to buffer
948
	mov	esi, [esp+4]
949
	mov	ecx, [esp+8]
950
	DEBUGF	1,"copying %u bytes from %x to %x\n", ecx, esi, edi
951
	rep	movsb
952
 
953
; set packet size
954
	mov	ecx, [eax+DES.DES1]
955
	and	ecx, TDES1_TER				; preserve 'End of Ring' bit
956
	or	ecx, [esp+8]				; set size
957
	or	ecx, TDES1_FS or TDES1_LS or TDES1_IC or TDES1_TCH    ; first descr, last descr, interrupt on complete, chained modus
958
	mov	[eax+DES.DES1], ecx
959
 
960
; set descriptor info
961
	mov	[eax+DES.DES0], DES0_OWN		; say it is now owned by the 21x4x
962
 
963
; start tx
964
	set_io	0
965
	status
966
	set_io	CSR6
967
	in	eax, dx
968
	test	eax, CSR6_ST		; if NOT started, start now
969
	jnz	.already_started
970
	or	eax, CSR6_ST
971
	DEBUGF	1,"Starting TX\n"
972
	jmp	.do_it
973
  .already_started:
974
					; if already started, issues a Transmit Poll command
975
	set_io	CSR1
976
	mov	eax, -1
977
  .do_it:
978
	out	dx , eax
979
 
1503 hidnplayr 980
; Update stats
1502 hidnplayr 981
 
1503 hidnplayr 982
	inc	[device.packets_tx]
983
	mov	eax, [esp+8]
984
	add	dword [device.bytes_tx], eax
985
	adc	dword [device.bytes_tx + 4], 0
1502 hidnplayr 986
 
987
; go to next descriptor
988
	inc	[device.tx_wr_des]
989
	and	[device.tx_wr_des], TX_DES_COUNT-1
990
 
991
; dec free descriptors count
992
	test	[device.tx_free_des], -1
993
	jz	.end
994
	dec	[device.tx_free_des]
995
  .end:
996
	status
997
 
998
	DEBUGF	1,"transmit ok\n"
999
	xor	eax, eax
1000
	ret
1001
 
1002
  .fail:
1003
	DEBUGF	1,"transmit failed\n"
1004
	or	eax, -1
1005
	ret
1006
 
1007
 
1008
 
1009
;;;;;;;;;;;;;;;;;;;;;;;
1010
;;                   ;;
1011
;; Interrupt handler ;;
1012
;;                   ;;
1013
;;;;;;;;;;;;;;;;;;;;;;;
1014
 
1015
align 4
1016
int_handler:
1017
 
1018
	DEBUGF	1,"IRQ %x ",eax:2			; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
1019
 
1020
; find pointer of device wich made IRQ occur
1021
 
1022
	mov	ecx, [devices]
1023
	test	ecx, ecx
1024
	jz	.fail
1025
	mov	esi, DEVICE_LIST
1026
  .nextdevice:
1027
	mov	ebx, dword [esi]
1028
 
1029
	set_io	0
1030
	set_io	CSR5
1031
	in	eax, dx
1032
	out	dx , eax				; send it back to ACK
1033
 
1034
	and	eax, CSR7_DEFAULT			; int mask
1035
	test	eax, eax
1036
	jnz	.got_it
1037
 
1038
  .continue:
1039
	add	esi, 4
1040
	dec	ecx
1041
	jnz	.nextdevice
1042
 
1043
	ret						; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1044
 
1045
  .got_it:
1046
 
1047
	DEBUGF	1,"CSR7: %x ", eax
1048
 
1049
; looks like we've found it!
1050
 
1051
; Lets found out why the irq occured then..
1052
 
1053
;----------------------------------
1054
; TX ok?
1055
 
1056
	test	eax, CSR5_TI
1057
	jz	.not_tx
1058
	push	ax esi ecx
1059
 
1060
	DEBUGF 1,"TX ok!\n"
1061
 
1062
	; go to current descriptor
1063
	mov	edi, [device.tx_p_des]
1064
 
1065
	mov	eax, [device.tx_rd_des]
1066
	mov	edx, DES.size
1067
	mul	edx
1068
	add	edi, eax
1069
 
1070
      .loop_tx:
1071
 
1072
	; done if all desc are free
1073
	cmp	[device.tx_free_des], TX_DES_COUNT
1074
	jz	.end_tx
1075
 
1076
	mov	eax, [edi+DES.DES0]
1077
 
1078
	; we stop at first desc that is owned be NIC
1079
	test	eax, DES0_OWN
1080
	jnz	.end_tx
1081
 
1082
	; detect is setup packet
1083
	cmp	eax, (0ffffffffh - DES0_OWN)		; all other bits are 1
1084
	jne	.not_setup_packet
1085
	DEBUGF	1,"Setup Packet detected\n"
1086
      .not_setup_packet:
1087
 
1088
	DEBUGF	1,"packet status: %x\n", eax
1089
 
1090
	; next descriptor
1091
	add	edi, DES.size
1092
	inc	[device.tx_rd_des]
1093
	and	[device.tx_rd_des], TX_DES_COUNT-1
1094
 
1095
	; inc free desc
1096
	inc	[device.tx_free_des]
1097
	cmp	[device.tx_free_des], TX_DES_COUNT
1098
	jle	@f
1099
	mov	[device.tx_free_des], TX_DES_COUNT
1100
       @@:
1101
 
1102
	jmp	.loop_tx
1103
      .end_tx:
1104
 
1105
	;------------------------------------------------------
1106
	; here must be called standard Ethernet Tx Irq Handler
1107
	;------------------------------------------------------
1108
 
1109
	pop	ecx esi ax
1110
 
1111
;----------------------------------
1112
; RX irq
1113
  .not_tx:
1114
	test	eax, CSR5_RI
1115
	jz	.not_rx
1116
	push	ax esi ecx
1117
 
1118
	DEBUGF 1,"RX ok!\n"
1119
 
1120
	;go to current descriptor
1121
	mov	edi, [device.rx_p_des]
1122
 
1123
	mov	eax, [device.rx_crt_des]
1124
	mov	edx, DES.size
1125
	mul	edx
1126
	add	edi, eax
1127
 
1128
      .loop_rx_start_of_packet:
1129
	mov	eax, [edi+DES.DES0]
1130
 
1131
	test	eax, DES0_OWN
1132
	jnz	.end_rx 				; current desc is busy, nothing to do
1133
 
1134
	test	eax, RDES0_FS
1135
	jz	.end_rx 				; current desc is NOT first packet, ERROR!
1136
 
1137
	test	eax, RDES0_LS				; if not last desc of packet, error for now
1138
	jz	.end_rx
1139
 
1140
;        .IF     ZERO?
1141
;                ODS2 <"Net_Interrupt: packet > 1 descriptor, not supported yet :P">
1142
;                jmp     @@end_rx
1143
;        .ENDIF
1144
 
1145
	test	eax, RDES0_ES
1146
	jnz	.end_rx
1147
 
1148
;        .IF     !ZERO?
1149
;                ODS2 <"Net_Interrupt: RX error">
1150
;                jmp     @@end_rx
1151
;        .ENDIF
1152
 
1153
	mov	esi, [edi+DES.realaddr]
1154
	mov	ecx, [edi+DES.DES0]
1155
	shr	ecx, RDES0_FL_SH
1156
	and	ecx, RDES0_FL_MASK
1157
	sub	ecx, 4					 ; crc
1158
 
1159
	DEBUGF	1,"Received packet!, size=%u, addr:%x\n", ecx, esi
1160
 
1161
	push	esi edi ecx
1162
	stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
1163
	pop	ecx edi esi
1164
	test	eax, eax
1165
	jz	.fail
1166
 
1167
	push	edi
1168
	push	dword .continue_rx
1169
	push	ecx eax
1170
	mov	edi, eax
1171
 
1172
; update statistics
1173
	inc	[device.packets_rx]
1174
 
1175
	add	dword [device.bytes_rx], ecx
1176
	adc	dword [device.bytes_rx + 4], 0
1177
 
1178
; copy packet data
1179
	shr	cx , 1
1180
	jnc	.nb
1181
	movsb
1182
  .nb:
1183
	shr	cx , 1
1184
	jnc	.nw
1185
	movsw
1186
  .nw:
1187
	rep	movsd
1188
 
1189
	jmp	EthReceiver
1190
 
1191
    .continue_rx:
1192
	pop	edi
1193
 
1194
	; free descriptor
1195
	mov	[edi+DES.DES0], DES0_OWN
1196
 
1197
	; next descriptor
1198
	add	edi, DES.size
1199
 
1200
	inc	[device.rx_crt_des]
1201
	and	[device.rx_crt_des], RX_DES_COUNT-1
1202
 
1203
	jmp	.loop_rx_start_of_packet
1204
 
1205
      .end_rx:
1206
      .fail:
1207
	pop	ecx esi ax
1208
      .not_rx:
1209
 
1210
	jmp	.continue
1211
 
1212
 
1213
 
1214
align 4
1215
write_mac:	; in: mac pushed onto stack (as 3 words)
1216
 
1217
	DEBUGF	2,"Writing MAC: "
1218
 
1219
; write data into driver cache
1220
	mov	esi, esp
1221
	lea	edi, [device.mac]
1222
	movsd
1223
	movsw
1224
	add	esp, 6
1225
 
1226
; send setup packet (only if driver is started)
1227
	call	Send_Setup_Packet
1228
 
1229
align 4
1230
read_mac:
1231
 
1232
	DEBUGF 1,"Read_mac\n"
1233
 
1234
	ret
1235
 
1236
 
1237
 
1238
align 4
1239
read_mac_eeprom:
1240
 
1241
	DEBUGF 1,"Read_mac_eeprom\n"
1242
 
1243
	lea	edi, [device.mac]
1244
	mov	esi, 20/2		; read words, start address is 20
1245
     .loop:
1246
	push	esi edi
1247
	call	SROM_Read_Word
1248
	pop	edi esi
1249
	stosw
1250
	inc	esi
1251
	cmp	esi, 26/2
1252
	jl	.loop
1253
 
1254
	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
1255
 
1256
	ret
1257
 
1258
align 4
1259
write_mac_eeprom:
1260
 
1261
	DEBUGF 1,"Write_mac_eeprom\n"
1262
 
1263
	ret
1264
 
1265
 
1266
align 4
1267
SROM_GetWidth:	; should be 6 or 8 according to some manuals (returns in ecx)
1268
 
1269
	DEBUGF 1,"SROM_GetWidth\n"
1270
 
1271
	call	SROM_Idle
1272
	call	SROM_EnterAccessMode
1273
 
1274
;        set_io  0
1275
;        set_io  CSR9
1276
 
1277
	; send 110b
1278
 
1279
	in	eax, dx
1280
	or	eax, CSR9_SROM_DI
1281
	call	SROM_out
1282
 
1283
	in	eax, dx
1284
	or	eax, CSR9_SROM_DI
1285
	call	SROM_out
1286
 
1287
	in	eax, dx
1288
	and	eax, not (CSR9_SROM_DI)
1289
	call	SROM_out
1290
 
1291
	mov	ecx,1
1292
  .loop2:
1293
	Bit_Set CSR9_SROM_CK
1294
	SROM_Delay
1295
 
1296
	in	eax, dx
1297
	and	eax, CSR9_SROM_DO
1298
	jnz	.not_zero
1299
 
1300
	Bit_Clear CSR9_SROM_CK
1301
	SROM_Delay
1302
	jmp	.end_loop2
1303
  .not_zero:
1304
 
1305
	Bit_Clear CSR9_SROM_CK
1306
	SROM_Delay
1307
 
1308
	inc	ecx
1309
	cmp	ecx, 12
1310
	jle	.loop2
1311
  .end_loop2:
1312
 
1313
	DEBUGF 1,"Srom width=%u\n", ecx
1314
 
1315
	call	SROM_Idle
1316
	call	SROM_EnterAccessMode
1317
	call	SROM_Idle
1318
 
1319
	ret
1320
 
1321
 
1322
align 4
1323
SROM_out:
1324
 
1325
	out	dx, eax
1326
	SROM_Delay
1327
	Bit_Set CSR9_SROM_CK
1328
	SROM_Delay
1329
	Bit_Clear CSR9_SROM_CK
1330
	SROM_Delay
1331
 
1332
	ret
1333
 
1334
 
1335
 
1336
align 4
1337
SROM_EnterAccessMode:
1338
 
1339
	DEBUGF 1,"SROM_EnterAccessMode\n"
1340
 
1341
	set_io	0
1342
	set_io	CSR9
1343
	mov	eax, CSR9_SR
1344
	out	dx, eax
1345
	SROM_Delay
1346
 
1347
	Bit_Set CSR9_RD
1348
	SROM_Delay
1349
 
1350
	Bit_Clear CSR9_SROM_CK
1351
	SROM_Delay
1352
 
1353
	Bit_Set CSR9_SROM_CS
1354
	SROM_Delay
1355
 
1356
	ret
1357
 
1358
 
1359
 
1360
align 4
1361
SROM_Idle:
1362
 
1363
	DEBUGF 1,"SROM_Idle\n"
1364
 
1365
	call	SROM_EnterAccessMode
1366
 
1367
;        set_io  0
1368
;        set_io  CSR9
1369
 
1370
	mov	ecx, 25
1371
     .loop_clk:
1372
 
1373
	Bit_Clear CSR9_SROM_CK
1374
	SROM_Delay
1375
	Bit_Set CSR9_SROM_CK
1376
	SROM_Delay
1377
 
1378
	dec	ecx
1379
	jnz	.loop_clk
1380
 
1381
 
1382
	Bit_Clear CSR9_SROM_CK
1383
	SROM_Delay
1384
	Bit_Clear CSR9_SROM_CS
1385
	SROM_Delay
1386
 
1387
	xor	eax, eax
1388
	out	dx, eax
1389
 
1390
	ret
1391
 
1392
 
1393
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1394
;;                                                                      ;;
1395
;; Read serial EEprom word                                              ;;
1396
;;                                                                      ;;
1397
;; In: esi = read address                                               ;;
1398
;; OUT: ax = data word                                                  ;;
1399
;;                                                                      ;;
1400
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1401
align 4
1402
SROM_Read_Word:
1403
 
1404
	DEBUGF 1,"SROM_Read_word at: %x result: ", esi
1405
 
1406
	set_io	0
1407
	set_io	CSR9
1408
 
1409
; enter access mode
1410
	mov	eax, CSR9_SR + CSR9_RD
1411
	out	dx , eax
1412
	or	eax, CSR9_SROM_CS
1413
	out	dx , eax
1414
 
1415
	; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
1416
 
1417
; send read command "110b" + address to read from
1418
	and	esi, 111111b
1419
	or	esi, 110b shl 6
1420
 
1421
	mov	ecx, 1 shl 9
1422
  .loop_cmd:
1423
	mov	eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1424
	test	esi, ecx
1425
	jz	@f
1426
	or	eax, CSR9_SROM_DI
1427
       @@:
1428
	out	dx , eax
1429
	SROM_Delay
1430
	or	eax, CSR9_SROM_CK
1431
	out	dx , eax
1432
	SROM_Delay
1433
 
1434
	shr	ecx, 1
1435
	jnz	.loop_cmd
1436
 
1437
; read data from SROM
1438
 
1439
	xor	esi, esi
1440
	mov	ecx, 17 ;;; TODO: figure out why 17, not 16
1441
  .loop_read:
1442
 
1443
	mov	eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
1444
	out	dx , eax
1445
	SROM_Delay
1446
 
1447
	in	eax, dx
1448
	and	eax, CSR9_SROM_DO
1449
	shr	eax, 3
1450
	shl	esi, 1
1451
	or	esi, eax
1452
 
1453
	mov	eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1454
	out	dx , eax
1455
	SROM_Delay
1456
 
1457
	dec	ecx
1458
	jnz	.loop_read
1459
 
1460
	mov	eax, esi
1461
 
1462
	DEBUGF 1,"%x\n", ax
1463
 
1464
	ret
1465
 
1466
 
1503 hidnplayr 1467
 
1468
 
1469
 
1470
 
1471
 
1472
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1473
 
1474
 
1475
 
1476
;*********************************************************************
1477
;* Media Descriptor Code                                             *
1478
;*********************************************************************
1479
 
1480
; MII transceiver control section.
1481
; Read and write the MII registers using software-generated serial
1482
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1483
; for details.
1484
 
1485
; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
1486
; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
1487
; "overclocking" issues or future 66Mhz PCI.
1488
 
1489
; Read and write the MII registers using software-generated serial
1490
; MDIO protocol.  It is just different enough from the EEPROM protocol
1491
; to not share code.  The maxium data clock rate is 2.5 Mhz.
1492
 
1493
MDIO_SHIFT_CLK		equ	0x10000
1494
MDIO_DATA_WRITE0	equ	0x00000
1495
MDIO_DATA_WRITE1	equ	0x20000
1496
MDIO_ENB		equ	0x00000 	; Ignore the 0x02000 databook setting.
1497
MDIO_ENB_IN		equ	0x40000
1498
MDIO_DATA_READ		equ	0x80000
1499
 
1500
; MII transceiver control section.
1501
; Read and write the MII registers using software-generated serial
1502
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1503
; for details.
1504
 
1505
align 4
1506
mdio_read:	; phy_id:edx, location:esi
1507
 
1508
	DEBUGF	1,"mdio read, phy=%x, location=%x", edx, esi
1509
 
1510
	shl	edx, 5
1511
	or	esi, edx
1512
	or	esi, 0xf6 shl 10
1513
 
1514
	set_io	0
1515
	set_io	CSR9
1516
 
1517
;    if (tp->chip_id == LC82C168) {
1518
;        int i = 1000;
1519
;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
1520
;        inl(ioaddr + 0xA0);
1521
;        inl(ioaddr + 0xA0);
1522
;        while (--i > 0)
1523
;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
1524
;                return retval & 0xffff;
1525
;        return 0xffff;
1526
;    }
1527
;
1528
;    if (tp->chip_id == COMET) {
1529
;        if (phy_id == 1) {
1530
;            if (location < 7)
1531
;                return inl(ioaddr + 0xB4 + (location<<2));
1532
;            else if (location == 17)
1533
;                return inl(ioaddr + 0xD0);
1534
;            else if (location >= 29 && location <= 31)
1535
;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
1536
;        }
1537
;        return 0xffff;
1538
;    }
1539
 
1540
; Establish sync by sending at least 32 logic ones.
1541
 
1542
	mov	ecx, 32
1543
  .loop:
1544
	mov	eax, MDIO_ENB or MDIO_DATA_WRITE1
1545
	out	dx, eax
1546
	MDIO_Delay
1547
 
1548
	or	eax, MDIO_SHIFT_CLK
1549
	out	dx, eax
1550
	MDIO_Delay
1551
 
1552
	dec	ecx
1553
	jnz	.loop
1554
 
1555
 
1556
; Shift the read command bits out.
1557
 
1558
	mov	ecx, 1 shl 15
1559
  .loop2:
1560
	mov	eax, MDIO_ENB
1561
	test	esi, ecx
1562
	jz	@f
1563
	or	eax, MDIO_DATA_WRITE1
1564
       @@:
1565
	out	dx, eax
1566
	MDIO_Delay
1567
 
1568
	or	eax, MDIO_SHIFT_CLK
1569
	out	dx, eax
1570
	MDIO_Delay
1571
 
1572
	shr	ecx, 1
1573
	jnz	.loop2
1574
 
1575
 
1576
; Read the two transition, 16 data, and wire-idle bits.
1577
 
1578
	xor	esi, esi
1579
	mov	ecx, 19
1580
  .loop3:
1581
	mov	eax, MDIO_ENB_IN
1582
	out	dx, eax
1583
	MDIO_Delay
1584
 
1585
	shl	esi, 1
1586
	in	eax, dx
1587
	test	eax, MDIO_DATA_READ
1588
	jz	@f
1589
	inc	esi
1590
       @@:
1591
 
1592
	mov	eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
1593
	out	dx, eax
1594
	MDIO_Delay
1595
 
1596
	dec	ecx
1597
	jnz	.loop3
1598
 
1599
	shr	esi, 1
1600
	movzx	eax, si
1601
 
1602
	DEBUGF	1,", data=%x\n", ax
1603
 
1604
	ret
1605
 
1606
 
1607
 
1608
 
1609
align 4
1610
mdio_write:	;int phy_id: edx, int location: edi, int value: ax)
1611
 
1612
	DEBUGF	1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
1613
 
1614
	shl	edi, 18
1615
	or	edi, 0x5002 shl 16
1616
	shl	edx, 23
1617
	or	edi, edx
1618
	mov	di, ax
1619
 
1620
	set_io	0
1621
	set_io	CSR9
1622
 
1623
;    if (tp->chip_id == LC82C168) {
1624
;        int i = 1000;
1625
;        outl(cmd, ioaddr + 0xA0);
1626
;        do
1627
;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
1628
;                break;
1629
;        while (--i > 0);
1630
;        return;
1631
;    }
1632
 
1633
;    if (tp->chip_id == COMET) {
1634
;        if (phy_id != 1)
1635
;            return;
1636
;        if (location < 7)
1637
;            outl(value, ioaddr + 0xB4 + (location<<2));
1638
;        else if (location == 17)
1639
;            outl(value, ioaddr + 0xD0);
1640
;        else if (location >= 29 && location <= 31)
1641
;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
1642
;        return;
1643
;    }
1644
 
1645
 
1646
; Establish sync by sending at least 32 logic ones.
1647
 
1648
	mov	ecx, 32
1649
  .loop:
1650
	mov	eax, MDIO_ENB or MDIO_DATA_WRITE1
1651
	out	dx, eax
1652
	MDIO_Delay
1653
 
1654
	or	eax, MDIO_SHIFT_CLK
1655
	out	dx, eax
1656
	MDIO_Delay
1657
 
1658
	dec	ecx
1659
	jnz	.loop
1660
 
1661
 
1662
; Shift the command bits out.
1663
 
1664
	mov	ecx, 1 shl 31
1665
  .loop2:
1666
	mov	eax, MDIO_ENB
1667
	test	edi, ecx
1668
	jz	@f
1669
	or	eax, MDIO_DATA_WRITE1
1670
       @@:
1671
	out	dx, eax
1672
	MDIO_Delay
1673
 
1674
	or	eax, MDIO_SHIFT_CLK
1675
	out	dx, eax
1676
	MDIO_Delay
1677
 
1678
	shr	ecx, 1
1679
	jnz	.loop2
1680
 
1681
 
1682
; Clear out extra bits.
1683
 
1684
	mov	ecx, 2
1685
  .loop3:
1686
	mov	eax, MDIO_ENB
1687
	out	dx, eax
1688
	MDIO_Delay
1689
 
1690
	or	eax, MDIO_SHIFT_CLK
1691
	out	dx, eax
1692
	MDIO_Delay
1693
 
1694
	dec	ecx
1695
	jnz	.loop3
1696
 
1697
	ret
1698
 
1699
 
1502 hidnplayr 1700
; End of code
1701
 
1702
align 4 					; Place all initialised data here
1703
 
1704
devices       dd 0
1705
version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
1706
my_service    db 'DEC21X4X',0			 ; max 16 chars include zero
1707
 
1708
include_debug_strings				; All data wich FDO uses will be included here
1709
 
1710
section '.data' data readable writable align 16 ; place all uninitialized data place here
1711
 
1712
DEVICE_LIST rd MAX_DEVICES		       ; This list contains all pointers to device structures the driver is handling
1713
 
1714