Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/mii Implement a separate nsphy_reset(). There are t...



details:   https://anonhg.NetBSD.org/src/rev/e7f12cb59821
branches:  trunk
changeset: 554787:e7f12cb59821
user:      briggs <briggs%NetBSD.org@localhost>
date:      Sun Nov 02 01:42:28 2003 +0000

description:
Implement a separate nsphy_reset().  There are two reasons for this:

        1) This PHY can take an inordinate amount of time to reset if
           media is attached.  Under fairly normal circumstances, up
           to near one second.  This is because it appears to go through
           an implicit autonegotiation cycle as part of the reset.

        2) During reset and autonegotiation, the BMCR will clear the reset
           bit before the process is complete.  It will return 0 until the
           process is complete and it's safe to access the PHY again.

This gets the on-board pcnet + nsphy ethernet working properly for me on
an IBM PC Server/325.  Fixes PR/16346.

diffstat:

 sys/dev/mii/nsphy.c |  46 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 43 insertions(+), 3 deletions(-)

diffs (73 lines):

diff -r 88da8244f420 -r e7f12cb59821 sys/dev/mii/nsphy.c
--- a/sys/dev/mii/nsphy.c       Sun Nov 02 01:39:22 2003 +0000
+++ b/sys/dev/mii/nsphy.c       Sun Nov 02 01:42:28 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nsphy.c,v 1.39 2003/04/29 01:49:34 thorpej Exp $       */
+/*     $NetBSD: nsphy.c,v 1.40 2003/11/02 01:42:28 briggs Exp $        */
 
 /*-
  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nsphy.c,v 1.39 2003/04/29 01:49:34 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nsphy.c,v 1.40 2003/11/02 01:42:28 briggs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -98,9 +98,10 @@
 
 int    nsphy_service(struct mii_softc *, struct mii_data *, int);
 void   nsphy_status(struct mii_softc *);
+void   nsphy_reset(struct mii_softc *sc);
 
 const struct mii_phy_funcs nsphy_funcs = {
-       nsphy_service, nsphy_status, mii_phy_reset,
+       nsphy_service, nsphy_status, nsphy_reset,
 };
 
 const struct mii_phydesc nsphys[] = {
@@ -326,3 +327,42 @@
        } else
                mii->mii_media_active = ife->ifm_media;
 }
+
+void
+nsphy_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);
+
+       /*
+        * Give it a little time to settle in case we just got power.
+        * The DP83840A data sheet suggests that a soft reset not happen
+        * within 500us of power being applied.  Be conservative.
+        */
+       delay(1000);
+
+       /*
+        * Wait another 2s for it to complete.
+        * This is only a little overkill as under normal circumstances
+        * the PHY can take up to 1s to complete reset.
+        * This is also a bit odd because after a reset, the BMCR will
+        * clear the reset bit and simply reports 0 even though the reset
+        * is not yet complete.
+        */
+       for (i = 0; i < 1000; i++) {
+               reg = PHY_READ(sc, MII_BMCR); 
+               if (reg && ((reg & BMCR_RESET) == 0))
+                       break;
+               delay(2000);
+       }
+
+       if (sc->mii_inst != 0 && ((sc->mii_flags & MIIF_NOISOLATE) == 0)) {
+               PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+       }
+}
+



Home | Main Index | Thread Index | Old Index