summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/mii/rgephy.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/mii/rgephy.c')
-rw-r--r--freebsd/sys/dev/mii/rgephy.c54
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);
+}