diff options
author | marius <marius@FreeBSD.org> | 2010-11-22 22:03:11 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2010-11-22 22:03:11 +0000 |
commit | 288ac40397a78caa9cf36871dd109a096b0e0bfd (patch) | |
tree | 853b7c903cdafbabdb6232f816994b6ed62b0a2f /sys/dev/mii | |
parent | 858709918c5cced64cb6e5a0c4fbb6dcfb86a95e (diff) | |
download | FreeBSD-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/mii')
-rw-r--r-- | sys/dev/mii/bmtphy.c | 62 | ||||
-rw-r--r-- | sys/dev/mii/miidevs | 2 |
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 |