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