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  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:	Thu, 25 Jan 2007 17:22:11 -0600 (CST)
From:	Kumar Gala <galak@...nel.crashing.org>
To:	macro@...ux-mips.org
cc:	jgarizk@...nel.crashing.org, netdev@...r.kernel.org
Subject: [PATCH] RFC: Broadcom PHY forcing fix

Maciej,

I've got a BCM5461 that requires this fix to be able to force the speeds 
on the PHY.  Not sure if its needed on the other variants or not.  The 
problem is the genphy_config_aneg resets the PHY when forcing the speed 
and once we reset the BCM5461 it doesn't remember any of its settings.

Let me know if this works for you or not.

- k

diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 29666c8..bf752f4 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -99,6 +99,61 @@ static int bcm54xx_config_intr(struct ph
 	return err;
 }
 
+/* bcm_setup_forced
+ *
+ * description: Configures MII_BMCR to force speed/duplex
+ *   to the values in phydev. Assumes that the values are valid.
+ *   Please see phy_sanitize_settings() */
+static int bcm54xx_setup_forced(struct phy_device *phydev)
+{
+	int ctl = 0;
+	phydev->pause = phydev->asym_pause = 0;
+
+	if (SPEED_100 == phydev->speed)
+		ctl |= BMCR_SPEED100;
+
+	if (DUPLEX_FULL == phydev->duplex)
+		ctl |= BMCR_FULLDPLX;
+	
+	ctl = phy_write(phydev, MII_BMCR, ctl);
+
+	if (ctl < 0)
+		return ctl;
+
+	return ctl;
+}
+
+int bcm54xx_config_aneg(struct phy_device *phydev)
+{
+	int err = 0;
+
+	if (AUTONEG_ENABLE == phydev->autoneg) {
+		err = genphy_config_advert(phydev);
+
+		if (err < 0)
+			return err;
+
+		err = genphy_restart_aneg(phydev);
+	} else {
+		if (SPEED_1000 == phydev->speed) {
+			int adv;
+			adv = phy_read(phydev, MII_ADVERTISE);
+			adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+
+			err = phy_write(phydev, MII_ADVERTISE, adv);
+
+			if (err < 0)
+				return err;
+
+			err = genphy_restart_aneg(phydev);
+		} else {
+			err = bcm54xx_setup_forced(phydev);
+		}
+	}
+
+	return err;
+}
+
 static struct phy_driver bcm5411_driver = {
 	.phy_id		= 0x00206070,
 	.phy_id_mask	= 0xfffffff0,
@@ -106,7 +161,7 @@ static struct phy_driver bcm5411_driver 
 	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
-	.config_aneg	= genphy_config_aneg,
+	.config_aneg	= bcm54xx_config_aneg,
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
@@ -120,7 +175,7 @@ static struct phy_driver bcm5421_driver 
 	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
-	.config_aneg	= genphy_config_aneg,
+	.config_aneg	= bcm54xx_config_aneg,
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
@@ -134,7 +189,7 @@ static struct phy_driver bcm5461_driver 
 	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
-	.config_aneg	= genphy_config_aneg,
+	.config_aneg	= bcm54xx_config_aneg,
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-
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