From: Heiner Kallweit Date: Wed, 24 Apr 2019 19:41:06 +0000 (+0200) Subject: net: phy: improve genphy_soft_reset X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=8c90b795e90f7753d23c18e8b95dd71b4a18c5d9;p=openwrt%2Fstaging%2Fblogic.git net: phy: improve genphy_soft_reset 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 Signed-off-by: David S. Miller --- diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index b9192ae92e40..f794ff3a10c2 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1815,13 +1815,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);