net: phy: marvell: Add WAKE_PHY support to WOL event
authorSong Yoong Siang <yoong.siang.song@intel.com>
Fri, 13 Aug 2021 08:45:08 +0000 (16:45 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 16 Aug 2021 10:05:52 +0000 (11:05 +0100)
Add Wake-on-PHY feature support by enabling the Link Up Event.

Signed-off-by: Song Yoong Siang <yoong.siang.song@intel.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/marvell.c

index ce0a7de..4fcfca4 100644 (file)
 
 #define MII_88E1318S_PHY_WOL_CTRL                              0x10
 #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS             BIT(12)
+#define MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE               BIT(13)
 #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE    BIT(14)
 
 #define MII_PHY_LED_CTRL               16
@@ -1755,13 +1756,19 @@ static void m88e1318_get_wol(struct phy_device *phydev,
 {
        int ret;
 
-       wol->supported = WAKE_MAGIC;
+       wol->supported = WAKE_MAGIC | WAKE_PHY;
        wol->wolopts = 0;
 
        ret = phy_read_paged(phydev, MII_MARVELL_WOL_PAGE,
                             MII_88E1318S_PHY_WOL_CTRL);
-       if (ret >= 0 && ret & MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE)
+       if (ret < 0)
+               return;
+
+       if (ret & MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE)
                wol->wolopts |= WAKE_MAGIC;
+
+       if (ret & MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE)
+               wol->wolopts |= WAKE_PHY;
 }
 
 static int m88e1318_set_wol(struct phy_device *phydev,
@@ -1773,7 +1780,7 @@ static int m88e1318_set_wol(struct phy_device *phydev,
        if (oldpage < 0)
                goto error;
 
-       if (wol->wolopts & WAKE_MAGIC) {
+       if (wol->wolopts & (WAKE_MAGIC | WAKE_PHY)) {
                /* Explicitly switch to page 0x00, just to be sure */
                err = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
                if (err < 0)
@@ -1805,7 +1812,9 @@ static int m88e1318_set_wol(struct phy_device *phydev,
                                   MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
                if (err < 0)
                        goto error;
+       }
 
+       if (wol->wolopts & WAKE_MAGIC) {
                err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
                if (err < 0)
                        goto error;
@@ -1846,6 +1855,30 @@ static int m88e1318_set_wol(struct phy_device *phydev,
                        goto error;
        }
 
+       if (wol->wolopts & WAKE_PHY) {
+               err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
+               if (err < 0)
+                       goto error;
+
+               /* Clear WOL status and enable link up event */
+               err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 0,
+                                  MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |
+                                  MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE);
+               if (err < 0)
+                       goto error;
+       } else {
+               err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
+               if (err < 0)
+                       goto error;
+
+               /* Clear WOL status and disable link up event */
+               err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,
+                                  MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE,
+                                  MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
+               if (err < 0)
+                       goto error;
+       }
+
 error:
        return phy_restore_page(phydev, oldpage, err);
 }