|
@@ -672,17 +672,26 @@ static void ixgbe_ptp_clear_tx_timestamp(struct ixgbe_adapter *adapter)
|
|
*/
|
|
*/
|
|
static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter)
|
|
static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter)
|
|
{
|
|
{
|
|
|
|
+ struct sk_buff *skb = adapter->ptp_tx_skb;
|
|
struct ixgbe_hw *hw = &adapter->hw;
|
|
struct ixgbe_hw *hw = &adapter->hw;
|
|
struct skb_shared_hwtstamps shhwtstamps;
|
|
struct skb_shared_hwtstamps shhwtstamps;
|
|
u64 regval = 0;
|
|
u64 regval = 0;
|
|
|
|
|
|
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
|
|
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
|
|
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32;
|
|
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32;
|
|
-
|
|
|
|
ixgbe_ptp_convert_to_hwtstamp(adapter, &shhwtstamps, regval);
|
|
ixgbe_ptp_convert_to_hwtstamp(adapter, &shhwtstamps, regval);
|
|
- skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps);
|
|
|
|
|
|
|
|
- ixgbe_ptp_clear_tx_timestamp(adapter);
|
|
|
|
|
|
+ /* Handle cleanup of the ptp_tx_skb ourselves, and unlock the state
|
|
|
|
+ * bit prior to notifying the stack via skb_tstamp_tx(). This prevents
|
|
|
|
+ * well behaved applications from attempting to timestamp again prior
|
|
|
|
+ * to the lock bit being clear.
|
|
|
|
+ */
|
|
|
|
+ adapter->ptp_tx_skb = NULL;
|
|
|
|
+ clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
|
|
|
|
+
|
|
|
|
+ /* Notify the stack and then free the skb after we've unlocked */
|
|
|
|
+ skb_tstamp_tx(skb, &shhwtstamps);
|
|
|
|
+ dev_kfree_skb_any(skb);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|