@@ -3202,7 +3202,7 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
ice_ptp_extts_event(pf);
if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) {
- while (!ice_ptp_process_ts(pf))
+ while (ice_ptp_process_ts(pf) == ICE_TX_TSTAMP_WORK_PENDING)
usleep_range(50, 100);
}
@@ -617,7 +617,7 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
}
/**
- * ice_ptp_tx_tstamp - Process Tx timestamps for a port
+ * ice_ptp_process_tx_tstamp - Process Tx timestamps for a port
* @tx: the PTP Tx timestamp tracker
*
* Process timestamps captured by the PHY associated with this port. To do
@@ -633,15 +633,6 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
* 6) extend the 40 bit timestamp value to get a 64 bit timestamp value
* 7) send this 64 bit timestamp to the stack
*
- * Returns true if all timestamps were handled, and false if any slots remain
- * without a timestamp.
- *
- * After looping, if we still have waiting SKBs, return false. This may cause
- * us effectively poll even when not strictly necessary. We do this because
- * it's possible a new timestamp was requested around the same time as the
- * interrupt. In some cases hardware might not interrupt us again when the
- * timestamp is captured.
- *
* Note that we do not hold the tracking lock while reading the Tx timestamp.
* This is because reading the timestamp requires taking a mutex that might
* sleep.
@@ -673,10 +664,9 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
* the packet will never be sent by hardware and discard it without reading
* the timestamp register.
*/
-static bool ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
+static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
{
struct ice_ptp_port *ptp_port;
- bool more_timestamps;
struct ice_pf *pf;
struct ice_hw *hw;
u64 tstamp_ready;
@@ -685,7 +675,7 @@ static bool ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
u8 idx;
if (!tx->init)
- return true;
+ return;
ptp_port = container_of(tx, struct ice_ptp_port, tx);
pf = ptp_port_to_pf(ptp_port);
@@ -694,7 +684,7 @@ static bool ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
/* Read the Tx ready status first */
err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
if (err)
- return false;
+ return;
/* Drop packets if the link went down */
link_up = ptp_port->link_up;
@@ -782,15 +772,34 @@ static bool ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
skb_tstamp_tx(skb, &shhwtstamps);
dev_kfree_skb_any(skb);
}
+}
- /* Check if we still have work to do. If so, re-queue this task to
- * poll for remaining timestamps.
- */
+/**
+ * ice_ptp_tx_tstamp - Process Tx timestamps for this function.
+ * @tx: Tx tracking structure to initialize
+ *
+ * Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding incomplete
+ * Tx timestamps, or ICE_TX_TSTAMP_WORK_DONE otherwise.
+ */
+static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
+{
+ bool more_timestamps;
+
+ if (!tx->init)
+ return ICE_TX_TSTAMP_WORK_DONE;
+
+ /* Process the Tx timestamp tracker */
+ ice_ptp_process_tx_tstamp(tx);
+
+ /* Check if there are outstanding Tx timestamps */
spin_lock(&tx->lock);
more_timestamps = tx->init && !bitmap_empty(tx->in_use, tx->len);
spin_unlock(&tx->lock);
- return !more_timestamps;
+ if (more_timestamps)
+ return ICE_TX_TSTAMP_WORK_PENDING;
+
+ return ICE_TX_TSTAMP_WORK_DONE;
}
/**
@@ -2426,9 +2435,10 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
* ice_ptp_process_ts - Process the PTP Tx timestamps
* @pf: Board private structure
*
- * Returns true if timestamps are processed.
+ * Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding Tx
+ * timestamps that need processing, and ICE_TX_TSTAMP_WORK_DONE otherwise.
*/
-bool ice_ptp_process_ts(struct ice_pf *pf)
+enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
{
return ice_ptp_tx_tstamp(&pf->ptp.port.tx);
}
@@ -108,6 +108,16 @@ struct ice_tx_tstamp {
u64 cached_tstamp;
};
+/**
+ * enum ice_tx_tstamp_work - Status of Tx timestamp work function
+ * @ICE_TX_TSTAMP_WORK_DONE: Tx timestamp processing is complete
+ * @ICE_TX_TSTAMP_WORK_PENDING: More Tx timestamps are pending
+ */
+enum ice_tx_tstamp_work {
+ ICE_TX_TSTAMP_WORK_DONE = 0,
+ ICE_TX_TSTAMP_WORK_PENDING,
+};
+
/**
* struct ice_ptp_tx - Tracking structure for all Tx timestamp requests on a port
* @lock: lock to prevent concurrent access to fields of this struct
@@ -256,7 +266,7 @@ int ice_get_ptp_clock_index(struct ice_pf *pf);
void ice_ptp_extts_event(struct ice_pf *pf);
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
-bool ice_ptp_process_ts(struct ice_pf *pf);
+enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
void
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,