aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2010-11-24 03:31:48 -0500
committerDavid S. Miller <davem@davemloft.net>2010-11-24 14:06:17 -0500
commitcf79003d598b1f82a4caa0564107283b4f560e14 (patch)
treea41d4548a5a09578be104b133d4f7e698d91bc8a /drivers
parentd2394e6bb1aa636f3bd142cb6f7845a4332514b5 (diff)
tg3: Fix 5719 internal FIFO overflow problem
Under load, there an internal FIFO can overflow on the 5719. The fix is to scale back the PCIe maximum read request size based on the current link speed and width. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tg3.c44
-rw-r--r--drivers/net/tg3.h1
2 files changed, 42 insertions, 3 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 2624d714d16e..226e60dfaeaf 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -6985,7 +6985,7 @@ static void tg3_restore_pci_state(struct tg3 *tp)
6985 6985
6986 if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) { 6986 if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
6987 if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) 6987 if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
6988 pcie_set_readrq(tp->pdev, 4096); 6988 pcie_set_readrq(tp->pdev, tp->pcie_readrq);
6989 else { 6989 else {
6990 pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, 6990 pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
6991 tp->pci_cacheline_sz); 6991 tp->pci_cacheline_sz);
@@ -7179,7 +7179,7 @@ static int tg3_chip_reset(struct tg3 *tp)
7179 tp->pcie_cap + PCI_EXP_DEVCTL, 7179 tp->pcie_cap + PCI_EXP_DEVCTL,
7180 val16); 7180 val16);
7181 7181
7182 pcie_set_readrq(tp->pdev, 4096); 7182 pcie_set_readrq(tp->pdev, tp->pcie_readrq);
7183 7183
7184 /* Clear error status */ 7184 /* Clear error status */
7185 pci_write_config_word(tp->pdev, 7185 pci_write_config_word(tp->pdev,
@@ -13366,7 +13366,45 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
13366 13366
13367 tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; 13367 tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
13368 13368
13369 pcie_set_readrq(tp->pdev, 4096); 13369 tp->pcie_readrq = 4096;
13370 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
13371 u16 word;
13372
13373 pci_read_config_word(tp->pdev,
13374 tp->pcie_cap + PCI_EXP_LNKSTA,
13375 &word);
13376 switch (word & PCI_EXP_LNKSTA_CLS) {
13377 case PCI_EXP_LNKSTA_CLS_2_5GB:
13378 word &= PCI_EXP_LNKSTA_NLW;
13379 word >>= PCI_EXP_LNKSTA_NLW_SHIFT;
13380 switch (word) {
13381 case 2:
13382 tp->pcie_readrq = 2048;
13383 break;
13384 case 4:
13385 tp->pcie_readrq = 1024;
13386 break;
13387 }
13388 break;
13389
13390 case PCI_EXP_LNKSTA_CLS_5_0GB:
13391 word &= PCI_EXP_LNKSTA_NLW;
13392 word >>= PCI_EXP_LNKSTA_NLW_SHIFT;
13393 switch (word) {
13394 case 1:
13395 tp->pcie_readrq = 2048;
13396 break;
13397 case 2:
13398 tp->pcie_readrq = 1024;
13399 break;
13400 case 4:
13401 tp->pcie_readrq = 512;
13402 break;
13403 }
13404 }
13405 }
13406
13407 pcie_set_readrq(tp->pdev, tp->pcie_readrq);
13370 13408
13371 pci_read_config_word(tp->pdev, 13409 pci_read_config_word(tp->pdev,
13372 tp->pcie_cap + PCI_EXP_LNKCTL, 13410 tp->pcie_cap + PCI_EXP_LNKCTL,
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 06a4e7e8fff3..410703684e39 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2948,6 +2948,7 @@ struct tg3 {
2948 int pcix_cap; 2948 int pcix_cap;
2949 int pcie_cap; 2949 int pcie_cap;
2950 }; 2950 };
2951 int pcie_readrq;
2951 2952
2952 struct mii_bus *mdio_bus; 2953 struct mii_bus *mdio_bus;
2953 int mdio_irq[PHY_MAX_ADDR]; 2954 int mdio_irq[PHY_MAX_ADDR];