|
@@ -711,6 +711,35 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * igb_ptp_tx_hang - detect error case where Tx timestamp never finishes
|
|
|
+ * @adapter: private network adapter structure
|
|
|
+ */
|
|
|
+void igb_ptp_tx_hang(struct igb_adapter *adapter)
|
|
|
+{
|
|
|
+ bool timeout = time_is_before_jiffies(adapter->ptp_tx_start +
|
|
|
+ IGB_PTP_TX_TIMEOUT);
|
|
|
+
|
|
|
+ if (!adapter->ptp_tx_skb)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!test_bit(__IGB_PTP_TX_IN_PROGRESS, &adapter->state))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* If we haven't received a timestamp within the timeout, it is
|
|
|
+ * reasonable to assume that it will never occur, so we can unlock the
|
|
|
+ * timestamp bit when this occurs.
|
|
|
+ */
|
|
|
+ if (timeout) {
|
|
|
+ cancel_work_sync(&adapter->ptp_tx_work);
|
|
|
+ dev_kfree_skb_any(adapter->ptp_tx_skb);
|
|
|
+ adapter->ptp_tx_skb = NULL;
|
|
|
+ clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
|
|
|
+ adapter->tx_hwtstamp_timeouts++;
|
|
|
+ dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* igb_ptp_tx_hwtstamp - utility function which checks for TX time stamp
|
|
|
* @adapter: Board private structure.
|