diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2018-10-11 23:36:56 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-10-16 08:06:38 +0300 |
commit | 74fb5e25a3e925286e80eb2e0253f88f2b44ec96 (patch) | |
tree | 638910c925464a35fd1575734e42479dff9e8479 /drivers/net/phy | |
parent | 0813e95760f1963c3ca0c47b4bb3583f07147a2e (diff) | |
download | linux-74fb5e25a3e925286e80eb2e0253f88f2b44ec96.tar.xz |
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 <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/phy.c | 29 |
1 files 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: |