diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/io/nge/nge.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/nge/nge_chip.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/io/nge/nge_main.c | 19 | ||||
-rw-r--r-- | usr/src/uts/common/io/nge/nge_xmii.c | 20 |
4 files changed, 28 insertions, 16 deletions
diff --git a/usr/src/uts/common/io/nge/nge.h b/usr/src/uts/common/io/nge/nge.h index af5a747c22..e7bbc1512e 100644 --- a/usr/src/uts/common/io/nge/nge.h +++ b/usr/src/uts/common/io/nge/nge.h @@ -450,7 +450,7 @@ typedef struct { * check for link status change */ typedef struct { - void (*phys_restart)(struct nge *); + boolean_t (*phys_restart)(struct nge *); void (*phys_update)(struct nge *); boolean_t (*phys_check)(struct nge *); } phys_ops_t; diff --git a/usr/src/uts/common/io/nge/nge_chip.c b/usr/src/uts/common/io/nge/nge_chip.c index aea886cb03..3a75e1eb93 100644 --- a/usr/src/uts/common/io/nge/nge_chip.c +++ b/usr/src/uts/common/io/nge/nge_chip.c @@ -1095,7 +1095,8 @@ nge_chip_reset(nge_t *ngep) /* * Reset the external phy */ - (void) nge_phy_reset(ngep); + if (!nge_phy_reset(ngep)) + return (DDI_FAILURE); ngep->nge_chip_state = NGE_CHIP_RESET; return (DDI_SUCCESS); } diff --git a/usr/src/uts/common/io/nge/nge_main.c b/usr/src/uts/common/io/nge/nge_main.c index 03a2367cda..80266592f1 100644 --- a/usr/src/uts/common/io/nge/nge_main.c +++ b/usr/src/uts/common/io/nge/nge_main.c @@ -2115,6 +2115,7 @@ nge_restart(nge_t *ngep) { int err = 0; err = nge_reset(ngep); + nge_chip_sync(ngep); if (!err) err = nge_chip_start(ngep); @@ -2521,13 +2522,6 @@ nge_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) if (brp->rx_hold != 0) return (DDI_FAILURE); - /* Recycle the multicast table */ - for (p = ngep->pcur_mulist; p != NULL; p = nextp) { - nextp = p->next; - kmem_free(p, sizeof (mul_item)); - } - ngep->pcur_mulist = NULL; - /* * Unregister from the GLD subsystem. This can fail, in * particular if there are DLPI style-2 streams still open - @@ -2538,6 +2532,17 @@ nge_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) return (DDI_FAILURE); /* + * Recycle the multicast table. mac_unregister() should be called + * before it to ensure the multicast table can be used even if + * mac_unregister() fails. + */ + for (p = ngep->pcur_mulist; p != NULL; p = nextp) { + nextp = p->next; + kmem_free(p, sizeof (mul_item)); + } + ngep->pcur_mulist = NULL; + + /* * All activity stopped, so we can clean up & exit */ nge_unattach(ngep); diff --git a/usr/src/uts/common/io/nge/nge_xmii.c b/usr/src/uts/common/io/nge/nge_xmii.c index b4d94951a4..2733780265 100644 --- a/usr/src/uts/common/io/nge/nge_xmii.c +++ b/usr/src/uts/common/io/nge/nge_xmii.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -244,7 +244,8 @@ nge_phy_reset(nge_t *ngep) control = nge_mii_get16(ngep, MII_CONTROL); control |= MII_CONTROL_RESET; nge_mii_put16(ngep, MII_CONTROL, control); - drv_usecwait(30); + /* We should wait for 500ms. It's defined in the manual */ + drv_usectohz(500000); for (count = 0; ++count < 10; ) { drv_usecwait(5); control = nge_mii_get16(ngep, MII_CONTROL); @@ -256,13 +257,16 @@ nge_phy_reset(nge_t *ngep) return (B_FALSE); } -static void +static boolean_t nge_phy_restart(nge_t *ngep) { uint16_t mii_reg; - (void) nge_phy_recover(ngep); - (void) nge_phy_reset(ngep); + if (!nge_phy_recover(ngep)) + return (B_FALSE); + if (!nge_phy_reset(ngep)) + return (B_FALSE); + if (PHY_MANUFACTURER(ngep->phy_id) == MII_ID_CICADA) { if (ngep->phy_mode == RGMII_IN) { mii_reg = nge_mii_get16(ngep, @@ -291,6 +295,8 @@ nge_phy_restart(nge_t *ngep) nge_mii_put16(ngep, MII_CICADA_BYPASS_CONTROL, mii_reg); } } + + return (B_TRUE); } /* @@ -460,8 +466,8 @@ nge_update_copper(nge_t *ngep) nge_mii_put16(ngep, MII_AN_ADVERT, anar); nge_mii_put16(ngep, MII_CONTROL, control); nge_mii_put16(ngep, MII_1000BASE_T_CONTROL, gigctrl); - nge_phy_restart(ngep); - + if (!nge_phy_restart(ngep)) + nge_error(ngep, "nge_update_copper: failed to restart phy"); /* * Loopback bit in control register is not reset sticky * write it after PHY restart. |