diff options
author | Nithin Nayak Sujir <nsujir@broadcom.com> | 2013-01-14 12:11:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-14 22:09:29 -0500 |
commit | daf3ec688e057f6060fb9bb0819feac7a8bbf45c (patch) | |
tree | 24cd103a7a9553436d6c6fb8d0b4ef2b5281ca26 | |
parent | 9c13cb8bb477a83b9a3c9e5a5478a4e21294a760 (diff) |
tg3: Fix crc errors on jumbo frame receive
TG3_PHY_AUXCTL_SMDSP_ENABLE/DISABLE macros do a blind write to the phy
auxiliary control register and overwrite the EXT_PKT_LEN (bit 14) resulting
in intermittent crc errors on jumbo frames with some link partners. Change
the code to do a read/modify/write.
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index d326d9219aa8..bdb086934cd9 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -1283,14 +1283,26 @@ static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set) | |||
1283 | return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg); | 1283 | return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg); |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | #define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \ | 1286 | static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable) |
1287 | tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \ | 1287 | { |
1288 | MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \ | 1288 | u32 val; |
1289 | MII_TG3_AUXCTL_ACTL_TX_6DB) | 1289 | int err; |
1290 | |||
1291 | err = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val); | ||
1290 | 1292 | ||
1291 | #define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \ | 1293 | if (err) |
1292 | tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \ | 1294 | return err; |
1293 | MII_TG3_AUXCTL_ACTL_TX_6DB); | 1295 | if (enable) |
1296 | |||
1297 | val |= MII_TG3_AUXCTL_ACTL_SMDSP_ENA; | ||
1298 | else | ||
1299 | val &= ~MII_TG3_AUXCTL_ACTL_SMDSP_ENA; | ||
1300 | |||
1301 | err = tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, | ||
1302 | val | MII_TG3_AUXCTL_ACTL_TX_6DB); | ||
1303 | |||
1304 | return err; | ||
1305 | } | ||
1294 | 1306 | ||
1295 | static int tg3_bmcr_reset(struct tg3 *tp) | 1307 | static int tg3_bmcr_reset(struct tg3 *tp) |
1296 | { | 1308 | { |
@@ -2223,7 +2235,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp) | |||
2223 | 2235 | ||
2224 | otp = tp->phy_otp; | 2236 | otp = tp->phy_otp; |
2225 | 2237 | ||
2226 | if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) | 2238 | if (tg3_phy_toggle_auxctl_smdsp(tp, true)) |
2227 | return; | 2239 | return; |
2228 | 2240 | ||
2229 | phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT); | 2241 | phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT); |
@@ -2248,7 +2260,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp) | |||
2248 | ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT); | 2260 | ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT); |
2249 | tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy); | 2261 | tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy); |
2250 | 2262 | ||
2251 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2263 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2252 | } | 2264 | } |
2253 | 2265 | ||
2254 | static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) | 2266 | static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) |
@@ -2284,9 +2296,9 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) | |||
2284 | 2296 | ||
2285 | if (!tp->setlpicnt) { | 2297 | if (!tp->setlpicnt) { |
2286 | if (current_link_up == 1 && | 2298 | if (current_link_up == 1 && |
2287 | !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2299 | !tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2288 | tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); | 2300 | tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); |
2289 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2301 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2290 | } | 2302 | } |
2291 | 2303 | ||
2292 | val = tr32(TG3_CPMU_EEE_MODE); | 2304 | val = tr32(TG3_CPMU_EEE_MODE); |
@@ -2302,11 +2314,11 @@ static void tg3_phy_eee_enable(struct tg3 *tp) | |||
2302 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || | 2314 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || |
2303 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || | 2315 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || |
2304 | tg3_flag(tp, 57765_CLASS)) && | 2316 | tg3_flag(tp, 57765_CLASS)) && |
2305 | !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2317 | !tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2306 | val = MII_TG3_DSP_TAP26_ALNOKO | | 2318 | val = MII_TG3_DSP_TAP26_ALNOKO | |
2307 | MII_TG3_DSP_TAP26_RMRXSTO; | 2319 | MII_TG3_DSP_TAP26_RMRXSTO; |
2308 | tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); | 2320 | tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); |
2309 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2321 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2310 | } | 2322 | } |
2311 | 2323 | ||
2312 | val = tr32(TG3_CPMU_EEE_MODE); | 2324 | val = tr32(TG3_CPMU_EEE_MODE); |
@@ -2450,7 +2462,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) | |||
2450 | tg3_writephy(tp, MII_CTRL1000, | 2462 | tg3_writephy(tp, MII_CTRL1000, |
2451 | CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER); | 2463 | CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER); |
2452 | 2464 | ||
2453 | err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); | 2465 | err = tg3_phy_toggle_auxctl_smdsp(tp, true); |
2454 | if (err) | 2466 | if (err) |
2455 | return err; | 2467 | return err; |
2456 | 2468 | ||
@@ -2471,7 +2483,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) | |||
2471 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); | 2483 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); |
2472 | tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000); | 2484 | tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000); |
2473 | 2485 | ||
2474 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2486 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2475 | 2487 | ||
2476 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); | 2488 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); |
2477 | 2489 | ||
@@ -2572,10 +2584,10 @@ static int tg3_phy_reset(struct tg3 *tp) | |||
2572 | 2584 | ||
2573 | out: | 2585 | out: |
2574 | if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) && | 2586 | if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) && |
2575 | !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2587 | !tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2576 | tg3_phydsp_write(tp, 0x201f, 0x2aaa); | 2588 | tg3_phydsp_write(tp, 0x201f, 0x2aaa); |
2577 | tg3_phydsp_write(tp, 0x000a, 0x0323); | 2589 | tg3_phydsp_write(tp, 0x000a, 0x0323); |
2578 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2590 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2579 | } | 2591 | } |
2580 | 2592 | ||
2581 | if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) { | 2593 | if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) { |
@@ -2584,14 +2596,14 @@ out: | |||
2584 | } | 2596 | } |
2585 | 2597 | ||
2586 | if (tp->phy_flags & TG3_PHYFLG_BER_BUG) { | 2598 | if (tp->phy_flags & TG3_PHYFLG_BER_BUG) { |
2587 | if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2599 | if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2588 | tg3_phydsp_write(tp, 0x000a, 0x310b); | 2600 | tg3_phydsp_write(tp, 0x000a, 0x310b); |
2589 | tg3_phydsp_write(tp, 0x201f, 0x9506); | 2601 | tg3_phydsp_write(tp, 0x201f, 0x9506); |
2590 | tg3_phydsp_write(tp, 0x401f, 0x14e2); | 2602 | tg3_phydsp_write(tp, 0x401f, 0x14e2); |
2591 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2603 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2592 | } | 2604 | } |
2593 | } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) { | 2605 | } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) { |
2594 | if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2606 | if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2595 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); | 2607 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); |
2596 | if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) { | 2608 | if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) { |
2597 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); | 2609 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); |
@@ -2600,7 +2612,7 @@ out: | |||
2600 | } else | 2612 | } else |
2601 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); | 2613 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); |
2602 | 2614 | ||
2603 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2615 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2604 | } | 2616 | } |
2605 | } | 2617 | } |
2606 | 2618 | ||
@@ -4009,7 +4021,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) | |||
4009 | tw32(TG3_CPMU_EEE_MODE, | 4021 | tw32(TG3_CPMU_EEE_MODE, |
4010 | tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); | 4022 | tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); |
4011 | 4023 | ||
4012 | err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); | 4024 | err = tg3_phy_toggle_auxctl_smdsp(tp, true); |
4013 | if (!err) { | 4025 | if (!err) { |
4014 | u32 err2; | 4026 | u32 err2; |
4015 | 4027 | ||
@@ -4042,7 +4054,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) | |||
4042 | MII_TG3_DSP_CH34TP2_HIBW01); | 4054 | MII_TG3_DSP_CH34TP2_HIBW01); |
4043 | } | 4055 | } |
4044 | 4056 | ||
4045 | err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 4057 | err2 = tg3_phy_toggle_auxctl_smdsp(tp, false); |
4046 | if (!err) | 4058 | if (!err) |
4047 | err = err2; | 4059 | err = err2; |
4048 | } | 4060 | } |