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