diff options
Diffstat (limited to 'freebsd/sys/dev/mii/rgephy.c')
-rw-r--r-- | freebsd/sys/dev/mii/rgephy.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/freebsd/sys/dev/mii/rgephy.c b/freebsd/sys/dev/mii/rgephy.c index 8dacb0e8..067bbadf 100644 --- a/freebsd/sys/dev/mii/rgephy.c +++ b/freebsd/sys/dev/mii/rgephy.c @@ -44,9 +44,11 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/module.h> #include <sys/socket.h> +#include <sys/taskqueue.h> #include <sys/bus.h> #include <net/if.h> +#include <net/if_var.h> #include <net/if_arp.h> #include <net/if_media.h> @@ -59,7 +61,7 @@ __FBSDID("$FreeBSD$"); #include <rtems/bsd/local/miibus_if.h> #include <machine/bus.h> -#include <pci/if_rlreg.h> +#include <dev/rl/if_rlreg.h> static int rgephy_probe(device_t); static int rgephy_attach(device_t); @@ -90,6 +92,7 @@ static void rgephy_reset(struct mii_softc *); static int rgephy_linkup(struct mii_softc *); static void rgephy_loop(struct mii_softc *); static void rgephy_load_dspcode(struct mii_softc *); +static void rgephy_disable_eee(struct mii_softc *); static const struct mii_phydesc rgephys[] = { MII_PHY_DESC(REALTEK, RTL8169S), @@ -114,13 +117,11 @@ static int rgephy_attach(device_t dev) { struct mii_softc *sc; - struct mii_attach_args *ma; u_int flags; sc = device_get_softc(dev); - ma = device_get_ivars(dev); flags = 0; - if (strcmp(ma->mii_data->mii_ifp->if_dname, "re") == 0) + if (mii_dev_mac_match(dev, "re")) flags |= MIIF_PHYPRIV0; mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0); @@ -157,12 +158,6 @@ rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) break; case MII_MEDIACHG: - /* - * If the interface is not up, don't do anything. - */ - if ((mii->mii_ifp->if_flags & IFF_UP) == 0) - break; - PHY_RESET(sc); /* XXX hardware bug work-around */ anar = PHY_READ(sc, RGEPHY_MII_ANAR); @@ -235,12 +230,6 @@ setit: case MII_TICK: /* - * Is the interface even up? - */ - if ((mii->mii_ifp->if_flags & IFF_UP) == 0) - return (0); - - /* * Only used for autonegotiation. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { @@ -531,10 +520,9 @@ rgephy_reset(struct mii_softc *sc) switch (sc->mii_mpd_rev) { case RGEPHY_8211F: pcr = PHY_READ(sc, RGEPHY_F_MII_PCR1); - if ((pcr & RGEPHY_F_PCR1_MDI_MM) != 0) { - pcr &= ~RGEPHY_F_PCR1_MDI_MM; - PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr); - } + pcr &= ~(RGEPHY_F_PCR1_MDI_MM | RGEPHY_F_PCR1_ALDPS_EN); + PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr); + rgephy_disable_eee(sc); break; case RGEPHY_8211C: if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) { @@ -562,3 +550,29 @@ rgephy_reset(struct mii_softc *sc) DELAY(1000); rgephy_load_dspcode(sc); } + +static void +rgephy_disable_eee(struct mii_softc *sc) +{ + uint16_t anar; + + PHY_WRITE(sc, RGEPHY_F_EPAGSR, 0x0000); + PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_ADDRESS | + (MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7)); + PHY_WRITE(sc, MII_MMDAADR, RGEPHY_F_MMD_EEEAR); + PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_DATANPI | + (MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7)); + PHY_WRITE(sc, MII_MMDAADR, 0x0000); + PHY_WRITE(sc, MII_MMDACR, 0x0000); + /* + * XXX + * Restart auto-negotiation to take changes effect. + * This may result in link establishment. + */ + anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; + PHY_WRITE(sc, RGEPHY_MII_ANAR, anar); + PHY_WRITE(sc, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD | + RGEPHY_1000CTL_AFD); + PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_RESET | + RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); +} |