diff options
author | Kevin Lo <kevlo@cvs.openbsd.org> | 2011-09-03 14:33:52 +0000 |
---|---|---|
committer | Kevin Lo <kevlo@cvs.openbsd.org> | 2011-09-03 14:33:52 +0000 |
commit | 6833228f547d2ab17b41178659d0a35b6dda35ad (patch) | |
tree | 3a40917c0fa148e99294d7521c067d0cbb91399e /sys/dev | |
parent | 20b725fa81b43bb7d41b419ff6951882e2dfd72c (diff) |
Disable PHY hibernation. The PHY will 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 was plugged in such that it required turning the
interface down and then up to make it work. This was caused by
incorrectly programmed hibernation parameters. Further details
regarding PHY setup are necessary to be able to re-enable this
feature.
Tested by Matteo Filippetto and Gabriel Linder
From FreeBSD via Brad
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_alc.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/sys/dev/pci/if_alc.c b/sys/dev/pci/if_alc.c index 2efda29788d..e8ecac8e3ce 100644 --- a/sys/dev/pci/if_alc.c +++ b/sys/dev/pci/if_alc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_alc.c,v 1.17 2011/08/26 07:49:04 kevlo Exp $ */ +/* $OpenBSD: if_alc.c,v 1.18 2011/09/03 14:33:51 kevlo Exp $ */ /*- * Copyright (c) 2009, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -420,13 +420,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); @@ -511,6 +509,23 @@ alc_phy_reset(struct alc_softc *sc) alc_miibus_writereg(&sc->sc_dev, sc->alc_phyaddr, ALC_MII_DBG_DATA, data); DELAY(1000); + + /* Disable hibernation. */ + alc_miibus_writereg(&sc->sc_dev, sc->alc_phyaddr, ALC_MII_DBG_ADDR, + 0x0029); + data = alc_miibus_readreg(&sc->sc_dev, sc->alc_phyaddr, + ALC_MII_DBG_DATA); + data &= ~0x8000; + alc_miibus_writereg(&sc->sc_dev, sc->alc_phyaddr, ALC_MII_DBG_DATA, + data); + + alc_miibus_writereg(&sc->sc_dev, sc->alc_phyaddr, ALC_MII_DBG_ADDR, + 0x000B); + data = alc_miibus_readreg(&sc->sc_dev, sc->alc_phyaddr, + ALC_MII_DBG_DATA); + data &= ~0x8000; + alc_miibus_writereg(&sc->sc_dev, sc->alc_phyaddr, ALC_MII_DBG_DATA, + data); } void @@ -535,8 +550,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); |