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 <stdlib.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <minix/com.h> 16 #include <minix/ds.h> 17 #include <minix/syslib.h> 18 #include <minix/type.h> 19 #include <minix/sysutil.h> 20 #include <minix/endpoint.h> 21 #include <minix/timers.h> 22 #include <net/hton.h> 23 #include <net/gen/ether.h> 24 #include <net/gen/eth_io.h> 25 #include <machine/pci.h> 26 27 #include <sys/types.h> 28 #include <assert.h> 29 #include <unistd.h> 30 #include "kernel/const.h" 31 #include "kernel/config.h" 32 #include "kernel/type.h" 33 34 #define VERBOSE 0 /* display message during init */ 35 36 #include "rtl8169.h" 37 38 #define IOVEC_NR 16 /* I/O vectors are handled IOVEC_NR entries at a time. */ 39 40 #define RE_DTCC_VALUE 600 /* DTCC Update after every 10 minutes */ 41 42 #define RX_CONFIG_MASK 0xff7e1880 /* Clears the bits supported by chip */ 43 44 #define RE_INTR_MASK (RL_IMR_TDU | RL_IMR_FOVW | RL_IMR_PUN | RL_IMR_RDU | RL_IMR_TER | RL_IMR_TOK | RL_IMR_RER | RL_IMR_ROK) 45 46 #define RL_ENVVAR "RTLETH" /* Configuration */ 47 48 typedef struct re_desc 49 { 50 u32_t status; /* command/status */ 51 u32_t vlan; /* VLAN */ 52 u32_t addr_low; /* low 32-bits of physical buffer address */ 53 u32_t addr_high; /* high 32-bits of physical buffer address */ 54 } re_desc; 55 56 typedef struct re_dtcc 57 { 58 u32_t TxOk_low; /* low 32-bits of Tx Ok packets */ 59 u32_t TxOk_high; /* high 32-bits of Tx Ok packets */ 60 u32_t RxOk_low; /* low 32-bits of Rx Ok packets */ 61 u32_t RxOk_high; /* high 32-bits of Rx Ok packets */ 62 u32_t TxEr_low; /* low 32-bits of Tx errors */ 63 u32_t TxEr_high; /* high 32-bits of Tx errors */ 64 u32_t RxEr; /* Rx errors */ 65 u16_t MissPkt; /* Missed packets */ 66 u16_t FAE; /* Frame Aignment Error packets (MII mode only) */ 67 u32_t Tx1Col; /* Tx Ok packets with only 1 collision happened before Tx Ok */ 68 u32_t TxMCol; /* Tx Ok packets with > 1 and < 16 collisions happened before Tx Ok */ 69 u32_t RxOkPhy_low; /* low 32-bits of Rx Ok packets with physical addr destination ID */ 70 u32_t RxOkPhy_high; /* high 32-bits of Rx Ok packets with physical addr destination ID */ 71 u32_t RxOkBrd_low; /* low 32-bits of Rx Ok packets with broadcast destination ID */ 72 u32_t RxOkBrd_high; /* high 32-bits of Rx Ok packets with broadcast destination ID */ 73 u32_t RxOkMul; /* Rx Ok Packets with multicast destination ID */ 74 u16_t TxAbt; /* Tx abort packets */ 75 u16_t TxUndrn; /* Tx underrun packets */ 76 } re_dtcc; 77 78 typedef struct re { 79 port_t re_base_port; 80 int re_irq; 81 int re_mode; 82 int re_flags; 83 endpoint_t re_client; 84 int re_link_up; 85 int re_got_int; 86 int re_send_int; 87 int re_report_link; 88 int re_need_reset; 89 int re_tx_alive; 90 int setup; 91 u32_t re_mac; 92 char *re_model; 93 94 /* Rx */ 95 int re_rx_head; 96 struct { 97 int ret_busy; 98 phys_bytes ret_buf; 99 char *v_ret_buf; 100 } re_rx[N_RX_DESC]; 101 102 vir_bytes re_read_s; 103 re_desc *re_rx_desc; /* Rx descriptor buffer */ 104 phys_bytes p_rx_desc; /* Rx descriptor buffer physical */ 105 106 /* Tx */ 107 int re_tx_head; 108 struct { 109 int ret_busy; 110 phys_bytes ret_buf; 111 char *v_ret_buf; 112 } re_tx[N_TX_DESC]; 113 re_desc *re_tx_desc; /* Tx descriptor buffer */ 114 phys_bytes p_tx_desc; /* Tx descriptor buffer physical */ 115 116 /* PCI related */ 117 int re_seen; /* TRUE iff device available */ 118 119 /* 'large' items */ 120 int re_hook_id; /* IRQ hook id at kernel */ 121 eth_stat_t re_stat; 122 phys_bytes dtcc_buf; /* Dump Tally Counter buffer physical */ 123 re_dtcc *v_dtcc_buf; /* Dump Tally Counter buffer */ 124 u32_t dtcc_counter; /* DTCC update counter */ 125 ether_addr_t re_address; 126 message re_rx_mess; 127 message re_tx_mess; 128 char re_name[sizeof("rtl8169#n")]; 129 iovec_t re_iovec[IOVEC_NR]; 130 iovec_s_t re_iovec_s[IOVEC_NR]; 131 u32_t interrupts; 132 } 133 re_t; 134 135 #define REM_DISABLED 0x0 136 #define REM_ENABLED 0x1 137 138 #define REF_PACK_SENT 0x001 139 #define REF_PACK_RECV 0x002 140 #define REF_SEND_AVAIL 0x004 141 #define REF_READING 0x010 142 #define REF_EMPTY 0x000 143 #define REF_PROMISC 0x040 144 #define REF_MULTI 0x080 145 #define REF_BROAD 0x100 146 #define REF_ENABLED 0x200 147 148 static re_t re_state; 149 150 static int re_instance; 151 152 static unsigned my_inb(u16_t port) 153 { 154 u32_t value; 155 int s; 156 if ((s = sys_inb(port, &value)) != OK) 157 printf("RTL8169: warning, sys_inb failed: %d\n", s); 158 return value; 159 } 160 static unsigned my_inw(u16_t port) 161 { 162 u32_t value; 163 int s; 164 if ((s = sys_inw(port, &value)) != OK) 165 printf("RTL8169: warning, sys_inw failed: %d\n", s); 166 return value; 167 } 168 static unsigned my_inl(u16_t port) 169 { 170 u32_t value; 171 int s; 172 if ((s = sys_inl(port, &value)) != OK) 173 printf("RTL8169: warning, sys_inl failed: %d\n", s); 174 return value; 175 } 176 #define rl_inb(port, offset) (my_inb((port) + (offset))) 177 #define rl_inw(port, offset) (my_inw((port) + (offset))) 178 #define rl_inl(port, offset) (my_inl((port) + (offset))) 179 180 static void my_outb(u16_t port, u8_t value) 181 { 182 int s; 183 184 if ((s = sys_outb(port, value)) != OK) 185 printf("RTL8169: warning, sys_outb failed: %d\n", s); 186 } 187 static void my_outw(u16_t port, u16_t value) 188 { 189 int s; 190 191 if ((s = sys_outw(port, value)) != OK) 192 printf("RTL8169: warning, sys_outw failed: %d\n", s); 193 } 194 static void my_outl(u16_t port, u32_t value) 195 { 196 int s; 197 198 if ((s = sys_outl(port, value)) != OK) 199 printf("RTL8169: warning, sys_outl failed: %d\n", s); 200 } 201 #define rl_outb(port, offset, value) (my_outb((port) + (offset), (value))) 202 #define rl_outw(port, offset, value) (my_outw((port) + (offset), (value))) 203 #define rl_outl(port, offset, value) (my_outl((port) + (offset), (value))) 204 205 static void rl_init(message *mp); 206 static void rl_pci_conf(void); 207 static int rl_probe(re_t *rep, int skip); 208 static void rl_conf_hw(re_t *rep); 209 static void rl_init_buf(re_t *rep); 210 static void rl_init_hw(re_t *rep); 211 static void rl_reset_hw(re_t *rep); 212 static void rl_confaddr(re_t *rep); 213 static void rl_rec_mode(re_t *rep); 214 static void rl_readv_s(const message *mp, int from_int); 215 static void rl_writev_s(const message *mp, int from_int); 216 static void rl_check_ints(re_t *rep); 217 static void rl_report_link(re_t *rep); 218 static void rl_do_reset(re_t *rep); 219 static void rl_getstat_s(message *mp); 220 static void reply(re_t *rep); 221 static void mess_reply(message *req, message *reply); 222 static void check_int_events(void); 223 static void do_hard_int(void); 224 static void dump_phy(const re_t *rep); 225 static void rl_handler(re_t *rep); 226 static void rl_watchdog_f(minix_timer_t *tp); 227 228 /* 229 * The message used in the main loop is made global, so that rl_watchdog_f() 230 * can change its message type to fake an interrupt message. 231 */ 232 static message m; 233 static int int_event_check; /* set to TRUE if events arrived */ 234 235 u32_t system_hz; 236 237 /* SEF functions and variables. */ 238 static void sef_local_startup(void); 239 static int sef_cb_init_fresh(int type, sef_init_info_t *info); 240 static void sef_cb_signal_handler(int signo); 241 242 /*===========================================================================* 243 * main * 244 *===========================================================================*/ 245 int main(int argc, char *argv[]) 246 { 247 int r; 248 int ipc_status; 249 250 /* SEF local startup. */ 251 env_setargs(argc, argv); 252 sef_local_startup(); 253 254 while (TRUE) { 255 if ((r = netdriver_receive(ANY, &m, &ipc_status)) != OK) 256 panic("netdriver_receive failed: %d", r); 257 258 if (is_ipc_notify(ipc_status)) { 259 switch (_ENDPOINT_P(m.m_source)) { 260 case CLOCK: 261 /* 262 * Under MINIX, synchronous alarms are used 263 * instead of watchdog functions. 264 * The approach is very different: MINIX VMD 265 * timeouts are handled within the kernel 266 * (the watchdog is executed by CLOCK), and 267 * notify() the driver in some cases. MINIX 268 * timeouts result in a SYN_ALARM message to 269 * the driver and thus are handled where they 270 * should be handled. Locally, watchdog 271 * functions are used again. 272 */ 273 rl_watchdog_f(NULL); 274 break; 275 case HARDWARE: 276 do_hard_int(); 277 if (int_event_check) { 278 check_int_events(); 279 } 280 break ; 281 default: 282 panic("illegal notify from: %d", m.m_type); 283 } 284 285 /* done, get nwe message */ 286 continue; 287 } 288 289 switch (m.m_type) { 290 case DL_WRITEV_S: rl_writev_s(&m, FALSE); break; 291 case DL_READV_S: rl_readv_s(&m, FALSE); break; 292 case DL_CONF: rl_init(&m); break; 293 case DL_GETSTAT_S: rl_getstat_s(&m); break; 294 default: 295 panic("illegal message: %d", m.m_type); 296 } 297 } 298 } 299 300 /*===========================================================================* 301 * sef_local_startup * 302 *===========================================================================*/ 303 static void sef_local_startup() 304 { 305 /* Register init callbacks. */ 306 sef_setcb_init_fresh(sef_cb_init_fresh); 307 sef_setcb_init_lu(sef_cb_init_fresh); 308 sef_setcb_init_restart(sef_cb_init_fresh); 309 310 /* Register live update callbacks. */ 311 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); 312 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); 313 314 /* Register signal callbacks. */ 315 sef_setcb_signal_handler(sef_cb_signal_handler); 316 317 /* Let SEF perform startup. */ 318 sef_startup(); 319 } 320 321 /*===========================================================================* 322 * sef_cb_init_fresh * 323 *===========================================================================*/ 324 static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) 325 { 326 /* Initialize the rtl8169 driver. */ 327 long v; 328 329 system_hz = sys_hz(); 330 331 v = 0; 332 (void) env_parse("instance", "d", 0, &v, 0, 255); 333 re_instance = (int) v; 334 335 /* Claim buffer memory now. */ 336 rl_init_buf(&re_state); 337 338 /* Announce we are up! */ 339 netdriver_announce(); 340 341 return(OK); 342 } 343 344 /*===========================================================================* 345 * sef_cb_signal_handler * 346 *===========================================================================*/ 347 static void sef_cb_signal_handler(int signo) 348 { 349 re_t *rep; 350 351 /* Only check for termination signal, ignore anything else. */ 352 if (signo != SIGTERM) return; 353 354 rep = &re_state; 355 if (rep->re_mode == REM_ENABLED) 356 rl_outb(rep->re_base_port, RL_CR, RL_CR_RST); 357 358 exit(0); 359 } 360 361 static void mdio_write(u16_t port, int regaddr, int value) 362 { 363 int i; 364 365 rl_outl(port, RL_PHYAR, 0x80000000 | (regaddr & 0x1F) << 16 | (value & 0xFFFF)); 366 367 for (i = 20; i > 0; i--) { 368 /* 369 * Check if the RTL8169 has completed writing to the specified 370 * MII register 371 */ 372 if (!(rl_inl(port, RL_PHYAR) & 0x80000000)) 373 break; 374 else 375 micro_delay(50); 376 } 377 } 378 379 static int mdio_read(u16_t port, int regaddr) 380 { 381 int i, value = -1; 382 383 rl_outl(port, RL_PHYAR, (regaddr & 0x1F) << 16); 384 385 for (i = 20; i > 0; i--) { 386 /* 387 * Check if the RTL8169 has completed retrieving data from 388 * the specified MII register 389 */ 390 if (rl_inl(port, RL_PHYAR) & 0x80000000) { 391 value = (int)(rl_inl(port, RL_PHYAR) & 0xFFFF); 392 break; 393 } else 394 micro_delay(50); 395 } 396 return value; 397 } 398 399 /*===========================================================================* 400 * check_int_events * 401 *===========================================================================*/ 402 static void check_int_events(void) 403 { 404 re_t *rep; 405 406 rep = &re_state; 407 408 if (rep->re_mode != REM_ENABLED) 409 return; 410 if (!rep->re_got_int) 411 return; 412 rep->re_got_int = 0; 413 assert(rep->re_flags & REF_ENABLED); 414 rl_check_ints(rep); 415 } 416 417 static void rtl8169_update_stat(re_t *rep) 418 { 419 port_t port; 420 int i; 421 422 port = rep->re_base_port; 423 424 /* Fetch Missed Packets */ 425 rep->re_stat.ets_missedP += rl_inw(port, RL_MPC); 426 rl_outw(port, RL_MPC, 0x00); 427 428 /* Dump Tally Counter Command */ 429 rl_outl(port, RL_DTCCR_HI, 0); /* 64 bits */ 430 rl_outl(port, RL_DTCCR_LO, rep->dtcc_buf | RL_DTCCR_CMD); 431 for (i = 0; i < 1000; i++) { 432 if (!(rl_inl(port, RL_DTCCR_LO) & RL_DTCCR_CMD)) 433 break; 434 micro_delay(10); 435 } 436 437 /* Update counters */ 438 rep->re_stat.ets_frameAll = rep->v_dtcc_buf->FAE; 439 rep->re_stat.ets_transDef = rep->v_dtcc_buf->TxUndrn; 440 rep->re_stat.ets_transAb = rep->v_dtcc_buf->TxAbt; 441 rep->re_stat.ets_collision = 442 rep->v_dtcc_buf->Tx1Col + rep->v_dtcc_buf->TxMCol; 443 } 444 445 #if 0 446 /*===========================================================================* 447 * rtl8169_dump * 448 *===========================================================================*/ 449 static void rtl8169_dump(void) 450 { 451 re_dtcc *dtcc; 452 re_t *rep; 453 454 rep = &re_state; 455 456 printf("\n"); 457 if (rep->re_mode == REM_DISABLED) 458 printf("Realtek RTL 8169 instance %d is disabled\n", 459 re_instance); 460 461 if (rep->re_mode != REM_ENABLED) 462 return; 463 464 rtl8169_update_stat(rep); 465 466 printf("Realtek RTL 8169 statistics of instance %d:\n", re_instance); 467 468 printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr); 469 printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr); 470 printf("OVW :%8ld\n", rep->re_stat.ets_OVW); 471 472 printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr); 473 printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll); 474 printf("missedP :%8ld\n", rep->re_stat.ets_missedP); 475 476 printf("packetR :%8ld\t", rep->re_stat.ets_packetR); 477 printf("packetT :%8ld\t", rep->re_stat.ets_packetT); 478 printf("transDef :%8ld\n", rep->re_stat.ets_transDef); 479 480 printf("collision :%8ld\t", rep->re_stat.ets_collision); 481 printf("transAb :%8ld\t", rep->re_stat.ets_transAb); 482 printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense); 483 484 printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder); 485 printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver); 486 printf("OWC :%8ld\n", rep->re_stat.ets_OWC); 487 printf("interrupts :%8lu\n", rep->interrupts); 488 489 printf("\nRealtek RTL 8169 Tally Counters:\n"); 490 491 dtcc = rep->v_dtcc_buf; 492 493 if (dtcc->TxOk_high) 494 printf("TxOk :%8ld%08ld\t", dtcc->TxOk_high, dtcc->TxOk_low); 495 else 496 printf("TxOk :%16lu\t", dtcc->TxOk_low); 497 498 if (dtcc->RxOk_high) 499 printf("RxOk :%8ld%08ld\n", dtcc->RxOk_high, dtcc->RxOk_low); 500 else 501 printf("RxOk :%16lu\n", dtcc->RxOk_low); 502 503 if (dtcc->TxEr_high) 504 printf("TxEr :%8ld%08ld\t", dtcc->TxEr_high, dtcc->TxEr_low); 505 else 506 printf("TxEr :%16ld\t", dtcc->TxEr_low); 507 508 printf("RxEr :%16ld\n", dtcc->RxEr); 509 510 printf("Tx1Col :%16ld\t", dtcc->Tx1Col); 511 printf("TxMCol :%16ld\n", dtcc->TxMCol); 512 513 if (dtcc->RxOkPhy_high) 514 printf("RxOkPhy :%8ld%08ld\t", dtcc->RxOkPhy_high, dtcc->RxOkPhy_low); 515 else 516 printf("RxOkPhy :%16ld\t", dtcc->RxOkPhy_low); 517 518 if (dtcc->RxOkBrd_high) 519 printf("RxOkBrd :%8ld%08ld\n", dtcc->RxOkBrd_high, dtcc->RxOkBrd_low); 520 else 521 printf("RxOkBrd :%16ld\n", dtcc->RxOkBrd_low); 522 523 printf("RxOkMul :%16ld\t", dtcc->RxOkMul); 524 printf("MissPkt :%16d\n", dtcc->MissPkt); 525 526 printf("\nRealtek RTL 8169 Miscellaneous Info:\n"); 527 528 printf("re_flags : 0x%08x\n", rep->re_flags); 529 printf("tx_head :%8d busy %d\t", 530 rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy); 531 } 532 #endif 533 534 /*===========================================================================* 535 * do_init * 536 *===========================================================================*/ 537 static void rl_init(mp) 538 message *mp; 539 { 540 static int first_time = 1; 541 542 re_t *rep; 543 message reply_mess; 544 545 if (first_time) { 546 first_time = 0; 547 rl_pci_conf(); /* Configure PCI devices. */ 548 549 /* Use a synchronous alarm instead of a watchdog timer. */ 550 sys_setalarm(system_hz, 0); 551 } 552 553 rep = &re_state; 554 if (rep->re_mode == REM_DISABLED) { 555 /* This is the default, try to (re)locate the device. */ 556 rl_conf_hw(rep); 557 if (rep->re_mode == REM_DISABLED) { 558 /* Probe failed, or the device is configured off. */ 559 reply_mess.m_type = DL_CONF_REPLY; 560 reply_mess.m_netdrv_net_dl_conf.stat = ENXIO; 561 mess_reply(mp, &reply_mess); 562 return; 563 } 564 if (rep->re_mode == REM_ENABLED) 565 rl_init_hw(rep); 566 } 567 568 assert(rep->re_mode == REM_ENABLED); 569 assert(rep->re_flags & REF_ENABLED); 570 571 rep->re_flags &= ~(REF_PROMISC | REF_MULTI | REF_BROAD); 572 573 if (mp->m_net_netdrv_dl_conf.mode & DL_PROMISC_REQ) 574 rep->re_flags |= REF_PROMISC; 575 if (mp->m_net_netdrv_dl_conf.mode & DL_MULTI_REQ) 576 rep->re_flags |= REF_MULTI; 577 if (mp->m_net_netdrv_dl_conf.mode & DL_BROAD_REQ) 578 rep->re_flags |= REF_BROAD; 579 580 rl_rec_mode(rep); 581 582 reply_mess.m_type = DL_CONF_REPLY; 583 reply_mess.m_netdrv_net_dl_conf.stat = OK; 584 memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr, 585 rep->re_address.ea_addr, 586 sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr)); 587 588 mess_reply(mp, &reply_mess); 589 } 590 591 /*===========================================================================* 592 * rl_pci_conf * 593 *===========================================================================*/ 594 static void rl_pci_conf() 595 { 596 re_t *rep; 597 598 rep = &re_state; 599 600 strlcpy(rep->re_name, "rtl8169#0", sizeof(rep->re_name)); 601 rep->re_name[8] += re_instance; 602 rep->re_seen = FALSE; 603 604 pci_init(); 605 606 if (rl_probe(rep, re_instance)) 607 rep->re_seen = TRUE; 608 } 609 610 /*===========================================================================* 611 * rl_probe * 612 *===========================================================================*/ 613 static int rl_probe(rep, skip) 614 re_t *rep; 615 int skip; 616 { 617 int r, devind; 618 u16_t vid, did; 619 u32_t bar; 620 u8_t ilr; 621 #if VERBOSE 622 char *dname; 623 #endif 624 625 r = pci_first_dev(&devind, &vid, &did); 626 if (r == 0) 627 return 0; 628 629 while (skip--) { 630 r = pci_next_dev(&devind, &vid, &did); 631 if (!r) 632 return 0; 633 } 634 635 #if VERBOSE 636 dname = pci_dev_name(vid, did); 637 if (!dname) 638 dname = "unknown device"; 639 printf("%s: ", rep->re_name); 640 printf("%s (%x/%x) at %s\n", dname, vid, did, pci_slot_name(devind)); 641 #endif 642 643 pci_reserve(devind); 644 bar = pci_attr_r32(devind, PCI_BAR) & 0xffffffe0; 645 if (bar < 0x400) { 646 panic("base address is not properly configured"); 647 } 648 rep->re_base_port = bar; 649 650 ilr = pci_attr_r8(devind, PCI_ILR); 651 rep->re_irq = ilr; 652 #if VERBOSE 653 printf("%s: using I/O address 0x%lx, IRQ %d\n", 654 rep->re_name, (unsigned long)bar, ilr); 655 #endif 656 657 return TRUE; 658 } 659 660 /*===========================================================================* 661 * rl_conf_hw * 662 *===========================================================================*/ 663 static void rl_conf_hw(rep) 664 re_t *rep; 665 { 666 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ }; 667 668 rep->re_mode = REM_DISABLED; /* Superfluous */ 669 670 if (rep->re_seen) 671 rep->re_mode = REM_ENABLED; /* PCI device is present */ 672 if (rep->re_mode != REM_ENABLED) 673 return; 674 675 rep->re_flags = REF_EMPTY; 676 rep->re_link_up = 0; 677 rep->re_got_int = 0; 678 rep->re_send_int = 0; 679 rep->re_report_link = 0; 680 rep->re_need_reset = 0; 681 rep->re_tx_alive = 0; 682 rep->re_rx_head = 0; 683 rep->re_read_s = 0; 684 rep->re_tx_head = 0; 685 rep->re_stat = empty_stat; 686 rep->dtcc_counter = 0; 687 } 688 689 /*===========================================================================* 690 * rl_init_buf * 691 *===========================================================================*/ 692 static void rl_init_buf(rep) 693 re_t *rep; 694 { 695 size_t rx_bufsize, tx_bufsize, rx_descsize, tx_descsize, tot_bufsize; 696 struct re_desc *desc; 697 phys_bytes buf; 698 char *mallocbuf; 699 int d; 700 701 assert(!rep->setup); 702 703 /* Allocate receive and transmit descriptors */ 704 rx_descsize = (N_RX_DESC * sizeof(struct re_desc)); 705 tx_descsize = (N_TX_DESC * sizeof(struct re_desc)); 706 707 /* Allocate receive and transmit buffers */ 708 tx_bufsize = ETH_MAX_PACK_SIZE_TAGGED; 709 if (tx_bufsize % 4) 710 tx_bufsize += 4-(tx_bufsize % 4); /* Align */ 711 rx_bufsize = RX_BUFSIZE; 712 tot_bufsize = rx_descsize + tx_descsize; 713 tot_bufsize += (N_TX_DESC * tx_bufsize) + (N_RX_DESC * rx_bufsize); 714 tot_bufsize += sizeof(struct re_dtcc); 715 716 if (tot_bufsize % 4096) 717 tot_bufsize += 4096 - (tot_bufsize % 4096); 718 719 if (!(mallocbuf = alloc_contig(tot_bufsize, AC_ALIGN64K, &buf))) 720 panic("Couldn't allocate kernel buffer"); 721 722 /* Rx Descriptor */ 723 rep->re_rx_desc = (re_desc *)mallocbuf; 724 rep->p_rx_desc = buf; 725 memset(mallocbuf, 0x00, rx_descsize); 726 buf += rx_descsize; 727 mallocbuf += rx_descsize; 728 729 /* Tx Descriptor */ 730 rep->re_tx_desc = (re_desc *)mallocbuf; 731 rep->p_tx_desc = buf; 732 memset(mallocbuf, 0x00, tx_descsize); 733 buf += tx_descsize; 734 mallocbuf += tx_descsize; 735 736 desc = rep->re_rx_desc; 737 for (d = 0; d < N_RX_DESC; d++) { 738 /* Setting Rx buffer */ 739 rep->re_rx[d].ret_buf = buf; 740 rep->re_rx[d].v_ret_buf = mallocbuf; 741 buf += rx_bufsize; 742 mallocbuf += rx_bufsize; 743 744 /* Setting Rx descriptor */ 745 if (d == (N_RX_DESC - 1)) /* Last descriptor? if so, set the EOR bit */ 746 desc->status = DESC_EOR | DESC_OWN | (RX_BUFSIZE & DESC_RX_LENMASK); 747 else 748 desc->status = DESC_OWN | (RX_BUFSIZE & DESC_RX_LENMASK); 749 750 desc->addr_low = rep->re_rx[d].ret_buf; 751 desc++; 752 } 753 desc = rep->re_tx_desc; 754 for (d = 0; d < N_TX_DESC; d++) { 755 rep->re_tx[d].ret_busy = FALSE; 756 rep->re_tx[d].ret_buf = buf; 757 rep->re_tx[d].v_ret_buf = mallocbuf; 758 buf += tx_bufsize; 759 mallocbuf += tx_bufsize; 760 761 /* Setting Tx descriptor */ 762 desc->addr_low = rep->re_tx[d].ret_buf; 763 desc++; 764 } 765 766 /* Dump Tally Counter buffer */ 767 rep->dtcc_buf = buf; 768 rep->v_dtcc_buf = (re_dtcc *)mallocbuf; 769 770 rep->setup = 1; 771 } 772 773 /*===========================================================================* 774 * rl_init_hw * 775 *===========================================================================*/ 776 static void rl_init_hw(rep) 777 re_t *rep; 778 { 779 int s; 780 #if VERBOSE 781 int i; 782 #endif 783 784 rep->re_flags = REF_EMPTY; 785 rep->re_flags |= REF_ENABLED; 786 787 /* 788 * Set the interrupt handler. The policy is to only send HARD_INT 789 * notifications. Don't reenable interrupts automatically. The id 790 * that is passed back is the interrupt line number. 791 */ 792 rep->re_hook_id = rep->re_irq; 793 if ((s = sys_irqsetpolicy(rep->re_irq, 0, &rep->re_hook_id)) != OK) 794 printf("RTL8169: error, couldn't set IRQ policy: %d\n", s); 795 796 rl_reset_hw(rep); 797 798 if ((s = sys_irqenable(&rep->re_hook_id)) != OK) 799 printf("RTL8169: error, couldn't enable interrupts: %d\n", s); 800 801 #if VERBOSE 802 printf("%s: model: %s mac: 0x%08x\n", 803 rep->re_name, rep->re_model, rep->re_mac); 804 #endif 805 806 rl_confaddr(rep); 807 #if VERBOSE 808 printf("%s: Ethernet address ", rep->re_name); 809 for (i = 0; i < 6; i++) { 810 printf("%x%c", rep->re_address.ea_addr[i], 811 i < 5 ? ':' : '\n'); 812 } 813 #endif 814 } 815 816 static void rtl8169s_phy_config(port_t port) 817 { 818 mdio_write(port, 0x1f, 0x0001); 819 mdio_write(port, 0x06, 0x006e); 820 mdio_write(port, 0x08, 0x0708); 821 mdio_write(port, 0x15, 0x4000); 822 mdio_write(port, 0x18, 0x65c7); 823 824 mdio_write(port, 0x1f, 0x0001); 825 mdio_write(port, 0x03, 0x00a1); 826 mdio_write(port, 0x02, 0x0008); 827 mdio_write(port, 0x01, 0x0120); 828 mdio_write(port, 0x00, 0x1000); 829 mdio_write(port, 0x04, 0x0800); 830 mdio_write(port, 0x04, 0x0000); 831 832 mdio_write(port, 0x03, 0xff41); 833 mdio_write(port, 0x02, 0xdf60); 834 mdio_write(port, 0x01, 0x0140); 835 mdio_write(port, 0x00, 0x0077); 836 mdio_write(port, 0x04, 0x7800); 837 mdio_write(port, 0x04, 0x7000); 838 839 mdio_write(port, 0x03, 0x802f); 840 mdio_write(port, 0x02, 0x4f02); 841 mdio_write(port, 0x01, 0x0409); 842 mdio_write(port, 0x00, 0xf0f9); 843 mdio_write(port, 0x04, 0x9800); 844 mdio_write(port, 0x04, 0x9000); 845 846 mdio_write(port, 0x03, 0xdf01); 847 mdio_write(port, 0x02, 0xdf20); 848 mdio_write(port, 0x01, 0xff95); 849 mdio_write(port, 0x00, 0xba00); 850 mdio_write(port, 0x04, 0xa800); 851 mdio_write(port, 0x04, 0xa000); 852 853 mdio_write(port, 0x03, 0xff41); 854 mdio_write(port, 0x02, 0xdf20); 855 mdio_write(port, 0x01, 0x0140); 856 mdio_write(port, 0x00, 0x00bb); 857 mdio_write(port, 0x04, 0xb800); 858 mdio_write(port, 0x04, 0xb000); 859 860 mdio_write(port, 0x03, 0xdf41); 861 mdio_write(port, 0x02, 0xdc60); 862 mdio_write(port, 0x01, 0x6340); 863 mdio_write(port, 0x00, 0x007d); 864 mdio_write(port, 0x04, 0xd800); 865 mdio_write(port, 0x04, 0xd000); 866 867 mdio_write(port, 0x03, 0xdf01); 868 mdio_write(port, 0x02, 0xdf20); 869 mdio_write(port, 0x01, 0x100a); 870 mdio_write(port, 0x00, 0xa0ff); 871 mdio_write(port, 0x04, 0xf800); 872 mdio_write(port, 0x04, 0xf000); 873 874 mdio_write(port, 0x1f, 0x0000); 875 mdio_write(port, 0x0b, 0x0000); 876 mdio_write(port, 0x00, 0x9200); 877 } 878 879 static void rtl8169scd_phy_config(port_t port) 880 { 881 mdio_write(port, 0x1f, 0x0001); 882 mdio_write(port, 0x04, 0x0000); 883 mdio_write(port, 0x03, 0x00a1); 884 mdio_write(port, 0x02, 0x0008); 885 mdio_write(port, 0x01, 0x0120); 886 mdio_write(port, 0x00, 0x1000); 887 mdio_write(port, 0x04, 0x0800); 888 mdio_write(port, 0x04, 0x9000); 889 mdio_write(port, 0x03, 0x802f); 890 mdio_write(port, 0x02, 0x4f02); 891 mdio_write(port, 0x01, 0x0409); 892 mdio_write(port, 0x00, 0xf099); 893 mdio_write(port, 0x04, 0x9800); 894 mdio_write(port, 0x04, 0xa000); 895 mdio_write(port, 0x03, 0xdf01); 896 mdio_write(port, 0x02, 0xdf20); 897 mdio_write(port, 0x01, 0xff95); 898 mdio_write(port, 0x00, 0xba00); 899 mdio_write(port, 0x04, 0xa800); 900 mdio_write(port, 0x04, 0xf000); 901 mdio_write(port, 0x03, 0xdf01); 902 mdio_write(port, 0x02, 0xdf20); 903 mdio_write(port, 0x01, 0x101a); 904 mdio_write(port, 0x00, 0xa0ff); 905 mdio_write(port, 0x04, 0xf800); 906 mdio_write(port, 0x04, 0x0000); 907 mdio_write(port, 0x1f, 0x0000); 908 909 mdio_write(port, 0x1f, 0x0001); 910 mdio_write(port, 0x10, 0xf41b); 911 mdio_write(port, 0x14, 0xfb54); 912 mdio_write(port, 0x18, 0xf5c7); 913 mdio_write(port, 0x1f, 0x0000); 914 915 mdio_write(port, 0x1f, 0x0001); 916 mdio_write(port, 0x17, 0x0cc0); 917 mdio_write(port, 0x1f, 0x0000); 918 } 919 920 /*===========================================================================* 921 * rl_reset_hw * 922 *===========================================================================*/ 923 static void rl_reset_hw(rep) 924 re_t *rep; 925 { 926 port_t port; 927 u32_t t; 928 int i; 929 930 port = rep->re_base_port; 931 932 rl_outw(port, RL_IMR, 0x0000); 933 934 /* Reset the device */ 935 rl_outb(port, RL_CR, RL_CR_RST); 936 SPIN_UNTIL(!(rl_inb(port, RL_CR) & RL_CR_RST), 1000000); 937 if (rl_inb(port, RL_CR) & RL_CR_RST) 938 printf("rtl8169: reset failed to complete"); 939 rl_outw(port, RL_ISR, 0xFFFF); 940 941 /* Get Model and MAC info */ 942 t = rl_inl(port, RL_TCR); 943 rep->re_mac = (t & (RL_TCR_HWVER_AM | RL_TCR_HWVER_BM)); 944 switch (rep->re_mac) { 945 case RL_TCR_HWVER_RTL8169: 946 rep->re_model = "RTL8169"; 947 948 rl_outw(port, RL_CCR_UNDOC, 0x01); 949 break; 950 case RL_TCR_HWVER_RTL8169S: 951 rep->re_model = "RTL8169S"; 952 953 rtl8169s_phy_config(port); 954 955 rl_outw(port, RL_CCR_UNDOC, 0x01); 956 mdio_write(port, 0x0b, 0x0000); /* w 0x0b 15 0 0 */ 957 break; 958 case RL_TCR_HWVER_RTL8110S: 959 rep->re_model = "RTL8110S"; 960 961 rtl8169s_phy_config(port); 962 963 rl_outw(port, RL_CCR_UNDOC, 0x01); 964 break; 965 case RL_TCR_HWVER_RTL8169SB: 966 rep->re_model = "RTL8169SB"; 967 968 mdio_write(port, 0x1f, 0x02); 969 mdio_write(port, 0x01, 0x90d0); 970 mdio_write(port, 0x1f, 0x00); 971 972 rl_outw(port, RL_CCR_UNDOC, 0x01); 973 break; 974 case RL_TCR_HWVER_RTL8110SCd: 975 rep->re_model = "RTL8110SCd"; 976 977 rtl8169scd_phy_config(port); 978 979 rl_outw(port, RL_CCR_UNDOC, 0x01); 980 break; 981 case RL_TCR_HWVER_RTL8105E: 982 rep->re_model = "RTL8105E"; 983 break; 984 default: 985 rep->re_model = "Unknown"; 986 rep->re_mac = t; 987 break; 988 } 989 990 mdio_write(port, MII_CTRL, MII_CTRL_RST); 991 for (i = 0; i < 1000; i++) { 992 t = mdio_read(port, MII_CTRL); 993 if (!(t & MII_CTRL_RST)) 994 break; 995 else 996 micro_delay(100); 997 } 998 999 t = mdio_read(port, MII_CTRL) | MII_CTRL_ANE | MII_CTRL_DM | MII_CTRL_SP_1000; 1000 mdio_write(port, MII_CTRL, t); 1001 1002 t = mdio_read(port, MII_ANA); 1003 t |= MII_ANA_10THD | MII_ANA_10TFD | MII_ANA_100TXHD | MII_ANA_100TXFD; 1004 t |= MII_ANA_PAUSE_SYM | MII_ANA_PAUSE_ASYM; 1005 mdio_write(port, MII_ANA, t); 1006 1007 t = mdio_read(port, MII_1000_CTRL) | 0x300; 1008 mdio_write(port, MII_1000_CTRL, t); 1009 1010 /* Restart Auto-Negotiation Process */ 1011 t = mdio_read(port, MII_CTRL) | MII_CTRL_ANE | MII_CTRL_RAN; 1012 mdio_write(port, MII_CTRL, t); 1013 1014 rl_outw(port, RL_9346CR, RL_9346CR_EEM_CONFIG); /* Unlock */ 1015 1016 switch (rep->re_mac) { 1017 case RL_TCR_HWVER_RTL8169S: 1018 case RL_TCR_HWVER_RTL8110S: 1019 /* Bit-3 and bit-14 of the C+CR register MUST be 1. */ 1020 t = rl_inw(port, RL_CPLUSCMD); 1021 rl_outw(port, RL_CPLUSCMD, t | RL_CPLUS_MULRW | (1 << 14)); 1022 break; 1023 case RL_TCR_HWVER_RTL8169: 1024 case RL_TCR_HWVER_RTL8169SB: 1025 case RL_TCR_HWVER_RTL8110SCd: 1026 t = rl_inw(port, RL_CPLUSCMD); 1027 rl_outw(port, RL_CPLUSCMD, t | RL_CPLUS_MULRW); 1028 break; 1029 } 1030 1031 rl_outw(port, RL_INTRMITIGATE, 0x00); 1032 1033 t = rl_inb(port, RL_CR); 1034 rl_outb(port, RL_CR, t | RL_CR_RE | RL_CR_TE); 1035 1036 /* Initialize Rx */ 1037 rl_outw(port, RL_RMS, RX_BUFSIZE); /* Maximum rx packet size */ 1038 t = rl_inl(port, RL_RCR) & RX_CONFIG_MASK; 1039 rl_outl(port, RL_RCR, RL_RCR_RXFTH_UNLIM | RL_RCR_MXDMA_1024 | t); 1040 rl_outl(port, RL_RDSAR_LO, rep->p_rx_desc); 1041 rl_outl(port, RL_RDSAR_HI, 0x00); /* For 64 bit */ 1042 1043 /* Initialize Tx */ 1044 rl_outw(port, RL_ETTHR, 0x3f); /* No early transmit */ 1045 rl_outl(port, RL_TCR, RL_TCR_MXDMA_2048 | RL_TCR_IFG_STD); 1046 rl_outl(port, RL_TNPDS_LO, rep->p_tx_desc); 1047 rl_outl(port, RL_TNPDS_HI, 0x00); /* For 64 bit */ 1048 1049 rl_outw(port, RL_9346CR, RL_9346CR_EEM_NORMAL); /* Lock */ 1050 1051 rl_outw(port, RL_MPC, 0x00); 1052 rl_outw(port, RL_MULINT, rl_inw(port, RL_MULINT) & 0xF000); 1053 rl_outw(port, RL_IMR, RE_INTR_MASK); 1054 } 1055 1056 /*===========================================================================* 1057 * rl_confaddr * 1058 *===========================================================================*/ 1059 static void rl_confaddr(rep) 1060 re_t *rep; 1061 { 1062 static char eakey[] = RL_ENVVAR "#_EA"; 1063 static char eafmt[] = "x:x:x:x:x:x"; 1064 1065 int i; 1066 port_t port; 1067 u32_t w; 1068 long v; 1069 1070 /* User defined ethernet address? */ 1071 eakey[sizeof(RL_ENVVAR)-1] = '0' + re_instance; 1072 1073 port = rep->re_base_port; 1074 1075 for (i = 0; i < 6; i++) { 1076 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) 1077 break; 1078 rep->re_address.ea_addr[i] = v; 1079 } 1080 1081 if (i != 0 && i != 6) 1082 env_panic(eakey); /* It's all or nothing */ 1083 1084 /* Should update ethernet address in hardware */ 1085 if (i == 6) { 1086 port = rep->re_base_port; 1087 rl_outb(port, RL_9346CR, RL_9346CR_EEM_CONFIG); 1088 w = 0; 1089 for (i = 0; i < 4; i++) 1090 w |= (rep->re_address.ea_addr[i] << (i * 8)); 1091 rl_outl(port, RL_IDR, w); 1092 w = 0; 1093 for (i = 4; i < 6; i++) 1094 w |= (rep->re_address.ea_addr[i] << ((i-4) * 8)); 1095 rl_outl(port, RL_IDR + 4, w); 1096 rl_outb(port, RL_9346CR, RL_9346CR_EEM_NORMAL); 1097 } 1098 1099 /* Get ethernet address */ 1100 for (i = 0; i < 6; i++) 1101 rep->re_address.ea_addr[i] = rl_inb(port, RL_IDR+i); 1102 } 1103 1104 /*===========================================================================* 1105 * rl_rec_mode * 1106 *===========================================================================*/ 1107 static void rl_rec_mode(rep) 1108 re_t *rep; 1109 { 1110 port_t port; 1111 u32_t rcr; 1112 u32_t mc_filter[2]; /* Multicast hash filter */ 1113 1114 port = rep->re_base_port; 1115 1116 mc_filter[1] = mc_filter[0] = 0xffffffff; 1117 rl_outl(port, RL_MAR + 0, mc_filter[0]); 1118 rl_outl(port, RL_MAR + 4, mc_filter[1]); 1119 1120 rcr = rl_inl(port, RL_RCR); 1121 rcr &= ~(RL_RCR_AB | RL_RCR_AM | RL_RCR_APM | RL_RCR_AAP); 1122 if (rep->re_flags & REF_PROMISC) 1123 rcr |= RL_RCR_AB | RL_RCR_AM | RL_RCR_AAP; 1124 if (rep->re_flags & REF_BROAD) 1125 rcr |= RL_RCR_AB; 1126 if (rep->re_flags & REF_MULTI) 1127 rcr |= RL_RCR_AM; 1128 rcr |= RL_RCR_APM; 1129 rl_outl(port, RL_RCR, RL_RCR_RXFTH_UNLIM | RL_RCR_MXDMA_1024 | rcr); 1130 } 1131 1132 void transmittest(re_t *rep) 1133 { 1134 int tx_head; 1135 int ipc_status; 1136 1137 tx_head = rep->re_tx_head; 1138 1139 if(rep->re_tx[tx_head].ret_busy) { 1140 do { 1141 message m; 1142 int r; 1143 if ((r = netdriver_receive(ANY, &m, &ipc_status)) != OK) 1144 panic("netdriver_receive failed: %d", r); 1145 } while(m.m_source != HARDWARE); 1146 assert(!(rep->re_flags & REF_SEND_AVAIL)); 1147 rep->re_flags |= REF_SEND_AVAIL; 1148 } 1149 1150 return; 1151 } 1152 1153 /*===========================================================================* 1154 * rl_readv_s * 1155 *===========================================================================*/ 1156 static void rl_readv_s(const message *mp, int from_int) 1157 { 1158 int i, j, n, s, count, size, index; 1159 port_t port; 1160 unsigned totlen, packlen; 1161 re_desc *desc; 1162 u32_t rxstat = 0x12345678; 1163 re_t *rep; 1164 iovec_s_t *iovp; 1165 int cps; 1166 int iov_offset = 0; 1167 1168 rep = &re_state; 1169 1170 rep->re_client = mp->m_source; 1171 count = mp->m_net_netdrv_dl_readv_s.count; 1172 1173 assert(rep->re_mode == REM_ENABLED); 1174 assert(rep->re_flags & REF_ENABLED); 1175 1176 port = rep->re_base_port; 1177 1178 /* 1179 * Assume that the RL_CR_BUFE check was been done by rl_checks_ints 1180 */ 1181 if (!from_int && (rl_inb(port, RL_CR) & RL_CR_BUFE)) 1182 goto suspend; /* Receive buffer is empty, suspend */ 1183 1184 index = rep->re_rx_head; 1185 desc = rep->re_rx_desc; 1186 desc += index; 1187 readvs_loop: 1188 rxstat = desc->status; 1189 1190 if (rxstat & DESC_OWN) 1191 goto suspend; 1192 1193 if (rxstat & DESC_RX_CRC) 1194 rep->re_stat.ets_CRCerr++; 1195 1196 if ((rxstat & (DESC_FS | DESC_LS)) != (DESC_FS | DESC_LS)) { 1197 #if VERBOSE 1198 printf("rl_readv_s: packet is fragmented\n"); 1199 #endif 1200 /* Fix the fragmented packet */ 1201 if (index == N_RX_DESC - 1) { 1202 desc->status = DESC_EOR | DESC_OWN | (RX_BUFSIZE & DESC_RX_LENMASK); 1203 index = 0; 1204 desc = rep->re_rx_desc; 1205 } else { 1206 desc->status = DESC_OWN | (RX_BUFSIZE & DESC_RX_LENMASK); 1207 index++; 1208 desc++; 1209 } 1210 goto readvs_loop; /* Loop until we get correct packet */ 1211 } 1212 1213 totlen = rxstat & DESC_RX_LENMASK; 1214 if (totlen < 8 || totlen > 2 * ETH_MAX_PACK_SIZE) { 1215 /* Someting went wrong */ 1216 printf("rl_readv_s: bad length (%u) in status 0x%08x\n", 1217 totlen, rxstat); 1218 panic(NULL); 1219 } 1220 1221 /* Should subtract the CRC */ 1222 packlen = totlen - ETH_CRC_SIZE; 1223 1224 size = 0; 1225 for (i = 0; i < count; i += IOVEC_NR, 1226 iov_offset += IOVEC_NR * sizeof(rep->re_iovec_s[0])) 1227 { 1228 n = IOVEC_NR; 1229 if (i + n > count) 1230 n = count-i; 1231 cps = sys_safecopyfrom(mp->m_source, 1232 mp->m_net_netdrv_dl_readv_s.grant, iov_offset, 1233 (vir_bytes) rep->re_iovec_s, 1234 n * sizeof(rep->re_iovec_s[0])); 1235 if (cps != OK) { 1236 panic("rl_readv_s: sys_safecopyfrom failed: %d", cps); 1237 } 1238 1239 for (j = 0, iovp = rep->re_iovec_s; j < n; j++, iovp++) { 1240 s = iovp->iov_size; 1241 if (size + s > packlen) { 1242 assert(packlen > size); 1243 s = packlen-size; 1244 } 1245 1246 cps = sys_safecopyto(mp->m_source, iovp->iov_grant, 0, 1247 (vir_bytes) rep->re_rx[index].v_ret_buf + size, s); 1248 if (cps != OK) 1249 panic("rl_readv_s: sys_safecopyto failed: %d", cps); 1250 1251 size += s; 1252 if (size == packlen) 1253 break; 1254 } 1255 if (size == packlen) 1256 break; 1257 } 1258 if (size < packlen) 1259 assert(0); 1260 1261 rep->re_stat.ets_packetR++; 1262 rep->re_read_s = packlen; 1263 if (index == N_RX_DESC - 1) { 1264 desc->status = DESC_EOR | DESC_OWN | (RX_BUFSIZE & DESC_RX_LENMASK); 1265 index = 0; 1266 } else { 1267 desc->status = DESC_OWN | (RX_BUFSIZE & DESC_RX_LENMASK); 1268 index++; 1269 } 1270 rep->re_rx_head = index; 1271 assert(rep->re_rx_head < N_RX_DESC); 1272 rep->re_flags = (rep->re_flags & ~REF_READING) | REF_PACK_RECV; 1273 1274 if (!from_int) 1275 reply(rep); 1276 1277 return; 1278 1279 suspend: 1280 if (from_int) { 1281 assert(rep->re_flags & REF_READING); 1282 1283 /* No need to store any state */ 1284 return; 1285 } 1286 1287 rep->re_rx_mess = *mp; 1288 assert(!(rep->re_flags & REF_READING)); 1289 rep->re_flags |= REF_READING; 1290 1291 reply(rep); 1292 } 1293 1294 /*===========================================================================* 1295 * rl_writev_s * 1296 *===========================================================================*/ 1297 static void rl_writev_s(const message *mp, int from_int) 1298 { 1299 int i, j, n, s, count, size; 1300 int tx_head; 1301 re_t *rep; 1302 iovec_s_t *iovp; 1303 re_desc *desc; 1304 char *ret; 1305 int cps; 1306 int iov_offset = 0; 1307 1308 rep = &re_state; 1309 1310 rep->re_client = mp->m_source; 1311 count = mp->m_net_netdrv_dl_writev_s.count; 1312 assert(rep->setup); 1313 1314 assert(rep->re_mode == REM_ENABLED); 1315 assert(rep->re_flags & REF_ENABLED); 1316 1317 if (from_int) { 1318 assert(rep->re_flags & REF_SEND_AVAIL); 1319 rep->re_flags &= ~REF_SEND_AVAIL; 1320 rep->re_send_int = FALSE; 1321 rep->re_tx_alive = TRUE; 1322 } 1323 1324 tx_head = rep->re_tx_head; 1325 1326 desc = rep->re_tx_desc; 1327 desc += tx_head; 1328 1329 if(!desc || !rep->re_tx_desc) { 1330 printf("desc %p, re_tx_desc %p, tx_head %d, setup %d\n", 1331 desc, rep->re_tx_desc, tx_head, rep->setup); 1332 } 1333 1334 assert(rep->re_tx_desc); 1335 assert(rep->re_tx_head >= 0 && rep->re_tx_head < N_TX_DESC); 1336 1337 assert(desc); 1338 1339 if (rep->re_tx[tx_head].ret_busy) { 1340 assert(!(rep->re_flags & REF_SEND_AVAIL)); 1341 rep->re_flags |= REF_SEND_AVAIL; 1342 if (rep->re_tx[tx_head].ret_busy) 1343 goto suspend; 1344 1345 /* 1346 * Race condition, the interrupt handler may clear re_busy 1347 * before we got a chance to set REF_SEND_AVAIL. Checking 1348 * ret_busy twice should be sufficient. 1349 */ 1350 #if VERBOSE 1351 printf("rl_writev_s: race detected\n"); 1352 #endif 1353 rep->re_flags &= ~REF_SEND_AVAIL; 1354 rep->re_send_int = FALSE; 1355 } 1356 1357 assert(!(rep->re_flags & REF_SEND_AVAIL)); 1358 assert(!(rep->re_flags & REF_PACK_SENT)); 1359 1360 size = 0; 1361 ret = rep->re_tx[tx_head].v_ret_buf; 1362 for (i = 0; i < count; i += IOVEC_NR, 1363 iov_offset += IOVEC_NR * sizeof(rep->re_iovec_s[0])) 1364 { 1365 n = IOVEC_NR; 1366 if (i + n > count) 1367 n = count - i; 1368 cps = sys_safecopyfrom(mp->m_source, 1369 mp->m_net_netdrv_dl_writev_s.grant, iov_offset, 1370 (vir_bytes) rep->re_iovec_s, 1371 n * sizeof(rep->re_iovec_s[0])); 1372 if (cps != OK) { 1373 panic("rl_writev_s: sys_safecopyfrom failed: %d", cps); 1374 } 1375 1376 for (j = 0, iovp = rep->re_iovec_s; j < n; j++, iovp++) { 1377 s = iovp->iov_size; 1378 if (size + s > ETH_MAX_PACK_SIZE_TAGGED) 1379 panic("invalid packet size"); 1380 1381 cps = sys_safecopyfrom(mp->m_source, iovp->iov_grant, 1382 0, (vir_bytes) ret, s); 1383 if (cps != OK) { 1384 panic("rl_writev_s: sys_safecopyfrom failed: %d", cps); 1385 } 1386 size += s; 1387 ret += s; 1388 } 1389 } 1390 assert(desc); 1391 if (size < ETH_MIN_PACK_SIZE) 1392 panic("invalid packet size: %d", size); 1393 1394 rep->re_tx[tx_head].ret_busy = TRUE; 1395 1396 if (tx_head == N_TX_DESC - 1) { 1397 desc->status = DESC_EOR | DESC_OWN | DESC_FS | DESC_LS | size; 1398 tx_head = 0; 1399 } else { 1400 desc->status = DESC_OWN | DESC_FS | DESC_LS | size; 1401 tx_head++; 1402 } 1403 1404 assert(tx_head < N_TX_DESC); 1405 rep->re_tx_head = tx_head; 1406 1407 rl_outl(rep->re_base_port, RL_TPPOLL, RL_TPPOLL_NPQ); 1408 rep->re_flags |= REF_PACK_SENT; 1409 1410 /* 1411 * If the interrupt handler called, don't send a reply. The reply 1412 * will be sent after all interrupts are handled. 1413 */ 1414 if (from_int) 1415 return; 1416 reply(rep); 1417 return; 1418 1419 suspend: 1420 if (from_int) 1421 panic("should not be sending"); 1422 1423 rep->re_tx_mess = *mp; 1424 reply(rep); 1425 } 1426 1427 /*===========================================================================* 1428 * rl_check_ints * 1429 *===========================================================================*/ 1430 static void rl_check_ints(rep) 1431 re_t *rep; 1432 { 1433 int re_flags; 1434 1435 re_flags = rep->re_flags; 1436 1437 if ((re_flags & REF_READING) && 1438 !(rl_inb(rep->re_base_port, RL_CR) & RL_CR_BUFE)) 1439 { 1440 assert(rep->re_rx_mess.m_type == DL_READV_S); 1441 rl_readv_s(&rep->re_rx_mess, TRUE /* from int */); 1442 } 1443 1444 if (rep->re_need_reset) 1445 rl_do_reset(rep); 1446 1447 if (rep->re_send_int) { 1448 assert(rep->re_tx_mess.m_type == DL_WRITEV_S); 1449 rl_writev_s(&rep->re_tx_mess, TRUE /* from int */); 1450 } 1451 1452 if (rep->re_report_link) { 1453 rep->re_report_link = FALSE; 1454 1455 rl_report_link(rep); 1456 } 1457 1458 if (rep->re_flags & (REF_PACK_SENT | REF_PACK_RECV)) 1459 reply(rep); 1460 } 1461 1462 /*===========================================================================* 1463 * rl_report_link * 1464 *===========================================================================*/ 1465 static void rl_report_link(rep) 1466 re_t *rep; 1467 { 1468 #if VERBOSE 1469 port_t port; 1470 u8_t mii_status; 1471 1472 port = rep->re_base_port; 1473 1474 mii_status = rl_inb(port, RL_PHYSTAT); 1475 1476 if (mii_status & RL_STAT_LINK) { 1477 rep->re_link_up = 1; 1478 printf("%s: link up at ", rep->re_name); 1479 } else { 1480 rep->re_link_up = 0; 1481 printf("%s: link down\n", rep->re_name); 1482 return; 1483 } 1484 1485 if (mii_status & RL_STAT_1000) 1486 printf("1000 Mbps"); 1487 else if (mii_status & RL_STAT_100) 1488 printf("100 Mbps"); 1489 else if (mii_status & RL_STAT_10) 1490 printf("10 Mbps"); 1491 1492 if (mii_status & RL_STAT_FULLDUP) 1493 printf(", full duplex"); 1494 else 1495 printf(", half duplex"); 1496 printf("\n"); 1497 #endif 1498 1499 dump_phy(rep); 1500 } 1501 1502 /*===========================================================================* 1503 * rl_do_reset * 1504 *===========================================================================*/ 1505 static void rl_do_reset(rep) 1506 re_t *rep; 1507 { 1508 rep->re_need_reset = FALSE; 1509 rl_reset_hw(rep); 1510 rl_rec_mode(rep); 1511 1512 rep->re_tx_head = 0; 1513 if (rep->re_flags & REF_SEND_AVAIL) { 1514 rep->re_tx[rep->re_tx_head].ret_busy = FALSE; 1515 rep->re_send_int = TRUE; 1516 } 1517 } 1518 1519 /*===========================================================================* 1520 * rl_getstat_s * 1521 *===========================================================================*/ 1522 static void rl_getstat_s(mp) 1523 message *mp; 1524 { 1525 int r; 1526 eth_stat_t stats; 1527 re_t *rep; 1528 1529 rep = &re_state; 1530 1531 assert(rep->re_mode == REM_ENABLED); 1532 assert(rep->re_flags & REF_ENABLED); 1533 1534 stats = rep->re_stat; 1535 1536 r = sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant, 1537 0, (vir_bytes) &stats, sizeof(stats)); 1538 if (r != OK) 1539 panic("rl_getstat_s: sys_safecopyto failed: %d", r); 1540 1541 mp->m_type = DL_STAT_REPLY; 1542 r = ipc_send(mp->m_source, mp); 1543 if (r != OK) 1544 panic("rl_getstat_s: ipc_send failed: %d", r); 1545 } 1546 1547 /*===========================================================================* 1548 * reply * 1549 *===========================================================================*/ 1550 static void reply(rep) 1551 re_t *rep; 1552 { 1553 message reply; 1554 int flags; 1555 int r; 1556 1557 flags = DL_NOFLAGS; 1558 if (rep->re_flags & REF_PACK_SENT) 1559 flags |= DL_PACK_SEND; 1560 if (rep->re_flags & REF_PACK_RECV) 1561 flags |= DL_PACK_RECV; 1562 1563 reply.m_type = DL_TASK_REPLY; 1564 reply.m_netdrv_net_dl_task.flags = flags; 1565 reply.m_netdrv_net_dl_task.count = rep->re_read_s; 1566 1567 r = ipc_send(rep->re_client, &reply); 1568 1569 if (r < 0) { 1570 printf("RTL8169 tried sending to %d, type %d\n", 1571 rep->re_client, reply.m_type); 1572 panic("ipc_send failed: %d", r); 1573 } 1574 1575 rep->re_read_s = 0; 1576 rep->re_flags &= ~(REF_PACK_SENT | REF_PACK_RECV); 1577 } 1578 1579 /*===========================================================================* 1580 * mess_reply * 1581 *===========================================================================*/ 1582 static void mess_reply(req, reply_mess) 1583 message *req; 1584 message *reply_mess; 1585 { 1586 if (ipc_send(req->m_source, reply_mess) != OK) 1587 panic("unable to mess_reply"); 1588 } 1589 1590 static void dump_phy(const re_t *rep) 1591 { 1592 #if VERBOSE 1593 port_t port; 1594 u32_t t; 1595 1596 port = rep->re_base_port; 1597 1598 t = rl_inb(port, RL_CONFIG0); 1599 printf("CONFIG0\t\t:"); 1600 t = t & RL_CFG0_ROM; 1601 if (t == RL_CFG0_ROM128K) 1602 printf(" 128K Boot ROM"); 1603 else if (t == RL_CFG0_ROM64K) 1604 printf(" 64K Boot ROM"); 1605 else if (t == RL_CFG0_ROM32K) 1606 printf(" 32K Boot ROM"); 1607 else if (t == RL_CFG0_ROM16K) 1608 printf(" 16K Boot ROM"); 1609 else if (t == RL_CFG0_ROM8K) 1610 printf(" 8K Boot ROM"); 1611 else if (t == RL_CFG0_ROMNO) 1612 printf(" No Boot ROM"); 1613 printf("\n"); 1614 1615 t = rl_inb(port, RL_CONFIG1); 1616 printf("CONFIG1\t\t:"); 1617 if (t & RL_CFG1_LEDS1) 1618 printf(" LED1"); 1619 if (t & RL_CFG1_LEDS0) 1620 printf(" LED0"); 1621 if (t & RL_CFG1_DVRLOAD) 1622 printf(" Driver"); 1623 if (t & RL_CFG1_LWACT) 1624 printf(" LWAKE"); 1625 if (t & RL_CFG1_IOMAP) 1626 printf(" IOMAP"); 1627 if (t & RL_CFG1_MEMMAP) 1628 printf(" MEMMAP"); 1629 if (t & RL_CFG1_VPD) 1630 printf(" VPD"); 1631 if (t & RL_CFG1_PME) 1632 printf(" PME"); 1633 printf("\n"); 1634 1635 t = rl_inb(port, RL_CONFIG2); 1636 printf("CONFIG2\t\t:"); 1637 if (t & RL_CFG2_AUX) 1638 printf(" AUX"); 1639 if (t & RL_CFG2_PCIBW) 1640 printf(" PCI-64-Bit"); 1641 else 1642 printf(" PCI-32-Bit"); 1643 t = t & RL_CFG2_PCICLK; 1644 if (t == RL_CFG2_66MHZ) 1645 printf(" 66 MHz"); 1646 else if (t == RL_CFG2_33MHZ) 1647 printf(" 33 MHz"); 1648 printf("\n"); 1649 1650 t = mdio_read(port, MII_CTRL); 1651 printf("MII_CTRL\t:"); 1652 if (t & MII_CTRL_RST) 1653 printf(" Reset"); 1654 if (t & MII_CTRL_LB) 1655 printf(" Loopback"); 1656 if (t & MII_CTRL_ANE) 1657 printf(" ANE"); 1658 if (t & MII_CTRL_PD) 1659 printf(" Power-down"); 1660 if (t & MII_CTRL_ISO) 1661 printf(" Isolate"); 1662 if (t & MII_CTRL_RAN) 1663 printf(" RAN"); 1664 if (t & MII_CTRL_DM) 1665 printf(" Full-duplex"); 1666 if (t & MII_CTRL_CT) 1667 printf(" COL-signal"); 1668 t = t & (MII_CTRL_SP_LSB | MII_CTRL_SP_MSB); 1669 if (t == MII_CTRL_SP_10) 1670 printf(" 10 Mb/s"); 1671 else if (t == MII_CTRL_SP_100) 1672 printf(" 100 Mb/s"); 1673 else if (t == MII_CTRL_SP_1000) 1674 printf(" 1000 Mb/s"); 1675 printf("\n"); 1676 1677 t = mdio_read(port, MII_STATUS); 1678 printf("MII_STATUS\t:"); 1679 if (t & MII_STATUS_100T4) 1680 printf(" 100Base-T4"); 1681 if (t & MII_STATUS_100XFD) 1682 printf(" 100BaseX-FD"); 1683 if (t & MII_STATUS_100XHD) 1684 printf(" 100BaseX-HD"); 1685 if (t & MII_STATUS_10FD) 1686 printf(" 10Mbps-FD"); 1687 if (t & MII_STATUS_10HD) 1688 printf(" 10Mbps-HD"); 1689 if (t & MII_STATUS_100T2FD) 1690 printf(" 100Base-T2-FD"); 1691 if (t & MII_STATUS_100T2HD) 1692 printf(" 100Base-T2-HD"); 1693 if (t & MII_STATUS_EXT_STAT) 1694 printf(" Ext-stat"); 1695 if (t & MII_STATUS_RES) 1696 printf(" res-0x%x", t & MII_STATUS_RES); 1697 if (t & MII_STATUS_MFPS) 1698 printf(" MFPS"); 1699 if (t & MII_STATUS_ANC) 1700 printf(" ANC"); 1701 if (t & MII_STATUS_RF) 1702 printf(" remote-fault"); 1703 if (t & MII_STATUS_ANA) 1704 printf(" ANA"); 1705 if (t & MII_STATUS_LS) 1706 printf(" Link"); 1707 if (t & MII_STATUS_JD) 1708 printf(" Jabber"); 1709 if (t & MII_STATUS_EC) 1710 printf(" Extended-capability"); 1711 printf("\n"); 1712 1713 t = mdio_read(port, MII_ANA); 1714 printf("MII_ANA\t\t: 0x%04x\n", t); 1715 1716 t = mdio_read(port, MII_ANLPA); 1717 printf("MII_ANLPA\t: 0x%04x\n", t); 1718 1719 t = mdio_read(port, MII_ANE); 1720 printf("MII_ANE\t\t:"); 1721 if (t & MII_ANE_RES) 1722 printf(" res-0x%x", t & MII_ANE_RES); 1723 if (t & MII_ANE_PDF) 1724 printf(" Par-Detect-Fault"); 1725 if (t & MII_ANE_LPNPA) 1726 printf(" LP-Next-Page-Able"); 1727 if (t & MII_ANE_NPA) 1728 printf(" Loc-Next-Page-Able"); 1729 if (t & MII_ANE_PR) 1730 printf(" Page-Received"); 1731 if (t & MII_ANE_LPANA) 1732 printf(" LP-Auto-Neg-Able"); 1733 printf("\n"); 1734 1735 t = mdio_read(port, MII_1000_CTRL); 1736 printf("MII_1000_CTRL\t:"); 1737 if (t & MII_1000C_FULL) 1738 printf(" 1000BaseT-FD"); 1739 if (t & MII_1000C_HALF) 1740 printf(" 1000BaseT-HD"); 1741 printf("\n"); 1742 1743 t = mdio_read(port, MII_1000_STATUS); 1744 if (t) { 1745 printf("MII_1000_STATUS\t:"); 1746 if (t & MII_1000S_LRXOK) 1747 printf(" Local-Receiver"); 1748 if (t & MII_1000S_RRXOK) 1749 printf(" Remote-Receiver"); 1750 if (t & MII_1000S_HALF) 1751 printf(" 1000BaseT-HD"); 1752 if (t & MII_1000S_FULL) 1753 printf(" 1000BaseT-FD"); 1754 printf("\n"); 1755 1756 t = mdio_read(port, MII_EXT_STATUS); 1757 printf("MII_EXT_STATUS\t:"); 1758 if (t & MII_ESTAT_1000XFD) 1759 printf(" 1000BaseX-FD"); 1760 if (t & MII_ESTAT_1000XHD) 1761 printf(" 1000BaseX-HD"); 1762 if (t & MII_ESTAT_1000TFD) 1763 printf(" 1000BaseT-FD"); 1764 if (t & MII_ESTAT_1000THD) 1765 printf(" 1000BaseT-HD"); 1766 printf("\n"); 1767 } 1768 #endif 1769 } 1770 1771 static void do_hard_int(void) 1772 { 1773 int s; 1774 1775 /* Run interrupt handler at driver level. */ 1776 rl_handler(&re_state); 1777 1778 /* Reenable interrupts for this hook. */ 1779 if ((s = sys_irqenable(&re_state.re_hook_id)) != OK) 1780 printf("RTL8169: error, couldn't enable interrupts: %d\n", s); 1781 } 1782 1783 /*===========================================================================* 1784 * rl_handler * 1785 *===========================================================================*/ 1786 static void rl_handler(re_t *rep) 1787 { 1788 int i, port, tx_head, tx_tail, link_up; 1789 u16_t isr; 1790 re_desc *desc; 1791 int_event_check = FALSE; /* disable check by default */ 1792 1793 port = rep->re_base_port; 1794 1795 /* Ack interrupt */ 1796 isr = rl_inw(port, RL_ISR); 1797 if(!isr) 1798 return; 1799 rl_outw(port, RL_ISR, isr); 1800 rep->interrupts++; 1801 1802 if (isr & RL_IMR_FOVW) { 1803 isr &= ~RL_IMR_FOVW; 1804 /* Should do anything? */ 1805 1806 rep->re_stat.ets_fifoOver++; 1807 } 1808 if (isr & RL_IMR_PUN) { 1809 isr &= ~RL_IMR_PUN; 1810 1811 /* 1812 * Either the link status changed or there was a TX fifo 1813 * underrun. 1814 */ 1815 link_up = !(!(rl_inb(port, RL_PHYSTAT) & RL_STAT_LINK)); 1816 if (link_up != rep->re_link_up) { 1817 rep->re_report_link = TRUE; 1818 rep->re_got_int = TRUE; 1819 int_event_check = TRUE; 1820 } 1821 } 1822 1823 if (isr & (RL_ISR_RDU | RL_ISR_RER | RL_ISR_ROK)) { 1824 if (isr & RL_ISR_RER) 1825 rep->re_stat.ets_recvErr++; 1826 isr &= ~(RL_ISR_RDU | RL_ISR_RER | RL_ISR_ROK); 1827 1828 if (!rep->re_got_int && (rep->re_flags & REF_READING)) { 1829 rep->re_got_int = TRUE; 1830 int_event_check = TRUE; 1831 } 1832 } 1833 1834 if ((isr & (RL_ISR_TDU | RL_ISR_TER | RL_ISR_TOK)) || 1) { 1835 if (isr & RL_ISR_TER) 1836 rep->re_stat.ets_sendErr++; 1837 isr &= ~(RL_ISR_TDU | RL_ISR_TER | RL_ISR_TOK); 1838 1839 /* Transmit completed */ 1840 tx_head = rep->re_tx_head; 1841 tx_tail = tx_head+1; 1842 if (tx_tail >= N_TX_DESC) 1843 tx_tail = 0; 1844 for (i = 0; i < 2 * N_TX_DESC; i++) { 1845 if (!rep->re_tx[tx_tail].ret_busy) { 1846 /* Strange, this buffer is not in-use. 1847 * Increment tx_tail until tx_head is 1848 * reached (or until we find a buffer that 1849 * is in-use. 1850 */ 1851 if (tx_tail == tx_head) 1852 break; 1853 if (++tx_tail >= N_TX_DESC) 1854 tx_tail = 0; 1855 assert(tx_tail < N_TX_DESC); 1856 continue; 1857 } 1858 desc = rep->re_tx_desc; 1859 desc += tx_tail; 1860 if (desc->status & DESC_OWN) { 1861 /* Buffer is not yet ready */ 1862 break; 1863 } 1864 1865 rep->re_stat.ets_packetT++; 1866 rep->re_tx[tx_tail].ret_busy = FALSE; 1867 1868 if (++tx_tail >= N_TX_DESC) 1869 tx_tail = 0; 1870 assert(tx_tail < N_TX_DESC); 1871 1872 if (rep->re_flags & REF_SEND_AVAIL) { 1873 rep->re_send_int = TRUE; 1874 if (!rep->re_got_int) { 1875 rep->re_got_int = TRUE; 1876 int_event_check = TRUE; 1877 } 1878 } 1879 } 1880 assert(i < 2 * N_TX_DESC); 1881 } 1882 1883 /* Ignore Reserved Interrupt */ 1884 if (isr & RL_ISR_RES) 1885 isr &= ~RL_ISR_RES; 1886 1887 if (isr) 1888 printf("rl_handler: unhandled interrupt isr = 0x%04x\n", isr); 1889 } 1890 1891 /*===========================================================================* 1892 * rl_watchdog_f * 1893 *===========================================================================*/ 1894 static void rl_watchdog_f(tp) 1895 minix_timer_t *tp; 1896 { 1897 re_t *rep; 1898 /* Use a synchronous alarm instead of a watchdog timer. */ 1899 sys_setalarm(system_hz, 0); 1900 1901 rep = &re_state; 1902 1903 if (rep->re_mode != REM_ENABLED) 1904 return; 1905 1906 /* Should collect statistics */ 1907 if (!(++rep->dtcc_counter % RE_DTCC_VALUE)) 1908 rtl8169_update_stat(rep); 1909 1910 if (!(rep->re_flags & REF_SEND_AVAIL)) { 1911 /* Assume that an idle system is alive */ 1912 rep->re_tx_alive = TRUE; 1913 return; 1914 } 1915 if (rep->re_tx_alive) { 1916 rep->re_tx_alive = FALSE; 1917 return; 1918 } 1919 printf("rl_watchdog_f: resetting instance %d mode 0x%x flags 0x%x\n", 1920 re_instance, rep->re_mode, rep->re_flags); 1921 printf("tx_head :%8d busy %d\t", 1922 rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy); 1923 rep->re_need_reset = TRUE; 1924 rep->re_got_int = TRUE; 1925 1926 check_int_events(); 1927 } 1928 1929