summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2011-08-19 19:12:58 +0000
committermarius <marius@FreeBSD.org>2011-08-19 19:12:58 +0000
commit2852f5cc381b4789a383f57d7ae05c5752eb69eb (patch)
tree92ff24c835440203422d9ec935c2eae0d2ebddea
parentb31a18eeb421bb3ef0f05f205f940cca8a5b1c1f (diff)
downloadFreeBSD-src-2852f5cc381b4789a383f57d7ae05c5752eb69eb.zip
FreeBSD-src-2852f5cc381b4789a383f57d7ae05c5752eb69eb.tar.gz
r221812 reveals that at least some Broadcom PHYs default to being not only
isolated but also powered down after a reset and while they just work fine [sic] when both is the case they don't if they are only deisolate but still powered down. So in order to put PHYs in an overall normal operation mode for the common case, ensure in mii_phy_reset() that they are not powered down after a reset. Unfortunately, this only helps in case of BCM5421, while BCM5709S apparently only work when they remain isolated and powered down after a reset. So don't call mii_phy_reset() in brgphy_reset() and implement the reset locally leaving the problematic bits alone. Effectively this bypasses r221812 for brgphy(4). Thanks to Justin Hibbits for doing a binary search in order to identify the problematic commit. PR: 157405, 158156 Reviewed by: yongari (mii_phy_reset() part) Approved by: re (kib) MFC after: 3 days
-rw-r--r--sys/dev/mii/brgphy.c18
-rw-r--r--sys/dev/mii/mii_physubr.c4
2 files changed, 17 insertions, 5 deletions
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index 8e3986a..88090b7 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -876,10 +876,22 @@ brgphy_reset(struct mii_softc *sc)
struct bge_softc *bge_sc = NULL;
struct bce_softc *bce_sc = NULL;
struct ifnet *ifp;
- int val;
+ int i, val;
+
+ /*
+ * Perform a reset. Note that at least some Broadcom PHYs default to
+ * being powered down as well as isolated after a reset but don't work
+ * if one or both of these bits are cleared. However, they just work
+ * fine if both bits remain set, so we don't use mii_phy_reset() here.
+ */
+ PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_RESET);
- /* Perform a standard PHY reset. */
- mii_phy_reset(sc);
+ /* Wait 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ if ((PHY_READ(sc, BRGPHY_MII_BMCR) & BRGPHY_BMCR_RESET) == 0)
+ break;
+ DELAY(1000);
+ }
/* Handle any PHY specific procedures following the reset. */
switch (sc->mii_mpd_oui) {
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c
index be66505..8e1476a 100644
--- a/sys/dev/mii/mii_physubr.c
+++ b/sys/dev/mii/mii_physubr.c
@@ -273,8 +273,8 @@ mii_phy_reset(struct mii_softc *sc)
DELAY(1000);
}
- /* NB: a PHY may default to isolation. */
- reg &= ~BMCR_ISO;
+ /* NB: a PHY may default to being powered down and/or isolated. */
+ reg &= ~(BMCR_PDOWN | BMCR_ISO);
if ((sc->mii_flags & MIIF_NOISOLATE) == 0 &&
((ife == NULL && sc->mii_inst != 0) ||
(ife != NULL && IFM_INST(ife->ifm_media) != sc->mii_inst)))
OpenPOWER on IntegriCloud