[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <Pine.LNX.4.64.0701251718270.4944@gate.crashing.org>
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