From 74fb5e25a3e925286e80eb2e0253f88f2b44ec96 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 11 Oct 2018 22:36:56 +0200 Subject: [PATCH 1/2] net: phy: improve handling of PHY_RUNNING in state machine Handling of state PHY_RUNNING seems to be more complex than it needs to be. If not polling, then we don't have to do anything, we'll receive an interrupt and go to state PHY_CHANGELINK once the link goes down. If polling and link is down, we don't have to go the extra mile over PHY_CHANGELINK and call phy_read_status() again but can set status PHY_NOLINK directly. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 7044282110da..696955d38dd6 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -941,7 +941,6 @@ void phy_state_machine(struct work_struct *work) bool needs_aneg = false, do_suspend = false; enum phy_state old_state; int err = 0; - int old_link; mutex_lock(&phydev->lock); @@ -1025,26 +1024,16 @@ void phy_state_machine(struct work_struct *work) } break; case PHY_RUNNING: - /* Only register a CHANGE if we are polling and link changed - * since latest checking. - */ - if (phy_polling_mode(phydev)) { - old_link = phydev->link; - err = phy_read_status(phydev); - if (err) - break; + if (!phy_polling_mode(phydev)) + break; - if (old_link != phydev->link) - phydev->state = PHY_CHANGELINK; - } - /* - * Failsafe: check that nobody set phydev->link=0 between two - * poll cycles, otherwise we won't leave RUNNING state as long - * as link remains down. - */ - if (!phydev->link && phydev->state == PHY_RUNNING) { - phydev->state = PHY_CHANGELINK; - phydev_err(phydev, "no link in PHY_RUNNING\n"); + err = phy_read_status(phydev); + if (err) + break; + + if (!phydev->link) { + phydev->state = PHY_NOLINK; + phy_link_down(phydev, true); } break; case PHY_CHANGELINK: From eb4c470a154d2d3176d08155c3136973661f69ad Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 11 Oct 2018 22:37:38 +0200 Subject: [PATCH 2/2] net: phy: simplify handling of PHY_RESUMING in state machine Simplify code for handling state PHY_RESUMING, no functional change intended. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 43 ++++++++++++++----------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 696955d38dd6..d03bdbbd1eaf 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1059,41 +1059,26 @@ void phy_state_machine(struct work_struct *work) case PHY_RESUMING: if (AUTONEG_ENABLE == phydev->autoneg) { err = phy_aneg_done(phydev); - if (err < 0) + if (err < 0) { break; - - /* err > 0 if AN is done. - * Otherwise, it's 0, and we're still waiting for AN - */ - if (err > 0) { - err = phy_read_status(phydev); - if (err) - break; - - if (phydev->link) { - phydev->state = PHY_RUNNING; - phy_link_up(phydev); - } else { - phydev->state = PHY_NOLINK; - phy_link_down(phydev, false); - } - } else { + } else if (!err) { phydev->state = PHY_AN; phydev->link_timeout = PHY_AN_TIMEOUT; - } - } else { - err = phy_read_status(phydev); - if (err) break; - - if (phydev->link) { - phydev->state = PHY_RUNNING; - phy_link_up(phydev); - } else { - phydev->state = PHY_NOLINK; - phy_link_down(phydev, false); } } + + err = phy_read_status(phydev); + if (err) + break; + + if (phydev->link) { + phydev->state = PHY_RUNNING; + phy_link_up(phydev); + } else { + phydev->state = PHY_NOLINK; + phy_link_down(phydev, false); + } break; }