lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 17 Nov 2008 13:33:25 -0800
From:	Trent Piepho <tpiepho@...escale.com>
To:	netdev@...r.kernel.org
Cc:	Scott Wood <scottwood@...escale.com>,
	Trent Piepho <tpiepho@...escale.com>,
	Andy Fleming <afleming@...escale.com>
Subject: [PATCH] phylib: Fix auto-negotiation restart avoidance

A previous patch, 51e2a3846eab18711f4eb59cd0a4c33054e2980a, 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: Trent Piepho <tpiepho@...escale.com>
Reported-by: Scott Wood <scottwood@...escale.com>
CC: Andy Fleming <afleming@...escale.com>
---
This fixes a 2.6.28 regression.

 drivers/net/phy/phy_device.c |   34 +++++++++++++++++++++++-----------
 1 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e11b03b..4fe2a53 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -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) /* 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);
+	/* Only restart aneg if we are advertising something different
+	 * than we were before.	 */
+	if (result > 0)
+		result = genphy_restart_aneg(phydev);
 
 	return result;
 }
-- 
1.5.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ