]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: ethernet: ti: am65-cpsw: Use also port number to identify timestamps
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Fri, 6 Mar 2026 14:44:39 +0000 (15:44 +0100)
committerJakub Kicinski <kuba@kernel.org>
Tue, 10 Mar 2026 02:01:08 +0000 (19:01 -0700)
The driver uses packet-type (RX/TX) PTP-message type and PTP-sequence
number to identify a matching timestamp packet for a skb. If the same
PTP packet arrives on both ports (as in a PRP environment) then it is
not obvious which event belongs to which skb.

The event contains also the port number on which it was received.
Instead of masking it out, use it for matching.

Tested-by: Chintan Vankar <c-vankar@ti.com>
Reviewed-by: Martin Kaistra <martin.kaistra@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://patch.msgid.link/20260306144439.cVwaaopR@linutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/ti/am65-cpsw-nuss.c
drivers/net/ethernet/ti/am65-cpts.c
drivers/net/ethernet/ti/am65-cpts.h

index 9679180504330fc59617da84119bed1332c7cb58..a38bf7f4f43434e46944fe34938575f3a1b81404 100644 (file)
@@ -1352,7 +1352,7 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow,
        am65_cpsw_nuss_set_offload_fwd_mark(skb, ndev_priv->offload_fwd_mark);
        skb_put(skb, pkt_len);
        if (port->rx_ts_enabled)
-               am65_cpts_rx_timestamp(common->cpts, skb);
+               am65_cpts_rx_timestamp(common->cpts, port_id, skb);
        skb_mark_for_recycle(skb);
        skb->protocol = eth_type_trans(skb, ndev);
        am65_cpsw_nuss_rx_csum(skb, csum_info);
@@ -1607,7 +1607,7 @@ static netdev_tx_t am65_cpsw_nuss_ndo_slave_xmit(struct sk_buff *skb,
 
        /* SKB TX timestamp */
        if (port->tx_ts_enabled)
-               am65_cpts_prep_tx_timestamp(common->cpts, skb);
+               am65_cpts_prep_tx_timestamp(common->cpts, port->port_id, skb);
 
        q_idx = skb_get_queue_mapping(skb);
        dev_dbg(dev, "%s skb_queue:%d\n", __func__, q_idx);
index 8ffbfaa3ab18c8ca015c76c79933b4df8b6ea90e..efbf2ef976a3232d8c705bc9f757f428480952ea 100644 (file)
@@ -796,11 +796,7 @@ static bool am65_cpts_match_tx_ts(struct am65_cpts *cpts,
        bool found = false;
        u32 mtype_seqid;
 
-       mtype_seqid = event->event1 &
-                     (AM65_CPTS_EVENT_1_MESSAGE_TYPE_MASK |
-                      AM65_CPTS_EVENT_1_EVENT_TYPE_MASK |
-                      AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK);
-
+       mtype_seqid = event->event1;
        __skb_queue_head_init(&txq_list);
 
        spin_lock_irqsave(&cpts->txq.lock, flags);
@@ -922,7 +918,6 @@ static u64 am65_cpts_find_rx_ts(struct am65_cpts *cpts, u32 skb_mtype_seqid)
        struct list_head *this, *next;
        struct am65_cpts_event *event;
        unsigned long flags;
-       u32 mtype_seqid;
        u64 ns = 0;
 
        spin_lock_irqsave(&cpts->lock, flags);
@@ -934,12 +929,7 @@ static u64 am65_cpts_find_rx_ts(struct am65_cpts *cpts, u32 skb_mtype_seqid)
                        continue;
                }
 
-               mtype_seqid = event->event1 &
-                             (AM65_CPTS_EVENT_1_MESSAGE_TYPE_MASK |
-                              AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK |
-                              AM65_CPTS_EVENT_1_EVENT_TYPE_MASK);
-
-               if (mtype_seqid == skb_mtype_seqid) {
+               if (event->event1 == skb_mtype_seqid) {
                        ns = event->timestamp;
                        list_move(&event->list, &cpts->pool);
                        break;
@@ -950,7 +940,8 @@ static u64 am65_cpts_find_rx_ts(struct am65_cpts *cpts, u32 skb_mtype_seqid)
        return ns;
 }
 
-void am65_cpts_rx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb)
+void am65_cpts_rx_timestamp(struct am65_cpts *cpts, unsigned int port_id,
+                           struct sk_buff *skb)
 {
        struct am65_cpts_skb_cb_data *skb_cb = (struct am65_cpts_skb_cb_data *)skb->cb;
        struct skb_shared_hwtstamps *ssh;
@@ -966,6 +957,7 @@ void am65_cpts_rx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb)
        if (!ret)
                return; /* if not PTP class packet */
 
+       skb_cb->skb_mtype_seqid |= port_id << AM65_CPTS_EVENT_1_PORT_NUMBER_SHIFT;
        skb_cb->skb_mtype_seqid |= (AM65_CPTS_EV_RX << AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT);
 
        dev_dbg(cpts->dev, "%s mtype seqid %08x\n", __func__, skb_cb->skb_mtype_seqid);
@@ -1009,13 +1001,15 @@ EXPORT_SYMBOL_GPL(am65_cpts_tx_timestamp);
 /**
  * am65_cpts_prep_tx_timestamp - check and prepare tx packet for timestamping
  * @cpts: cpts handle
+ * @port_id: The port on which the skb will be sent
  * @skb: packet
  *
  * This functions should be called from .xmit().
  * It checks if packet can be timestamped, fills internal cpts data
  * in skb-cb and marks packet as SKBTX_IN_PROGRESS.
  */
-void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb)
+void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts, unsigned int port_id,
+                                struct sk_buff *skb)
 {
        struct am65_cpts_skb_cb_data *skb_cb = (void *)skb->cb;
        int ret;
@@ -1026,6 +1020,7 @@ void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb)
        ret = am65_skb_get_mtype_seqid(skb, &skb_cb->skb_mtype_seqid);
        if (!ret)
                return;
+       skb_cb->skb_mtype_seqid |= port_id << AM65_CPTS_EVENT_1_PORT_NUMBER_SHIFT;
        skb_cb->skb_mtype_seqid |= (AM65_CPTS_EV_TX <<
                                   AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT);
 
index 6099d772799da8d6ef650d5904f43db61694a992..5fa77b0fc8372a4bc496173b7fec45b25abf4514 100644 (file)
@@ -22,9 +22,11 @@ void am65_cpts_release(struct am65_cpts *cpts);
 struct am65_cpts *am65_cpts_create(struct device *dev, void __iomem *regs,
                                   struct device_node *node);
 int am65_cpts_phc_index(struct am65_cpts *cpts);
-void am65_cpts_rx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb);
+void am65_cpts_rx_timestamp(struct am65_cpts *cpts, unsigned int port_id,
+                           struct sk_buff *skb);
 void am65_cpts_tx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb);
-void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb);
+void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts, unsigned int port_id,
+                                struct sk_buff *skb);
 u64 am65_cpts_ns_gettime(struct am65_cpts *cpts);
 int am65_cpts_estf_enable(struct am65_cpts *cpts, int idx,
                          struct am65_cpts_estf_cfg *cfg);
@@ -49,6 +51,7 @@ static inline int am65_cpts_phc_index(struct am65_cpts *cpts)
 }
 
 static inline void am65_cpts_rx_timestamp(struct am65_cpts *cpts,
+                                         unsigned int port_id,
                                          struct sk_buff *skb)
 {
 }
@@ -59,6 +62,7 @@ static inline void am65_cpts_tx_timestamp(struct am65_cpts *cpts,
 }
 
 static inline void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts,
+                                              unsigned int port_id,
                                               struct sk_buff *skb)
 {
 }