net: phy: improve resuming from hibernation
authorHeiner Kallweit <hkallweit1@gmail.com>
Wed, 1 May 2019 20:14:21 +0000 (22:14 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 4 May 2019 04:50:58 +0000 (00:50 -0400)
I got an interesting report [0] that after resuming from hibernation
the link has 100Mbps instead of 1Gbps. Reason is that another OS has
been used whilst Linux was hibernated. And this OS speeds down the link
due to WoL. Therefore, when resuming, we shouldn't expect that what
the PHY advertises is what it did when hibernating.
Easiest way to do this is removing state PHY_RESUMING. Instead always
go via PHY_UP that configures PHY advertisement.

[0] https://bugzilla.kernel.org/show_bug.cgi?id=202851

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/phy.c
include/linux/phy.h

index 984de987241cfb1a79cdf5ca63cd0de8f8926ca5..1a146c5c503619c796741a7a1494d8e21c2aa3ac 100644 (file)
@@ -43,7 +43,6 @@ static const char *phy_state_to_str(enum phy_state st)
        PHY_STATE_STR(NOLINK)
        PHY_STATE_STR(FORCING)
        PHY_STATE_STR(HALTED)
-       PHY_STATE_STR(RESUMING)
        }
 
        return NULL;
@@ -859,10 +858,7 @@ void phy_start(struct phy_device *phydev)
                        goto out;
        }
 
-       if (phydev->state == PHY_READY)
-               phydev->state = PHY_UP;
-       else
-               phydev->state = PHY_RESUMING;
+       phydev->state = PHY_UP;
 
        phy_start_machine(phydev);
 out:
@@ -897,7 +893,6 @@ void phy_state_machine(struct work_struct *work)
                break;
        case PHY_NOLINK:
        case PHY_RUNNING:
-       case PHY_RESUMING:
                err = phy_check_link_status(phydev);
                break;
        case PHY_FORCING:
index 4a03f8a46d33354fbc7589245fffbfc43b623083..073fb151b5a99c7e51dea743496d4b21e1663ae2 100644 (file)
@@ -308,13 +308,7 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
  *
  * HALTED: PHY is up, but no polling or interrupts are done. Or
  * PHY is in an error state.
- *
- * - phy_start moves to RESUMING
- *
- * RESUMING: PHY was halted, but now wants to run again.
- * - If we are forcing, or aneg is done, timer moves to RUNNING
- * - If aneg is not done, timer moves to AN
- * - phy_stop moves to HALTED
+ * - phy_start moves to UP
  */
 enum phy_state {
        PHY_DOWN = 0,
@@ -324,7 +318,6 @@ enum phy_state {
        PHY_RUNNING,
        PHY_NOLINK,
        PHY_FORCING,
-       PHY_RESUMING
 };
 
 /**