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
my_inb(u16_t port)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 }
my_inw(u16_t port)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 }
my_inl(u16_t port)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
my_outb(u16_t port,u8_t value)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 }
my_outw(u16_t port,u16_t value)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 }
my_outl(u16_t port,u32_t value)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 *===========================================================================*/
main(int argc,char * argv[])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 *===========================================================================*/
rl_init(unsigned int instance,netdriver_addr_t * addr,uint32_t * caps,unsigned int * ticks)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 *===========================================================================*/
rl_stop(void)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
mdio_write(u16_t port,int regaddr,int value)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
mdio_read(u16_t port,int regaddr)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
rtl8169_update_stat(re_t * rep)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 *===========================================================================*/
rl_set_mode(unsigned int mode,const netdriver_addr_t * mcast_list __unused,unsigned int mcast_count __unused)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 *===========================================================================*/
rl_probe(re_t * rep,unsigned int skip)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 *===========================================================================*/
rl_init_buf(re_t * rep)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 *===========================================================================*/
rl_init_hw(re_t * rep,netdriver_addr_t * addr,unsigned int instance)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
rtl8169s_phy_config(port_t port)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
rtl8169scd_phy_config(port_t port)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 *===========================================================================*/
rl_reset_hw(re_t * rep)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 *===========================================================================*/
rl_confaddr(re_t * rep,netdriver_addr_t * addr,unsigned int instance)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 *===========================================================================*/
rl_set_hwaddr(const netdriver_addr_t * addr)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 *===========================================================================*/
rl_rec_mode(re_t * rep)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 *===========================================================================*/
rl_recv(struct netdriver_data * data,size_t max)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 *===========================================================================*/
rl_send(struct netdriver_data * data,size_t size)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 *===========================================================================*/
rl_check_ints(re_t * rep)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 *===========================================================================*/
rl_get_link(uint32_t * media)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
rl_report_link(re_t * rep)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 *===========================================================================*/
rl_do_reset(re_t * rep)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
dump_phy(const re_t * rep)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 *===========================================================================*/
rl_intr(unsigned int __unused mask)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 *===========================================================================*/
rl_handler(re_t * rep)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 *===========================================================================*/
rl_tick(void)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