Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * Etherlink III, Fast EtherLink and Fast EtherLink XL adapters.
3
 * To do:
4
 *	check robustness in the face of errors (e.g. busmaster & rxUnderrun);
5
 *	RxEarly and busmaster;
6
 *	autoSelect;
7
 *	PCI latency timer and master enable;
8
 *	errata list;
9
 *	rewrite all initialisation.
10
 */
11
#include "u.h"
12
#include "../port/lib.h"
13
#include "mem.h"
14
#include "dat.h"
15
#include "fns.h"
16
#include "io.h"
17
#include "../port/error.h"
18
#include "../port/netif.h"
19
 
20
#include "etherif.h"
21
 
22
#define XCVRDEBUG		if(0)print
23
 
24
enum {
25
	IDport			= 0x0110,	/* anywhere between 0x0100 and 0x01F0 */
26
};
27
 
28
enum {						/* all windows */
29
	CommandR		= 0x000E,
30
	IntStatusR		= 0x000E,
31
};
32
 
33
enum {						/* Commands */
34
	GlobalReset		= 0x0000,
35
	SelectRegisterWindow	= 0x0001,
36
	EnableDcConverter	= 0x0002,
37
	RxDisable		= 0x0003,
38
	RxEnable		= 0x0004,
39
	RxReset			= 0x0005,
40
	Stall			= 0x0006,	/* 3C90x */
41
	TxDone			= 0x0007,
42
	RxDiscard		= 0x0008,
43
	TxEnable		= 0x0009,
44
	TxDisable		= 0x000A,
45
	TxReset			= 0x000B,
46
	RequestInterrupt	= 0x000C,
47
	AcknowledgeInterrupt	= 0x000D,
48
	SetInterruptEnable	= 0x000E,
49
	SetIndicationEnable	= 0x000F,	/* SetReadZeroMask */
50
	SetRxFilter		= 0x0010,
51
	SetRxEarlyThresh	= 0x0011,
52
	SetTxAvailableThresh	= 0x0012,
53
	SetTxStartThresh	= 0x0013,
54
	StartDma		= 0x0014,	/* initiate busmaster operation */
55
	StatisticsEnable	= 0x0015,
56
	StatisticsDisable	= 0x0016,
57
	DisableDcConverter	= 0x0017,
58
	SetTxReclaimThresh	= 0x0018,	/* PIO-only adapters */
59
	PowerUp			= 0x001B,	/* not all adapters */
60
	PowerDownFull		= 0x001C,	/* not all adapters */
61
	PowerAuto		= 0x001D,	/* not all adapters */
62
};
63
 
64
enum {						/* (Global|Rx|Tx)Reset command bits */
65
	tpAuiReset		= 0x0001,	/* 10BaseT and AUI transceivers */
66
	endecReset		= 0x0002,	/* internal Ethernet encoder/decoder */
67
	networkReset		= 0x0004,	/* network interface logic */
68
	fifoReset		= 0x0008,	/* FIFO control logic */
69
	aismReset		= 0x0010,	/* autoinitialise state-machine logic */
70
	hostReset		= 0x0020,	/* bus interface logic */
71
	dmaReset		= 0x0040,	/* bus master logic */
72
	vcoReset		= 0x0080,	/* on-board 10Mbps VCO */
73
	updnReset		= 0x0100,	/* upload/download (Rx/TX) logic */
74
 
75
	resetMask		= 0x01FF,
76
};
77
 
78
enum {						/* Stall command bits */
79
	upStall			= 0x0000,
80
	upUnStall		= 0x0001,
81
	dnStall			= 0x0002,
82
	dnUnStall		= 0x0003,
83
};
84
 
85
enum {						/* SetRxFilter command bits */
86
	receiveIndividual	= 0x0001,	/* match station address */
87
	receiveMulticast	= 0x0002,
88
	receiveBroadcast	= 0x0004,
89
	receiveAllFrames	= 0x0008,	/* promiscuous */
90
};
91
 
92
enum {						/* StartDma command bits */
93
	Upload			= 0x0000,	/* transfer data from adapter to memory */
94
	Download		= 0x0001,	/* transfer data from memory to adapter */
95
};
96
 
97
enum {						/* IntStatus bits */
98
	interruptLatch		= 0x0001,
99
	hostError		= 0x0002,	/* Adapter Failure */
100
	txComplete		= 0x0004,
101
	txAvailable		= 0x0008,
102
	rxComplete		= 0x0010,
103
	rxEarly			= 0x0020,
104
	intRequested		= 0x0040,
105
	updateStats		= 0x0080,
106
	transferInt		= 0x0100,	/* Bus Master Transfer Complete */
107
	dnComplete		= 0x0200,
108
	upComplete		= 0x0400,
109
	busMasterInProgress	= 0x0800,
110
	commandInProgress	= 0x1000,
111
 
112
	interruptMask		= 0x07FE,
113
};
114
 
115
#define COMMAND(port, cmd, a)	outs((port)+CommandR, ((cmd)<<11)|(a))
116
#define STATUS(port)		ins((port)+IntStatusR)
117
 
118
enum {						/* Window 0 - setup */
119
	Wsetup			= 0x0000,
120
						/* registers */
121
	ManufacturerID		= 0x0000,	/* 3C5[08]*, 3C59[27] */
122
	ProductID		= 0x0002,	/* 3C5[08]*, 3C59[27] */
123
	ConfigControl		= 0x0004,	/* 3C5[08]*, 3C59[27] */
124
	AddressConfig		= 0x0006,	/* 3C5[08]*, 3C59[27] */
125
	ResourceConfig		= 0x0008,	/* 3C5[08]*, 3C59[27] */
126
	EepromCommand		= 0x000A,
127
	EepromData		= 0x000C,
128
						/* AddressConfig Bits */
129
	autoSelect9		= 0x0080,
130
	xcvrMask9		= 0xC000,
131
						/* ConfigControl bits */
132
	Ena			= 0x0001,
133
	base10TAvailable9	= 0x0200,
134
	coaxAvailable9		= 0x1000,
135
	auiAvailable9		= 0x2000,
136
						/* EepromCommand bits */
137
	EepromReadRegister	= 0x0080,
138
	EepromReadOffRegister	= 0x00B0,
139
	EepromRead8bRegister	= 0x0230,
140
	EepromBusy		= 0x8000,
141
};
142
 
143
#define EEPROMCMD(port, cmd, a)	outs((port)+EepromCommand, (cmd)|(a))
144
#define EEPROMBUSY(port)	(ins((port)+EepromCommand) & EepromBusy)
145
#define EEPROMDATA(port)	ins((port)+EepromData)
146
 
147
enum {						/* Window 1 - operating set */
148
	Wop			= 0x0001,
149
						/* registers */
150
	Fifo			= 0x0000,
151
	RxError			= 0x0004,	/* 3C59[0257] only */
152
	RxStatus		= 0x0008,
153
	TIMER			= 0x000A,
154
	TxStatus		= 0x000B,
155
	TxFree			= 0x000C,
156
						/* RxError bits */
157
	rxOverrun		= 0x0001,
158
	runtFrame		= 0x0002,
159
	alignmentError		= 0x0004,	/* Framing */
160
	crcError		= 0x0008,
161
	oversizedFrame		= 0x0010,
162
	dribbleBits		= 0x0080,
163
						/* RxStatus bits */
164
	rxBytes			= 0x1FFF,	/* 3C59[0257] mask */
165
	rxBytes9		= 0x07FF,	/* 3C5[078]9 mask */
166
	rxError9		= 0x3800,	/* 3C5[078]9 error mask */
167
	rxOverrun9		= 0x0000,
168
	oversizedFrame9		= 0x0800,
169
	dribbleBits9		= 0x1000,
170
	runtFrame9		= 0x1800,
171
	alignmentError9		= 0x2000,	/* Framing */
172
	crcError9		= 0x2800,
173
	rxError			= 0x4000,
174
	rxIncomplete		= 0x8000,
175
						/* TxStatus Bits */
176
	txStatusOverflow	= 0x0004,
177
	maxCollisions		= 0x0008,
178
	txUnderrun		= 0x0010,
179
	txJabber		= 0x0020,
180
	interruptRequested	= 0x0040,
181
	txStatusComplete	= 0x0080,
182
};
183
 
184
enum {						/* Window 2 - station address */
185
	Wstation		= 0x0002,
186
 
187
	ResetOp905B		= 0x000C,
188
};
189
 
190
enum {						/* Window 3 - FIFO management */
191
	Wfifo			= 0x0003,
192
						/* registers */
193
	InternalConfig		= 0x0000,	/* 3C509B, 3C589, 3C59[0257] */
194
	OtherInt		= 0x0004,	/* 3C59[0257] */
195
	RomControl		= 0x0006,	/* 3C509B, 3C59[27] */
196
	MacControl		= 0x0006,	/* 3C59[0257] */
197
	ResetOptions		= 0x0008,	/* 3C59[0257] */
198
	MediaOptions		= 0x0008,	/* 3C905B */
199
	RxFree			= 0x000A,
200
						/* InternalConfig bits */
201
	disableBadSsdDetect	= 0x00000100,
202
	ramLocation		= 0x00000200,	/* 0 external, 1 internal */
203
	ramPartition5to3	= 0x00000000,
204
	ramPartition3to1	= 0x00010000,
205
	ramPartition1to1	= 0x00020000,
206
	ramPartition3to5	= 0x00030000,
207
	ramPartitionMask	= 0x00030000,
208
	xcvr10BaseT		= 0x00000000,
209
	xcvrAui			= 0x00100000,	/* 10BASE5 */
210
	xcvr10Base2		= 0x00300000,
211
	xcvr100BaseTX		= 0x00400000,
212
	xcvr100BaseFX		= 0x00500000,
213
	xcvrMii			= 0x00600000,
214
	xcvrMask		= 0x00700000,
215
	autoSelect		= 0x01000000,
216
						/* MacControl bits */
217
	deferExtendEnable	= 0x0001,
218
	deferTIMERSelect	= 0x001E,	/* mask */
219
	fullDuplexEnable	= 0x0020,
220
	allowLargePackets	= 0x0040,
221
	extendAfterCollision	= 0x0080,	/* 3C90xB */
222
	flowControlEnable	= 0x0100,	/* 3C90xB */
223
	vltEnable		= 0x0200,	/* 3C90xB */
224
						/* ResetOptions bits */
225
	baseT4Available		= 0x0001,
226
	baseTXAvailable		= 0x0002,
227
	baseFXAvailable		= 0x0004,
228
	base10TAvailable	= 0x0008,
229
	coaxAvailable		= 0x0010,
230
	auiAvailable		= 0x0020,
231
	miiConnector		= 0x0040,
232
};
233
 
234
enum {						/* Window 4 - diagnostic */
235
	Wdiagnostic		= 0x0004,
236
						/* registers */
237
	VcoDiagnostic		= 0x0002,
238
	FifoDiagnostic		= 0x0004,
239
	NetworkDiagnostic	= 0x0006,
240
	PhysicalMgmt		= 0x0008,
241
	MediaStatus		= 0x000A,
242
	BadSSD			= 0x000C,
243
	UpperBytesOk		= 0x000D,
244
						/* FifoDiagnostic bits */
245
	txOverrun		= 0x0400,
246
	rxUnderrun		= 0x2000,
247
	receiving		= 0x8000,
248
						/* PhysicalMgmt bits */
249
	mgmtClk			= 0x0001,
250
	mgmtData		= 0x0002,
251
	mgmtDir			= 0x0004,
252
	cat5LinkTestDefeat	= 0x8000,
253
						/* MediaStatus bits */
254
	dataRate100		= 0x0002,
255
	crcStripDisable		= 0x0004,
256
	enableSqeStats		= 0x0008,
257
	collisionDetect		= 0x0010,
258
	carrierSense		= 0x0020,
259
	jabberGuardEnable	= 0x0040,
260
	linkBeatEnable		= 0x0080,
261
	jabberDetect		= 0x0200,
262
	polarityReversed	= 0x0400,
263
	linkBeatDetect		= 0x0800,
264
	txInProg		= 0x1000,
265
	dcConverterEnabled	= 0x4000,
266
	auiDisable		= 0x8000,	/* 10BaseT transceiver selected */
267
};
268
 
269
enum {						/* Window 5 - internal state */
270
	Wstate			= 0x0005,
271
						/* registers */
272
	TxStartThresh		= 0x0000,
273
	TxAvailableThresh	= 0x0002,
274
	RxEarlyThresh		= 0x0006,
275
	RxFilter		= 0x0008,
276
	InterruptEnable		= 0x000A,
277
	IndicationEnable	= 0x000C,
278
};
279
 
280
enum {						/* Window 6 - statistics */
281
	Wstatistics		= 0x0006,
282
						/* registers */
283
	CarrierLost		= 0x0000,
284
	SqeErrors		= 0x0001,
285
	MultipleColls		= 0x0002,
286
	SingleCollFrames	= 0x0003,
287
	LateCollisions		= 0x0004,
288
	RxOverruns		= 0x0005,
289
	FramesXmittedOk		= 0x0006,
290
	FramesRcvdOk		= 0x0007,
291
	FramesDeferred		= 0x0008,
292
	UpperFramesOk		= 0x0009,
293
	BytesRcvdOk		= 0x000A,
294
	BytesXmittedOk		= 0x000C,
295
};
296
 
297
enum {						/* Window 7 - bus master operations */
298
	Wmaster			= 0x0007,
299
						/* registers */
300
	MasterAddress		= 0x0000,
301
	MasterLen		= 0x0006,
302
	MasterStatus		= 0x000C,
303
						/* MasterStatus bits */
304
	masterAbort		= 0x0001,
305
	targetAbort		= 0x0002,
306
	targetRetry		= 0x0004,
307
	targetDisc		= 0x0008,
308
	masterDownload		= 0x1000,
309
	masterUpload		= 0x4000,
310
	masterInProgress	= 0x8000,
311
 
312
	masterMask		= 0xD00F,
313
};
314
 
315
enum {						/* 3C90x extended register set */
316
	TIMER905		= 0x001A,	/* 8-bits */
317
	TxStatus905		= 0x001B,	/* 8-bits */
318
	PktStatus		= 0x0020,	/* 32-bits */
319
	DnListPtr		= 0x0024,	/* 32-bits, 8-byte aligned */
320
	FragAddr		= 0x0028,	/* 32-bits */
321
	FragLen			= 0x002C,	/* 16-bits */
322
	ListOffset		= 0x002E,	/* 8-bits */
323
	TxFreeThresh		= 0x002F,	/* 8-bits */
324
	UpPktStatus		= 0x0030,	/* 32-bits */
325
	FreeTIMER		= 0x0034,	/* 16-bits */
326
	UpListPtr		= 0x0038,	/* 32-bits, 8-byte aligned */
327
 
328
						/* PktStatus bits */
329
	fragLast		= 0x00000001,
330
	dnCmplReq		= 0x00000002,
331
	dnStalled		= 0x00000004,
332
	upCompleteX		= 0x00000008,
333
	dnCompleteX		= 0x00000010,
334
	upRxEarlyEnable		= 0x00000020,
335
	armCountdown		= 0x00000040,
336
	dnInProg		= 0x00000080,
337
	counterSpeed		= 0x00000010,	/* 0 3.2uS, 1 320nS */
338
	countdownMode		= 0x00000020,
339
						/* UpPktStatus bits (dpd->control) */
340
	upPktLenMask		= 0x00001FFF,
341
	upStalled		= 0x00002000,
342
	upError			= 0x00004000,
343
	upPktComplete		= 0x00008000,
344
	upOverrun		= 0x00010000,	/* RxError<<16 */
345
	upRuntFrame		= 0x00020000,
346
	upAlignmentError	= 0x00040000,
347
	upCRCError		= 0x00080000,
348
	upOversizedFrame	= 0x00100000,
349
	upDribbleBits		= 0x00800000,
350
	upOverflow		= 0x01000000,
351
 
352
	dnIndicate		= 0x80000000,	/* FrameStartHeader (dpd->control) */
353
 
354
	updnLastFrag		= 0x80000000,	/* (dpd->len) */
355
 
356
	Nup			= 32,
357
	Ndn			= 64,
358
};
359
 
360
/*
361
 * Up/Dn Packet Descriptors.
362
 * The hardware info (np, control, addr, len) must be 8-byte aligned
363
 * and this structure size must be a multiple of 8.
364
 */
365
typedef struct Pd Pd;
366
typedef struct Pd {
367
	ulong	np;			/* next pointer */
368
	ulong	control;		/* FSH or UpPktStatus */
369
	ulong	addr;
370
	ulong	len;
371
 
372
	Pd*	next;
373
	Block*	bp;
374
} Pd;
375
 
376
typedef struct Ctlr Ctlr;
377
typedef struct Ctlr {
378
	int	port;
379
	Pcidev*	pcidev;
380
	int	irq;
381
	Ctlr*	next;
382
	int	active;
383
	int	did;
384
 
385
	Lock	wlock;			/* window access */
386
 
387
	int	attached;
388
	int	busmaster;
389
	Block*	rbp;			/* receive buffer */
390
 
391
	Block*	txbp;			/* FIFO -based transmission */
392
	int	txthreshold;
393
	int	txbusy;
394
 
395
	int	nup;			/* full-busmaster -based reception */
396
	void*	upbase;
397
	Pd*	upr;
398
	Pd*	uphead;
399
 
400
	int	ndn;			/* full-busmaster -based transmission */
401
	void*	dnbase;
402
	Pd*	dnr;
403
	Pd*	dnhead;
404
	Pd*	dntail;
405
	int	dnq;
406
 
407
	long	interrupts;		/* statistics */
408
	long	bogusinterrupts;
409
	long	timer[2];
410
	long	stats[BytesRcvdOk+3];
411
 
412
	int	upqmax;
413
	int	upqmaxhw;
414
	ulong	upinterrupts;
415
	ulong	upqueued;
416
	ulong	upstalls;
417
	int	dnqmax;
418
	int	dnqmaxhw;
419
	ulong	dninterrupts;
420
	ulong	dnqueued;
421
 
422
	int	xcvr;			/* transceiver type */
423
	int	eepromcmd;		/* EEPROM read command */
424
	int	rxstatus9;		/* old-style RxStatus register */
425
	int	rxearly;		/* RxEarlyThreshold */
426
	int	ts;			/* threshold shift */
427
	int	upenabled;
428
	int	dnenabled;
429
	ulong	cbfnpa;			/* CardBus functions */
430
	ulong*	cbfn;
431
} Ctlr;
432
 
433
static Ctlr* ctlrhead;
434
static Ctlr* ctlrtail;
435
 
436
static void
437
init905(Ctlr* ctlr)
438
{
439
	Block *bp;
440
	Pd *pd, *prev;
441
 
442
	/*
443
	 * Create rings for the receive and transmit sides.
444
	 * Take care with alignment:
445
	 *	make sure ring base is 8-byte aligned;
446
	 *	make sure each entry is 8-byte aligned.
447
	 */
448
	ctlr->upbase = malloc((ctlr->nup+1)*sizeof(Pd));
449
	if(ctlr->upbase == nil)
450
		error(Enomem);
451
	ctlr->upr = (Pd*)ROUNDUP((ulong)ctlr->upbase, 8);
452
 
453
	prev = ctlr->upr;
454
	for(pd = &ctlr->upr[ctlr->nup-1]; pd >= ctlr->upr; pd--){
455
		pd->np = PADDR(&prev->np);
456
		pd->control = 0;
457
		bp = iallocb(sizeof(Etherpkt));
458
		if(bp == nil)
459
			panic("can't allocate ethernet receive ring");
460
		pd->addr = PADDR(bp->rp);
461
		pd->len = updnLastFrag|sizeof(Etherpkt);
462
 
463
		pd->next = prev;
464
		prev = pd;
465
		pd->bp = bp;
466
	}
467
	ctlr->uphead = ctlr->upr;
468
 
469
	ctlr->dnbase = malloc((ctlr->ndn+1)*sizeof(Pd));
470
	if(ctlr->dnbase == nil) {
471
		free(ctlr->upbase);
472
		error(Enomem);
473
	}
474
	ctlr->dnr = (Pd*)ROUNDUP((ulong)ctlr->dnbase, 8);
475
 
476
	prev = ctlr->dnr;
477
	for(pd = &ctlr->dnr[ctlr->ndn-1]; pd >= ctlr->dnr; pd--){
478
		pd->next = prev;
479
		prev = pd;
480
	}
481
	ctlr->dnhead = ctlr->dnr;
482
	ctlr->dntail = ctlr->dnr;
483
	ctlr->dnq = 0;
484
}
485
 
486
static Block*
487
rbpalloc(Block* (*f)(int))
488
{
489
	Block *bp;
490
	ulong addr;
491
 
492
	/*
493
	 * The receive buffers must be on a 32-byte
494
	 * boundary for EISA busmastering.
495
	 */
496
	if(bp = f(ROUNDUP(sizeof(Etherpkt), 4) + 31)){
497
		addr = (ulong)bp->base;
498
		addr = ROUNDUP(addr, 32);
499
		bp->rp = (uchar*)addr;
500
	}
501
 
502
	return bp;
503
}
504
 
505
static uchar*
506
startdma(Ether* ether, ulong address)
507
{
508
	int port, status, w;
509
	uchar *wp;
510
 
511
	port = ether->port;
512
 
513
	w = (STATUS(port)>>13) & 0x07;
514
	COMMAND(port, SelectRegisterWindow, Wmaster);
515
 
516
	wp = KADDR(inl(port+MasterAddress));
517
	status = ins(port+MasterStatus);
518
	if(status & (masterInProgress|targetAbort|masterAbort))
519
		print("#l%d: BM status 0x%uX\n", ether->ctlrno, status);
520
	outs(port+MasterStatus, masterMask);
521
	outl(port+MasterAddress, address);
522
	outs(port+MasterLen, sizeof(Etherpkt));
523
	COMMAND(port, StartDma, Upload);
524
 
525
	COMMAND(port, SelectRegisterWindow, w);
526
	return wp;
527
}
528
 
529
static void
530
promiscuous(void* arg, int on)
531
{
532
	int filter, port;
533
	Ether *ether;
534
 
535
	ether = (Ether*)arg;
536
	port = ether->port;
537
 
538
	filter = receiveBroadcast|receiveIndividual;
539
	if(ether->nmaddr)
540
		filter |= receiveMulticast;
541
	if(on)
542
		filter |= receiveAllFrames;
543
	COMMAND(port, SetRxFilter, filter);
544
}
545
 
546
static void
547
multicast(void* arg, uchar *addr, int on)
548
{
549
	int filter, port;
550
	Ether *ether;
551
 
552
	USED(addr, on);
553
 
554
	ether = (Ether*)arg;
555
	port = ether->port;
556
 
557
	filter = receiveBroadcast|receiveIndividual;
558
	if(ether->nmaddr)
559
		filter |= receiveMulticast;
560
	if(ether->prom)
561
		filter |= receiveAllFrames;
562
	COMMAND(port, SetRxFilter, filter);
563
}
564
 
565
/* On the 575B and C, interrupts need to be acknowledged in CardBus memory space */
566
static void
567
intrackcb(ulong *cbfn)
568
{
569
	cbfn[1] = 0x8000;
570
}
571
 
572
static void
573
attach(Ether* ether)
574
{
575
	int port, x;
576
	Ctlr *ctlr;
577
 
578
	ctlr = ether->ctlr;
579
	ilock(&ctlr->wlock);
580
	if(ctlr->attached){
581
		iunlock(&ctlr->wlock);
582
		return;
583
	}
584
 
585
	port = ether->port;
586
 
587
	/*
588
	 * Set the receiver packet filter for this and broadcast addresses,
589
	 * set the interrupt masks for all interrupts, enable the receiver
590
	 * and transmitter.
591
	 */
592
	promiscuous(ether, ether->prom);
593
 
594
	x = interruptMask;
595
	if(ctlr->busmaster == 1)
596
		x &= ~(rxEarly|rxComplete);
597
	else{
598
		if(ctlr->dnenabled)
599
			x &= ~transferInt;
600
		if(ctlr->upenabled)
601
			x &= ~(rxEarly|rxComplete);
602
	}
603
	COMMAND(port, SetIndicationEnable, x);
604
	COMMAND(port, SetInterruptEnable, x);
605
	COMMAND(port, RxEnable, 0);
606
	COMMAND(port, TxEnable, 0);
607
 
608
	/*
609
	 * If this is a CardBus card, acknowledge any interrupts.
610
	 */
611
	if(ctlr->cbfn != nil)
612
		intrackcb(ctlr->cbfn);
613
 
614
	/*
615
	 * Prime the busmaster channel for receiving directly into a
616
	 * receive packet buffer if necessary.
617
	 */
618
	if(ctlr->busmaster == 1)
619
		startdma(ether, PADDR(ctlr->rbp->rp));
620
	else{
621
		if(ctlr->upenabled)
622
			outl(port+UpListPtr, PADDR(&ctlr->uphead->np));
623
	}
624
 
625
	ctlr->attached = 1;
626
	iunlock(&ctlr->wlock);
627
}
628
 
629
static void
630
statistics(Ether* ether)
631
{
632
	int port, i, u, w;
633
	Ctlr *ctlr;
634
 
635
	port = ether->port;
636
	ctlr = ether->ctlr;
637
 
638
	/*
639
	 * 3C59[27] require a read between a PIO write and
640
	 * reading a statistics register.
641
	 */
642
	w = (STATUS(port)>>13) & 0x07;
643
	COMMAND(port, SelectRegisterWindow, Wstatistics);
644
	STATUS(port);
645
 
646
	for(i = 0; i < UpperFramesOk; i++)
647
		ctlr->stats[i] += inb(port+i) & 0xFF;
648
	u = inb(port+UpperFramesOk) & 0xFF;
649
	ctlr->stats[FramesXmittedOk] += (u & 0x30)<<4;
650
	ctlr->stats[FramesRcvdOk] += (u & 0x03)<<8;
651
	ctlr->stats[BytesRcvdOk] += ins(port+BytesRcvdOk) & 0xFFFF;
652
	ctlr->stats[BytesRcvdOk+1] += ins(port+BytesXmittedOk) & 0xFFFF;
653
 
654
	switch(ctlr->xcvr){
655
 
656
	case xcvrMii:
657
	case xcvr100BaseTX:
658
	case xcvr100BaseFX:
659
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
660
		STATUS(port);
661
		ctlr->stats[BytesRcvdOk+2] += inb(port+BadSSD);
662
		break;
663
	}
664
 
665
	COMMAND(port, SelectRegisterWindow, w);
666
}
667
 
668
static void
669
txstart(Ether* ether)
670
{
671
	int port, len;
672
	Ctlr *ctlr;
673
	Block *bp;
674
 
675
	port = ether->port;
676
	ctlr = ether->ctlr;
677
 
678
	/*
679
	 * Attempt to top-up the transmit FIFO. If there's room simply
680
	 * stuff in the packet length (unpadded to a dword boundary), the
681
	 * packet data (padded) and remove the packet from the queue.
682
	 * If there's no room post an interrupt for when there is.
683
	 * This routine is called both from the top level and from interrupt
684
	 * level and expects to be called with ctlr->wlock already locked
685
	 * and the correct register window (Wop) in place.
686
	 */
687
	for(;;){
688
		if(ctlr->txbp){
689
			bp = ctlr->txbp;
690
			ctlr->txbp = 0;
691
		}
692
		else{
693
			bp = qget(ether->oq);
694
			if(bp == nil)
695
				break;
696
		}
697
 
698
		len = ROUNDUP(BLEN(bp), 4);
699
		if(len+4 <= ins(port+TxFree)){
700
			outl(port+Fifo, BLEN(bp));
701
			outsl(port+Fifo, bp->rp, len/4);
702
 
703
			freeb(bp);
704
 
705
			ether->outpackets++;
706
		}
707
		else{
708
			ctlr->txbp = bp;
709
			if(ctlr->txbusy == 0){
710
				ctlr->txbusy = 1;
711
				COMMAND(port, SetTxAvailableThresh, len>>ctlr->ts);
712
			}
713
			break;
714
		}
715
	}
716
}
717
 
718
static void
719
txstart905(Ether* ether)
720
{
721
	Ctlr *ctlr;
722
	int port, stalled, timeo;
723
	Block *bp;
724
	Pd *pd;
725
 
726
	ctlr = ether->ctlr;
727
	port = ether->port;
728
 
729
	/*
730
	 * Free any completed packets.
731
	 */
732
	pd = ctlr->dntail;
733
	while(ctlr->dnq){
734
		if(PADDR(&pd->np) == inl(port+DnListPtr))
735
			break;
736
		if(pd->bp){
737
			freeb(pd->bp);
738
			pd->bp = nil;
739
		}
740
		ctlr->dnq--;
741
		pd = pd->next;
742
	}
743
	ctlr->dntail = pd;
744
 
745
	stalled = 0;
746
	while(ctlr->dnq < (ctlr->ndn-1)){
747
		bp = qget(ether->oq);
748
		if(bp == nil)
749
			break;
750
 
751
		pd = ctlr->dnhead->next;
752
		pd->np = 0;
753
		pd->control = dnIndicate|BLEN(bp);
754
		pd->addr = PADDR(bp->rp);
755
		pd->len = updnLastFrag|BLEN(bp);
756
		pd->bp = bp;
757
 
758
		if(stalled == 0 && ctlr->dnq && inl(port+DnListPtr)){
759
			COMMAND(port, Stall, dnStall);
760
			for(timeo = 100; (STATUS(port) & commandInProgress) && timeo; timeo--)
761
				;
762
			if(timeo == 0)
763
				print("#l%d: dnstall %d\n", ether->ctlrno, timeo);
764
			stalled = 1;
765
		}
766
 
767
		coherence();
768
		ctlr->dnhead->np = PADDR(&pd->np);
769
		ctlr->dnhead->control &= ~dnIndicate;
770
		ctlr->dnhead = pd;
771
		if(ctlr->dnq == 0)
772
			ctlr->dntail = pd;
773
		ctlr->dnq++;
774
 
775
		ctlr->dnqueued++;
776
	}
777
 
778
	if(ctlr->dnq > ctlr->dnqmax)
779
		ctlr->dnqmax = ctlr->dnq;
780
 
781
	/*
782
	 * If the adapter is not currently processing anything
783
	 * and there is something on the queue, start it processing.
784
	 */
785
	if(inl(port+DnListPtr) == 0 && ctlr->dnq)
786
		outl(port+DnListPtr, PADDR(&ctlr->dnhead->np));
787
	if(stalled)
788
		COMMAND(port, Stall, dnUnStall);
789
}
790
 
791
static void
792
transmit(Ether* ether)
793
{
794
	Ctlr *ctlr;
795
	int port, w;
796
 
797
	port = ether->port;
798
	ctlr = ether->ctlr;
799
 
800
	ilock(&ctlr->wlock);
801
	if(ctlr->dnenabled)
802
		txstart905(ether);
803
	else{
804
		w = (STATUS(port)>>13) & 0x07;
805
		COMMAND(port, SelectRegisterWindow, Wop);
806
		txstart(ether);
807
		COMMAND(port, SelectRegisterWindow, w);
808
	}
809
	iunlock(&ctlr->wlock);
810
}
811
 
812
static void
813
receive905(Ether* ether)
814
{
815
	Ctlr *ctlr;
816
	int len, port, q;
817
	Pd *pd;
818
	Block *bp;
819
 
820
	ctlr = ether->ctlr;
821
	port = ether->port;
822
 
823
	if(inl(port+UpPktStatus) & upStalled)
824
		ctlr->upstalls++;
825
	q = 0;
826
	for(pd = ctlr->uphead; pd->control & upPktComplete; pd = pd->next){
827
		if(pd->control & upError){
828
			if(pd->control & upOverrun)
829
				ether->overflows++;
830
			if(pd->control & (upOversizedFrame|upRuntFrame))
831
				ether->buffs++;
832
			if(pd->control & upAlignmentError)
833
				ether->frames++;
834
			if(pd->control & upCRCError)
835
				ether->crcs++;
836
		}
837
		else if(bp = iallocb(sizeof(Etherpkt)+4)){
838
			len = pd->control & rxBytes;
839
			pd->bp->wp = pd->bp->rp+len;
840
			etheriq(ether, pd->bp, 1);
841
			pd->bp = bp;
842
			pd->addr = PADDR(bp->rp);
843
			coherence();
844
		}
845
 
846
		pd->control = 0;
847
		COMMAND(port, Stall, upUnStall);
848
 
849
		q++;
850
	}
851
	ctlr->uphead = pd;
852
 
853
	ctlr->upqueued += q;
854
	if(q > ctlr->upqmax)
855
		ctlr->upqmax = q;
856
}
857
 
858
static void
859
receive(Ether* ether)
860
{
861
	int len, port, rxerror, rxstatus;
862
	Ctlr *ctlr;
863
	Block *bp;
864
 
865
	port = ether->port;
866
	ctlr = ether->ctlr;
867
 
868
	while(((rxstatus = ins(port+RxStatus)) & rxIncomplete) == 0){
869
		if(ctlr->busmaster == 1 && (STATUS(port) & busMasterInProgress))
870
			break;
871
 
872
		/*
873
		 * If there was an error, log it and continue.
874
		 * Unfortunately the 3C5[078]9 has the error info in the status register
875
		 * and the 3C59[0257] implement a separate RxError register.
876
		 */
877
		if(rxstatus & rxError){
878
			if(ctlr->rxstatus9){
879
				switch(rxstatus & rxError9){
880
 
881
				case rxOverrun9:
882
					ether->overflows++;
883
					break;
884
 
885
				case oversizedFrame9:
886
				case runtFrame9:
887
					ether->buffs++;
888
					break;
889
 
890
				case alignmentError9:
891
					ether->frames++;
892
					break;
893
 
894
				case crcError9:
895
					ether->crcs++;
896
					break;
897
 
898
				}
899
			}
900
			else{
901
				rxerror = inb(port+RxError);
902
				if(rxerror & rxOverrun)
903
					ether->overflows++;
904
				if(rxerror & (oversizedFrame|runtFrame))
905
					ether->buffs++;
906
				if(rxerror & alignmentError)
907
					ether->frames++;
908
				if(rxerror & crcError)
909
					ether->crcs++;
910
			}
911
		}
912
 
913
		/*
914
		 * If there was an error or a new receive buffer can't be
915
		 * allocated, discard the packet and go on to the next.
916
		 */
917
		if((rxstatus & rxError) || (bp = rbpalloc(iallocb)) == 0){
918
			COMMAND(port, RxDiscard, 0);
919
			while(STATUS(port) & commandInProgress)
920
				;
921
 
922
			if(ctlr->busmaster == 1)
923
				startdma(ether, PADDR(ctlr->rbp->rp));
924
 
925
			continue;
926
		}
927
 
928
		/*
929
		 * A valid receive packet awaits:
930
		 *	if using PIO, read it into the buffer;
931
		 *	discard the packet from the FIFO;
932
		 *	if using busmastering, start a new transfer for
933
		 *	  the next packet and as a side-effect get the
934
		 *	  end-pointer of the one just received;
935
		 *	pass the packet on to whoever wants it.
936
		 */
937
		if(ctlr->busmaster == 0 || ctlr->busmaster == 2){
938
			len = (rxstatus & rxBytes9);
939
			ctlr->rbp->wp = ctlr->rbp->rp + len;
940
			insl(port+Fifo, ctlr->rbp->rp, HOWMANY(len, 4));
941
		}
942
 
943
		COMMAND(port, RxDiscard, 0);
944
		while(STATUS(port) & commandInProgress)
945
			;
946
 
947
		if(ctlr->busmaster == 1)
948
			ctlr->rbp->wp = startdma(ether, PADDR(bp->rp));
949
 
950
		etheriq(ether, ctlr->rbp, 1);
951
		ctlr->rbp = bp;
952
	}
953
}
954
 
955
static int
956
ejectable(int did)
957
{
958
	switch (did) {
959
	case 0x5157:
960
		return 1;
961
 
962
	default:
963
		return 0;
964
	}
965
}
966
 
967
static void
968
interrupt(Ureg*, void* arg)
969
{
970
	Ether *ether;
971
	int port, status, s, txstatus, w, x;
972
	Ctlr *ctlr;
973
 
974
	ether = arg;
975
	port = ether->port;
976
	ctlr = ether->ctlr;
977
 
978
	ilock(&ctlr->wlock);
979
	status = STATUS(port);
980
	if(!(status & (interruptMask|interruptLatch))){
981
		ctlr->bogusinterrupts++;
982
		iunlock(&ctlr->wlock);
983
		return;
984
	}
985
	w = (status>>13) & 0x07;
986
	COMMAND(port, SelectRegisterWindow, Wop);
987
 
988
	ctlr->interrupts++;
989
	if(ctlr->busmaster == 2)
990
		ctlr->timer[0] += inb(port+TIMER905) & 0xFF;
991
	else
992
		ctlr->timer[0] += inb(port+TIMER) & 0xFF;
993
 
994
	do{
995
		if(status & hostError){
996
			/*
997
			 * Adapter failure, try to find out why, reset if
998
			 * necessary. What happens if Tx is active and a reset
999
			 * occurs, need to retransmit? This probably isn't right.
1000
			 */
1001
			COMMAND(port, SelectRegisterWindow, Wdiagnostic);
1002
			x = ins(port+FifoDiagnostic);
1003
			COMMAND(port, SelectRegisterWindow, Wop);
1004
 
1005
			if (status == 0xFFFF && x == 0xFFFF && ejectable(ctlr->did)) {
1006
				print("#l%d: Card ejected?\n", ether->ctlrno);
1007
				iunlock(&ctlr->wlock);
1008
				return;
1009
			}
1010
 
1011
			print("#l%d: status 0x%uX, diag 0x%uX\n",
1012
			    ether->ctlrno, status, x);
1013
 
1014
			if(x & txOverrun){
1015
				if(ctlr->busmaster == 0)
1016
					COMMAND(port, TxReset, 0);
1017
				else
1018
					COMMAND(port, TxReset, (updnReset|dmaReset));
1019
				COMMAND(port, TxEnable, 0);
1020
			}
1021
 
1022
			if(x & rxUnderrun){
1023
				/*
1024
				 * This shouldn't happen...
1025
				 * Reset the receiver and restore the filter and RxEarly
1026
				 * threshold before re-enabling.
1027
				 * Need to restart any busmastering?
1028
				 */
1029
				COMMAND(port, SelectRegisterWindow, Wstate);
1030
				s = (port+RxFilter) & 0x000F;
1031
				COMMAND(port, SelectRegisterWindow, Wop);
1032
				COMMAND(port, RxReset, 0);
1033
				while(STATUS(port) & commandInProgress)
1034
					;
1035
				COMMAND(port, SetRxFilter, s);
1036
				COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts);
1037
				COMMAND(port, RxEnable, 0);
1038
			}
1039
 
1040
			status &= ~hostError;
1041
		}
1042
 
1043
		if(status & (transferInt|rxComplete)){
1044
			receive(ether);
1045
			status &= ~(transferInt|rxComplete);
1046
		}
1047
 
1048
		if(status & (upComplete)){
1049
			COMMAND(port, AcknowledgeInterrupt, upComplete);
1050
			receive905(ether);
1051
			status &= ~upComplete;
1052
			ctlr->upinterrupts++;
1053
		}
1054
 
1055
		if(status & txComplete){
1056
			/*
1057
			 * Pop the TxStatus stack, accumulating errors.
1058
			 * Adjust the TX start threshold if there was an underrun.
1059
			 * If there was a Jabber or Underrun error, reset
1060
			 * the transmitter, taking care not to reset the dma logic
1061
			 * as a busmaster receive may be in progress.
1062
			 * For all conditions enable the transmitter.
1063
			 */
1064
			if(ctlr->busmaster == 2)
1065
				txstatus = port+TxStatus905;
1066
			else
1067
				txstatus = port+TxStatus;
1068
			s = 0;
1069
			do{
1070
				if(x = inb(txstatus))
1071
					outb(txstatus, 0);
1072
				s |= x;
1073
			}while(STATUS(port) & txComplete);
1074
 
1075
			if(s & txUnderrun){
1076
				if(ctlr->dnenabled){
1077
					while(inl(port+PktStatus) & dnInProg)
1078
						;
1079
				}
1080
				COMMAND(port, SelectRegisterWindow, Wdiagnostic);
1081
				while(ins(port+MediaStatus) & txInProg)
1082
					;
1083
				COMMAND(port, SelectRegisterWindow, Wop);
1084
				if(ctlr->txthreshold < ETHERMAXTU)
1085
					ctlr->txthreshold += ETHERMINTU;
1086
			}
1087
 
1088
			/*
1089
			 * According to the manual, maxCollisions does not require
1090
			 * a TxReset, merely a TxEnable. However, evidence points to
1091
			 * it being necessary on the 3C905. The jury is still out.
1092
			 * On busy or badly configured networks maxCollisions can
1093
			 * happen frequently enough for messages to be annoying so
1094
			 * keep quiet about them by popular request.
1095
			 */
1096
			if(s & (txJabber|txUnderrun|maxCollisions)){
1097
				if(ctlr->busmaster == 0)
1098
					COMMAND(port, TxReset, 0);
1099
				else
1100
					COMMAND(port, TxReset, (updnReset|dmaReset));
1101
				while(STATUS(port) & commandInProgress)
1102
					;
1103
				COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts);
1104
				if(ctlr->busmaster == 2)
1105
					outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256));
1106
				if(ctlr->dnenabled)
1107
					status |= dnComplete;
1108
			}
1109
 
1110
			if(s & ~(txStatusComplete|maxCollisions))
1111
				print("#l%d: txstatus 0x%uX, threshold %d\n",
1112
			    		ether->ctlrno, s, ctlr->txthreshold);
1113
			COMMAND(port, TxEnable, 0);
1114
			ether->oerrs++;
1115
			status &= ~txComplete;
1116
			status |= txAvailable;
1117
		}
1118
 
1119
		if(status & txAvailable){
1120
			COMMAND(port, AcknowledgeInterrupt, txAvailable);
1121
			ctlr->txbusy = 0;
1122
			txstart(ether);
1123
			status &= ~txAvailable;
1124
		}
1125
 
1126
		if(status & dnComplete){
1127
			COMMAND(port, AcknowledgeInterrupt, dnComplete);
1128
			txstart905(ether);
1129
			status &= ~dnComplete;
1130
			ctlr->dninterrupts++;
1131
		}
1132
 
1133
		if(status & updateStats){
1134
			statistics(ether);
1135
			status &= ~updateStats;
1136
		}
1137
 
1138
		/*
1139
		 * Currently, this shouldn't happen.
1140
		 */
1141
		if(status & rxEarly){
1142
			COMMAND(port, AcknowledgeInterrupt, rxEarly);
1143
			status &= ~rxEarly;
1144
		}
1145
 
1146
		/*
1147
		 * Panic if there are any interrupts not dealt with.
1148
		 */
1149
		if(status & interruptMask)
1150
			panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status);
1151
 
1152
		COMMAND(port, AcknowledgeInterrupt, interruptLatch);
1153
		if(ctlr->cbfn != nil)
1154
			intrackcb(ctlr->cbfn);
1155
 
1156
	}while((status = STATUS(port)) & (interruptMask|interruptLatch));
1157
 
1158
	if(ctlr->busmaster == 2)
1159
		ctlr->timer[1] += inb(port+TIMER905) & 0xFF;
1160
	else
1161
		ctlr->timer[1] += inb(port+TIMER) & 0xFF;
1162
 
1163
	COMMAND(port, SelectRegisterWindow, w);
1164
	iunlock(&ctlr->wlock);
1165
}
1166
 
1167
static long
1168
ifstat(Ether* ether, void* a, long n, ulong offset)
1169
{
1170
	char *p;
1171
	int len;
1172
	Ctlr *ctlr;
1173
 
1174
	if(n == 0)
1175
		return 0;
1176
 
1177
	ctlr = ether->ctlr;
1178
 
1179
	ilock(&ctlr->wlock);
1180
	statistics(ether);
1181
	iunlock(&ctlr->wlock);
1182
 
1183
	p = malloc(READSTR);
1184
	if(p == nil)
1185
		error(Enomem);
1186
	len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts);
1187
	len += snprint(p+len, READSTR-len, "bogusinterrupts: %lud\n", ctlr->bogusinterrupts);
1188
	len += snprint(p+len, READSTR-len, "timer: %lud %lud\n",
1189
		ctlr->timer[0], ctlr->timer[1]);
1190
	len += snprint(p+len, READSTR-len, "carrierlost: %lud\n",
1191
		ctlr->stats[CarrierLost]);
1192
	len += snprint(p+len, READSTR-len, "sqeerrors: %lud\n",
1193
		ctlr->stats[SqeErrors]);
1194
	len += snprint(p+len, READSTR-len, "multiplecolls: %lud\n",
1195
		ctlr->stats[MultipleColls]);
1196
	len += snprint(p+len, READSTR-len, "singlecollframes: %lud\n",
1197
		ctlr->stats[SingleCollFrames]);
1198
	len += snprint(p+len, READSTR-len, "latecollisions: %lud\n",
1199
		ctlr->stats[LateCollisions]);
1200
	len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n",
1201
		ctlr->stats[RxOverruns]);
1202
	len += snprint(p+len, READSTR-len, "framesxmittedok: %lud\n",
1203
		ctlr->stats[FramesXmittedOk]);
1204
	len += snprint(p+len, READSTR-len, "framesrcvdok: %lud\n",
1205
		ctlr->stats[FramesRcvdOk]);
1206
	len += snprint(p+len, READSTR-len, "framesdeferred: %lud\n",
1207
		ctlr->stats[FramesDeferred]);
1208
	len += snprint(p+len, READSTR-len, "bytesrcvdok: %lud\n",
1209
		ctlr->stats[BytesRcvdOk]);
1210
	len += snprint(p+len, READSTR-len, "bytesxmittedok: %lud\n",
1211
		ctlr->stats[BytesRcvdOk+1]);
1212
 
1213
	if(ctlr->upenabled){
1214
		if(ctlr->upqmax > ctlr->upqmaxhw)
1215
			ctlr->upqmaxhw = ctlr->upqmax;
1216
		len += snprint(p+len, READSTR-len, "up: q %lud i %lud m %d h %d s %lud\n",
1217
			ctlr->upqueued, ctlr->upinterrupts,
1218
			ctlr->upqmax, ctlr->upqmaxhw, ctlr->upstalls);
1219
		ctlr->upqmax = 0;
1220
	}
1221
	if(ctlr->dnenabled){
1222
		if(ctlr->dnqmax > ctlr->dnqmaxhw)
1223
			ctlr->dnqmaxhw = ctlr->dnqmax;
1224
		len += snprint(p+len, READSTR-len, "dn: q %lud i %lud m %d h %d\n",
1225
			ctlr->dnqueued, ctlr->dninterrupts, ctlr->dnqmax, ctlr->dnqmaxhw);
1226
		ctlr->dnqmax = 0;
1227
	}
1228
 
1229
	snprint(p+len, READSTR-len, "badssd: %lud\n", ctlr->stats[BytesRcvdOk+2]);
1230
 
1231
	n = readstr(offset, a, n, p);
1232
	free(p);
1233
 
1234
	return n;
1235
}
1236
 
1237
static void
1238
txrxreset(int port)
1239
{
1240
	COMMAND(port, TxReset, 0);
1241
	while(STATUS(port) & commandInProgress)
1242
		;
1243
	COMMAND(port, RxReset, 0);
1244
	while(STATUS(port) & commandInProgress)
1245
		;
1246
}
1247
 
1248
static Ctlr*
1249
tcmadapter(int port, int irq, Pcidev* pcidev)
1250
{
1251
	Ctlr *ctlr;
1252
 
1253
	ctlr = malloc(sizeof(Ctlr));
1254
	if(ctlr == nil)
1255
		error(Enomem);
1256
	ctlr->port = port;
1257
	ctlr->irq = irq;
1258
	ctlr->pcidev = pcidev;
1259
	ctlr->eepromcmd = EepromReadRegister;
1260
 
1261
	if(ctlrhead != nil)
1262
		ctlrtail->next = ctlr;
1263
	else
1264
		ctlrhead = ctlr;
1265
	ctlrtail = ctlr;
1266
 
1267
	return ctlr;
1268
}
1269
 
1270
/*
1271
 * Write two 0 bytes to identify the IDport and then reset the
1272
 * ID sequence. Then send the ID sequence to the card to get
1273
 * the card into command state.
1274
 */
1275
static void
1276
idseq(void)
1277
{
1278
	int i;
1279
	uchar al;
1280
	static int reset, untag;
1281
 
1282
	/*
1283
	 * One time only:
1284
	 *	reset any adapters listening
1285
	 */
1286
	if(reset == 0){
1287
		outb(IDport, 0);
1288
		outb(IDport, 0);
1289
		outb(IDport, 0xC0);
1290
		delay(20);
1291
		reset = 1;
1292
	}
1293
 
1294
	outb(IDport, 0);
1295
	outb(IDport, 0);
1296
	for(al = 0xFF, i = 0; i < 255; i++){
1297
		outb(IDport, al);
1298
		if(al & 0x80){
1299
			al <<= 1;
1300
			al ^= 0xCF;
1301
		}
1302
		else
1303
			al <<= 1;
1304
	}
1305
 
1306
	/*
1307
	 * One time only:
1308
	 *	write ID sequence to get the attention of all adapters;
1309
	 *	untag all adapters.
1310
	 * If a global reset is done here on all adapters it will confuse
1311
	 * any ISA cards configured for EISA mode.
1312
	 */
1313
	if(untag == 0){
1314
		outb(IDport, 0xD0);
1315
		untag = 1;
1316
	}
1317
}
1318
 
1319
static ulong
1320
activate(void)
1321
{
1322
	int i;
1323
	ushort x, acr;
1324
 
1325
	/*
1326
	 * Do the little configuration dance:
1327
	 *
1328
	 * 2. write the ID sequence to get to command state.
1329
	 */
1330
	idseq();
1331
 
1332
	/*
1333
	 * 3. Read the Manufacturer ID from the EEPROM.
1334
	 *    This is done by writing the IDPort with 0x87 (0x80
1335
	 *    is the 'read EEPROM' command, 0x07 is the offset of
1336
	 *    the Manufacturer ID field in the EEPROM).
1337
	 *    The data comes back 1 bit at a time.
1338
	 *    A delay seems necessary between reading the bits.
1339
	 *
1340
	 * If the ID doesn't match, there are no more adapters.
1341
	 */
1342
	outb(IDport, 0x87);
1343
	delay(20);
1344
	for(x = 0, i = 0; i < 16; i++){
1345
		delay(20);
1346
		x <<= 1;
1347
		x |= inb(IDport) & 0x01;
1348
	}
1349
	if(x != 0x6D50)
1350
		return 0;
1351
 
1352
	/*
1353
	 * 3. Read the Address Configuration from the EEPROM.
1354
	 *    The Address Configuration field is at offset 0x08 in the EEPROM).
1355
	 */
1356
	outb(IDport, 0x88);
1357
	for(acr = 0, i = 0; i < 16; i++){
1358
		delay(20);
1359
		acr <<= 1;
1360
		acr |= inb(IDport) & 0x01;
1361
	}
1362
 
1363
	return (acr & 0x1F)*0x10 + 0x200;
1364
}
1365
 
1366
static void
1367
tcm509isa(void)
1368
{
1369
	int irq, port;
1370
 
1371
	/*
1372
	 * Attempt to activate all adapters. If adapter is set for
1373
	 * EISA mode (0x3F0), tag it and ignore. Otherwise, activate
1374
	 * it fully.
1375
	 */
1376
	while(port = activate()){
1377
		if(ioalloc(port, 0x10, 0, "tcm509isa") < 0){
1378
			print("tcm509isa: port 0x%uX in use\n", port);
1379
			continue;
1380
		}
1381
 
1382
		/*
1383
		 * 6. Tag the adapter so it won't respond in future.
1384
		 */
1385
		outb(IDport, 0xD1);
1386
		if(port == 0x3F0){
1387
			iofree(port);
1388
			continue;
1389
		}
1390
 
1391
		/*
1392
		 * 6. Activate the adapter by writing the Activate command
1393
		 *    (0xFF).
1394
		 */
1395
		outb(IDport, 0xFF);
1396
		delay(20);
1397
 
1398
		/*
1399
		 * 8. Can now talk to the adapter's I/O base addresses.
1400
		 *    Use the I/O base address from the acr just read.
1401
		 *
1402
		 *    Enable the adapter and clear out any lingering status
1403
		 *    and interrupts.
1404
		 */
1405
		while(STATUS(port) & commandInProgress)
1406
			;
1407
		COMMAND(port, SelectRegisterWindow, Wsetup);
1408
		outs(port+ConfigControl, Ena);
1409
 
1410
		txrxreset(port);
1411
		COMMAND(port, AcknowledgeInterrupt, 0xFF);
1412
 
1413
		irq = (ins(port+ResourceConfig)>>12) & 0x0F;
1414
		tcmadapter(port, irq, nil);
1415
	}
1416
}
1417
 
1418
static void
1419
tcm5XXeisa(void)
1420
{
1421
	ushort x;
1422
	int irq, port, slot;
1423
 
1424
	/*
1425
	 * Check if this is an EISA machine.
1426
	 * If not, nothing to do.
1427
	 */
1428
	if(strncmp((char*)KADDR(0xFFFD9), "EISA", 4))
1429
		return;
1430
 
1431
	/*
1432
	 * Continue through the EISA slots looking for a match on both
1433
	 * 3COM as the manufacturer and 3C579-* or 3C59[27]-* as the product.
1434
	 * If an adapter is found, select window 0, enable it and clear
1435
	 * out any lingering status and interrupts.
1436
	 */
1437
	for(slot = 1; slot < MaxEISA; slot++){
1438
		port = slot*0x1000;
1439
		if(ioalloc(port, 0x1000, 0, "tcm5XXeisa") < 0){
1440
			print("tcm5XXeisa: port 0x%uX in use\n", port);
1441
			continue;
1442
		}
1443
		if(ins(port+0xC80+ManufacturerID) != 0x6D50){
1444
			iofree(port);
1445
			continue;
1446
		}
1447
		x = ins(port+0xC80+ProductID);
1448
		if((x & 0xF0FF) != 0x9050 && (x & 0xFF00) != 0x5900){
1449
			iofree(port);
1450
			continue;
1451
		}
1452
 
1453
		COMMAND(port, SelectRegisterWindow, Wsetup);
1454
		outs(port+ConfigControl, Ena);
1455
 
1456
		txrxreset(port);
1457
		COMMAND(port, AcknowledgeInterrupt, 0xFF);
1458
 
1459
		irq = (ins(port+ResourceConfig)>>12) & 0x0F;
1460
		tcmadapter(port, irq, nil);
1461
	}
1462
}
1463
 
1464
static void
1465
tcm59Xpci(void)
1466
{
1467
	Pcidev *p;
1468
	Ctlr *ctlr;
1469
	int irq, port;
1470
 
1471
	p = nil;
1472
	while(p = pcimatch(p, 0x10B7, 0)){
1473
		if(p->ccrb != 0x02 || p->ccru != 0)
1474
			continue;
1475
		/*
1476
		 * Not prepared to deal with memory-mapped
1477
		 * devices yet.
1478
		 */
1479
		if(!(p->mem[0].bar & 0x01))
1480
			continue;
1481
		port = p->mem[0].bar & ~0x01;
1482
		if((port = ioalloc((port == 0)? -1: port,  p->mem[0].size, 
1483
					  0, "tcm59Xpci")) < 0){
1484
			print("tcm59Xpci: port 0x%uX in use\n", port);
1485
			continue;
1486
		}
1487
		irq = p->intl;
1488
 
1489
		txrxreset(port);
1490
		COMMAND(port, AcknowledgeInterrupt, 0xFF);
1491
 
1492
		ctlr = tcmadapter(port, irq, p);
1493
		switch(p->did){
1494
		default:
1495
			break;
1496
		case 0x5157:
1497
			ctlr->eepromcmd = EepromRead8bRegister;
1498
			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
1499
			ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
1500
			break;
1501
		case 0x6056:
1502
			ctlr->eepromcmd = EepromReadOffRegister;
1503
			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
1504
			ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
1505
			break;
1506
		}
1507
		pcisetbme(p);
1508
	}
1509
}
1510
 
1511
static char* tcmpcmcia[] = {
1512
	"3C589",			/* 3COM 589[ABCD] */
1513
	"3C562",			/* 3COM 562 */
1514
	"589E",				/* 3COM Megahertz 589E */
1515
	nil,
1516
};
1517
 
1518
static Ctlr*
1519
tcm5XXpcmcia(Ether* ether)
1520
{
1521
	int i;
1522
	Ctlr *ctlr;
1523
 
1524
	if(ether->type == nil)
1525
		return nil;
1526
 
1527
	for(i = 0; tcmpcmcia[i] != nil; i++){
1528
		if(cistrcmp(ether->type, tcmpcmcia[i]))
1529
			continue;
1530
		ctlr = tcmadapter(ether->port, ether->irq, nil);
1531
		ctlr->active = 1;
1532
		return ctlr;
1533
	}
1534
 
1535
	return nil;
1536
}
1537
 
1538
static void
1539
setxcvr(Ctlr* ctlr, int xcvr)
1540
{
1541
	int port, x;
1542
 
1543
	port = ctlr->port;
1544
	if(ctlr->rxstatus9){
1545
		COMMAND(port, SelectRegisterWindow, Wsetup);
1546
		x = ins(port+AddressConfig) & ~xcvrMask9;
1547
		x |= (xcvr>>20)<<14;
1548
		outs(port+AddressConfig, x);
1549
	}
1550
	else{
1551
		COMMAND(port, SelectRegisterWindow, Wfifo);
1552
		x = inl(port+InternalConfig) & ~xcvrMask;
1553
		x |= xcvr;
1554
		outl(port+InternalConfig, x);
1555
	}
1556
 
1557
	txrxreset(port);
1558
}
1559
 
1560
static void
1561
setfullduplex(int port)
1562
{
1563
	int x;
1564
 
1565
	COMMAND(port, SelectRegisterWindow, Wfifo);
1566
	x = ins(port+MacControl);
1567
	outs(port+MacControl, fullDuplexEnable|x);
1568
 
1569
	txrxreset(port);
1570
}
1571
 
1572
static int
1573
miimdi(int port, int n)
1574
{
1575
	int data, i;
1576
 
1577
	/*
1578
	 * Read n bits from the MII Management Register.
1579
	 */
1580
	data = 0;
1581
	for(i = n-1; i >= 0; i--){
1582
		if(ins(port) & mgmtData)
1583
			data |= (1<<i);
1584
		microdelay(1);
1585
		outs(port, mgmtClk);
1586
		microdelay(1);
1587
		outs(port, 0);
1588
		microdelay(1);
1589
	}
1590
 
1591
	return data;
1592
}
1593
 
1594
static void
1595
miimdo(int port, int bits, int n)
1596
{
1597
	int i, mdo;
1598
 
1599
	/*
1600
	 * Write n bits to the MII Management Register.
1601
	 */
1602
	for(i = n-1; i >= 0; i--){
1603
		if(bits & (1<<i))
1604
			mdo = mgmtDir|mgmtData;
1605
		else
1606
			mdo = mgmtDir;
1607
		outs(port, mdo);
1608
		microdelay(1);
1609
		outs(port, mdo|mgmtClk);
1610
		microdelay(1);
1611
		outs(port, mdo);
1612
		microdelay(1);
1613
	}
1614
}
1615
 
1616
static int
1617
miir(int port, int phyad, int regad)
1618
{
1619
	int data, w;
1620
 
1621
	w = (STATUS(port)>>13) & 0x07;
1622
	COMMAND(port, SelectRegisterWindow, Wdiagnostic);
1623
	port += PhysicalMgmt;
1624
 
1625
	/*
1626
	 * Preamble;
1627
	 * ST+OP+PHYAD+REGAD;
1628
	 * TA + 16 data bits.
1629
	 */
1630
	miimdo(port, 0xFFFFFFFF, 32);
1631
	miimdo(port, 0x1800|(phyad<<5)|regad, 14);
1632
	data = miimdi(port, 18);
1633
 
1634
	port -= PhysicalMgmt;
1635
	COMMAND(port, SelectRegisterWindow, w);
1636
 
1637
	if(data & 0x10000)
1638
		return -1;
1639
 
1640
	return data & 0xFFFF;
1641
}
1642
 
1643
static int
1644
scanphy(int port)
1645
{
1646
	int i, x;
1647
 
1648
	for(i = 0; i < 32; i++){
1649
		if((x = miir(port, i, 2)) == -1 || x == 0)
1650
			continue;
1651
		x <<= 6;
1652
		x |= miir(port, i, 3)>>10;
1653
		XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(port, i, 1));
1654
		USED(x);
1655
 
1656
		return i;
1657
	}
1658
	return 24;
1659
}
1660
 
1661
static struct {
1662
	char *name;
1663
	int avail;
1664
	int xcvr;
1665
} media[] = {
1666
	"10BaseT",	base10TAvailable,	xcvr10BaseT,
1667
	"10Base2",	coaxAvailable,		xcvr10Base2,
1668
	"100BaseTX",	baseTXAvailable,	xcvr100BaseTX,
1669
	"100BaseFX",	baseFXAvailable,	xcvr100BaseFX,
1670
	"aui",		auiAvailable,		xcvrAui,
1671
	"mii",		miiConnector,		xcvrMii
1672
};
1673
 
1674
static int
1675
autoselect(Ctlr* ctlr)
1676
{
1677
	int media, port, x;
1678
 
1679
	/*
1680
	 * Pathetic attempt at automatic media selection.
1681
	 * Really just to get the Fast Etherlink 10BASE-T/100BASE-TX
1682
	 * cards operational.
1683
	 * It's a bonus if it works for anything else.
1684
	 */
1685
	port = ctlr->port;
1686
	if(ctlr->rxstatus9){
1687
		COMMAND(port, SelectRegisterWindow, Wsetup);
1688
		x = ins(port+ConfigControl);
1689
		media = 0;
1690
		if(x & base10TAvailable9)
1691
			media |= base10TAvailable;
1692
		if(x & coaxAvailable9)
1693
			media |= coaxAvailable;
1694
		if(x & auiAvailable9)
1695
			media |= auiAvailable;
1696
	}
1697
	else{
1698
		COMMAND(port, SelectRegisterWindow, Wfifo);
1699
		media = ins(port+ResetOptions);
1700
	}
1701
	XCVRDEBUG("autoselect: media %uX\n", media);
1702
 
1703
	if(media & miiConnector)
1704
		return xcvrMii;
1705
 
1706
	COMMAND(port, SelectRegisterWindow, Wdiagnostic);
1707
	XCVRDEBUG("autoselect: media status %uX\n", ins(port+MediaStatus));
1708
 
1709
	if(media & baseTXAvailable){
1710
		/*
1711
		 * Must have InternalConfig register.
1712
		 */
1713
		setxcvr(ctlr, xcvr100BaseTX);
1714
 
1715
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
1716
		x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable);
1717
		outs(port+MediaStatus, linkBeatEnable|x);
1718
		delay(10);
1719
 
1720
		if(ins(port+MediaStatus) & linkBeatDetect)
1721
			return xcvr100BaseTX;
1722
		outs(port+MediaStatus, x);
1723
	}
1724
 
1725
	if(media & base10TAvailable){
1726
		setxcvr(ctlr, xcvr10BaseT);
1727
 
1728
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
1729
		x = ins(port+MediaStatus) & ~dcConverterEnabled;
1730
		outs(port+MediaStatus, linkBeatEnable|jabberGuardEnable|x);
1731
		delay(100);
1732
 
1733
		XCVRDEBUG("autoselect: 10BaseT media status %uX\n", ins(port+MediaStatus));
1734
		if(ins(port+MediaStatus) & linkBeatDetect)
1735
			return xcvr10BaseT;
1736
		outs(port+MediaStatus, x);
1737
	}
1738
 
1739
	/*
1740
	 * Botch.
1741
	 */
1742
	return autoSelect;
1743
}
1744
 
1745
static int
1746
eepromdata(Ctlr* ctlr, int offset)
1747
{
1748
	int port;
1749
 
1750
	port = ctlr->port;
1751
 
1752
	COMMAND(port, SelectRegisterWindow, Wsetup);
1753
	while(EEPROMBUSY(port))
1754
		;
1755
	EEPROMCMD(port, ctlr->eepromcmd, offset);
1756
	while(EEPROMBUSY(port))
1757
		;
1758
	return EEPROMDATA(port);
1759
}
1760
 
1761
static void
1762
resetctlr(Ctlr *ctlr)
1763
{
1764
	int x, port = ctlr->port;
1765
 
1766
	txrxreset(port);
1767
	x = ins(port+ResetOp905B);
1768
	XCVRDEBUG("905[BC] reset ops 0x%uX\n", x);
1769
	x &= ~0x4010;
1770
	if(ctlr->did == 0x5157){
1771
		x |= 0x0010;			/* Invert LED */
1772
		outs(port+ResetOp905B, x);
1773
	}
1774
	if(ctlr->did == 0x6056){
1775
		x |= 0x4000;
1776
		outs(port+ResetOp905B, x);
1777
 
1778
		COMMAND(port, SelectRegisterWindow, Wsetup);
1779
		outs(port, 0x0800);
1780
	}
1781
}
1782
 
1783
static void
1784
shutdown(Ether *ether)
1785
{
1786
print("etherelnk3 shutting down\n");
1787
	resetctlr(ether->ctlr);
1788
}
1789
 
1790
int
1791
etherelnk3reset(Ether* ether)
1792
{
1793
	char *p;
1794
	Ctlr *ctlr;
1795
	uchar ea[Eaddrlen];
1796
	static int scandone;
1797
	int anar, anlpar, i, j, phyaddr, phystat, port, timeo, x;
1798
 
1799
	/*
1800
	 * Scan for adapter on PCI, EISA and finally
1801
	 * using the little ISA configuration dance.
1802
	 */
1803
	if(scandone == 0){
1804
		tcm59Xpci();
1805
		tcm5XXeisa();
1806
		tcm509isa();
1807
		scandone = 1;
1808
	}
1809
 
1810
	/*
1811
	 * Any adapter matches if no ether->port is supplied,
1812
	 * otherwise the ports must match.
1813
	 */
1814
	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
1815
		if(ctlr->active)
1816
			continue;
1817
		if(ether->port == 0 || ether->port == ctlr->port){
1818
			ctlr->active = 1;
1819
			break;
1820
		}
1821
	}
1822
	if(ctlr == nil && (ctlr = tcm5XXpcmcia(ether)) == 0)
1823
		return -1;
1824
 
1825
	ether->ctlr = ctlr;
1826
	port = ctlr->port;
1827
	ether->port = port;
1828
	ether->irq = ctlr->irq;
1829
	if(ctlr->pcidev != nil)
1830
		ether->tbdf = ctlr->pcidev->tbdf;
1831
	else
1832
		ether->tbdf = BUSUNKNOWN;
1833
 
1834
	/*
1835
	 * Read the DeviceID from the EEPROM, it's at offset 0x03,
1836
	 * and do something depending on capabilities.
1837
	 */
1838
	switch(ctlr->did = eepromdata(ctlr, 0x03)){
1839
	case 0x5157:		/* 3C575 Cyclone */
1840
	case 0x6056:
1841
		/*FALLTHROUGH*/
1842
	case 0x4500:		/* 3C450 HomePNA Tornado */
1843
	case 0x7646:		/* 3CSOHO100-TX */
1844
	case 0x9055:		/* 3C905B-TX */
1845
	case 0x9200:		/* 3C905C-TX */
1846
	case 0x9201:		/* 3C920 */
1847
	case 0x9805:		/* 3C9805: 3C980-TX Python-T 10/100baseTX */
1848
		/*FALLTHROUGH*/
1849
	case 0x9000:		/* 3C900-TPO */
1850
	case 0x9001:		/* 3C900-COMBO */
1851
	case 0x9005:		/* 3C900B-COMBO */
1852
	case 0x9050:		/* 3C905-TX */
1853
	case 0x9051:		/* 3C905-T4 */
1854
		if(BUSTYPE(ether->tbdf) != BusPCI)
1855
			goto buggery;
1856
		ctlr->busmaster = 2;
1857
		goto vortex;
1858
	case 0x5900:		/* 3C590-[TP|COMBO|TPO] */
1859
	case 0x5920:		/* 3C592-[TP|COMBO|TPO] */
1860
	case 0x5950:		/* 3C595-TX */
1861
	case 0x5951:		/* 3C595-T4 */
1862
	case 0x5952:		/* 3C595-MII */
1863
	case 0x5970:		/* 3C597-TX */
1864
	case 0x5971:		/* 3C597-T4 */
1865
	case 0x5972:		/* 3C597-MII */
1866
		ctlr->busmaster = 1;
1867
	vortex:
1868
		COMMAND(port, SelectRegisterWindow, Wfifo);
1869
		ctlr->xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask);
1870
		ctlr->rxearly = 8188;
1871
		ctlr->rxstatus9 = 0;
1872
		break;
1873
	buggery:
1874
	default:
1875
		ctlr->busmaster = 0;
1876
		COMMAND(port, SelectRegisterWindow, Wsetup);
1877
		x = ins(port+AddressConfig);
1878
		ctlr->xcvr = ((x & xcvrMask9)>>14)<<20;
1879
		if(x & autoSelect9)
1880
			ctlr->xcvr |= autoSelect;
1881
		ctlr->rxearly = 2044;
1882
		ctlr->rxstatus9 = 1;
1883
		break;
1884
	}
1885
	if(ctlr->rxearly >= 2048)
1886
		ctlr->ts = 2;
1887
 
1888
	/*
1889
	 * Check if the adapter's station address is to be overridden.
1890
	 * If not, read it from the EEPROM and set in ether->ea prior to
1891
	 * loading the station address in Wstation.
1892
	 * The EEPROM returns 16-bits at a time.
1893
	 */
1894
	memset(ea, 0, Eaddrlen);
1895
	if(memcmp(ea, ether->ea, Eaddrlen) == 0){
1896
		for(i = 0; i < Eaddrlen/2; i++){
1897
			x = eepromdata(ctlr, i);
1898
			ether->ea[2*i] = x>>8;
1899
			ether->ea[2*i+1] = x;
1900
		}
1901
	}
1902
 
1903
	COMMAND(port, SelectRegisterWindow, Wstation);
1904
	for(i = 0; i < Eaddrlen; i++)
1905
		outb(port+i, ether->ea[i]);
1906
 
1907
	/*
1908
	 * Enable the transceiver if necessary and determine whether
1909
	 * busmastering can be used. Due to bugs in the first revision
1910
	 * of the 3C59[05], don't use busmastering at 10Mbps.
1911
	 */
1912
	XCVRDEBUG("reset: xcvr %uX\n", ctlr->xcvr);
1913
 
1914
	/*
1915
	 * Allow user to specify desired media in plan9.ini
1916
	 */
1917
	for(i = 0; i < ether->nopt; i++){
1918
		if(cistrncmp(ether->opt[i], "media=", 6) != 0)
1919
			continue;
1920
		p = ether->opt[i]+6;
1921
		for(j = 0; j < nelem(media); j++)
1922
			if(cistrcmp(p, media[j].name) == 0)
1923
				ctlr->xcvr = media[j].xcvr;
1924
	}
1925
 
1926
	/*
1927
	 * forgive me, but i am weak
1928
	 */
1929
	switch(ctlr->did){
1930
	default:
1931
		if(ctlr->xcvr & autoSelect)
1932
			ctlr->xcvr = autoselect(ctlr);
1933
		break;
1934
	case 0x5157:
1935
	case 0x6056:
1936
	case 0x4500:
1937
	case 0x7646:
1938
	case 0x9055:
1939
	case 0x9200:
1940
	case 0x9201:
1941
	case 0x9805:
1942
		ctlr->xcvr = xcvrMii;
1943
		resetctlr(ctlr);
1944
		break;
1945
	}
1946
	XCVRDEBUG("xcvr selected: %uX, did 0x%uX\n", ctlr->xcvr, ctlr->did);
1947
 
1948
	switch(ctlr->xcvr){
1949
	case xcvrMii:
1950
		/*
1951
		 * Quick hack.
1952
		 */
1953
		if(ctlr->did == 0x5157)
1954
			phyaddr = 0;
1955
		else if(ctlr->did == 0x6056)
1956
			phyaddr = scanphy(port);
1957
		else
1958
			phyaddr = 24;
1959
		for(i = 0; i < 7; i++)
1960
			XCVRDEBUG(" %2.2uX", miir(port, phyaddr, i));
1961
			XCVRDEBUG("\n");
1962
 
1963
		for(timeo = 0; timeo < 30; timeo++){
1964
			phystat = miir(port, phyaddr, 0x01);
1965
			if(phystat & 0x20)
1966
				break;
1967
			XCVRDEBUG(" %2.2uX", phystat);
1968
			delay(100);
1969
		}
1970
		XCVRDEBUG(" %2.2uX", miir(port, phyaddr, 0x01));
1971
		XCVRDEBUG("\n");
1972
 
1973
		anar = miir(port, phyaddr, 0x04);
1974
		anlpar = miir(port, phyaddr, 0x05) & 0x03E0;
1975
		anar &= anlpar;
1976
		miir(port, phyaddr, 0x00);
1977
		XCVRDEBUG("mii an: %uX anlp: %uX r0:%uX r1:%uX\n",
1978
			anar, anlpar, miir(port, phyaddr, 0x00),
1979
			miir(port, phyaddr, 0x01));
1980
		for(i = 0; i < ether->nopt; i++){
1981
			if(cistrcmp(ether->opt[i], "fullduplex") == 0)
1982
				anar |= 0x0100;
1983
			else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0)
1984
				anar |= 0x0100;
1985
			else if(cistrcmp(ether->opt[i], "force100") == 0)
1986
				anar |= 0x0080;
1987
		}
1988
		XCVRDEBUG("mii anar: %uX\n", anar);
1989
		if(anar & 0x0100){		/* 100BASE-TXFD */
1990
			ether->mbps = 100;
1991
			setfullduplex(port);
1992
		}
1993
		else if(anar & 0x0200){		/* 100BASE-T4 */
1994
			/* nothing to do */
1995
		}
1996
		else if(anar & 0x0080)		/* 100BASE-TX */
1997
			ether->mbps = 100;
1998
		else if(anar & 0x0040)		/* 10BASE-TFD */
1999
			setfullduplex(port);
2000
		else{				/* 10BASE-T */
2001
			/* nothing to do */
2002
		}
2003
		break;
2004
	case xcvr100BaseTX:
2005
	case xcvr100BaseFX:
2006
		COMMAND(port, SelectRegisterWindow, Wfifo);
2007
		x = inl(port+InternalConfig) & ~ramPartitionMask;
2008
		outl(port+InternalConfig, x|ramPartition1to1);
2009
 
2010
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
2011
		x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable);
2012
		x |= linkBeatEnable;
2013
		outs(port+MediaStatus, x);
2014
 
2015
		if(x & dataRate100)
2016
			ether->mbps = 100;
2017
		break;
2018
	case xcvr10BaseT:
2019
		/*
2020
		 * Enable Link Beat and Jabber to start the
2021
		 * transceiver.
2022
		 */
2023
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
2024
		x = ins(port+MediaStatus) & ~dcConverterEnabled;
2025
		x |= linkBeatEnable|jabberGuardEnable;
2026
		outs(port+MediaStatus, x);
2027
 
2028
		if((ctlr->did & 0xFF00) == 0x5900)
2029
			ctlr->busmaster = 0;
2030
		break;
2031
	case xcvr10Base2:
2032
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
2033
		x = ins(port+MediaStatus) & ~(linkBeatEnable|jabberGuardEnable);
2034
		outs(port+MediaStatus, x);
2035
 
2036
		/*
2037
		 * Start the DC-DC converter.
2038
		 * Wait > 800 microseconds.
2039
		 */
2040
		COMMAND(port, EnableDcConverter, 0);
2041
		delay(1);
2042
		break;
2043
	}
2044
 
2045
	/*
2046
	 * Wop is the normal operating register set.
2047
	 * The 3C59[0257] adapters allow access to more than one register window
2048
	 * at a time, but there are situations where switching still needs to be
2049
	 * done, so just do it.
2050
	 * Clear out any lingering Tx status.
2051
	 */
2052
	COMMAND(port, SelectRegisterWindow, Wop);
2053
	if(ctlr->busmaster == 2)
2054
		x = port+TxStatus905;
2055
	else
2056
		x = port+TxStatus;
2057
	while(inb(x))
2058
		outb(x, 0);
2059
 
2060
	/*
2061
	 * Clear out the
2062
	 * adapter statistics, clear the statistics logged into ctlr
2063
	 * and enable statistics collection.
2064
	 */
2065
	ilock(&ctlr->wlock);
2066
	statistics(ether);
2067
	memset(ctlr->stats, 0, sizeof(ctlr->stats));
2068
 
2069
	COMMAND(port, StatisticsEnable, 0);
2070
 
2071
	/*
2072
	 * Allocate any receive buffers.
2073
	 */
2074
	switch(ctlr->busmaster){
2075
	case 2:
2076
		ctlr->dnenabled = 1;
2077
 
2078
		/*
2079
		 * 10MUpldBug.
2080
		 * Disabling is too severe, can use receive busmastering at
2081
		 * 100Mbps OK, but how to tell which rate is actually being used -
2082
		 * the 3c905 always seems to have dataRate100 set?
2083
		 * Believe the bug doesn't apply if upRxEarlyEnable is set
2084
		 * and the threshold is set such that uploads won't start
2085
		 * until the whole packet has been received.
2086
		 */
2087
		ctlr->upenabled = 1;
2088
		x = eepromdata(ctlr, 0x0F);
2089
		if(!(x & 0x01))
2090
			outl(port+PktStatus, upRxEarlyEnable);
2091
 
2092
		if(ctlr->upenabled || ctlr->dnenabled){
2093
			ctlr->nup = Nup;
2094
			ctlr->ndn = Ndn;
2095
			init905(ctlr);
2096
		}
2097
		else {
2098
			ctlr->rbp = rbpalloc(iallocb);
2099
			if(ctlr->rbp == nil)
2100
				panic("can't reset ethernet: out of memory");
2101
		}
2102
		outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256));
2103
		break;
2104
	default:
2105
		ctlr->rbp = rbpalloc(iallocb);
2106
		if(ctlr->rbp == nil)
2107
			panic("can't reset ethernet: out of memory");
2108
		break;
2109
	}
2110
 
2111
	/*
2112
	 * Set a base TxStartThresh which will be incremented
2113
	 * if any txUnderrun errors occur and ensure no RxEarly
2114
	 * interrupts happen.
2115
	 */
2116
	ctlr->txthreshold = ETHERMAXTU/2;
2117
	COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts);
2118
	COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts);
2119
 
2120
	iunlock(&ctlr->wlock);
2121
 
2122
	/*
2123
	 * Linkage to the generic ethernet driver.
2124
	 */
2125
	ether->attach = attach;
2126
	ether->transmit = transmit;
2127
	ether->interrupt = interrupt;
2128
	ether->ifstat = ifstat;
2129
 
2130
	ether->promiscuous = promiscuous;
2131
	ether->multicast = multicast;
2132
	ether->shutdown = shutdown;
2133
	ether->arg = ether;
2134
 
2135
	return 0;
2136
}
2137
 
2138
void
2139
etherelnk3link(void)
2140
{
2141
	addethercard("elnk3", etherelnk3reset);
2142
	addethercard("3C509", etherelnk3reset);
2143
	addethercard("3C575", etherelnk3reset);
2144
}