diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2005-05-27 09:24:02 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2005-05-27 09:24:02 +0000 |
commit | 7292c74355e5d99197ee5abe163eb46765d7cc9c (patch) | |
tree | cfecca8c89850b424a33b10d577dbed989b97914 | |
parent | 141f6c9496a550f50379a449e7eca41c9b368813 (diff) |
modernize and cleanup the nsgphy code, using mii_phy_setmedia/mii_phy_tick
and the generic MII #defines
-rw-r--r-- | sys/dev/mii/nsgphy.c | 230 | ||||
-rw-r--r-- | sys/dev/mii/nsgphyreg.h | 120 |
2 files changed, 51 insertions, 299 deletions
diff --git a/sys/dev/mii/nsgphy.c b/sys/dev/mii/nsgphy.c index aedf5968594..4516ea10278 100644 --- a/sys/dev/mii/nsgphy.c +++ b/sys/dev/mii/nsgphy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nsgphy.c,v 1.15 2005/03/26 04:40:09 krw Exp $ */ +/* $OpenBSD: nsgphy.c,v 1.16 2005/05/27 09:24:01 brad Exp $ */ /* * Copyright (c) 2001 Wind River Systems * Copyright (c) 2001 @@ -77,8 +77,6 @@ struct cfdriver nsgphy_cd = { int nsgphy_service(struct mii_softc *, struct mii_data *, int); void nsgphy_status(struct mii_softc *); -int nsgphy_mii_phy_auto(struct mii_softc *, int); - const struct mii_phy_funcs nsgphy_funcs = { nsgphy_service, nsgphy_status, mii_phy_reset, }; @@ -120,9 +118,7 @@ nsgphyattach(struct device *parent, struct device *self, void *aux) sc->mii_funcs = &nsgphy_funcs; sc->mii_pdata = mii; sc->mii_flags = ma->mii_flags; - sc->mii_anegticks = MII_ANEGTICKS_GIGE; - - PHY_RESET(sc); + sc->mii_anegticks = MII_ANEGTICKS; sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; @@ -131,15 +127,6 @@ nsgphyattach(struct device *parent, struct device *self, void *aux) if ((sc->mii_capabilities & BMSR_MEDIAMASK) || (sc->mii_extcapabilities & EXTSR_MEDIAMASK)) mii_phy_add_media(sc); - -#if 0 - strap = PHY_READ(sc, MII_GPHYTER_STRAP); - printf("%s: strapped to %s mode", sc->mii_dev.dv_xname, - (strap & STRAP_MS_VAL) ? "master" : "slave"); - if (strap & STRAP_NC_MODE) - printf(", pre-C5 BCM5400 compat enabled"); - printf("\n"); -#endif } int @@ -177,53 +164,7 @@ nsgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; - switch (IFM_SUBTYPE(ife->ifm_media)) { - case IFM_AUTO: - (void) nsgphy_mii_phy_auto(sc, 0); - break; - case IFM_1000_T: - if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) { - PHY_WRITE(sc, NSGPHY_MII_BMCR, - NSGPHY_BMCR_FDX|NSGPHY_BMCR_SPD1); - } else { - PHY_WRITE(sc, NSGPHY_MII_BMCR, - NSGPHY_BMCR_SPD1); - } - PHY_WRITE(sc, NSGPHY_MII_ANAR, NSGPHY_SEL_TYPE); - - /* - * When setting the link manually, one side must - * be the master and the other the slave. However - * ifmedia doesn't give us a good way to specify - * this, so we fake it by using one of the LINK - * flags. If LINK0 is set, we program the PHY to - * be a master, otherwise it's a slave. - */ - if ((mii->mii_ifp->if_flags & IFF_LINK0)) { - PHY_WRITE(sc, NSGPHY_MII_1000CTL, - NSGPHY_1000CTL_MSE|NSGPHY_1000CTL_MSC); - } else { - PHY_WRITE(sc, NSGPHY_MII_1000CTL, - NSGPHY_1000CTL_MSE); - } - break; - case IFM_100_T4: - /* - * XXX Not supported as a manual setting right now. - */ - return (EINVAL); - case IFM_NONE: - PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN); - 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); - break; - } + mii_phy_setmedia(sc); break; case MII_TICK: @@ -233,36 +174,8 @@ nsgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); - /* - * Only used for autonegotiation. - */ - if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) + if (mii_phy_tick(sc) == EJUSTRETURN) return (0); - - /* - * Is the interface even up? - */ - if ((mii->mii_ifp->if_flags & IFF_UP) == 0) - return (0); - - /* - * Only retry autonegotiation every mii_anegticks seconds. - */ - if (++sc->mii_ticks <= sc->mii_anegticks) - return (0); - - sc->mii_ticks = 0; - - /* - * Check to see if we have link. - */ - reg = PHY_READ(sc, NSGPHY_MII_PHYSUP); - if (reg & NSGPHY_PHYSUP_LNKSTS) - break; - - PHY_RESET(sc); - if (nsgphy_mii_phy_auto(sc, 0) == EJUSTRETURN) - return(0); break; case MII_DOWN: mii_phy_down(sc); @@ -281,123 +194,58 @@ void nsgphy_status(struct mii_softc *sc) { struct mii_data *mii = sc->mii_pdata; - int bmsr, bmcr, physup, anlpar, gstat; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; + int bmsr, bmcr, physup, gtsr; mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER; - bmsr = PHY_READ(sc, NSGPHY_MII_BMSR) | PHY_READ(sc, NSGPHY_MII_BMSR); + bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); + physup = PHY_READ(sc, NSGPHY_MII_PHYSUP); - if (physup & NSGPHY_PHYSUP_LNKSTS) + + if (physup & PHY_SUP_LINK) mii->mii_media_status |= IFM_ACTIVE; - bmcr = PHY_READ(sc, NSGPHY_MII_BMCR); + bmcr = PHY_READ(sc, MII_BMCR); + if (bmcr & BMCR_ISO) { + mii->mii_media_active |= IFM_NONE; + mii->mii_media_status = 0; + return; + } - if (bmcr & NSGPHY_BMCR_LOOP) + if (bmcr & BMCR_LOOP) mii->mii_media_active |= IFM_LOOP; - if (bmcr & NSGPHY_BMCR_AUTOEN) { - if ((bmsr & NSGPHY_BMSR_ACOMP) == 0) { + if (bmcr & BMCR_AUTOEN) { + if ((bmsr & BMSR_ACOMP) == 0) { /* Erg, still trying, I guess... */ mii->mii_media_active |= IFM_NONE; return; } - anlpar = PHY_READ(sc, NSGPHY_MII_ANLPAR); - gstat = PHY_READ(sc, NSGPHY_MII_1000STS); - if (gstat & NSGPHY_1000STS_LPFD) - mii->mii_media_active |= IFM_1000_T|IFM_FDX; - else if (gstat & NSGPHY_1000STS_LPHD) - mii->mii_media_active |= IFM_1000_T|IFM_HDX; - else if (anlpar & NSGPHY_ANLPAR_100T4) - mii->mii_media_active |= IFM_100_T4; - else if (anlpar & NSGPHY_ANLPAR_100FDX) - mii->mii_media_active |= IFM_100_TX|IFM_FDX; - else if (anlpar & NSGPHY_ANLPAR_100HDX) - mii->mii_media_active |= IFM_100_TX; - else if (anlpar & NSGPHY_ANLPAR_10FDX) - mii->mii_media_active |= IFM_10_T|IFM_FDX; - else if (anlpar & NSGPHY_ANLPAR_10HDX) - mii->mii_media_active |= IFM_10_T|IFM_HDX; - else - mii->mii_media_active |= IFM_NONE; - return; - } - switch(bmcr & (NSGPHY_BMCR_SPD1|NSGPHY_BMCR_SPD0)) { - case NSGPHY_S1000: - mii->mii_media_active |= IFM_1000_T; - break; - case NSGPHY_S100: - mii->mii_media_active |= IFM_100_TX; - break; - case NSGPHY_S10: - mii->mii_media_active |= IFM_10_T; - break; - default: - break; - } - - if (bmcr & NSGPHY_BMCR_FDX) - mii->mii_media_active |= IFM_FDX; - else - mii->mii_media_active |= IFM_HDX; - - return; -} + switch (physup & (PHY_SUP_SPEED1|PHY_SUP_SPEED0)) { + case PHY_SUP_SPEED1: + mii->mii_media_active |= IFM_1000_T; + gtsr = PHY_READ(sc, MII_100T2SR); + if (gtsr & GTSR_MS_RES) + mii->mii_media_active |= IFM_ETH_MASTER; + break; + case PHY_SUP_SPEED0: + mii->mii_media_active |= IFM_100_TX; + break; -int -nsgphy_mii_phy_auto(struct mii_softc *sc, int waitfor) -{ - int bmsr, ktcr = 0, i; - - if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) { - PHY_RESET(sc); - PHY_WRITE(sc, NSGPHY_MII_BMCR, 0); - DELAY(1000); - ktcr = PHY_READ(sc, NSGPHY_MII_1000CTL); - PHY_WRITE(sc, NSGPHY_MII_1000CTL, ktcr | - (NSGPHY_1000CTL_AFD|NSGPHY_1000CTL_AHD)); - ktcr = PHY_READ(sc, NSGPHY_MII_1000CTL); - DELAY(1000); - PHY_WRITE(sc, NSGPHY_MII_ANAR, - BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA); - DELAY(1000); - PHY_WRITE(sc, NSGPHY_MII_BMCR, - NSGPHY_BMCR_AUTOEN | NSGPHY_BMCR_STARTNEG); - } + case 0: + mii->mii_media_active |= IFM_10_T; + break; - if (waitfor) { - /* Wait 500ms for it to complete. */ - for (i = 0; i < 500; i++) { - if ((bmsr = PHY_READ(sc, NSGPHY_MII_BMSR)) & - NSGPHY_BMSR_ACOMP) - return (0); - DELAY(1000); -#if 0 - if ((bmsr & BMSR_ACOMP) == 0) - printf("%s: autonegotiation failed to complete\n", - mii->mii_dev.dv_xname); -#endif + default: + mii->mii_media_active |= IFM_NONE; + mii->mii_media_status = 0; } - - /* - * Don't need to worry about clearing MIIF_DOINGAUTO. - * If that's set, a timeout is pending, and it will - * clear the flag. - */ - return (EIO); - } - - /* - * Just let it finish asynchronously. This is for the benefit of - * the tick handler driving autonegotiation. Don't want 500ms - * delays all the time while the system is running! - */ - if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) { - sc->mii_flags |= MIIF_DOINGAUTO; - timeout_set(&sc->mii_phy_timo, mii_phy_auto_timeout, sc); - timeout_add(&sc->mii_phy_timo, hz >> 1); - } - return (EJUSTRETURN); + if (physup & PHY_SUP_DUPLEX) + mii->mii_media_active |= IFM_FDX; + } else + mii->mii_media_active = ife->ifm_media; } diff --git a/sys/dev/mii/nsgphyreg.h b/sys/dev/mii/nsgphyreg.h index 4ab42281422..145b6475840 100644 --- a/sys/dev/mii/nsgphyreg.h +++ b/sys/dev/mii/nsgphyreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nsgphyreg.h,v 1.4 2003/10/22 09:39:29 jmc Exp $ */ +/* $OpenBSD: nsgphyreg.h,v 1.5 2005/05/27 09:24:01 brad Exp $ */ /* * Copyright (c) 2001 Wind River Systems * Copyright (c) 2001 @@ -31,7 +31,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD$ + * $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/dev/mii/nsgphyreg.h,v 1.3 2002/04/29 11:57:28 phk Exp $ */ #ifndef _DEV_MII_NSGPHYREG_H_ @@ -41,110 +41,6 @@ * NatSemi DP83891 registers */ -#define NSGPHY_MII_BMCR 0x00 -#define NSGPHY_BMCR_RESET 0x8000 -#define NSGPHY_BMCR_LOOP 0x4000 -#define NSGPHY_BMCR_SPD0 0x2000 /* speed select, lower bit */ -#define NSGPHY_BMCR_AUTOEN 0x1000 /* Autoneg enabled */ -#define NSGPHY_BMCR_PDOWN 0x0800 /* Power down */ -#define NSGPHY_BMCR_ISO 0x0400 /* Isolate */ -#define NSGPHY_BMCR_STARTNEG 0x0200 /* Restart autoneg */ -#define NSGPHY_BMCR_FDX 0x0100 /* Duplex mode */ -#define NSGPHY_BMCR_CTEST 0x0080 /* Collision test enable */ -#define NSGPHY_BMCR_SPD1 0x0040 /* Speed select, upper bit */ - -#define NSGPHY_S1000 NSGPHY_BMCR_SPD1 /* 1000mbps */ -#define NSGPHY_S100 NSGPHY_BMCR_SPD0 /* 100mpbs */ -#define NSGPHY_S10 0 /* 10mbps */ - -#define NSGPHY_MII_BMSR 0x01 -#define NSGPHY_BMSR_100BT4 0x8000 /* 100baseT4 support */ -#define NSGPHY_BMSR_100FDX 0x4000 /* 100baseTX full duplex */ -#define NSGPHY_BMSR_100HDX 0x2000 /* 100baseTX half duplex */ -#define NSGPHY_BMSR_10FDX 0x1000 /* 10baseT full duplex */ -#define NSGPHY_BMSR_10HDX 0x0800 /* 10baseT half duplex */ -#define NSGPHY_BMSR_100T2FDX 0x0400 /* 100baseT2 full duplex */ -#define NSGPHY_BMSR_100T2HDX 0x0200 /* 100baseT2 full duplex */ -#define NSGPHY_BMSR_EXTSTS 0x0100 /* 1000baseT Extended status present */ -#define NSGPHY_BMSR_PRESUB 0x0040 /* Preamble suppression */ -#define NSGPHY_BMSR_ACOMP 0x0020 /* Autoneg complete */ -#define NSGPHY_BMSR_RFAULT 0x0010 /* Remote fault condition occurred */ -#define NSGPHY_BMSR_ANEG 0x0008 /* Autoneg capable */ -#define NSGPHY_BMSR_LINK 0x0004 /* Link status */ -#define NSGPHY_BMSR_JABBER 0x0002 /* Jabber detected */ -#define NSGPHY_BMSR_EXT 0x0001 /* Extended capability */ - -#define NSGPHY_MII_ANAR 0x04 -#define NSGPHY_ANAR_NP 0x8000 /* Next page */ -#define NSGPHY_ANAR_RF 0x2000 /* Remote fault */ -#define NSGPHY_ANAR_ASP 0x0800 /* Asymmetric Pause */ -#define NSGPHY_ANAR_PC 0x0400 /* Pause capable */ -#define NSGPHY_ANAR_100T4 0x0200 /* 100baseT4 support */ -#define NSGPHY_ANAR_100FDX 0x0100 /* 100baseTX full duplex support */ -#define NSGPHY_ANAR_100HDX 0x0080 /* 100baseTX half duplex support */ -#define NSGPHY_ANAR_10FDX 0x0040 /* 10baseT full duplex support */ -#define NSGPHY_ANAR_10HDX 0x0020 /* 10baseT half duplex support */ -#define NSGPHY_ANAR_SEL 0x001F /* selector field, 00001=Ethernet */ - -#define NSGPHY_MII_ANLPAR 0x05 -#define NSGPHY_ANLPAR_NP 0x8000 /* Next page */ -#define NSGPHY_ANLPAR_RF 0x2000 /* Remote fault */ -#define NSGPHY_ANLPAR_ASP 0x0800 /* Asymmetric Pause */ -#define NSGPHY_ANLPAR_PC 0x0400 /* Pause capable */ -#define NSGPHY_ANLPAR_100T4 0x0200 /* 100baseT4 support */ -#define NSGPHY_ANLPAR_100FDX 0x0100 /* 100baseTX full duplex support */ -#define NSGPHY_ANLPAR_100HDX 0x0080 /* 100baseTX half duplex support */ -#define NSGPHY_ANLPAR_10FDX 0x0040 /* 10baseT full duplex support */ -#define NSGPHY_ANLPAR_10HDX 0x0020 /* 10baseT half duplex support */ -#define NSGPHY_ANLPAR_SEL 0x001F /* selector field, 00001=Ethernet */ - -#define NSGPHY_SEL_TYPE 0x0001 /* ethernet */ - -#define NSGPHY_MII_ANER 0x06 -#define NSGPHY_ANER_PDF 0x0010 /* Parallel detection fault */ -#define NSGPHY_ANER_LPNP 0x0008 /* Link partner can next page */ -#define NSGPHY_ANER_NP 0x0004 /* Local PHY can next page */ -#define NSGPHY_ANER_RX 0x0002 /* Next page received */ -#define NSGPHY_ANER_LPAN 0x0001 /* Link partner autoneg capable */ - -#define NSGPHY_MII_NEXTP 0x07 /* Next page */ -#define NSGPHY_NEXTP_NP 0x8000 /* Next page indication */ -#define NSGPHY_NEXTP_MP 0x2000 /* Message page */ -#define NSGPHY_NEXTP_ACK2 0x1000 /* Acknowledge 2 */ -#define NSGPHY_NEXTP_TOGGLE 0x0800 /* Toggle */ -#define NSGPHY_NEXTP_CODE 0x07FF /* Code field */ - -#define NSGPHY_MII_NEXTP_LP 0x08 /* Next page of link partner */ -#define NSGPHY_NEXTPLP_NP 0x8000 /* Next page indication */ -#define NSGPHY_NEXTPLP_MP 0x2000 /* Message page */ -#define NSGPHY_NEXTPLP_ACK2 0x1000 /* Acknowledge 2 */ -#define NSGPHY_NEXTPLP_TOGGLE 0x0800 /* Toggle */ -#define NSGPHY_NEXTPLP_CODE 0x07FF /* Code field */ - -#define NSGPHY_MII_1000CTL 0x09 /* 1000baseT control */ -#define NSGPHY_1000CTL_TST 0xE000 /* test modes */ -#define NSGPHY_1000CTL_MSE 0x1000 /* Master/Slave config enable */ -#define NSGPHY_1000CTL_MSC 0x0800 /* Master/Slave setting */ -#define NSGPHY_1000CTL_RD 0x0400 /* Port type: Repeater/DTE */ -#define NSGPHY_1000CTL_AFD 0x0200 /* Advertise full duplex */ -#define NSGPHY_1000CTL_AHD 0x0100 /* Advertise half duplex */ - -#define NSGPHY_MII_1000STS 0x0A /* 1000baseT status */ -#define NSGPHY_1000STS_MSF 0x8000 /* Master/slave fault */ -#define NSGPHY_1000STS_MSR 0x4000 /* Master/slave result */ -#define NSGPHY_1000STS_LRS 0x2000 /* Local receiver status */ -#define NSGPHY_1000STS_RRS 0x1000 /* Remote receiver status */ -#define NSGPHY_1000STS_LPFD 0x0800 /* Link partner can FD */ -#define NSGPHY_1000STS_LPHD 0x0400 /* Link partner can HD */ -#define NSGPHY_1000STS_ASM_DIR 0x0200 /* Asymmetric pause capable */ -#define NSGPHY_1000STS_IEC 0x00FF /* Idle error count */ - -#define NSGPHY_MII_EXTSTS 0x0F /* Extended status */ -#define NSGPHY_EXTSTS_X_FD_CAP 0x8000 /* 1000base-X FD capable */ -#define NSGPHY_EXTSTS_X_HD_CAP 0x4000 /* 1000base-X HD capable */ -#define NSGPHY_EXTSTS_T_FD_CAP 0x2000 /* 1000base-T FD capable */ -#define NSGPHY_EXTSTS_T_HD_CAP 0x1000 /* 1000base-T HD capable */ - #define NSGPHY_MII_STRAPOPT 0x10 /* Strap options */ #define NSGPHY_STRAPOPT_PHYADDR 0xF800 /* PHY address */ #define NSGPHY_STRAPOPT_COMPAT 0x0400 /* Broadcom compat mode */ @@ -154,11 +50,19 @@ #define NSGPHY_STRAPOPT_1000HDX 0x0010 /* Advertise 1000 half-duplex */ #define NSGPHY_STRAPOPT_1000FDX 0x0008 /* Advertise 1000 full-duplex */ #define NSGPHY_STRAPOPT_100_ADV 0x0004 /* Advertise 100 full/half-duplex */ -#define NSGPHY_STRAPOPT_SPDSEL 0x0003 /* speed selection */ +#define NSGPHY_STRAPOPT_SPEED1 0x0002 /* speed selection */ +#define NSGPHY_STRAPOPT_SPEED0 0x0001 /* speed selection */ +#define NSGPHY_STRAPOPT_SPDSEL (NSGPHY_STRAPOPT_SPEED1|NSGPHY_STRAPOPT_SPEED0) #define NSGPHY_MII_PHYSUP 0x11 /* PHY support/current status */ -#define NSGPHY_PHYSUP_SPDSTS 0x0018 /* speed status */ +#define PHY_SUP_SPEED1 0x0010 /* speed bit 1 */ +#define PHY_SUP_SPEED0 0x0008 /* speed bit 1 */ +#define NSGPHY_PHYSUP_SPEED1 0x0010 /* speed status */ +#define NSGPHY_PHYSUP_SPEED0 0x0008 /* speed status */ +#define NSGPHY_PHYSUP_SPDSTS (NSGPHY_PHYSUP_SPEED1|NSGPHY_PHYSUP_SPEED0) #define NSGPHY_PHYSUP_LNKSTS 0x0004 /* link status */ +#define PHY_SUP_LINK 0x0004 /* link status */ +#define PHY_SUP_DUPLEX 0x0002 /* 1 == full-duplex */ #define NSGPHY_PHYSUP_DUPSTS 0x0002 /* duplex status 1 == full */ #define NSGPHY_PHYSUP_10BT 0x0001 /* 10baseT resolved */ |