]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/tg3.c
tg3: Prevent tx BD corruption
[net-next-2.6.git] / drivers / net / tg3.c
index e8def28877ce8dcc7f814d45bd3accc38b6220fa..595ddf2eb7d2a7b272962c3510f4060de4601271 100644 (file)
@@ -3167,6 +3167,15 @@ relink:
                        pci_write_config_word(tp->pdev,
                                              tp->pcie_cap + PCI_EXP_LNKCTL,
                                              newlnkctl);
+       } else if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
+               u32 newreg, oldreg = tr32(TG3_PCIE_LNKCTL);
+               if (tp->link_config.active_speed == SPEED_100 ||
+                   tp->link_config.active_speed == SPEED_10)
+                       newreg = oldreg & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+               else
+                       newreg = oldreg | TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+               if (newreg != oldreg)
+                       tw32(TG3_PCIE_LNKCTL, newreg);
        }
 
        if (current_link_up != netif_carrier_ok(tp->dev)) {
@@ -6160,6 +6169,11 @@ static int tg3_chip_reset(struct tg3 *tp)
        smp_mb();
        synchronize_irq(tp->pdev->irq);
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+               val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+               tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
+       }
+
        /* do the reset */
        val = GRC_MISC_CFG_CORECLK_RESET;
 
@@ -6726,6 +6740,15 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR);
        }
 
+       if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
+               val = tr32(TG3_PCIE_LNKCTL);
+               if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG)
+                       val |= TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
+               else
+                       val &= ~TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
+               tw32(TG3_PCIE_LNKCTL, val);
+       }
+
        /* This works around an issue with Athlon chipsets on
         * B3 tigon3 silicon.  This bit has no effect on any
         * other revision.  But do not set this on PCI Express
@@ -12274,6 +12297,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
 
+       if ((tp->pci_chip_rev_id == CHIPREV_ID_57780_A1 &&
+            tr32(RCVLPC_STATS_ENABLE) & RCVLPC_STATSENAB_ASF_FIX) ||
+           tp->pci_chip_rev_id == CHIPREV_ID_57780_A0)
+               tp->tg3_flags3 |= TG3_FLG3_TOGGLE_10_100_L1PLLPD;
+
        err = tg3_mdio_init(tp);
        if (err)
                return err;