summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsemenu <semenu@FreeBSD.org>2002-05-01 19:15:54 +0000
committersemenu <semenu@FreeBSD.org>2002-05-01 19:15:54 +0000
commit7c4d7211448ad4ae368cf07cc871c6052895b73f (patch)
tree304ca0e4c18d3fb7bc12110f504ab37205711fa9 /sys
parent59e363cb4e865ff7d8b202404ec9fe6769815abf (diff)
downloadFreeBSD-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.c56
-rw-r--r--sys/dev/mii/qsphy.c108
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
OpenPOWER on IntegriCloud