aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ucc_geth_ethtool.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-08-27 07:35:57 +0000
committerDavid S. Miller <davem@davemloft.net>2009-08-30 21:51:47 -0700
commit2394905f67aeec5f9452f2881cbeb2b42009de0e (patch)
tree799de0b229027408b0f894cb9f50e36f4707f3d7 /drivers/net/ucc_geth_ethtool.c
parentucc_geth: Remove UGETH_MAGIC_PACKET Kconfig symbol and code (diff)
downloadlinux-dev-2394905f67aeec5f9452f2881cbeb2b42009de0e.tar.xz
linux-dev-2394905f67aeec5f9452f2881cbeb2b42009de0e.zip
ucc_geth: Implement suspend/resume and Wake-On-LAN support
This patch implements suspend/resume and WOL support for UCC Ethernet driver. We support two wake up events: wake on PHY/link changes and wake on magic packet. In some CPUs (like MPC8569) QE shuts down during sleep, so magic packet detection is unusable, and also on resume we should fully reinitialize UCC structures. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ucc_geth_ethtool.c')
-rw-r--r--drivers/net/ucc_geth_ethtool.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 304128fa6058..7075f26e97da 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -359,6 +359,44 @@ uec_get_drvinfo(struct net_device *netdev,
drvinfo->regdump_len = uec_get_regs_len(netdev);
}
+#ifdef CONFIG_PM
+
+static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ struct phy_device *phydev = ugeth->phydev;
+
+ if (phydev && phydev->irq)
+ wol->supported |= WAKE_PHY;
+ if (qe_alive_during_sleep())
+ wol->supported |= WAKE_MAGIC;
+
+ wol->wolopts = ugeth->wol_en;
+}
+
+static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ struct phy_device *phydev = ugeth->phydev;
+
+ if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
+ return -EINVAL;
+ else if (wol->wolopts & WAKE_PHY && (!phydev || !phydev->irq))
+ return -EINVAL;
+ else if (wol->wolopts & WAKE_MAGIC && !qe_alive_during_sleep())
+ return -EINVAL;
+
+ ugeth->wol_en = wol->wolopts;
+ device_set_wakeup_enable(&netdev->dev, ugeth->wol_en);
+
+ return 0;
+}
+
+#else
+#define uec_get_wol NULL
+#define uec_set_wol NULL
+#endif /* CONFIG_PM */
+
static const struct ethtool_ops uec_ethtool_ops = {
.get_settings = uec_get_settings,
.set_settings = uec_set_settings,
@@ -377,6 +415,8 @@ static const struct ethtool_ops uec_ethtool_ops = {
.get_sset_count = uec_get_sset_count,
.get_strings = uec_get_strings,
.get_ethtool_stats = uec_get_ethtool_stats,
+ .get_wol = uec_get_wol,
+ .set_wol = uec_set_wol,
};
void uec_set_ethtool_ops(struct net_device *netdev)