xref: /minix/minix/drivers/net/rtl8169/rtl8169.c (revision e4dbab1e)
1 /*
2  * rtl8169.c
3  *
4  * This file contains a ethernet device driver for Realtek rtl8169 based
5  * ethernet cards.
6  *
7  */
8 
9 #include <minix/drivers.h>
10 #include <minix/netdriver.h>
11 
12 #include <machine/pci.h>
13 #include <assert.h>
14 
15 #include "rtl8169.h"
16 
17 #define VERBOSE		0		/* display message during init */
18 
19 #define RE_DTCC_VALUE	600		/* DTCC Update once every 10 minutes */
20 
21 #define RX_CONFIG_MASK	0xff7e1880	/* Clears the bits supported by chip */
22 
23 #define RE_INTR_MASK	(RL_IMR_TDU | RL_IMR_FOVW | RL_IMR_PUN | RL_IMR_RDU | \
24 			 RL_IMR_TER | RL_IMR_TOK | RL_IMR_RER | RL_IMR_ROK)
25 
26 #define RL_ENVVAR	"RTLETH"	/* Configuration */
27 
28 typedef struct re_desc
29 {
30 	u32_t status;		/* command/status */
31 	u32_t vlan;		/* VLAN */
32 	u32_t addr_low;		/* low 32-bits of physical buffer address */
33 	u32_t addr_high;	/* high 32-bits of physical buffer address */
34 } re_desc;
35 
36 typedef struct re_dtcc
37 {
38 	u32_t	TxOk_low;	/* low 32-bits of Tx Ok packets */
39 	u32_t	TxOk_high;	/* high 32-bits of Tx Ok packets */
40 	u32_t	RxOk_low;	/* low 32-bits of Rx Ok packets */
41 	u32_t	RxOk_high;	/* high 32-bits of Rx Ok packets */
42 	u32_t	TxEr_low;	/* low 32-bits of Tx errors */
43 	u32_t	TxEr_high;	/* high 32-bits of Tx errors */
44 	u32_t	RxEr;		/* Rx errors */
45 	u16_t	MissPkt;	/* Missed packets */
46 	u16_t	FAE;		/* Frame Alignment Error packets (MII only) */
47 	u32_t	Tx1Col;		/* Tx Ok packets with 1 collision before Tx */
48 	u32_t	TxMCol;		/* Tx Ok packets with 2..15 collisions */
49 	u32_t	RxOkPhy_low;	/* low 32-bits of Rx Ok packets for us */
50 	u32_t	RxOkPhy_high;	/* high 32-bits of Rx Ok packets for us */
51 	u32_t	RxOkBrd_low;	/* low 32-bits of Rx Ok broadcast packets */
52 	u32_t	RxOkBrd_high;	/* high 32-bits of Rx Ok broadcast packets */
53 	u32_t	RxOkMul;	/* Rx Ok multicast packets */
54 	u16_t	TxAbt;		/* Tx abort packets */
55 	u16_t	TxUndrn;	/* Tx underrun packets */
56 } re_dtcc;
57 
58 typedef struct re {
59 	port_t re_base_port;
60 	int re_irq;
61 	int re_mode;
62 	int re_link_up;
63 	int re_got_int;
64 	int re_send_int;
65 	int re_report_link;
66 	int re_need_reset;
67 	int re_tx_alive;
68 	u32_t re_mac;
69 	const char *re_model;
70 
71 	/* Rx */
72 	int re_rx_head;
73 	struct {
74 		phys_bytes ret_buf;
75 		char *v_ret_buf;
76 	} re_rx[N_RX_DESC];
77 
78 	re_desc *re_rx_desc;	/* Rx descriptor buffer */
79 	phys_bytes p_rx_desc;	/* Rx descriptor buffer physical */
80 
81 	/* Tx */
82 	int re_tx_head;
83 	struct {
84 		int ret_busy;
85 		phys_bytes ret_buf;
86 		char *v_ret_buf;
87 	} re_tx[N_TX_DESC];
88 	re_desc *re_tx_desc;	/* Tx descriptor buffer */
89 	phys_bytes p_tx_desc;	/* Tx descriptor buffer physical */
90 	int re_tx_busy;		/* how many Tx descriptors are busy? */
91 
92 	int re_hook_id;		/* IRQ hook id at kernel */
93 	phys_bytes dtcc_buf;	/* Dump Tally Counter buffer physical */
94 	re_dtcc *v_dtcc_buf;	/* Dump Tally Counter buffer */
95 	u32_t dtcc_counter;	/* DTCC update counter */
96 	u32_t interrupts;
97 } re_t;
98 
99 static re_t re_state;
100 
101 static unsigned my_inb(u16_t port)
102 {
103 	u32_t value;
104 	int s;
105 	if ((s = sys_inb(port, &value)) != OK)
106 		printf("RTL8169: warning, sys_inb failed: %d\n", s);
107 	return value;
108 }
109 static unsigned my_inw(u16_t port)
110 {
111 	u32_t value;
112 	int s;
113 	if ((s = sys_inw(port, &value)) != OK)
114 		printf("RTL8169: warning, sys_inw failed: %d\n", s);
115 	return value;
116 }
117 static unsigned my_inl(u16_t port)
118 {
119 	u32_t value;
120 	int s;
121 	if ((s = sys_inl(port, &value)) != OK)
122 		printf("RTL8169: warning, sys_inl failed: %d\n", s);
123 	return value;
124 }
125 #define rl_inb(port, offset)	(my_inb((port) + (offset)))
126 #define rl_inw(port, offset)	(my_inw((port) + (offset)))
127 #define rl_inl(port, offset)	(my_inl((port) + (offset)))
128 
129 static void my_outb(u16_t port, u8_t value)
130 {
131 	int s;
132 
133 	if ((s = sys_outb(port, value)) != OK)
134 		printf("RTL8169: warning, sys_outb failed: %d\n", s);
135 }
136 static void my_outw(u16_t port, u16_t value)
137 {
138 	int s;
139 
140 	if ((s = sys_outw(port, value)) != OK)
141 		printf("RTL8169: warning, sys_outw failed: %d\n", s);
142 }
143 static void my_outl(u16_t port, u32_t value)
144 {
145 	int s;
146 
147 	if ((s = sys_outl(port, value)) != OK)
148 		printf("RTL8169: warning, sys_outl failed: %d\n", s);
149 }
150 #define rl_outb(port, offset, value)	(my_outb((port) + (offset), (value)))
151 #define rl_outw(port, offset, value)	(my_outw((port) + (offset), (value)))
152 #define rl_outl(port, offset, value)	(my_outl((port) + (offset), (value)))
153 
154 static int rl_init(unsigned int instance, netdriver_addr_t *addr,
155 	uint32_t *caps, unsigned int *ticks);
156 static int rl_probe(re_t *rep, unsigned int skip);
157 static void rl_init_buf(re_t *rep);
158 static void rl_init_hw(re_t *rep, netdriver_addr_t *addr,
159 	unsigned int instance);
160 static void rl_reset_hw(re_t *rep);
161 static void rl_confaddr(re_t *rep, netdriver_addr_t *addr,
162 	unsigned int instance);
163 static void rl_set_hwaddr(const netdriver_addr_t *addr);
164 static void rl_stop(void);
165 static void rl_rec_mode(re_t *rep);
166 static void rl_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list,
167 	unsigned int mcast_count);
168 static ssize_t rl_recv(struct netdriver_data *data, size_t max);
169 static int rl_send(struct netdriver_data *data, size_t size);
170 static unsigned int rl_get_link(uint32_t *media);
171 static void rl_intr(unsigned int mask);
172 static void rl_check_ints(re_t *rep);
173 static void rl_do_reset(re_t *rep);
174 #if VERBOSE
175 static void rl_report_link(re_t *rep);
176 static void dump_phy(const re_t *rep);
177 #endif
178 static void rl_handler(re_t *rep);
179 static void rl_tick(void);
180 
181 static const struct netdriver rl_table = {
182 	.ndr_name	= "re",
183 	.ndr_init	= rl_init,
184 	.ndr_stop	= rl_stop,
185 	.ndr_set_mode	= rl_set_mode,
186 	.ndr_set_hwaddr	= rl_set_hwaddr,
187 	.ndr_recv	= rl_recv,
188 	.ndr_send	= rl_send,
189 	.ndr_get_link	= rl_get_link,
190 	.ndr_intr	= rl_intr,
191 	.ndr_tick	= rl_tick
192 };
193 
194 /*===========================================================================*
195  *				main					     *
196  *===========================================================================*/
197 int main(int argc, char *argv[])
198 {
199 	env_setargs(argc, argv);
200 
201 	netdriver_task(&rl_table);
202 
203 	return 0;
204 }
205 
206 /*===========================================================================*
207  *				rl_init					     *
208  *===========================================================================*/
209 static int rl_init(unsigned int instance, netdriver_addr_t *addr,
210 	uint32_t *caps, unsigned int *ticks)
211 {
212 /* Initialize the rtl8169 driver. */
213 	re_t *rep;
214 
215 	/* Initialize driver state. */
216 	rep = &re_state;
217 	memset(rep, 0, sizeof(*rep));
218 
219 	/* Try to find a matching device. */
220 	if (!rl_probe(rep, instance))
221 		return ENXIO;
222 
223 	/* Claim buffer memory now. */
224 	rl_init_buf(&re_state);
225 
226 	/* Initialize the device we found. */
227 	rl_init_hw(rep, addr, instance);
228 
229 	*caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST | NDEV_CAP_HWADDR;
230 	*ticks = sys_hz();
231 	return OK;
232 }
233 
234 /*===========================================================================*
235  *				rl_stop					     *
236  *===========================================================================*/
237 static void rl_stop(void)
238 {
239 	re_t *rep;
240 
241 	rep = &re_state;
242 
243 	rl_outb(rep->re_base_port, RL_CR, RL_CR_RST);
244 }
245 
246 static void mdio_write(u16_t port, int regaddr, int value)
247 {
248 	int i;
249 
250 	rl_outl(port, RL_PHYAR,
251 	    0x80000000 | (regaddr & 0x1F) << 16 | (value & 0xFFFF));
252 
253 	for (i = 20; i > 0; i--) {
254 		/*
255 		 * Check if the RTL8169 has completed writing to the specified
256 		 * MII register
257 		 */
258 		if (!(rl_inl(port, RL_PHYAR) & 0x80000000))
259 			break;
260 		else
261 			micro_delay(50);
262 	}
263 }
264 
265 static int mdio_read(u16_t port, int regaddr)
266 {
267 	int i, value = -1;
268 
269 	rl_outl(port, RL_PHYAR, (regaddr & 0x1F) << 16);
270 
271 	for (i = 20; i > 0; i--) {
272 		/*
273 		 * Check if the RTL8169 has completed retrieving data from
274 		 * the specified MII register
275 		 */
276 		if (rl_inl(port, RL_PHYAR) & 0x80000000) {
277 			value = (int)(rl_inl(port, RL_PHYAR) & 0xFFFF);
278 			break;
279 		} else
280 			micro_delay(50);
281 	}
282 	return value;
283 }
284 
285 static void rtl8169_update_stat(re_t *rep)
286 {
287 	static u64_t last_miss = 0, last_coll = 0;
288 	u64_t miss, coll;
289 	port_t port;
290 	int i;
291 
292 	port = rep->re_base_port;
293 
294 	/* Dump Tally Counter Command */
295 	rl_outl(port, RL_DTCCR_HI, 0);		/* 64 bits */
296 	rl_outl(port, RL_DTCCR_LO, rep->dtcc_buf | RL_DTCCR_CMD);
297 	for (i = 0; i < 1000; i++) {
298 		if (!(rl_inl(port, RL_DTCCR_LO) & RL_DTCCR_CMD))
299 			break;
300 		micro_delay(10);
301 	}
302 
303 	/* Update counters */
304 	miss = rep->v_dtcc_buf->MissPkt;
305 	netdriver_stat_ierror(miss - last_miss);
306 	last_miss = miss;
307 
308 	coll = rep->v_dtcc_buf->Tx1Col + rep->v_dtcc_buf->TxMCol;
309 	netdriver_stat_coll(coll - last_coll);
310 	last_coll = coll;
311 }
312 
313 #if 0
314 /*===========================================================================*
315  *				rtl8169_dump				     *
316  *===========================================================================*/
317 static void rtl8169_dump(void)
318 {
319 	re_dtcc *dtcc;
320 	re_t *rep;
321 
322 	rep = &re_state;
323 
324 	printf("\n");
325 
326 	rtl8169_update_stat(rep);
327 
328 	printf("Realtek RTL 8169 driver %s:\n", netdriver_name());
329 
330 	printf("interrupts :%8u\n", rep->interrupts);
331 
332 	printf("\nRealtek RTL 8169 Tally Counters:\n");
333 
334 	dtcc = rep->v_dtcc_buf;
335 
336 	if (dtcc->TxOk_high)
337 		printf("TxOk       :%8u%08u\t",
338 		    dtcc->TxOk_high, dtcc->TxOk_low);
339 	else
340 		printf("TxOk       :%16u\t", dtcc->TxOk_low);
341 
342 	if (dtcc->RxOk_high)
343 		printf("RxOk       :%8u%08u\n",
344 		    dtcc->RxOk_high, dtcc->RxOk_low);
345 	else
346 		printf("RxOk       :%16u\n", dtcc->RxOk_low);
347 
348 	if (dtcc->TxEr_high)
349 		printf("TxEr       :%8u%08u\t",
350 		    dtcc->TxEr_high, dtcc->TxEr_low);
351 	else
352 		printf("TxEr       :%16u\t", dtcc->TxEr_low);
353 
354 	printf("RxEr       :%16u\n", dtcc->RxEr);
355 
356 	printf("Tx1Col     :%16u\t", dtcc->Tx1Col);
357 	printf("TxMCol     :%16u\n", dtcc->TxMCol);
358 
359 	if (dtcc->RxOkPhy_high)
360 		printf("RxOkPhy    :%8u%08u\t",
361 		    dtcc->RxOkPhy_high, dtcc->RxOkPhy_low);
362 	else
363 		printf("RxOkPhy    :%16u\t", dtcc->RxOkPhy_low);
364 
365 	if (dtcc->RxOkBrd_high)
366 		printf("RxOkBrd    :%8u%08u\n",
367 		    dtcc->RxOkBrd_high, dtcc->RxOkBrd_low);
368 	else
369 		printf("RxOkBrd    :%16u\n", dtcc->RxOkBrd_low);
370 
371 	printf("RxOkMul    :%16u\t", dtcc->RxOkMul);
372 	printf("MissPkt    :%16d\n", dtcc->MissPkt);
373 
374 	printf("\nRealtek RTL 8169 Miscellaneous Info:\n");
375 
376 	printf("tx_head    :%8d  busy %d\t",
377 		rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy);
378 }
379 #endif
380 
381 /*===========================================================================*
382  *				rl_set_mode				     *
383  *===========================================================================*/
384 static void rl_set_mode(unsigned int mode,
385 	const netdriver_addr_t * mcast_list __unused,
386 	unsigned int mcast_count __unused)
387 {
388 	re_t *rep;
389 
390 	rep = &re_state;
391 
392 	rep->re_mode = mode;
393 
394 	rl_rec_mode(rep);
395 }
396 
397 /*===========================================================================*
398  *				rl_probe				     *
399  *===========================================================================*/
400 static int rl_probe(re_t *rep, unsigned int skip)
401 {
402 	int r, devind;
403 	u16_t vid, did;
404 	u32_t bar;
405 	u8_t ilr;
406 #if VERBOSE
407 	const char *dname;
408 #endif
409 
410 	pci_init();
411 
412 	r = pci_first_dev(&devind, &vid, &did);
413 	if (r == 0)
414 		return 0;
415 
416 	while (skip--) {
417 		r = pci_next_dev(&devind, &vid, &did);
418 		if (!r)
419 			return 0;
420 	}
421 
422 #if VERBOSE
423 	dname = pci_dev_name(vid, did);
424 	if (!dname)
425 		dname = "unknown device";
426 	printf("%s: ", netdriver_name());
427 	printf("%s (%x/%x) at %s\n", dname, vid, did, pci_slot_name(devind));
428 #endif
429 
430 	pci_reserve(devind);
431 	bar = pci_attr_r32(devind, PCI_BAR) & 0xffffffe0;
432 	if (bar < 0x400) {
433 		panic("base address is not properly configured");
434 	}
435 	rep->re_base_port = bar;
436 
437 	ilr = pci_attr_r8(devind, PCI_ILR);
438 	rep->re_irq = ilr;
439 #if VERBOSE
440 	printf("%s: using I/O address 0x%lx, IRQ %d\n",
441 		netdriver_name(), (unsigned long)bar, ilr);
442 #endif
443 
444 	return TRUE;
445 }
446 
447 /*===========================================================================*
448  *				rl_init_buf				     *
449  *===========================================================================*/
450 static void rl_init_buf(re_t *rep)
451 {
452 	size_t rx_bufsize, tx_bufsize, rx_descsize, tx_descsize, tot_bufsize;
453 	struct re_desc *desc;
454 	phys_bytes buf;
455 	char *mallocbuf;
456 	int d;
457 
458 	/* Allocate receive and transmit descriptors */
459 	rx_descsize = (N_RX_DESC * sizeof(struct re_desc));
460 	tx_descsize = (N_TX_DESC * sizeof(struct re_desc));
461 
462 	/* Allocate receive and transmit buffers */
463 	tx_bufsize = NDEV_ETH_PACKET_MAX_TAGGED;
464 	if (tx_bufsize % 4)
465 		tx_bufsize += 4-(tx_bufsize % 4);	/* Align */
466 	rx_bufsize = RX_BUFSIZE;
467 	tot_bufsize = rx_descsize + tx_descsize;
468 	tot_bufsize += (N_TX_DESC * tx_bufsize) + (N_RX_DESC * rx_bufsize);
469 	tot_bufsize += sizeof(struct re_dtcc);
470 
471 	if (tot_bufsize % 4096)
472 		tot_bufsize += 4096 - (tot_bufsize % 4096);
473 
474 	if (!(mallocbuf = alloc_contig(tot_bufsize, AC_ALIGN64K, &buf)))
475 		panic("Couldn't allocate kernel buffer");
476 
477 	/* Rx Descriptor */
478 	rep->re_rx_desc = (re_desc *)mallocbuf;
479 	rep->p_rx_desc = buf;
480 	memset(mallocbuf, 0x00, rx_descsize);
481 	buf += rx_descsize;
482 	mallocbuf += rx_descsize;
483 
484 	/* Tx Descriptor */
485 	rep->re_tx_desc = (re_desc *)mallocbuf;
486 	rep->p_tx_desc = buf;
487 	memset(mallocbuf, 0x00, tx_descsize);
488 	buf += tx_descsize;
489 	mallocbuf += tx_descsize;
490 
491 	desc = rep->re_rx_desc;
492 	for (d = 0; d < N_RX_DESC; d++) {
493 		/* Setting Rx buffer */
494 		rep->re_rx[d].ret_buf = buf;
495 		rep->re_rx[d].v_ret_buf = mallocbuf;
496 		buf += rx_bufsize;
497 		mallocbuf += rx_bufsize;
498 
499 		/* Setting Rx descriptor */
500 		if (d == (N_RX_DESC - 1)) /* Last descriptor: set EOR bit */
501 			desc->status = DESC_EOR | DESC_OWN |
502 			    (RX_BUFSIZE & DESC_RX_LENMASK);
503 		else
504 			desc->status = DESC_OWN |
505 			    (RX_BUFSIZE & DESC_RX_LENMASK);
506 
507 		desc->addr_low =  rep->re_rx[d].ret_buf;
508 		desc++;
509 	}
510 	desc = rep->re_tx_desc;
511 	for (d = 0; d < N_TX_DESC; d++) {
512 		rep->re_tx[d].ret_busy = FALSE;
513 		rep->re_tx[d].ret_buf = buf;
514 		rep->re_tx[d].v_ret_buf = mallocbuf;
515 		buf += tx_bufsize;
516 		mallocbuf += tx_bufsize;
517 
518 		/* Setting Tx descriptor */
519 		desc->addr_low =  rep->re_tx[d].ret_buf;
520 		desc++;
521 	}
522 	rep->re_tx_busy = 0;
523 
524 	/* Dump Tally Counter buffer */
525 	rep->dtcc_buf = buf;
526 	rep->v_dtcc_buf = (re_dtcc *)mallocbuf;
527 }
528 
529 /*===========================================================================*
530  *				rl_init_hw				     *
531  *===========================================================================*/
532 static void rl_init_hw(re_t *rep, netdriver_addr_t *addr,
533 	unsigned int instance)
534 {
535 	int s;
536 #if VERBOSE
537 	int i;
538 #endif
539 
540 	/*
541 	 * Set the interrupt handler. The policy is to only send HARD_INT
542 	 * notifications. Don't reenable interrupts automatically. The id
543 	 * that is passed back is the interrupt line number.
544 	 */
545 	rep->re_hook_id = rep->re_irq;
546 	if ((s = sys_irqsetpolicy(rep->re_irq, 0, &rep->re_hook_id)) != OK)
547 		printf("RTL8169: error, couldn't set IRQ policy: %d\n", s);
548 
549 	rl_reset_hw(rep);
550 
551 	if ((s = sys_irqenable(&rep->re_hook_id)) != OK)
552 		printf("RTL8169: error, couldn't enable interrupts: %d\n", s);
553 
554 #if VERBOSE
555 	printf("%s: model: %s mac: 0x%08x\n",
556 		netdriver_name(), rep->re_model, rep->re_mac);
557 #endif
558 
559 	rl_confaddr(rep, addr, instance);
560 
561 #if VERBOSE
562 	printf("%s: Ethernet address ", netdriver_name());
563 	for (i = 0; i < 6; i++) {
564 		printf("%x%c", addr->na_addr[i],
565 			i < 5 ? ':' : '\n');
566 	}
567 #endif
568 }
569 
570 static void rtl8169s_phy_config(port_t port)
571 {
572 	mdio_write(port, 0x1f, 0x0001);
573 	mdio_write(port, 0x06, 0x006e);
574 	mdio_write(port, 0x08, 0x0708);
575 	mdio_write(port, 0x15, 0x4000);
576 	mdio_write(port, 0x18, 0x65c7);
577 
578 	mdio_write(port, 0x1f, 0x0001);
579 	mdio_write(port, 0x03, 0x00a1);
580 	mdio_write(port, 0x02, 0x0008);
581 	mdio_write(port, 0x01, 0x0120);
582 	mdio_write(port, 0x00, 0x1000);
583 	mdio_write(port, 0x04, 0x0800);
584 	mdio_write(port, 0x04, 0x0000);
585 
586 	mdio_write(port, 0x03, 0xff41);
587 	mdio_write(port, 0x02, 0xdf60);
588 	mdio_write(port, 0x01, 0x0140);
589 	mdio_write(port, 0x00, 0x0077);
590 	mdio_write(port, 0x04, 0x7800);
591 	mdio_write(port, 0x04, 0x7000);
592 
593 	mdio_write(port, 0x03, 0x802f);
594 	mdio_write(port, 0x02, 0x4f02);
595 	mdio_write(port, 0x01, 0x0409);
596 	mdio_write(port, 0x00, 0xf0f9);
597 	mdio_write(port, 0x04, 0x9800);
598 	mdio_write(port, 0x04, 0x9000);
599 
600 	mdio_write(port, 0x03, 0xdf01);
601 	mdio_write(port, 0x02, 0xdf20);
602 	mdio_write(port, 0x01, 0xff95);
603 	mdio_write(port, 0x00, 0xba00);
604 	mdio_write(port, 0x04, 0xa800);
605 	mdio_write(port, 0x04, 0xa000);
606 
607 	mdio_write(port, 0x03, 0xff41);
608 	mdio_write(port, 0x02, 0xdf20);
609 	mdio_write(port, 0x01, 0x0140);
610 	mdio_write(port, 0x00, 0x00bb);
611 	mdio_write(port, 0x04, 0xb800);
612 	mdio_write(port, 0x04, 0xb000);
613 
614 	mdio_write(port, 0x03, 0xdf41);
615 	mdio_write(port, 0x02, 0xdc60);
616 	mdio_write(port, 0x01, 0x6340);
617 	mdio_write(port, 0x00, 0x007d);
618 	mdio_write(port, 0x04, 0xd800);
619 	mdio_write(port, 0x04, 0xd000);
620 
621 	mdio_write(port, 0x03, 0xdf01);
622 	mdio_write(port, 0x02, 0xdf20);
623 	mdio_write(port, 0x01, 0x100a);
624 	mdio_write(port, 0x00, 0xa0ff);
625 	mdio_write(port, 0x04, 0xf800);
626 	mdio_write(port, 0x04, 0xf000);
627 
628 	mdio_write(port, 0x1f, 0x0000);
629 	mdio_write(port, 0x0b, 0x0000);
630 	mdio_write(port, 0x00, 0x9200);
631 }
632 
633 static void rtl8169scd_phy_config(port_t port)
634 {
635 	mdio_write(port, 0x1f, 0x0001);
636 	mdio_write(port, 0x04, 0x0000);
637 	mdio_write(port, 0x03, 0x00a1);
638 	mdio_write(port, 0x02, 0x0008);
639 	mdio_write(port, 0x01, 0x0120);
640 	mdio_write(port, 0x00, 0x1000);
641 	mdio_write(port, 0x04, 0x0800);
642 	mdio_write(port, 0x04, 0x9000);
643 	mdio_write(port, 0x03, 0x802f);
644 	mdio_write(port, 0x02, 0x4f02);
645 	mdio_write(port, 0x01, 0x0409);
646 	mdio_write(port, 0x00, 0xf099);
647 	mdio_write(port, 0x04, 0x9800);
648 	mdio_write(port, 0x04, 0xa000);
649 	mdio_write(port, 0x03, 0xdf01);
650 	mdio_write(port, 0x02, 0xdf20);
651 	mdio_write(port, 0x01, 0xff95);
652 	mdio_write(port, 0x00, 0xba00);
653 	mdio_write(port, 0x04, 0xa800);
654 	mdio_write(port, 0x04, 0xf000);
655 	mdio_write(port, 0x03, 0xdf01);
656 	mdio_write(port, 0x02, 0xdf20);
657 	mdio_write(port, 0x01, 0x101a);
658 	mdio_write(port, 0x00, 0xa0ff);
659 	mdio_write(port, 0x04, 0xf800);
660 	mdio_write(port, 0x04, 0x0000);
661 	mdio_write(port, 0x1f, 0x0000);
662 
663 	mdio_write(port, 0x1f, 0x0001);
664 	mdio_write(port, 0x10, 0xf41b);
665 	mdio_write(port, 0x14, 0xfb54);
666 	mdio_write(port, 0x18, 0xf5c7);
667 	mdio_write(port, 0x1f, 0x0000);
668 
669 	mdio_write(port, 0x1f, 0x0001);
670 	mdio_write(port, 0x17, 0x0cc0);
671 	mdio_write(port, 0x1f, 0x0000);
672 }
673 
674 /*===========================================================================*
675  *				rl_reset_hw				     *
676  *===========================================================================*/
677 static void rl_reset_hw(re_t *rep)
678 {
679 	port_t port;
680 	u32_t t;
681 	int i;
682 
683 	port = rep->re_base_port;
684 
685 	rl_outw(port, RL_IMR, 0x0000);
686 
687 	/* Reset the device */
688 	rl_outb(port, RL_CR, RL_CR_RST);
689 	SPIN_UNTIL(!(rl_inb(port, RL_CR) & RL_CR_RST), 1000000);
690 	if (rl_inb(port, RL_CR) & RL_CR_RST)
691 		printf("rtl8169: reset failed to complete");
692 	rl_outw(port, RL_ISR, 0xFFFF);
693 
694 	/* Get Model and MAC info */
695 	t = rl_inl(port, RL_TCR);
696 	rep->re_mac = (t & (RL_TCR_HWVER_AM | RL_TCR_HWVER_BM));
697 	switch (rep->re_mac) {
698 	case RL_TCR_HWVER_RTL8169:
699 		rep->re_model = "RTL8169";
700 
701 		rl_outw(port, RL_CCR_UNDOC, 0x01);
702 		break;
703 	case RL_TCR_HWVER_RTL8169S:
704 		rep->re_model = "RTL8169S";
705 
706 		rtl8169s_phy_config(port);
707 
708 		rl_outw(port, RL_CCR_UNDOC, 0x01);
709 		mdio_write(port, 0x0b, 0x0000);		/* w 0x0b 15 0 0 */
710 		break;
711 	case RL_TCR_HWVER_RTL8110S:
712 		rep->re_model = "RTL8110S";
713 
714 		rtl8169s_phy_config(port);
715 
716 		rl_outw(port, RL_CCR_UNDOC, 0x01);
717 		break;
718 	case RL_TCR_HWVER_RTL8169SB:
719 		rep->re_model = "RTL8169SB";
720 
721 		mdio_write(port, 0x1f, 0x02);
722 		mdio_write(port, 0x01, 0x90d0);
723 		mdio_write(port, 0x1f, 0x00);
724 
725 		rl_outw(port, RL_CCR_UNDOC, 0x01);
726 		break;
727 	case RL_TCR_HWVER_RTL8110SCd:
728 		rep->re_model = "RTL8110SCd";
729 
730 		rtl8169scd_phy_config(port);
731 
732 		rl_outw(port, RL_CCR_UNDOC, 0x01);
733 		break;
734 	case RL_TCR_HWVER_RTL8105E:
735 		rep->re_model = "RTL8105E";
736 		break;
737 	default:
738 		rep->re_model = "Unknown";
739 		rep->re_mac = t;
740 		break;
741 	}
742 
743 	mdio_write(port, MII_CTRL, MII_CTRL_RST);
744 	for (i = 0; i < 1000; i++) {
745 		t = mdio_read(port, MII_CTRL);
746 		if (!(t & MII_CTRL_RST))
747 			break;
748 		else
749 			micro_delay(100);
750 	}
751 
752 	t = mdio_read(port, MII_CTRL);
753 	t |= MII_CTRL_ANE | MII_CTRL_DM | MII_CTRL_SP_1000;
754 	mdio_write(port, MII_CTRL, t);
755 
756 	t = mdio_read(port, MII_ANA);
757 	t |= MII_ANA_10THD | MII_ANA_10TFD | MII_ANA_100TXHD | MII_ANA_100TXFD;
758 	t |= MII_ANA_PAUSE_SYM | MII_ANA_PAUSE_ASYM;
759 	mdio_write(port, MII_ANA, t);
760 
761 	t = mdio_read(port, MII_1000_CTRL) | 0x300;
762 	mdio_write(port, MII_1000_CTRL, t);
763 
764 	/* Restart Auto-Negotiation Process */
765 	t = mdio_read(port, MII_CTRL) | MII_CTRL_ANE | MII_CTRL_RAN;
766 	mdio_write(port, MII_CTRL, t);
767 
768 	rl_outw(port, RL_9346CR, RL_9346CR_EEM_CONFIG);	/* Unlock */
769 
770 	switch (rep->re_mac) {
771 	case RL_TCR_HWVER_RTL8169S:
772 	case RL_TCR_HWVER_RTL8110S:
773 		/* Bit-3 and bit-14 of the C+CR register MUST be 1. */
774 		t = rl_inw(port, RL_CPLUSCMD);
775 		rl_outw(port, RL_CPLUSCMD, t | RL_CPLUS_MULRW | (1 << 14));
776 		break;
777 	case RL_TCR_HWVER_RTL8169:
778 	case RL_TCR_HWVER_RTL8169SB:
779 	case RL_TCR_HWVER_RTL8110SCd:
780 		t = rl_inw(port, RL_CPLUSCMD);
781 		rl_outw(port, RL_CPLUSCMD, t | RL_CPLUS_MULRW);
782 		break;
783 	}
784 
785 	rl_outw(port, RL_INTRMITIGATE, 0x00);
786 
787 	t = rl_inb(port, RL_CR);
788 	rl_outb(port, RL_CR, t | RL_CR_RE | RL_CR_TE);
789 
790 	/* Initialize Rx */
791 	rl_outw(port, RL_RMS, RX_BUFSIZE);	/* Maximum rx packet size */
792 	t = rl_inl(port, RL_RCR) & RX_CONFIG_MASK;
793 	rl_outl(port, RL_RCR, RL_RCR_RXFTH_UNLIM | RL_RCR_MXDMA_1024 | t);
794 	rl_outl(port, RL_RDSAR_LO, rep->p_rx_desc);
795 	rl_outl(port, RL_RDSAR_HI, 0x00);	/* For 64 bit */
796 
797 	/* Initialize Tx */
798 	rl_outw(port, RL_ETTHR, 0x3f);		/* No early transmit */
799 	rl_outl(port, RL_TCR, RL_TCR_MXDMA_2048 | RL_TCR_IFG_STD);
800 	rl_outl(port, RL_TNPDS_LO, rep->p_tx_desc);
801 	rl_outl(port, RL_TNPDS_HI, 0x00);	/* For 64 bit */
802 
803 	rl_outw(port, RL_9346CR, RL_9346CR_EEM_NORMAL);	/* Lock */
804 
805 	rl_outw(port, RL_MPC, 0x00);
806 	rl_outw(port, RL_MULINT, rl_inw(port, RL_MULINT) & 0xF000);
807 	rl_outw(port, RL_IMR, RE_INTR_MASK);
808 }
809 
810 /*===========================================================================*
811  *				rl_confaddr				     *
812  *===========================================================================*/
813 static void rl_confaddr(re_t *rep, netdriver_addr_t *addr,
814 	unsigned int instance)
815 {
816 	static char eakey[] = RL_ENVVAR "#_EA";
817 	static char eafmt[] = "x:x:x:x:x:x";
818 	int i;
819 	port_t port;
820 	long v;
821 
822 	/* User defined ethernet address? */
823 	eakey[sizeof(RL_ENVVAR)-1] = '0' + instance;
824 
825 	port = rep->re_base_port;
826 
827 	for (i = 0; i < 6; i++) {
828 		if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
829 			break;
830 		addr->na_addr[i] = v;
831 	}
832 
833 	if (i != 0 && i != 6)
834 		env_panic(eakey);	/* It's all or nothing */
835 
836 	/* Should update ethernet address in hardware */
837 	if (i == 6)
838 		rl_set_hwaddr(addr);
839 
840 	/* Get ethernet address */
841 	for (i = 0; i < 6; i++)
842 		addr->na_addr[i] = rl_inb(port, RL_IDR+i);
843 }
844 
845 /*===========================================================================*
846  *				rl_set_hwaddr				     *
847  *===========================================================================*/
848 static void rl_set_hwaddr(const netdriver_addr_t *addr)
849 {
850 	re_t *rep;
851 	port_t port;
852 	u32_t w;
853 	int i;
854 
855 	rep = &re_state;
856 
857 	port = rep->re_base_port;
858 	rl_outb(port, RL_9346CR, RL_9346CR_EEM_CONFIG);
859 	w = 0;
860 	for (i = 0; i < 4; i++)
861 		w |= (addr->na_addr[i] << (i * 8));
862 	rl_outl(port, RL_IDR, w);
863 	w = 0;
864 	for (i = 4; i < 6; i++)
865 		w |= (addr->na_addr[i] << ((i-4) * 8));
866 	rl_outl(port, RL_IDR + 4, w);
867 	rl_outb(port, RL_9346CR, RL_9346CR_EEM_NORMAL);
868 }
869 
870 /*===========================================================================*
871  *				rl_rec_mode				     *
872  *===========================================================================*/
873 static void rl_rec_mode(re_t *rep)
874 {
875 	port_t port;
876 	u32_t rcr;
877 	u32_t mc_filter[2];		/* Multicast hash filter */
878 
879 	port = rep->re_base_port;
880 
881 	mc_filter[1] = mc_filter[0] = 0xffffffff;
882 	rl_outl(port, RL_MAR + 0, mc_filter[0]);
883 	rl_outl(port, RL_MAR + 4, mc_filter[1]);
884 
885 	rcr = rl_inl(port, RL_RCR);
886 	rcr &= ~(RL_RCR_AB | RL_RCR_AM | RL_RCR_APM | RL_RCR_AAP);
887 	if (rep->re_mode & NDEV_MODE_PROMISC)
888 		rcr |= RL_RCR_AB | RL_RCR_AM | RL_RCR_AAP;
889 	if (rep->re_mode & NDEV_MODE_BCAST)
890 		rcr |= RL_RCR_AB;
891 	if (rep->re_mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL))
892 		rcr |= RL_RCR_AM;
893 	rcr |= RL_RCR_APM;
894 	rl_outl(port, RL_RCR, RL_RCR_RXFTH_UNLIM | RL_RCR_MXDMA_1024 | rcr);
895 }
896 
897 /*===========================================================================*
898  *				rl_recv					     *
899  *===========================================================================*/
900 static ssize_t rl_recv(struct netdriver_data *data, size_t max)
901 {
902 	int index;
903 	port_t port;
904 	unsigned totlen, packlen;
905 	re_desc *desc;
906 	u32_t rxstat;
907 	re_t *rep;
908 
909 	rep = &re_state;
910 
911 	port = rep->re_base_port;
912 
913 	if (rl_inb(port, RL_CR) & RL_CR_BUFE)
914 		return SUSPEND; /* Receive buffer is empty, suspend */
915 
916 	index = rep->re_rx_head;
917 	desc = rep->re_rx_desc;
918 	desc += index;
919 
920 	for (;;) {
921 		rxstat = desc->status;
922 
923 		if (rxstat & DESC_OWN)
924 			return SUSPEND;
925 
926 		if (rxstat & DESC_RX_CRC)
927 			netdriver_stat_ierror(1);
928 
929 		if ((rxstat & (DESC_FS | DESC_LS)) == (DESC_FS | DESC_LS))
930 			break;
931 
932 #if VERBOSE
933 		printf("rl_recv: packet is fragmented\n");
934 #endif
935 		/* Fix the fragmented packet */
936 		if (index == N_RX_DESC - 1) {
937 			desc->status = DESC_EOR | DESC_OWN |
938 			    (RX_BUFSIZE & DESC_RX_LENMASK);
939 			index = 0;
940 			desc = rep->re_rx_desc;
941 		} else {
942 			desc->status = DESC_OWN |
943 			    (RX_BUFSIZE & DESC_RX_LENMASK);
944 			index++;
945 			desc++;
946 		}
947 		/* Loop until we get correct packet */
948 	}
949 
950 	totlen = rxstat & DESC_RX_LENMASK;
951 	if (totlen < 8 || totlen > 2 * NDEV_ETH_PACKET_MAX) {
952 		/* Someting went wrong */
953 		printf("rl_recv: bad length (%u) in status 0x%08x\n",
954 			totlen, rxstat);
955 		panic(NULL);
956 	}
957 
958 	/* Should subtract the CRC */
959 	packlen = totlen - NDEV_ETH_PACKET_CRC;
960 	if (packlen > max)
961 		packlen = max;
962 
963 	netdriver_copyout(data, 0, rep->re_rx[index].v_ret_buf, packlen);
964 
965 	if (index == N_RX_DESC - 1) {
966 		desc->status = DESC_EOR | DESC_OWN |
967 		    (RX_BUFSIZE & DESC_RX_LENMASK);
968 		index = 0;
969 	} else {
970 		desc->status = DESC_OWN | (RX_BUFSIZE & DESC_RX_LENMASK);
971 		index++;
972 	}
973 	rep->re_rx_head = index;
974 	assert(rep->re_rx_head < N_RX_DESC);
975 
976 	return packlen;
977 }
978 
979 /*===========================================================================*
980  *				rl_send					     *
981  *===========================================================================*/
982 static int rl_send(struct netdriver_data *data, size_t size)
983 {
984 	int tx_head;
985 	re_t *rep;
986 	re_desc *desc;
987 
988 	rep = &re_state;
989 
990 	tx_head = rep->re_tx_head;
991 
992 	desc = rep->re_tx_desc;
993 	desc += tx_head;
994 
995 	assert(desc);
996 	assert(rep->re_tx_desc);
997 	assert(rep->re_tx_head >= 0 && rep->re_tx_head < N_TX_DESC);
998 
999 	if (rep->re_tx[tx_head].ret_busy)
1000 		return SUSPEND;
1001 
1002 	netdriver_copyin(data, 0, rep->re_tx[tx_head].v_ret_buf, size);
1003 
1004 	rep->re_tx[tx_head].ret_busy = TRUE;
1005 	rep->re_tx_busy++;
1006 
1007 	if (tx_head == N_TX_DESC - 1) {
1008 		desc->status =  DESC_EOR | DESC_OWN | DESC_FS | DESC_LS | size;
1009 		tx_head = 0;
1010 	} else {
1011 		desc->status =  DESC_OWN | DESC_FS | DESC_LS | size;
1012 		tx_head++;
1013 	}
1014 
1015 	assert(tx_head < N_TX_DESC);
1016 	rep->re_tx_head = tx_head;
1017 
1018 	rl_outl(rep->re_base_port, RL_TPPOLL, RL_TPPOLL_NPQ);
1019 
1020 	return OK;
1021 }
1022 
1023 /*===========================================================================*
1024  *				rl_check_ints				     *
1025  *===========================================================================*/
1026 static void rl_check_ints(re_t *rep)
1027 {
1028 	if (!rep->re_got_int)
1029 		return;
1030 	rep->re_got_int = FALSE;
1031 
1032 	netdriver_recv();
1033 
1034 	if (rep->re_need_reset)
1035 		rl_do_reset(rep);
1036 
1037 	if (rep->re_send_int) {
1038 		rep->re_send_int = FALSE;
1039 
1040 		netdriver_send();
1041 	}
1042 
1043 	if (rep->re_report_link) {
1044 		rep->re_report_link = FALSE;
1045 
1046 		netdriver_link();
1047 
1048 #if VERBOSE
1049 		rl_report_link(rep);
1050 #endif
1051 	}
1052 }
1053 
1054 /*===========================================================================*
1055  *				rl_get_link				     *
1056  *===========================================================================*/
1057 static unsigned int rl_get_link(uint32_t *media)
1058 {
1059 	re_t *rep;
1060 	u8_t mii_status;
1061 
1062 	rep = &re_state;
1063 
1064 	mii_status = rl_inb(rep->re_base_port, RL_PHYSTAT);
1065 
1066 	if (!(mii_status & RL_STAT_LINK))
1067 		return NDEV_LINK_DOWN;
1068 
1069 	if (mii_status & RL_STAT_1000)
1070 		*media = IFM_ETHER | IFM_1000_T;
1071 	else if (mii_status & RL_STAT_100)
1072 		*media = IFM_ETHER | IFM_100_TX;
1073 	else if (mii_status & RL_STAT_10)
1074 		*media = IFM_ETHER | IFM_10_T;
1075 
1076 	if (mii_status & RL_STAT_FULLDUP)
1077 		*media |= IFM_FDX;
1078 	else
1079 		*media |= IFM_HDX;
1080 
1081 	return NDEV_LINK_UP;
1082 }
1083 
1084 /*===========================================================================*
1085  *				rl_report_link				     *
1086  *===========================================================================*/
1087 #if VERBOSE
1088 static void rl_report_link(re_t *rep)
1089 {
1090 	port_t port;
1091 	u8_t mii_status;
1092 
1093 	port = rep->re_base_port;
1094 
1095 	mii_status = rl_inb(port, RL_PHYSTAT);
1096 
1097 	if (mii_status & RL_STAT_LINK) {
1098 		rep->re_link_up = 1;
1099 		printf("%s: link up at ", netdriver_name());
1100 	} else {
1101 		rep->re_link_up = 0;
1102 		printf("%s: link down\n", netdriver_name());
1103 		return;
1104 	}
1105 
1106 	if (mii_status & RL_STAT_1000)
1107 		printf("1000 Mbps");
1108 	else if (mii_status & RL_STAT_100)
1109 		printf("100 Mbps");
1110 	else if (mii_status & RL_STAT_10)
1111 		printf("10 Mbps");
1112 
1113 	if (mii_status & RL_STAT_FULLDUP)
1114 		printf(", full duplex");
1115 	else
1116 		printf(", half duplex");
1117 	printf("\n");
1118 
1119 	dump_phy(rep);
1120 }
1121 #endif
1122 
1123 /*===========================================================================*
1124  *				rl_do_reset				     *
1125  *===========================================================================*/
1126 static void rl_do_reset(re_t *rep)
1127 {
1128 	rep->re_need_reset = FALSE;
1129 	rl_reset_hw(rep);
1130 	rl_rec_mode(rep);
1131 
1132 	rep->re_tx_head = 0;
1133 	if (rep->re_tx[rep->re_tx_head].ret_busy)
1134 		rep->re_tx_busy--;
1135 	rep->re_tx[rep->re_tx_head].ret_busy = FALSE;
1136 	rep->re_send_int = TRUE;
1137 }
1138 
1139 #if VERBOSE
1140 static void dump_phy(const re_t *rep)
1141 {
1142 	port_t port;
1143 	u32_t t;
1144 
1145 	port = rep->re_base_port;
1146 
1147 	t = rl_inb(port, RL_CONFIG0);
1148 	printf("CONFIG0\t\t:");
1149 	t = t & RL_CFG0_ROM;
1150 	if (t == RL_CFG0_ROM128K)
1151 		printf(" 128K Boot ROM");
1152 	else if (t == RL_CFG0_ROM64K)
1153 		printf(" 64K Boot ROM");
1154 	else if (t == RL_CFG0_ROM32K)
1155 		printf(" 32K Boot ROM");
1156 	else if (t == RL_CFG0_ROM16K)
1157 		printf(" 16K Boot ROM");
1158 	else if (t == RL_CFG0_ROM8K)
1159 		printf(" 8K Boot ROM");
1160 	else if (t == RL_CFG0_ROMNO)
1161 		printf(" No Boot ROM");
1162 	printf("\n");
1163 
1164 	t = rl_inb(port, RL_CONFIG1);
1165 	printf("CONFIG1\t\t:");
1166 	if (t & RL_CFG1_LEDS1)
1167 		printf(" LED1");
1168 	if (t & RL_CFG1_LEDS0)
1169 		printf(" LED0");
1170 	if (t & RL_CFG1_DVRLOAD)
1171 		printf(" Driver");
1172 	if (t & RL_CFG1_LWACT)
1173 		printf(" LWAKE");
1174 	if (t & RL_CFG1_IOMAP)
1175 		printf(" IOMAP");
1176 	if (t & RL_CFG1_MEMMAP)
1177 		printf(" MEMMAP");
1178 	if (t & RL_CFG1_VPD)
1179 		printf(" VPD");
1180 	if (t & RL_CFG1_PME)
1181 		printf(" PME");
1182 	printf("\n");
1183 
1184 	t = rl_inb(port, RL_CONFIG2);
1185 	printf("CONFIG2\t\t:");
1186 	if (t & RL_CFG2_AUX)
1187 		printf(" AUX");
1188 	if (t & RL_CFG2_PCIBW)
1189 		printf(" PCI-64-Bit");
1190 	else
1191 		printf(" PCI-32-Bit");
1192 	t = t & RL_CFG2_PCICLK;
1193 	if (t == RL_CFG2_66MHZ)
1194 		printf(" 66 MHz");
1195 	else if (t == RL_CFG2_33MHZ)
1196 		printf(" 33 MHz");
1197 	printf("\n");
1198 
1199 	t = mdio_read(port, MII_CTRL);
1200 	printf("MII_CTRL\t:");
1201 	if (t & MII_CTRL_RST)
1202 		printf(" Reset");
1203 	if (t & MII_CTRL_LB)
1204 		printf(" Loopback");
1205 	if (t & MII_CTRL_ANE)
1206 		printf(" ANE");
1207 	if (t & MII_CTRL_PD)
1208 		printf(" Power-down");
1209 	if (t & MII_CTRL_ISO)
1210 		printf(" Isolate");
1211 	if (t & MII_CTRL_RAN)
1212 		printf(" RAN");
1213 	if (t & MII_CTRL_DM)
1214 		printf(" Full-duplex");
1215 	if (t & MII_CTRL_CT)
1216 		printf(" COL-signal");
1217 	t = t & (MII_CTRL_SP_LSB | MII_CTRL_SP_MSB);
1218 	if (t == MII_CTRL_SP_10)
1219 		printf(" 10 Mb/s");
1220 	else if (t == MII_CTRL_SP_100)
1221 		printf(" 100 Mb/s");
1222 	else if (t == MII_CTRL_SP_1000)
1223 		printf(" 1000 Mb/s");
1224 	printf("\n");
1225 
1226 	t = mdio_read(port, MII_STATUS);
1227 	printf("MII_STATUS\t:");
1228 	if (t & MII_STATUS_100T4)
1229 		printf(" 100Base-T4");
1230 	if (t & MII_STATUS_100XFD)
1231 		printf(" 100BaseX-FD");
1232 	if (t & MII_STATUS_100XHD)
1233 		printf(" 100BaseX-HD");
1234 	if (t & MII_STATUS_10FD)
1235 		printf(" 10Mbps-FD");
1236 	if (t & MII_STATUS_10HD)
1237 		printf(" 10Mbps-HD");
1238 	if (t & MII_STATUS_100T2FD)
1239 		printf(" 100Base-T2-FD");
1240 	if (t & MII_STATUS_100T2HD)
1241 		printf(" 100Base-T2-HD");
1242 	if (t & MII_STATUS_EXT_STAT)
1243 		printf(" Ext-stat");
1244 	if (t & MII_STATUS_RES)
1245 		printf(" res-0x%x", t & MII_STATUS_RES);
1246 	if (t & MII_STATUS_MFPS)
1247 		printf(" MFPS");
1248 	if (t & MII_STATUS_ANC)
1249 		printf(" ANC");
1250 	if (t & MII_STATUS_RF)
1251 		printf(" remote-fault");
1252 	if (t & MII_STATUS_ANA)
1253 		printf(" ANA");
1254 	if (t & MII_STATUS_LS)
1255 		printf(" Link");
1256 	if (t & MII_STATUS_JD)
1257 		printf(" Jabber");
1258 	if (t & MII_STATUS_EC)
1259 		printf(" Extended-capability");
1260 	printf("\n");
1261 
1262 	t = mdio_read(port, MII_ANA);
1263 	printf("MII_ANA\t\t: 0x%04x\n", t);
1264 
1265 	t = mdio_read(port, MII_ANLPA);
1266 	printf("MII_ANLPA\t: 0x%04x\n", t);
1267 
1268 	t = mdio_read(port, MII_ANE);
1269 	printf("MII_ANE\t\t:");
1270 	if (t & MII_ANE_RES)
1271 		printf(" res-0x%x", t & MII_ANE_RES);
1272 	if (t & MII_ANE_PDF)
1273 		printf(" Par-Detect-Fault");
1274 	if (t & MII_ANE_LPNPA)
1275 		printf(" LP-Next-Page-Able");
1276 	if (t & MII_ANE_NPA)
1277 		printf(" Loc-Next-Page-Able");
1278 	if (t & MII_ANE_PR)
1279 		printf(" Page-Received");
1280 	if (t & MII_ANE_LPANA)
1281 		printf(" LP-Auto-Neg-Able");
1282 	printf("\n");
1283 
1284 	t = mdio_read(port, MII_1000_CTRL);
1285 	printf("MII_1000_CTRL\t:");
1286 	if (t & MII_1000C_FULL)
1287 		printf(" 1000BaseT-FD");
1288 	if (t & MII_1000C_HALF)
1289 		printf(" 1000BaseT-HD");
1290 	printf("\n");
1291 
1292 	t = mdio_read(port, MII_1000_STATUS);
1293 	if (t) {
1294 		printf("MII_1000_STATUS\t:");
1295 		if (t & MII_1000S_LRXOK)
1296 			printf(" Local-Receiver");
1297 		if (t & MII_1000S_RRXOK)
1298 			printf(" Remote-Receiver");
1299 		if (t & MII_1000S_HALF)
1300 			printf(" 1000BaseT-HD");
1301 		if (t & MII_1000S_FULL)
1302 			printf(" 1000BaseT-FD");
1303 		printf("\n");
1304 
1305 		t = mdio_read(port, MII_EXT_STATUS);
1306 		printf("MII_EXT_STATUS\t:");
1307 		if (t & MII_ESTAT_1000XFD)
1308 			printf(" 1000BaseX-FD");
1309 		if (t & MII_ESTAT_1000XHD)
1310 			printf(" 1000BaseX-HD");
1311 		if (t & MII_ESTAT_1000TFD)
1312 			printf(" 1000BaseT-FD");
1313 		if (t & MII_ESTAT_1000THD)
1314 			printf(" 1000BaseT-HD");
1315 		printf("\n");
1316 	}
1317 }
1318 #endif
1319 
1320 /*===========================================================================*
1321  *				rl_intr					     *
1322  *===========================================================================*/
1323 static void rl_intr(unsigned int __unused mask)
1324 {
1325 	re_t *rep;
1326 	int s;
1327 
1328 	rep = &re_state;
1329 
1330 	/* Run interrupt handler at driver level. */
1331 	rl_handler(rep);
1332 
1333 	/* Reenable interrupts for this hook. */
1334 	if ((s = sys_irqenable(&rep->re_hook_id)) != OK)
1335 		printf("RTL8169: error, couldn't enable interrupts: %d\n", s);
1336 
1337 	/* Perform tasks based on the flagged conditions. */
1338 	rl_check_ints(rep);
1339 }
1340 
1341 /*===========================================================================*
1342  *				rl_handler				     *
1343  *===========================================================================*/
1344 static void rl_handler(re_t *rep)
1345 {
1346 	int i, port, tx_head, tx_tail, link_up;
1347 	u16_t isr;
1348 	re_desc *desc;
1349 
1350 	port = rep->re_base_port;
1351 
1352 	/* Ack interrupt */
1353 	isr = rl_inw(port, RL_ISR);
1354 	if(!isr)
1355 		return;
1356 	rl_outw(port, RL_ISR, isr);
1357 	rep->interrupts++;
1358 
1359 	if (isr & RL_IMR_FOVW) {
1360 		isr &= ~RL_IMR_FOVW;
1361 		/* Should do anything? */
1362 	}
1363 	if (isr & RL_IMR_PUN) {
1364 		isr &= ~RL_IMR_PUN;
1365 
1366 		/*
1367 		 * Either the link status changed or there was a TX fifo
1368 		 * underrun.
1369 		 */
1370 		link_up = !(!(rl_inb(port, RL_PHYSTAT) & RL_STAT_LINK));
1371 		if (link_up != rep->re_link_up) {
1372 			rep->re_report_link = TRUE;
1373 			rep->re_got_int = TRUE;
1374 		}
1375 	}
1376 
1377 	if (isr & (RL_ISR_RDU | RL_ISR_RER | RL_ISR_ROK)) {
1378 		if (isr & RL_ISR_RER)
1379 			netdriver_stat_ierror(1);
1380 		isr &= ~(RL_ISR_RDU | RL_ISR_RER | RL_ISR_ROK);
1381 
1382 		rep->re_got_int = TRUE;
1383 	}
1384 
1385 	if ((isr & (RL_ISR_TDU | RL_ISR_TER | RL_ISR_TOK)) || 1) {
1386 		if (isr & RL_ISR_TER)
1387 			netdriver_stat_oerror(1);
1388 		isr &= ~(RL_ISR_TDU | RL_ISR_TER | RL_ISR_TOK);
1389 
1390 		/* Transmit completed */
1391 		tx_head = rep->re_tx_head;
1392 		tx_tail = tx_head+1;
1393 		if (tx_tail >= N_TX_DESC)
1394 			tx_tail = 0;
1395 		for (i = 0; i < 2 * N_TX_DESC; i++) {
1396 			if (!rep->re_tx[tx_tail].ret_busy) {
1397 				/* Strange, this buffer is not in-use.
1398 				 * Increment tx_tail until tx_head is
1399 				 * reached (or until we find a buffer that
1400 				 * is in-use.
1401 				 */
1402 				if (tx_tail == tx_head)
1403 					break;
1404 				if (++tx_tail >= N_TX_DESC)
1405 					tx_tail = 0;
1406 				assert(tx_tail < N_TX_DESC);
1407 				continue;
1408 			}
1409 			desc = rep->re_tx_desc;
1410 			desc += tx_tail;
1411 			if (desc->status & DESC_OWN) {
1412 				/* Buffer is not yet ready */
1413 				break;
1414 			}
1415 
1416 			rep->re_tx[tx_tail].ret_busy = FALSE;
1417 			rep->re_tx_busy--;
1418 
1419 			if (++tx_tail >= N_TX_DESC)
1420 				tx_tail = 0;
1421 			assert(tx_tail < N_TX_DESC);
1422 
1423 			rep->re_send_int = TRUE;
1424 			rep->re_got_int = TRUE;
1425 			rep->re_tx_alive = TRUE;
1426 		}
1427 		assert(i < 2 * N_TX_DESC);
1428 	}
1429 
1430 	/* Ignore Reserved Interrupt */
1431 	if (isr & RL_ISR_RES)
1432 		isr &= ~RL_ISR_RES;
1433 
1434 	if (isr)
1435 		printf("rl_handler: unhandled interrupt isr = 0x%04x\n", isr);
1436 }
1437 
1438 /*===========================================================================*
1439  *				rl_tick					     *
1440  *===========================================================================*/
1441 static void rl_tick(void)
1442 {
1443 	re_t *rep;
1444 
1445 	rep = &re_state;
1446 
1447 	/* Should collect statistics */
1448 	if (!(++rep->dtcc_counter % RE_DTCC_VALUE))
1449 		rtl8169_update_stat(rep);
1450 
1451 	assert(rep->re_tx_busy >= 0 && rep->re_tx_busy <= N_TX_DESC);
1452 	if (rep->re_tx_busy == 0) {
1453 		/* Assume that an idle system is alive */
1454 		rep->re_tx_alive = TRUE;
1455 		return;
1456 	}
1457 	if (rep->re_tx_alive) {
1458 		rep->re_tx_alive = FALSE;
1459 		return;
1460 	}
1461 	printf("%s: TX timeout, resetting\n", netdriver_name());
1462 	printf("tx_head    :%8d  busy %d\t",
1463 		rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy);
1464 	rep->re_need_reset = TRUE;
1465 	rep->re_got_int = TRUE;
1466 
1467 	rl_check_ints(rep);
1468 }
1469