xref: /inferno-os/os/boot/pc/ether8169.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1 /*
2  * Realtek RTL8110S/8169S.
3  * Mostly there. There are some magic register values used
4  * which are not described in any datasheet or driver but seem
5  * to be necessary.
6  * Why is the Fovf descriptor bit set for every received packet?
7  * Occasionally the hardware indicates an input TCP checksum error
8  * although the higher-level software seems to check the packet OK?
9  * No tuning has been done. Only tested on an RTL8110S, there
10  * are slight differences between the chips in the series so some
11  * tweaks may be needed.
12  */
13 #include "u.h"
14 #include "lib.h"
15 #include "mem.h"
16 #include "dat.h"
17 #include "fns.h"
18 #include "io.h"
19 
20 typedef struct QLock { int r; } QLock;
21 #define qlock(i)	while(0)
22 #define qunlock(i)	while(0)
23 #define iallocb		allocb
24 #define iprint		print
25 #define mallocalign(n, a, o, s)	ialloc((n), (a))
26 
27 #include "etherif.h"
28 #include "ethermii.h"
29 
30 enum {					/* registers */
31 	Idr0		= 0x00,		/* MAC address */
32 	Mar0		= 0x08,		/* Multicast address */
33 	Dtccr		= 0x10,		/* Dump Tally Counter Command */
34 	Tnpds		= 0x20,		/* Transmit Normal Priority Descriptors */
35 	Thpds		= 0x28,		/* Transmit High Priority Descriptors */
36 	Flash		= 0x30,		/* Flash Memory Read/Write */
37 	Erbcr		= 0x34,		/* Early Receive Byte Count */
38 	Ersr		= 0x36,		/* Early Receive Status */
39 	Cr		= 0x37,		/* Command Register */
40 	Tppoll		= 0x38,		/* Transmit Priority Polling */
41 	Imr		= 0x3C,		/* Interrupt Mask */
42 	Isr		= 0x3E,		/* Interrupt Status */
43 	Tcr		= 0x40,		/* Transmit Configuration */
44 	Rcr		= 0x44,		/* Receive Configuration */
45 	Tctr		= 0x48,		/* Timer Count */
46 	Mpc		= 0x4C,		/* Missed Packet Counter */
47 	Cr9346		= 0x50,		/* 9346 Command Register */
48 	Config0		= 0x51,		/* Configuration Register 0 */
49 	Config1		= 0x52,		/* Configuration Register 1 */
50 	Config2		= 0x53,		/* Configuration Register 2 */
51 	Config3		= 0x54,		/* Configuration Register 3 */
52 	Config4		= 0x55,		/* Configuration Register 4 */
53 	Config5		= 0x56,		/* Configuration Register 5 */
54 	Timerint	= 0x58,		/* Timer Interrupt */
55 	Mulint		= 0x5C,		/* Multiple Interrupt Select */
56 	Phyar		= 0x60,		/* PHY Access */
57 	Tbicsr0		= 0x64,		/* TBI Control and Status */
58 	Tbianar		= 0x68,		/* TBI Auto-Negotiation Advertisment */
59 	Tbilpar		= 0x6A,		/* TBI Auto-Negotiation Link Partner */
60 	Phystatus	= 0x6C,		/* PHY Status */
61 
62 	Rms		= 0xDA,		/* Receive Packet Maximum Size */
63 	Cplusc		= 0xE0,		/* C+ Command */
64 	Rdsar		= 0xE4,		/* Receive Descriptor Start Address */
65 	Mtps		= 0xEC,		/* Max. Transmit Packet Size */
66 };
67 
68 enum {					/* Dtccr */
69 	Cmd		= 0x00000008,	/* Command */
70 };
71 
72 enum {					/* Cr */
73 	Te		= 0x04,		/* Transmitter Enable */
74 	Re		= 0x08,		/* Receiver Enable */
75 	Rst		= 0x10,		/* Software Reset */
76 };
77 
78 enum {					/* Tppoll */
79 	Fswint		= 0x01,		/* Forced Software Interrupt */
80 	Npq		= 0x40,		/* Normal Priority Queue polling */
81 	Hpq		= 0x80,		/* High Priority Queue polling */
82 };
83 
84 enum {					/* Imr/Isr */
85 	Rok		= 0x0001,	/* Receive OK */
86 	Rer		= 0x0002,	/* Receive Error */
87 	Tok		= 0x0004,	/* Transmit OK */
88 	Ter		= 0x0008,	/* Transmit Error */
89 	Rdu		= 0x0010,	/* Receive Descriptor Unavailable */
90 	Punlc		= 0x0020,	/* Packet Underrun or Link Change */
91 	Fovw		= 0x0040,	/* Receive FIFO Overflow */
92 	Tdu		= 0x0080,	/* Transmit Descriptor Unavailable */
93 	Swint		= 0x0100,	/* Software Interrupt */
94 	Timeout		= 0x4000,	/* Timer */
95 	Serr		= 0x8000,	/* System Error */
96 };
97 
98 enum {					/* Tcr */
99 	MtxdmaSHIFT	= 8,		/* Max. DMA Burst Size */
100 	MtxdmaMASK	= 0x00000700,
101 	Mtxdmaunlimited	= 0x00000700,
102 	Acrc		= 0x00010000,	/* Append CRC (not) */
103 	Lbk0		= 0x00020000,	/* Loopback Test 0 */
104 	Lbk1		= 0x00040000,	/* Loopback Test 1 */
105 	Ifg2		= 0x00080000,	/* Interframe Gap 2 */
106 	HwveridSHIFT	= 23,		/* Hardware Version ID */
107 	HwveridMASK	= 0x7C800000,
108 	Macv01		= 0x00000000,	/* RTL8169 */
109 	Macv02		= 0x00800000,	/* RTL8169S/8110S */
110 	Macv03		= 0x04000000,	/* RTL8169S/8110S */
111 	Macv04		= 0x10000000,	/* RTL8169SB/8110SB */
112 	Macv05		= 0x18000000,	/* RTL8169SC/8110SC */
113 	Macv11		= 0x30000000,	/* RTL8168B/8111B */
114 	Macv12		= 0x38000000,	/* RTL8169B/8111B */
115 	Macv13		= 0x34000000,	/* RTL8101E */
116 	Macv14		= 0x30800000,	/* RTL8100E */
117 	Macv15		= 0x38800000,	/* RTL8100E */
118 	Ifg0		= 0x01000000,	/* Interframe Gap 0 */
119 	Ifg1		= 0x02000000,	/* Interframe Gap 1 */
120 };
121 
122 enum {					/* Rcr */
123 	Aap		= 0x00000001,	/* Accept All Packets */
124 	Apm		= 0x00000002,	/* Accept Physical Match */
125 	Am		= 0x00000004,	/* Accept Multicast */
126 	Ab		= 0x00000008,	/* Accept Broadcast */
127 	Ar		= 0x00000010,	/* Accept Runt */
128 	Aer		= 0x00000020,	/* Accept Error */
129 	Sel9356		= 0x00000040,	/* 9356 EEPROM used */
130 	MrxdmaSHIFT	= 8,		/* Max. DMA Burst Size */
131 	MrxdmaMASK	= 0x00000700,
132 	Mrxdmaunlimited	= 0x00000700,
133 	RxfthSHIFT	= 13,		/* Receive Buffer Length */
134 	RxfthMASK	= 0x0000E000,
135 	Rxfth256	= 0x00008000,
136 	Rxfthnone	= 0x0000E000,
137 	Rer8		= 0x00010000,	/* Accept Error Packets > 8 bytes */
138 	MulERINT	= 0x01000000,	/* Multiple Early Interrupt Select */
139 };
140 
141 enum {					/* Cr9346 */
142 	Eedo		= 0x01,		/* */
143 	Eedi		= 0x02,		/* */
144 	Eesk		= 0x04,		/* */
145 	Eecs		= 0x08,		/* */
146 	Eem0		= 0x40,		/* Operating Mode */
147 	Eem1		= 0x80,
148 };
149 
150 enum {					/* Phyar */
151 	DataMASK	= 0x0000FFFF,	/* 16-bit GMII/MII Register Data */
152 	DataSHIFT	= 0,
153 	RegaddrMASK	= 0x001F0000,	/* 5-bit GMII/MII Register Address */
154 	RegaddrSHIFT	= 16,
155 	Flag		= 0x80000000,	/* */
156 };
157 
158 enum {					/* Phystatus */
159 	Fd		= 0x01,		/* Full Duplex */
160 	Linksts		= 0x02,		/* Link Status */
161 	Speed10		= 0x04,		/* */
162 	Speed100	= 0x08,		/* */
163 	Speed1000	= 0x10,		/* */
164 	Rxflow		= 0x20,		/* */
165 	Txflow		= 0x40,		/* */
166 	Entbi		= 0x80,		/* */
167 };
168 
169 enum {					/* Cplusc */
170 	Mulrw		= 0x0008,	/* PCI Multiple R/W Enable */
171 	Dac		= 0x0010,	/* PCI Dual Address Cycle Enable */
172 	Rxchksum	= 0x0020,	/* Receive Checksum Offload Enable */
173 	Rxvlan		= 0x0040,	/* Receive VLAN De-tagging Enable */
174 	Endian		= 0x0200,	/* Endian Mode */
175 };
176 
177 typedef struct D D;			/* Transmit/Receive Descriptor */
178 struct D {
179 	u32int	control;
180 	u32int	vlan;
181 	u32int	addrlo;
182 	u32int	addrhi;
183 };
184 
185 enum {					/* Transmit Descriptor control */
186 	TxflMASK	= 0x0000FFFF,	/* Transmit Frame Length */
187 	TxflSHIFT	= 0,
188 	Tcps		= 0x00010000,	/* TCP Checksum Offload */
189 	Udpcs		= 0x00020000,	/* UDP Checksum Offload */
190 	Ipcs		= 0x00040000,	/* IP Checksum Offload */
191 	Lgsen		= 0x08000000,	/* Large Send */
192 };
193 
194 enum {					/* Receive Descriptor control */
195 	RxflMASK	= 0x00003FFF,	/* Receive Frame Length */
196 	RxflSHIFT	= 0,
197 	Tcpf		= 0x00004000,	/* TCP Checksum Failure */
198 	Udpf		= 0x00008000,	/* UDP Checksum Failure */
199 	Ipf		= 0x00010000,	/* IP Checksum Failure */
200 	Pid0		= 0x00020000,	/* Protocol ID0 */
201 	Pid1		= 0x00040000,	/* Protocol ID1 */
202 	Crce		= 0x00080000,	/* CRC Error */
203 	Runt		= 0x00100000,	/* Runt Packet */
204 	Res		= 0x00200000,	/* Receive Error Summary */
205 	Rwt		= 0x00400000,	/* Receive Watchdog Timer Expired */
206 	Fovf		= 0x00800000,	/* FIFO Overflow */
207 	Bovf		= 0x01000000,	/* Buffer Overflow */
208 	Bar		= 0x02000000,	/* Broadcast Address Received */
209 	Pam		= 0x04000000,	/* Physical Address Matched */
210 	Mar		= 0x08000000,	/* Multicast Address Received */
211 };
212 
213 enum {					/* General Descriptor control */
214 	Ls		= 0x10000000,	/* Last Segment Descriptor */
215 	Fs		= 0x20000000,	/* First Segment Descriptor */
216 	Eor		= 0x40000000,	/* End of Descriptor Ring */
217 	Own		= 0x80000000,	/* Ownership */
218 };
219 
220 /*
221  */
222 enum {					/* Ring sizes  (<= 1024) */
223 	Ntd		= 8,		/* Transmit Ring */
224 	Nrd		= 32,		/* Receive Ring */
225 
226 	Mps		= ROUNDUP(ETHERMAXTU+4, 128),
227 };
228 
229 typedef struct Dtcc Dtcc;
230 struct Dtcc {
231 	u64int	txok;
232 	u64int	rxok;
233 	u64int	txer;
234 	u32int	rxer;
235 	u16int	misspkt;
236 	u16int	fae;
237 	u32int	tx1col;
238 	u32int	txmcol;
239 	u64int	rxokph;
240 	u64int	rxokbrd;
241 	u32int	rxokmu;
242 	u16int	txabt;
243 	u16int	txundrn;
244 };
245 
246 enum {						/* Variants */
247 	Rtl8100e	= (0x8136<<16)|0x10EC,	/* RTL810[01]E ? */
248 	Rtl8169c		= (0x0116<<16)|0x16EC,	/* RTL8169C+ (USR997902) */
249 	Rtl8169sc	= (0x8167<<16)|0x10EC,	/* RTL8169SC */
250 	Rtl8168b	= (0x8168<<16)|0x10EC,	/* RTL8168B */
251 	Rtl8169		= (0x8169<<16)|0x10EC,	/* RTL8169 */
252 };
253 
254 typedef struct Ctlr Ctlr;
255 typedef struct Ctlr {
256 	int	port;
257 	Pcidev*	pcidev;
258 	Ctlr*	next;
259 	int	active;
260 
261 	void*	nic;
262 
263 	QLock	alock;			/* attach */
264 	Lock	ilock;			/* init */
265 	int	init;			/*  */
266 
267 	int	pciv;			/*  */
268 	int	macv;			/* MAC version */
269 	int	phyv;			/* PHY version */
270 
271 	Mii*	mii;
272 
273 	Lock	tlock;			/* transmit */
274 	D*	td;			/* descriptor ring */
275 	Block**	tb;			/* transmit buffers */
276 	int	ntd;
277 
278 	int	tdh;			/* head - producer index (host) */
279 	int	tdt;			/* tail - consumer index (NIC) */
280 	int	ntdfree;
281 	int	ntq;
282 
283 	int	mtps;			/* Max. Transmit Packet Size */
284 
285 	Lock	rlock;			/* receive */
286 	D*	rd;			/* descriptor ring */
287 	void**	rb;			/* receive buffers */
288 	int	nrd;
289 
290 	int	rdh;			/* head - producer index (NIC) */
291 	int	rdt;			/* tail - consumer index (host) */
292 	int	nrdfree;
293 
294 	int	rcr;			/* receive configuration register */
295 
296 	QLock	slock;			/* statistics */
297 	Dtcc*	dtcc;
298 	uint	txdu;
299 	uint	tcpf;
300 	uint	udpf;
301 	uint	ipf;
302 	uint	fovf;
303 	uint	ierrs;
304 	uint	rer;
305 	uint	rdu;
306 	uint	punlc;
307 	uint	fovw;
308 } Ctlr;
309 
310 static Ctlr* rtl8169ctlrhead;
311 static Ctlr* rtl8169ctlrtail;
312 
313 #define csr8r(c, r)	(inb((c)->port+(r)))
314 #define csr16r(c, r)	(ins((c)->port+(r)))
315 #define csr32r(c, r)	(inl((c)->port+(r)))
316 #define csr8w(c, r, b)	(outb((c)->port+(r), (int)(b)))
317 #define csr16w(c, r, w)	(outs((c)->port+(r), (ushort)(w)))
318 #define csr32w(c, r, l)	(outl((c)->port+(r), (ulong)(l)))
319 
320 static int
321 rtl8169miimir(Mii* mii, int pa, int ra)
322 {
323 	uint r;
324 	int timeo;
325 	Ctlr *ctlr;
326 
327 	if(pa != 1)
328 		return -1;
329 	ctlr = mii->ctlr;
330 
331 	r = (ra<<16) & RegaddrMASK;
332 	csr32w(ctlr, Phyar, r);
333 	delay(1);
334 	for(timeo = 0; timeo < 2000; timeo++){
335 		if((r = csr32r(ctlr, Phyar)) & Flag)
336 			break;
337 		microdelay(100);
338 	}
339 	if(!(r & Flag))
340 		return -1;
341 
342 	return (r & DataMASK)>>DataSHIFT;
343 }
344 
345 static int
346 rtl8169miimiw(Mii* mii, int pa, int ra, int data)
347 {
348 	uint r;
349 	int timeo;
350 	Ctlr *ctlr;
351 
352 	if(pa != 1)
353 		return -1;
354 	ctlr = mii->ctlr;
355 
356 	r = Flag|((ra<<16) & RegaddrMASK)|((data<<DataSHIFT) & DataMASK);
357 	csr32w(ctlr, Phyar, r);
358 	delay(1);
359 	for(timeo = 0; timeo < 2000; timeo++){
360 		if(!((r = csr32r(ctlr, Phyar)) & Flag))
361 			break;
362 		microdelay(100);
363 	}
364 	if(r & Flag)
365 		return -1;
366 
367 	return 0;
368 }
369 
370 static int
371 rtl8169mii(Ctlr* ctlr)
372 {
373 	MiiPhy *phy;
374 
375 	/*
376 	 * Link management.
377 	 */
378 	if((ctlr->mii = malloc(sizeof(Mii))) == nil)
379 		return -1;
380 	ctlr->mii->mir = rtl8169miimir;
381 	ctlr->mii->miw = rtl8169miimiw;
382 	ctlr->mii->ctlr = ctlr;
383 
384 	/*
385 	 * Get rev number out of Phyidr2 so can config properly.
386 	 * There's probably more special stuff for Macv0[234] needed here.
387 	 */
388 	ctlr->phyv = rtl8169miimir(ctlr->mii, 1, Phyidr2) & 0x0F;
389 	if(ctlr->macv == Macv02){
390 		csr8w(ctlr, 0x82, 1);				/* magic */
391 		rtl8169miimiw(ctlr->mii, 1, 0x0B, 0x0000);	/* magic */
392 	}
393 
394 	if(mii(ctlr->mii, (1<<1)) == 0 || (phy = ctlr->mii->curphy) == nil){
395 		free(ctlr->mii);
396 		ctlr->mii = nil;
397 		return -1;
398 	}
399 	print("oui %#ux phyno %d, macv = %#8.8ux phyv = %#4.4ux\n",
400 		phy->oui, phy->phyno, ctlr->macv, ctlr->phyv);
401 
402 	miiane(ctlr->mii, ~0, ~0, ~0);
403 
404 	return 0;
405 }
406 
407 static void
408 rtl8169halt(Ctlr* ctlr)
409 {
410 	csr8w(ctlr, Cr, 0);
411 	csr16w(ctlr, Imr, 0);
412 	csr16w(ctlr, Isr, ~0);
413 }
414 
415 static int
416 rtl8169reset(Ctlr* ctlr)
417 {
418 	u32int r;
419 	int timeo;
420 
421 	/*
422 	 * Soft reset the controller.
423 	 */
424 	csr8w(ctlr, Cr, Rst);
425 	for(r = timeo = 0; timeo < 1000; timeo++){
426 		r = csr8r(ctlr, Cr);
427 		if(!(r & Rst))
428 			break;
429 		delay(1);
430 	}
431 	rtl8169halt(ctlr);
432 
433 	if(r & Rst)
434 		return -1;
435 	return 0;
436 }
437 
438 static void
439 rtl8169detach(Ether* edev)
440 {
441 	rtl8169reset(edev->ctlr);
442 }
443 
444 static void
445 rtl8169replenish(Ctlr* ctlr)
446 {
447 	D *d;
448 	int rdt;
449 	void *bp;
450 
451 	rdt = ctlr->rdt;
452 	while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
453 		d = &ctlr->rd[rdt];
454 		if(ctlr->rb[rdt] == nil){
455 			/*
456 			 * simple allocation for now
457 			 */
458 			bp = mallocalign(Mps, 8, 0, 0);
459 			ctlr->rb[rdt] = bp;
460 			d->addrlo = PCIWADDR(bp);
461 			d->addrhi = 0;
462 		}
463 		coherence();
464 		d->control |= Own|Mps;
465 		rdt = NEXT(rdt, ctlr->nrd);
466 		ctlr->nrdfree++;
467 	}
468 	ctlr->rdt = rdt;
469 }
470 
471 static int
472 rtl8169init(Ether* edev)
473 {
474 	u32int r;
475 	Ctlr *ctlr;
476 	u8int cplusc;
477 
478 	ctlr = edev->ctlr;
479 	ilock(&ctlr->ilock);
480 
481 	rtl8169halt(ctlr);
482 
483 	/*
484 	 * MAC Address.
485 	 * Must put chip into config register write enable mode.
486 	 */
487 	csr8w(ctlr, Cr9346, Eem1|Eem0);
488 	r = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
489 	csr32w(ctlr, Idr0, r);
490 	r = (edev->ea[5]<<8)|edev->ea[4];
491 	csr32w(ctlr, Idr0+4, r);
492 
493 	/*
494 	 * Transmitter.
495 	 */
496 	memset(ctlr->td, 0, sizeof(D)*ctlr->ntd);
497 	ctlr->tdh = ctlr->tdt = 0;
498 	ctlr->td[ctlr->ntd-1].control = Eor;
499 
500 	/*
501 	 * Receiver.
502 	 * Need to do something here about the multicast filter.
503 	 */
504 	memset(ctlr->rd, 0, sizeof(D)*ctlr->nrd);
505 	ctlr->rdh = ctlr->rdt = 0;
506 	ctlr->rd[ctlr->nrd-1].control = Eor;
507 	rtl8169replenish(ctlr);
508 	ctlr->rcr = Rxfthnone|Mrxdmaunlimited|Ab|Apm;
509 
510 	/*
511 	 * Mtps is in units of 128 except for the RTL8169
512 	 * where is is 32. If using jumbo frames should be
513 	 * set to 0x3F.
514 	 * Setting Mulrw in Cplusc disables the Tx/Rx DMA burst
515 	 * settings in Tcr/Rcr; the (1<<14) is magic.
516 	 */
517 	ctlr->mtps = HOWMANY(Mps, 128);
518 	cplusc = csr16r(ctlr, Cplusc) & ~(1<<14);
519 	cplusc |= Rxchksum|Mulrw;
520 	switch(ctlr->macv){
521 	default:
522 		return -1;
523 	case Macv01:
524 		ctlr->mtps = HOWMANY(Mps, 32);
525 		break;
526 	case Macv02:
527 	case Macv03:
528 		cplusc |= (1<<14);			/* magic */
529 		break;
530 	case Macv05:
531 		/*
532 		 * This is interpreted from clearly bogus code
533 		 * in the manufacturer-supplied driver, it could
534 		 * be wrong. Untested.
535 		 */
536 		r = csr8r(ctlr, Config2) & 0x07;
537 		if(r == 0x01)				/* 66MHz PCI */
538 			csr32w(ctlr, 0x7C, 0x0007FFFF);	/* magic */
539 		else
540 			csr32w(ctlr, 0x7C, 0x0007FF00);	/* magic */
541 		pciclrmwi(ctlr->pcidev);
542 		break;
543 	case Macv13:
544 		/*
545 		 * This is interpreted from clearly bogus code
546 		 * in the manufacturer-supplied driver, it could
547 		 * be wrong. Untested.
548 		 */
549 		pcicfgw8(ctlr->pcidev, 0x68, 0x00);	/* magic */
550 		pcicfgw8(ctlr->pcidev, 0x69, 0x08);	/* magic */
551 		break;
552 	case Macv04:
553 	case Macv11:
554 	case Macv12:
555 	case Macv14:
556 	case Macv15:
557 		break;
558 	}
559 
560 	/*
561 	 * Enable receiver/transmitter.
562 	 * Need to do this first or some of the settings below
563 	 * won't take.
564 	 */
565 	switch(ctlr->pciv){
566 	default:
567 		csr8w(ctlr, Cr, Te|Re);
568 		csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
569 		csr32w(ctlr, Rcr, ctlr->rcr);
570 	case Rtl8169sc:
571 	case Rtl8168b:
572 		break;
573 	}
574 
575 	/*
576 	 * Interrupts.
577 	 * Disable Tdu|Tok for now, the transmit routine will tidy.
578 	 * Tdu means the NIC ran out of descriptors to send, so it
579 	 * doesn't really need to ever be on.
580 	 */
581 	csr32w(ctlr, Timerint, 0);
582 	csr16w(ctlr, Imr, Serr|Timeout|Fovw|Punlc|Rdu|Ter|Rer|Rok);
583 
584 	/*
585 	 * Clear missed-packet counter;
586 	 * initial early transmit threshold value;
587 	 * set the descriptor ring base addresses;
588 	 * set the maximum receive packet size;
589 	 * no early-receive interrupts.
590 	 */
591 	csr32w(ctlr, Mpc, 0);
592 	csr8w(ctlr, Mtps, ctlr->mtps);
593 	csr32w(ctlr, Tnpds+4, 0);
594 	csr32w(ctlr, Tnpds, PCIWADDR(ctlr->td));
595 	csr32w(ctlr, Rdsar+4, 0);
596 	csr32w(ctlr, Rdsar, PCIWADDR(ctlr->rd));
597 	csr16w(ctlr, Rms, Mps);
598 	r = csr16r(ctlr, Mulint) & 0xF000;
599 	csr16w(ctlr, Mulint, r);
600 	csr16w(ctlr, Cplusc, cplusc);
601 
602 	/*
603 	 * Set configuration.
604 	 */
605 	switch(ctlr->pciv){
606 	default:
607 		break;
608 	case Rtl8169sc:
609 		csr16w(ctlr, 0xE2, 0);			/* magic */
610 		csr8w(ctlr, Cr, Te|Re);
611 		csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
612 		csr32w(ctlr, Rcr, ctlr->rcr);
613 		break;
614 	case Rtl8168b:
615 	case Rtl8169c:
616 		csr16w(ctlr, 0xE2, 0);			/* magic */
617 		csr16w(ctlr, Cplusc, 0x2000);		/* magic */
618 		csr8w(ctlr, Cr, Te|Re);
619 		csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
620 		csr32w(ctlr, Rcr, ctlr->rcr);
621 		csr16w(ctlr, Rms, 0x0800);
622 		csr8w(ctlr, Mtps, 0x3F);
623 		break;
624 	}
625 
626 	csr8w(ctlr, Cr9346, 0);
627 
628 	iunlock(&ctlr->ilock);
629 
630 //	rtl8169mii(ctlr);
631 
632 	return 0;
633 }
634 
635 static void
636 rtl8169attach(Ether* edev)
637 {
638 	int timeo;
639 	Ctlr *ctlr;
640 
641 	ctlr = edev->ctlr;
642 	qlock(&ctlr->alock);
643 	if(ctlr->init == 0){
644 		/*
645 		 * Handle allocation/init errors here.
646 		 */
647 		ctlr->td = xspanalloc(sizeof(D)*Ntd, 256, 0);
648 		ctlr->tb = malloc(Ntd*sizeof(Block*));
649 		ctlr->ntd = Ntd;
650 		ctlr->rd = xspanalloc(sizeof(D)*Nrd, 256, 0);
651 		ctlr->rb = malloc(Nrd*sizeof(Block*));
652 		ctlr->nrd = Nrd;
653 		ctlr->dtcc = xspanalloc(sizeof(Dtcc), 64, 0);
654 		rtl8169init(edev);
655 		ctlr->init = 1;
656 	}
657 	qunlock(&ctlr->alock);
658 
659 	for(timeo = 0; timeo < 3500; timeo++){
660 		if(miistatus(ctlr->mii) == 0)
661 			break;
662 		delay(10);
663 	}
664 }
665 
666 static void
667 rtl8169transmit(Ether* edev)
668 {
669 	D *d;
670 	Block *bp;
671 	Ctlr *ctlr;
672 	int control, x;
673 	RingBuf *tb;
674 
675 	ctlr = edev->ctlr;
676 
677 	ilock(&ctlr->tlock);
678 	for(x = ctlr->tdh; ctlr->ntq > 0; x = NEXT(x, ctlr->ntd)){
679 		d = &ctlr->td[x];
680 		if((control = d->control) & Own)
681 			break;
682 
683 		/*
684 		 * Check errors and log here.
685 		 */
686 		USED(control);
687 
688 		/*
689 		 * Free it up.
690 		 * Need to clean the descriptor here? Not really.
691 		 * Simple freeb for now (no chain and freeblist).
692 		 * Use ntq count for now.
693 		 */
694 		freeb(ctlr->tb[x]);
695 		ctlr->tb[x] = nil;
696 		d->control &= Eor;
697 
698 		ctlr->ntq--;
699 	}
700 	ctlr->tdh = x;
701 
702 	x = ctlr->tdt;
703 	while(ctlr->ntq < (ctlr->ntd-1)){
704 		tb = &edev->tb[edev->ti];
705 		if(tb->owner != Interface)
706 			break;
707 
708 		bp = allocb(tb->len);
709 		memmove(bp->wp, tb->pkt, tb->len);
710 		memmove(bp->wp+Eaddrlen, edev->ea, Eaddrlen);
711 		bp->wp += tb->len;
712 
713 		tb->owner = Host;
714 		edev->ti = NEXT(edev->ti, edev->ntb);
715 
716 		d = &ctlr->td[x];
717 		d->addrlo = PCIWADDR(bp->rp);
718 		d->addrhi = 0;
719 		ctlr->tb[x] = bp;
720 		coherence();
721 		d->control |= Own|Fs|Ls|((BLEN(bp)<<TxflSHIFT) & TxflMASK);
722 
723 		x = NEXT(x, ctlr->ntd);
724 		ctlr->ntq++;
725 	}
726 	if(x != ctlr->tdt){
727 		ctlr->tdt = x;
728 		csr8w(ctlr, Tppoll, Npq);
729 	}
730 	else if(ctlr->ntq >= (ctlr->ntd-1))
731 		ctlr->txdu++;
732 
733 	iunlock(&ctlr->tlock);
734 }
735 
736 static void
737 rtl8169receive(Ether* edev)
738 {
739 	D *d;
740 	int len, rdh;
741 	Ctlr *ctlr;
742 	u32int control;
743 	RingBuf *ring;
744 
745 	ctlr = edev->ctlr;
746 
747 	rdh = ctlr->rdh;
748 	for(;;){
749 		d = &ctlr->rd[rdh];
750 
751 		if(d->control & Own)
752 			break;
753 
754 		control = d->control;
755 		if((control & (Fs|Ls|Res)) == (Fs|Ls)){
756 			len = ((control & RxflMASK)>>RxflSHIFT) - 4;
757 
758 			ring = &edev->rb[edev->ri];
759 			if(ring->owner == Interface){
760 				ring->owner = Host;
761 				ring->len = len;
762 				memmove(ring->pkt, ctlr->rb[rdh], len);
763 				edev->ri = NEXT(edev->ri, edev->nrb);
764 			}
765 		}
766 		else{
767 			/*
768 			 * Error stuff here.
769 			print("control %#8.8ux\n", control);
770 			 */
771 		}
772 		d->control &= Eor;
773 		ctlr->nrdfree--;
774 		rdh = NEXT(rdh, ctlr->nrd);
775 	}
776 	ctlr->rdh = rdh;
777 
778 	if(ctlr->nrdfree < ctlr->nrd/2)
779 		rtl8169replenish(ctlr);
780 }
781 
782 static void
783 rtl8169interrupt(Ureg*, void* arg)
784 {
785 	Ctlr *ctlr;
786 	Ether *edev;
787 	u32int isr;
788 
789 	edev = arg;
790 	ctlr = edev->ctlr;
791 
792 	while((isr = csr16r(ctlr, Isr)) != 0 && isr != 0xFFFF){
793 		csr16w(ctlr, Isr, isr);
794 		if(isr & (Fovw|Punlc|Rdu|Rer|Rok)){
795 			rtl8169receive(edev);
796 			if(!(isr & (Punlc|Rok)))
797 				ctlr->ierrs++;
798 			if(isr & Rer)
799 				ctlr->rer++;
800 			if(isr & Rdu)
801 				ctlr->rdu++;
802 			if(isr & Punlc)
803 				ctlr->punlc++;
804 			if(isr & Fovw)
805 				ctlr->fovw++;
806 			isr &= ~(Fovw|Rdu|Rer|Rok);
807 		}
808 
809 		if(isr & (Tdu|Ter|Tok)){
810 			rtl8169transmit(edev);
811 			isr &= ~(Tdu|Ter|Tok);
812 		}
813 
814 		if(isr & Punlc){
815 //			rtl8169link(edev);
816 			isr &= ~Punlc;
817 		}
818 
819 		/*
820 		 * Some of the reserved bits get set sometimes...
821 		 */
822 		if(isr & (Serr|Timeout|Tdu|Fovw|Punlc|Rdu|Ter|Tok|Rer|Rok))
823 			panic("rtl8169interrupt: imr %#4.4ux isr %#4.4ux\n",
824 				csr16r(ctlr, Imr), isr);
825 	}
826 }
827 
828 static void
829 rtl8169pci(void)
830 {
831 	Pcidev *p;
832 	Ctlr *ctlr;
833 	int i, port;
834 	u32int bar;
835 
836 	p = nil;
837 	while(p = pcimatch(p, 0, 0)){
838 		if(p->ccrb != 0x02 || p->ccru != 0)
839 			continue;
840 
841 		switch(i = ((p->did<<16)|p->vid)){
842 		default:
843 			continue;
844 		case Rtl8100e:			/* RTL810[01]E ? */
845 		case Rtl8169c:			/* RTL8169C */
846 		case Rtl8169sc:			/* RTL8169SC */
847 		case Rtl8168b:			/* RTL8168B */
848 		case Rtl8169:			/* RTL8169 */
849 			break;
850 		case (0xC107<<16)|0x1259:	/* Corega CG-LAPCIGT */
851 			i = Rtl8169;
852 			break;
853 		}
854 
855 		bar = p->mem[0].bar;
856 		port = bar & ~0x01;
857 		if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
858 			print("rtl8169: port %#ux in use\n", port);
859 			continue;
860 		}
861 		ctlr = malloc(sizeof(Ctlr));
862 		ctlr->port = port;
863 		ctlr->pcidev = p;
864 		ctlr->pciv = i;
865 
866 		if(pcigetpms(p) > 0){
867 			pcisetpms(p, 0);
868 
869 			for(i = 0; i < 6; i++)
870 				pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
871 			pcicfgw8(p, PciINTL, p->intl);
872 			pcicfgw8(p, PciLTR, p->ltr);
873 			pcicfgw8(p, PciCLS, p->cls);
874 			pcicfgw16(p, PciPCR, p->pcr);
875 		}
876 
877 		if(rtl8169reset(ctlr)){
878 			iofree(port);
879 			free(ctlr);
880 			continue;
881 		}
882 
883 		/*
884 		 * Extract the chip hardware version,
885 		 * needed to configure each properly.
886 		 */
887 		ctlr->macv = csr32r(ctlr, Tcr) & HwveridMASK;
888 
889 		rtl8169mii(ctlr);
890 
891 		pcisetbme(p);
892 
893 		if(rtl8169ctlrhead != nil)
894 			rtl8169ctlrtail->next = ctlr;
895 		else
896 			rtl8169ctlrhead = ctlr;
897 		rtl8169ctlrtail = ctlr;
898 	}
899 }
900 
901 int
902 rtl8169pnp(Ether* edev)
903 {
904 	u32int r;
905 	Ctlr *ctlr;
906 
907 	if(rtl8169ctlrhead == nil)
908 		rtl8169pci();
909 
910 	/*
911 	 * Any adapter matches if no edev->port is supplied,
912 	 * otherwise the ports must match.
913 	 */
914 	for(ctlr = rtl8169ctlrhead; ctlr != nil; ctlr = ctlr->next){
915 		if(ctlr->active)
916 			continue;
917 		if(edev->port == 0 || edev->port == ctlr->port){
918 			ctlr->active = 1;
919 			break;
920 		}
921 	}
922 	if(ctlr == nil)
923 		return -1;
924 
925 	edev->ctlr = ctlr;
926 	edev->port = ctlr->port;
927 	edev->irq = ctlr->pcidev->intl;
928 	edev->tbdf = ctlr->pcidev->tbdf;
929 //	edev->mbps = 100;
930 
931 	/*
932 	 * Pull the MAC address out of the chip.
933 	 */
934 	r = csr32r(ctlr, Idr0);
935 	edev->ea[0] = r;
936 	edev->ea[1] = r>>8;
937 	edev->ea[2] = r>>16;
938 	edev->ea[3] = r>>24;
939 	r = csr32r(ctlr, Idr0+4);
940 	edev->ea[4] = r;
941 	edev->ea[5] = r>>8;
942 
943 	/*
944 	 * Linkage to the generic ethernet driver.
945 	 */
946 	edev->attach = rtl8169attach;
947 	edev->transmit = rtl8169transmit;
948 	edev->interrupt = rtl8169interrupt;
949 	edev->detach = rtl8169detach;
950 //	edev->ifstat = rtl8169ifstat;
951 //	edev->ctl = nil;
952 //
953 //	edev->arg = edev;
954 //	edev->promiscuous = rtl8169promiscuous;
955 //	edev->multicast = rtl8169multicast;
956 
957 	return 0;
958 }
959