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