Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Move the BCM5401 DSP patch out of the bge driver and...



details:   https://anonhg.NetBSD.org/src/rev/bcb0a10f0af8
branches:  trunk
changeset: 534014:bcb0a10f0af8
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sat Jul 13 01:23:27 2002 +0000

description:
Move the BCM5401 DSP patch out of the bge driver and into
the brgphy driver; all users of the BCM5400 and BCM5401 need
the DSP patch and the sledgehammer-reset-at-media-set-time.

Also add a DSP patch for the BCM5411 gleaned from Apple's
GMAC driver for Darwin.

Tested with a 3Com 3c996-T (BCM5700 + BCM5401).

diffstat:

 sys/dev/mii/brgphy.c |  120 ++++++++++++++++++++++++++++++++++++++++++++++++--
 sys/dev/pci/if_bge.c |   52 +---------------------
 2 files changed, 116 insertions(+), 56 deletions(-)

diffs (268 lines):

diff -r 85362d307a7c -r bcb0a10f0af8 sys/dev/mii/brgphy.c
--- a/sys/dev/mii/brgphy.c      Fri Jul 12 22:29:14 2002 +0000
+++ b/sys/dev/mii/brgphy.c      Sat Jul 13 01:23:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: brgphy.c,v 1.9 2002/07/12 04:00:10 thorpej Exp $       */
+/*     $NetBSD: brgphy.c,v 1.10 2002/07/13 01:23:27 thorpej Exp $      */
 
 /*-
  * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.9 2002/07/12 04:00:10 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.10 2002/07/13 01:23:27 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -103,10 +103,21 @@
 int    brgphy_service(struct mii_softc *, struct mii_data *, int);
 void   brgphy_status(struct mii_softc *);
 
+void   brgphy_5401_reset(struct mii_softc *);
+void   brgphy_5411_reset(struct mii_softc *);
+
 const struct mii_phy_funcs brgphy_funcs = {
        brgphy_service, brgphy_status, mii_phy_reset,
 };
 
+const struct mii_phy_funcs brgphy_5401_funcs = {
+       brgphy_service, brgphy_status, brgphy_5401_reset,
+};
+
+const struct mii_phy_funcs brgphy_5411_funcs = {
+       brgphy_service, brgphy_status, brgphy_5411_reset,
+};
+
 const struct mii_phydesc brgphys[] = {
        { MII_OUI_BROADCOM,             MII_MODEL_BROADCOM_BCM5400,
          MII_STR_BROADCOM_BCM5400 },
@@ -127,6 +138,9 @@
          NULL },
 };
 
+static void bcm5401_load_dspcode(struct mii_softc *);
+static void bcm5411_load_dspcode(struct mii_softc *);
+
 int
 brgphymatch(struct device *parent, struct cfdata *match, void *aux)
 {
@@ -151,11 +165,35 @@
 
        sc->mii_inst = mii->mii_instance;
        sc->mii_phy = ma->mii_phyno;
-       sc->mii_funcs = &brgphy_funcs;
        sc->mii_pdata = mii;
        sc->mii_flags = ma->mii_flags;
        sc->mii_anegticks = 5;
 
+       switch (MII_MODEL(ma->mii_id2)) {
+       case MII_MODEL_BROADCOM_BCM5400:
+               sc->mii_funcs = &brgphy_5401_funcs;
+               printf("%s: using BCM5401 DSP patch\n", sc->mii_dev.dv_xname);
+               break;
+
+       case MII_MODEL_BROADCOM_BCM5401:
+               if (MII_REV(ma->mii_id2) == 1 || MII_REV(ma->mii_id2) == 3) {
+                       sc->mii_funcs = &brgphy_5401_funcs;
+                       printf("%s: using BCM5401 DSP patch\n",
+                           sc->mii_dev.dv_xname);
+               } else
+                       sc->mii_funcs = &brgphy_funcs;
+               break;
+
+       case MII_MODEL_BROADCOM_BCM5411:
+               sc->mii_funcs = &brgphy_5411_funcs;
+               printf("%s: using BCM5411 DSP patch\n", sc->mii_dev.dv_xname);
+               break;
+
+       default:
+               sc->mii_funcs = &brgphy_funcs;
+               break;
+       }
+
        PHY_RESET(sc);
 
        sc->mii_capabilities =
@@ -204,6 +242,7 @@
                if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
                        break;
 
+               mii_phy_reset(sc);      /* XXX hardware bug work-around */
                mii_phy_setmedia(sc);
                break;
 
@@ -226,8 +265,19 @@
        /* Update the media status. */
        mii_phy_status(sc);
 
-       /* Callback if something changed. */
-       mii_phy_update(sc, cmd);
+       /*
+        * Callback if something changed.  Note that we need to poke
+        * the DSP on the Broadcom PHYs if the media changes.
+        */
+       if (sc->mii_media_active != mii->mii_media_active || 
+           sc->mii_media_status != mii->mii_media_status ||
+           cmd == MII_MEDIACHG) {
+               mii_phy_update(sc, cmd);
+               if (sc->mii_funcs == &brgphy_5401_funcs)
+                       bcm5401_load_dspcode(sc);
+               else if (sc->mii_funcs == &brgphy_5411_funcs)
+                       bcm5411_load_dspcode(sc);
+       }
        return (0);
 }
 
@@ -309,3 +359,63 @@
        } else
                mii->mii_media_active = ife->ifm_media;
 }
+
+void
+brgphy_5401_reset(struct mii_softc *sc)
+{
+
+       mii_phy_reset(sc);
+       bcm5401_load_dspcode(sc);
+}
+
+void
+brgphy_5411_reset(struct mii_softc *sc)
+{
+
+       mii_phy_reset(sc);
+       bcm5411_load_dspcode(sc);
+}
+
+static void
+bcm5401_load_dspcode(struct mii_softc *sc)
+{
+       static const struct {
+               int             reg;
+               uint16_t        val;
+       } dspcode[] = {
+               { BRGPHY_MII_AUXCTL,            0x4c20 },
+               { BRGPHY_MII_DSP_ADDR_REG,      0x0012 },
+               { BRGPHY_MII_DSP_RW_PORT,       0x1804 },
+               { BRGPHY_MII_DSP_ADDR_REG,      0x0013 },
+               { BRGPHY_MII_DSP_RW_PORT,       0x1204 },
+               { BRGPHY_MII_DSP_ADDR_REG,      0x8006 },
+               { BRGPHY_MII_DSP_RW_PORT,       0x0132 },
+               { BRGPHY_MII_DSP_ADDR_REG,      0x8006 },
+               { BRGPHY_MII_DSP_RW_PORT,       0x0232 },
+               { BRGPHY_MII_DSP_ADDR_REG,      0x201f },
+               { BRGPHY_MII_DSP_RW_PORT,       0x0a20 },
+               { 0,                            0 },
+       };
+       int i;
+
+       for (i = 0; dspcode[i].reg != 0; i++)
+               PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
+}
+
+static void
+bcm5411_load_dspcode(struct mii_softc *sc)
+{
+       static const struct {
+               int             reg;
+               uint16_t        val;
+       } dspcode[] = {
+               { 0x1c,                         0x8c23 },
+               { 0x1c,                         0x8ca3 },
+               { 0x1c,                         0x8c23 },
+               { 0,                            0 },
+       };
+       int i;
+
+       for (i = 0; dspcode[i].reg != 0; i++)
+               PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
+}
diff -r 85362d307a7c -r bcb0a10f0af8 sys/dev/pci/if_bge.c
--- a/sys/dev/pci/if_bge.c      Fri Jul 12 22:29:14 2002 +0000
+++ b/sys/dev/pci/if_bge.c      Sat Jul 13 01:23:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bge.c,v 1.14 2002/07/12 22:29:14 enami Exp $        */
+/*     $NetBSD: if_bge.c,v 1.15 2002/07/13 01:23:27 thorpej Exp $      */
 
 /*
  * Copyright (c) 2001 Wind River Systems
@@ -181,7 +181,6 @@
 void bge_miibus_statchg(struct device *);
 
 void bge_reset(struct bge_softc *);
-void bge_phy_hack(struct bge_softc *);
 
 void bge_dump_status(struct bge_softc *);
 void bge_dump_rxbd(struct bge_rx_bd *);
@@ -489,8 +488,6 @@
        } else {
                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
        }
-
-       bge_phy_hack(sc);
 }
 
 /*
@@ -2498,46 +2495,6 @@
        ifp->if_timer = 5;
 }
 
-/*
- * If we have a BCM5400 or BCM5401 PHY, we need to properly
- * program its internal DSP. Failing to do this can result in
- * massive packet loss at 1Gb speeds.
- */
-void
-bge_phy_hack(sc)
-       struct bge_softc *sc;
-{
-       struct bge_bcom_hack bhack[] = {
-       { BRGPHY_MII_AUXCTL, 0x4C20 },
-       { BRGPHY_MII_DSP_ADDR_REG, 0x0012 },
-       { BRGPHY_MII_DSP_RW_PORT, 0x1804 },
-       { BRGPHY_MII_DSP_ADDR_REG, 0x0013 },
-       { BRGPHY_MII_DSP_RW_PORT, 0x1204 },
-       { BRGPHY_MII_DSP_ADDR_REG, 0x8006 },
-       { BRGPHY_MII_DSP_RW_PORT, 0x0132 },
-       { BRGPHY_MII_DSP_ADDR_REG, 0x8006 },
-       { BRGPHY_MII_DSP_RW_PORT, 0x0232 },
-       { BRGPHY_MII_DSP_ADDR_REG, 0x201F },
-       { BRGPHY_MII_DSP_RW_PORT, 0x0A20 },
-       { 0, 0 } };
-       u_int16_t vid, did;
-       int i;
-
-       vid = bge_miibus_readreg(&sc->bge_dev, 1, MII_PHYIDR1);
-       did = bge_miibus_readreg(&sc->bge_dev, 1, MII_PHYIDR2);
-
-       if (MII_OUI(vid, did) == MII_OUI_BROADCOM &&
-           (MII_MODEL(did) == MII_MODEL_BROADCOM_BCM5400 ||
-            MII_MODEL(did) == MII_MODEL_BROADCOM_BCM5401)) {
-               i = 0;
-               while (bhack[i].reg) {
-                       bge_miibus_writereg(&sc->bge_dev, 1, bhack[i].reg,
-                                           bhack[i].val);
-                       i++;
-               }
-       }
-}
-
 int
 bge_init(ifp)
        struct ifnet *ifp;
@@ -2661,13 +2618,6 @@
        }
 
        sc->bge_link = 0;
-       if (mii->mii_instance) {
-               struct mii_softc *miisc;
-               for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
-                   miisc = LIST_NEXT(miisc, mii_list))
-                       mii_phy_reset(miisc);
-       }
-       bge_phy_hack(sc);
        mii_mediachg(mii);
 
        return(0);



Home | Main Index | Thread Index | Old Index