[TG3]: Add ASPM workaround.
authorMatt Carlson <mcarlson@broadcom.com>
Mon, 7 May 2007 07:25:49 +0000 (00:25 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 7 May 2007 07:25:49 +0000 (00:25 -0700)
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>
drivers/net/tg3.c
drivers/net/tg3.h

index 59d6e74..630c8a6 100644 (file)
@@ -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;
 }
 
index dcdfc08..4d334cf 100644 (file)
 #define  VCPU_STATUS_INIT_DONE          0x04000000
 #define  VCPU_STATUS_DRV_RESET          0x08000000
 
+#define VCPU_CFGSHDW                   0x00005104
+#define  VCPU_CFGSHDW_ASPM_DBNC                 0x00001000
+
 /* Mailboxes */
 #define GRCMBOX_BASE                   0x00005600
 #define GRCMBOX_INTERRUPT_0            0x00005800 /* 64-bit */
 #define PCIE_TRANS_CFG_1SHOT_MSI        0x20000000
 #define PCIE_TRANS_CFG_LOM              0x00000020
 
+#define PCIE_PWR_MGMT_THRESH           0x00007d28
+#define PCIE_PWR_MGMT_L1_THRESH_MSK     0x0000ff00
 
 #define TG3_EEPROM_MAGIC               0x669955aa
 #define TG3_EEPROM_MAGIC_FW            0xa5000000
 #define  SHASTA_EXT_LED_MAC             0x00010000
 #define  SHASTA_EXT_LED_COMBO           0x00018000
 
+#define NIC_SRAM_DATA_CFG_3            0x00000d3c
+#define  NIC_SRAM_ASPM_DEBOUNCE                 0x00000002
+
 #define NIC_SRAM_RX_MINI_BUFFER_DESC   0x00001000
 
 #define NIC_SRAM_DMA_DESC_POOL_BASE    0x00002000
@@ -2200,6 +2208,7 @@ struct tg3 {
 #define TG3_FLAG_USE_LINKCHG_REG       0x00000008
 #define TG3_FLAG_USE_MI_INTERRUPT      0x00000010
 #define TG3_FLAG_ENABLE_ASF            0x00000020
+#define TG3_FLAG_ASPM_WORKAROUND       0x00000040
 #define TG3_FLAG_POLL_SERDES           0x00000080
 #define TG3_FLAG_MBOX_WRITE_REORDER    0x00000100
 #define TG3_FLAG_PCIX_TARGET_HWBUG     0x00000200
@@ -2288,6 +2297,7 @@ struct tg3 {
        u32                             grc_local_ctrl;
        u32                             dma_rwctrl;
        u32                             coalesce_mode;
+       u32                             pwrmgmt_thresh;
 
        /* PCI block */
        u16                             pci_chip_rev_id;