diff options
author | semenu <semenu@FreeBSD.org> | 2002-05-01 19:15:54 +0000 |
---|---|---|
committer | semenu <semenu@FreeBSD.org> | 2002-05-01 19:15:54 +0000 |
commit | 7c4d7211448ad4ae368cf07cc871c6052895b73f (patch) | |
tree | 304ca0e4c18d3fb7bc12110f504ab37205711fa9 /sys | |
parent | 59e363cb4e865ff7d8b202404ec9fe6769815abf (diff) | |
download | FreeBSD-src-7c4d7211448ad4ae368cf07cc871c6052895b73f.zip FreeBSD-src-7c4d7211448ad4ae368cf07cc871c6052895b73f.tar.gz |
MII_TICK handlers need not restart aneg on these PHYs, they behave pretty
well as is, so - just fetch current status upon MII_TICK.
Also do IFM_INST verification at the top of *_service() then doing it
separately for every case in switch.
acphy: do not read MII_ACPHY_DIAG twice, there is nothing latching.
qsphy: always fetch actual link status from MII_QSPHY_PCTL.
MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/mii/acphy.c | 56 | ||||
-rw-r--r-- | sys/dev/mii/qsphy.c | 108 |
2 files changed, 55 insertions, 109 deletions
diff --git a/sys/dev/mii/acphy.c b/sys/dev/mii/acphy.c index e885bde..f505761 100644 --- a/sys/dev/mii/acphy.c +++ b/sys/dev/mii/acphy.c @@ -176,33 +176,31 @@ acphy_service(sc, mii, cmd) struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; + /* + * If we're not selected, then do nothing, just isolate and power + * down, if changing media. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + if (cmd == MII_MEDIACHG) { + reg = PHY_READ(sc, MII_BMCR); + PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO | BMCR_PDOWN); + } + + return (0); + } + 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 | BMCR_PDOWN); - return (0); - } - - /* * If the interface is not up, don't do anything. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; - /* Wake & deisolate up is needed */ + /* Wake & deisolate up if necessary */ reg = PHY_READ(sc, MII_BMCR); if (reg & (BMCR_ISO | BMCR_PDOWN)) PHY_WRITE(sc, MII_BMCR, reg & ~(BMCR_ISO | BMCR_PDOWN)); @@ -230,12 +228,6 @@ acphy_service(sc, mii, cmd) case MII_TICK: /* - * If we're not currently selected, just return. - */ - if (IFM_INST(ife->ifm_media) != sc->mii_inst) - return (0); - - /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) @@ -248,23 +240,8 @@ acphy_service(sc, mii, cmd) break; /* - * check for link. - * Read the status register twice; BMSR_LINK is latch-low. + * This PHY's autonegotiation doesn't need to be kicked. */ - reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); - if (reg & BMSR_LINK) - break; - - /* - * Only retry autonegotiation every 5 seconds. - */ - if (++sc->mii_ticks != 5) - return (0); - - sc->mii_ticks = 0; - acphy_reset(sc); - if (mii_phy_auto(sc, 0) == EJUSTRETURN) - return (0); break; } @@ -308,8 +285,7 @@ acphy_status(sc) mii->mii_media_active |= IFM_NONE; return; } - diag = PHY_READ(sc, MII_ACPHY_DIAG) | - PHY_READ(sc, MII_ACPHY_DIAG); + diag = PHY_READ(sc, MII_ACPHY_DIAG); if (diag & AC_DIAG_SPEED) mii->mii_media_active |= IFM_100_TX; else diff --git a/sys/dev/mii/qsphy.c b/sys/dev/mii/qsphy.c index a8f3432..fae4567 100644 --- a/sys/dev/mii/qsphy.c +++ b/sys/dev/mii/qsphy.c @@ -180,27 +180,25 @@ qsphy_service(sc, mii, cmd) struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; + /* + * If we're not selected, then do nothing, just isolate, if + * changing media. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + if (cmd == MII_MEDIACHG) { + reg = PHY_READ(sc, MII_BMCR); + PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); + } + + return (0); + } + 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) @@ -229,12 +227,6 @@ qsphy_service(sc, mii, cmd) case MII_TICK: /* - * If we're not currently selected, just return. - */ - if (IFM_INST(ife->ifm_media) != sc->mii_inst) - return (0); - - /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) @@ -247,23 +239,8 @@ qsphy_service(sc, mii, cmd) break; /* - * check for link. - * Read the status register twice; BMSR_LINK is latch-low. - */ - reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); - if (reg & BMSR_LINK) - break; - - /* - * Only retry autonegotiation every 5 seconds. + * This PHY's autonegotiation doesn't need to be kicked. */ - if (++sc->mii_ticks != 5) - return (0); - - sc->mii_ticks = 0; - qsphy_reset(sc); - if (mii_phy_auto(sc, 0) == EJUSTRETURN) - return (0); break; } @@ -280,7 +257,6 @@ 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; @@ -301,37 +277,31 @@ qsphy_status(sc) 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; - } - pctl = PHY_READ(sc, MII_QSPHY_PCTL) | - PHY_READ(sc, MII_QSPHY_PCTL); - switch (pctl & PCTL_OPMASK) { - case PCTL_10_T: - mii->mii_media_active |= IFM_10_T; - break; - case PCTL_10_T_FDX: - mii->mii_media_active |= IFM_10_T|IFM_FDX; - break; - case PCTL_100_TX: - mii->mii_media_active |= IFM_100_TX; - break; - case PCTL_100_TX_FDX: - mii->mii_media_active |= IFM_100_TX|IFM_FDX; - break; - case PCTL_100_T4: - mii->mii_media_active |= IFM_100_T4; - break; - default: - /* Erg... this shouldn't happen. */ - mii->mii_media_active |= IFM_NONE; - break; - } - } else - mii->mii_media_active = ife->ifm_media; + pctl = PHY_READ(sc, MII_QSPHY_PCTL); + switch (pctl & PCTL_OPMASK) { + case PCTL_10_T: + mii->mii_media_active |= IFM_10_T; + break; + case PCTL_10_T_FDX: + mii->mii_media_active |= IFM_10_T|IFM_FDX; + break; + case PCTL_100_TX: + mii->mii_media_active |= IFM_100_TX; + break; + case PCTL_100_TX_FDX: + mii->mii_media_active |= IFM_100_TX|IFM_FDX; + break; + case PCTL_100_T4: + mii->mii_media_active |= IFM_100_T4; + break; + case PCTL_AN: + mii->mii_media_active |= IFM_NONE; + break; + default: + /* Erg... this shouldn't happen. */ + mii->mii_media_active |= IFM_NONE; + break; + } } static void |