summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/nge/nge.h2
-rw-r--r--usr/src/uts/common/io/nge/nge_chip.c3
-rw-r--r--usr/src/uts/common/io/nge/nge_main.c19
-rw-r--r--usr/src/uts/common/io/nge/nge_xmii.c20
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.