Disable PHY hibernation until I get more detailed hibernation

programming secret.  The PHY would go into sleep state when it
detects no established link and it will re-establish link when the
cable is plugged in.  Previously it failed to re-establish link
when the cable is plugged in such that it required to manually down
and up the interface again to make it work.  This came from
incorrectly programmed hibernation parameters.  According to
Atheros, each PHY chip requires different configuration for
hibernation and different vendor has different settings for the
same chip.
Disabling hibernation may consume more power but establishing link
looks more important than saving power.
Special thanks to Atheros for giving me instructions that disable
hibernation.

MFC after:	1 week
Approved by:	re (kib)
This commit is contained in:
Pyun YongHyeon 2011-08-22 20:33:05 +00:00
parent 5a7ca5ee05
commit 462d5251d7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=225088

View File

@ -532,13 +532,11 @@ alc_phy_reset(struct alc_softc *sc)
uint16_t data;
/* Reset magic from Linux. */
CSR_WRITE_2(sc, ALC_GPHY_CFG,
GPHY_CFG_HIB_EN | GPHY_CFG_HIB_PULSE | GPHY_CFG_SEL_ANA_RESET);
CSR_WRITE_2(sc, ALC_GPHY_CFG, GPHY_CFG_SEL_ANA_RESET);
CSR_READ_2(sc, ALC_GPHY_CFG);
DELAY(10 * 1000);
CSR_WRITE_2(sc, ALC_GPHY_CFG,
GPHY_CFG_EXT_RESET | GPHY_CFG_HIB_EN | GPHY_CFG_HIB_PULSE |
CSR_WRITE_2(sc, ALC_GPHY_CFG, GPHY_CFG_EXT_RESET |
GPHY_CFG_SEL_ANA_RESET);
CSR_READ_2(sc, ALC_GPHY_CFG);
DELAY(10 * 1000);
@ -623,6 +621,23 @@ alc_phy_reset(struct alc_softc *sc)
alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
ALC_MII_DBG_DATA, data);
DELAY(1000);
/* Disable hibernation. */
alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr, ALC_MII_DBG_ADDR,
0x0029);
data = alc_miibus_readreg(sc->alc_dev, sc->alc_phyaddr,
ALC_MII_DBG_DATA);
data &= ~0x8000;
alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr, ALC_MII_DBG_DATA,
data);
alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr, ALC_MII_DBG_ADDR,
0x000B);
data = alc_miibus_readreg(sc->alc_dev, sc->alc_phyaddr,
ALC_MII_DBG_DATA);
data &= ~0x8000;
alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr, ALC_MII_DBG_DATA,
data);
}
static void
@ -648,8 +663,7 @@ alc_phy_down(struct alc_softc *sc)
break;
default:
/* Force PHY down. */
CSR_WRITE_2(sc, ALC_GPHY_CFG,
GPHY_CFG_EXT_RESET | GPHY_CFG_HIB_EN | GPHY_CFG_HIB_PULSE |
CSR_WRITE_2(sc, ALC_GPHY_CFG, GPHY_CFG_EXT_RESET |
GPHY_CFG_SEL_ANA_RESET | GPHY_CFG_PHY_IDDQ |
GPHY_CFG_PWDOWN_HW);
DELAY(1000);