aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/tg3.c
diff options
context:
space:
mode:
authorNithin Nayak Sujir <nsujir@broadcom.com>2012-11-14 09:44:27 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-14 22:04:28 -0500
commitf4a46d1f46a8fece34edd2023e054072b02e110d (patch)
treeccb6ac29a6f01080d5efd9de482264f520c2af62 /drivers/net/ethernet/broadcom/tg3.c
parent3d567e0e291c4ffd041cf653aea3c38a1d5f4620 (diff)
tg3: Prevent spurious tx timeout by setting carrier off before tx disable.
The watchdog will not trigger when the carrier is off when reconfiguring the device. Because carrier state is now off during reset, we need to introduce a link_up flag to keep track of link state during PHY setup. 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>
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c98
1 files changed, 56 insertions, 42 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 8d4581bdba3c..f533e17cac6c 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -2473,6 +2473,18 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
2473 return err; 2473 return err;
2474} 2474}
2475 2475
2476static void tg3_carrier_on(struct tg3 *tp)
2477{
2478 netif_carrier_on(tp->dev);
2479 tp->link_up = true;
2480}
2481
2482static void tg3_carrier_off(struct tg3 *tp)
2483{
2484 netif_carrier_off(tp->dev);
2485 tp->link_up = false;
2486}
2487
2476/* This will reset the tigon3 PHY if there is no valid 2488/* This will reset the tigon3 PHY if there is no valid
2477 * link unless the FORCE argument is non-zero. 2489 * link unless the FORCE argument is non-zero.
2478 */ 2490 */
@@ -2491,8 +2503,8 @@ static int tg3_phy_reset(struct tg3 *tp)
2491 if (err != 0) 2503 if (err != 0)
2492 return -EBUSY; 2504 return -EBUSY;
2493 2505
2494 if (netif_running(tp->dev) && netif_carrier_ok(tp->dev)) { 2506 if (netif_running(tp->dev) && tp->link_up) {
2495 netif_carrier_off(tp->dev); 2507 tg3_carrier_off(tp);
2496 tg3_link_report(tp); 2508 tg3_link_report(tp);
2497 } 2509 }
2498 2510
@@ -4186,6 +4198,24 @@ static bool tg3_phy_copper_fetch_rmtadv(struct tg3 *tp, u32 *rmtadv)
4186 return true; 4198 return true;
4187} 4199}
4188 4200
4201static bool tg3_test_and_report_link_chg(struct tg3 *tp, int curr_link_up)
4202{
4203 if (curr_link_up != tp->link_up) {
4204 if (curr_link_up) {
4205 tg3_carrier_on(tp);
4206 } else {
4207 tg3_carrier_off(tp);
4208 if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
4209 tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
4210 }
4211
4212 tg3_link_report(tp);
4213 return true;
4214 }
4215
4216 return false;
4217}
4218
4189static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) 4219static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
4190{ 4220{
4191 int current_link_up; 4221 int current_link_up;
@@ -4218,7 +4248,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
4218 if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || 4248 if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
4219 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || 4249 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
4220 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && 4250 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
4221 netif_carrier_ok(tp->dev)) { 4251 tp->link_up) {
4222 tg3_readphy(tp, MII_BMSR, &bmsr); 4252 tg3_readphy(tp, MII_BMSR, &bmsr);
4223 if (!tg3_readphy(tp, MII_BMSR, &bmsr) && 4253 if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
4224 !(bmsr & BMSR_LSTATUS)) 4254 !(bmsr & BMSR_LSTATUS))
@@ -4460,13 +4490,7 @@ relink:
4460 PCI_EXP_LNKCTL_CLKREQ_EN); 4490 PCI_EXP_LNKCTL_CLKREQ_EN);
4461 } 4491 }
4462 4492
4463 if (current_link_up != netif_carrier_ok(tp->dev)) { 4493 tg3_test_and_report_link_chg(tp, current_link_up);
4464 if (current_link_up)
4465 netif_carrier_on(tp->dev);
4466 else
4467 netif_carrier_off(tp->dev);
4468 tg3_link_report(tp);
4469 }
4470 4494
4471 return 0; 4495 return 0;
4472} 4496}
@@ -5106,7 +5130,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
5106 orig_active_duplex = tp->link_config.active_duplex; 5130 orig_active_duplex = tp->link_config.active_duplex;
5107 5131
5108 if (!tg3_flag(tp, HW_AUTONEG) && 5132 if (!tg3_flag(tp, HW_AUTONEG) &&
5109 netif_carrier_ok(tp->dev) && 5133 tp->link_up &&
5110 tg3_flag(tp, INIT_COMPLETE)) { 5134 tg3_flag(tp, INIT_COMPLETE)) {
5111 mac_status = tr32(MAC_STATUS); 5135 mac_status = tr32(MAC_STATUS);
5112 mac_status &= (MAC_STATUS_PCS_SYNCED | 5136 mac_status &= (MAC_STATUS_PCS_SYNCED |
@@ -5184,13 +5208,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
5184 LED_CTRL_TRAFFIC_OVERRIDE)); 5208 LED_CTRL_TRAFFIC_OVERRIDE));
5185 } 5209 }
5186 5210
5187 if (current_link_up != netif_carrier_ok(tp->dev)) { 5211 if (!tg3_test_and_report_link_chg(tp, current_link_up)) {
5188 if (current_link_up)
5189 netif_carrier_on(tp->dev);
5190 else
5191 netif_carrier_off(tp->dev);
5192 tg3_link_report(tp);
5193 } else {
5194 u32 now_pause_cfg = tp->link_config.active_flowctrl; 5212 u32 now_pause_cfg = tp->link_config.active_flowctrl;
5195 if (orig_pause_cfg != now_pause_cfg || 5213 if (orig_pause_cfg != now_pause_cfg ||
5196 orig_active_speed != tp->link_config.active_speed || 5214 orig_active_speed != tp->link_config.active_speed ||
@@ -5283,7 +5301,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
5283 new_bmcr |= BMCR_SPEED1000; 5301 new_bmcr |= BMCR_SPEED1000;
5284 5302
5285 /* Force a linkdown */ 5303 /* Force a linkdown */
5286 if (netif_carrier_ok(tp->dev)) { 5304 if (tp->link_up) {
5287 u32 adv; 5305 u32 adv;
5288 5306
5289 err |= tg3_readphy(tp, MII_ADVERTISE, &adv); 5307 err |= tg3_readphy(tp, MII_ADVERTISE, &adv);
@@ -5295,7 +5313,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
5295 BMCR_ANRESTART | 5313 BMCR_ANRESTART |
5296 BMCR_ANENABLE); 5314 BMCR_ANENABLE);
5297 udelay(10); 5315 udelay(10);
5298 netif_carrier_off(tp->dev); 5316 tg3_carrier_off(tp);
5299 } 5317 }
5300 tg3_writephy(tp, MII_BMCR, new_bmcr); 5318 tg3_writephy(tp, MII_BMCR, new_bmcr);
5301 bmcr = new_bmcr; 5319 bmcr = new_bmcr;
@@ -5361,15 +5379,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
5361 tp->link_config.active_speed = current_speed; 5379 tp->link_config.active_speed = current_speed;
5362 tp->link_config.active_duplex = current_duplex; 5380 tp->link_config.active_duplex = current_duplex;
5363 5381
5364 if (current_link_up != netif_carrier_ok(tp->dev)) { 5382 tg3_test_and_report_link_chg(tp, current_link_up);
5365 if (current_link_up)
5366 netif_carrier_on(tp->dev);
5367 else {
5368 netif_carrier_off(tp->dev);
5369 tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
5370 }
5371 tg3_link_report(tp);
5372 }
5373 return err; 5383 return err;
5374} 5384}
5375 5385
@@ -5381,7 +5391,7 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp)
5381 return; 5391 return;
5382 } 5392 }
5383 5393
5384 if (!netif_carrier_ok(tp->dev) && 5394 if (!tp->link_up &&
5385 (tp->link_config.autoneg == AUTONEG_ENABLE)) { 5395 (tp->link_config.autoneg == AUTONEG_ENABLE)) {
5386 u32 bmcr; 5396 u32 bmcr;
5387 5397
@@ -5411,7 +5421,7 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp)
5411 tp->phy_flags |= TG3_PHYFLG_PARALLEL_DETECT; 5421 tp->phy_flags |= TG3_PHYFLG_PARALLEL_DETECT;
5412 } 5422 }
5413 } 5423 }
5414 } else if (netif_carrier_ok(tp->dev) && 5424 } else if (tp->link_up &&
5415 (tp->link_config.autoneg == AUTONEG_ENABLE) && 5425 (tp->link_config.autoneg == AUTONEG_ENABLE) &&
5416 (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) { 5426 (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) {
5417 u32 phy2; 5427 u32 phy2;
@@ -5477,7 +5487,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
5477 (32 << TX_LENGTHS_SLOT_TIME_SHIFT)); 5487 (32 << TX_LENGTHS_SLOT_TIME_SHIFT));
5478 5488
5479 if (!tg3_flag(tp, 5705_PLUS)) { 5489 if (!tg3_flag(tp, 5705_PLUS)) {
5480 if (netif_carrier_ok(tp->dev)) { 5490 if (tp->link_up) {
5481 tw32(HOSTCC_STAT_COAL_TICKS, 5491 tw32(HOSTCC_STAT_COAL_TICKS,
5482 tp->coal.stats_block_coalesce_usecs); 5492 tp->coal.stats_block_coalesce_usecs);
5483 } else { 5493 } else {
@@ -5487,7 +5497,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
5487 5497
5488 if (tg3_flag(tp, ASPM_WORKAROUND)) { 5498 if (tg3_flag(tp, ASPM_WORKAROUND)) {
5489 val = tr32(PCIE_PWR_MGMT_THRESH); 5499 val = tr32(PCIE_PWR_MGMT_THRESH);
5490 if (!netif_carrier_ok(tp->dev)) 5500 if (!tp->link_up)
5491 val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) | 5501 val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) |
5492 tp->pwrmgmt_thresh; 5502 tp->pwrmgmt_thresh;
5493 else 5503 else
@@ -6503,6 +6513,7 @@ static inline void tg3_netif_stop(struct tg3 *tp)
6503{ 6513{
6504 tp->dev->trans_start = jiffies; /* prevent tx timeout */ 6514 tp->dev->trans_start = jiffies; /* prevent tx timeout */
6505 tg3_napi_disable(tp); 6515 tg3_napi_disable(tp);
6516 netif_carrier_off(tp->dev);
6506 netif_tx_disable(tp->dev); 6517 netif_tx_disable(tp->dev);
6507} 6518}
6508 6519
@@ -6514,6 +6525,9 @@ static inline void tg3_netif_start(struct tg3 *tp)
6514 */ 6525 */
6515 netif_tx_wake_all_queues(tp->dev); 6526 netif_tx_wake_all_queues(tp->dev);
6516 6527
6528 if (tp->link_up)
6529 netif_carrier_on(tp->dev);
6530
6517 tg3_napi_enable(tp); 6531 tg3_napi_enable(tp);
6518 tp->napi[0].hw_status->status |= SD_STATUS_UPDATED; 6532 tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
6519 tg3_enable_ints(tp); 6533 tg3_enable_ints(tp);
@@ -8412,7 +8426,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
8412 tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq); 8426 tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
8413 tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq); 8427 tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq);
8414 8428
8415 if (!netif_carrier_ok(tp->dev)) 8429 if (!tp->link_up)
8416 val = 0; 8430 val = 0;
8417 8431
8418 tw32(HOSTCC_STAT_COAL_TICKS, val); 8432 tw32(HOSTCC_STAT_COAL_TICKS, val);
@@ -9705,7 +9719,7 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
9705{ 9719{
9706 struct tg3_hw_stats *sp = tp->hw_stats; 9720 struct tg3_hw_stats *sp = tp->hw_stats;
9707 9721
9708 if (!netif_carrier_ok(tp->dev)) 9722 if (!tp->link_up)
9709 return; 9723 return;
9710 9724
9711 TG3_STAT_ADD32(&sp->tx_octets, MAC_TX_STATS_OCTETS); 9725 TG3_STAT_ADD32(&sp->tx_octets, MAC_TX_STATS_OCTETS);
@@ -9849,11 +9863,11 @@ static void tg3_timer(unsigned long __opaque)
9849 u32 mac_stat = tr32(MAC_STATUS); 9863 u32 mac_stat = tr32(MAC_STATUS);
9850 int need_setup = 0; 9864 int need_setup = 0;
9851 9865
9852 if (netif_carrier_ok(tp->dev) && 9866 if (tp->link_up &&
9853 (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)) { 9867 (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)) {
9854 need_setup = 1; 9868 need_setup = 1;
9855 } 9869 }
9856 if (!netif_carrier_ok(tp->dev) && 9870 if (!tp->link_up &&
9857 (mac_stat & (MAC_STATUS_PCS_SYNCED | 9871 (mac_stat & (MAC_STATUS_PCS_SYNCED |
9858 MAC_STATUS_SIGNAL_DET))) { 9872 MAC_STATUS_SIGNAL_DET))) {
9859 need_setup = 1; 9873 need_setup = 1;
@@ -10505,7 +10519,7 @@ static int tg3_open(struct net_device *dev)
10505 } 10519 }
10506 } 10520 }
10507 10521
10508 netif_carrier_off(tp->dev); 10522 tg3_carrier_off(tp);
10509 10523
10510 err = tg3_power_up(tp); 10524 err = tg3_power_up(tp);
10511 if (err) 10525 if (err)
@@ -10538,7 +10552,7 @@ static int tg3_close(struct net_device *dev)
10538 10552
10539 tg3_power_down(tp); 10553 tg3_power_down(tp);
10540 10554
10541 netif_carrier_off(tp->dev); 10555 tg3_carrier_off(tp);
10542 10556
10543 return 0; 10557 return 0;
10544} 10558}
@@ -10912,7 +10926,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
10912 cmd->advertising |= ADVERTISED_Asym_Pause; 10926 cmd->advertising |= ADVERTISED_Asym_Pause;
10913 } 10927 }
10914 } 10928 }
10915 if (netif_running(dev) && netif_carrier_ok(dev)) { 10929 if (netif_running(dev) && tp->link_up) {
10916 ethtool_cmd_speed_set(cmd, tp->link_config.active_speed); 10930 ethtool_cmd_speed_set(cmd, tp->link_config.active_speed);
10917 cmd->duplex = tp->link_config.active_duplex; 10931 cmd->duplex = tp->link_config.active_duplex;
10918 cmd->lp_advertising = tp->link_config.rmt_adv; 10932 cmd->lp_advertising = tp->link_config.rmt_adv;
@@ -11430,7 +11444,7 @@ static int tg3_set_channels(struct net_device *dev,
11430 11444
11431 tg3_stop(tp); 11445 tg3_stop(tp);
11432 11446
11433 netif_carrier_off(dev); 11447 tg3_carrier_off(tp);
11434 11448
11435 tg3_start(tp, true, false); 11449 tg3_start(tp, true, false);
11436 11450
@@ -11779,7 +11793,7 @@ static int tg3_test_link(struct tg3 *tp)
11779 max = TG3_COPPER_TIMEOUT_SEC; 11793 max = TG3_COPPER_TIMEOUT_SEC;
11780 11794
11781 for (i = 0; i < max; i++) { 11795 for (i = 0; i < max; i++) {
11782 if (netif_carrier_ok(tp->dev)) 11796 if (tp->link_up)
11783 return 0; 11797 return 0;
11784 11798
11785 if (msleep_interruptible(1000)) 11799 if (msleep_interruptible(1000))