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 | |
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')
-rw-r--r-- | sys/dev/mii/exphy.c | 42 | ||||
-rw-r--r-- | sys/dev/mii/files.mii | 6 | ||||
-rw-r--r-- | sys/dev/mii/icsphy.c | 48 | ||||
-rw-r--r-- | sys/dev/mii/inphy.c | 44 | ||||
-rw-r--r-- | sys/dev/mii/iophy.c | 37 | ||||
-rw-r--r-- | sys/dev/mii/lxtphy.c | 48 | ||||
-rw-r--r-- | sys/dev/mii/mii.c | 112 | ||||
-rw-r--r-- | sys/dev/mii/mii_physubr.c | 112 | ||||
-rw-r--r-- | sys/dev/mii/miidevs | 63 | ||||
-rw-r--r-- | sys/dev/mii/miivar.h | 35 | ||||
-rw-r--r-- | sys/dev/mii/mtdphy.c | 42 | ||||
-rw-r--r-- | sys/dev/mii/nsphy.c | 63 | ||||
-rw-r--r-- | sys/dev/mii/qsphy.c | 42 | ||||
-rw-r--r-- | sys/dev/mii/rlphy.c | 28 | ||||
-rw-r--r-- | sys/dev/mii/sqphy.c | 48 | ||||
-rw-r--r-- | sys/dev/mii/tlphy.c | 57 | ||||
-rw-r--r-- | sys/dev/mii/tqphy.c | 305 | ||||
-rw-r--r-- | sys/dev/mii/tqphyreg.h | 94 | ||||
-rw-r--r-- | sys/dev/mii/ukphy.c | 41 | ||||
-rw-r--r-- | sys/dev/mii/ukphy_subr.c | 5 |
20 files changed, 706 insertions, 566 deletions
diff --git a/sys/dev/mii/exphy.c b/sys/dev/mii/exphy.c index f29a3c1fdb2..3ba7b351c10 100644 --- a/sys/dev/mii/exphy.c +++ b/sys/dev/mii/exphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exphy.c,v 1.5 1999/09/26 17:50:41 jason Exp $ */ +/* $OpenBSD: exphy.c,v 1.6 1999/12/07 22:01:28 jason Exp $ */ /* $NetBSD: exphy.c,v 1.15.6.1 1999/04/23 15:39:33 perry Exp $ */ /*- @@ -85,22 +85,16 @@ #include <dev/mii/miivar.h> #include <dev/mii/miidevs.h> -#ifdef __NetBSD__ -int exphymatch __P((struct device *, struct cfdata *, void *)); -#else int exphymatch __P((struct device *, void *, void *)); -#endif void exphyattach __P((struct device *, struct device *, void *)); struct cfattach exphy_ca = { sizeof(struct mii_softc), exphymatch, exphyattach }; -#ifdef __OpenBSD__ struct cfdriver exphy_cd = { NULL, "exphy", DV_DULL }; -#endif int exphy_service __P((struct mii_softc *, struct mii_data *, int)); void exphy_reset __P((struct mii_softc *)); @@ -108,11 +102,7 @@ void exphy_reset __P((struct mii_softc *)); int exphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { struct mii_attach_args *ma = aux; @@ -160,24 +150,12 @@ exphyattach(parent, self, aux) } sc->mii_flags |= MIIF_NOISOLATE; -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - -#if 0 /* See above. */ - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO); -#endif - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); - exphy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -214,18 +192,8 @@ exphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -247,6 +215,10 @@ exphy_service(sc, mii, cmd) * kicked; it continues in the background. */ break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ diff --git a/sys/dev/mii/files.mii b/sys/dev/mii/files.mii index 1cfb0418495..44aea8f9701 100644 --- a/sys/dev/mii/files.mii +++ b/sys/dev/mii/files.mii @@ -1,4 +1,4 @@ -# $OpenBSD: files.mii,v 1.5 1999/10/12 16:59:29 jason Exp $ +# $OpenBSD: files.mii,v 1.6 1999/12/07 22:01:29 jason Exp $ # $NetBSD: files.mii,v 1.13 1998/11/05 00:36:48 thorpej Exp $ file dev/mii/mii.c mii @@ -53,6 +53,10 @@ device sqphy: mii_phy attach sqphy at mii file dev/mii/sqphy.c sqphy +device tqphy: mii_phy +attach tqphy at mii +file dev/mii/tqphy.c tqphy + device ukphy: mii_phy, ukphy_subr attach ukphy at mii file dev/mii/ukphy.c ukphy diff --git a/sys/dev/mii/icsphy.c b/sys/dev/mii/icsphy.c index f5feaafcff1..f349c0af6c7 100644 --- a/sys/dev/mii/icsphy.c +++ b/sys/dev/mii/icsphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icsphy.c,v 1.4 1999/09/07 10:05:15 niklas Exp $ */ +/* $OpenBSD: icsphy.c,v 1.5 1999/12/07 22:01:30 jason Exp $ */ /* $NetBSD: icsphy.c,v 1.8.6.1 1999/04/23 15:40:56 perry Exp $ */ /*- @@ -88,11 +88,7 @@ #include <dev/mii/icsphyreg.h> -#ifdef __NetBSD__ -int icsphymatch __P((struct device *, struct cfdata *, void *)); -#else int icsphymatch __P((struct device *, void *, void *)); -#endif void icsphyattach __P((struct device *, struct device *, void *)); int icsphydetach __P((struct device *, int)); @@ -100,11 +96,9 @@ struct cfattach icsphy_ca = { sizeof(struct mii_softc), icsphymatch, icsphyattach, icsphydetach }; -#ifdef __OpenBSD__ struct cfdriver icsphy_cd = { NULL, "icsphy", DV_DULL }; -#endif int icsphy_service __P((struct mii_softc *, struct mii_data *, int)); void icsphy_reset __P((struct mii_softc *)); @@ -113,17 +107,13 @@ void icsphy_status __P((struct mii_softc *)); int icsphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { struct mii_attach_args *ma = aux; - if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_ICS && - MII_MODEL(ma->mii_id2) == MII_MODEL_ICS_1890) + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxICS && + MII_MODEL(ma->mii_id2) == MII_MODEL_xxICS_1890) return (10); return (0); @@ -138,7 +128,7 @@ icsphyattach(parent, self, aux) struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; - printf(": %s, rev. %d\n", MII_STR_ICS_1890, + printf(": %s, rev. %d\n", MII_STR_xxICS_1890, MII_REV(ma->mii_id2)); sc->mii_inst = mii->mii_instance; @@ -146,21 +136,12 @@ icsphyattach(parent, self, aux) sc->mii_service = icsphy_service; sc->mii_pdata = mii; -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); - icsphy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -215,18 +196,8 @@ icsphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -254,6 +225,10 @@ icsphy_service(sc, mii, cmd) * kicked; it continues in the background. */ break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ @@ -272,6 +247,7 @@ icsphy_status(sc) struct mii_softc *sc; { struct mii_data *mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmcr, qpr; mii->mii_media_status = IFM_AVALID; @@ -311,7 +287,7 @@ icsphy_status(sc) if (qpr & QPR_FDX) mii->mii_media_active |= IFM_FDX; } else - mii->mii_media_active = mii_media_from_bmcr(bmcr); + mii->mii_media_active = ife->ifm_media; } void diff --git a/sys/dev/mii/inphy.c b/sys/dev/mii/inphy.c index 0f07f41fe44..938e283f04b 100644 --- a/sys/dev/mii/inphy.c +++ b/sys/dev/mii/inphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inphy.c,v 1.4 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: inphy.c,v 1.5 1999/12/07 22:01:30 jason Exp $ */ /* $NetBSD: inphy.c,v 1.10.6.1 1999/04/23 15:39:09 perry Exp $ */ /*- @@ -89,22 +89,16 @@ #include <dev/mii/inphyreg.h> -#ifdef __NetBSD__ -int inphymatch __P((struct device *, struct cfdata *, void *)); -#else int inphymatch __P((struct device *, void *, void *)); -#endif void inphyattach __P((struct device *, struct device *, void *)); struct cfattach inphy_ca = { sizeof(struct mii_softc), inphymatch, inphyattach }; -#ifdef __OpenBSD__ struct cfdriver inphy_cd = { NULL, "inphy", DV_DULL }; -#endif int inphy_service __P((struct mii_softc *, struct mii_data *, int)); void inphy_status __P((struct mii_softc *)); @@ -112,11 +106,7 @@ void inphy_status __P((struct mii_softc *)); int inphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { struct mii_attach_args *ma = aux; @@ -152,23 +142,12 @@ inphyattach(parent, self, aux) mii->mii_instance == 0) sc->mii_flags |= MIIF_NOISOLATE; -#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), - BMCR_ISO); - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); - mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -215,18 +194,8 @@ inphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -270,6 +239,10 @@ inphy_service(sc, mii, cmd) if (mii_phy_auto(sc, 0) == EJUSTRETURN) return (0); break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ @@ -288,6 +261,7 @@ inphy_status(sc) struct mii_softc *sc; { struct mii_data *mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmsr, bmcr, scr; mii->mii_media_status = IFM_AVALID; @@ -324,5 +298,5 @@ inphy_status(sc) if (scr & SCR_FDX) mii->mii_media_active |= IFM_FDX; } else - mii->mii_media_active = mii_media_from_bmcr(bmcr); + mii->mii_media_active = ife->ifm_media; } diff --git a/sys/dev/mii/iophy.c b/sys/dev/mii/iophy.c index b5f24843b6b..fe5247da650 100644 --- a/sys/dev/mii/iophy.c +++ b/sys/dev/mii/iophy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iophy.c,v 1.4 1999/11/25 19:35:27 deraadt Exp $ */ +/* $OpenBSD: iophy.c,v 1.5 1999/12/07 22:01:30 jason Exp $ */ /* $NetBSD: iophy.c,v 1.1 1999/09/05 00:40:27 soren Exp $ */ /* @@ -109,8 +109,8 @@ iophymatch(parent, match, aux) { struct mii_attach_args *ma = aux; - if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_INTEL_ALT && - MII_MODEL(ma->mii_id2) == MII_MODEL_INTEL_ALT_I82553) + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxINTEL && + MII_MODEL(ma->mii_id2) == MII_MODEL_xxINTEL_I82553) return (10); if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_INTEL && @@ -144,27 +144,12 @@ iophyattach(parent, self, aux) mii->mii_instance == 0) sc->mii_flags |= MIIF_NOISOLATE; -#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), - BMCR_ISO); - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), - BMCR_ISO); -#if 0 - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); -#endif - mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -212,12 +197,7 @@ iophy_service(sc, mii, cmd) (void) mii_phy_auto(sc, 1); break; default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -261,6 +241,10 @@ iophy_service(sc, mii, cmd) if (mii_phy_auto(sc, 0) == EJUSTRETURN) return (0); break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ @@ -279,6 +263,7 @@ iophy_status(sc) struct mii_softc *sc; { struct mii_data *mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmsr, bmcr, ext0; mii->mii_media_status = IFM_AVALID; @@ -321,5 +306,5 @@ iophy_status(sc) if (ext0 & EXT0_DUPLEX) mii->mii_media_active |= IFM_FDX; } else - mii->mii_media_active = mii_media_from_bmcr(bmcr); + mii->mii_media_active = ife->ifm_media; } diff --git a/sys/dev/mii/lxtphy.c b/sys/dev/mii/lxtphy.c index e2cb377d8e3..5c290b39fe8 100644 --- a/sys/dev/mii/lxtphy.c +++ b/sys/dev/mii/lxtphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lxtphy.c,v 1.3 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: lxtphy.c,v 1.4 1999/12/07 22:01:31 jason Exp $ */ /* $NetBSD: lxtphy.c,v 1.9.6.1 1999/04/23 15:41:43 perry Exp $ */ /*- @@ -89,22 +89,16 @@ #include <dev/mii/lxtphyreg.h> -#ifdef __NetBSD__ -int lxtphymatch __P((struct device *, struct cfdata *, void *)); -#else int lxtphymatch __P((struct device *, void *, void *)); -#endif void lxtphyattach __P((struct device *, struct device *, void *)); struct cfattach lxtphy_ca = { sizeof(struct mii_softc), lxtphymatch, lxtphyattach }; -#ifdef __OpenBSD__ struct cfdriver lxtphy_cd = { NULL, "lxtphy", DV_DULL }; -#endif int lxtphy_service __P((struct mii_softc *, struct mii_data *, int)); void lxtphy_status __P((struct mii_softc *)); @@ -112,17 +106,13 @@ void lxtphy_status __P((struct mii_softc *)); int lxtphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { struct mii_attach_args *ma = aux; - if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_LEVEL1 && - MII_MODEL(ma->mii_id2) == MII_MODEL_LEVEL1_LXT970) + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxLEVEL1 && + MII_MODEL(ma->mii_id2) == MII_MODEL_xxLEVEL1_LXT970) return (10); return (0); @@ -137,7 +127,7 @@ lxtphyattach(parent, self, aux) struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; - printf(": %s, rev. %d\n", MII_STR_LEVEL1_LXT970, + printf(": %s, rev. %d\n", MII_STR_xxLEVEL1_LXT970, MII_REV(ma->mii_id2)); sc->mii_inst = mii->mii_instance; @@ -145,21 +135,12 @@ lxtphyattach(parent, self, aux) sc->mii_service = lxtphy_service; sc->mii_pdata = mii; -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); - mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -206,18 +187,8 @@ lxtphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -262,6 +233,10 @@ lxtphy_service(sc, mii, cmd) if (mii_phy_auto(sc, 0) == EJUSTRETURN) return (0); break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ @@ -280,6 +255,7 @@ lxtphy_status(sc) struct mii_softc *sc; { struct mii_data *mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmcr, csr; mii->mii_media_status = IFM_AVALID; @@ -317,5 +293,5 @@ lxtphy_status(sc) if (csr & CSR_DUPLEX) mii->mii_media_active |= IFM_FDX; } else - mii->mii_media_active = mii_media_from_bmcr(bmcr); + mii->mii_media_active = ife->ifm_media; } diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c index ba60852ba13..274bbcc357c 100644 --- a/sys/dev/mii/mii.c +++ b/sys/dev/mii/mii.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mii.c,v 1.5 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: mii.c,v 1.6 1999/12/07 22:01:31 jason Exp $ */ /* $NetBSD: mii.c,v 1.9 1998/11/05 04:08:02 thorpej Exp $ */ /*- @@ -56,16 +56,10 @@ #include <dev/mii/miivar.h> int mii_print __P((void *, const char *)); -#ifdef __NetBSD__ -int mii_submatch __P((struct device *, struct cfdata *, void *)); -#else int mii_submatch __P((struct device *, void *, void *)); -#endif -#ifdef __OpenBSD__ #define MIICF_PHY 0 /* cf_loc index */ #define MIICF_PHY_DEFAULT (-1) /* default phy device */ -#endif /* * Helper function used by network interface drivers, attaches PHYs @@ -139,21 +133,12 @@ mii_print(aux, pnp) return (UNCONF); } -#ifdef __NetBSD__ -int -mii_submatch(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ -#else int mii_submatch(parent, match, aux) struct device *parent; void *match, *aux; { struct cfdata *cf = match; -#endif struct mii_attach_args *ma = aux; if (ma->mii_phyno != cf->cf_loc[MIICF_PHY] && @@ -164,58 +149,6 @@ mii_submatch(parent, match, aux) } /* - * Given an ifmedia word, return the corresponding ANAR value. - */ -int -mii_anar(media) - int media; -{ - int rv; - - switch (media & (IFM_TMASK|IFM_NMASK|IFM_FDX)) { - case IFM_ETHER|IFM_10_T: - rv = ANAR_10|ANAR_CSMA; - break; - case IFM_ETHER|IFM_10_T|IFM_FDX: - rv = ANAR_10_FD|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_TX: - rv = ANAR_TX|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_TX|IFM_FDX: - rv = ANAR_TX_FD|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_T4: - rv = ANAR_T4|ANAR_CSMA; - break; - default: - rv = 0; - break; - } - - return (rv); -} - -/* - * Given a BMCR value, return the corresponding ifmedia word. - */ -int -mii_media_from_bmcr(bmcr) - int bmcr; -{ - int rv = IFM_ETHER; - - if (bmcr & BMCR_S100) - rv |= IFM_100_TX; - else - rv |= IFM_10_T; - if (bmcr & BMCR_FDX) - rv |= IFM_FDX; - - return (rv); -} - -/* * Media changed; notify all PHYs. */ int @@ -269,40 +202,15 @@ mii_pollstat(mii) } /* - * 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. + * Inform the PHYs that the interface is down. */ void -mii_add_media(mii, bmsr, instance) +mii_down(mii) struct mii_data *mii; - int bmsr, instance; -{ -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - - if (bmsr & BMSR_10THDX) - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, instance), 0); - if (bmsr & BMSR_10TFDX) - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, instance), - BMCR_FDX); - if (bmsr & BMSR_100TXHDX) - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, instance), - BMCR_S100); - if (bmsr & BMSR_100TXFDX) - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, instance), - BMCR_S100|BMCR_FDX); - if (bmsr & BMSR_100T4) { - /* - * XXX How do you enable 100baseT4? I assume we set - * XXX BMCR_S100 and then assume the PHYs will take - * XXX watever action is necessary to switch themselves - * XXX into T4 mode. - */ - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, instance), - BMCR_S100); - } - if (bmsr & BMSR_ANEG) - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, instance), - BMCR_AUTOEN); -#undef ADD -} +{ + struct mii_softc *child; + + for (child = LIST_FIRST(&mii->mii_phys); child != NULL; + child = LIST_NEXT(child, mii_list)) + (void) (*child->mii_service)(child, mii, MII_DOWN); +} 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 +} diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs index c3e660b5a18..67282b07987 100644 --- a/sys/dev/mii/miidevs +++ b/sys/dev/mii/miidevs @@ -1,4 +1,4 @@ -$OpenBSD: miidevs,v 1.6 1999/10/12 16:55:34 jason Exp $ +$OpenBSD: miidevs,v 1.7 1999/12/07 22:01:31 jason Exp $ /* $NetBSD: miidevs,v 1.3 1998/11/05 03:43:43 thorpej Exp $ */ /*- @@ -42,39 +42,60 @@ $OpenBSD: miidevs,v 1.6 1999/10/12 16:55:34 jason Exp $ * List of known MII OUIs */ -oui AMD 0x00606e Advanced Micro Devices -oui DAVICOM 0x006040 Davicom Semiconductor -oui ICS 0x00057d Integrated Circuit Systems +oui AMD 0x00001a Advanced Micro Devices +oui ENABLESEMI 0x0010dd Enable Semiconductor +oui DAVICOM 0x00606e Davicom Semiconductor +oui ICS 0x00a0be Integrated Circuit Systems oui INTEL 0x00aa00 Intel -oui INTEL_ALT 0x00f800 Intel (alt) -oui LEVEL1 0x1e0400 Level 1 +oui LEVEL1 0x00207b Level 1 oui MYSON 0x00c0b4 Myson Technology oui NATSEMI 0x080017 National Semiconductor oui QUALSEMI 0x006051 Quality Semiconductor -oui SEEQ 0x0005be Seeq -oui SIS 0x000760 Silicon Integrated Systems -oui TI 0x100014 Texas Instruments +oui SEEQ 0x00a07d Seeq +oui SIS 0x00e006 Silicon Integrated Systems +oui TI 0x080028 Texas Instruments +oui TSC 0x00c039 TDK Semiconductor + +/* in the 79c873, AMD uses another OUI (which matches Davicom!) */ +oui xxAMD 0x00606e Advanced Micro Devices + +oui xxINTEL 0x00f800 Intel (alt) + +/* some vendors have the bits swapped within bytes + (ie, ordered as on the wire) */ +oui xxICS 0x00057d Integrated Circuit Systems +oui xxSEEQ 0x0005be Seeq +oui xxSIS 0x000760 Silicon Integrated Systems +oui xxTI 0x100014 Texas Instruments + +/* Level 1 is completely different - from right to left. + (Two bits get lost in the third OUI byte.) */ +oui xxLEVEL1 0x1e0400 Level 1 + +/* Don't know what's going on here. */ +oui xxDAVICOM 0x006040 Davicom Semiconductor /* * List of known models. Grouped by oui. */ /* Advanced Micro Devices PHYs */ -model AMD 79C873 0x0000 Am79C873 10/100 media interface +model xxAMD 79C873 0x0000 Am79C873 10/100 media interface +model AMD 79C873phy 0x0036 Am79C873 internal PHY /* Davicom Semiconductor PHYs */ -model DAVICOM DM9101 0x0000 DM9101 10/100 media interface +model xxDAVICOM DM9101 0x0000 DM9101 10/100 media interface /* Integrated Circuit Systems PHYs */ -model ICS 1890 0x0002 ICS1890 10/100 media interface +model xxICS 1890 0x0002 ICS1890 10/100 media interface /* Intel PHYs */ +model xxINTEL I82553 0x0000 i82553 10/100 media interface model INTEL I82555 0x0015 i82555 10/100 media interface model INTEL I82553 0x0035 i82553 10/100 media interface -model INTEL_ALT I82553 0x0000 i82553 10/100 media interface /* Level 1 PHYs */ -model LEVEL1 LXT970 0x0000 LXT970 10/100 media interface +model xxLEVEL1 LXT970 0x0000 LXT970 10/100 media interface /* Myson Technology PHYs */ model MYSON MTD972 0x0000 MTD972 10/100 media interface @@ -87,12 +108,16 @@ model NATSEMI DP83843 0x0001 DP83843 10/100 media interface model QUALSEMI QS6612 0x0000 QS6612 10/100 media interface /* Seeq PHYs */ -model SEEQ 80220 0x0003 Seeq 80220 10/100 media interface -model SEEQ 84220 0x0004 Seeq 84220 10/100 media interface +model xxSEEQ 80220 0x0003 Seeq 80220 10/100 media interface +model xxSEEQ 84220 0x0004 Seeq 84220 10/100 media interface /* Silicon Integrated Systems PHYs */ -model SIS 900 0x0000 SiS 900 10/100 media interface +model xxSIS 900 0x0000 SiS 900 10/100 media interface /* Texas Instruments PHYs */ -model TI TLAN10T 0x0001 ThunderLAN 10baseT media interface -model TI 100VGPMI 0x0002 ThunderLAN 100VG-AnyLan media interface +model xxTI TLAN10T 0x0001 ThunderLAN 10baseT media interface +model xxTI 100VGPMI 0x0002 ThunderLAN 100VG-AnyLan media interface + +/* TDK Semiconductor PHYs */ +model TSC 78Q2120 0x0014 78Q2120 10/100 media interface +model TSC 78Q2121 0x0015 78Q2121 100baseTX media interface diff --git a/sys/dev/mii/miivar.h b/sys/dev/mii/miivar.h index e084e861bde..717d13788a0 100644 --- a/sys/dev/mii/miivar.h +++ b/sys/dev/mii/miivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: miivar.h,v 1.3 1999/07/16 14:59:07 jason Exp $ */ +/* $OpenBSD: miivar.h,v 1.4 1999/12/07 22:01:31 jason Exp $ */ /* $NetBSD: miivar.h,v 1.7.6.1 1999/04/23 15:40:35 perry Exp $ */ /*- @@ -103,6 +103,7 @@ typedef int (*mii_downcall_t) __P((struct mii_softc *, struct mii_data *, int)); #define MII_TICK 1 /* once-per-second tick */ #define MII_MEDIACHG 2 /* user changed media; perform the switch */ #define MII_POLLSTAT 3 /* user requested media status; fill it in */ +#define MII_DOWN 4 /* interface is down */ /* * Each PHY driver's softc has one of these as the first member. @@ -128,8 +129,12 @@ struct mii_softc { typedef struct mii_softc mii_softc_t; /* mii_flags */ -#define MIIF_NOISOLATE 0x0001 /* do not isolate the PHY */ -#define MIIF_DOINGAUTO 0x0002 /* doing autonegotiation */ +#define MIIF_INITDONE 0x0001 /* has been initialized (mii_data) */ +#define MIIF_NOISOLATE 0x0002 /* do not isolate the PHY */ +#define MIIF_NOLOOP 0x0004 /* no loopback capability */ +#define MIIF_DOINGAUTO 0x0008 /* doing autonegotiation (mii_softc) */ + +#define MIIF_INHERIT_MASK (MIIF_NOISOLATE|MIIF_NOLOOP) /* * Used to attach a PHY to a parent. @@ -143,6 +148,22 @@ struct mii_attach_args { }; typedef struct mii_attach_args mii_attach_args_t; +/* + * An array of these structures map MII media types to BMCR/ANAR settings. + */ +struct mii_media { + int mm_bmcr; /* BMCR settings for this media */ + int mm_anar; /* ANAR settings for this media */ +}; + +#define MII_MEDIA_NONE 0 +#define MII_MEDIA_10_T 1 +#define MII_MEDIA_10_T_FDX 2 +#define MII_MEDIA_100_T4 3 +#define MII_MEDIA_100_TX 4 +#define MII_MEDIA_100_TX_FDX 5 +#define MII_NMEDIA 6 + #ifdef _KERNEL #define PHY_READ(p, r) \ @@ -153,17 +174,17 @@ typedef struct mii_attach_args mii_attach_args_t; (*(p)->mii_pdata->mii_writereg)((p)->mii_dev.dv_parent, \ (p)->mii_phy, (r), (v)) -int mii_anar __P((int)); int mii_mediachg __P((struct mii_data *)); void mii_tick __P((struct mii_data *)); void mii_pollstat __P((struct mii_data *)); +void mii_down __P((struct mii_data *)); void mii_phy_probe __P((struct device *, struct mii_data *, int)); -void mii_add_media __P((struct mii_data *, int, int)); - -int mii_media_from_bmcr __P((int)); +void mii_add_media __P((struct mii_softc *)); +void mii_phy_setmedia __P((struct mii_softc *)); int mii_phy_auto __P((struct mii_softc *, int)); void mii_phy_reset __P((struct mii_softc *)); +void mii_phy_down __P((struct mii_softc *)); void ukphy_status __P((struct mii_softc *)); #endif /* _KERNEL */ diff --git a/sys/dev/mii/mtdphy.c b/sys/dev/mii/mtdphy.c index cff80b3d69e..67086f5d24c 100644 --- a/sys/dev/mii/mtdphy.c +++ b/sys/dev/mii/mtdphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mtdphy.c,v 1.3 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: mtdphy.c,v 1.4 1999/12/07 22:01:31 jason Exp $ */ /* * Copyright (c) 1998, 1999 Jason L. Wright (jason@thought.net) @@ -95,20 +95,12 @@ mtdphyattach(parent, self, aux) sc->mii_service = mtdphy_service; sc->mii_pdata = mii; - ifmedia_add(&mii->mii_media, - IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO, NULL); - ifmedia_add(&mii->mii_media, - IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP | BMCR_S100, NULL); - mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); + mii_add_media(sc); } int @@ -152,32 +144,8 @@ mtdphy_service(sc, mii, cmd) (void) mii_phy_auto(sc, 1); break; - case IFM_100_TX: - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - - reg = BMCR_ISO | BMCR_S100; - if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) - reg |= BMCR_FDX; - PHY_WRITE(sc, MII_BMCR, reg); - delay(75000); - - reg &= ~BMCR_ISO; - PHY_WRITE(sc, MII_BMCR, reg); - break; - - case IFM_100_T4: - /* - * Not supported by MTD972. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -205,6 +173,10 @@ mtdphy_service(sc, mii, cmd) * kicked; it continues in the background. */ break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ diff --git a/sys/dev/mii/nsphy.c b/sys/dev/mii/nsphy.c index aa6241e0cde..7debd74e6f3 100644 --- a/sys/dev/mii/nsphy.c +++ b/sys/dev/mii/nsphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nsphy.c,v 1.6 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: nsphy.c,v 1.7 1999/12/07 22:01:32 jason Exp $ */ /* $NetBSD: nsphy.c,v 1.18 1999/07/14 23:57:36 thorpej Exp $ */ /*- @@ -89,22 +89,16 @@ #include <dev/mii/nsphyreg.h> -#ifdef __NetBSD__ -int nsphymatch __P((struct device *, struct cfdata *, void *)); -#else int nsphymatch __P((struct device *, void *, void *)); -#endif void nsphyattach __P((struct device *, struct device *, void *)); struct cfattach nsphy_ca = { sizeof(struct mii_softc), nsphymatch, nsphyattach }; -#ifdef __OpenBSD__ struct cfdriver nsphy_cd = { NULL, "nsphy", DV_DULL }; -#endif int nsphy_service __P((struct mii_softc *, struct mii_data *, int)); void nsphy_status __P((struct mii_softc *)); @@ -113,11 +107,7 @@ void nsphy_reset __P((struct mii_softc *)); int nsphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { struct mii_attach_args *ma = aux; @@ -154,24 +144,12 @@ nsphyattach(parent, self, aux) mii->mii_instance == 0) sc->mii_flags |= MIIF_NOISOLATE; -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - -#if 0 - /* Can't do this on the i82557! */ - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO); -#endif - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); - nsphy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -251,36 +229,8 @@ nsphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); - case IFM_100_TX: - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - - reg = 0; - reg |= BMCR_S100; - if ((sc->mii_flags & MIIF_NOISOLATE) == 0) - reg |= BMCR_ISO; - - if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) - reg |= BMCR_FDX; - PHY_WRITE(sc, MII_BMCR, reg); - delay(1000000); /* XXX too long, will adjust */ - - reg &= ~BMCR_ISO; - PHY_WRITE(sc, MII_BMCR, reg); - break; - default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -324,6 +274,10 @@ nsphy_service(sc, mii, cmd) if (mii_phy_auto(sc, 0) == EJUSTRETURN) return (0); break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ @@ -342,6 +296,7 @@ nsphy_status(sc) struct mii_softc *sc; { struct mii_data *mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmsr, bmcr, par, anlpar; mii->mii_media_status = IFM_AVALID; @@ -411,7 +366,7 @@ nsphy_status(sc) mii->mii_media_active |= IFM_FDX; #endif } else - mii->mii_media_active = mii_media_from_bmcr(bmcr); + mii->mii_media_active = ife->ifm_media; } void diff --git a/sys/dev/mii/qsphy.c b/sys/dev/mii/qsphy.c index 5305cdabfcb..8bc841649a8 100644 --- a/sys/dev/mii/qsphy.c +++ b/sys/dev/mii/qsphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qsphy.c,v 1.4 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: qsphy.c,v 1.5 1999/12/07 22:01:32 jason Exp $ */ /* $NetBSD: qsphy.c,v 1.11.6.1 1999/04/23 15:39:21 perry Exp $ */ /*- @@ -88,22 +88,16 @@ #include <dev/mii/qsphyreg.h> -#ifdef __NetBSD__ -int qsphymatch __P((struct device *, struct cfdata *, void *)); -#else int qsphymatch __P((struct device *, void *, void *)); -#endif void qsphyattach __P((struct device *, struct device *, void *)); struct cfattach qsphy_ca = { sizeof(struct mii_softc), qsphymatch, qsphyattach }; -#ifdef __OpenBSD__ struct cfdriver qsphy_cd = { NULL, "qsphy", DV_DULL }; -#endif int qsphy_service __P((struct mii_softc *, struct mii_data *, int)); void qsphy_reset __P((struct mii_softc *)); @@ -112,11 +106,7 @@ void qsphy_status __P((struct mii_softc *)); int qsphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { struct mii_attach_args *ma = aux; @@ -145,21 +135,12 @@ qsphyattach(parent, self, aux) sc->mii_service = qsphy_service; sc->mii_pdata = mii; -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); - qsphy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -206,18 +187,8 @@ qsphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -245,6 +216,10 @@ qsphy_service(sc, mii, cmd) * kicked; it continues in the background. */ break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ @@ -263,6 +238,7 @@ qsphy_status(sc) struct mii_softc *sc; { struct mii_data *mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmsr, bmcr, pctl; mii->mii_media_status = IFM_AVALID; @@ -313,7 +289,7 @@ qsphy_status(sc) break; } } else - mii->mii_media_active = mii_media_from_bmcr(bmcr); + mii->mii_media_active = ife->ifm_media; } void diff --git a/sys/dev/mii/rlphy.c b/sys/dev/mii/rlphy.c index 5053e78d974..5fdd8ee8ffa 100644 --- a/sys/dev/mii/rlphy.c +++ b/sys/dev/mii/rlphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rlphy.c,v 1.4 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: rlphy.c,v 1.5 1999/12/07 22:01:32 jason Exp $ */ /* * Copyright (c) 1998, 1999 Jason L. Wright (jason@thought.net) @@ -104,20 +104,12 @@ rlphyattach(parent, self, aux) sc->mii_service = rlphy_service; sc->mii_pdata = mii; - ifmedia_add(&mii->mii_media, - IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO, NULL); - ifmedia_add(&mii->mii_media, - IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP | BMCR_S100, NULL); - rlphy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); + mii_add_media(sc); } int @@ -154,18 +146,8 @@ rlphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -187,6 +169,10 @@ rlphy_service(sc, mii, cmd) * kicked; it continues in the background. */ break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ diff --git a/sys/dev/mii/sqphy.c b/sys/dev/mii/sqphy.c index eac511080d0..3b13d8a5abc 100644 --- a/sys/dev/mii/sqphy.c +++ b/sys/dev/mii/sqphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sqphy.c,v 1.3 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: sqphy.c,v 1.4 1999/12/07 22:01:32 jason Exp $ */ /* $NetBSD: sqphy.c,v 1.8.6.1 1999/04/23 15:41:25 perry Exp $ */ /*- @@ -89,22 +89,16 @@ #include <dev/mii/sqphyreg.h> -#ifdef __NetBSD__ -int sqphymatch __P((struct device *, struct cfdata *, void *)); -#else int sqphymatch __P((struct device *, void *, void *)); -#endif void sqphyattach __P((struct device *, struct device *, void *)); struct cfattach sqphy_ca = { sizeof(struct mii_softc), sqphymatch, sqphyattach }; -#ifdef __OpenBSD__ struct cfdriver sqphy_cd = { NULL, "sqphy", DV_DULL }; -#endif int sqphy_service __P((struct mii_softc *, struct mii_data *, int)); void sqphy_status __P((struct mii_softc *)); @@ -112,17 +106,13 @@ void sqphy_status __P((struct mii_softc *)); int sqphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { struct mii_attach_args *ma = aux; - if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_SEEQ && - MII_MODEL(ma->mii_id2) == MII_MODEL_SEEQ_80220) + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxSEEQ && + MII_MODEL(ma->mii_id2) == MII_MODEL_xxSEEQ_80220) return (10); return (0); @@ -137,7 +127,7 @@ sqphyattach(parent, self, aux) struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; - printf(": %s, rev. %d\n", MII_STR_SEEQ_80220, + printf(": %s, rev. %d\n", MII_STR_xxSEEQ_80220, MII_REV(ma->mii_id2)); sc->mii_inst = mii->mii_instance; @@ -145,21 +135,12 @@ sqphyattach(parent, self, aux) sc->mii_service = sqphy_service; sc->mii_pdata = mii; -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); - mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -206,18 +187,8 @@ sqphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -261,6 +232,10 @@ sqphy_service(sc, mii, cmd) if (mii_phy_auto(sc, 0) == EJUSTRETURN) return (0); break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ @@ -279,6 +254,7 @@ sqphy_status(sc) struct mii_softc *sc; { struct mii_data *mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmsr, bmcr, status; mii->mii_media_status = IFM_AVALID; @@ -313,5 +289,5 @@ sqphy_status(sc) if (status & STATUS_DPLX_DET) mii->mii_media_active |= IFM_FDX; } else - mii->mii_media_active = mii_media_from_bmcr(bmcr); + mii->mii_media_active = ife->ifm_media; } diff --git a/sys/dev/mii/tlphy.c b/sys/dev/mii/tlphy.c index 75b184dfb51..ce92a2d8348 100644 --- a/sys/dev/mii/tlphy.c +++ b/sys/dev/mii/tlphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tlphy.c,v 1.4 1999/07/23 12:39:11 deraadt Exp $ */ +/* $OpenBSD: tlphy.c,v 1.5 1999/12/07 22:01:32 jason Exp $ */ /* $NetBSD: tlphy.c,v 1.16.6.1 1999/04/23 15:40:13 perry Exp $ */ /*- @@ -78,25 +78,13 @@ #include <sys/socket.h> #include <sys/errno.h> -#ifdef __NetBSD__ -#include <machine/bus.h> -#endif - #include <net/if.h> #include <net/if_media.h> -#ifdef __NetBSD__ -#include <net/if_ether.h> -#endif - #include <dev/mii/mii.h> #include <dev/mii/miivar.h> #include <dev/mii/miidevs.h> -#ifdef __NetBSD__ -#include <dev/i2c/i2c_bus.h> -#endif - #include <dev/mii/tlphyreg.h> #include <dev/mii/tlphyvar.h> @@ -109,18 +97,12 @@ struct tlphy_softc { int sc_need_acomp; }; -#ifdef __NetBSD__ -int tlphymatch __P((struct device *, struct cfdata *, void *)); -#else int tlphymatch __P((struct device *, void *, void *)); -#endif void tlphyattach __P((struct device *, struct device *, void *)); -#ifdef __OpenBSD__ struct cfdriver tlphy_cd = { NULL, "tlphy", DV_DULL }; -#endif struct cfattach tlphy_ca = { sizeof(struct tlphy_softc), tlphymatch, tlphyattach @@ -134,17 +116,13 @@ void tlphy_status __P((struct tlphy_softc *)); int tlphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { struct mii_attach_args *ma = aux; - if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_TI && - MII_MODEL(ma->mii_id2) == MII_MODEL_TI_TLAN10T) + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxTI && + MII_MODEL(ma->mii_id2) == MII_MODEL_xxTI_TLAN10T) return (10); return (0); @@ -160,7 +138,7 @@ tlphyattach(parent, self, aux) struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; - printf(": %s, rev. %d\n", MII_STR_TI_TLAN10T, + printf(": %s, rev. %d\n", MII_STR_xxTI_TLAN10T, MII_REV(ma->mii_id2)); sc->sc_mii.mii_inst = mii->mii_instance; @@ -184,29 +162,10 @@ tlphyattach(parent, self, aux) else sc->sc_mii.mii_capabilities = 0; -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->sc_mii.mii_inst), - BMCR_ISO); - - if ((sc->sc_tlphycap & TLPHY_MEDIA_NO_10_T) == 0) - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_LOOP, - sc->sc_mii.mii_inst), BMCR_LOOP); - - if (sc->sc_tlphycap) { - if (sc->sc_tlphycap & TLPHY_MEDIA_10_2) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_2, 0, - sc->sc_mii.mii_inst), 0); - } else if (sc->sc_tlphycap & TLPHY_MEDIA_10_5) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_5, 0, - sc->sc_mii.mii_inst), 0); - } - } if (sc->sc_mii.mii_capabilities & BMSR_MEDIAMASK) { mii_add_media(mii, sc->sc_mii.mii_capabilities, sc->sc_mii.mii_inst); } -#undef ADD } int @@ -266,9 +225,7 @@ tlphy_service(self, mii, cmd) default: PHY_WRITE(&sc->sc_mii, MII_TLPHY_CTRL, 0); delay(100000); - PHY_WRITE(&sc->sc_mii, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(&sc->sc_mii, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(&sc->sc_mii); } break; @@ -314,6 +271,10 @@ tlphy_service(self, mii, cmd) if (tlphy_auto(sc, 0) == EJUSTRETURN) return (0); break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ diff --git a/sys/dev/mii/tqphy.c b/sys/dev/mii/tqphy.c new file mode 100644 index 00000000000..d57ef39842b --- /dev/null +++ b/sys/dev/mii/tqphy.c @@ -0,0 +1,305 @@ +/* $OpenBSD: tqphy.c,v 1.1 1999/12/07 22:01:33 jason Exp $ */ +/* $NetBSD: tqphy.c,v 1.4 1999/11/12 18:13:01 thorpej Exp $ */ + +/* + * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1997 Manuel Bouyer. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Manuel Bouyer. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * TDK TSC78Q2120 PHY driver + * + * Documentation available at http://www.tsc.tdk.com/lan/78Q2120.pdf . + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/malloc.h> +#include <sys/socket.h> + +#include <net/if.h> +#include <net/if_media.h> + +#include <dev/mii/mii.h> +#include <dev/mii/miivar.h> +#include <dev/mii/miidevs.h> + +#include <dev/mii/tqphyreg.h> + +int tqphymatch __P((struct device *, void *, void *)); +void tqphyattach __P((struct device *, struct device *, void *)); + +struct cfattach tqphy_ca = { + sizeof(struct mii_softc), tqphymatch, tqphyattach +}; + +struct cfdriver tqphy_cd = { + NULL, "tqphy", DV_DULL +}; + +int tqphy_service __P((struct mii_softc *, struct mii_data *, int)); +void tqphy_status __P((struct mii_softc *)); + +int +tqphymatch(parent, match, aux) + struct device *parent; + void *match; + void *aux; +{ + struct mii_attach_args *ma = aux; + + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_TSC) + switch MII_MODEL(ma->mii_id2) { + case MII_MODEL_TSC_78Q2120: + /* case MII_MODEL_TSC_78Q2121: */ + return (10); + } + + return (0); +} + +void +tqphyattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct mii_softc *sc = (struct mii_softc *)self; + struct mii_attach_args *ma = aux; + struct mii_data *mii = ma->mii_data; + + printf(": %s, rev. %d\n", MII_STR_TSC_78Q2120, + MII_REV(ma->mii_id2)); + + sc->mii_inst = mii->mii_instance; + sc->mii_phy = ma->mii_phyno; + sc->mii_service = tqphy_service; + sc->mii_pdata = mii; + + /* + * Apparently, we can't do loopback on this PHY. + */ + sc->mii_flags |= MIIF_NOLOOP; + + mii_phy_reset(sc); + + sc->mii_capabilities = + PHY_READ(sc, MII_BMSR) & ma->mii_capmask; + printf("%s: ", sc->mii_dev.dv_xname); + if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0) + printf("no media present"); + else + mii_add_media(sc); + printf("\n"); +} + +int +tqphy_service(sc, mii, cmd) + struct mii_softc *sc; + struct mii_data *mii; + int cmd; +{ + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; + int reg; + + switch (cmd) { + case MII_POLLSTAT: + /* + * If we're not polling our PHY instance, just return. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) + return (0); + break; + + case MII_MEDIACHG: + /* + * If the media indicates a different PHY instance, + * isolate ourselves. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + reg = PHY_READ(sc, MII_BMCR); + PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); + return (0); + } + + /* + * If the interface is not up, don't do anything. + */ + if ((mii->mii_ifp->if_flags & IFF_UP) == 0) + break; + + switch (IFM_SUBTYPE(ife->ifm_media)) { + case IFM_AUTO: + /* + * If we're already in auto mode, just return. + */ + if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) + return (0); + (void) mii_phy_auto(sc, 1); + break; + default: + mii_phy_setmedia(sc); + } + break; + + case MII_TICK: + /* + * If we're not currently selected, just return. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) + return (0); + + /* + * Only used for autonegotiation. + */ + if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) + return (0); + + /* + * Is the interface even up? + */ + if ((mii->mii_ifp->if_flags & IFF_UP) == 0) + return (0); + + /* + * Check to see if we have link. If we do, we don't + * need to restart the autonegotiation process. Read + * the BMSR twice in case it's latched. + */ + reg = PHY_READ(sc, MII_BMSR) | + PHY_READ(sc, MII_BMSR); + if (reg & BMSR_LINK) + return (0); + + /* + * Only retry autonegotiation every 5 seconds. + */ + if (++sc->mii_ticks != 5) + return (0); + + sc->mii_ticks = 0; + mii_phy_reset(sc); + if (mii_phy_auto(sc, 0) == EJUSTRETURN) + return (0); + break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); + } + + /* Update the media status. */ + tqphy_status(sc); + + /* Callback if something changed. */ + if (sc->mii_active != mii->mii_media_active || cmd == MII_MEDIACHG) { + (*mii->mii_statchg)(sc->mii_dev.dv_parent); + sc->mii_active = mii->mii_media_active; + } + return (0); +} + +void +tqphy_status(sc) + struct mii_softc *sc; +{ + struct mii_data *mii = sc->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; + int bmsr, bmcr, diag; + + mii->mii_media_status = IFM_AVALID; + mii->mii_media_active = IFM_ETHER; + + bmsr = PHY_READ(sc, MII_BMSR) | + PHY_READ(sc, MII_BMSR); + if (bmsr & BMSR_LINK) + mii->mii_media_status |= IFM_ACTIVE; + + bmcr = PHY_READ(sc, MII_BMCR); + if (bmcr & BMCR_ISO) { + mii->mii_media_active |= IFM_NONE; + mii->mii_media_status = 0; + return; + } + + if (bmcr & BMCR_LOOP) + mii->mii_media_active |= IFM_LOOP; + + if (bmcr & BMCR_AUTOEN) { + if ((bmsr & BMSR_ACOMP) == 0) { + /* Erg, still trying, I guess... */ + mii->mii_media_active |= IFM_NONE; + return; + } + diag = PHY_READ(sc, MII_TQPHY_DIAG); + if (diag & DIAG_RATE) + mii->mii_media_active |= IFM_100_TX; + else + mii->mii_media_active |= IFM_10_T; + if (diag & DIAG_DPLX) + mii->mii_media_active |= IFM_FDX; + } else + mii->mii_media_active = ife->ifm_media; +} diff --git a/sys/dev/mii/tqphyreg.h b/sys/dev/mii/tqphyreg.h new file mode 100644 index 00000000000..9ddd14ead81 --- /dev/null +++ b/sys/dev/mii/tqphyreg.h @@ -0,0 +1,94 @@ +/* $OpenBSD: tqphyreg.h,v 1.1 1999/12/07 22:01:33 jason Exp $ */ +/* $NetBSD: tqphyreg.h,v 1.2 1999/09/16 05:58:18 soren Exp $ */ + +/* + * Copyright (c) 1999 Soren S. Jorvang. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _DEV_MII_TQPHYREG_H_ +#define _DEV_MII_TQPHYREG_H_ + +/* + * TDK TSC78Q2120 PHY registers + * + * Documentation available at http://www.tsc.tdk.com/lan/78Q2120.pdf . + */ + +/* + * http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html has this to say: + * + * TDK Semiconductor (formerly Silicon Systems) 78Q2120 (10/100) and 78Q2121 + * (100Mbps only) MII transceivers. The first PHY available which worked at + * both 5.0 and 3.3V. Used on the 3Com 3c574 and Ositech products. The OUI + * is 00:c0:39, models 20 and 21. Warning: The older revision 3 part has + * several bugs. It always responds to MDIO address 0, and has clear-only + * semantics for the capability-advertise registers. The current (3/99) + * revision 11 part, shipping since 8/98, has reportedly fixed these problems. + */ + +#define MII_TQPHY_VENDOR 0x10 /* Vendor specific register */ +#define VENDOR_RPTR 0x8000 /* Repeater mode */ +#define VENDOR_INTLEVEL 0x4000 /* INTR pin level */ +#define VENDOR_RSVD1 0x2000 /* Reserved */ +#define VENDOR_TXHIM 0x1000 /* Transmit high impedance */ +#define VENDOR_SEQTESTINHIBIT 0x0800 /* Disables 10baseT SQE testing */ +#define VENDOR_10BT_LOOPBACK 0x0400 /* 10baseT natural loopback */ +#define VENDOR_GPIO1_DAT 0x0200 /* General purpose I/O 1 data */ +#define VENDOR_GPIO1_DIR 0x0100 /* General purpose I/O 1 direction */ +#define VENDOR_GPIO0_DAT 0x0080 /* General purpose I/O 0 data */ +#define VENDOR_GPIO0_DIR 0x0040 /* General purpose I/O 0 direction */ +#define VENDOR_APOL 0x0020 /* Auto polarity */ +#define VENDOR_RVSPOL 0x0010 /* Reverse polarity */ +#define VENDOR_RSVD2 0x0008 /* Reserved (must be zero) */ +#define VENDOR_RSVD3 0x0004 /* Reserved (must be zero) */ +#define VENDOR_PCSBP 0x0002 /* PCS bypass */ +#define VENDOR_RXCC 0x0001 /* Receive clock control */ + +#define MII_TQPHY_INTR 0x11 /* Interrupt control/status register */ +#define INTR_JABBER_IE 0x8000 /* Jabber interrupt enable */ +#define INTR_RXER_IE 0x4000 /* Receive error enable */ +#define INTR_PRX_IE 0x2000 /* Page received enable */ +#define INTR_PFD_IE 0x1000 /* Parallel detect fault enable */ +#define INTR_LPACK_IE 0x0800 /* Link partner ack. enable */ +#define INTR_LSCHG_IE 0x0400 /* Link status change enable */ +#define INTR_RFAULT_IE 0x0200 /* Remote fault enable */ +#define INTR_ANEGCOMP_IE 0x0100 /* Autonegotiation complete enable */ +#define INTR_JABBER_INT 0x0080 /* Jabber interrupt */ +#define INTR_RXER_INT 0x0040 /* Receive error interrupt */ +#define INTR_PRX_INT 0x0020 /* Page receive interrupt */ +#define INTR_PDF_INT 0x0010 /* Parallel detect fault interrupt */ +#define INTR_LPACK_INT 0x0008 /* Link partner ack. interrupt */ +#define INTR_LSCHG_INT 0x0004 /* Link status change interrupt */ +#define INTR_RFAULT_INT 0x0002 /* Remote fault interrupt */ +#define INTR_ANEGCOMP_INT 0x0001 /* Autonegotiation complete interrupt */ + +#define MII_TQPHY_DIAG 0x12 /* Diagnostic register */ +#define DIAG_ANEGF 0x1000 /* Autonegotiation fail */ +#define DIAG_DPLX 0x0800 /* Duplex (half/full) */ +#define DIAG_RATE 0x0400 /* Rate (10/100) */ +#define DIAG_RXPASS 0x0200 /* Receive pass */ +#define DIAG_RXLOCK 0x0100 /* Receive lock */ + +#endif /* _DEV_MII_TQPHYREG_H_ */ diff --git a/sys/dev/mii/ukphy.c b/sys/dev/mii/ukphy.c index 23c56f1ac68..ee24f04f8a2 100644 --- a/sys/dev/mii/ukphy.c +++ b/sys/dev/mii/ukphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ukphy.c,v 1.5 1999/09/17 01:38:56 jason Exp $ */ +/* $OpenBSD: ukphy.c,v 1.6 1999/12/07 22:01:33 jason Exp $ */ /* $NetBSD: ukphy.c,v 1.1.6.1 1999/04/23 15:39:00 perry Exp $ */ /*- @@ -85,33 +85,23 @@ #include <dev/mii/mii.h> #include <dev/mii/miivar.h> -#ifdef __NetBSD__ -int ukphymatch __P((struct device *, struct cfdata *, void *)); -#else int ukphymatch __P((struct device *, void *, void *)); -#endif void ukphyattach __P((struct device *, struct device *, void *)); struct cfattach ukphy_ca = { sizeof(struct mii_softc), ukphymatch, ukphyattach }; -#ifdef __OpenBSD__ struct cfdriver ukphy_cd = { NULL, "ukphy", DV_DULL }; -#endif int ukphy_service __P((struct mii_softc *, struct mii_data *, int)); int ukphymatch(parent, match, aux) struct device *parent; -#ifdef __NetBSD__ - struct cfdata *match; -#else void *match; -#endif void *aux; { @@ -140,23 +130,12 @@ ukphyattach(parent, self, aux) sc->mii_service = ukphy_service; sc->mii_pdata = mii; -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - BMCR_ISO); -#if 0 - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - BMCR_LOOP|BMCR_S100); -#endif - mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_MEDIAMASK) - mii_add_media(mii, sc->mii_capabilities, - sc->mii_inst); -#undef ADD + mii_add_media(sc); } int @@ -203,18 +182,8 @@ ukphy_service(sc, mii, cmd) return (0); (void) mii_phy_auto(sc, 1); break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); default: - /* - * BMCR data is stored in the ifmedia entry. - */ - PHY_WRITE(sc, MII_ANAR, - mii_anar(ife->ifm_media)); - PHY_WRITE(sc, MII_BMCR, ife->ifm_data); + mii_phy_setmedia(sc); } break; @@ -258,6 +227,10 @@ ukphy_service(sc, mii, cmd) if (mii_phy_auto(sc, 0) == EJUSTRETURN) return (0); break; + + case MII_DOWN: + mii_phy_down(sc); + return (0); } /* Update the media status. */ diff --git a/sys/dev/mii/ukphy_subr.c b/sys/dev/mii/ukphy_subr.c index d389507e3ad..2dc2f47157e 100644 --- a/sys/dev/mii/ukphy_subr.c +++ b/sys/dev/mii/ukphy_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ukphy_subr.c,v 1.1 1998/11/11 19:34:51 jason Exp $ */ +/* $OpenBSD: ukphy_subr.c,v 1.2 1999/12/07 22:01:33 jason Exp $ */ /* $NetBSD: ukphy_subr.c,v 1.2 1998/11/05 04:08:02 thorpej Exp $ */ /*- @@ -64,6 +64,7 @@ ukphy_status(phy) struct mii_softc *phy; { struct mii_data *mii = phy->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmsr, bmcr, anlpar; mii->mii_media_status = IFM_AVALID; @@ -109,5 +110,5 @@ ukphy_status(phy) else mii->mii_media_active |= IFM_NONE; } else - mii->mii_media_active = mii_media_from_bmcr(bmcr); + mii->mii_media_active = ife->ifm_media; } |