summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2010-11-22 22:03:11 +0000
committermarius <marius@FreeBSD.org>2010-11-22 22:03:11 +0000
commit288ac40397a78caa9cf36871dd109a096b0e0bfd (patch)
tree853b7c903cdafbabdb6232f816994b6ed62b0a2f /sys/dev
parent858709918c5cced64cb6e5a0c4fbb6dcfb86a95e (diff)
downloadFreeBSD-src-288ac40397a78caa9cf36871dd109a096b0e0bfd.zip
FreeBSD-src-288ac40397a78caa9cf36871dd109a096b0e0bfd.tar.gz
- Also probe BCM5214 and BCM5222.
- Add some DSP init code for BCM5221. The values derived from Apple's GMAC driver and the same init code also exists in Linux's sungem_phy driver. - Only read media status bits when they are valid. Obtained from: NetBSD, OpenBSD
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/mii/bmtphy.c62
-rw-r--r--sys/dev/mii/miidevs2
2 files changed, 53 insertions, 11 deletions
diff --git a/sys/dev/mii/bmtphy.c b/sys/dev/mii/bmtphy.c
index 9d1225a..6f53349 100644
--- a/sys/dev/mii/bmtphy.c
+++ b/sys/dev/mii/bmtphy.c
@@ -85,6 +85,11 @@ __FBSDID("$FreeBSD$");
static int bmtphy_probe(device_t);
static int bmtphy_attach(device_t);
+struct bmtphy_softc {
+ struct mii_softc mii_sc;
+ int mii_model;
+};
+
static device_method_t bmtphy_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bmtphy_probe),
@@ -100,18 +105,21 @@ static devclass_t bmtphy_devclass;
static driver_t bmtphy_driver = {
"bmtphy",
bmtphy_methods,
- sizeof(struct mii_softc)
+ sizeof(struct bmtphy_softc)
};
DRIVER_MODULE(bmtphy, miibus, bmtphy_driver, bmtphy_devclass, 0, 0);
static int bmtphy_service(struct mii_softc *, struct mii_data *, int);
static void bmtphy_status(struct mii_softc *);
+static void bmtphy_reset(struct mii_softc *);
static const struct mii_phydesc bmtphys_dp[] = {
MII_PHY_DESC(BROADCOM, BCM4401),
MII_PHY_DESC(BROADCOM, BCM5201),
+ MII_PHY_DESC(BROADCOM, BCM5214),
MII_PHY_DESC(BROADCOM, BCM5221),
+ MII_PHY_DESC(BROADCOM, BCM5222),
MII_PHY_END
};
@@ -137,11 +145,13 @@ bmtphy_probe(device_t dev)
static int
bmtphy_attach(device_t dev)
{
- struct mii_softc *sc;
- struct mii_attach_args *ma;
- struct mii_data *mii;
+ struct bmtphy_softc *bsc;
+ struct mii_softc *sc;
+ struct mii_attach_args *ma;
+ struct mii_data *mii;
- sc = device_get_softc(dev);
+ bsc = device_get_softc(dev);
+ sc = &bsc->mii_sc;
ma = device_get_ivars(dev);
sc->mii_dev = device_get_parent(dev);
mii = ma->mii_data;
@@ -155,7 +165,9 @@ bmtphy_attach(device_t dev)
sc->mii_flags |= MIIF_NOMANPAUSE;
- mii_phy_reset(sc);
+ bsc->mii_model = MII_MODEL(ma->mii_id2);
+
+ bmtphy_reset(sc);
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
device_printf(dev, " ");
@@ -196,16 +208,15 @@ bmtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
/* Callback if something changed. */
mii_phy_update(sc, cmd);
-
return (0);
}
static void
bmtphy_status(struct mii_softc *sc)
{
- struct mii_data *mii;
- struct ifmedia_entry *ife;
- int bmsr, bmcr, aux_csr;
+ struct mii_data *mii;
+ struct ifmedia_entry *ife;
+ int bmsr, bmcr, aux_csr;
mii = sc->mii_pdata;
ife = mii->mii_media.ifm_cur;
@@ -214,7 +225,6 @@ bmtphy_status(struct mii_softc *sc)
mii->mii_media_active = IFM_ETHER;
bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
- aux_csr = PHY_READ(sc, MII_BMTPHY_AUX_CSR);
if (bmsr & BMSR_LINK)
mii->mii_media_status |= IFM_ACTIVE;
@@ -240,6 +250,7 @@ bmtphy_status(struct mii_softc *sc)
return;
}
+ aux_csr = PHY_READ(sc, MII_BMTPHY_AUX_CSR);
if (aux_csr & AUX_CSR_SPEED)
mii->mii_media_active |= IFM_100_TX;
else
@@ -252,3 +263,32 @@ bmtphy_status(struct mii_softc *sc)
} else
mii->mii_media_active = ife->ifm_media;
}
+
+static void
+bmtphy_reset(struct mii_softc *sc)
+{
+ struct bmtphy_softc *bsc;
+ u_int16_t data;
+
+ bsc = (struct bmtphy_softc *)sc;
+
+ mii_phy_reset(sc);
+
+ if (bsc->mii_model == MII_MODEL_BROADCOM_BCM5221) {
+ /* Enable shadow register mode. */
+ data = PHY_READ(sc, 0x1f);
+ PHY_WRITE(sc, 0x1f, data | 0x0080);
+
+ /* Enable APD (Auto PowerDetect). */
+ data = PHY_READ(sc, MII_BMTPHY_AUX2);
+ PHY_WRITE(sc, MII_BMTPHY_AUX2, data | 0x0020);
+
+ /* Enable clocks across APD for Auto-MDIX functionality. */
+ data = PHY_READ(sc, MII_BMTPHY_INTR);
+ PHY_WRITE(sc, MII_BMTPHY_INTR, data | 0x0004);
+
+ /* Disable shadow register mode. */
+ data = PHY_READ(sc, 0x1f);
+ PHY_WRITE(sc, 0x1f, data & ~0x0080);
+ }
+}
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index ec0b846..24cd551 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -128,7 +128,9 @@ model ATHEROS F1_7 0x0007 Atheros F1 10/100/1000 PHY
model BROADCOM 3C905B 0x0012 3c905B 10/100 internal PHY
model BROADCOM 3C905C 0x0017 3c905C 10/100 internal PHY
model BROADCOM BCM5201 0x0021 BCM5201 10/100baseTX PHY
+model BROADCOM BCM5214 0x0028 BCM5214 Quad 10/100 PHY
model BROADCOM BCM5221 0x001e BCM5221 10/100baseTX PHY
+model BROADCOM BCM5222 0x0032 BCM5222 Dual 10/100 PHY
model BROADCOM BCM4401 0x0036 BCM4401 10/100baseTX PHY
model xxBROADCOM BCM5400 0x0004 Broadcom 1000baseTX PHY
model xxBROADCOM BCM5401 0x0005 BCM5401 10/100/1000baseTX PHY
OpenPOWER on IntegriCloud