aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNithin Nayak Sujir <nsujir@broadcom.com>2013-01-14 12:11:00 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-14 22:09:29 -0500
commitdaf3ec688e057f6060fb9bb0819feac7a8bbf45c (patch)
tree24cd103a7a9553436d6c6fb8d0b4ef2b5281ca26
parent9c13cb8bb477a83b9a3c9e5a5478a4e21294a760 (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.c58
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) \ 1286static 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
1295static int tg3_bmcr_reset(struct tg3 *tp) 1307static 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
2254static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) 2266static 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
2573out: 2585out:
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 }