aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ae
diff options
context:
space:
mode:
authorBruce M Simpson <bms@FreeBSD.org>2009-03-18 17:14:44 +0000
committerBruce M Simpson <bms@FreeBSD.org>2009-03-18 17:14:44 +0000
commit7bc9d2e6fb97d4c8396c5f9a156b649fe7eccf8b (patch)
treeb73fb2d8e99ee8f352cecf641a25caf990c4c740 /sys/dev/ae
parentc552ce951bbcc48071bef8d670332bab8241659a (diff)
Notes
Diffstat (limited to 'sys/dev/ae')
-rw-r--r--sys/dev/ae/if_ae.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c
index 34165245b878..345a01f708fd 100644
--- a/sys/dev/ae/if_ae.c
+++ b/sys/dev/ae/if_ae.c
@@ -380,8 +380,10 @@ ae_attach(device_t dev)
ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
IFQ_SET_READY(&ifp->if_snd);
- if (pci_find_extcap(dev, PCIY_PMG, &pmc) == 0)
+ if (pci_find_extcap(dev, PCIY_PMG, &pmc) == 0) {
+ ifp->if_capabilities |= IFCAP_WOL_MAGIC;
sc->flags |= AE_FLAG_PMG;
+ }
ifp->if_capenable = ifp->if_capabilities;
/*
@@ -1329,6 +1331,7 @@ ae_pm_init(ae_softc_t *sc)
struct ifnet *ifp;
uint32_t val;
uint16_t pmstat;
+ struct mii_data *mii;
int pmc;
AE_LOCK_ASSERT(sc);
@@ -1340,7 +1343,40 @@ ae_pm_init(ae_softc_t *sc)
return;
}
- ae_powersave_enable(sc);
+ /*
+ * Configure WOL if enabled.
+ */
+ if ((ifp->if_capenable & IFCAP_WOL) != 0) {
+ mii = device_get_softc(sc->miibus);
+ mii_pollstat(mii);
+ if ((mii->mii_media_status & IFM_AVALID) != 0 &&
+ (mii->mii_media_status & IFM_ACTIVE) != 0) {
+ AE_WRITE_4(sc, AE_WOL_REG, AE_WOL_MAGIC | \
+ AE_WOL_MAGIC_PME);
+
+ /*
+ * Configure MAC.
+ */
+ val = AE_MAC_RX_EN | AE_MAC_CLK_PHY | \
+ AE_MAC_TX_CRC_EN | AE_MAC_TX_AUTOPAD | \
+ ((AE_HALFBUF_DEFAULT << AE_HALFBUF_SHIFT) & \
+ AE_HALFBUF_MASK) | \
+ ((AE_MAC_PREAMBLE_DEFAULT << \
+ AE_MAC_PREAMBLE_SHIFT) & AE_MAC_PREAMBLE_MASK) | \
+ AE_MAC_BCAST_EN | AE_MAC_MCAST_EN;
+ if ((IFM_OPTIONS(mii->mii_media_active) & \
+ IFM_FDX) != 0)
+ val |= AE_MAC_FULL_DUPLEX;
+ AE_WRITE_4(sc, AE_MAC_REG, val);
+
+ } else { /* No link. */
+ AE_WRITE_4(sc, AE_WOL_REG, AE_WOL_LNKCHG | \
+ AE_WOL_LNKCHG_PME);
+ AE_WRITE_4(sc, AE_MAC_REG, 0);
+ }
+ } else {
+ ae_powersave_enable(sc);
+ }
/*
* PCIE hacks. Magic numbers.
@@ -1358,6 +1394,8 @@ ae_pm_init(ae_softc_t *sc)
pci_find_extcap(sc->dev, PCIY_PMG, &pmc);
pmstat = pci_read_config(sc->dev, pmc + PCIR_POWER_STATUS, 2);
pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
+ if ((ifp->if_capenable & IFCAP_WOL) != 0)
+ pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
}