1 /* 2 * fxp.c 3 * 4 * This file contains an ethernet device driver for Intel 82557, 82558, 5 * 82559, 82550, and 82562 fast ethernet controllers. 6 * 7 * Created: Nov 2004 by Philip Homburg <philip@f-mnx.phicoh.com> 8 */ 9 10 #include <minix/drivers.h> 11 #include <minix/netdriver.h> 12 13 #include <stdlib.h> 14 #include <net/hton.h> 15 #include <net/gen/ether.h> 16 #include <net/gen/eth_io.h> 17 #include <machine/pci.h> 18 #include <minix/ds.h> 19 #include <minix/endpoint.h> 20 21 #include <minix/timers.h> 22 23 #define debug 0 24 #define RAND_UPDATE /**/ 25 #define printW() ((void)0) 26 27 #include "assert.h" 28 #include "fxp.h" 29 #include "mii.h" 30 31 /* Number of receive buffers */ 32 #define N_RX_BUF 40 33 34 /* Number of transmit buffers */ 35 #define N_TX_BUF 4 36 37 /* I/O vectors are handled IOVEC_NR entries at a time. */ 38 #define IOVEC_NR 16 39 40 /* Configuration */ 41 #define FXP_ENVVAR "FXPETH" 42 43 typedef int irq_hook_t; 44 45 /* ignore interrupt for the moment */ 46 #define interrupt(x) do { } while(0) 47 48 static union tmpbuf 49 { 50 char pad[4096]; 51 struct cbl_conf cc; 52 struct ias ias; 53 } *tmpbufp; 54 55 typedef struct fxp 56 { 57 port_t fxp_base_port; 58 int fxp_mode; 59 int fxp_got_int; 60 int fxp_send_int; 61 int fxp_flags; 62 int fxp_client; 63 int fxp_features; /* Needed? */ 64 int fxp_irq; 65 int fxp_type; /* What kind of hardware */ 66 int fxp_ms_regs; /* Master/slave registers */ 67 int fxp_ee_addrlen; /* #EEPROM address bits */ 68 int fxp_tx_alive; 69 int fxp_need_reset; 70 71 /* Rx */ 72 vir_bytes fxp_read_s; 73 int fxp_rx_nbuf; 74 int fxp_rx_bufsize; 75 struct rfd *fxp_rx_buf; 76 phys_bytes fxp_rx_busaddr; 77 int fxp_rx_head; 78 int fxp_rx_need_restart; 79 int fxp_need_conf; /* Re-configure after draining send 80 * queue 81 */ 82 83 /* Tx */ 84 int fxp_tx_nbuf; 85 int fxp_tx_bufsize; 86 struct tx *fxp_tx_buf; 87 phys_bytes fxp_tx_busaddr; 88 int fxp_tx_idle; 89 int fxp_tx_head; 90 int fxp_tx_tail; 91 int fxp_tx_threshold; 92 93 /* Link status */ 94 int fxp_report_link; 95 int fxp_link_up; 96 int fxp_mii_busy; 97 u16_t fxp_mii_scr; 98 99 /* PCI related */ 100 int fxp_seen; /* TRUE iff device available */ 101 102 /* 'large' items */ 103 irq_hook_t fxp_hook; 104 ether_addr_t fxp_address; 105 message fxp_rx_mess; 106 message fxp_tx_mess; 107 struct sc fxp_stat; 108 u8_t fxp_conf_bytes[CC_BYTES_NR]; 109 char fxp_name[sizeof("fxp#n")]; 110 iovec_t fxp_iovec[IOVEC_NR]; 111 iovec_s_t fxp_iovec_s[IOVEC_NR]; 112 } 113 fxp_t; 114 115 /* fxp_mode */ 116 #define FM_DISABLED 0x0 117 #define FM_ENABLED 0x1 118 119 /* fxp_flags */ 120 #define FF_EMPTY 0x000 121 #define FF_PACK_SENT 0x001 122 #define FF_PACK_RECV 0x002 123 #define FF_SEND_AVAIL 0x004 124 #define FF_READING 0x010 125 #define FF_PROMISC 0x040 126 #define FF_MULTI 0x080 127 #define FF_BROAD 0x100 128 #define FF_ENABLED 0x200 129 130 /* fxp_features */ 131 #define FFE_NONE 0x0 132 133 /* fxp_type */ 134 #define FT_UNKNOWN 0x0 135 #define FT_82557 0x1 136 #define FT_82558A 0x2 137 #define FT_82559 0x4 138 #define FT_82801 0x8 139 140 static int fxp_instance; 141 142 static fxp_t *fxp_state; 143 144 static minix_timer_t fxp_watchdog; 145 146 static u32_t system_hz; 147 148 #define fxp_inb(port, offset) (do_inb((port) + (offset))) 149 #define fxp_inl(port, offset) (do_inl((port) + (offset))) 150 #define fxp_outb(port, offset, value) (do_outb((port) + (offset), (value))) 151 #define fxp_outl(port, offset, value) (do_outl((port) + (offset), (value))) 152 153 static void fxp_init(message *mp); 154 static void fxp_pci_conf(void); 155 static int fxp_probe(fxp_t *fp, int skip); 156 static void fxp_conf_hw(fxp_t *fp); 157 static void fxp_init_hw(fxp_t *fp); 158 static void fxp_init_buf(fxp_t *fp); 159 static void fxp_reset_hw(fxp_t *fp); 160 static void fxp_confaddr(fxp_t *fp); 161 static void fxp_rec_mode(fxp_t *fp); 162 static void fxp_writev_s(const message *mp, int from_int); 163 static void fxp_readv_s(message *mp, int from_int); 164 static void fxp_do_conf(fxp_t *fp); 165 static void fxp_cu_ptr_cmd(fxp_t *fp, int cmd, phys_bytes bus_addr, int 166 check_idle); 167 static void fxp_ru_ptr_cmd(fxp_t *fp, int cmd, phys_bytes bus_addr, int 168 check_idle); 169 static void fxp_restart_ru(fxp_t *fp); 170 static void fxp_getstat_s(message *mp); 171 static void fxp_handler(fxp_t *fp); 172 static void fxp_check_ints(fxp_t *fp); 173 static void fxp_watchdog_f(minix_timer_t *tp); 174 static int fxp_link_changed(fxp_t *fp); 175 static void fxp_report_link(fxp_t *fp); 176 static void reply(fxp_t *fp); 177 static void mess_reply(message *req, message *reply); 178 static u16_t eeprom_read(fxp_t *fp, int reg); 179 static void eeprom_addrsize(fxp_t *fp); 180 static u16_t mii_read(fxp_t *fp, int reg); 181 static u8_t do_inb(port_t port); 182 static u32_t do_inl(port_t port); 183 static void do_outb(port_t port, u8_t v); 184 static void do_outl(port_t port, u32_t v); 185 static void tell_dev(vir_bytes start, size_t size, int pci_bus, int 186 pci_dev, int pci_func); 187 188 static void handle_hw_intr(void) 189 { 190 int r; 191 fxp_t *fp; 192 193 fp= fxp_state; 194 195 if (fp->fxp_mode != FM_ENABLED) 196 return; 197 fxp_handler(fp); 198 199 r= sys_irqenable(&fp->fxp_hook); 200 if (r != OK) { 201 panic("unable enable interrupts: %d", r); 202 } 203 204 if (!fp->fxp_got_int) 205 return; 206 fp->fxp_got_int= 0; 207 assert(fp->fxp_flags & FF_ENABLED); 208 fxp_check_ints(fp); 209 } 210 211 /* SEF functions and variables. */ 212 static void sef_local_startup(void); 213 static int sef_cb_init_fresh(int type, sef_init_info_t *info); 214 static void sef_cb_signal_handler(int signo); 215 216 /*===========================================================================* 217 * main * 218 *===========================================================================*/ 219 int main(int argc, char *argv[]) 220 { 221 message m; 222 int ipc_status; 223 int r; 224 225 /* SEF local startup. */ 226 env_setargs(argc, argv); 227 sef_local_startup(); 228 229 while (TRUE) 230 { 231 if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) 232 panic("netdriver_receive failed: %d", r); 233 234 if (is_ipc_notify(ipc_status)) { 235 switch (_ENDPOINT_P(m.m_source)) { 236 case HARDWARE: 237 handle_hw_intr(); 238 break; 239 case CLOCK: 240 expire_timers(m.m_notify.timestamp); 241 break; 242 default: 243 panic(" illegal notify from: %d", m.m_source); 244 } 245 246 /* get new message */ 247 continue; 248 } 249 250 switch (m.m_type) 251 { 252 case DL_WRITEV_S: fxp_writev_s(&m, FALSE); break; 253 case DL_READV_S: fxp_readv_s(&m, FALSE); break; 254 case DL_CONF: fxp_init(&m); break; 255 case DL_GETSTAT_S: fxp_getstat_s(&m); break; 256 default: 257 panic(" illegal message: %d", m.m_type); 258 } 259 } 260 } 261 262 /*===========================================================================* 263 * sef_local_startup * 264 *===========================================================================*/ 265 static void sef_local_startup() 266 { 267 /* Register init callbacks. */ 268 sef_setcb_init_fresh(sef_cb_init_fresh); 269 sef_setcb_init_lu(sef_cb_init_fresh); 270 sef_setcb_init_restart(sef_cb_init_fresh); 271 272 /* Register live update callbacks. */ 273 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); 274 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); 275 276 /* Register signal callbacks. */ 277 sef_setcb_signal_handler(sef_cb_signal_handler); 278 279 /* Let SEF perform startup. */ 280 sef_startup(); 281 } 282 283 /*===========================================================================* 284 * sef_cb_init_fresh * 285 *===========================================================================*/ 286 static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) 287 { 288 /* Initialize the fxp driver. */ 289 long v; 290 int r; 291 vir_bytes ft; 292 293 system_hz = sys_hz(); 294 295 v = 0; 296 (void) env_parse("instance", "d", 0, &v, 0, 255); 297 fxp_instance = (int) v; 298 299 ft = sizeof(*fxp_state); 300 301 if(!(fxp_state = alloc_contig(ft, 0, NULL))) 302 panic("couldn't allocate table: %d", ENOMEM); 303 304 memset(fxp_state, 0, ft); 305 306 if((r=tsc_calibrate()) != OK) 307 panic("tsc_calibrate failed: %d", r); 308 309 /* Announce we are up! */ 310 netdriver_announce(); 311 312 return(OK); 313 } 314 315 /*===========================================================================* 316 * sef_cb_signal_handler * 317 *===========================================================================*/ 318 static void sef_cb_signal_handler(int signo) 319 { 320 port_t port; 321 fxp_t *fp; 322 323 /* Only check for termination signal, ignore anything else. */ 324 if (signo != SIGTERM) return; 325 326 fp= fxp_state; 327 328 if (fp->fxp_mode == FM_ENABLED && (fp->fxp_flags & FF_ENABLED)) { 329 port= fp->fxp_base_port; 330 331 /* Reset device */ 332 if (debug) 333 printf("%s: resetting device\n", fp->fxp_name); 334 fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET); 335 } 336 337 exit(0); 338 } 339 340 /*===========================================================================* 341 * fxp_init * 342 *===========================================================================*/ 343 static void fxp_init(mp) 344 message *mp; 345 { 346 static int first_time= 1; 347 348 fxp_t *fp; 349 message reply_mess; 350 351 if (first_time) 352 { 353 first_time= 0; 354 fxp_pci_conf(); /* Configure PCI devices. */ 355 356 init_timer(&fxp_watchdog); 357 set_timer(&fxp_watchdog, system_hz, fxp_watchdog_f, 0); 358 } 359 360 fp= fxp_state; 361 if (fp->fxp_mode == FM_DISABLED) 362 { 363 /* This is the default, try to (re)locate the device. */ 364 fxp_conf_hw(fp); 365 if (fp->fxp_mode == FM_DISABLED) 366 { 367 /* Probe failed, or the device is configured off. */ 368 reply_mess.m_type= DL_CONF_REPLY; 369 reply_mess.m_netdrv_net_dl_conf.stat= ENXIO; 370 mess_reply(mp, &reply_mess); 371 return; 372 } 373 if (fp->fxp_mode == FM_ENABLED) 374 fxp_init_hw(fp); 375 fxp_report_link(fp); 376 } 377 378 assert(fp->fxp_mode == FM_ENABLED); 379 assert(fp->fxp_flags & FF_ENABLED); 380 381 fp->fxp_flags &= ~(FF_PROMISC | FF_MULTI | FF_BROAD); 382 383 if (mp->m_net_netdrv_dl_conf.mode & DL_PROMISC_REQ) 384 fp->fxp_flags |= FF_PROMISC; 385 if (mp->m_net_netdrv_dl_conf.mode & DL_MULTI_REQ) 386 fp->fxp_flags |= FF_MULTI; 387 if (mp->m_net_netdrv_dl_conf.mode & DL_BROAD_REQ) 388 fp->fxp_flags |= FF_BROAD; 389 390 fxp_rec_mode(fp); 391 392 reply_mess.m_type = DL_CONF_REPLY; 393 reply_mess.m_netdrv_net_dl_conf.stat = OK; 394 memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr, 395 fp->fxp_address.ea_addr, 396 sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr)); 397 398 mess_reply(mp, &reply_mess); 399 } 400 401 /*===========================================================================* 402 * fxp_pci_conf * 403 *===========================================================================*/ 404 static void fxp_pci_conf() 405 { 406 fxp_t *fp; 407 408 fp= fxp_state; 409 410 strlcpy(fp->fxp_name, "fxp#0", sizeof(fp->fxp_name)); 411 fp->fxp_name[4] += fxp_instance; 412 fp->fxp_seen= FALSE; 413 fp->fxp_features= FFE_NONE; 414 415 pci_init(); 416 417 if (fxp_probe(fp, fxp_instance)) 418 fp->fxp_seen= TRUE; 419 } 420 421 /*===========================================================================* 422 * fxp_probe * 423 *===========================================================================*/ 424 static int fxp_probe(fxp_t *fp, int skip) 425 { 426 int r, devind; 427 u16_t vid, did; 428 u32_t bar; 429 u8_t ilr, rev; 430 char *str; 431 #if VERBOSE 432 char *dname; 433 #endif 434 435 r= pci_first_dev(&devind, &vid, &did); 436 if (r == 0) 437 return FALSE; 438 439 while (skip--) 440 { 441 r= pci_next_dev(&devind, &vid, &did); 442 if (!r) 443 return FALSE; 444 } 445 446 #if VERBOSE 447 dname= pci_dev_name(vid, did); 448 if (!dname) 449 dname= "unknown device"; 450 printf("%s: %s (%04x/%04x) at %s\n", 451 fp->fxp_name, dname, vid, did, pci_slot_name(devind)); 452 #endif 453 pci_reserve(devind); 454 455 bar= pci_attr_r32(devind, PCI_BAR_2) & 0xffffffe0; 456 if (bar < 0x400) { 457 panic("fxp_probe: base address is not properly configured"); 458 } 459 fp->fxp_base_port= bar; 460 461 ilr= pci_attr_r8(devind, PCI_ILR); 462 fp->fxp_irq= ilr; 463 if (debug) 464 { 465 printf("%s: using I/O address 0x%lx, IRQ %d\n", 466 fp->fxp_name, (unsigned long)bar, ilr); 467 } 468 469 rev= pci_attr_r8(devind, PCI_REV); 470 str= NULL; 471 fp->fxp_type= FT_UNKNOWN; 472 switch(rev) 473 { 474 case FXP_REV_82557A: str= "82557A"; /* 0x01 */ 475 fp->fxp_type= FT_82557; 476 break; 477 case FXP_REV_82557B: str= "82557B"; break; /* 0x02 */ 478 case FXP_REV_82557C: str= "82557C"; break; /* 0x03 */ 479 case FXP_REV_82558A: str= "82558A"; /* 0x04 */ 480 fp->fxp_type= FT_82558A; 481 break; 482 case FXP_REV_82558B: str= "82558B"; /* 0x05 */ 483 fp->fxp_type= FT_82559; 484 break; 485 case FXP_REV_82559A: str= "82559A"; break; /* 0x06 */ 486 case FXP_REV_82559B: str= "82559B"; break; /* 0x07 */ 487 case FXP_REV_82559C: str= "82559C"; /* 0x08 */ 488 fp->fxp_type= FT_82559; 489 break; 490 case FXP_REV_82559ERA: str= "82559ER-A"; /* 0x09 */ 491 fp->fxp_type= FT_82559; 492 break; 493 case FXP_REV_82550_1: str= "82550(1)"; /* 0x0C */ 494 fp->fxp_type= FT_82559; 495 break; 496 case FXP_REV_82550_2: str= "82550(2)"; /* 0x0D */ 497 fp->fxp_type= FT_82559; 498 break; 499 case FXP_REV_82550_3: str= "82550(3)"; /* 0x0E */ 500 fp->fxp_type= FT_82559; 501 break; 502 case FXP_REV_82551_1: str= "82551(1)"; /* 0x0F */ 503 fp->fxp_type= FT_82559; 504 break; 505 case FXP_REV_82551_2: str= "82551(2)"; /* 0x10 */ 506 fp->fxp_type= FT_82559; 507 break; 508 case FXP_REV_82801CAM: str= "82801CAM"; /* 0x42 */ 509 fp->fxp_type= FT_82801; 510 break; 511 case FXP_REV_82801DB: str= "82801DB"; /* 0x81 */ 512 fp->fxp_type= FT_82801; 513 break; 514 case FXP_REV_82550_4: str= "82550(4)"; /* 0x83 */ 515 fp->fxp_type= FT_82559; 516 break; 517 } 518 519 #if VERBOSE 520 if (str) 521 printf("%s: device revision: %s\n", fp->fxp_name, str); 522 else 523 printf("%s: unknown revision: 0x%x\n", fp->fxp_name, rev); 524 #endif 525 526 if (fp->fxp_type == FT_UNKNOWN) 527 { 528 printf("fxp_probe: device is not supported by this driver\n"); 529 return FALSE; 530 } 531 532 return TRUE; 533 } 534 535 /*===========================================================================* 536 * fxp_conf_hw * 537 *===========================================================================*/ 538 static void fxp_conf_hw(fxp_t *fp) 539 { 540 #if VERBOSE 541 int i; 542 #endif 543 544 fp->fxp_mode= FM_DISABLED; /* Superfluous */ 545 546 if (!fp->fxp_seen) 547 return; 548 549 /* PCI device is present */ 550 fp->fxp_mode= FM_ENABLED; 551 552 fp->fxp_flags= FF_EMPTY; 553 fp->fxp_got_int= 0; 554 fp->fxp_send_int= 0; 555 fp->fxp_ee_addrlen= 0; /* Unknown */ 556 fp->fxp_need_reset= 0; 557 fp->fxp_report_link= 0; 558 fp->fxp_link_up= -1; /* Unknown */ 559 fp->fxp_mii_busy= 0; 560 fp->fxp_read_s= 0; 561 fp->fxp_rx_need_restart= 0; 562 fp->fxp_need_conf= 0; 563 fp->fxp_tx_head= 0; 564 fp->fxp_tx_tail= 0; 565 fp->fxp_tx_alive= 0; 566 fp->fxp_tx_threshold= TXTT_MIN; 567 568 /* Try to come up with a sensible configuration for the current 569 * device. Unfortunately every device is different, defaults are 570 * not always zero, and some fields are re-used with a completely 571 * different interpretation. We start out with a sensible default 572 * for all devices and then add device specific changes. 573 */ 574 fp->fxp_conf_bytes[0]= CC_BYTES_NR; 575 fp->fxp_conf_bytes[1]= CTL_DEFAULT | CRL_DEFAULT; 576 fp->fxp_conf_bytes[2]= CAI_DEFAULT; 577 fp->fxp_conf_bytes[3]= 0; 578 fp->fxp_conf_bytes[4]= 0; 579 fp->fxp_conf_bytes[5]= 0; 580 fp->fxp_conf_bytes[6]= CCB6_ESC | CCB6_ETCB | CCB6_RES; 581 fp->fxp_conf_bytes[7]= CUR_1; 582 fp->fxp_conf_bytes[8]= CCB8_503_MII; 583 fp->fxp_conf_bytes[9]= 0; 584 fp->fxp_conf_bytes[10]= CLB_NORMAL | CPAL_DEFAULT | CCB10_NSAI | 585 CCB10_RES1; 586 fp->fxp_conf_bytes[11]= 0; 587 fp->fxp_conf_bytes[12]= CIS_DEFAULT; 588 fp->fxp_conf_bytes[13]= CCB13_DEFAULT; 589 fp->fxp_conf_bytes[14]= CCB14_DEFAULT; 590 fp->fxp_conf_bytes[15]= CCB15_RES1 | CCB15_RES2; 591 fp->fxp_conf_bytes[16]= CCB16_DEFAULT; 592 fp->fxp_conf_bytes[17]= CCB17_DEFAULT; 593 fp->fxp_conf_bytes[18]= CCB18_RES1 | CCB18_PFCT | CCB18_PE; 594 fp->fxp_conf_bytes[19]= CCB19_FDPE; 595 fp->fxp_conf_bytes[20]= CCB20_PFCL | CCB20_RES1; 596 fp->fxp_conf_bytes[21]= CCB21_RES21; 597 598 #if VERBOSE 599 for (i= 0; i<CC_BYTES_NR; i++) 600 printf("%d: %0x, ", i, fp->fxp_conf_bytes[i]); 601 printf("\n"); 602 #endif 603 604 switch(fp->fxp_type) 605 { 606 case FT_82557: 607 break; 608 case FT_82558A: 609 case FT_82559: 610 case FT_82801: 611 fp->fxp_conf_bytes[18] |= CCB18_LROK; 612 613 if (fp->fxp_type == FT_82801) 614 { 615 fp->fxp_conf_bytes[6] = 0xba; /* ctrl 1 */ 616 fp->fxp_conf_bytes[15] = 0x48; /* promiscuous */ 617 fp->fxp_conf_bytes[21] = 0x05; /* mc_all */ 618 } 619 break; 620 default: 621 panic("fxp_conf_hw: bad device type: %d", fp->fxp_type); 622 } 623 624 /* Assume an 82555 (compatible) PHY. The should be changed for 625 * 82557 NICs with different PHYs 626 */ 627 fp->fxp_ms_regs = 0; /* No master/slave registers. */ 628 629 #if VERBOSE 630 for (i= 0; i<CC_BYTES_NR; i++) 631 printf("%d: %0x, ", i, fp->fxp_conf_bytes[i]); 632 printf("\n"); 633 #endif 634 } 635 636 /*===========================================================================* 637 * fxp_init_hw * 638 *===========================================================================*/ 639 static void fxp_init_hw(fp) 640 fxp_t *fp; 641 { 642 int i, r, isr; 643 port_t port; 644 phys_bytes bus_addr; 645 646 port= fp->fxp_base_port; 647 648 fxp_init_buf(fp); 649 650 fp->fxp_flags = FF_EMPTY; 651 fp->fxp_flags |= FF_ENABLED; 652 653 /* Set the interrupt handler and policy. Do not automatically 654 * reenable interrupts. Return the IRQ line number on interrupts. 655 */ 656 fp->fxp_hook = fp->fxp_irq; 657 r= sys_irqsetpolicy(fp->fxp_irq, 0, &fp->fxp_hook); 658 if (r != OK) 659 panic("sys_irqsetpolicy failed: %d", r); 660 661 fxp_reset_hw(fp); 662 663 r= sys_irqenable(&fp->fxp_hook); 664 if (r != OK) 665 panic("sys_irqenable failed: %d", r); 666 667 /* Reset PHY? */ 668 669 fxp_do_conf(fp); 670 671 /* Set pointer to statistical counters */ 672 r= sys_umap(SELF, VM_D, (vir_bytes)&fp->fxp_stat, sizeof(fp->fxp_stat), 673 &bus_addr); 674 if (r != OK) 675 panic("sys_umap failed: %d", r); 676 fxp_cu_ptr_cmd(fp, SC_CU_LOAD_DCA, bus_addr, TRUE /* check idle */); 677 678 /* Ack previous interrupts */ 679 isr= fxp_inb(port, SCB_INT_STAT); 680 fxp_outb(port, SCB_INT_STAT, isr); 681 682 /* Enable interrupts */ 683 fxp_outb(port, SCB_INT_MASK, 0); 684 685 fxp_ru_ptr_cmd(fp, SC_RU_START, fp->fxp_rx_busaddr, 686 TRUE /* check idle */); 687 688 fxp_confaddr(fp); 689 if (debug) 690 { 691 printf("%s: Ethernet address ", fp->fxp_name); 692 for (i= 0; i < 6; i++) 693 { 694 printf("%x%c", fp->fxp_address.ea_addr[i], 695 i < 5 ? ':' : '\n'); 696 } 697 } 698 } 699 700 /*===========================================================================* 701 * fxp_init_buf * 702 *===========================================================================*/ 703 static void fxp_init_buf(fp) 704 fxp_t *fp; 705 { 706 size_t rx_totbufsize, tx_totbufsize, tot_bufsize, alloc_bufsize; 707 char *alloc_buf; 708 phys_bytes buf, bus_addr; 709 int i, r; 710 struct rfd *rfdp; 711 struct tx *txp; 712 phys_bytes ph; 713 714 fp->fxp_rx_nbuf= N_RX_BUF; 715 rx_totbufsize= fp->fxp_rx_nbuf * sizeof(struct rfd); 716 fp->fxp_rx_bufsize= rx_totbufsize; 717 718 fp->fxp_tx_nbuf= N_TX_BUF; 719 tx_totbufsize= fp->fxp_tx_nbuf * sizeof(struct tx); 720 fp->fxp_tx_bufsize= tx_totbufsize; 721 722 tot_bufsize= sizeof(*tmpbufp) + tx_totbufsize + rx_totbufsize; 723 if (tot_bufsize % 4096) 724 tot_bufsize += 4096 - (tot_bufsize % 4096); 725 alloc_bufsize= tot_bufsize; 726 alloc_buf= alloc_contig(alloc_bufsize, AC_ALIGN4K, &ph); 727 if (alloc_buf == NULL) { 728 panic("fxp_init_buf: unable to alloc_contig size: %d", alloc_bufsize); 729 } 730 731 buf= (phys_bytes)alloc_buf; 732 733 tell_dev((vir_bytes)buf, tot_bufsize, 0, 0, 0); 734 735 tmpbufp= (union tmpbuf *)buf; 736 737 fp->fxp_rx_buf= (struct rfd *)&tmpbufp[1]; 738 r= sys_umap(SELF, VM_D, (vir_bytes)fp->fxp_rx_buf, rx_totbufsize, 739 &bus_addr); 740 if (r != OK) 741 panic("sys_umap failed: %d", r); 742 fp->fxp_rx_busaddr= bus_addr; 743 744 #if 0 745 printf("fxp_init_buf: got phys 0x%x for vir 0x%x\n", 746 fp->fxp_rx_busaddr, fp->fxp_rx_buf); 747 #endif 748 749 for (i= 0, rfdp= fp->fxp_rx_buf; i<fp->fxp_rx_nbuf; i++, rfdp++) 750 { 751 rfdp->rfd_status= 0; 752 rfdp->rfd_command= 0; 753 if (i != fp->fxp_rx_nbuf-1) 754 { 755 r= sys_umap(SELF, VM_D, (vir_bytes)&rfdp[1], 756 sizeof(rfdp[1]), &bus_addr); 757 if (r != OK) 758 panic("sys_umap failed: %d", r); 759 rfdp->rfd_linkaddr= bus_addr; 760 } 761 else 762 { 763 rfdp->rfd_linkaddr= fp->fxp_rx_busaddr; 764 rfdp->rfd_command |= RFDC_EL; 765 } 766 rfdp->rfd_reserved= 0; 767 rfdp->rfd_res= 0; 768 rfdp->rfd_size= sizeof(rfdp->rfd_buf); 769 770 } 771 fp->fxp_rx_head= 0; 772 773 fp->fxp_tx_buf= (struct tx *)((char *)fp->fxp_rx_buf+rx_totbufsize); 774 r= sys_umap(SELF, VM_D, (vir_bytes)fp->fxp_tx_buf, 775 (phys_bytes)tx_totbufsize, &fp->fxp_tx_busaddr); 776 if (r != OK) 777 panic("sys_umap failed: %d", r); 778 779 for (i= 0, txp= fp->fxp_tx_buf; i<fp->fxp_tx_nbuf; i++, txp++) 780 { 781 txp->tx_status= 0; 782 txp->tx_command= TXC_EL | CBL_NOP; /* Just in case */ 783 if (i != fp->fxp_tx_nbuf-1) 784 { 785 r= sys_umap(SELF, VM_D, (vir_bytes)&txp[1], 786 (phys_bytes)sizeof(txp[1]), &bus_addr); 787 if (r != OK) 788 panic("sys_umap failed: %d", r); 789 txp->tx_linkaddr= bus_addr; 790 } 791 else 792 { 793 txp->tx_linkaddr= fp->fxp_tx_busaddr; 794 } 795 txp->tx_tbda= TX_TBDA_NIL; 796 txp->tx_size= 0; 797 txp->tx_tthresh= fp->fxp_tx_threshold; 798 txp->tx_ntbd= 0; 799 } 800 fp->fxp_tx_idle= 1; 801 } 802 803 /*===========================================================================* 804 * fxp_reset_hw * 805 *===========================================================================*/ 806 static void fxp_reset_hw(fp) 807 fxp_t *fp; 808 { 809 /* Inline the function in init? */ 810 port_t port; 811 812 port= fp->fxp_base_port; 813 814 /* Reset device */ 815 fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET); 816 tickdelay(micros_to_ticks(CSR_PORT_RESET_DELAY)); 817 818 /* Disable interrupts */ 819 fxp_outb(port, SCB_INT_MASK, SIM_M); 820 821 /* Set CU base to zero */ 822 fxp_cu_ptr_cmd(fp, SC_CU_LOAD_BASE, 0, TRUE /* check idle */); 823 824 /* Set RU base to zero */ 825 fxp_ru_ptr_cmd(fp, SC_RU_LOAD_BASE, 0, TRUE /* check idle */); 826 } 827 828 /*===========================================================================* 829 * fxp_confaddr * 830 *===========================================================================*/ 831 static void fxp_confaddr(fxp_t *fp) 832 { 833 static char eakey[]= FXP_ENVVAR "#_EA"; 834 static char eafmt[]= "x:x:x:x:x:x"; 835 int i, r; 836 phys_bytes bus_addr; 837 long v; 838 839 /* User defined ethernet address? */ 840 eakey[sizeof(FXP_ENVVAR)-1]= '0' + fxp_instance; 841 842 for (i= 0; i < 6; i++) 843 { 844 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) 845 break; 846 fp->fxp_address.ea_addr[i]= v; 847 } 848 849 if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */ 850 851 if (i == 0) 852 { 853 /* Get ethernet address from EEPROM */ 854 for (i= 0; i<3; i++) 855 { 856 v= eeprom_read(fp, i); 857 fp->fxp_address.ea_addr[i*2]= (v & 0xff); 858 fp->fxp_address.ea_addr[i*2+1]= ((v >> 8) & 0xff); 859 } 860 } 861 862 /* Tell NIC about ethernet address */ 863 tmpbufp->ias.ias_status= 0; 864 tmpbufp->ias.ias_command= CBL_C_EL | CBL_AIS; 865 tmpbufp->ias.ias_linkaddr= 0; 866 memcpy(tmpbufp->ias.ias_ethaddr, fp->fxp_address.ea_addr, 867 sizeof(tmpbufp->ias.ias_ethaddr)); 868 r= sys_umap(SELF, VM_D, (vir_bytes)&tmpbufp->ias, 869 (phys_bytes)sizeof(tmpbufp->ias), &bus_addr); 870 if (r != OK) 871 panic("sys_umap failed: %d", r); 872 873 fxp_cu_ptr_cmd(fp, SC_CU_START, bus_addr, TRUE /* check idle */); 874 875 /* Wait for CU command to complete */ 876 SPIN_UNTIL(tmpbufp->ias.ias_status & CBL_F_C, 1000); 877 878 if (!(tmpbufp->ias.ias_status & CBL_F_C)) 879 panic("fxp_confaddr: CU command failed to complete"); 880 if (!(tmpbufp->ias.ias_status & CBL_F_OK)) 881 panic("fxp_confaddr: CU command failed"); 882 883 #if VERBOSE 884 printf("%s: hardware ethernet address: ", fp->fxp_name); 885 for (i= 0; i<6; i++) 886 { 887 printf("%02x%s", fp->fxp_address.ea_addr[i], 888 i < 5 ? ":" : ""); 889 } 890 printf("\n"); 891 #endif 892 } 893 894 /*===========================================================================* 895 * fxp_rec_mode * 896 *===========================================================================*/ 897 static void fxp_rec_mode(fp) 898 fxp_t *fp; 899 { 900 fp->fxp_conf_bytes[0]= CC_BYTES_NR; /* Just to be sure */ 901 fp->fxp_conf_bytes[15] &= ~(CCB15_BD|CCB15_PM); 902 fp->fxp_conf_bytes[21] &= ~CCB21_MA; 903 904 if (fp->fxp_flags & FF_PROMISC) 905 fp->fxp_conf_bytes[15] |= CCB15_PM; 906 if (fp->fxp_flags & FF_MULTI) 907 fp->fxp_conf_bytes[21] |= CCB21_MA; 908 909 if (!(fp->fxp_flags & (FF_BROAD|FF_MULTI|FF_PROMISC))) 910 fp->fxp_conf_bytes[15] |= CCB15_BD; 911 912 /* Queue request if not idle */ 913 if (fp->fxp_tx_idle) 914 { 915 fxp_do_conf(fp); 916 } 917 else 918 { 919 printf("fxp_rec_mode: setting fxp_need_conf\n"); 920 fp->fxp_need_conf= TRUE; 921 } 922 } 923 924 /*===========================================================================* 925 * fxp_writev_s * 926 *===========================================================================*/ 927 static void fxp_writev_s(const message *mp, int from_int) 928 { 929 endpoint_t iov_endpt; 930 cp_grant_id_t iov_grant; 931 vir_bytes iov_offset; 932 int i, j, n, o, r, s, count, size, prev_head; 933 int fxp_tx_nbuf, fxp_tx_head; 934 u16_t tx_command; 935 fxp_t *fp; 936 iovec_s_t *iovp; 937 struct tx *txp, *prev_txp; 938 939 fp= fxp_state; 940 941 count = mp->m_net_netdrv_dl_writev_s.count; 942 fp->fxp_client= mp->m_source; 943 944 assert(fp->fxp_mode == FM_ENABLED); 945 assert(fp->fxp_flags & FF_ENABLED); 946 947 if (from_int) 948 { 949 assert(fp->fxp_flags & FF_SEND_AVAIL); 950 fp->fxp_flags &= ~FF_SEND_AVAIL; 951 fp->fxp_tx_alive= TRUE; 952 } 953 954 if (fp->fxp_tx_idle) 955 { 956 txp= fp->fxp_tx_buf; 957 fxp_tx_head= 0; /* lint */ 958 prev_txp= NULL; /* lint */ 959 } 960 else 961 { 962 fxp_tx_nbuf= fp->fxp_tx_nbuf; 963 prev_head= fp->fxp_tx_head; 964 fxp_tx_head= prev_head+1; 965 if (fxp_tx_head == fxp_tx_nbuf) 966 fxp_tx_head= 0; 967 assert(fxp_tx_head < fxp_tx_nbuf); 968 969 if (fxp_tx_head == fp->fxp_tx_tail) 970 { 971 /* Send queue is full */ 972 assert(!(fp->fxp_flags & FF_SEND_AVAIL)); 973 fp->fxp_flags |= FF_SEND_AVAIL; 974 goto suspend; 975 } 976 977 prev_txp= &fp->fxp_tx_buf[prev_head]; 978 txp= &fp->fxp_tx_buf[fxp_tx_head]; 979 } 980 981 assert(!(fp->fxp_flags & FF_SEND_AVAIL)); 982 assert(!(fp->fxp_flags & FF_PACK_SENT)); 983 984 iov_endpt= mp->m_source; 985 iov_grant= mp->m_net_netdrv_dl_writev_s.grant; 986 987 size= 0; 988 o= 0; 989 iov_offset= 0; 990 for (i= 0; i<count; i += IOVEC_NR, 991 iov_offset += IOVEC_NR * sizeof(fp->fxp_iovec_s[0])) 992 { 993 n= IOVEC_NR; 994 if (i+n > count) 995 n= count-i; 996 r= sys_safecopyfrom(iov_endpt, iov_grant, iov_offset, 997 (vir_bytes)fp->fxp_iovec_s, 998 n * sizeof(fp->fxp_iovec_s[0])); 999 if (r != OK) 1000 panic("fxp_writev: sys_safecopyfrom failed: %d", r); 1001 1002 for (j= 0, iovp= fp->fxp_iovec_s; j<n; j++, iovp++) 1003 { 1004 s= iovp->iov_size; 1005 if (size + s > ETH_MAX_PACK_SIZE_TAGGED) { 1006 panic("fxp_writev: invalid packet size: %d", size + s); 1007 } 1008 1009 r= sys_safecopyfrom(iov_endpt, iovp->iov_grant, 1010 0, (vir_bytes)(txp->tx_buf+o), s); 1011 if (r != OK) { 1012 panic("fxp_writev_s: sys_safecopyfrom failed: %d", r); 1013 } 1014 size += s; 1015 o += s; 1016 } 1017 } 1018 if (size < ETH_MIN_PACK_SIZE) 1019 panic("fxp_writev: invalid packet size: %d", size); 1020 1021 txp->tx_status= 0; 1022 txp->tx_command= TXC_EL | CBL_XMIT; 1023 txp->tx_tbda= TX_TBDA_NIL; 1024 txp->tx_size= TXSZ_EOF | size; 1025 txp->tx_tthresh= fp->fxp_tx_threshold; 1026 txp->tx_ntbd= 0; 1027 if (fp->fxp_tx_idle) 1028 { 1029 fp->fxp_tx_idle= 0; 1030 fp->fxp_tx_head= fp->fxp_tx_tail= 0; 1031 1032 fxp_cu_ptr_cmd(fp, SC_CU_START, fp->fxp_tx_busaddr, 1033 TRUE /* check idle */); 1034 } 1035 else 1036 { 1037 /* Link new request in transmit list */ 1038 tx_command= prev_txp->tx_command; 1039 assert(tx_command == (TXC_EL | CBL_XMIT)); 1040 prev_txp->tx_command= CBL_XMIT; 1041 fp->fxp_tx_head= fxp_tx_head; 1042 } 1043 1044 fp->fxp_flags |= FF_PACK_SENT; 1045 1046 /* If the interrupt handler called, don't send a reply. The reply 1047 * will be sent after all interrupts are handled. 1048 */ 1049 if (from_int) 1050 return; 1051 reply(fp); 1052 return; 1053 1054 suspend: 1055 if (from_int) 1056 panic("fxp: should not be sending"); 1057 1058 fp->fxp_tx_mess= *mp; 1059 reply(fp); 1060 } 1061 1062 /*===========================================================================* 1063 * fxp_readv_s * 1064 *===========================================================================*/ 1065 static void fxp_readv_s(mp, from_int) 1066 message *mp; 1067 int from_int; 1068 { 1069 int i, j, n, o, r, s, count, size, fxp_rx_head, fxp_rx_nbuf; 1070 endpoint_t iov_endpt; 1071 cp_grant_id_t iov_grant; 1072 port_t port; 1073 unsigned packlen; 1074 vir_bytes iov_offset; 1075 u16_t rfd_status; 1076 u16_t rfd_res; 1077 u8_t scb_status; 1078 fxp_t *fp; 1079 iovec_s_t *iovp; 1080 struct rfd *rfdp, *prev_rfdp; 1081 1082 fp= fxp_state; 1083 1084 count = mp->m_net_netdrv_dl_readv_s.count; 1085 fp->fxp_client= mp->m_source; 1086 1087 assert(fp->fxp_mode == FM_ENABLED); 1088 assert(fp->fxp_flags & FF_ENABLED); 1089 1090 port= fp->fxp_base_port; 1091 1092 fxp_rx_head= fp->fxp_rx_head; 1093 rfdp= &fp->fxp_rx_buf[fxp_rx_head]; 1094 1095 rfd_status= rfdp->rfd_status; 1096 if (!(rfd_status & RFDS_C)) 1097 { 1098 /* Receive buffer is empty, suspend */ 1099 goto suspend; 1100 } 1101 1102 if (!(rfd_status & RFDS_OK)) 1103 { 1104 /* Not OK? What happened? */ 1105 assert(0); 1106 } 1107 else 1108 { 1109 assert(!(rfd_status & (RFDS_CRCERR | RFDS_ALIGNERR | 1110 RFDS_OUTOFBUF | RFDS_DMAOVR | RFDS_TOOSHORT | 1111 RFDS_RXERR))); 1112 } 1113 rfd_res= rfdp->rfd_res; 1114 assert(rfd_res & RFDR_EOF); 1115 assert(rfd_res & RFDR_F); 1116 1117 packlen= rfd_res & RFDSZ_SIZE; 1118 1119 iov_endpt = mp->m_source; 1120 iov_grant = mp->m_net_netdrv_dl_readv_s.grant; 1121 1122 size= 0; 1123 o= 0; 1124 iov_offset= 0; 1125 for (i= 0; i<count; i += IOVEC_NR, 1126 iov_offset += IOVEC_NR * sizeof(fp->fxp_iovec_s[0])) 1127 { 1128 n= IOVEC_NR; 1129 if (i+n > count) 1130 n= count-i; 1131 r= sys_safecopyfrom(iov_endpt, iov_grant, iov_offset, 1132 (vir_bytes)fp->fxp_iovec_s, 1133 n * sizeof(fp->fxp_iovec_s[0])); 1134 if (r != OK) 1135 panic("fxp_readv_s: sys_safecopyfrom failed: %d", r); 1136 1137 for (j= 0, iovp= fp->fxp_iovec_s; j<n; j++, iovp++) 1138 { 1139 s= iovp->iov_size; 1140 if (size + s > packlen) 1141 { 1142 assert(packlen > size); 1143 s= packlen-size; 1144 } 1145 1146 r= sys_safecopyto(iov_endpt, iovp->iov_grant, 1147 0, (vir_bytes)(rfdp->rfd_buf+o), s); 1148 if (r != OK) 1149 { 1150 panic("fxp_readv: sys_safecopyto failed: %d", r); 1151 } 1152 1153 size += s; 1154 if (size == packlen) 1155 break; 1156 o += s; 1157 } 1158 if (size == packlen) 1159 break; 1160 } 1161 if (size < packlen) 1162 { 1163 assert(0); 1164 } 1165 1166 fp->fxp_read_s= packlen; 1167 fp->fxp_flags= (fp->fxp_flags & ~FF_READING) | FF_PACK_RECV; 1168 1169 /* Re-init the current buffer */ 1170 rfdp->rfd_status= 0; 1171 rfdp->rfd_command= RFDC_EL; 1172 rfdp->rfd_reserved= 0; 1173 rfdp->rfd_res= 0; 1174 rfdp->rfd_size= sizeof(rfdp->rfd_buf); 1175 1176 fxp_rx_nbuf= fp->fxp_rx_nbuf; 1177 if (fxp_rx_head == 0) 1178 { 1179 prev_rfdp= &fp->fxp_rx_buf[fxp_rx_nbuf-1]; 1180 } 1181 else 1182 prev_rfdp= &rfdp[-1]; 1183 1184 assert(prev_rfdp->rfd_command & RFDC_EL); 1185 prev_rfdp->rfd_command &= ~RFDC_EL; 1186 1187 fxp_rx_head++; 1188 if (fxp_rx_head == fxp_rx_nbuf) 1189 fxp_rx_head= 0; 1190 assert(fxp_rx_head < fxp_rx_nbuf); 1191 fp->fxp_rx_head= fxp_rx_head; 1192 1193 if (!from_int) 1194 reply(fp); 1195 1196 return; 1197 1198 suspend: 1199 if (fp->fxp_rx_need_restart) 1200 { 1201 fp->fxp_rx_need_restart= 0; 1202 1203 /* Check the status of the RU */ 1204 scb_status= fxp_inb(port, SCB_STATUS); 1205 if ((scb_status & SS_RUS_MASK) != SS_RU_NORES) 1206 { 1207 /* Race condition? */ 1208 printf("fxp_readv: restart race: 0x%x\n", 1209 scb_status); 1210 assert((scb_status & SS_RUS_MASK) == SS_RU_READY); 1211 } 1212 else 1213 { 1214 fxp_restart_ru(fp); 1215 } 1216 } 1217 if (from_int) 1218 { 1219 assert(fp->fxp_flags & FF_READING); 1220 1221 /* No need to store any state */ 1222 return; 1223 } 1224 1225 fp->fxp_rx_mess= *mp; 1226 assert(!(fp->fxp_flags & FF_READING)); 1227 fp->fxp_flags |= FF_READING; 1228 1229 reply(fp); 1230 } 1231 1232 /*===========================================================================* 1233 * fxp_do_conf * 1234 *===========================================================================*/ 1235 static void fxp_do_conf(fp) 1236 fxp_t *fp; 1237 { 1238 int r; 1239 phys_bytes bus_addr; 1240 1241 /* Configure device */ 1242 tmpbufp->cc.cc_status= 0; 1243 tmpbufp->cc.cc_command= CBL_C_EL | CBL_CONF; 1244 tmpbufp->cc.cc_linkaddr= 0; 1245 memcpy(tmpbufp->cc.cc_bytes, fp->fxp_conf_bytes, 1246 sizeof(tmpbufp->cc.cc_bytes)); 1247 1248 r= sys_umap(SELF, VM_D, (vir_bytes)&tmpbufp->cc, 1249 (phys_bytes)sizeof(tmpbufp->cc), &bus_addr); 1250 if (r != OK) 1251 panic("sys_umap failed: %d", r); 1252 1253 fxp_cu_ptr_cmd(fp, SC_CU_START, bus_addr, TRUE /* check idle */); 1254 1255 /* Wait for CU command to complete */ 1256 SPIN_UNTIL(tmpbufp->cc.cc_status & CBL_F_C, 100000); 1257 1258 if (!(tmpbufp->cc.cc_status & CBL_F_C)) 1259 panic("fxp_do_conf: CU command failed to complete"); 1260 if (!(tmpbufp->cc.cc_status & CBL_F_OK)) 1261 panic("fxp_do_conf: CU command failed"); 1262 1263 } 1264 1265 /*===========================================================================* 1266 * fxp_cu_ptr_cmd * 1267 *===========================================================================*/ 1268 static void fxp_cu_ptr_cmd(fp, cmd, bus_addr, check_idle) 1269 fxp_t *fp; 1270 int cmd; 1271 phys_bytes bus_addr; 1272 int check_idle; 1273 { 1274 spin_t spin; 1275 port_t port; 1276 u8_t scb_cmd; 1277 1278 port= fp->fxp_base_port; 1279 1280 if (check_idle) 1281 { 1282 /* Consistency check. Make sure that CU is idle */ 1283 if ((fxp_inb(port, SCB_STATUS) & SS_CUS_MASK) != SS_CU_IDLE) 1284 panic("fxp_cu_ptr_cmd: CU is not idle"); 1285 } 1286 1287 fxp_outl(port, SCB_POINTER, bus_addr); 1288 fxp_outb(port, SCB_CMD, cmd); 1289 1290 /* What is a reasonable time-out? There is nothing in the 1291 * documentation. 1 ms should be enough. We use 100 ms. 1292 */ 1293 spin_init(&spin, 100000); 1294 do { 1295 /* Wait for CU command to be accepted */ 1296 scb_cmd= fxp_inb(port, SCB_CMD); 1297 if ((scb_cmd & SC_CUC_MASK) == SC_CU_NOP) 1298 break; 1299 } while (spin_check(&spin)); 1300 1301 if ((scb_cmd & SC_CUC_MASK) != SC_CU_NOP) 1302 panic("fxp_cu_ptr_cmd: CU does not accept command"); 1303 } 1304 1305 /*===========================================================================* 1306 * fxp_ru_ptr_cmd * 1307 *===========================================================================*/ 1308 static void fxp_ru_ptr_cmd(fp, cmd, bus_addr, check_idle) 1309 fxp_t *fp; 1310 int cmd; 1311 phys_bytes bus_addr; 1312 int check_idle; 1313 { 1314 spin_t spin; 1315 port_t port; 1316 u8_t scb_cmd; 1317 1318 port= fp->fxp_base_port; 1319 1320 if (check_idle) 1321 { 1322 /* Consistency check, make sure that RU is idle */ 1323 if ((fxp_inb(port, SCB_STATUS) & SS_RUS_MASK) != SS_RU_IDLE) 1324 panic("fxp_ru_ptr_cmd: RU is not idle"); 1325 } 1326 1327 fxp_outl(port, SCB_POINTER, bus_addr); 1328 fxp_outb(port, SCB_CMD, cmd); 1329 1330 spin_init(&spin, 1000); 1331 do { 1332 /* Wait for RU command to be accepted */ 1333 scb_cmd= fxp_inb(port, SCB_CMD); 1334 if ((scb_cmd & SC_RUC_MASK) == SC_RU_NOP) 1335 break; 1336 } while (spin_check(&spin)); 1337 1338 if ((scb_cmd & SC_RUC_MASK) != SC_RU_NOP) 1339 panic("fxp_ru_ptr_cmd: RU does not accept command"); 1340 } 1341 1342 /*===========================================================================* 1343 * fxp_restart_ru * 1344 *===========================================================================*/ 1345 static void fxp_restart_ru(fp) 1346 fxp_t *fp; 1347 { 1348 int i, fxp_rx_nbuf; 1349 port_t port; 1350 struct rfd *rfdp; 1351 1352 port= fp->fxp_base_port; 1353 1354 fxp_rx_nbuf= fp->fxp_rx_nbuf; 1355 for (i= 0, rfdp= fp->fxp_rx_buf; i<fxp_rx_nbuf; i++, rfdp++) 1356 { 1357 rfdp->rfd_status= 0; 1358 rfdp->rfd_command= 0; 1359 if (i == fp->fxp_rx_nbuf-1) 1360 rfdp->rfd_command= RFDC_EL; 1361 rfdp->rfd_reserved= 0; 1362 rfdp->rfd_res= 0; 1363 rfdp->rfd_size= sizeof(rfdp->rfd_buf); 1364 } 1365 fp->fxp_rx_head= 0; 1366 1367 /* Make sure that RU is in the 'No resources' state */ 1368 if ((fxp_inb(port, SCB_STATUS) & SS_RUS_MASK) != SS_RU_NORES) 1369 panic("fxp_restart_ru: RU is in an unexpected state"); 1370 1371 fxp_ru_ptr_cmd(fp, SC_RU_START, fp->fxp_rx_busaddr, 1372 FALSE /* do not check idle */); 1373 } 1374 1375 /*===========================================================================* 1376 * fxp_getstat_s * 1377 *===========================================================================*/ 1378 static void fxp_getstat_s(message *mp) 1379 { 1380 int r; 1381 fxp_t *fp; 1382 u32_t *p; 1383 eth_stat_t stats; 1384 1385 fp= fxp_state; 1386 1387 assert(fp->fxp_mode == FM_ENABLED); 1388 assert(fp->fxp_flags & FF_ENABLED); 1389 1390 p= &fp->fxp_stat.sc_tx_fcp; 1391 *p= 0; 1392 1393 /* The dump commmand doesn't take a pointer. Setting a pointer 1394 * doesn't hurt though. 1395 */ 1396 fxp_cu_ptr_cmd(fp, SC_CU_DUMP_SC, 0, FALSE /* do not check idle */); 1397 1398 /* Wait for CU command to complete */ 1399 SPIN_UNTIL(*p != 0, 1000); 1400 1401 if (*p == 0) 1402 panic("fxp_getstat: CU command failed to complete"); 1403 if (*p != SCM_DSC) 1404 panic("fxp_getstat: bad magic"); 1405 1406 stats.ets_recvErr= 1407 fp->fxp_stat.sc_rx_crc + 1408 fp->fxp_stat.sc_rx_align + 1409 fp->fxp_stat.sc_rx_resource + 1410 fp->fxp_stat.sc_rx_overrun + 1411 fp->fxp_stat.sc_rx_cd + 1412 fp->fxp_stat.sc_rx_short; 1413 stats.ets_sendErr= 1414 fp->fxp_stat.sc_tx_maxcol + 1415 fp->fxp_stat.sc_tx_latecol + 1416 fp->fxp_stat.sc_tx_crs; 1417 stats.ets_OVW= fp->fxp_stat.sc_rx_overrun; 1418 stats.ets_CRCerr= fp->fxp_stat.sc_rx_crc; 1419 stats.ets_frameAll= fp->fxp_stat.sc_rx_align; 1420 stats.ets_missedP= fp->fxp_stat.sc_rx_resource; 1421 stats.ets_packetR= fp->fxp_stat.sc_rx_good; 1422 stats.ets_packetT= fp->fxp_stat.sc_tx_good; 1423 stats.ets_transDef= fp->fxp_stat.sc_tx_defered; 1424 stats.ets_collision= fp->fxp_stat.sc_tx_totcol; 1425 stats.ets_transAb= fp->fxp_stat.sc_tx_maxcol; 1426 stats.ets_carrSense= fp->fxp_stat.sc_tx_crs; 1427 stats.ets_fifoUnder= fp->fxp_stat.sc_tx_underrun; 1428 stats.ets_fifoOver= fp->fxp_stat.sc_rx_overrun; 1429 stats.ets_CDheartbeat= 0; 1430 stats.ets_OWC= fp->fxp_stat.sc_tx_latecol; 1431 1432 r= sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant, 0, 1433 (vir_bytes)&stats, sizeof(stats)); 1434 if (r != OK) 1435 panic("fxp_getstat_s: sys_safecopyto failed: %d", r); 1436 1437 mp->m_type= DL_STAT_REPLY; 1438 r= ipc_send(mp->m_source, mp); 1439 if (r != OK) 1440 panic("fxp_getstat_s: ipc_send failed: %d", r); 1441 } 1442 1443 /*===========================================================================* 1444 * fxp_handler * 1445 *===========================================================================*/ 1446 static void fxp_handler(fxp_t *fp) 1447 { 1448 int port; 1449 u16_t isr; 1450 1451 RAND_UPDATE 1452 1453 port= fp->fxp_base_port; 1454 1455 /* Ack interrupt */ 1456 isr= fxp_inb(port, SCB_INT_STAT); 1457 fxp_outb(port, SCB_INT_STAT, isr); 1458 1459 if (isr & SIS_FR) 1460 { 1461 isr &= ~SIS_FR; 1462 1463 if (!fp->fxp_got_int && (fp->fxp_flags & FF_READING)) 1464 { 1465 fp->fxp_got_int= TRUE; 1466 interrupt(fxp_tasknr); 1467 } 1468 } 1469 if (isr & SIS_CNA) 1470 { 1471 isr &= ~SIS_CNA; 1472 if (!fp->fxp_tx_idle) 1473 { 1474 fp->fxp_send_int= TRUE; 1475 if (!fp->fxp_got_int) 1476 { 1477 fp->fxp_got_int= TRUE; 1478 interrupt(fxp_tasknr); 1479 } 1480 } 1481 } 1482 if (isr & SIS_RNR) 1483 { 1484 isr &= ~SIS_RNR; 1485 1486 /* Assume that receive buffer is full of packets. fxp_readv 1487 * will restart the RU. 1488 */ 1489 fp->fxp_rx_need_restart= 1; 1490 } 1491 if (isr) 1492 { 1493 printf("fxp_handler: unhandled interrupt: isr = 0x%02x\n", 1494 isr); 1495 } 1496 } 1497 1498 /*===========================================================================* 1499 * fxp_check_ints * 1500 *===========================================================================*/ 1501 static void fxp_check_ints(fxp_t *fp) 1502 { 1503 int n, fxp_flags, prev_tail; 1504 int fxp_tx_tail, fxp_tx_nbuf, fxp_tx_threshold; 1505 port_t port; 1506 u32_t busaddr; 1507 u16_t tx_status; 1508 u8_t scb_status; 1509 struct tx *txp; 1510 1511 fxp_flags= fp->fxp_flags; 1512 1513 if (fxp_flags & FF_READING) 1514 { 1515 if (!(fp->fxp_rx_buf[fp->fxp_rx_head].rfd_status & RFDS_C)) 1516 ; /* Nothing */ 1517 else 1518 { 1519 fxp_readv_s(&fp->fxp_rx_mess, TRUE /* from int */); 1520 } 1521 } 1522 if (fp->fxp_tx_idle) 1523 ; /* Nothing to do */ 1524 else if (fp->fxp_send_int) 1525 { 1526 fp->fxp_send_int= FALSE; 1527 fxp_tx_tail= fp->fxp_tx_tail; 1528 fxp_tx_nbuf= fp->fxp_tx_nbuf; 1529 n= 0; 1530 for (;;) 1531 { 1532 txp= &fp->fxp_tx_buf[fxp_tx_tail]; 1533 tx_status= txp->tx_status; 1534 if (!(tx_status & TXS_C)) 1535 break; 1536 1537 n++; 1538 1539 assert(tx_status & TXS_OK); 1540 if (tx_status & TXS_U) 1541 { 1542 fxp_tx_threshold= fp->fxp_tx_threshold; 1543 if (fxp_tx_threshold < TXTT_MAX) 1544 { 1545 fxp_tx_threshold++; 1546 fp->fxp_tx_threshold= fxp_tx_threshold; 1547 } 1548 printf( 1549 "fxp_check_ints: fxp_tx_threshold = 0x%x\n", 1550 fxp_tx_threshold); 1551 } 1552 1553 if (txp->tx_command & TXC_EL) 1554 { 1555 fp->fxp_tx_idle= 1; 1556 break; 1557 } 1558 1559 fxp_tx_tail++; 1560 if (fxp_tx_tail == fxp_tx_nbuf) 1561 fxp_tx_tail= 0; 1562 assert(fxp_tx_tail < fxp_tx_nbuf); 1563 } 1564 1565 if (fp->fxp_need_conf) 1566 { 1567 /* Check the status of the CU */ 1568 port= fp->fxp_base_port; 1569 scb_status= fxp_inb(port, SCB_STATUS); 1570 if ((scb_status & SS_CUS_MASK) != SS_CU_IDLE) 1571 { 1572 /* Nothing to do */ 1573 printf("scb_status = 0x%x\n", scb_status); 1574 } 1575 else 1576 { 1577 printf("fxp_check_ints: fxp_need_conf\n"); 1578 fp->fxp_need_conf= FALSE; 1579 fxp_do_conf(fp); 1580 } 1581 } 1582 1583 if (n) 1584 { 1585 if (!fp->fxp_tx_idle) 1586 { 1587 fp->fxp_tx_tail= fxp_tx_tail; 1588 1589 /* Check the status of the CU */ 1590 port= fp->fxp_base_port; 1591 scb_status= fxp_inb(port, SCB_STATUS); 1592 if ((scb_status & SS_CUS_MASK) != SS_CU_IDLE) 1593 { 1594 /* Nothing to do */ 1595 printf("scb_status = 0x%x\n", 1596 scb_status); 1597 1598 } 1599 else 1600 { 1601 if (fxp_tx_tail == 0) 1602 prev_tail= fxp_tx_nbuf-1; 1603 else 1604 prev_tail= fxp_tx_tail-1; 1605 busaddr= fp->fxp_tx_buf[prev_tail]. 1606 tx_linkaddr; 1607 1608 fxp_cu_ptr_cmd(fp, SC_CU_START, 1609 busaddr, 1 /* check idle */); 1610 } 1611 } 1612 1613 if (fp->fxp_flags & FF_SEND_AVAIL) 1614 { 1615 fxp_writev_s(&fp->fxp_tx_mess, 1616 TRUE /* from int */); 1617 } 1618 } 1619 1620 } 1621 if (fp->fxp_report_link) 1622 fxp_report_link(fp); 1623 1624 if (fp->fxp_flags & (FF_PACK_SENT | FF_PACK_RECV)) 1625 reply(fp); 1626 } 1627 1628 /*===========================================================================* 1629 * fxp_watchdog_f * 1630 *===========================================================================*/ 1631 static void fxp_watchdog_f(tp) 1632 minix_timer_t *tp; 1633 { 1634 fxp_t *fp; 1635 1636 set_timer(&fxp_watchdog, system_hz, fxp_watchdog_f, 0); 1637 1638 fp= fxp_state; 1639 if (fp->fxp_mode != FM_ENABLED) 1640 return; 1641 1642 /* Handle race condition, MII interface might be busy */ 1643 if(!fp->fxp_mii_busy) 1644 { 1645 /* Check the link status. */ 1646 if (fxp_link_changed(fp)) 1647 { 1648 #if VERBOSE 1649 printf("fxp_watchdog_f: link changed\n"); 1650 #endif 1651 fp->fxp_report_link= TRUE; 1652 fp->fxp_got_int= TRUE; 1653 interrupt(fxp_tasknr); 1654 } 1655 } 1656 1657 if (!(fp->fxp_flags & FF_SEND_AVAIL)) 1658 { 1659 /* Assume that an idle system is alive */ 1660 fp->fxp_tx_alive= TRUE; 1661 return; 1662 } 1663 if (fp->fxp_tx_alive) 1664 { 1665 fp->fxp_tx_alive= FALSE; 1666 return; 1667 } 1668 1669 fp->fxp_need_reset= TRUE; 1670 fp->fxp_got_int= TRUE; 1671 interrupt(fxp_tasknr); 1672 } 1673 1674 /*===========================================================================* 1675 * fxp_link_changed * 1676 *===========================================================================*/ 1677 static int fxp_link_changed(fp) 1678 fxp_t *fp; 1679 { 1680 u16_t scr; 1681 1682 scr= mii_read(fp, MII_SCR); 1683 scr &= ~(MII_SCR_RES|MII_SCR_RES_1); 1684 1685 return (fp->fxp_mii_scr != scr); 1686 } 1687 1688 /*===========================================================================* 1689 * fxp_report_link * 1690 *===========================================================================*/ 1691 static void fxp_report_link(fxp_t *fp) 1692 { 1693 u16_t mii_ctrl, mii_status, mii_id1, mii_id2, 1694 mii_ana, mii_anlpa, mii_ane, mii_extstat, 1695 mii_ms_ctrl, mii_ms_status, scr; 1696 u32_t oui; 1697 int model, rev; 1698 int f, link_up; 1699 1700 fp->fxp_report_link= FALSE; 1701 1702 scr= mii_read(fp, MII_SCR); 1703 scr &= ~(MII_SCR_RES|MII_SCR_RES_1); 1704 fp->fxp_mii_scr= scr; 1705 1706 mii_ctrl= mii_read(fp, MII_CTRL); 1707 mii_read(fp, MII_STATUS); /* The status reg is latched, read twice */ 1708 mii_status= mii_read(fp, MII_STATUS); 1709 mii_id1= mii_read(fp, MII_PHYID_H); 1710 mii_id2= mii_read(fp, MII_PHYID_L); 1711 mii_ana= mii_read(fp, MII_ANA); 1712 mii_anlpa= mii_read(fp, MII_ANLPA); 1713 mii_ane= mii_read(fp, MII_ANE); 1714 if (mii_status & MII_STATUS_EXT_STAT) 1715 mii_extstat= mii_read(fp, MII_EXT_STATUS); 1716 else 1717 mii_extstat= 0; 1718 if (fp->fxp_ms_regs) 1719 { 1720 mii_ms_ctrl= mii_read(fp, MII_MS_CTRL); 1721 mii_ms_status= mii_read(fp, MII_MS_STATUS); 1722 } 1723 else 1724 { 1725 mii_ms_ctrl= 0; 1726 mii_ms_status= 0; 1727 } 1728 1729 /* How do we know about the link status? */ 1730 link_up= !!(mii_status & MII_STATUS_LS); 1731 1732 fp->fxp_link_up= link_up; 1733 if (!link_up) 1734 { 1735 #if VERBOSE 1736 printf("%s: link down\n", fp->fxp_name); 1737 #endif 1738 return; 1739 } 1740 1741 oui= (mii_id1 << MII_PH_OUI_H_C_SHIFT) | 1742 ((mii_id2 & MII_PL_OUI_L_MASK) >> MII_PL_OUI_L_SHIFT); 1743 model= ((mii_id2 & MII_PL_MODEL_MASK) >> MII_PL_MODEL_SHIFT); 1744 rev= (mii_id2 & MII_PL_REV_MASK); 1745 1746 #if VERBOSE 1747 printf("OUI 0x%06lx, Model 0x%02x, Revision 0x%x\n", oui, model, rev); 1748 #endif 1749 1750 if (mii_ctrl & (MII_CTRL_LB|MII_CTRL_PD|MII_CTRL_ISO)) 1751 { 1752 printf("%s: PHY: ", fp->fxp_name); 1753 f= 1; 1754 if (mii_ctrl & MII_CTRL_LB) 1755 { 1756 printf("loopback mode"); 1757 f= 0; 1758 } 1759 if (mii_ctrl & MII_CTRL_PD) 1760 { 1761 if (!f) printf(", "); 1762 f= 0; 1763 printf("powered down"); 1764 } 1765 if (mii_ctrl & MII_CTRL_ISO) 1766 { 1767 if (!f) printf(", "); 1768 f= 0; 1769 printf("isolated"); 1770 } 1771 printf("\n"); 1772 return; 1773 } 1774 if (!(mii_ctrl & MII_CTRL_ANE)) 1775 { 1776 printf("%s: manual config: ", fp->fxp_name); 1777 switch(mii_ctrl & (MII_CTRL_SP_LSB|MII_CTRL_SP_MSB)) 1778 { 1779 case MII_CTRL_SP_10: printf("10 Mbps"); break; 1780 case MII_CTRL_SP_100: printf("100 Mbps"); break; 1781 case MII_CTRL_SP_1000: printf("1000 Mbps"); break; 1782 case MII_CTRL_SP_RES: printf("reserved speed"); break; 1783 } 1784 if (mii_ctrl & MII_CTRL_DM) 1785 printf(", full duplex"); 1786 else 1787 printf(", half duplex"); 1788 printf("\n"); 1789 return; 1790 } 1791 1792 if (!debug) goto resspeed; 1793 1794 printf("%s: ", fp->fxp_name); 1795 mii_print_stat_speed(mii_status, mii_extstat); 1796 printf("\n"); 1797 1798 if (!(mii_status & MII_STATUS_ANC)) 1799 printf("%s: auto-negotiation not complete\n", fp->fxp_name); 1800 if (mii_status & MII_STATUS_RF) 1801 printf("%s: remote fault detected\n", fp->fxp_name); 1802 if (!(mii_status & MII_STATUS_ANA)) 1803 { 1804 printf("%s: local PHY has no auto-negotiation ability\n", 1805 fp->fxp_name); 1806 } 1807 if (!(mii_status & MII_STATUS_LS)) 1808 printf("%s: link down\n", fp->fxp_name); 1809 if (mii_status & MII_STATUS_JD) 1810 printf("%s: jabber condition detected\n", fp->fxp_name); 1811 if (!(mii_status & MII_STATUS_EC)) 1812 { 1813 printf("%s: no extended register set\n", fp->fxp_name); 1814 goto resspeed; 1815 } 1816 if (!(mii_status & MII_STATUS_ANC)) 1817 goto resspeed; 1818 1819 printf("%s: local cap.: ", fp->fxp_name); 1820 if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD)) 1821 { 1822 printf("1000 Mbps: T-"); 1823 switch(mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD)) 1824 { 1825 case MII_MSC_1000T_FD: printf("FD"); break; 1826 case MII_MSC_1000T_HD: printf("HD"); break; 1827 default: printf("FD/HD"); break; 1828 } 1829 if (mii_ana) 1830 printf(", "); 1831 } 1832 mii_print_techab(mii_ana); 1833 printf("\n"); 1834 1835 if (mii_ane & MII_ANE_PDF) 1836 printf("%s: parallel detection fault\n", fp->fxp_name); 1837 if (!(mii_ane & MII_ANE_LPANA)) 1838 { 1839 printf("%s: link-partner does not support auto-negotiation\n", 1840 fp->fxp_name); 1841 goto resspeed; 1842 } 1843 1844 printf("%s: remote cap.: ", fp->fxp_name); 1845 if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD)) 1846 if (mii_ms_status & (MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD)) 1847 { 1848 printf("1000 Mbps: T-"); 1849 switch(mii_ms_status & 1850 (MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD)) 1851 { 1852 case MII_MSS_LP1000T_FD: printf("FD"); break; 1853 case MII_MSS_LP1000T_HD: printf("HD"); break; 1854 default: printf("FD/HD"); break; 1855 } 1856 if (mii_anlpa) 1857 printf(", "); 1858 } 1859 mii_print_techab(mii_anlpa); 1860 printf("\n"); 1861 1862 if (fp->fxp_ms_regs) 1863 { 1864 printf("%s: ", fp->fxp_name); 1865 if (mii_ms_ctrl & MII_MSC_MS_MANUAL) 1866 { 1867 printf("manual %s", 1868 (mii_ms_ctrl & MII_MSC_MS_VAL) ? 1869 "MASTER" : "SLAVE"); 1870 } 1871 else 1872 { 1873 printf("%s device", 1874 (mii_ms_ctrl & MII_MSC_MULTIPORT) ? 1875 "multiport" : "single-port"); 1876 } 1877 if (mii_ms_ctrl & MII_MSC_RES) 1878 printf(" reserved<0x%x>", mii_ms_ctrl & MII_MSC_RES); 1879 printf(": "); 1880 if (mii_ms_status & MII_MSS_FAULT) 1881 printf("M/S config fault"); 1882 else if (mii_ms_status & MII_MSS_MASTER) 1883 printf("MASTER"); 1884 else 1885 printf("SLAVE"); 1886 printf("\n"); 1887 } 1888 1889 if (mii_ms_status & (MII_MSS_LP1000T_FD|MII_MSS_LP1000T_HD)) 1890 { 1891 if (!(mii_ms_status & MII_MSS_LOCREC)) 1892 { 1893 printf("%s: local receiver not OK\n", 1894 fp->fxp_name); 1895 } 1896 if (!(mii_ms_status & MII_MSS_REMREC)) 1897 { 1898 printf("%s: remote receiver not OK\n", 1899 fp->fxp_name); 1900 } 1901 } 1902 if (mii_ms_status & (MII_MSS_RES|MII_MSS_IDLE_ERR)) 1903 { 1904 printf("%s", fp->fxp_name); 1905 if (mii_ms_status & MII_MSS_RES) 1906 printf(" reserved<0x%x>", mii_ms_status & MII_MSS_RES); 1907 if (mii_ms_status & MII_MSS_IDLE_ERR) 1908 { 1909 printf(" idle error %d", 1910 mii_ms_status & MII_MSS_IDLE_ERR); 1911 } 1912 printf("\n"); 1913 } 1914 1915 resspeed: 1916 #if VERBOSE 1917 printf("%s: link up, %d Mbps, %s duplex\n", 1918 fp->fxp_name, (scr & MII_SCR_100) ? 100 : 10, 1919 (scr & MII_SCR_FD) ? "full" : "half"); 1920 #endif 1921 ; 1922 } 1923 1924 /*===========================================================================* 1925 * reply * 1926 *===========================================================================*/ 1927 static void reply(fp) 1928 fxp_t *fp; 1929 { 1930 message reply; 1931 int flags; 1932 int r; 1933 1934 flags = DL_NOFLAGS; 1935 if (fp->fxp_flags & FF_PACK_SENT) 1936 flags |= DL_PACK_SEND; 1937 if (fp->fxp_flags & FF_PACK_RECV) 1938 flags |= DL_PACK_RECV; 1939 1940 reply.m_type = DL_TASK_REPLY; 1941 reply.m_netdrv_net_dl_task.flags = flags; 1942 reply.m_netdrv_net_dl_task.count = fp->fxp_read_s; 1943 1944 r= ipc_send(fp->fxp_client, &reply); 1945 1946 if (r < 0) 1947 panic("fxp: ipc_send failed: %d", r); 1948 1949 fp->fxp_read_s = 0; 1950 fp->fxp_flags &= ~(FF_PACK_SENT | FF_PACK_RECV); 1951 } 1952 1953 /*===========================================================================* 1954 * mess_reply * 1955 *===========================================================================*/ 1956 static void mess_reply(req, reply_mess) 1957 message *req; 1958 message *reply_mess; 1959 { 1960 if (ipc_send(req->m_source, reply_mess) != OK) 1961 panic("fxp: unable to mess_reply"); 1962 } 1963 1964 /*===========================================================================* 1965 * eeprom_read * 1966 *===========================================================================*/ 1967 static u16_t eeprom_read(fp, reg) 1968 fxp_t *fp; 1969 int reg; 1970 { 1971 port_t port; 1972 u16_t v; 1973 int b, i, alen; 1974 1975 alen= fp->fxp_ee_addrlen; 1976 if (!alen) 1977 { 1978 eeprom_addrsize(fp); 1979 alen= fp->fxp_ee_addrlen; 1980 assert(alen == 6 || alen == 8); 1981 } 1982 1983 port= fp->fxp_base_port; 1984 1985 fxp_outb(port, CSR_EEPROM, CE_EECS); /* Enable EEPROM */ 1986 v= EEPROM_READ_PREFIX; 1987 for (i= EEPROM_PREFIX_LEN-1; i >= 0; i--) 1988 { 1989 b= ((v & (1 << i)) ? CE_EEDI : 0); 1990 fxp_outb(port, CSR_EEPROM, CE_EECS | b); /* bit */ 1991 fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */ 1992 micro_delay(EESK_PERIOD/2+1); 1993 fxp_outb(port, CSR_EEPROM, CE_EECS | b); 1994 micro_delay(EESK_PERIOD/2+1); 1995 } 1996 1997 v= reg; 1998 for (i= alen-1; i >= 0; i--) 1999 { 2000 b= ((v & (1 << i)) ? CE_EEDI : 0); 2001 fxp_outb(port, CSR_EEPROM, CE_EECS | b); /* bit */ 2002 fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */ 2003 micro_delay(EESK_PERIOD/2+1); 2004 fxp_outb(port, CSR_EEPROM, CE_EECS | b); 2005 micro_delay(EESK_PERIOD/2+1); 2006 } 2007 2008 v= 0; 2009 for (i= 0; i<16; i++) 2010 { 2011 fxp_outb(port, CSR_EEPROM, CE_EECS | CE_EESK); /* Clock */ 2012 micro_delay(EESK_PERIOD/2+1); 2013 b= !!(fxp_inb(port, CSR_EEPROM) & CE_EEDO); 2014 v= (v << 1) | b; 2015 fxp_outb(port, CSR_EEPROM, CE_EECS ); 2016 micro_delay(EESK_PERIOD/2+1); 2017 } 2018 fxp_outb(port, CSR_EEPROM, 0); /* Disable EEPROM */ 2019 micro_delay(EECS_DELAY); 2020 2021 return v; 2022 } 2023 2024 /*===========================================================================* 2025 * eeprom_addrsize * 2026 *===========================================================================*/ 2027 static void eeprom_addrsize(fp) 2028 fxp_t *fp; 2029 { 2030 port_t port; 2031 u16_t v; 2032 int b, i; 2033 2034 port= fp->fxp_base_port; 2035 2036 /* Try to find out the size of the EEPROM */ 2037 fxp_outb(port, CSR_EEPROM, CE_EECS); /* Enable EEPROM */ 2038 v= EEPROM_READ_PREFIX; 2039 for (i= EEPROM_PREFIX_LEN-1; i >= 0; i--) 2040 { 2041 b= ((v & (1 << i)) ? CE_EEDI : 0); 2042 fxp_outb(port, CSR_EEPROM, CE_EECS | b); /* bit */ 2043 fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */ 2044 micro_delay(EESK_PERIOD/2+1); 2045 fxp_outb(port, CSR_EEPROM, CE_EECS | b); 2046 micro_delay(EESK_PERIOD/2+1); 2047 } 2048 2049 for (i= 0; i<32; i++) 2050 { 2051 b= 0; 2052 fxp_outb(port, CSR_EEPROM, CE_EECS | b); /* bit */ 2053 fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */ 2054 micro_delay(EESK_PERIOD/2+1); 2055 fxp_outb(port, CSR_EEPROM, CE_EECS | b); 2056 micro_delay(EESK_PERIOD/2+1); 2057 v= fxp_inb(port, CSR_EEPROM); 2058 if (!(v & CE_EEDO)) 2059 break; 2060 } 2061 if (i >= 32) 2062 panic("eeprom_addrsize: failed"); 2063 fp->fxp_ee_addrlen= i+1; 2064 2065 /* Discard 16 data bits */ 2066 for (i= 0; i<16; i++) 2067 { 2068 fxp_outb(port, CSR_EEPROM, CE_EECS | CE_EESK); /* Clock */ 2069 micro_delay(EESK_PERIOD/2+1); 2070 fxp_outb(port, CSR_EEPROM, CE_EECS ); 2071 micro_delay(EESK_PERIOD/2+1); 2072 } 2073 fxp_outb(port, CSR_EEPROM, 0); /* Disable EEPROM */ 2074 micro_delay(EECS_DELAY); 2075 2076 #if VERBOSE 2077 printf("%s EEPROM address length: %d\n", 2078 fp->fxp_name, fp->fxp_ee_addrlen); 2079 #endif 2080 } 2081 2082 /*===========================================================================* 2083 * mii_read * 2084 *===========================================================================*/ 2085 static u16_t mii_read(fp, reg) 2086 fxp_t *fp; 2087 int reg; 2088 { 2089 spin_t spin; 2090 port_t port; 2091 u32_t v; 2092 2093 port= fp->fxp_base_port; 2094 2095 assert(!fp->fxp_mii_busy); 2096 fp->fxp_mii_busy++; 2097 2098 if (!(fxp_inl(port, CSR_MDI_CTL) & CM_READY)) 2099 panic("mii_read: MDI not ready"); 2100 fxp_outl(port, CSR_MDI_CTL, CM_READ | (1 << CM_PHYADDR_SHIFT) | 2101 (reg << CM_REG_SHIFT)); 2102 2103 spin_init(&spin, 100000); 2104 do { 2105 v= fxp_inl(port, CSR_MDI_CTL); 2106 if (v & CM_READY) 2107 break; 2108 } while (spin_check(&spin)); 2109 2110 if (!(v & CM_READY)) 2111 panic("mii_read: MDI not ready after command"); 2112 2113 fp->fxp_mii_busy--; 2114 assert(!fp->fxp_mii_busy); 2115 2116 return v & CM_DATA_MASK; 2117 } 2118 2119 static u8_t do_inb(port_t port) 2120 { 2121 int r; 2122 u32_t value; 2123 2124 r= sys_inb(port, &value); 2125 if (r != OK) 2126 panic("sys_inb failed: %d", r); 2127 return value; 2128 } 2129 2130 static u32_t do_inl(port_t port) 2131 { 2132 int r; 2133 u32_t value; 2134 2135 r= sys_inl(port, &value); 2136 if (r != OK) 2137 panic("sys_inl failed: %d", r); 2138 return value; 2139 } 2140 2141 static void do_outb(port_t port, u8_t value) 2142 { 2143 int r; 2144 2145 r= sys_outb(port, value); 2146 if (r != OK) 2147 panic("sys_outb failed: %d", r); 2148 } 2149 2150 static void do_outl(port_t port, u32_t value) 2151 { 2152 int r; 2153 2154 r= sys_outl(port, value); 2155 if (r != OK) 2156 panic("sys_outl failed: %d", r); 2157 } 2158 2159 static void tell_dev(buf, size, pci_bus, pci_dev, pci_func) 2160 vir_bytes buf; 2161 size_t size; 2162 int pci_bus; 2163 int pci_dev; 2164 int pci_func; 2165 { 2166 int r; 2167 endpoint_t dev_e; 2168 message m; 2169 2170 r= ds_retrieve_label_endpt("amddev", &dev_e); 2171 if (r != OK) 2172 { 2173 #if 0 2174 printf( 2175 "fxp`tell_dev: ds_retrieve_label_endpt failed for 'amddev': %d\n", 2176 r); 2177 #endif 2178 return; 2179 } 2180 2181 m.m_type= IOMMU_MAP; 2182 m.m2_i1= pci_bus; 2183 m.m2_i2= pci_dev; 2184 m.m2_i3= pci_func; 2185 m.m2_l1= buf; 2186 m.m2_l2= size; 2187 2188 r= ipc_sendrec(dev_e, &m); 2189 if (r != OK) 2190 { 2191 printf("fxp`tell_dev: ipc_sendrec to %d failed: %d\n", 2192 dev_e, r); 2193 return; 2194 } 2195 if (m.m_type != OK) 2196 { 2197 printf("fxp`tell_dev: dma map request failed: %d\n", 2198 m.m_type); 2199 return; 2200 } 2201 } 2202 2203 /* 2204 * $PchId: fxp.c,v 1.4 2005/01/31 22:10:37 philip Exp $ 2205 */ 2206 2207