summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorKevin Lo <kevlo@cvs.openbsd.org>2011-09-03 14:33:52 +0000
committerKevin Lo <kevlo@cvs.openbsd.org>2011-09-03 14:33:52 +0000
commit6833228f547d2ab17b41178659d0a35b6dda35ad (patch)
tree3a40917c0fa148e99294d7521c067d0cbb91399e /sys/dev
parent20b725fa81b43bb7d41b419ff6951882e2dfd72c (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.c28
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);