Merge branch 'net-phy-improve-and-simplify-state-machine'

Heiner Kallweit says:

====================
net: phy: improve and simplify state machine

Improve / simplify handling of states PHY_RUNNING and PHY_RESUMING in
phylib state machine.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2018-10-15 22:06:38 -07:00
commit 5985d5631d
1 changed files with 23 additions and 49 deletions

View File

@ -941,7 +941,6 @@ void phy_state_machine(struct work_struct *work)
bool needs_aneg = false, do_suspend = false; bool needs_aneg = false, do_suspend = false;
enum phy_state old_state; enum phy_state old_state;
int err = 0; int err = 0;
int old_link;
mutex_lock(&phydev->lock); mutex_lock(&phydev->lock);
@ -1025,26 +1024,16 @@ void phy_state_machine(struct work_struct *work)
} }
break; break;
case PHY_RUNNING: case PHY_RUNNING:
/* Only register a CHANGE if we are polling and link changed if (!phy_polling_mode(phydev))
* since latest checking. break;
*/
if (phy_polling_mode(phydev)) {
old_link = phydev->link;
err = phy_read_status(phydev);
if (err)
break;
if (old_link != phydev->link) err = phy_read_status(phydev);
phydev->state = PHY_CHANGELINK; if (err)
} break;
/*
* Failsafe: check that nobody set phydev->link=0 between two if (!phydev->link) {
* poll cycles, otherwise we won't leave RUNNING state as long phydev->state = PHY_NOLINK;
* as link remains down. phy_link_down(phydev, true);
*/
if (!phydev->link && phydev->state == PHY_RUNNING) {
phydev->state = PHY_CHANGELINK;
phydev_err(phydev, "no link in PHY_RUNNING\n");
} }
break; break;
case PHY_CHANGELINK: case PHY_CHANGELINK:
@ -1070,41 +1059,26 @@ void phy_state_machine(struct work_struct *work)
case PHY_RESUMING: case PHY_RESUMING:
if (AUTONEG_ENABLE == phydev->autoneg) { if (AUTONEG_ENABLE == phydev->autoneg) {
err = phy_aneg_done(phydev); err = phy_aneg_done(phydev);
if (err < 0) if (err < 0) {
break; break;
} else if (!err) {
/* 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 {
phydev->state = PHY_AN; phydev->state = PHY_AN;
phydev->link_timeout = PHY_AN_TIMEOUT; phydev->link_timeout = PHY_AN_TIMEOUT;
}
} else {
err = phy_read_status(phydev);
if (err)
break; 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; break;
} }