--- rgephy.c.orig Tue Mar 27 16:35:53 2007 +++ rgephy.c Tue Mar 27 16:43:28 2007 @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD: src/sys/dev/mii/rgephy.c,v 1.6.2.3 2006/08/17 00:08:26 yongari Exp $"); /* - * Driver for the RealTek 8169S/8110S internal 10/100/1000 PHY. + * Driver for the RealTek 8211B/8169S/8110S internal 10/100/1000 PHY. */ #include @@ -174,7 +174,8 @@ { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg, speed, gig, anar; - + uint16_t id2; + switch (cmd) { case MII_POLLSTAT: /* @@ -301,9 +302,16 @@ * need to restart the autonegotiation process. Read * the BMSR twice in case it's latched. */ - reg = PHY_READ(sc, RL_GMEDIASTAT); - if (reg & RL_GMEDIASTAT_LINK) - break; + id2 = PHY_READ(sc, MII_PHYIDR2); + if (MII_REV(id2) < 2) { + reg = PHY_READ(sc, RL_GMEDIASTAT); + if (reg & RL_GMEDIASTAT_LINK) + break; + } else { + reg = PHY_READ(sc, RGEPHY_SR); + if (reg & RGEPHY_SR_LINK) + break; + } /* * Only retry autonegotiation every 5 seconds. @@ -339,14 +347,22 @@ { struct mii_data *mii = sc->mii_pdata; int bmsr, bmcr; + uint16_t id2; mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER; - bmsr = PHY_READ(sc, RL_GMEDIASTAT); + id2 = PHY_READ(sc, MII_PHYIDR2); + if (MII_REV(id2) < 2) { + bmsr = PHY_READ(sc, RL_GMEDIASTAT); + if (bmsr & RL_GMEDIASTAT_LINK) + mii->mii_media_status |= IFM_ACTIVE; + } else { + bmsr = PHY_READ(sc, RGEPHY_SR); + if (bmsr & RGEPHY_SR_LINK) + mii->mii_media_status |= IFM_ACTIVE; + } - if (bmsr & RL_GMEDIASTAT_LINK) - mii->mii_media_status |= IFM_ACTIVE; bmsr = PHY_READ(sc, RGEPHY_MII_BMSR); bmcr = PHY_READ(sc, RGEPHY_MII_BMCR); @@ -362,18 +378,31 @@ } } - bmsr = PHY_READ(sc, RL_GMEDIASTAT); - if (bmsr & RL_GMEDIASTAT_1000MBPS) - mii->mii_media_active |= IFM_1000_T; - else if (bmsr & RL_GMEDIASTAT_100MBPS) - mii->mii_media_active |= IFM_100_TX; - else if (bmsr & RL_GMEDIASTAT_10MBPS) - mii->mii_media_active |= IFM_10_T; - else - mii->mii_media_active |= IFM_NONE; - if (bmsr & RL_GMEDIASTAT_FDX) - mii->mii_media_active |= IFM_FDX; - + if (MII_REV(id2) < 2) { + bmsr = PHY_READ(sc, RL_GMEDIASTAT); + if (bmsr & RL_GMEDIASTAT_1000MBPS) + mii->mii_media_active |= IFM_1000_T; + else if (bmsr & RL_GMEDIASTAT_100MBPS) + mii->mii_media_active |= IFM_100_TX; + else if (bmsr & RL_GMEDIASTAT_10MBPS) + mii->mii_media_active |= IFM_10_T; + else + mii->mii_media_active |= IFM_NONE; + if (bmsr & RL_GMEDIASTAT_FDX) + mii->mii_media_active |= IFM_FDX; + } else { + bmsr = PHY_READ(sc, RGEPHY_SR); + if (RGEPHY_SR_SPEED(bmsr) == 2) + mii->mii_media_active |= IFM_1000_T; + else if (RGEPHY_SR_SPEED(bmsr) == 1) + mii->mii_media_active |= IFM_100_TX; + else if (RGEPHY_SR_SPEED(bmsr) == 0) + mii->mii_media_active |= IFM_10_T; + else + mii->mii_media_active |= IFM_NONE; + if (bmsr & RGEPHY_SR_FDX) + mii->mii_media_active |= IFM_FDX; + } return; } @@ -382,12 +411,21 @@ rgephy_mii_phy_auto(mii) struct mii_softc *mii; { - rgephy_loop(mii); - rgephy_reset(mii); + uint16_t id2; + + id2 = PHY_READ(mii, MII_PHYIDR2); + + if (MII_REV(id2) < 2) { + rgephy_loop(mii); + rgephy_reset(mii); + } PHY_WRITE(mii, RGEPHY_MII_ANAR, BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA); DELAY(1000); + /* printf ("PHY Set TXC=25MHZ\n"); */ + /* Set TXC=25MHz */ + /* PHY_WRITE(mii, RGEPHY_EXT_CR, (7 << 4)); */ PHY_WRITE(mii, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD|RGEPHY_1000CTL_AFD); DELAY(1000); @@ -403,9 +441,14 @@ { u_int32_t bmsr; int i; + uint16_t id2; - PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN); - DELAY(1000); + id2 = PHY_READ(sc, MII_PHYIDR2); + + if (MII_REV(id2) < 2) { + PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN); + DELAY(1000); + } for (i = 0; i < 15000; i++) { bmsr = PHY_READ(sc, RGEPHY_MII_BMSR); @@ -488,9 +531,14 @@ static void rgephy_reset(struct mii_softc *sc) { + uint16_t id2; + mii_phy_reset(sc); - DELAY(1000); - rgephy_load_dspcode(sc); + id2 = PHY_READ(sc, MII_PHYIDR2); + if (MII_REV(id2) < 2) { + DELAY(1000); + rgephy_load_dspcode(sc); + } return; } --- rgephyreg.h.orig Tue Mar 27 16:35:53 2007 +++ rgephyreg.h Tue Mar 27 16:36:34 2007 @@ -138,5 +138,15 @@ #define RGEPHY_EXTSTS_T_HD_CAP 0x1000 /* 1000base-T HD capable */ +/* RTL8211B */ +#define RGEPHY_SR 0x11 +#define RGEPHY_SR_CROSSOVER (1<< 6) +#define RGEPHY_SR_LINK (1<<10) +#define RGEPHY_SR_FDX (1<<13) +#define RGEPHY_SR_SPEED(X) (((X)>>14)&3) + +#define RGEPHY_EXT_CR 0x14 + + #endif /* _DEV_RGEPHY_MIIREG_H_ */ --- miidevs.orig Tue Mar 27 16:43:47 2007 +++ miidevs Tue Mar 27 16:45:00 2007 @@ -93,7 +93,7 @@ /* Don't know what's going on here. */ oui xxDAVICOM 0x006040 Davicom Semiconductor -/* This is the OUI of the gigE PHY in the RealTek 8169S/8110S chips */ +/* This is the OUI of the gigE PHY in the RealTek 8211B/8169S/8110S chips */ oui xxREALTEK 0x000732 /* @@ -167,7 +167,7 @@ /* RealTek Semiconductor PHYs */ model REALTEK RTL8201L 0x0020 RTL8201L 10/100 media interface -model xxREALTEK RTL8169S 0x0011 RTL8169S/8110S media interface +model xxREALTEK RTL8169S 0x0011 RTL8211B/8169S/8110S media interface /* Seeq PHYs */ model xxSEEQ 80220 0x0003 Seeq 80220 10/100 media interface