net: ethernet: ave: Preserve wol state in suspend/resume sequence
authorKunihiko Hayashi <hayashi.kunihiko@socionext.com>
Thu, 29 Nov 2018 08:06:33 +0000 (17:06 +0900)
committerDavid S. Miller <davem@davemloft.net>
Thu, 29 Nov 2018 18:34:45 +0000 (10:34 -0800)
Since the wol state forces to be initialized after reset, the state should
be preserved in suspend/resume sequence.

Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/socionext/sni_ave.c

index 96b80309e36dec0b7ba95cb7860b9551f538356e..1f9ef68d91eee0974193d3db72906330d7e0af0c 100644 (file)
@@ -261,6 +261,7 @@ struct ave_private {
        struct regmap           *regmap;
        unsigned int            pinmode_mask;
        unsigned int            pinmode_val;
+       u32                     wolopts;
 
        /* stats */
        struct ave_stats        stats_rx;
@@ -1741,6 +1742,7 @@ static int ave_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int ave_suspend(struct device *dev)
 {
+       struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
        struct net_device *ndev = dev_get_drvdata(dev);
        struct ave_private *priv = netdev_priv(ndev);
        int ret = 0;
@@ -1750,17 +1752,25 @@ static int ave_suspend(struct device *dev)
                netif_device_detach(ndev);
        }
 
+       ave_ethtool_get_wol(ndev, &wol);
+       priv->wolopts = wol.wolopts;
+
        return ret;
 }
 
 static int ave_resume(struct device *dev)
 {
+       struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
        struct net_device *ndev = dev_get_drvdata(dev);
        struct ave_private *priv = netdev_priv(ndev);
        int ret = 0;
 
        ave_global_reset(ndev);
 
+       ave_ethtool_get_wol(ndev, &wol);
+       wol.wolopts = priv->wolopts;
+       ave_ethtool_set_wol(ndev, &wol);
+
        if (ndev->phydev) {
                ret = phy_resume(ndev->phydev);
                if (ret)