bnx2: Advertise nothing when speed is forced
authorMichael Chan <mchan@broadcom.com>
Wed, 1 Jan 2014 07:22:32 +0000 (23:22 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 2 Jan 2014 03:03:37 +0000 (22:03 -0500)
The current code does not reset the advertisement register when the speed
is forced, leaving the default advertisement value of 10 Mbps.  This does
not work with some link partners when the next patch enables auto-mdix.

Set advertisement register to 0 if the speed is forced.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnx2.c

index 0ced3587c88877c7c56a9d6c034d2306485e5484..1ae3348df3efe59b376753924f9f885356058d8b 100644 (file)
@@ -2048,29 +2048,27 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
 __releases(&bp->phy_lock)
 __acquires(&bp->phy_lock)
 {
-       u32 bmcr;
+       u32 bmcr, adv_reg, new_adv = 0;
        u32 new_bmcr;
 
        bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
 
+       bnx2_read_phy(bp, bp->mii_adv, &adv_reg);
+       adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP |
+                   ADVERTISE_PAUSE_ASYM);
+
+       new_adv = ADVERTISE_CSMA | ethtool_adv_to_mii_adv_t(bp->advertising);
+
        if (bp->autoneg & AUTONEG_SPEED) {
-               u32 adv_reg, adv1000_reg;
-               u32 new_adv = 0;
+               u32 adv1000_reg;
                u32 new_adv1000 = 0;
 
-               bnx2_read_phy(bp, bp->mii_adv, &adv_reg);
-               adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP |
-                       ADVERTISE_PAUSE_ASYM);
+               new_adv |= bnx2_phy_get_pause_adv(bp);
 
                bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg);
                adv1000_reg &= PHY_ALL_1000_SPEED;
 
-               new_adv = ethtool_adv_to_mii_adv_t(bp->advertising);
-               new_adv |= ADVERTISE_CSMA;
-               new_adv |= bnx2_phy_get_pause_adv(bp);
-
                new_adv1000 |= ethtool_adv_to_mii_ctrl1000_t(bp->advertising);
-
                if ((adv1000_reg != new_adv1000) ||
                        (adv_reg != new_adv) ||
                        ((bmcr & BMCR_ANENABLE) == 0)) {
@@ -2090,6 +2088,10 @@ __acquires(&bp->phy_lock)
                return 0;
        }
 
+       /* advertise nothing when forcing speed */
+       if (adv_reg != new_adv)
+               bnx2_write_phy(bp, bp->mii_adv, new_adv);
+
        new_bmcr = 0;
        if (bp->req_line_speed == SPEED_100) {
                new_bmcr |= BMCR_SPEED100;