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