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