diff options
author | Jason Wright <jason@cvs.openbsd.org> | 1999-12-07 22:01:34 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 1999-12-07 22:01:34 +0000 |
commit | 90108b38f19fc6ca669c2296a3d74500d8818a39 (patch) | |
tree | 675bda7203b288a18e60016c22f6e3e78ac90114 /sys/dev/mii/mii_physubr.c | |
parent | 703694a5279961334bfedfce9c01810442e3cd2f (diff) |
Merge with NetBSD:
o move common support functions for phy drivers from mii.c to mii_physubr.c,
so that they are not includes if no PHY is configured
o Clean up the code that adds media a little, and make media selection
table-driven in preparation for some other changes to be made.
o Don't add any loopback versions of media, for now.
o Add mii_down(), which is used by MAC drivers to inform PHYs that the
interface is now down. PHYs use this to cancel pending asynchronous
operations.
o Add OUI for Enable Semiconductor.
o New Driver for TDK TSC78Q2120 PHY
Diffstat (limited to 'sys/dev/mii/mii_physubr.c')
-rw-r--r-- | sys/dev/mii/mii_physubr.c | 112 |
1 files changed, 106 insertions, 6 deletions
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c index dc8a0ba0b56..3aecb15f884 100644 --- a/sys/dev/mii/mii_physubr.c +++ b/sys/dev/mii/mii_physubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mii_physubr.c,v 1.2 1999/07/16 14:59:07 jason Exp $ */ +/* $OpenBSD: mii_physubr.c,v 1.3 1999/12/07 22:01:31 jason Exp $ */ /* $NetBSD: mii_physubr.c,v 1.2.6.1 1999/04/23 15:40:26 perry Exp $ */ /*- @@ -55,8 +55,47 @@ #include <dev/mii/mii.h> #include <dev/mii/miivar.h> +/* + * Media to register setting conversion table. Order matters. + */ +const struct mii_media mii_media_table[] = { + { BMCR_ISO, ANAR_CSMA }, /* None */ + { 0, ANAR_CSMA|ANAR_10 }, /* 10baseT */ + { BMCR_FDX, ANAR_CSMA|ANAR_10_FD }, /* 10baseT-FDX */ + { BMCR_S100, ANAR_CSMA|ANAR_T4 }, /* 100baseT4 */ + { BMCR_S100, ANAR_CSMA|ANAR_TX }, /* 100baseTX */ + { BMCR_S100|BMCR_FDX, ANAR_CSMA|ANAR_TX_FD }, /* 100baseTX-FDX */ +}; + void mii_phy_auto_timeout __P((void *)); +void +mii_phy_setmedia(sc) + struct mii_softc *sc; +{ + struct mii_data*mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; + int bmcr, anar; + + /* + * Table index is stored in the media entry. + */ + +#ifdef DIAGNOSTIC + if (ife->ifm_data < 0 || ife->ifm_data >= MII_NMEDIA) + panic("mii_phy_setmedia"); +#endif + + anar = mii_media_table[ife->ifm_data].mm_anar; + bmcr = mii_media_table[ife->ifm_data].mm_bmcr; + + if (ife->ifm_media & IFM_LOOP) + bmcr |= BMCR_LOOP; + + PHY_WRITE(sc, MII_ANAR, anar); + PHY_WRITE(sc, MII_BMCR, bmcr); +} + int mii_phy_auto(mii, waitfor) struct mii_softc *mii; @@ -112,11 +151,6 @@ mii_phy_auto_timeout(arg) s = splnet(); mii->mii_flags &= ~MIIF_DOINGAUTO; bmsr = PHY_READ(mii, MII_BMSR); -#if 0 - if ((bmsr & BMSR_ACOMP) == 0) - printf("%s: autonegotiation failed to complete\n", - sc->sc_dev.dv_xname); -#endif /* Update the media status. */ (void) (*mii->mii_service)(mii, mii->mii_pdata, MII_POLLSTAT); @@ -146,3 +180,69 @@ mii_phy_reset(mii) if (mii->mii_inst != 0 && ((mii->mii_flags & MIIF_NOISOLATE) == 0)) PHY_WRITE(mii, MII_BMCR, reg | BMCR_ISO); } +void +mii_phy_down(sc) + struct mii_softc *sc; +{ + if (sc->mii_flags & MIIF_DOINGAUTO) { + sc->mii_flags &= ~MIIF_DOINGAUTO; + untimeout(mii_phy_auto_timeout, sc); + } +} + +/* + * Initialize generic PHY media based on BMSR, called when a PHY is + * attached. We expect to be set up to print a comma-separated list + * of media names. Does not print a newline. + */ +void +mii_add_media(sc) + struct mii_softc *sc; +{ + struct mii_data *mii = sc->mii_pdata; + +#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) + + if ((sc->mii_flags & MIIF_NOISOLATE) == 0) + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), + MII_MEDIA_NONE); + + if (sc->mii_capabilities & BMSR_10THDX) { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), + MII_MEDIA_10_T); +#if 0 + if ((sc->mii_flags & MIIF_NOLOOP) == 0) + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_LOOP, + sc->mii_inst), MII_MEDIA_10_T); +#endif + } + + if (sc->mii_capabilities & BMSR_10TFDX) + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), + MII_MEDIA_10_T_FDX); + if (sc->mii_capabilities & BMSR_100TXHDX) { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), + MII_MEDIA_100_TX); +#if 0 + if ((sc->mii_flags & MIIF_NOLOOP) == 0) + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, IFM_LOOP, + sc->mii_inst), MII_MEDIA_100_T4); +#endif + } + if (sc->mii_capabilities & BMSR_100TXFDX) + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), + MII_MEDIA_100_TX_FDX); + if (sc->mii_capabilities & BMSR_100T4) { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, sc->mii_inst), + MII_MEDIA_100_T4); +#if 0 + if ((sc->mii_flags & MIIF_NOLOOP) == 0) + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, IFM_LOOP, + sc->mii_inst), MII_MEDIA_100_T4); +#endif + } + if (sc->mii_capabilities & BMSR_ANEG) + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), + MII_NMEDIA); /* intentionally invalid index */ +#undef ADD +} |