diff options
| author | msaitoh <msaitoh@NetBSD.org> | 2008-01-20 07:58:19 +0000 |
|---|---|---|
| committer | msaitoh <msaitoh@NetBSD.org> | 2008-01-20 07:58:19 +0000 |
| commit | fae0af7902bdc04478c6f3764845e37a59c4bb29 (patch) | |
| tree | fb466d2e0570e5155a13d57e1cff1fb66a68ea5c /sys/dev | |
| parent | aa7cb7b8f07784fd164bc36ae1e9e3309eafb4da (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.c | 40 | ||||
| -rw-r--r-- | sys/dev/mii/mii_physubr.c | 14 | ||||
| -rw-r--r-- | sys/dev/mii/nsphyter.c | 40 |
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); +} |
