Print this page
Just the 5719/5720 changes


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 




  26 #include "bge_impl.h"
  27 
  28 /*
  29  * Bit test macros, returning boolean_t values
  30  */
  31 #define BIS(w, b)       (((w) & (b)) ? B_TRUE : B_FALSE)
  32 #define BIC(w, b)       (((w) & (b)) ? B_FALSE : B_TRUE)
  33 #define UPORDOWN(x)     ((x) ? "up" : "down")
  34 
  35 /*
  36  * ========== Copper (PHY) support ==========
  37  */
  38 
  39 #define BGE_DBG         BGE_DBG_PHY     /* debug flag for this code     */
  40 
  41 /*
  42  * #defines:
  43  *      BGE_COPPER_WIRESPEED controls whether the Broadcom WireSpeed(tm)
  44  *      feature is enabled.  We need to recheck whether this can be
  45  *      enabled; at one time it seemed to interact unpleasantly with the


 190                 case 0xffff:
 191                         return (B_FALSE);
 192 
 193                 default :
 194                         return (B_TRUE);
 195                 }
 196         }
 197 }
 198 
 199 /*
 200  * Basic low-level function to reset the PHY.
 201  * Doesn't incorporate any special-case workarounds.
 202  *
 203  * Returns TRUE on success, FALSE if the RESET bit doesn't clear
 204  */
 205 static boolean_t
 206 bge_phy_reset(bge_t *bgep)
 207 {
 208         uint16_t control;
 209         uint_t count;

 210 
 211         BGE_TRACE(("bge_phy_reset($%p)", (void *)bgep));
 212 
 213         ASSERT(mutex_owned(bgep->genlock));
 214 
 215         if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
 216                 drv_usecwait(40);
 217                 /* put PHY into ready state */
 218                 bge_reg_clr32(bgep, MISC_CONFIG_REG, MISC_CONFIG_EPHY_IDDQ);
 219                 (void) bge_reg_get32(bgep, MISC_CONFIG_REG); /* flush */
 220                 drv_usecwait(40);
 221         }
 222 
 223         /*
 224          * Set the PHY RESET bit, then wait up to 5 ms for it to self-clear
 225          */
 226         bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_RESET);
 227         for (count = 0; ++count < 1000; ) {
 228                 drv_usecwait(5);
 229                 control = bge_mii_get16(bgep, MII_CONTROL);
 230                 if (BIC(control, MII_CONTROL_RESET))
 231                         return (B_TRUE);


 232         }


 233 
 234         if (DEVICE_5906_SERIES_CHIPSETS(bgep))
 235                 (void) bge_adj_volt_5906(bgep);
 236 

 237         BGE_DEBUG(("bge_phy_reset: FAILED, control now 0x%x", control));
 238 
 239         return (B_FALSE);
 240 }
 241 
 242 /*
 243  * Basic low-level function to powerdown the PHY, if supported
 244  * If powerdown support is compiled out, this function does nothing.
 245  */
 246 static void
 247 bge_phy_powerdown(bge_t *bgep)
 248 {
 249         BGE_TRACE(("bge_phy_powerdown"));
 250 #if     BGE_COPPER_IDLEOFF
 251         bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_PWRDN);
 252 #endif  /* BGE_COPPER_IDLEOFF */
 253 }
 254 
 255 /*
 256  * The following functions are based on sample code provided by
 257  * Broadcom (20-June-2003), and implement workarounds said to be
 258  * required on the early revisions of the BCM5703/4C.
 259  *


 524         bge_mii_put16(bgep, 0x17, 0x401f);
 525         bge_mii_put16(bgep, 0x15, 0x14e2);
 526         bge_mii_put16(bgep, 0x18, 0x0400);
 527 }
 528 
 529 /*
 530  * End of Broadcom-derived workaround code                              *
 531  */
 532 
 533 static int
 534 bge_restart_copper(bge_t *bgep, boolean_t powerdown)
 535 {
 536         uint16_t phy_status;
 537         boolean_t reset_ok;
 538         uint16_t extctrl, auxctrl;
 539 
 540         BGE_TRACE(("bge_restart_copper($%p, %d)", (void *)bgep, powerdown));
 541 
 542         ASSERT(mutex_owned(bgep->genlock));
 543 
 544         switch (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev)) {
 545         default:
 546                 /*
 547                  * Shouldn't happen; it means we don't recognise this chip.
 548                  * It's probably a new one, so we'll try our best anyway ...
 549                  */
 550         case MHCR_CHIP_ASIC_REV_5703:
 551         case MHCR_CHIP_ASIC_REV_5704:
 552         case MHCR_CHIP_ASIC_REV_5705:
 553         case MHCR_CHIP_ASIC_REV_5752:
 554         case MHCR_CHIP_ASIC_REV_5714:
 555         case MHCR_CHIP_ASIC_REV_5715:
 556                 reset_ok = bge_phy_reset_and_check(bgep);
 557                 break;
 558 
 559         case MHCR_CHIP_ASIC_REV_5906:
 560         case MHCR_CHIP_ASIC_REV_5700:
 561         case MHCR_CHIP_ASIC_REV_5701:
 562         case MHCR_CHIP_ASIC_REV_5723:
 563         case MHCR_CHIP_ASIC_REV_5721_5751:
 564                 /*
 565                  * Just a plain reset; the "check" code breaks these chips
 566                  */
 567                 reset_ok = bge_phy_reset(bgep);
 568                 if (!reset_ok)
 569                         bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE);
 570                 break;

 571         }

 572         if (!reset_ok) {
 573                 BGE_REPORT((bgep, "PHY failed to reset correctly"));
 574                 return (DDI_FAILURE);
 575         }
 576 
 577         /*
 578          * Step 5: disable WOL (not required after RESET)
 579          *
 580          * Step 6: refer to errata
 581          */
 582         switch (bgep->chipid.asic_rev) {
 583         default:
 584                 break;
 585 
 586         case MHCR_CHIP_REV_5704_A0:
 587                 bge_phy_tweak_gmii(bgep);
 588                 break;
 589         }
 590 
 591         switch (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev)) {
 592         case MHCR_CHIP_ASIC_REV_5705:
 593         case MHCR_CHIP_ASIC_REV_5721_5751:
 594                 bge_phy_bit_err_fix(bgep);
 595                 break;
 596         }
 597 
 598         if (!(bgep->chipid.flags & CHIP_FLAG_NO_JUMBO) &&
 599             (bgep->chipid.default_mtu > BGE_DEFAULT_MTU)) {
 600                 /* Set the GMII Fifo Elasticity to high latency */
 601                 extctrl = bge_mii_get16(bgep, 0x10);
 602                 bge_mii_put16(bgep, 0x10, extctrl | 0x1);
 603 
 604                 /* Allow reception of extended length packets */
 605                 bge_mii_put16(bgep, MII_AUX_CONTROL, 0x0007);
 606                 auxctrl = bge_mii_get16(bgep, MII_AUX_CONTROL);
 607                 auxctrl |= 0x4000;
 608                 bge_mii_put16(bgep, MII_AUX_CONTROL, auxctrl);
 609         }
 610 
 611         /*
 612          * Step 7: read the MII_INTR_STATUS register twice,
 613          * in order to clear any sticky bits (but they should


1490 
1491 /*
1492  * Here we have to determine which media we're using (copper or serdes).
1493  * Once that's done, we can initialise the physical layer appropriately.
1494  */
1495 int
1496 bge_phys_init(bge_t *bgep)
1497 {
1498         BGE_TRACE(("bge_phys_init($%p)", (void *)bgep));
1499 
1500         mutex_enter(bgep->genlock);
1501 
1502         /*
1503          * Probe for the (internal) PHY.  If it's not there, we'll assume
1504          * that this is a 5703/4S, with a SerDes interface rather than
1505          * a PHY. BCM5714S/BCM5715S are not supported.It are based on
1506          * BCM800x PHY.
1507          */
1508         bgep->phy_mii_addr = 1;
1509         if (DEVICE_5717_SERIES_CHIPSETS(bgep)) {
1510                 int regval = bge_reg_get32(bgep, CPMU_STATUS_REG);
1511                 if (regval & CPMU_STATUS_FUN_NUM)
1512                         bgep->phy_mii_addr += 1;









1513                 regval = bge_reg_get32(bgep, SGMII_STATUS_REG);
1514                 if (regval & MEDIA_SELECTION_MODE)
1515                         bgep->phy_mii_addr += 7;
1516         }
1517 
1518         if (bge_phy_probe(bgep)) {
1519                 bgep->chipid.flags &= ~CHIP_FLAG_SERDES;
1520                 bgep->physops = &copper_ops;
1521         } else {
1522                 bgep->chipid.flags |= CHIP_FLAG_SERDES;
1523                 bgep->physops = &serdes_ops;
1524         }
1525 
1526         if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) {
1527                 mutex_exit(bgep->genlock);
1528                 return (EIO);
1529         }
1530         if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
1531                 mutex_exit(bgep->genlock);
1532                 return (EIO);
1533         }
1534         mutex_exit(bgep->genlock);
1535         return (0);
1536 }
1537 




   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


 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  *


 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


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