1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include "bge_impl.h" 28 29 /* 30 * Bit test macros, returning boolean_t values 31 */ 32 #define BIS(w, b) (((w) & (b)) ? B_TRUE : B_FALSE) 33 #define BIC(w, b) (((w) & (b)) ? B_FALSE : B_TRUE) 34 #define UPORDOWN(x) ((x) ? "up" : "down") 35 36 /* 37 * ========== Copper (PHY) support ========== 38 */ 39 40 #define BGE_DBG BGE_DBG_PHY /* debug flag for this code */ 41 42 /* 43 * #defines: 44 * BGE_COPPER_WIRESPEED controls whether the Broadcom WireSpeed(tm) 45 * feature is enabled. We need to recheck whether this can be 46 * enabled; at one time it seemed to interact unpleasantly with the 47 * loopback modes. 48 * 49 * BGE_COPPER_IDLEOFF controls whether the (copper) PHY power is 50 * turned off when the PHY is idled i.e. during driver suspend(). 51 * For now this is disabled because the chip doesn't seem to 52 * resume cleanly if the PHY power is turned off. 53 */ 54 #define BGE_COPPER_WIRESPEED B_TRUE 55 #define BGE_COPPER_IDLEOFF B_FALSE 56 57 /* 58 * The arrays below can be indexed by the MODE bits from the Auxiliary 59 * Status register to determine the current speed/duplex settings. 60 */ 61 static const int16_t bge_copper_link_speed[] = { 62 0, /* MII_AUX_STATUS_MODE_NONE */ 63 10, /* MII_AUX_STATUS_MODE_10_H */ 64 10, /* MII_AUX_STATUS_MODE_10_F */ 65 100, /* MII_AUX_STATUS_MODE_100_H */ 66 0, /* MII_AUX_STATUS_MODE_100_4 */ 67 100, /* MII_AUX_STATUS_MODE_100_F */ 68 1000, /* MII_AUX_STATUS_MODE_1000_H */ 69 1000 /* MII_AUX_STATUS_MODE_1000_F */ 70 }; 71 72 static const int8_t bge_copper_link_duplex[] = { 73 LINK_DUPLEX_UNKNOWN, /* MII_AUX_STATUS_MODE_NONE */ 74 LINK_DUPLEX_HALF, /* MII_AUX_STATUS_MODE_10_H */ 75 LINK_DUPLEX_FULL, /* MII_AUX_STATUS_MODE_10_F */ 76 LINK_DUPLEX_HALF, /* MII_AUX_STATUS_MODE_100_H */ 77 LINK_DUPLEX_UNKNOWN, /* MII_AUX_STATUS_MODE_100_4 */ 78 LINK_DUPLEX_FULL, /* MII_AUX_STATUS_MODE_100_F */ 79 LINK_DUPLEX_HALF, /* MII_AUX_STATUS_MODE_1000_H */ 80 LINK_DUPLEX_FULL /* MII_AUX_STATUS_MODE_1000_F */ 81 }; 82 83 #if BGE_DEBUGGING 84 85 static void 86 bge_phydump(bge_t *bgep, uint16_t mii_status, uint16_t aux) 87 { 88 uint16_t regs[32]; 89 int i; 90 91 ASSERT(mutex_owned(bgep->genlock)); 92 93 for (i = 0; i < 32; ++i) 94 switch (i) { 95 default: 96 regs[i] = bge_mii_get16(bgep, i); 97 break; 98 99 case MII_STATUS: 100 regs[i] = mii_status; 101 break; 102 103 case MII_AUX_STATUS: 104 regs[i] = aux; 105 break; 106 107 case 0x0b: case 0x0c: case 0x0d: case 0x0e: 108 case 0x15: case 0x16: case 0x17: 109 case 0x1c: 110 case 0x1f: 111 /* reserved registers -- don't read these */ 112 regs[i] = 0; 113 break; 114 } 115 116 for (i = 0; i < 32; i += 8) 117 BGE_DEBUG(("bge_phydump: " 118 "0x%04x %04x %04x %04x %04x %04x %04x %04x", 119 regs[i+0], regs[i+1], regs[i+2], regs[i+3], 120 regs[i+4], regs[i+5], regs[i+6], regs[i+7])); 121 } 122 123 #endif /* BGE_DEBUGGING */ 124 125 /* 126 * Basic low-level function to probe for a PHY 127 * 128 * Returns TRUE if the PHY responds with valid data, FALSE otherwise 129 */ 130 static boolean_t 131 bge_phy_probe(bge_t *bgep) 132 { 133 uint16_t miicfg; 134 uint32_t nicsig, niccfg; 135 136 BGE_TRACE(("bge_phy_probe($%p)", (void *)bgep)); 137 138 ASSERT(mutex_owned(bgep->genlock)); 139 140 nicsig = bge_nic_read32(bgep, BGE_NIC_DATA_SIG_ADDR); 141 if (nicsig == BGE_NIC_DATA_SIG) { 142 niccfg = bge_nic_read32(bgep, BGE_NIC_DATA_NIC_CFG_ADDR); 143 switch (niccfg & BGE_NIC_CFG_PHY_TYPE_MASK) { 144 default: 145 case BGE_NIC_CFG_PHY_TYPE_COPPER: 146 return (B_TRUE); 147 case BGE_NIC_CFG_PHY_TYPE_FIBER: 148 return (B_FALSE); 149 } 150 } else { 151 /* 152 * Read the MII_STATUS register twice, in 153 * order to clear any sticky bits (but they should 154 * have been cleared by the RESET, I think). 155 */ 156 miicfg = bge_mii_get16(bgep, MII_STATUS); 157 miicfg = bge_mii_get16(bgep, MII_STATUS); 158 BGE_DEBUG(("bge_phy_probe: status 0x%x", miicfg)); 159 160 /* 161 * Now check the value read; it should have at least one bit set 162 * (for the device capabilities) and at least one clear (one of 163 * the error bits). So if we see all 0s or all 1s, there's a 164 * problem. In particular, bge_mii_get16() returns all 1s if 165 * communications fails ... 166 */ 167 switch (miicfg) { 168 case 0x0000: 169 case 0xffff: 170 return (B_FALSE); 171 172 default : 173 return (B_TRUE); 174 } 175 } 176 } 177 178 /* 179 * Basic low-level function to reset the PHY. 180 * Doesn't incorporate any special-case workarounds. 181 * 182 * Returns TRUE on success, FALSE if the RESET bit doesn't clear 183 */ 184 static boolean_t 185 bge_phy_reset(bge_t *bgep) 186 { 187 uint16_t control; 188 uint_t count; 189 190 BGE_TRACE(("bge_phy_reset($%p)", (void *)bgep)); 191 192 ASSERT(mutex_owned(bgep->genlock)); 193 194 /* 195 * Set the PHY RESET bit, then wait up to 5 ms for it to self-clear 196 */ 197 bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_RESET); 198 for (count = 0; ++count < 1000; ) { 199 drv_usecwait(5); 200 control = bge_mii_get16(bgep, MII_CONTROL); 201 if (BIC(control, MII_CONTROL_RESET)) 202 return (B_TRUE); 203 } 204 205 BGE_DEBUG(("bge_phy_reset: FAILED, control now 0x%x", control)); 206 207 return (B_FALSE); 208 } 209 210 /* 211 * Basic low-level function to powerdown the PHY, if supported 212 * If powerdown support is compiled out, this function does nothing. 213 */ 214 static void 215 bge_phy_powerdown(bge_t *bgep) 216 { 217 BGE_TRACE(("bge_phy_powerdown")); 218 #if BGE_COPPER_IDLEOFF 219 bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_PWRDN); 220 #endif /* BGE_COPPER_IDLEOFF */ 221 } 222 223 /* 224 * The following functions are based on sample code provided by 225 * Broadcom (20-June-2003), and implement workarounds said to be 226 * required on the early revisions of the BCM5703/4C. 227 * 228 * The registers and values used are mostly UNDOCUMENTED, and 229 * therefore don't have symbolic names ;-( 230 * 231 * Many of the comments are straight out of the Broadcom code: 232 * even where the code has been restructured, the original 233 * comments have been preserved in order to explain what these 234 * undocumented registers & values are all about ... 235 */ 236 237 static void 238 bge_phy_macro_wait(bge_t *bgep) 239 { 240 uint_t count; 241 242 for (count = 100; --count; ) 243 if ((bge_mii_get16(bgep, 0x16) & 0x1000) == 0) 244 break; 245 } 246 247 /* 248 * PHY test data pattern: 249 * 250 * For 5703/04, each DFE TAP has 21-bits (low word 15, hi word 6) 251 * For 5705, each DFE TAP has 19-bits (low word 15, hi word 4) 252 * For simplicity, we check only 19-bits, so we don't have to 253 * distinguish which chip it is. 254 * the LO word contains 15 bits, make sure pattern data is < 0x7fff 255 * the HI word contains 6 bits, make sure pattern data is < 0x003f 256 */ 257 #define N_CHANNELS 4 258 #define N_TAPS 3 259 260 static struct { 261 uint16_t lo; 262 uint16_t hi; 263 } tap_data[N_CHANNELS][N_TAPS] = { 264 { 265 { 0x5555, 0x0005 }, /* ch0, TAP 0, LO/HI pattern */ 266 { 0x2aaa, 0x000a }, /* ch0, TAP 1, LO/HI pattern */ 267 { 0x3456, 0x0003 } /* ch0, TAP 2, LO/HI pattern */ 268 }, 269 { 270 { 0x2aaa, 0x000a }, /* ch1, TAP 0, LO/HI pattern */ 271 { 0x3333, 0x0003 }, /* ch1, TAP 1, LO/HI pattern */ 272 { 0x789a, 0x0005 } /* ch1, TAP 2, LO/HI pattern */ 273 }, 274 { 275 { 0x5a5a, 0x0005 }, /* ch2, TAP 0, LO/HI pattern */ 276 { 0x2a6a, 0x000a }, /* ch2, TAP 1, LO/HI pattern */ 277 { 0x1bcd, 0x0003 } /* ch2, TAP 2, LO/HI pattern */ 278 }, 279 { 280 { 0x2a5a, 0x000a }, /* ch3, TAP 0, LO/HI pattern */ 281 { 0x33c3, 0x0003 }, /* ch3, TAP 1, LO/HI pattern */ 282 { 0x2ef1, 0x0005 } /* ch3, TAP 2, LO/HI pattern */ 283 } 284 }; 285 286 /* 287 * Check whether the PHY has locked up after a RESET. 288 * 289 * Returns TRUE if it did, FALSE is it's OK ;-) 290 */ 291 static boolean_t 292 bge_phy_locked_up(bge_t *bgep) 293 { 294 uint16_t dataLo; 295 uint16_t dataHi; 296 uint_t chan; 297 uint_t tap; 298 299 /* 300 * Check TAPs for all 4 channels, as soon as we see a lockup 301 * we'll stop checking. 302 */ 303 for (chan = 0; chan < N_CHANNELS; ++chan) { 304 /* Select channel and set TAP index to 0 */ 305 bge_mii_put16(bgep, 0x17, (chan << 13) | 0x0200); 306 /* Freeze filter again just to be safe */ 307 bge_mii_put16(bgep, 0x16, 0x0002); 308 309 /* 310 * Write fixed pattern to the RAM, 3 TAPs for 311 * each channel, each TAP have 2 WORDs (LO/HI) 312 */ 313 for (tap = 0; tap < N_TAPS; ++tap) { 314 bge_mii_put16(bgep, 0x15, tap_data[chan][tap].lo); 315 bge_mii_put16(bgep, 0x15, tap_data[chan][tap].hi); 316 } 317 318 /* 319 * Active PHY's Macro operation to write DFE 320 * TAP from RAM, and wait for Macro to complete. 321 */ 322 bge_mii_put16(bgep, 0x16, 0x0202); 323 bge_phy_macro_wait(bgep); 324 325 /* 326 * Done with write phase, now begin read phase. 327 */ 328 329 /* Select channel and set TAP index to 0 */ 330 bge_mii_put16(bgep, 0x17, (chan << 13) | 0x0200); 331 332 /* 333 * Active PHY's Macro operation to load DFE 334 * TAP to RAM, and wait for Macro to complete 335 */ 336 bge_mii_put16(bgep, 0x16, 0x0082); 337 bge_phy_macro_wait(bgep); 338 339 /* Enable "pre-fetch" */ 340 bge_mii_put16(bgep, 0x16, 0x0802); 341 bge_phy_macro_wait(bgep); 342 343 /* 344 * Read back the TAP values. 3 TAPs for each 345 * channel, each TAP have 2 WORDs (LO/HI) 346 */ 347 for (tap = 0; tap < N_TAPS; ++tap) { 348 /* 349 * Read Lo/Hi then wait for 'done' is faster. 350 * For DFE TAP, the HI word contains 6 bits, 351 * LO word contains 15 bits 352 */ 353 dataLo = bge_mii_get16(bgep, 0x15) & 0x7fff; 354 dataHi = bge_mii_get16(bgep, 0x15) & 0x003f; 355 bge_phy_macro_wait(bgep); 356 357 /* 358 * Check if what we wrote is what we read back. 359 * If failed, then the PHY is locked up, we need 360 * to do PHY reset again 361 */ 362 if (dataLo != tap_data[chan][tap].lo) 363 return (B_TRUE); /* wedged! */ 364 365 if (dataHi != tap_data[chan][tap].hi) 366 return (B_TRUE); /* wedged! */ 367 } 368 } 369 370 /* 371 * The PHY isn't locked up ;-) 372 */ 373 return (B_FALSE); 374 } 375 376 /* 377 * Special-case code to reset the PHY on the 5702/5703/5704C/5705/5782. 378 * Tries up to 5 times to recover from failure to reset or PHY lockup. 379 * 380 * Returns TRUE on success, FALSE if there's an unrecoverable problem 381 */ 382 static boolean_t 383 bge_phy_reset_and_check(bge_t *bgep) 384 { 385 boolean_t reset_success; 386 boolean_t phy_locked; 387 uint16_t extctrl; 388 uint_t retries; 389 390 for (retries = 0; retries < 5; ++retries) { 391 /* Issue a phy reset, and wait for reset to complete */ 392 /* Assuming reset is successful first */ 393 reset_success = bge_phy_reset(bgep); 394 395 /* 396 * Now go check the DFE TAPs to see if locked up, but 397 * first, we need to set up PHY so we can read DFE 398 * TAPs. 399 */ 400 401 /* 402 * Disable Transmitter and Interrupt, while we play 403 * with the PHY registers, so the link partner won't 404 * see any strange data and the Driver won't see any 405 * interrupts. 406 */ 407 extctrl = bge_mii_get16(bgep, 0x10); 408 bge_mii_put16(bgep, 0x10, extctrl | 0x3000); 409 410 /* Setup Full-Duplex, 1000 mbps */ 411 bge_mii_put16(bgep, 0x0, 0x0140); 412 413 /* Set to Master mode */ 414 bge_mii_put16(bgep, 0x9, 0x1800); 415 416 /* Enable SM_DSP_CLOCK & 6dB */ 417 bge_mii_put16(bgep, 0x18, 0x0c00); /* "the ADC fix" */ 418 419 /* Work-arounds */ 420 bge_mii_put16(bgep, 0x17, 0x201f); 421 bge_mii_put16(bgep, 0x15, 0x2aaa); 422 423 /* More workarounds */ 424 bge_mii_put16(bgep, 0x17, 0x000a); 425 bge_mii_put16(bgep, 0x15, 0x0323); /* "the Gamma fix" */ 426 427 /* Blocks the PHY control access */ 428 bge_mii_put16(bgep, 0x17, 0x8005); 429 bge_mii_put16(bgep, 0x15, 0x0800); 430 431 /* Test whether PHY locked up ;-( */ 432 phy_locked = bge_phy_locked_up(bgep); 433 if (reset_success && !phy_locked) 434 break; 435 436 /* 437 * Some problem here ... log it & retry 438 */ 439 if (!reset_success) 440 BGE_REPORT((bgep, "PHY didn't reset!")); 441 if (phy_locked) 442 BGE_REPORT((bgep, "PHY locked up!")); 443 } 444 445 /* Remove block phy control */ 446 bge_mii_put16(bgep, 0x17, 0x8005); 447 bge_mii_put16(bgep, 0x15, 0x0000); 448 449 /* Unfreeze DFE TAP filter for all channels */ 450 bge_mii_put16(bgep, 0x17, 0x8200); 451 bge_mii_put16(bgep, 0x16, 0x0000); 452 453 /* Restore PHY back to operating state */ 454 bge_mii_put16(bgep, 0x18, 0x0400); 455 456 /* Enable transmitter and interrupt */ 457 extctrl = bge_mii_get16(bgep, 0x10); 458 bge_mii_put16(bgep, 0x10, extctrl & ~0x3000); 459 460 if (!reset_success) 461 bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE); 462 else if (phy_locked) 463 bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE); 464 return (reset_success && !phy_locked); 465 } 466 467 static void 468 bge_phy_tweak_gmii(bge_t *bgep) 469 { 470 /* Tweak GMII timing */ 471 bge_mii_put16(bgep, 0x1c, 0x8d68); 472 bge_mii_put16(bgep, 0x1c, 0x8d68); 473 } 474 475 /* Bit Error Rate reduction fix */ 476 static void 477 bge_phy_bit_err_fix(bge_t *bgep) 478 { 479 bge_mii_put16(bgep, 0x18, 0x0c00); 480 bge_mii_put16(bgep, 0x17, 0x000a); 481 bge_mii_put16(bgep, 0x15, 0x310b); 482 bge_mii_put16(bgep, 0x17, 0x201f); 483 bge_mii_put16(bgep, 0x15, 0x9506); 484 bge_mii_put16(bgep, 0x17, 0x401f); 485 bge_mii_put16(bgep, 0x15, 0x14e2); 486 bge_mii_put16(bgep, 0x18, 0x0400); 487 } 488 489 /* 490 * End of Broadcom-derived workaround code * 491 */ 492 493 static int 494 bge_restart_copper(bge_t *bgep, boolean_t powerdown) 495 { 496 uint16_t phy_status; 497 boolean_t reset_ok; 498 499 BGE_TRACE(("bge_restart_copper($%p, %d)", (void *)bgep, powerdown)); 500 501 ASSERT(mutex_owned(bgep->genlock)); 502 503 switch (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev)) { 504 default: 505 /* 506 * Shouldn't happen; it means we don't recognise this chip. 507 * It's probably a new one, so we'll try our best anyway ... 508 */ 509 case MHCR_CHIP_ASIC_REV_5703: 510 case MHCR_CHIP_ASIC_REV_5704: 511 case MHCR_CHIP_ASIC_REV_5705: 512 case MHCR_CHIP_ASIC_REV_5721_5751: 513 case MHCR_CHIP_ASIC_REV_5752: 514 case MHCR_CHIP_ASIC_REV_5714: 515 case MHCR_CHIP_ASIC_REV_5715: 516 reset_ok = bge_phy_reset_and_check(bgep); 517 break; 518 519 case MHCR_CHIP_ASIC_REV_5700: 520 case MHCR_CHIP_ASIC_REV_5701: 521 /* 522 * Just a plain reset; the "check" code breaks these chips 523 */ 524 reset_ok = bge_phy_reset(bgep); 525 if (!reset_ok) 526 bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE); 527 break; 528 } 529 if (!reset_ok) { 530 BGE_REPORT((bgep, "PHY failed to reset correctly")); 531 return (DDI_FAILURE); 532 } 533 534 /* 535 * Step 5: disable WOL (not required after RESET) 536 * 537 * Step 6: refer to errata 538 */ 539 switch (bgep->chipid.asic_rev) { 540 default: 541 break; 542 543 case MHCR_CHIP_REV_5704_A0: 544 bge_phy_tweak_gmii(bgep); 545 break; 546 } 547 548 switch (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev)) { 549 case MHCR_CHIP_ASIC_REV_5705: 550 case MHCR_CHIP_ASIC_REV_5721_5751: 551 bge_phy_bit_err_fix(bgep); 552 break; 553 } 554 555 /* 556 * Step 7: read the MII_INTR_STATUS register twice, 557 * in order to clear any sticky bits (but they should 558 * have been cleared by the RESET, I think), and we're 559 * not using PHY interrupts anyway. 560 * 561 * Step 8: enable the PHY to interrupt on link status 562 * change (not required) 563 * 564 * Step 9: configure PHY LED Mode - not applicable? 565 * 566 * Step 10: read the MII_STATUS register twice, in 567 * order to clear any sticky bits (but they should 568 * have been cleared by the RESET, I think). 569 */ 570 phy_status = bge_mii_get16(bgep, MII_STATUS); 571 phy_status = bge_mii_get16(bgep, MII_STATUS); 572 BGE_DEBUG(("bge_restart_copper: status 0x%x", phy_status)); 573 574 /* 575 * Finally, shut down the PHY, if required 576 */ 577 if (powerdown) 578 bge_phy_powerdown(bgep); 579 return (DDI_SUCCESS); 580 } 581 582 /* 583 * Synchronise the (copper) PHY's speed/duplex/autonegotiation capabilities 584 * and advertisements with the required settings as specified by the various 585 * param_* variables that can be poked via the NDD interface. 586 * 587 * We always reset the PHY and reprogram *all* the relevant registers, 588 * not just those changed. This should cause the link to go down, and then 589 * back up again once the link is stable and autonegotiation (if enabled) 590 * is complete. We should get a link state change interrupt somewhere along 591 * the way ... 592 * 593 * NOTE: <genlock> must already be held by the caller 594 */ 595 static int 596 bge_update_copper(bge_t *bgep) 597 { 598 boolean_t adv_autoneg; 599 boolean_t adv_pause; 600 boolean_t adv_asym_pause; 601 boolean_t adv_1000fdx; 602 boolean_t adv_1000hdx; 603 boolean_t adv_100fdx; 604 boolean_t adv_100hdx; 605 boolean_t adv_10fdx; 606 boolean_t adv_10hdx; 607 608 uint16_t control; 609 uint16_t gigctrl; 610 uint16_t auxctrl; 611 uint16_t anar; 612 613 BGE_TRACE(("bge_update_copper($%p)", (void *)bgep)); 614 615 ASSERT(mutex_owned(bgep->genlock)); 616 617 BGE_DEBUG(("bge_update_copper: autoneg %d " 618 "pause %d asym_pause %d " 619 "1000fdx %d 1000hdx %d " 620 "100fdx %d 100hdx %d " 621 "10fdx %d 10hdx %d ", 622 bgep->param_adv_autoneg, 623 bgep->param_adv_pause, bgep->param_adv_asym_pause, 624 bgep->param_adv_1000fdx, bgep->param_adv_1000hdx, 625 bgep->param_adv_100fdx, bgep->param_adv_100hdx, 626 bgep->param_adv_10fdx, bgep->param_adv_10hdx)); 627 628 control = gigctrl = auxctrl = anar = 0; 629 630 /* 631 * PHY settings are normally based on the param_* variables, 632 * but if any loopback mode is in effect, that takes precedence. 633 * 634 * BGE supports MAC-internal loopback, PHY-internal loopback, 635 * and External loopback at a variety of speeds (with a special 636 * cable). In all cases, autoneg is turned OFF, full-duplex 637 * is turned ON, and the speed/mastership is forced. 638 */ 639 switch (bgep->param_loop_mode) { 640 case BGE_LOOP_NONE: 641 default: 642 adv_autoneg = bgep->param_adv_autoneg; 643 adv_pause = bgep->param_adv_pause; 644 adv_asym_pause = bgep->param_adv_asym_pause; 645 adv_1000fdx = bgep->param_adv_1000fdx; 646 adv_1000hdx = bgep->param_adv_1000hdx; 647 adv_100fdx = bgep->param_adv_100fdx; 648 adv_100hdx = bgep->param_adv_100hdx; 649 adv_10fdx = bgep->param_adv_10fdx; 650 adv_10hdx = bgep->param_adv_10hdx; 651 break; 652 653 case BGE_LOOP_EXTERNAL_1000: 654 case BGE_LOOP_EXTERNAL_100: 655 case BGE_LOOP_EXTERNAL_10: 656 case BGE_LOOP_INTERNAL_PHY: 657 case BGE_LOOP_INTERNAL_MAC: 658 adv_autoneg = adv_pause = adv_asym_pause = B_FALSE; 659 adv_1000fdx = adv_100fdx = adv_10fdx = B_FALSE; 660 adv_1000hdx = adv_100hdx = adv_10hdx = B_FALSE; 661 bgep->param_link_duplex = LINK_DUPLEX_FULL; 662 663 switch (bgep->param_loop_mode) { 664 case BGE_LOOP_EXTERNAL_1000: 665 bgep->param_link_speed = 1000; 666 adv_1000fdx = B_TRUE; 667 auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK; 668 gigctrl |= MII_1000BT_CTL_MASTER_CFG; 669 gigctrl |= MII_1000BT_CTL_MASTER_SEL; 670 break; 671 672 case BGE_LOOP_EXTERNAL_100: 673 bgep->param_link_speed = 100; 674 adv_100fdx = B_TRUE; 675 auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK; 676 break; 677 678 case BGE_LOOP_EXTERNAL_10: 679 bgep->param_link_speed = 10; 680 adv_10fdx = B_TRUE; 681 auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK; 682 break; 683 684 case BGE_LOOP_INTERNAL_PHY: 685 bgep->param_link_speed = 1000; 686 adv_1000fdx = B_TRUE; 687 control = MII_CONTROL_LOOPBACK; 688 break; 689 690 case BGE_LOOP_INTERNAL_MAC: 691 bgep->param_link_speed = 1000; 692 adv_1000fdx = B_TRUE; 693 break; 694 } 695 } 696 697 BGE_DEBUG(("bge_update_copper: autoneg %d " 698 "pause %d asym_pause %d " 699 "1000fdx %d 1000hdx %d " 700 "100fdx %d 100hdx %d " 701 "10fdx %d 10hdx %d ", 702 adv_autoneg, 703 adv_pause, adv_asym_pause, 704 adv_1000fdx, adv_1000hdx, 705 adv_100fdx, adv_100hdx, 706 adv_10fdx, adv_10hdx)); 707 708 /* 709 * We should have at least one technology capability set; 710 * if not, we select a default of 1000Mb/s full-duplex 711 */ 712 if (!adv_1000fdx && !adv_100fdx && !adv_10fdx && 713 !adv_1000hdx && !adv_100hdx && !adv_10hdx) 714 adv_1000fdx = B_TRUE; 715 716 /* 717 * Now transform the adv_* variables into the proper settings 718 * of the PHY registers ... 719 * 720 * If autonegotiation is (now) enabled, we want to trigger 721 * a new autonegotiation cycle once the PHY has been 722 * programmed with the capabilities to be advertised. 723 */ 724 if (adv_autoneg) 725 control |= MII_CONTROL_ANE|MII_CONTROL_RSAN; 726 727 if (adv_1000fdx) 728 control |= MII_CONTROL_1000MB|MII_CONTROL_FDUPLEX; 729 else if (adv_1000hdx) 730 control |= MII_CONTROL_1000MB; 731 else if (adv_100fdx) 732 control |= MII_CONTROL_100MB|MII_CONTROL_FDUPLEX; 733 else if (adv_100hdx) 734 control |= MII_CONTROL_100MB; 735 else if (adv_10fdx) 736 control |= MII_CONTROL_FDUPLEX; 737 else if (adv_10hdx) 738 control |= 0; 739 else 740 { _NOTE(EMPTY); } /* Can't get here anyway ... */ 741 742 if (adv_1000fdx) 743 gigctrl |= MII_1000BT_CTL_ADV_FDX; 744 if (adv_1000hdx) 745 gigctrl |= MII_1000BT_CTL_ADV_HDX; 746 747 if (adv_100fdx) 748 anar |= MII_ABILITY_100BASE_TX_FD; 749 if (adv_100hdx) 750 anar |= MII_ABILITY_100BASE_TX; 751 if (adv_10fdx) 752 anar |= MII_ABILITY_10BASE_T_FD; 753 if (adv_10hdx) 754 anar |= MII_ABILITY_10BASE_T; 755 756 if (adv_pause) 757 anar |= MII_ABILITY_PAUSE; 758 if (adv_asym_pause) 759 anar |= MII_ABILITY_ASYM_PAUSE; 760 761 /* 762 * Munge in any other fixed bits we require ... 763 */ 764 anar |= MII_AN_SELECTOR_8023; 765 auxctrl |= MII_AUX_CTRL_NORM_TX_MODE; 766 auxctrl |= MII_AUX_CTRL_NORMAL; 767 768 /* 769 * Restart the PHY and write the new values. Note the 770 * time, so that we can say whether subsequent link state 771 * changes can be attributed to our reprogramming the PHY 772 */ 773 if ((*bgep->physops->phys_restart)(bgep, B_FALSE) == DDI_FAILURE) 774 return (DDI_FAILURE); 775 bge_mii_put16(bgep, MII_AN_ADVERT, anar); 776 bge_mii_put16(bgep, MII_CONTROL, control); 777 bge_mii_put16(bgep, MII_AUX_CONTROL, auxctrl); 778 bge_mii_put16(bgep, MII_1000BASE_T_CONTROL, gigctrl); 779 780 BGE_DEBUG(("bge_update_copper: anar <- 0x%x", anar)); 781 BGE_DEBUG(("bge_update_copper: control <- 0x%x", control)); 782 BGE_DEBUG(("bge_update_copper: auxctrl <- 0x%x", auxctrl)); 783 BGE_DEBUG(("bge_update_copper: gigctrl <- 0x%x", gigctrl)); 784 785 #if BGE_COPPER_WIRESPEED 786 /* 787 * Enable the 'wire-speed' feature, if the chip supports it 788 * and we haven't got (any) loopback mode selected. 789 */ 790 switch (bgep->chipid.device) { 791 case DEVICE_ID_5700: 792 case DEVICE_ID_5700x: 793 case DEVICE_ID_5705C: 794 case DEVICE_ID_5782: 795 /* 796 * These chips are known or assumed not to support it 797 */ 798 break; 799 800 default: 801 /* 802 * All other Broadcom chips are expected to support it. 803 */ 804 if (bgep->param_loop_mode == BGE_LOOP_NONE) 805 bge_mii_put16(bgep, MII_AUX_CONTROL, 806 MII_AUX_CTRL_MISC_WRITE_ENABLE | 807 MII_AUX_CTRL_MISC_WIRE_SPEED | 808 MII_AUX_CTRL_MISC); 809 break; 810 } 811 #endif /* BGE_COPPER_WIRESPEED */ 812 return (DDI_SUCCESS); 813 } 814 815 static boolean_t 816 bge_check_copper(bge_t *bgep, boolean_t recheck) 817 { 818 uint32_t emac_status; 819 uint16_t mii_status; 820 uint16_t aux; 821 uint_t mode; 822 boolean_t linkup; 823 824 /* 825 * Step 10: read the status from the PHY (which is self-clearing 826 * on read!); also read & clear the main (Ethernet) MAC status 827 * (the relevant bits of this are write-one-to-clear). 828 */ 829 mii_status = bge_mii_get16(bgep, MII_STATUS); 830 emac_status = bge_reg_get32(bgep, ETHERNET_MAC_STATUS_REG); 831 bge_reg_put32(bgep, ETHERNET_MAC_STATUS_REG, emac_status); 832 833 BGE_DEBUG(("bge_check_copper: link %d/%s, MII status 0x%x " 834 "(was 0x%x), Ethernet MAC status 0x%x", 835 bgep->link_state, UPORDOWN(bgep->param_link_up), mii_status, 836 bgep->phy_gen_status, emac_status)); 837 838 /* 839 * If the PHY status hasn't changed since last we looked, and 840 * we not forcing a recheck (i.e. the link state was already 841 * known), there's nothing to do. 842 */ 843 if (mii_status == bgep->phy_gen_status && !recheck) 844 return (B_FALSE); 845 846 do { 847 /* 848 * Step 11: read AUX STATUS register to find speed/duplex 849 */ 850 aux = bge_mii_get16(bgep, MII_AUX_STATUS); 851 BGE_CDB(bge_phydump, (bgep, mii_status, aux)); 852 853 /* 854 * We will only consider the link UP if all the readings 855 * are consistent and give meaningful results ... 856 */ 857 mode = aux & MII_AUX_STATUS_MODE_MASK; 858 mode >>= MII_AUX_STATUS_MODE_SHIFT; 859 linkup = bge_copper_link_speed[mode] > 0; 860 linkup &= bge_copper_link_duplex[mode] != LINK_DUPLEX_UNKNOWN; 861 linkup &= BIS(aux, MII_AUX_STATUS_LINKUP); 862 linkup &= BIS(mii_status, MII_STATUS_LINKUP); 863 864 BGE_DEBUG(("bge_check_copper: MII status 0x%x aux 0x%x " 865 "=> mode %d (%s)", 866 mii_status, aux, 867 mode, UPORDOWN(linkup))); 868 869 /* 870 * Record current register values, then reread status 871 * register & loop until it stabilises ... 872 */ 873 bgep->phy_aux_status = aux; 874 bgep->phy_gen_status = mii_status; 875 mii_status = bge_mii_get16(bgep, MII_STATUS); 876 } while (mii_status != bgep->phy_gen_status); 877 878 /* 879 * Assume very little ... 880 */ 881 bgep->param_lp_autoneg = B_FALSE; 882 bgep->param_lp_1000fdx = B_FALSE; 883 bgep->param_lp_1000hdx = B_FALSE; 884 bgep->param_lp_100fdx = B_FALSE; 885 bgep->param_lp_100hdx = B_FALSE; 886 bgep->param_lp_10fdx = B_FALSE; 887 bgep->param_lp_10hdx = B_FALSE; 888 bgep->param_lp_pause = B_FALSE; 889 bgep->param_lp_asym_pause = B_FALSE; 890 bgep->param_link_autoneg = B_FALSE; 891 bgep->param_link_tx_pause = B_FALSE; 892 if (bgep->param_adv_autoneg) 893 bgep->param_link_rx_pause = B_FALSE; 894 else 895 bgep->param_link_rx_pause = bgep->param_adv_pause; 896 897 /* 898 * Discover all the link partner's abilities. 899 * These are scattered through various registers ... 900 */ 901 if (BIS(aux, MII_AUX_STATUS_LP_ANEG_ABLE)) { 902 bgep->param_lp_autoneg = B_TRUE; 903 bgep->param_link_autoneg = B_TRUE; 904 bgep->param_link_tx_pause = BIS(aux, MII_AUX_STATUS_TX_PAUSE); 905 bgep->param_link_rx_pause = BIS(aux, MII_AUX_STATUS_RX_PAUSE); 906 907 aux = bge_mii_get16(bgep, MII_1000BASE_T_STATUS); 908 bgep->param_lp_1000fdx = BIS(aux, MII_1000BT_STAT_LP_FDX_CAP); 909 bgep->param_lp_1000hdx = BIS(aux, MII_1000BT_STAT_LP_HDX_CAP); 910 911 aux = bge_mii_get16(bgep, MII_AN_LPABLE); 912 bgep->param_lp_100fdx = BIS(aux, MII_ABILITY_100BASE_TX_FD); 913 bgep->param_lp_100hdx = BIS(aux, MII_ABILITY_100BASE_TX); 914 bgep->param_lp_10fdx = BIS(aux, MII_ABILITY_10BASE_T_FD); 915 bgep->param_lp_10hdx = BIS(aux, MII_ABILITY_10BASE_T); 916 bgep->param_lp_pause = BIS(aux, MII_ABILITY_PAUSE); 917 bgep->param_lp_asym_pause = BIS(aux, MII_ABILITY_ASYM_PAUSE); 918 } 919 920 /* 921 * Step 12: update ndd-visible state parameters, BUT! 922 * we don't transfer the new state to <link_state> just yet; 923 * instead we mark the <link_state> as UNKNOWN, and our caller 924 * will resolve it once the status has stopped changing and 925 * been stable for several seconds. 926 */ 927 BGE_DEBUG(("bge_check_copper: link was %s speed %d duplex %d", 928 UPORDOWN(bgep->param_link_up), 929 bgep->param_link_speed, 930 bgep->param_link_duplex)); 931 932 if (!linkup) 933 mode = MII_AUX_STATUS_MODE_NONE; 934 bgep->param_link_up = linkup; 935 bgep->param_link_speed = bge_copper_link_speed[mode]; 936 bgep->param_link_duplex = bge_copper_link_duplex[mode]; 937 bgep->link_state = LINK_STATE_UNKNOWN; 938 939 BGE_DEBUG(("bge_check_copper: link now %s speed %d duplex %d", 940 UPORDOWN(bgep->param_link_up), 941 bgep->param_link_speed, 942 bgep->param_link_duplex)); 943 944 return (B_TRUE); 945 } 946 947 static const phys_ops_t copper_ops = { 948 bge_restart_copper, 949 bge_update_copper, 950 bge_check_copper 951 }; 952 953 954 /* 955 * ========== SerDes support ========== 956 */ 957 958 #undef BGE_DBG 959 #define BGE_DBG BGE_DBG_SERDES /* debug flag for this code */ 960 961 /* 962 * Reinitialise the SerDes interface. Note that it normally powers 963 * up in the disabled state, so we need to explicitly activate it. 964 */ 965 static int 966 bge_restart_serdes(bge_t *bgep, boolean_t powerdown) 967 { 968 uint32_t macmode; 969 970 BGE_TRACE(("bge_restart_serdes($%p, %d)", (void *)bgep, powerdown)); 971 972 ASSERT(mutex_owned(bgep->genlock)); 973 974 /* 975 * Ensure that the main Ethernet MAC mode register is programmed 976 * appropriately for the SerDes interface ... 977 */ 978 macmode = bge_reg_get32(bgep, ETHERNET_MAC_MODE_REG); 979 if (DEVICE_5714_SERIES_CHIPSETS(bgep)) { 980 macmode |= ETHERNET_MODE_LINK_POLARITY; 981 macmode &= ~ETHERNET_MODE_PORTMODE_MASK; 982 macmode |= ETHERNET_MODE_PORTMODE_GMII; 983 } else { 984 macmode &= ~ETHERNET_MODE_LINK_POLARITY; 985 macmode &= ~ETHERNET_MODE_PORTMODE_MASK; 986 macmode |= ETHERNET_MODE_PORTMODE_TBI; 987 } 988 bge_reg_put32(bgep, ETHERNET_MAC_MODE_REG, macmode); 989 990 /* 991 * Ensure that loopback is OFF and comma detection is enabled. Then 992 * disable the SerDes output (the first time through, it may/will 993 * already be disabled). If we're shutting down, leave it disabled. 994 */ 995 bge_reg_clr32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TBI_LOOPBACK); 996 bge_reg_set32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_COMMA_DETECT); 997 bge_reg_set32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TX_DISABLE); 998 if (powerdown) 999 return (DDI_SUCCESS); 1000 1001 /* 1002 * Otherwise, pause, (re-)enable the SerDes output, and send 1003 * all-zero config words in order to force autoneg restart. 1004 * Invalidate the saved "link partners received configs", as 1005 * we're starting over ... 1006 */ 1007 drv_usecwait(10000); 1008 bge_reg_clr32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TX_DISABLE); 1009 bge_reg_put32(bgep, TX_1000BASEX_AUTONEG_REG, 0); 1010 bge_reg_set32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS); 1011 drv_usecwait(10); 1012 bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS); 1013 bgep->serdes_lpadv = AUTONEG_CODE_FAULT_ANEG_ERR; 1014 bgep->serdes_status = ~0U; 1015 return (DDI_SUCCESS); 1016 } 1017 1018 /* 1019 * Synchronise the SerDes speed/duplex/autonegotiation capabilities and 1020 * advertisements with the required settings as specified by the various 1021 * param_* variables that can be poked via the NDD interface. 1022 * 1023 * We always reinitalise the SerDes; this should cause the link to go down, 1024 * and then back up again once the link is stable and autonegotiation 1025 * (if enabled) is complete. We should get a link state change interrupt 1026 * somewhere along the way ... 1027 * 1028 * NOTE: SerDes only supports 1000FDX/HDX (with or without pause) so the 1029 * param_* variables relating to lower speeds are ignored. 1030 * 1031 * NOTE: <genlock> must already be held by the caller 1032 */ 1033 static int 1034 bge_update_serdes(bge_t *bgep) 1035 { 1036 boolean_t adv_autoneg; 1037 boolean_t adv_pause; 1038 boolean_t adv_asym_pause; 1039 boolean_t adv_1000fdx; 1040 boolean_t adv_1000hdx; 1041 1042 uint32_t serdes; 1043 uint32_t advert; 1044 1045 BGE_TRACE(("bge_update_serdes($%p)", (void *)bgep)); 1046 1047 ASSERT(mutex_owned(bgep->genlock)); 1048 1049 BGE_DEBUG(("bge_update_serdes: autoneg %d " 1050 "pause %d asym_pause %d " 1051 "1000fdx %d 1000hdx %d " 1052 "100fdx %d 100hdx %d " 1053 "10fdx %d 10hdx %d ", 1054 bgep->param_adv_autoneg, 1055 bgep->param_adv_pause, bgep->param_adv_asym_pause, 1056 bgep->param_adv_1000fdx, bgep->param_adv_1000hdx, 1057 bgep->param_adv_100fdx, bgep->param_adv_100hdx, 1058 bgep->param_adv_10fdx, bgep->param_adv_10hdx)); 1059 1060 serdes = advert = 0; 1061 1062 /* 1063 * SerDes settings are normally based on the param_* variables, 1064 * but if any loopback mode is in effect, that takes precedence. 1065 * 1066 * BGE supports MAC-internal loopback, PHY-internal loopback, 1067 * and External loopback at a variety of speeds (with a special 1068 * cable). In all cases, autoneg is turned OFF, full-duplex 1069 * is turned ON, and the speed/mastership is forced. 1070 * 1071 * Note: for the SerDes interface, "PHY" internal loopback is 1072 * interpreted as SerDes internal loopback, and all external 1073 * loopback modes are treated equivalently, as 1Gb/external. 1074 */ 1075 switch (bgep->param_loop_mode) { 1076 case BGE_LOOP_NONE: 1077 default: 1078 adv_autoneg = bgep->param_adv_autoneg; 1079 adv_pause = bgep->param_adv_pause; 1080 adv_asym_pause = bgep->param_adv_asym_pause; 1081 adv_1000fdx = bgep->param_adv_1000fdx; 1082 adv_1000hdx = bgep->param_adv_1000hdx; 1083 break; 1084 1085 case BGE_LOOP_INTERNAL_PHY: 1086 serdes |= SERDES_CONTROL_TBI_LOOPBACK; 1087 /* FALLTHRU */ 1088 case BGE_LOOP_INTERNAL_MAC: 1089 case BGE_LOOP_EXTERNAL_1000: 1090 case BGE_LOOP_EXTERNAL_100: 1091 case BGE_LOOP_EXTERNAL_10: 1092 adv_autoneg = adv_pause = adv_asym_pause = B_FALSE; 1093 adv_1000fdx = B_TRUE; 1094 adv_1000hdx = B_FALSE; 1095 break; 1096 } 1097 1098 BGE_DEBUG(("bge_update_serdes: autoneg %d " 1099 "pause %d asym_pause %d " 1100 "1000fdx %d 1000hdx %d ", 1101 adv_autoneg, 1102 adv_pause, adv_asym_pause, 1103 adv_1000fdx, adv_1000hdx)); 1104 1105 /* 1106 * We should have at least one gigabit technology capability 1107 * set; if not, we select a default of 1000Mb/s full-duplex 1108 */ 1109 if (!adv_1000fdx && !adv_1000hdx) 1110 adv_1000fdx = B_TRUE; 1111 1112 /* 1113 * Now transform the adv_* variables into the proper settings 1114 * of the SerDes registers ... 1115 * 1116 * If autonegotiation is (now) not enabled, pretend it's been 1117 * done and failed ... 1118 */ 1119 if (!adv_autoneg) 1120 advert |= AUTONEG_CODE_FAULT_ANEG_ERR; 1121 1122 if (adv_1000fdx) { 1123 advert |= AUTONEG_CODE_FULL_DUPLEX; 1124 bgep->param_adv_1000fdx = adv_1000fdx; 1125 bgep->param_link_duplex = LINK_DUPLEX_FULL; 1126 bgep->param_link_speed = 1000; 1127 } 1128 if (adv_1000hdx) { 1129 advert |= AUTONEG_CODE_HALF_DUPLEX; 1130 bgep->param_adv_1000hdx = adv_1000hdx; 1131 bgep->param_link_duplex = LINK_DUPLEX_HALF; 1132 bgep->param_link_speed = 1000; 1133 } 1134 1135 if (adv_pause) 1136 advert |= AUTONEG_CODE_PAUSE; 1137 if (adv_asym_pause) 1138 advert |= AUTONEG_CODE_ASYM_PAUSE; 1139 1140 /* 1141 * Restart the SerDes and write the new values. Note the 1142 * time, so that we can say whether subsequent link state 1143 * changes can be attributed to our reprogramming the SerDes 1144 */ 1145 bgep->serdes_advert = advert; 1146 (void) bge_restart_serdes(bgep, B_FALSE); 1147 bge_reg_set32(bgep, SERDES_CONTROL_REG, serdes); 1148 1149 BGE_DEBUG(("bge_update_serdes: serdes |= 0x%x, advert 0x%x", 1150 serdes, advert)); 1151 return (DDI_SUCCESS); 1152 } 1153 1154 /* 1155 * Bare-minimum autoneg protocol 1156 * 1157 * This code is only called when the link is up and we're receiving config 1158 * words, which implies that the link partner wants to autonegotiate 1159 * (otherwise, we wouldn't see configs and wouldn't reach this code). 1160 */ 1161 static void 1162 bge_autoneg_serdes(bge_t *bgep) 1163 { 1164 boolean_t ack; 1165 1166 bgep->serdes_lpadv = bge_reg_get32(bgep, RX_1000BASEX_AUTONEG_REG); 1167 ack = BIS(bgep->serdes_lpadv, AUTONEG_CODE_ACKNOWLEDGE); 1168 1169 if (!ack) { 1170 /* 1171 * Phase 1: after SerDes reset, we send a few zero configs 1172 * but then stop. Here the partner is sending configs, but 1173 * not ACKing ours; we assume that's 'cos we're not sending 1174 * any. So here we send ours, with ACK already set. 1175 */ 1176 bge_reg_put32(bgep, TX_1000BASEX_AUTONEG_REG, 1177 bgep->serdes_advert | AUTONEG_CODE_ACKNOWLEDGE); 1178 bge_reg_set32(bgep, ETHERNET_MAC_MODE_REG, 1179 ETHERNET_MODE_SEND_CFGS); 1180 } else { 1181 /* 1182 * Phase 2: partner has ACKed our configs, so now we can 1183 * stop sending; once our partner also stops sending, we 1184 * can resolve the Tx/Rx configs. 1185 */ 1186 bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG, 1187 ETHERNET_MODE_SEND_CFGS); 1188 } 1189 1190 BGE_DEBUG(("bge_autoneg_serdes: Rx 0x%x %s Tx 0x%x", 1191 bgep->serdes_lpadv, 1192 ack ? "stop" : "send", 1193 bgep->serdes_advert)); 1194 } 1195 1196 static boolean_t 1197 bge_check_serdes(bge_t *bgep, boolean_t recheck) 1198 { 1199 uint32_t emac_status; 1200 uint32_t lpadv; 1201 boolean_t linkup; 1202 boolean_t linkup_old = bgep->param_link_up; 1203 1204 for (;;) { 1205 /* 1206 * Step 10: BCM5714S, BCM5715S only 1207 * Don't call function bge_autoneg_serdes() as 1208 * RX_1000BASEX_AUTONEG_REG (0x0448) is not applicable 1209 * to BCM5705, BCM5788, BCM5721, BCM5751, BCM5752, 1210 * BCM5714, and BCM5715 devices. 1211 */ 1212 if (DEVICE_5714_SERIES_CHIPSETS(bgep)) { 1213 emac_status = bge_reg_get32(bgep, MI_STATUS_REG); 1214 linkup = BIS(emac_status, MI_STATUS_LINK); 1215 bgep->serdes_status = emac_status; 1216 if ((linkup && linkup_old) || 1217 (!linkup && !linkup_old)) { 1218 emac_status &= ~ETHERNET_STATUS_LINK_CHANGED; 1219 emac_status &= ~ETHERNET_STATUS_RECEIVING_CFG; 1220 break; 1221 } 1222 emac_status |= ETHERNET_STATUS_LINK_CHANGED; 1223 emac_status |= ETHERNET_STATUS_RECEIVING_CFG; 1224 if (linkup) 1225 linkup_old = B_TRUE; 1226 else 1227 linkup_old = B_FALSE; 1228 recheck = B_TRUE; 1229 } else { 1230 /* 1231 * Step 10: others 1232 * read & clear the main (Ethernet) MAC status 1233 * (the relevant bits of this are write-one-to-clear). 1234 */ 1235 emac_status = bge_reg_get32(bgep, 1236 ETHERNET_MAC_STATUS_REG); 1237 bge_reg_put32(bgep, 1238 ETHERNET_MAC_STATUS_REG, emac_status); 1239 1240 BGE_DEBUG(("bge_check_serdes: link %d/%s, " 1241 "MAC status 0x%x (was 0x%x)", 1242 bgep->link_state, UPORDOWN(bgep->param_link_up), 1243 emac_status, bgep->serdes_status)); 1244 1245 /* 1246 * We will only consider the link UP if all the readings 1247 * are consistent and give meaningful results ... 1248 */ 1249 bgep->serdes_status = emac_status; 1250 linkup = BIS(emac_status, 1251 ETHERNET_STATUS_SIGNAL_DETECT); 1252 linkup &= BIS(emac_status, ETHERNET_STATUS_PCS_SYNCHED); 1253 1254 /* 1255 * Now some fiddling with the interpretation: 1256 * if there's been an error at the PCS level, treat 1257 * it as a link change (the h/w doesn't do this) 1258 * 1259 * if there's been a change, but it's only a PCS 1260 * sync change (not a config change), AND the link 1261 * already was & is still UP, then ignore the 1262 * change 1263 */ 1264 if (BIS(emac_status, ETHERNET_STATUS_PCS_ERROR)) 1265 emac_status |= ETHERNET_STATUS_LINK_CHANGED; 1266 else if (BIC(emac_status, ETHERNET_STATUS_CFG_CHANGED)) 1267 if (bgep->param_link_up && linkup) 1268 emac_status &= 1269 ~ETHERNET_STATUS_LINK_CHANGED; 1270 1271 BGE_DEBUG(("bge_check_serdes: status 0x%x => 0x%x %s", 1272 bgep->serdes_status, emac_status, 1273 UPORDOWN(linkup))); 1274 1275 /* 1276 * If we're receiving configs, run the autoneg protocol 1277 */ 1278 if (linkup && BIS(emac_status, 1279 ETHERNET_STATUS_RECEIVING_CFG)) 1280 bge_autoneg_serdes(bgep); 1281 1282 /* 1283 * If the SerDes status hasn't changed, we're done ... 1284 */ 1285 if (BIC(emac_status, ETHERNET_STATUS_LINK_CHANGED)) 1286 break; 1287 1288 /* 1289 * Go round again until we no longer see a change ... 1290 */ 1291 recheck = B_TRUE; 1292 } 1293 } 1294 1295 /* 1296 * If we're not forcing a recheck (i.e. the link state was already 1297 * known), and we didn't see the hardware flag a change, there's 1298 * no more to do (and we tell the caller nothing happened). 1299 */ 1300 if (!recheck) 1301 return (B_FALSE); 1302 1303 /* 1304 * Don't resolve autoneg until we're no longer receiving configs 1305 */ 1306 if (linkup && BIS(emac_status, ETHERNET_STATUS_RECEIVING_CFG)) 1307 return (B_FALSE); 1308 1309 /* 1310 * Assume very little ... 1311 */ 1312 bgep->param_lp_autoneg = B_FALSE; 1313 bgep->param_lp_1000fdx = B_FALSE; 1314 bgep->param_lp_1000hdx = B_FALSE; 1315 bgep->param_lp_100fdx = B_FALSE; 1316 bgep->param_lp_100hdx = B_FALSE; 1317 bgep->param_lp_10fdx = B_FALSE; 1318 bgep->param_lp_10hdx = B_FALSE; 1319 bgep->param_lp_pause = B_FALSE; 1320 bgep->param_lp_asym_pause = B_FALSE; 1321 bgep->param_link_autoneg = B_FALSE; 1322 bgep->param_link_tx_pause = B_FALSE; 1323 if (bgep->param_adv_autoneg) 1324 bgep->param_link_rx_pause = B_FALSE; 1325 else 1326 bgep->param_link_rx_pause = bgep->param_adv_pause; 1327 1328 /* 1329 * Discover all the link partner's abilities. 1330 */ 1331 lpadv = bgep->serdes_lpadv; 1332 if (lpadv != 0 && BIC(lpadv, AUTONEG_CODE_FAULT_MASK)) { 1333 /* 1334 * No fault, so derive partner's capabilities 1335 */ 1336 bgep->param_lp_autoneg = B_TRUE; 1337 bgep->param_lp_1000fdx = BIS(lpadv, AUTONEG_CODE_FULL_DUPLEX); 1338 bgep->param_lp_1000hdx = BIS(lpadv, AUTONEG_CODE_HALF_DUPLEX); 1339 bgep->param_lp_pause = BIS(lpadv, AUTONEG_CODE_PAUSE); 1340 bgep->param_lp_asym_pause = BIS(lpadv, AUTONEG_CODE_ASYM_PAUSE); 1341 1342 /* 1343 * Pause direction resolution 1344 */ 1345 bgep->param_link_autoneg = B_TRUE; 1346 if (bgep->param_adv_pause && 1347 bgep->param_lp_pause) { 1348 bgep->param_link_tx_pause = B_TRUE; 1349 bgep->param_link_rx_pause = B_TRUE; 1350 } 1351 if (bgep->param_adv_asym_pause && 1352 bgep->param_lp_asym_pause) { 1353 if (bgep->param_adv_pause) 1354 bgep->param_link_rx_pause = B_TRUE; 1355 if (bgep->param_lp_pause) 1356 bgep->param_link_tx_pause = B_TRUE; 1357 } 1358 } 1359 1360 /* 1361 * Step 12: update ndd-visible state parameters, BUT! 1362 * we don't transfer the new state to <link_state> just yet; 1363 * instead we mark the <link_state> as UNKNOWN, and our caller 1364 * will resolve it once the status has stopped changing and 1365 * been stable for several seconds. 1366 */ 1367 BGE_DEBUG(("bge_check_serdes: link was %s speed %d duplex %d", 1368 UPORDOWN(bgep->param_link_up), 1369 bgep->param_link_speed, 1370 bgep->param_link_duplex)); 1371 1372 if (linkup) { 1373 bgep->param_link_up = B_TRUE; 1374 bgep->param_link_speed = 1000; 1375 if (bgep->param_adv_1000fdx) 1376 bgep->param_link_duplex = LINK_DUPLEX_FULL; 1377 else 1378 bgep->param_link_duplex = LINK_DUPLEX_HALF; 1379 if (bgep->param_lp_autoneg && !bgep->param_lp_1000fdx) 1380 bgep->param_link_duplex = LINK_DUPLEX_HALF; 1381 } else { 1382 bgep->param_link_up = B_FALSE; 1383 bgep->param_link_speed = 0; 1384 bgep->param_link_duplex = LINK_DUPLEX_UNKNOWN; 1385 } 1386 bgep->link_state = LINK_STATE_UNKNOWN; 1387 1388 BGE_DEBUG(("bge_check_serdes: link now %s speed %d duplex %d", 1389 UPORDOWN(bgep->param_link_up), 1390 bgep->param_link_speed, 1391 bgep->param_link_duplex)); 1392 1393 return (B_TRUE); 1394 } 1395 1396 static const phys_ops_t serdes_ops = { 1397 bge_restart_serdes, 1398 bge_update_serdes, 1399 bge_check_serdes 1400 }; 1401 1402 /* 1403 * ========== Exported physical layer control routines ========== 1404 */ 1405 1406 #undef BGE_DBG 1407 #define BGE_DBG BGE_DBG_PHYS /* debug flag for this code */ 1408 1409 /* 1410 * Here we have to determine which media we're using (copper or serdes). 1411 * Once that's done, we can initialise the physical layer appropriately. 1412 */ 1413 int 1414 bge_phys_init(bge_t *bgep) 1415 { 1416 BGE_TRACE(("bge_phys_init($%p)", (void *)bgep)); 1417 1418 mutex_enter(bgep->genlock); 1419 1420 /* 1421 * Probe for the (internal) PHY. If it's not there, we'll assume 1422 * that this is a 5703/4S, with a SerDes interface rather than 1423 * a PHY. BCM5714S/BCM5715S are not supported.It are based on 1424 * BCM800x PHY. 1425 */ 1426 bgep->phy_mii_addr = 1; 1427 if (bge_phy_probe(bgep)) { 1428 bgep->chipid.flags &= ~CHIP_FLAG_SERDES; 1429 bgep->physops = &copper_ops; 1430 } else { 1431 bgep->chipid.flags |= CHIP_FLAG_SERDES; 1432 bgep->physops = &serdes_ops; 1433 } 1434 1435 if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) { 1436 mutex_exit(bgep->genlock); 1437 return (EIO); 1438 } 1439 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 1440 mutex_exit(bgep->genlock); 1441 return (EIO); 1442 } 1443 mutex_exit(bgep->genlock); 1444 return (0); 1445 } 1446 1447 /* 1448 * Reset the physical layer 1449 */ 1450 void 1451 bge_phys_reset(bge_t *bgep) 1452 { 1453 BGE_TRACE(("bge_phys_reset($%p)", (void *)bgep)); 1454 1455 mutex_enter(bgep->genlock); 1456 if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) 1457 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); 1458 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) 1459 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); 1460 mutex_exit(bgep->genlock); 1461 } 1462 1463 /* 1464 * Reset and power off the physical layer. 1465 * 1466 * Another RESET should get it back to working, but it may take a few 1467 * seconds it may take a few moments to return to normal operation ... 1468 */ 1469 int 1470 bge_phys_idle(bge_t *bgep) 1471 { 1472 BGE_TRACE(("bge_phys_idle($%p)", (void *)bgep)); 1473 1474 ASSERT(mutex_owned(bgep->genlock)); 1475 return ((*bgep->physops->phys_restart)(bgep, B_TRUE)); 1476 } 1477 1478 /* 1479 * Synchronise the PHYSICAL layer's speed/duplex/autonegotiation capabilities 1480 * and advertisements with the required settings as specified by the various 1481 * param_* variables that can be poked via the NDD interface. 1482 * 1483 * We always reset the PHYSICAL layer and reprogram *all* relevant registers. 1484 * This is expected to cause the link to go down, and then back up again once 1485 * the link is stable and autonegotiation (if enabled) is complete. We should 1486 * get a link state change interrupt somewhere along the way ... 1487 * 1488 * NOTE: <genlock> must already be held by the caller 1489 */ 1490 int 1491 bge_phys_update(bge_t *bgep) 1492 { 1493 BGE_TRACE(("bge_phys_update($%p)", (void *)bgep)); 1494 1495 ASSERT(mutex_owned(bgep->genlock)); 1496 return ((*bgep->physops->phys_update)(bgep)); 1497 } 1498 1499 #undef BGE_DBG 1500 #define BGE_DBG BGE_DBG_LINK /* debug flag for this code */ 1501 1502 /* 1503 * Read the link status and determine whether anything's changed ... 1504 * 1505 * This routine should be called whenever the chip flags a change 1506 * in the hardware link state. 1507 * 1508 * This routine returns B_FALSE if the link state has not changed, 1509 * returns B_TRUE when the change to the new state should be accepted. 1510 * In such a case, the param_* variables give the new hardware state, 1511 * which the caller should use to update link_state etc. 1512 * 1513 * The caller must already hold <genlock> 1514 */ 1515 boolean_t 1516 bge_phys_check(bge_t *bgep) 1517 { 1518 int32_t orig_state; 1519 boolean_t recheck; 1520 1521 BGE_TRACE(("bge_phys_check($%p)", (void *)bgep)); 1522 1523 ASSERT(mutex_owned(bgep->genlock)); 1524 1525 orig_state = bgep->link_state; 1526 recheck = orig_state == LINK_STATE_UNKNOWN; 1527 recheck = (*bgep->physops->phys_check)(bgep, recheck); 1528 if (!recheck) 1529 return (B_FALSE); 1530 1531 return (B_TRUE); 1532 } 1533