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