]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ice: Process TSYN IRQ in a separate function
authorKarol Kolacinski <karol.kolacinski@intel.com>
Mon, 30 Sep 2024 12:12:41 +0000 (14:12 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Mon, 10 Feb 2025 18:43:47 +0000 (10:43 -0800)
Simplify TSYN IRQ processing by moving it to a separate function and
having appropriate behavior per PHY model, instead of multiple
conditions not related to HW, but to specific timestamping modes.

When PTP is not enabled in the kernel, don't process timestamps and
return IRQ_HANDLED.

Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_ptp.c
drivers/net/ethernet/intel/ice/ice_ptp.h

index d7037de29545f03c87ba921015a617ca0d65abef..c402ab9f34569eb8e2c1465d6b378fdc3b530330 100644 (file)
@@ -3304,22 +3304,8 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
 
        if (oicr & PFINT_OICR_TSYN_TX_M) {
                ena_mask &= ~PFINT_OICR_TSYN_TX_M;
-               if (ice_pf_state_is_nominal(pf) &&
-                   pf->hw.dev_caps.ts_dev_info.ts_ll_int_read) {
-                       struct ice_ptp_tx *tx = &pf->ptp.port.tx;
-                       unsigned long flags;
-                       u8 idx;
-
-                       spin_lock_irqsave(&tx->lock, flags);
-                       idx = find_next_bit_wrap(tx->in_use, tx->len,
-                                                tx->last_ll_ts_idx_read + 1);
-                       if (idx != tx->len)
-                               ice_ptp_req_tx_single_tstamp(tx, idx);
-                       spin_unlock_irqrestore(&tx->lock, flags);
-               } else if (ice_ptp_pf_handles_tx_interrupt(pf)) {
-                       set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
-                       ret = IRQ_WAKE_THREAD;
-               }
+
+               ret = ice_ptp_ts_irq(pf);
        }
 
        if (oicr & PFINT_OICR_TSYN_EVNT_M) {
index 7bb4005a67f63bbed7a911df6fea7b2c1d1362df..698f906e2e5914611e8752a47ca7221936925a87 100644 (file)
@@ -2763,6 +2763,55 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
        }
 }
 
+/**
+ * ice_ptp_ts_irq - Process the PTP Tx timestamps in IRQ context
+ * @pf: Board private structure
+ *
+ * Return: IRQ_WAKE_THREAD if Tx timestamp read has to be handled in the bottom
+ *         half of the interrupt and IRQ_HANDLED otherwise.
+ */
+irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf)
+{
+       struct ice_hw *hw = &pf->hw;
+
+       switch (hw->mac_type) {
+       case ICE_MAC_E810:
+               /* E810 capable of low latency timestamping with interrupt can
+                * request a single timestamp in the top half and wait for
+                * a second LL TS interrupt from the FW when it's ready.
+                */
+               if (hw->dev_caps.ts_dev_info.ts_ll_int_read) {
+                       struct ice_ptp_tx *tx = &pf->ptp.port.tx;
+                       u8 idx;
+
+                       if (!ice_pf_state_is_nominal(pf))
+                               return IRQ_HANDLED;
+
+                       spin_lock(&tx->lock);
+                       idx = find_next_bit_wrap(tx->in_use, tx->len,
+                                                tx->last_ll_ts_idx_read + 1);
+                       if (idx != tx->len)
+                               ice_ptp_req_tx_single_tstamp(tx, idx);
+                       spin_unlock(&tx->lock);
+
+                       return IRQ_HANDLED;
+               }
+               fallthrough; /* non-LL_TS E810 */
+       case ICE_MAC_GENERIC:
+       case ICE_MAC_GENERIC_3K_E825:
+               /* All other devices process timestamps in the bottom half due
+                * to sleeping or polling.
+                */
+               if (!ice_ptp_pf_handles_tx_interrupt(pf))
+                       return IRQ_HANDLED;
+
+               set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
+               return IRQ_WAKE_THREAD;
+       default:
+               return IRQ_HANDLED;
+       }
+}
+
 /**
  * ice_ptp_maybe_trigger_tx_interrupt - Trigger Tx timstamp interrupt
  * @pf: Board private structure
index a1d0e988c084b2c320fc638429cb8915e6582f86..a3b27f7162825f3da3fc695785c3c2d7b15f36f9 100644 (file)
@@ -304,6 +304,7 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
 void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx);
 void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx);
 enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
+irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf);
 
 u64 ice_ptp_get_rx_hwts(const union ice_32b_rx_flex_desc *rx_desc,
                        const struct ice_pkt_ctx *pkt_ctx);
@@ -342,6 +343,11 @@ static inline bool ice_ptp_process_ts(struct ice_pf *pf)
        return true;
 }
 
+static inline irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf)
+{
+       return IRQ_HANDLED;
+}
+
 static inline u64
 ice_ptp_get_rx_hwts(const union ice_32b_rx_flex_desc *rx_desc,
                    const struct ice_pkt_ctx *pkt_ctx)