]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
tg3: Fix link down notify failure when EEE disabled
authorMatt Carlson <mcarlson@broadcom.com>
Wed, 20 Jul 2011 10:20:52 +0000 (10:20 +0000)
committerJoe Jin <joe.jin@oracle.com>
Tue, 15 May 2012 08:36:28 +0000 (16:36 +0800)
Occasionally, when the network cable is removed after a successful
autonegotiation, the device will not send a link down interrupt to the
driver.  This happens because of a bad interaction of an EEE
workaround.  The fix is to adjust the code so that the root cause
condition does not happen.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit b715ce947f51c6637e78b262501f0c4ff9d848cc)

Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/tg3.c

index 79e8f00dc7e22456f12afe8486cea212ebff0f2f..64d8711b53e31350ddf535a0ffc11728458a940f 100644 (file)
@@ -1857,6 +1857,12 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
        }
 
        if (!tp->setlpicnt) {
+               if (current_link_up == 1 &&
+                  !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+                       tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000);
+                       TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+               }
+
                val = tr32(TG3_CPMU_EEE_MODE);
                tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE);
        }
@@ -1871,7 +1877,9 @@ static void tg3_phy_eee_enable(struct tg3 *tp)
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
            !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
-               tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0003);
+               val = MII_TG3_DSP_TAP26_ALNOKO |
+                     MII_TG3_DSP_TAP26_RMRXSTO;
+               tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
                TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
        }
 
@@ -3127,13 +3135,26 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
        if (!err) {
                u32 err2;
 
+               val = 0;
+               /* Advertise 100-BaseTX EEE ability */
+               if (advertise & ADVERTISED_100baseT_Full)
+                       val |= MDIO_AN_EEE_ADV_100TX;
+               /* Advertise 1000-BaseT EEE ability */
+               if (advertise & ADVERTISED_1000baseT_Full)
+                       val |= MDIO_AN_EEE_ADV_1000T;
+               err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+               if (err)
+                       val = 0;
+
                switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
                case ASIC_REV_5717:
                case ASIC_REV_57765:
                case ASIC_REV_5719:
-                       val = MII_TG3_DSP_TAP26_ALNOKO |
-                             MII_TG3_DSP_TAP26_RMRXSTO |
-                             MII_TG3_DSP_TAP26_OPCSINPT;
+                       /* If we advertised any eee advertisements above... */
+                       if (val)
+                               val = MII_TG3_DSP_TAP26_ALNOKO |
+                                     MII_TG3_DSP_TAP26_RMRXSTO |
+                                     MII_TG3_DSP_TAP26_OPCSINPT;
                        tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
                        /* Fall through */
                case ASIC_REV_5720:
@@ -3142,15 +3163,6 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
                                                 MII_TG3_DSP_CH34TP2_HIBW01);
                }
 
-               val = 0;
-               /* Advertise 100-BaseTX EEE ability */
-               if (advertise & ADVERTISED_100baseT_Full)
-                       val |= MDIO_AN_EEE_ADV_100TX;
-               /* Advertise 1000-BaseT EEE ability */
-               if (advertise & ADVERTISED_1000baseT_Full)
-                       val |= MDIO_AN_EEE_ADV_1000T;
-               err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
-
                err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
                if (!err)
                        err = err2;