aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/socionext/sni_ave.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c
index 9e7391faa1dc..1f9ef68d91ee 100644
--- a/drivers/net/ethernet/socionext/sni_ave.c
+++ b/drivers/net/ethernet/socionext/sni_ave.c
@@ -261,6 +261,7 @@ struct ave_private {
261 struct regmap *regmap; 261 struct regmap *regmap;
262 unsigned int pinmode_mask; 262 unsigned int pinmode_mask;
263 unsigned int pinmode_val; 263 unsigned int pinmode_val;
264 u32 wolopts;
264 265
265 /* stats */ 266 /* stats */
266 struct ave_stats stats_rx; 267 struct ave_stats stats_rx;
@@ -1208,9 +1209,13 @@ static int ave_init(struct net_device *ndev)
1208 1209
1209 priv->phydev = phydev; 1210 priv->phydev = phydev;
1210 1211
1211 phy_ethtool_get_wol(phydev, &wol); 1212 ave_ethtool_get_wol(ndev, &wol);
1212 device_set_wakeup_capable(&ndev->dev, !!wol.supported); 1213 device_set_wakeup_capable(&ndev->dev, !!wol.supported);
1213 1214
1215 /* set wol initial state disabled */
1216 wol.wolopts = 0;
1217 ave_ethtool_set_wol(ndev, &wol);
1218
1214 if (!phy_interface_is_rgmii(phydev)) 1219 if (!phy_interface_is_rgmii(phydev))
1215 phy_set_max_speed(phydev, SPEED_100); 1220 phy_set_max_speed(phydev, SPEED_100);
1216 1221
@@ -1734,6 +1739,58 @@ static int ave_remove(struct platform_device *pdev)
1734 return 0; 1739 return 0;
1735} 1740}
1736 1741
1742#ifdef CONFIG_PM_SLEEP
1743static int ave_suspend(struct device *dev)
1744{
1745 struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
1746 struct net_device *ndev = dev_get_drvdata(dev);
1747 struct ave_private *priv = netdev_priv(ndev);
1748 int ret = 0;
1749
1750 if (netif_running(ndev)) {
1751 ret = ave_stop(ndev);
1752 netif_device_detach(ndev);
1753 }
1754
1755 ave_ethtool_get_wol(ndev, &wol);
1756 priv->wolopts = wol.wolopts;
1757
1758 return ret;
1759}
1760
1761static int ave_resume(struct device *dev)
1762{
1763 struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
1764 struct net_device *ndev = dev_get_drvdata(dev);
1765 struct ave_private *priv = netdev_priv(ndev);
1766 int ret = 0;
1767
1768 ave_global_reset(ndev);
1769
1770 ave_ethtool_get_wol(ndev, &wol);
1771 wol.wolopts = priv->wolopts;
1772 ave_ethtool_set_wol(ndev, &wol);
1773
1774 if (ndev->phydev) {
1775 ret = phy_resume(ndev->phydev);
1776 if (ret)
1777 return ret;
1778 }
1779
1780 if (netif_running(ndev)) {
1781 ret = ave_open(ndev);
1782 netif_device_attach(ndev);
1783 }
1784
1785 return ret;
1786}
1787
1788static SIMPLE_DEV_PM_OPS(ave_pm_ops, ave_suspend, ave_resume);
1789#define AVE_PM_OPS (&ave_pm_ops)
1790#else
1791#define AVE_PM_OPS NULL
1792#endif
1793
1737static int ave_pro4_get_pinmode(struct ave_private *priv, 1794static int ave_pro4_get_pinmode(struct ave_private *priv,
1738 phy_interface_t phy_mode, u32 arg) 1795 phy_interface_t phy_mode, u32 arg)
1739{ 1796{
@@ -1908,6 +1965,7 @@ static struct platform_driver ave_driver = {
1908 .remove = ave_remove, 1965 .remove = ave_remove,
1909 .driver = { 1966 .driver = {
1910 .name = "ave", 1967 .name = "ave",
1968 .pm = AVE_PM_OPS,
1911 .of_match_table = of_ave_match, 1969 .of_match_table = of_ave_match,
1912 }, 1970 },
1913}; 1971};