summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-06-19 17:08:15 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-06-19 17:08:15 +0000
commitfcddca6386d7f38522d420db6ddf9afd5afc53ff (patch)
treea6fec10c41f17454ee1558c6400ec8ad5e64881b
parent152fcabed25d35558080ad2c42f23869e3091c7a (diff)
rev 1.4
Tweak the xmphy driver a little bit based on something I learned about the built-in 1000baseX interface in the Level 1 LXT1001 chip. The Level 1 PHY comes up with the isolate bit in the control register set by default, but it also has the autonegotiate bit set. When you tell the xmphy driver to select IFM_AUTO mode, it sees that the autoneg bit is already on, and thus doesn't bother updating the control register. However this means that the isolate bit is never turned off (unless you manually select 1000baseSX full or half duplex mode, which does result in the control register being modified and the ISO bit being turned off). This subtle and unusual behavioral difference stopped me from being able to receive packets on the SMC9462TX card for several days, since isolating the PHY disconnects it from the MAC's data interface. The fix is to omit the 'is the autoneg big set?' test, since it doesn't really provide much of an optimization anyway. This commit also updates the xmphy driver to support the Jato/Level 1 internal PHY. (I'm not sure how Jato Technologies is related to Level 1: all I know is the OUI from the PHY ID registers maps to Jato in the OUI database.) From FreeBSD
-rw-r--r--sys/dev/mii/xmphy.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/sys/dev/mii/xmphy.c b/sys/dev/mii/xmphy.c
index 5e6109304b1..f90d0869bda 100644
--- a/sys/dev/mii/xmphy.c
+++ b/sys/dev/mii/xmphy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xmphy.c,v 1.12 2005/03/26 04:40:09 krw Exp $ */
+/* $OpenBSD: xmphy.c,v 1.13 2005/06/19 17:08:14 brad Exp $ */
/*
* Copyright (c) 2000
@@ -81,6 +81,9 @@ static const struct mii_phydesc xmphys[] = {
{ MII_OUI_xxXAQTI, MII_MODEL_XAQTI_XMACII,
MII_STR_XAQTI_XMACII },
+ { MII_OUI_JATO, MII_MODEL_JATO_BASEX,
+ MII_STR_JATO_BASEX },
+
{ 0, 0,
NULL },
};
@@ -90,9 +93,9 @@ int xmphy_probe(struct device *parent, void *match, void *aux)
struct mii_attach_args *ma = aux;
if (mii_phy_match(ma, xmphys) != NULL)
- return(10);
+ return (10);
- return(0);
+ return (0);
}
void
@@ -167,11 +170,13 @@ xmphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
switch (IFM_SUBTYPE(ife->ifm_media)) {
case IFM_AUTO:
+#ifdef foo
/*
* If we're already in auto mode, just return.
*/
if (PHY_READ(sc, XMPHY_MII_BMCR) & XMPHY_BMCR_AUTOEN)
return (0);
+#endif
(void) xmphy_mii_phy_auto(sc, 1);
break;
case IFM_1000_SX:
@@ -200,38 +205,38 @@ xmphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
return (0);
/*
- * Only used for autonegotiation.
- */
- if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
- return (0);
-
- /*
* Is the interface even up?
*/
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
return (0);
/*
- * Only retry autonegotiation every mii_anegticks seconds.
+ * Only used for autonegotiation.
*/
- if (++sc->mii_ticks <= sc->mii_anegticks)
- return (0);
+ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
+ break;
- sc->mii_ticks = 0;
+ /*
+ * Check to see if we have link. If we do, we don't
+ * need to restart the autonegotiation process. Read
+ * the BMSR twice in case it's latched.
+ */
+ reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
+ if (reg & BMSR_LINK)
+ break;
/*
- * Check to see if we have link. If we do, we don't
- * need to restart the autonegotiation process. Read
- * the BMSR twice in case it's latched.
+ * Only retry autonegotiation every mii_anegticks seconds.
*/
- reg = PHY_READ(sc, XMPHY_MII_BMSR) |
- PHY_READ(sc, XMPHY_MII_BMSR);
- if (reg & XMPHY_BMSR_LINK)
+ if (++sc->mii_ticks <= sc->mii_anegticks)
break;
+ sc->mii_ticks = 0;
+
PHY_RESET(sc);
+
if (xmphy_mii_phy_auto(sc, 0) == EJUSTRETURN)
- return(0);
+ return (0);
break;
}
@@ -300,11 +305,13 @@ xmphy_status(struct mii_softc *sc)
int
xmphy_mii_phy_auto(struct mii_softc *sc, int waitfor)
{
- int bmsr, i;
+ int bmsr, anar = 0, i;
if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) {
- PHY_WRITE(sc, XMPHY_MII_ANAR,
- XMPHY_ANAR_FDX|XMPHY_ANAR_HDX);
+ anar = PHY_READ(sc, XMPHY_MII_ANAR);
+ anar |= XMPHY_ANAR_FDX|XMPHY_ANAR_HDX;
+ PHY_WRITE(sc, XMPHY_MII_ANAR, anar);
+ DELAY(1000);
PHY_WRITE(sc, XMPHY_MII_BMCR,
XMPHY_BMCR_AUTOEN | XMPHY_BMCR_STARTNEG);
}