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
This commit is contained in:
Semen Ustimenko 2002-05-01 19:15:54 +00:00
parent 6af7484d0f
commit 4592db4635
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=95877
2 changed files with 55 additions and 109 deletions

View File

@ -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));
@ -229,12 +227,6 @@ acphy_service(sc, mii, cmd)
break;
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?
*/
@ -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

View File

@ -180,26 +180,24 @@ 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.
*/
@ -228,12 +226,6 @@ qsphy_service(sc, mii, cmd)
break;
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?
*/
@ -247,23 +239,8 @@ qsphy_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;
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