| From 27277e80a363328a5713185efcf89ba7f9fd18b0 Mon Sep 17 00:00:00 2001 |
| From: Heiner Kallweit <hkallweit1@gmail.com> |
| Date: Wed, 24 Apr 2019 21:41:06 +0200 |
| Subject: net: phy: improve genphy_soft_reset |
| |
| [ Upstream commit 8c90b795e90f7753d23c18e8b95dd71b4a18c5d9 ] |
| |
| PHY's behave differently when being reset. Some reset registers to |
| defaults, some don't. Some trigger an autoneg restart, some don't. |
| |
| So let's also set the autoneg restart bit when resetting. Then PHY |
| behavior should be more consistent. Clearing BMCR_ISOLATE serves the |
| same purpose and is borrowed from genphy_restart_aneg. |
| |
| BMCR holds the speed / duplex settings in fixed mode. Therefore |
| we may have an issue if a soft reset resets BMCR to its default. |
| So better call genphy_setup_forced() afterwards in fixed mode. |
| We've seen no related complaint in the last >10 yrs, so let's |
| treat it as an improvement. |
| |
| Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/phy/phy_device.c | 16 ++++++++++++++-- |
| 1 file changed, 14 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c |
| index cd5966b0db571..f6a6cc5bf118d 100644 |
| --- a/drivers/net/phy/phy_device.c |
| +++ b/drivers/net/phy/phy_device.c |
| @@ -1829,13 +1829,25 @@ EXPORT_SYMBOL(genphy_read_status); |
| */ |
| int genphy_soft_reset(struct phy_device *phydev) |
| { |
| + u16 res = BMCR_RESET; |
| int ret; |
| |
| - ret = phy_set_bits(phydev, MII_BMCR, BMCR_RESET); |
| + if (phydev->autoneg == AUTONEG_ENABLE) |
| + res |= BMCR_ANRESTART; |
| + |
| + ret = phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, res); |
| if (ret < 0) |
| return ret; |
| |
| - return phy_poll_reset(phydev); |
| + ret = phy_poll_reset(phydev); |
| + if (ret) |
| + return ret; |
| + |
| + /* BMCR may be reset to defaults */ |
| + if (phydev->autoneg == AUTONEG_DISABLE) |
| + ret = genphy_setup_forced(phydev); |
| + |
| + return ret; |
| } |
| EXPORT_SYMBOL(genphy_soft_reset); |
| |
| -- |
| 2.20.1 |
| |