summaryrefslogtreecommitdiffstats
path: root/sys/dev/mii/brgphy.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-02-21 18:17:44 +0000
committerjhb <jhb@FreeBSD.org>2007-02-21 18:17:44 +0000
commitcacf0d22c40108d2bf73286869a50235afa4a913 (patch)
tree3076263f608486e26ab04e525a5ae2f7cdc6883f /sys/dev/mii/brgphy.c
parenta5cba253f7c129dcf48fc6203b925b8ec7dad484 (diff)
downloadFreeBSD-src-cacf0d22c40108d2bf73286869a50235afa4a913.zip
FreeBSD-src-cacf0d22c40108d2bf73286869a50235afa4a913.tar.gz
Restore support for the 5706C bce(4) phy that was broken during the
addition of SerDes support. According to the docs, the 5706C and 5708C phys are supposed to use the same MII model that is separate from the SerDes parts, but the 5706C actually uses the MII model of the SerDes parts. To fix this, readd the old 5706C entry to miidevs and add a special check in brgphy_probe() for phys that match the 5706C ID. If the phy is supported by the gentbi(4) driver, then it's a SerDes phy, so we fail the probe and let gentbi(4) grab it. Otherwise, it's a 5706C phy, so we let brgphy(4) grab it. In coordination with: dwhite
Diffstat (limited to 'sys/dev/mii/brgphy.c')
-rw-r--r--sys/dev/mii/brgphy.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index 247e83f..06a3d6f 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -97,6 +97,7 @@ static void brgphy_status(struct mii_softc *);
static int brgphy_mii_phy_auto(struct mii_softc *);
static void brgphy_reset(struct mii_softc *);
static void brgphy_loop(struct mii_softc *);
+static int bcm5706_is_tbi(device_t);
static void bcm5401_load_dspcode(struct mii_softc *);
static void bcm5411_load_dspcode(struct mii_softc *);
static void brgphy_fixup_5704_a0_bug(struct mii_softc *);
@@ -122,6 +123,7 @@ static const struct mii_phydesc brgphys[] = {
MII_PHY_DESC(xxBROADCOM, BCM5752),
MII_PHY_DESC(xxBROADCOM, BCM5754),
MII_PHY_DESC(xxBROADCOM, BCM5780),
+ MII_PHY_DESC(xxBROADCOM, BCM5708C),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5787),
MII_PHY_END
};
@@ -129,8 +131,29 @@ static const struct mii_phydesc brgphys[] = {
static int
brgphy_probe(device_t dev)
{
+ struct mii_attach_args *ma;
+ int error;
- return (mii_phy_dev_probe(dev, brgphys, BUS_PROBE_DEFAULT));
+ error = mii_phy_dev_probe(dev, brgphys, BUS_PROBE_DEFAULT);
+ if (error != BUS_PROBE_DEFAULT)
+ return (error);
+
+ ma = device_get_ivars(dev);
+ if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
+ MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5706C) {
+ /*
+ * Broadcom uses the same MII model ID on two
+ * different types of phys. The first is found on the
+ * BCM 5706 and is supported by this driver. The
+ * other is found on the BCM 5706S and 5708S and is
+ * supported by the gentbi(4) driver, so we check to
+ * see if this phy is supported by gentbi(4) and fail
+ * the probe if so.
+ */
+ if (bcm5706_is_tbi(dev))
+ return (ENXIO);
+ }
+ return (error);
}
static int
@@ -488,6 +511,34 @@ brgphy_loop(struct mii_softc *sc)
}
}
+/*
+ * Check to see if a 5706 phy is really a SerDes phy. Copied from
+ * gentbi_probe().
+ */
+static int
+bcm5706_is_tbi(device_t dev)
+{
+ device_t parent;
+ struct mii_attach_args *ma;
+ int bmsr, extsr;
+
+ parent = device_get_parent(dev);
+ ma = device_get_ivars(dev);
+
+ bmsr = MIIBUS_READREG(parent, ma->mii_phyno, MII_BMSR);
+ if ((bmsr & BMSR_EXTSTAT) == 0 || (bmsr & BMSR_MEDIAMASK) != 0)
+ return (0);
+
+ extsr = MIIBUS_READREG(parent, ma->mii_phyno, MII_EXTSR);
+ if (extsr & (EXTSR_1000TFDX|EXTSR_1000THDX))
+ return (0);
+
+ if (extsr & (EXTSR_1000XFDX|EXTSR_1000XHDX))
+ return (1);
+
+ return (0);
+}
+
/* Turn off tap power management on 5401. */
static void
bcm5401_load_dspcode(struct mii_softc *sc)
OpenPOWER on IntegriCloud