Disable EEE(Energy Efficient Ethernet) for RTL8211F PHY.

It seems the EEE made RX MAC enter LPI(Low Power Idle) mode such
that dwc(4) was not able to receive packets.  Ideally dwc(4) should
be able to use EEE to save power during periods of low link
utilization(i.e. gating off clock).  Due to lack of dwc(4)
datasheet it's not easy to take required steps for EEE on LPI
enter/exit events.  Disabling EEE in PHY seems to be easy
workaround until dwc(4) supports EEE.

Updating EEE advertisement register on RTL8211F seems to have no
effect until reprogramming MII_ANAR, MII_100T2CR and MII_BMCR
with auto-negotiation. It's not clear whether it's related with
mii_phy_reset()'s BMCR_ISO handling for RTL8211F though.
It seems rgephy_reset() needs careful investigation for newer
RealTek PHYs.

Ganbold submitted working version based on NetBSD change and
tested lots of changes I made. Thanks a lot!

Submitted by:	ganbold (initial version)
In collaboration with:	ganbold
This commit is contained in:
Pyun YongHyeon 2015-12-03 05:27:39 +00:00
parent 003a7c2b01
commit 7aa69e3107
2 changed files with 46 additions and 4 deletions

View file

@ -90,6 +90,7 @@ static void rgephy_reset(struct mii_softc *);
static int rgephy_linkup(struct mii_softc *);
static void rgephy_loop(struct mii_softc *);
static void rgephy_load_dspcode(struct mii_softc *);
static void rgephy_disable_eee(struct mii_softc *);
static const struct mii_phydesc rgephys[] = {
MII_PHY_DESC(REALTEK, RTL8169S),
@ -517,10 +518,9 @@ rgephy_reset(struct mii_softc *sc)
switch (sc->mii_mpd_rev) {
case RGEPHY_8211F:
pcr = PHY_READ(sc, RGEPHY_F_MII_PCR1);
if ((pcr & RGEPHY_F_PCR1_MDI_MM) != 0) {
pcr &= ~RGEPHY_F_PCR1_MDI_MM;
PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr);
}
pcr &= ~(RGEPHY_F_PCR1_MDI_MM | RGEPHY_F_PCR1_ALDPS_EN);
PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr);
rgephy_disable_eee(sc);
break;
case RGEPHY_8211C:
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) {
@ -548,3 +548,29 @@ rgephy_reset(struct mii_softc *sc)
DELAY(1000);
rgephy_load_dspcode(sc);
}
static void
rgephy_disable_eee(struct mii_softc *sc)
{
uint16_t anar;
PHY_WRITE(sc, RGEPHY_F_EPAGSR, 0x0000);
PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_ADDRESS |
(MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7));
PHY_WRITE(sc, MII_MMDAADR, RGEPHY_F_MMD_EEEAR);
PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_DATANPI |
(MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7));
PHY_WRITE(sc, MII_MMDAADR, 0x0000);
PHY_WRITE(sc, MII_MMDACR, 0x0000);
/*
* XXX
* Restart auto-negotiation to take changes effect.
* This may result in link establishment.
*/
anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
PHY_WRITE(sc, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD |
RGEPHY_1000CTL_AFD);
PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_RESET |
RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
}

View file

@ -183,4 +183,20 @@
#define RGEPHY_F_SSR_MDI 0x0002 /* MDI/MDIX */
#define RGEPHY_F_SSR_JABBER 0x0001 /* Jabber */
/* RTL8211F */
#define RGEPHY_F_EPAGSR 0x1F /* Extension page select register */
/* RTL8211F */
#define RGEPHY_F_MMD_DEV_7 0x07
/* RTL8211F MMD device 7 */
#define RGEPHY_F_MMD_EEEAR 0x3C /* EEE advertisement */
#define EEEAR_1000T 0x0004 /* adv. 1000baseT EEE */
#define EEEAR_100TX 0x0002 /* adv. 100baseTX EEE */
/* RTL8211F MMD device 7 */
#define RGEPHY_F_MMD_EEELPAR 0x3D /* EEE link partner abilities */
#define EEELPAR_1000T 0x0004 /* link partner 1000baseT EEE capable */
#define EEELPAR_100TX 0x0002 /* link partner 100baseTX EEE capable */
#endif /* _DEV_RGEPHY_MIIREG_H_ */