summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormsaitoh <msaitoh@NetBSD.org>2008-01-20 07:58:19 +0000
committermsaitoh <msaitoh@NetBSD.org>2008-01-20 07:58:19 +0000
commitfae0af7902bdc04478c6f3764845e37a59c4bb29 (patch)
treefb466d2e0570e5155a13d57e1cff1fb66a68ea5c /sys/dev
parentaa7cb7b8f07784fd164bc36ae1e9e3309eafb4da (diff)
mii_physubr.c::mii_phy_reset() has gphyter and nsphyter specific delay(500).
This delay cause 500us loops under splnet() per linkdown port per mii_tick. It causes periodically drop packets. It's not acceptable for other devices. Move gphyter and nsphyter specific delay(500) into the drivers from mii_physubr.c.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/mii/gphyter.c40
-rw-r--r--sys/dev/mii/mii_physubr.c14
-rw-r--r--sys/dev/mii/nsphyter.c40
3 files changed, 76 insertions, 18 deletions
diff --git a/sys/dev/mii/gphyter.c b/sys/dev/mii/gphyter.c
index 121702801d2..ffd4bae24e0 100644
--- a/sys/dev/mii/gphyter.c
+++ b/sys/dev/mii/gphyter.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gphyter.c,v 1.20 2007/12/09 20:28:03 jmcneill Exp $ */
+/* $NetBSD: gphyter.c,v 1.21 2008/01/20 07:58:19 msaitoh Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gphyter.c,v 1.20 2007/12/09 20:28:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gphyter.c,v 1.21 2008/01/20 07:58:19 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -101,9 +101,10 @@ CFATTACH_DECL(gphyter, sizeof(struct mii_softc),
static int gphyter_service(struct mii_softc *, struct mii_data *, int);
static void gphyter_status(struct mii_softc *);
+static void gphyter_reset(struct mii_softc *);
static const struct mii_phy_funcs gphyter_funcs = {
- gphyter_service, gphyter_status, mii_phy_reset,
+ gphyter_service, gphyter_status, gphyter_reset,
};
static const struct mii_phydesc gphyters[] = {
@@ -311,3 +312,36 @@ gphyter_status(struct mii_softc *sc)
} else
mii->mii_media_active = ife->ifm_media;
}
+
+void
+gphyter_reset(struct mii_softc *sc)
+{
+ int reg, i;
+
+ if (sc->mii_flags & MIIF_NOISOLATE)
+ reg = BMCR_RESET;
+ else
+ reg = BMCR_RESET | BMCR_ISO;
+ PHY_WRITE(sc, MII_BMCR, reg);
+
+ /*
+ * It is best to allow a little time for the reset to settle
+ * in before we start polling the BMCR again. Notably, the
+ * DP83840A manual states that there should be a 500us delay
+ * between asserting software reset and attempting MII serial
+ * operations. Also, a DP83815 can get into a bad state on
+ * cable removal and reinsertion if we do not delay here.
+ */
+ delay(500);
+
+ /* Wait another 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ reg = PHY_READ(sc, MII_BMCR);
+ if ((reg & BMCR_RESET) == 0)
+ break;
+ delay(1000);
+ }
+
+ if (sc->mii_inst != 0 && ((sc->mii_flags & MIIF_NOISOLATE) == 0))
+ PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+}
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c
index 246f9721844..cfaf68805e2 100644
--- a/sys/dev/mii/mii_physubr.c
+++ b/sys/dev/mii/mii_physubr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mii_physubr.c,v 1.56 2008/01/10 07:29:41 dyoung Exp $ */
+/* $NetBSD: mii_physubr.c,v 1.57 2008/01/20 07:58:19 msaitoh Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.56 2008/01/10 07:29:41 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.57 2008/01/20 07:58:19 msaitoh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -337,16 +337,6 @@ mii_phy_reset(struct mii_softc *sc)
reg = BMCR_RESET | BMCR_ISO;
PHY_WRITE(sc, MII_BMCR, reg);
- /*
- * It is best to allow a little time for the reset to settle
- * in before we start polling the BMCR again. Notably, the
- * DP83840A manual states that there should be a 500us delay
- * between asserting software reset and attempting MII serial
- * operations. Also, a DP83815 can get into a bad state on
- * cable removal and reinsertion if we do not delay here.
- */
- delay(500);
-
/* Wait another 100ms for it to complete. */
for (i = 0; i < 100; i++) {
reg = PHY_READ(sc, MII_BMCR);
diff --git a/sys/dev/mii/nsphyter.c b/sys/dev/mii/nsphyter.c
index 274fcc5075a..8507f148c08 100644
--- a/sys/dev/mii/nsphyter.c
+++ b/sys/dev/mii/nsphyter.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nsphyter.c,v 1.27 2007/12/09 20:28:04 jmcneill Exp $ */
+/* $NetBSD: nsphyter.c,v 1.28 2008/01/20 07:58:19 msaitoh Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nsphyter.c,v 1.27 2007/12/09 20:28:04 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nsphyter.c,v 1.28 2008/01/20 07:58:19 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -101,9 +101,10 @@ CFATTACH_DECL(nsphyter, sizeof(struct mii_softc),
static int nsphyter_service(struct mii_softc *, struct mii_data *, int);
static void nsphyter_status(struct mii_softc *);
+static void nsphyter_reset(struct mii_softc *);
static const struct mii_phy_funcs nsphyter_funcs = {
- nsphyter_service, nsphyter_status, mii_phy_reset,
+ nsphyter_service, nsphyter_status, nsphyter_reset,
};
static const struct mii_phydesc nsphyters[] = {
@@ -272,3 +273,36 @@ nsphyter_status(struct mii_softc *sc)
} else
mii->mii_media_active = ife->ifm_media;
}
+
+void
+nsphyter_reset(struct mii_softc *sc)
+{
+ int reg, i;
+
+ if (sc->mii_flags & MIIF_NOISOLATE)
+ reg = BMCR_RESET;
+ else
+ reg = BMCR_RESET | BMCR_ISO;
+ PHY_WRITE(sc, MII_BMCR, reg);
+
+ /*
+ * It is best to allow a little time for the reset to settle
+ * in before we start polling the BMCR again. Notably, the
+ * DP83840A manual states that there should be a 500us delay
+ * between asserting software reset and attempting MII serial
+ * operations. Also, a DP83815 can get into a bad state on
+ * cable removal and reinsertion if we do not delay here.
+ */
+ delay(500);
+
+ /* Wait another 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ reg = PHY_READ(sc, MII_BMCR);
+ if ((reg & BMCR_RESET) == 0)
+ break;
+ delay(1000);
+ }
+
+ if (sc->mii_inst != 0 && ((sc->mii_flags & MIIF_NOISOLATE) == 0))
+ PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+}