diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2007-05-07 00:25:49 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-05-07 00:25:49 -0700 |
commit | 8ed5d97e5e0be0fb1aebad16f4c464613a0e472d (patch) | |
tree | 4088096e3fbc02e671980db1a2f26e1068dec532 /drivers/net/tg3.c | |
parent | 15700770ef7c5d12e2f1659d2ddbeb3f658d9f37 (diff) | |
download | linux-8ed5d97e5e0be0fb1aebad16f4c464613a0e472d.tar.bz2 |
[TG3]: Add ASPM workaround.
This patch adds workaround to fix performance problems caused by slow
PCIE L1->L0 transitions on ICH8 platforms.
Changed all magic numbers to constants as suggested by Jeff Garzik.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 59d6e74a4a5f..630c8a6c9f73 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3019,6 +3019,16 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) } } + if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) { + u32 val = tr32(PCIE_PWR_MGMT_THRESH); + if (!netif_carrier_ok(tp->dev)) + val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) | + tp->pwrmgmt_thresh; + else + val |= PCIE_PWR_MGMT_L1_THRESH_MSK; + tw32(PCIE_PWR_MGMT_THRESH, val); + } + return err; } @@ -10004,6 +10014,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; tp->tg3_flags2 |= TG3_FLG2_IS_NIC; } + if (tr32(VCPU_CFGSHDW) & VCPU_CFGSHDW_ASPM_DBNC) + tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; return; } @@ -10131,6 +10143,14 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) /* bootcode if bit 18 is set */ if (cfg2 & (1 << 18)) tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS; + + if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { + u32 cfg3; + + tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3); + if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE) + tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; + } } } @@ -10998,6 +11018,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) */ tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; + if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) + tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) & + PCIE_PWR_MGMT_L1_THRESH_MSK; + return err; } |