diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2019-01-23 07:30:38 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-24 22:15:15 -0800 |
commit | 217962615662f1ab7a60978a194444023039f0a4 (patch) | |
tree | a8442084adcf6c415841a8a6a9a6591b7defaa88 /drivers/net/phy/phy.c | |
parent | a016becd3a56cdb260013c8fe1d4aefc6edc4989 (diff) | |
download | linux-stable-217962615662f1ab7a60978a194444023039f0a4.tar.gz linux-stable-217962615662f1ab7a60978a194444023039f0a4.tar.bz2 linux-stable-217962615662f1ab7a60978a194444023039f0a4.zip |
net: phy: warn if phy_start is called from invalid state
phy_start() should be called from states PHY_READY or PHY_HALTED only.
Check for this to detect misbehaving drivers. Also the state machine
should be started only when being called from one of the valid states.
Some more background:
For all invalid states phy_start() basically was a no-op. All it did
was triggering a state machine run, but for all "running" states the
poll loop was active anyway. And if called from PHY_DOWN, the state
machine does nothing.
v3:
- extended commit message
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/phy.c')
-rw-r--r-- | drivers/net/phy/phy.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index a7fca15888b6..dedd57b86c80 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -856,9 +856,16 @@ void phy_start(struct phy_device *phydev) mutex_lock(&phydev->lock); + if (phydev->state != PHY_READY && phydev->state != PHY_HALTED) { + WARN(1, "called from state %s\n", + phy_state_to_str(phydev->state)); + goto out; + } + switch (phydev->state) { case PHY_READY: phydev->state = PHY_UP; + phy_start_machine(phydev); break; case PHY_HALTED: /* if phy was suspended, bring the physical link up again */ @@ -872,13 +879,13 @@ void phy_start(struct phy_device *phydev) } phydev->state = PHY_RESUMING; + phy_start_machine(phydev); break; default: break; } +out: mutex_unlock(&phydev->lock); - - phy_start_machine(phydev); } EXPORT_SYMBOL(phy_start); |