phy/marvell: Make non-aneg speed/duplex forcing work for 88E1111 PHYs
authorAnton Vorontsov <avorontsov@ru.mvista.com>
Wed, 9 Sep 2009 16:01:30 +0000 (16:01 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 11 Sep 2009 19:54:38 +0000 (12:54 -0700)
According to specs, when auto-negotiation is disabled, Marvell PHYs need
a software reset after changing speed/duplex forcing bits. Otherwise,
the modified bits have no effect.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/marvell.c

index dd6f54d1b49539a39fb2b18bfd19d2a5e10f3746..6f69b9ba0df8994736e9f1a0eaad78b0a52f497f 100644 (file)
@@ -155,8 +155,27 @@ static int marvell_config_aneg(struct phy_device *phydev)
                return err;
 
        err = genphy_config_aneg(phydev);
+       if (err < 0)
+               return err;
 
-       return err;
+       if (phydev->autoneg != AUTONEG_ENABLE) {
+               int bmcr;
+
+               /*
+                * A write to speed/duplex bits (that is performed by
+                * genphy_config_aneg() call above) must be followed by
+                * a software reset. Otherwise, the write has no effect.
+                */
+               bmcr = phy_read(phydev, MII_BMCR);
+               if (bmcr < 0)
+                       return bmcr;
+
+               err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET);
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
 }
 
 static int m88e1121_config_aneg(struct phy_device *phydev)