|
@@ -435,10 +435,8 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter)
|
|
|
void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)
|
|
|
{
|
|
|
struct ixgbe_hw *hw = &adapter->hw;
|
|
|
- struct ixgbe_ring *rx_ring;
|
|
|
u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
|
|
|
unsigned long rx_event;
|
|
|
- int n;
|
|
|
|
|
|
/* if we don't have a valid timestamp in the registers, just update the
|
|
|
* timeout counter and exit
|
|
@@ -450,11 +448,8 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)
|
|
|
|
|
|
/* determine the most recent watchdog or rx_timestamp event */
|
|
|
rx_event = adapter->last_rx_ptp_check;
|
|
|
- for (n = 0; n < adapter->num_rx_queues; n++) {
|
|
|
- rx_ring = adapter->rx_ring[n];
|
|
|
- if (time_after(rx_ring->last_rx_timestamp, rx_event))
|
|
|
- rx_event = rx_ring->last_rx_timestamp;
|
|
|
- }
|
|
|
+ if (time_after(adapter->last_rx_timestamp, rx_event))
|
|
|
+ rx_event = adapter->last_rx_timestamp;
|
|
|
|
|
|
/* only need to read the high RXSTMP register to clear the lock */
|
|
|
if (time_is_before_jiffies(rx_event + 5*HZ)) {
|
|
@@ -530,35 +525,22 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * __ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
|
|
|
- * @q_vector: structure containing interrupt and ring information
|
|
|
+ * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
|
|
|
+ * @adapter: pointer to adapter struct
|
|
|
* @skb: particular skb to send timestamp with
|
|
|
*
|
|
|
* if the timestamp is valid, we convert it into the timecounter ns
|
|
|
* value, then store that result into the shhwtstamps structure which
|
|
|
* is passed up the network stack
|
|
|
*/
|
|
|
-void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
|
|
|
- struct sk_buff *skb)
|
|
|
+void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb)
|
|
|
{
|
|
|
- struct ixgbe_adapter *adapter;
|
|
|
- struct ixgbe_hw *hw;
|
|
|
+ struct ixgbe_hw *hw = &adapter->hw;
|
|
|
struct skb_shared_hwtstamps *shhwtstamps;
|
|
|
u64 regval = 0, ns;
|
|
|
u32 tsyncrxctl;
|
|
|
unsigned long flags;
|
|
|
|
|
|
- /* we cannot process timestamps on a ring without a q_vector */
|
|
|
- if (!q_vector || !q_vector->adapter)
|
|
|
- return;
|
|
|
-
|
|
|
- adapter = q_vector->adapter;
|
|
|
- hw = &adapter->hw;
|
|
|
-
|
|
|
- /*
|
|
|
- * Read the tsyncrxctl register afterwards in order to prevent taking an
|
|
|
- * I/O hit on every packet.
|
|
|
- */
|
|
|
tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
|
|
|
if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
|
|
|
return;
|
|
@@ -566,13 +548,17 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
|
|
|
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
|
|
|
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
|
|
|
|
|
|
-
|
|
|
spin_lock_irqsave(&adapter->tmreg_lock, flags);
|
|
|
ns = timecounter_cyc2time(&adapter->tc, regval);
|
|
|
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
|
|
|
|
|
|
shhwtstamps = skb_hwtstamps(skb);
|
|
|
shhwtstamps->hwtstamp = ns_to_ktime(ns);
|
|
|
+
|
|
|
+ /* Update the last_rx_timestamp timer in order to enable watchdog check
|
|
|
+ * for error case of latched timestamp on a dropped packet.
|
|
|
+ */
|
|
|
+ adapter->last_rx_timestamp = jiffies;
|
|
|
}
|
|
|
|
|
|
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
|