Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de339c2a authored by Trent Piepho's avatar Trent Piepho Committed by David S. Miller
Browse files

phylib: Fix auto-negotiation restart avoidance



A previous patch, 51e2a384, made
genphy_config_aneg() not restart aneg by calling genphy_restart_aneg() if
the advertisement hadn't changed.

But, genphy_restart_aneg() doesn't just restart aneg, it may also *enable*
aneg or un-isolate the PHY from the MII (those functions are controlled by
the same register).  The code to avoid calling genphy_restart_aneg() didn't
consider this.

So, modify genphy_config_aneg() to also check if the PHY needs to have aneg
enabled or be un-isolated before deciding not to restart aneg.

This caused a problem with certain Davicom PHYs, as that driver isolates
the PHY (why?) before calling genphy_config_aneg() and expects the PHY to
be un-isolated by that function.

Signed-off-by: default avatarTrent Piepho <tpiepho@freescale.com>
Reported-by: default avatarScott Wood <scottwood@freescale.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 31c221c4
Loading
Loading
Loading
Loading
+23 −11
Original line number Diff line number Diff line
@@ -564,20 +564,32 @@ EXPORT_SYMBOL(genphy_restart_aneg);
 */
int genphy_config_aneg(struct phy_device *phydev)
{
	int result = 0;
	int result;

	if (AUTONEG_ENABLE == phydev->autoneg) {
		int result = genphy_config_advert(phydev);
	if (AUTONEG_ENABLE != phydev->autoneg)
		return genphy_setup_forced(phydev);

	result = genphy_config_advert(phydev);

	if (result < 0) /* error */
		return result;

	if (result == 0) {
		/* Advertisment hasn't changed, but maybe aneg was never on to
		 * begin with?  Or maybe phy was isolated? */
		int ctl = phy_read(phydev, MII_BMCR);

		if (ctl < 0)
			return ctl;

		if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
			result = 1; /* do restart aneg */
	}

	/* Only restart aneg if we are advertising something different
	 * than we were before.	 */
	if (result > 0)
		result = genphy_restart_aneg(phydev);
	} else
		result = genphy_setup_forced(phydev);

	return result;
}