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.) This will be used once I add the if_lge driver to support
the LXT10010 chip.
This commit is contained in:
Bill Paul 2001-05-23 22:10:55 +00:00
parent 576f0c5fa4
commit 134c58d3c0
3 changed files with 23 additions and 8 deletions

View File

@ -55,6 +55,7 @@ oui BROADCOM 0x001018 Broadcom Corporation
oui DAVICOM 0x00606e Davicom Semiconductor
oui ICS 0x00a0be Integrated Circuit Systems
oui INTEL 0x00aa00 Intel
oui JATO 0x00e083 Jato Technologies
oui LEVEL1 0x00207b Level 1
oui NATSEMI 0x080017 National Semiconductor
oui QUALSEMI 0x006051 Quality Semiconductor
@ -118,6 +119,9 @@ model INTEL I82562EM 0x0032 i82562EM 10/100 media interface
model INTEL I82562ET 0x0033 i82562ET 10/100 media interface
model INTEL I82553C 0x0035 i82553 10/100 media interface
/* Jato Technologies PHYs */
model JATO BASEX 0x0000 Jato 1000baseX media interface
/* Level 1 PHYs */
model xxLEVEL1 LXT970 0x0000 LXT970 10/100 media interface

View File

@ -98,13 +98,19 @@ static int xmphy_probe(dev)
ma = device_get_ivars(dev);
if (MII_OUI(ma->mii_id1, ma->mii_id2) != MII_OUI_xxXAQTI ||
MII_MODEL(ma->mii_id2) != MII_MODEL_XAQTI_XMACII)
return(ENXIO);
if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxXAQTI &&
MII_MODEL(ma->mii_id2) == MII_MODEL_XAQTI_XMACII) {
device_set_desc(dev, MII_STR_XAQTI_XMACII);
return(0);
}
device_set_desc(dev, MII_STR_XAQTI_XMACII);
if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_JATO &&
MII_MODEL(ma->mii_id2) == MII_MODEL_JATO_BASEX) {
device_set_desc(dev, MII_STR_JATO_BASEX);
return(0);
}
return(0);
return(ENXIO);
}
static int xmphy_attach(dev)
@ -210,11 +216,13 @@ xmphy_service(sc, mii, 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:
@ -349,11 +357,13 @@ xmphy_mii_phy_auto(mii, waitfor)
struct mii_softc *mii;
int waitfor;
{
int bmsr, i;
int bmsr, anar = 0, i;
if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) {
PHY_WRITE(mii, XMPHY_MII_ANAR,
XMPHY_ANAR_FDX|XMPHY_ANAR_HDX);
anar = PHY_READ(mii, XMPHY_MII_ANAR);
anar |= XMPHY_ANAR_FDX|XMPHY_ANAR_HDX;
PHY_WRITE(mii, XMPHY_MII_ANAR, anar);
DELAY(1000);
PHY_WRITE(mii, XMPHY_MII_BMCR,
XMPHY_BMCR_AUTOEN | XMPHY_BMCR_STARTNEG);
}

View File

@ -44,6 +44,7 @@
#define XMPHY_BMCR_LOOP 0x4000
#define XMPHY_BMCR_AUTOEN 0x1000 /* Autoneg enabled */
#define XMPHY_BMCR_PDOWN 0x0800 /* Power down */
#define XMPHY_BMCR_ISO 0x0400 /* Isolate */
#define XMPHY_BMCR_STARTNEG 0x0200 /* Restart autoneg */
#define XMPHY_BMCR_FDX 0x0100 /* Duplex mode */