aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/e1000e
diff options
context:
space:
mode:
authorDavid Ertman <davidx.m.ertman@intel.com>2014-01-07 20:07:55 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-03-19 20:17:22 -0400
commitd9554e9659e974904fff3e93b2833f67e87ec084 (patch)
tree81ea9320481e872577901a85c61675349739528b /drivers/net/ethernet/intel/e1000e
parentdb44609480e8004906d7c8bd660b31ddb7641d93 (diff)
e1000e: Fix Hardware Unit Hang
The check for pending Tx work when link is lost was mistakenly moved to be done only when link is first detected to be lost. It turns out there is a small window of opportunity for additional Tx work to get queued up shortly after link is dropped. Move the check back to the place it was before in the watchdog task. Put in additional debug information for other reset paths and a final catch-all for false hangs in the scheduled function that prints out the hardware hang message. Signed-off-by: Dave Ertman <davidx.m.ertman@intel.com> Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e')
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index eafad410e59a..d57772327306 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -1090,8 +1090,14 @@ static void e1000_print_hw_hang(struct work_struct *work)
1090 adapter->tx_hang_recheck = true; 1090 adapter->tx_hang_recheck = true;
1091 return; 1091 return;
1092 } 1092 }
1093 /* Real hang detected */
1094 adapter->tx_hang_recheck = false; 1093 adapter->tx_hang_recheck = false;
1094
1095 if (er32(TDH(0)) == er32(TDT(0))) {
1096 e_dbg("false hang detected, ignoring\n");
1097 return;
1098 }
1099
1100 /* Real hang detected */
1095 netif_stop_queue(netdev); 1101 netif_stop_queue(netdev);
1096 1102
1097 e1e_rphy(hw, MII_BMSR, &phy_status); 1103 e1e_rphy(hw, MII_BMSR, &phy_status);
@@ -1121,6 +1127,8 @@ static void e1000_print_hw_hang(struct work_struct *work)
1121 eop, jiffies, eop_desc->upper.fields.status, er32(STATUS), 1127 eop, jiffies, eop_desc->upper.fields.status, er32(STATUS),
1122 phy_status, phy_1000t_status, phy_ext_status, pci_status); 1128 phy_status, phy_1000t_status, phy_ext_status, pci_status);
1123 1129
1130 e1000e_dump(adapter);
1131
1124 /* Suggest workaround for known h/w issue */ 1132 /* Suggest workaround for known h/w issue */
1125 if ((hw->mac.type == e1000_pchlan) && (er32(CTRL) & E1000_CTRL_TFCE)) 1133 if ((hw->mac.type == e1000_pchlan) && (er32(CTRL) & E1000_CTRL_TFCE))
1126 e_err("Try turning off Tx pause (flow control) via ethtool\n"); 1134 e_err("Try turning off Tx pause (flow control) via ethtool\n");
@@ -4798,6 +4806,7 @@ static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter)
4798 4806
4799 if (adapter->phy_hang_count > 1) { 4807 if (adapter->phy_hang_count > 1) {
4800 adapter->phy_hang_count = 0; 4808 adapter->phy_hang_count = 0;
4809 e_dbg("PHY appears hung - resetting\n");
4801 schedule_work(&adapter->reset_task); 4810 schedule_work(&adapter->reset_task);
4802 } 4811 }
4803} 4812}
@@ -4956,15 +4965,11 @@ static void e1000_watchdog_task(struct work_struct *work)
4956 mod_timer(&adapter->phy_info_timer, 4965 mod_timer(&adapter->phy_info_timer,
4957 round_jiffies(jiffies + 2 * HZ)); 4966 round_jiffies(jiffies + 2 * HZ));
4958 4967
4959 /* The link is lost so the controller stops DMA. 4968 /* 8000ES2LAN requires a Rx packet buffer work-around
4960 * If there is queued Tx work that cannot be done 4969 * on link down event; reset the controller to flush
4961 * or if on an 8000ES2LAN which requires a Rx packet 4970 * the Rx packet buffer.
4962 * buffer work-around on link down event, reset the
4963 * controller to flush the Tx/Rx packet buffers.
4964 * (Do the reset outside of interrupt context).
4965 */ 4971 */
4966 if ((adapter->flags & FLAG_RX_NEEDS_RESTART) || 4972 if (adapter->flags & FLAG_RX_NEEDS_RESTART)
4967 (e1000_desc_unused(tx_ring) + 1 < tx_ring->count))
4968 adapter->flags |= FLAG_RESTART_NOW; 4973 adapter->flags |= FLAG_RESTART_NOW;
4969 else 4974 else
4970 pm_schedule_suspend(netdev->dev.parent, 4975 pm_schedule_suspend(netdev->dev.parent,
@@ -4987,6 +4992,15 @@ link_up:
4987 adapter->gotc_old = adapter->stats.gotc; 4992 adapter->gotc_old = adapter->stats.gotc;
4988 spin_unlock(&adapter->stats64_lock); 4993 spin_unlock(&adapter->stats64_lock);
4989 4994
4995 /* If the link is lost the controller stops DMA, but
4996 * if there is queued Tx work it cannot be done. So
4997 * reset the controller to flush the Tx packet buffers.
4998 */
4999 if (!netif_carrier_ok(netdev) &&
5000 (e1000_desc_unused(tx_ring) + 1 < tx_ring->count))
5001 adapter->flags |= FLAG_RESTART_NOW;
5002
5003 /* If reset is necessary, do it outside of interrupt context. */
4990 if (adapter->flags & FLAG_RESTART_NOW) { 5004 if (adapter->flags & FLAG_RESTART_NOW) {
4991 schedule_work(&adapter->reset_task); 5005 schedule_work(&adapter->reset_task);
4992 /* return immediately since reset is imminent */ 5006 /* return immediately since reset is imminent */