aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2008-11-21 20:18:16 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-21 20:18:16 -0500
commit5e7dfd0fb94abed04f59481d1ce0cc06a892048a (patch)
tree9aa0223d967bfe42076887879596b4e778ac05c3 /drivers/net
parent52f4490c3b6dcb1e8dec7ff9f1c35f09bd7c136f (diff)
tg3: Prevent corruption at 10 / 100Mbps w CLKREQ
This patch disables CLKREQ at 10Mbps and 100Mbps to workaround a TX BD corruption issue. This problem only affects the 5784 and 5761 (and 57780 AX) ASIC revisions. 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')
-rw-r--r--drivers/net/tg3.c77
-rw-r--r--drivers/net/tg3.h4
2 files changed, 67 insertions, 14 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 821e3812c085..659fb9978195 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2154,6 +2154,20 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2154 tp->dev->name, state); 2154 tp->dev->name, state);
2155 return -EINVAL; 2155 return -EINVAL;
2156 } 2156 }
2157
2158 /* Restore the CLKREQ setting. */
2159 if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
2160 u16 lnkctl;
2161
2162 pci_read_config_word(tp->pdev,
2163 tp->pcie_cap + PCI_EXP_LNKCTL,
2164 &lnkctl);
2165 lnkctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
2166 pci_write_config_word(tp->pdev,
2167 tp->pcie_cap + PCI_EXP_LNKCTL,
2168 lnkctl);
2169 }
2170
2157 misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL); 2171 misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
2158 tw32(TG3PCI_MISC_HOST_CTRL, 2172 tw32(TG3PCI_MISC_HOST_CTRL,
2159 misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT); 2173 misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
@@ -2923,6 +2937,24 @@ relink:
2923 NIC_SRAM_FIRMWARE_MBOX_MAGIC2); 2937 NIC_SRAM_FIRMWARE_MBOX_MAGIC2);
2924 } 2938 }
2925 2939
2940 /* Prevent send BD corruption. */
2941 if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
2942 u16 oldlnkctl, newlnkctl;
2943
2944 pci_read_config_word(tp->pdev,
2945 tp->pcie_cap + PCI_EXP_LNKCTL,
2946 &oldlnkctl);
2947 if (tp->link_config.active_speed == SPEED_100 ||
2948 tp->link_config.active_speed == SPEED_10)
2949 newlnkctl = oldlnkctl & ~PCI_EXP_LNKCTL_CLKREQ_EN;
2950 else
2951 newlnkctl = oldlnkctl | PCI_EXP_LNKCTL_CLKREQ_EN;
2952 if (newlnkctl != oldlnkctl)
2953 pci_write_config_word(tp->pdev,
2954 tp->pcie_cap + PCI_EXP_LNKCTL,
2955 newlnkctl);
2956 }
2957
2926 if (current_link_up != netif_carrier_ok(tp->dev)) { 2958 if (current_link_up != netif_carrier_ok(tp->dev)) {
2927 if (current_link_up) 2959 if (current_link_up)
2928 netif_carrier_on(tp->dev); 2960 netif_carrier_on(tp->dev);
@@ -6016,7 +6048,7 @@ static int tg3_chip_reset(struct tg3 *tp)
6016 6048
6017 udelay(120); 6049 udelay(120);
6018 6050
6019 if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { 6051 if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pcie_cap) {
6020 if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) { 6052 if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
6021 int i; 6053 int i;
6022 u32 cfg_val; 6054 u32 cfg_val;
@@ -6029,9 +6061,23 @@ static int tg3_chip_reset(struct tg3 *tp)
6029 pci_write_config_dword(tp->pdev, 0xc4, 6061 pci_write_config_dword(tp->pdev, 0xc4,
6030 cfg_val | (1 << 15)); 6062 cfg_val | (1 << 15));
6031 } 6063 }
6032 if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) 6064
6033 /* Set PCIE max payload size and clear error status. */ 6065 /* Set PCIE max payload size to 128 bytes and
6034 pci_write_config_dword(tp->pdev, 0xd8, 0xf5000); 6066 * clear the "no snoop" and "relaxed ordering" bits.
6067 */
6068 pci_write_config_word(tp->pdev,
6069 tp->pcie_cap + PCI_EXP_DEVCTL,
6070 0);
6071
6072 pcie_set_readrq(tp->pdev, 4096);
6073
6074 /* Clear error status */
6075 pci_write_config_word(tp->pdev,
6076 tp->pcie_cap + PCI_EXP_DEVSTA,
6077 PCI_EXP_DEVSTA_CED |
6078 PCI_EXP_DEVSTA_NFED |
6079 PCI_EXP_DEVSTA_FED |
6080 PCI_EXP_DEVSTA_URD);
6035 } 6081 }
6036 6082
6037 tg3_restore_pci_state(tp); 6083 tg3_restore_pci_state(tp);
@@ -11967,7 +12013,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
11967 u32 pci_state_reg, grc_misc_cfg; 12013 u32 pci_state_reg, grc_misc_cfg;
11968 u32 val; 12014 u32 val;
11969 u16 pci_cmd; 12015 u16 pci_cmd;
11970 int err, pcie_cap; 12016 int err;
11971 12017
11972 /* Force memory write invalidate off. If we leave it on, 12018 /* Force memory write invalidate off. If we leave it on,
11973 * then on 5700_BX chips we have to enable a workaround. 12019 * then on 5700_BX chips we have to enable a workaround.
@@ -12193,20 +12239,23 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
12193 pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, 12239 pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
12194 &pci_state_reg); 12240 &pci_state_reg);
12195 12241
12196 pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP); 12242 tp->pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
12197 if (pcie_cap != 0) { 12243 if (tp->pcie_cap != 0) {
12244 u16 lnkctl;
12245
12198 tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; 12246 tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
12199 12247
12200 pcie_set_readrq(tp->pdev, 4096); 12248 pcie_set_readrq(tp->pdev, 4096);
12201 12249
12202 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { 12250 pci_read_config_word(tp->pdev,
12203 u16 lnkctl; 12251 tp->pcie_cap + PCI_EXP_LNKCTL,
12204 12252 &lnkctl);
12205 pci_read_config_word(tp->pdev, 12253 if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) {
12206 pcie_cap + PCI_EXP_LNKCTL, 12254 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
12207 &lnkctl);
12208 if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN)
12209 tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2; 12255 tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
12256 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
12257 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
12258 tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
12210 } 12259 }
12211 } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) { 12260 } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
12212 tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; 12261 tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 599e490cf62c..53684b9b83f9 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2618,6 +2618,7 @@ struct tg3 {
2618#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100 2618#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100
2619#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200 2619#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200
2620#define TG3_FLG3_RGMII_EXT_IBND_TX_EN 0x00000400 2620#define TG3_FLG3_RGMII_EXT_IBND_TX_EN 0x00000400
2621#define TG3_FLG3_CLKREQ_BUG 0x00000800
2621 2622
2622 struct timer_list timer; 2623 struct timer_list timer;
2623 u16 timer_counter; 2624 u16 timer_counter;
@@ -2656,7 +2657,10 @@ struct tg3 {
2656 2657
2657 int pm_cap; 2658 int pm_cap;
2658 int msi_cap; 2659 int msi_cap;
2660 union {
2659 int pcix_cap; 2661 int pcix_cap;
2662 int pcie_cap;
2663 };
2660 2664
2661 struct mii_bus *mdio_bus; 2665 struct mii_bus *mdio_bus;
2662 int mdio_irq[PHY_MAX_ADDR]; 2666 int mdio_irq[PHY_MAX_ADDR];