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 Reviewed-by: Martin Kaistra Signed-off-by: Sebastian Andrzej Siewior --- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 ++-- drivers/net/ethernet/ti/am65-cpts.c | 22 ++++++++-------------- drivers/net/ethernet/ti/am65-cpts.h | 8 ++++++-- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index 5924db6be3fea..756393088f0ee 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -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); diff --git a/drivers/net/ethernet/ti/am65-cpts.c b/drivers/net/ethernet/ti/am65-cpts.c index 8ffbfaa3ab18c..3699abec71f1f 100644 --- a/drivers/net/ethernet/ti/am65-cpts.c +++ b/drivers/net/ethernet/ti/am65-cpts.c @@ -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); @@ -1015,7 +1007,8 @@ EXPORT_SYMBOL_GPL(am65_cpts_tx_timestamp); * 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 +1019,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); diff --git a/drivers/net/ethernet/ti/am65-cpts.h b/drivers/net/ethernet/ti/am65-cpts.h index 6099d772799da..5fa77b0fc8372 100644 --- a/drivers/net/ethernet/ti/am65-cpts.h +++ b/drivers/net/ethernet/ti/am65-cpts.h @@ -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) { } -- 2.53.0