Due to the poor PHY documentation from RealTek I can't sure but I
think the RealTek PHY needs driver to set RGEPHY_BMCR_AUTOEN bit of RGEPHY_MII_BMCR register and proper ANAR register setting for manual media type selection. This fixes long standing manual media type selection bug in rgephy(4). Reported by: Jelte Jansen <jelte AT NLnetLabs DOT nl> Tested by: Jelte Jansen <jelte AT NLnetLabs DOT nl>
This commit is contained in:
parent
329532e54e
commit
4eb561d2e8
@ -166,7 +166,7 @@ static int
|
||||
rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
int reg, speed, gig;
|
||||
int reg, speed, gig, anar;
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
@ -196,6 +196,10 @@ rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
|
||||
rgephy_reset(sc); /* XXX hardware bug work-around */
|
||||
|
||||
anar = PHY_READ(sc, RGEPHY_MII_ANAR);
|
||||
anar &= ~(RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX |
|
||||
RGEPHY_ANAR_10_FD | RGEPHY_ANAR_10);
|
||||
|
||||
switch (IFM_SUBTYPE(ife->ifm_media)) {
|
||||
case IFM_AUTO:
|
||||
#ifdef foo
|
||||
@ -212,28 +216,30 @@ rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
goto setit;
|
||||
case IFM_100_TX:
|
||||
speed = RGEPHY_S100;
|
||||
anar |= RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX;
|
||||
goto setit;
|
||||
case IFM_10_T:
|
||||
speed = RGEPHY_S10;
|
||||
anar |= RGEPHY_ANAR_10_FD | RGEPHY_ANAR_10;
|
||||
setit:
|
||||
rgephy_loop(sc);
|
||||
if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) {
|
||||
speed |= RGEPHY_BMCR_FDX;
|
||||
gig = RGEPHY_1000CTL_AFD;
|
||||
anar &= ~(RGEPHY_ANAR_TX | RGEPHY_ANAR_10);
|
||||
} else {
|
||||
gig = RGEPHY_1000CTL_AHD;
|
||||
anar &=
|
||||
~(RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_10_FD);
|
||||
}
|
||||
|
||||
PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0);
|
||||
PHY_WRITE(sc, RGEPHY_MII_BMCR, speed);
|
||||
PHY_WRITE(sc, RGEPHY_MII_ANAR, RGEPHY_SEL_TYPE);
|
||||
|
||||
if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T)
|
||||
if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T) {
|
||||
PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0);
|
||||
PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
|
||||
PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
|
||||
RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
|
||||
break;
|
||||
|
||||
PHY_WRITE(sc, RGEPHY_MII_1000CTL, gig);
|
||||
PHY_WRITE(sc, RGEPHY_MII_BMCR,
|
||||
speed|RGEPHY_BMCR_AUTOEN|RGEPHY_BMCR_STARTNEG);
|
||||
}
|
||||
|
||||
/*
|
||||
* When settning the link manually, one side must
|
||||
@ -250,6 +256,8 @@ setit:
|
||||
PHY_WRITE(sc, RGEPHY_MII_1000CTL,
|
||||
gig|RGEPHY_1000CTL_MSE);
|
||||
}
|
||||
PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
|
||||
RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
|
||||
break;
|
||||
#ifdef foo
|
||||
case IFM_NONE:
|
||||
|
Loading…
x
Reference in New Issue
Block a user