aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJakub Kicinski <kubakici@wp.pl>2014-03-15 10:55:00 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-03-28 09:54:01 -0400
commit59c871c5f0540c974db85eaa77f518de26940c1f (patch)
tree0dfcd92ddb191648b8cc2578ddade2e5dbdd7b92 /drivers/net
parent13c2884f155bc524c5e94482216030de480fea60 (diff)
e1000e: add timeout for TX HW time stamping work
Hardware may fail to report time stamp e.g.: - when hardware time stamping is not enabled - when time stamp is requested shortly after ifup Timeout time stamp reading work to prevent it from scheduling itself indefinitely. Report timeout events via system log and device stats. Signed-off-by: Jakub Kicinski <kubakici@wp.pl> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h2
-rw-r--r--drivers/net/ethernet/intel/e1000e/ethtool.c1
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c7
3 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 5325e3e2154e..1471c5464a89 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -262,6 +262,7 @@ struct e1000_adapter {
262 u32 tx_head_addr; 262 u32 tx_head_addr;
263 u32 tx_fifo_size; 263 u32 tx_fifo_size;
264 u32 tx_dma_failed; 264 u32 tx_dma_failed;
265 u32 tx_hwtstamp_timeouts;
265 266
266 /* Rx */ 267 /* Rx */
267 bool (*clean_rx) (struct e1000_ring *ring, int *work_done, 268 bool (*clean_rx) (struct e1000_ring *ring, int *work_done,
@@ -334,6 +335,7 @@ struct e1000_adapter {
334 struct hwtstamp_config hwtstamp_config; 335 struct hwtstamp_config hwtstamp_config;
335 struct delayed_work systim_overflow_work; 336 struct delayed_work systim_overflow_work;
336 struct sk_buff *tx_hwtstamp_skb; 337 struct sk_buff *tx_hwtstamp_skb;
338 unsigned long tx_hwtstamp_start;
337 struct work_struct tx_hwtstamp_work; 339 struct work_struct tx_hwtstamp_work;
338 spinlock_t systim_lock; /* protects SYSTIML/H regsters */ 340 spinlock_t systim_lock; /* protects SYSTIML/H regsters */
339 struct cyclecounter cc; 341 struct cyclecounter cc;
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index 3c2898d0c2aa..cad250bc1b99 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -104,6 +104,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
104 E1000_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), 104 E1000_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
105 E1000_STAT("uncorr_ecc_errors", uncorr_errors), 105 E1000_STAT("uncorr_ecc_errors", uncorr_errors),
106 E1000_STAT("corr_ecc_errors", corr_errors), 106 E1000_STAT("corr_ecc_errors", corr_errors),
107 E1000_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
107}; 108};
108 109
109#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) 110#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 6bd1832e3f3e..b8d252fcad18 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -1163,6 +1163,12 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work)
1163 skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps); 1163 skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps);
1164 dev_kfree_skb_any(adapter->tx_hwtstamp_skb); 1164 dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
1165 adapter->tx_hwtstamp_skb = NULL; 1165 adapter->tx_hwtstamp_skb = NULL;
1166 } else if (time_after(jiffies, adapter->tx_hwtstamp_start
1167 + adapter->tx_timeout_factor * HZ)) {
1168 dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
1169 adapter->tx_hwtstamp_skb = NULL;
1170 adapter->tx_hwtstamp_timeouts++;
1171 e_warn("clearing Tx timestamp hang");
1166 } else { 1172 } else {
1167 /* reschedule to check later */ 1173 /* reschedule to check later */
1168 schedule_work(&adapter->tx_hwtstamp_work); 1174 schedule_work(&adapter->tx_hwtstamp_work);
@@ -5567,6 +5573,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
5567 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 5573 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
5568 tx_flags |= E1000_TX_FLAGS_HWTSTAMP; 5574 tx_flags |= E1000_TX_FLAGS_HWTSTAMP;
5569 adapter->tx_hwtstamp_skb = skb_get(skb); 5575 adapter->tx_hwtstamp_skb = skb_get(skb);
5576 adapter->tx_hwtstamp_start = jiffies;
5570 schedule_work(&adapter->tx_hwtstamp_work); 5577 schedule_work(&adapter->tx_hwtstamp_work);
5571 } else { 5578 } else {
5572 skb_tx_timestamp(skb); 5579 skb_tx_timestamp(skb);