From 26482216a39c9653ea319cd1d6e609b8d1f0fc12 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 28 Aug 2025 20:05:51 +0530 Subject: [PATCH] PENDING: net: ti: prueth: Fix queue pointer sync across PRU's As part of TX optimization, we have common queues which are accessed by both PRU's inorder to avoid double copy. It is very important to maintain synchronization of pointers across both PRU's in order to avoid queue corruption and non aligned access. Since the queues are common for both PRU's it is mandatory to update the pointers of both PRU's in order to maintain the sync. Reviewed-by: pmohan Signed-off-by: Roger Quadros Signed-off-by: Andrew F. Davis Signed-off-by: Basharath Hussain Khaja Signed-off-by: Parvathi Pudi --- drivers/net/ethernet/ti/icssm/icssm_prueth.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/icssm/icssm_prueth.c b/drivers/net/ethernet/ti/icssm/icssm_prueth.c index 6618ed517ae6..d067bea985fc 100644 --- a/drivers/net/ethernet/ti/icssm/icssm_prueth.c +++ b/drivers/net/ethernet/ti/icssm/icssm_prueth.c @@ -935,6 +935,7 @@ static int icssm_prueth_tx_enqueue(struct prueth_emac *emac, u16 bd_rd_ptr_other_port; struct ethhdr *ethhdr; bool is_vlan = false; + bool link_up = false; int pkt_block_size; void __iomem *sram; void __iomem *dram; @@ -947,6 +948,18 @@ static int icssm_prueth_tx_enqueue(struct prueth_emac *emac, other_emac = emac->prueth->emac[(emac->port_id ^ 3) - 1]; + /* TX Optimization + * As part of TX optimization, we have common queues which + * are accessed by both PRU's inorder to avoid double copy. + * It is very important to maintain synchronization of + * pointers across both PRU's in order to avoid queue corruption + * and non aligned access. + * Since the queues are common for both PRU's it is mandatory to + * update the pointers of both PRU's in order to maintain the sync. + */ + if (PRUETH_IS_LRE(prueth) && (emac->link || other_emac->link)) + link_up = true; + if (!PRUETH_IS_EMAC(prueth)) dram = prueth->mem[PRUETH_MEM_DRAM1].va; else @@ -990,7 +1003,7 @@ static int icssm_prueth_tx_enqueue(struct prueth_emac *emac, } /* HSR PRP Tx Optimization: Calculate free blocks for Other port */ - if (PRUETH_IS_LRE(prueth) && other_emac->link) { + if (PRUETH_IS_LRE(prueth) && link_up) { queue_desc_other_port = emac->tx_queue_descs_other_port + queue_id; bd_rd_ptr_other_port = readw(&queue_desc_other_port->rd_ptr); @@ -1180,7 +1193,7 @@ static int icssm_prueth_tx_enqueue(struct prueth_emac *emac, /* Tx optimization - update the write pointer in * queue descriptor of other port */ - if (PRUETH_IS_LRE(prueth) && other_emac->link) + if (PRUETH_IS_LRE(prueth) && link_up) writew(update_wr_ptr, &queue_desc_other_port->wr_ptr); return 0;