#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
{
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,
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)
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;
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);
}