From 3de3e6452398ed3e40db24d11ff4a59025ddb3f0 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 12 Feb 2026 09:10:26 +0000 Subject: [PATCH 1/2] Revert "net: macb: Fix RX ring refill issue after link up" This reverts commit 6fc937df589aa91e304bc9b174a880de911d497a. --- drivers/net/ethernet/cadence/macb.h | 1 - drivers/net/ethernet/cadence/macb_main.c | 15 +++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 90c0803c65c655..f797244f576416 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -1259,7 +1259,6 @@ struct macb_queue { void *rx_buffers; struct napi_struct napi_rx; struct queue_stats stats; - atomic_t full_refill; }; struct ethtool_rx_fs_item { diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 913a58c969376e..30f0ea8c435686 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -775,18 +775,11 @@ static void macb_mac_link_up(struct phylink_config *config, /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down * cleared the pipeline and control registers. */ - - for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) - atomic_set(&queue->full_refill, -1); - - bp->macbgem_ops.mog_init_rings(bp); macb_init_buffers(bp); - for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { - atomic_set(&queue->full_refill, bp->rx_ring_size); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) queue_writel(queue, IER, bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); - } } macb_or_gem_writel(bp, NCFGR, ctrl); @@ -1334,9 +1327,8 @@ static void gem_rx_refill(struct macb_queue *queue) struct macb *bp = queue->bp; struct macb_dma_desc *desc; - while (atomic_dec_if_positive(&queue->full_refill) >= 0 || - ((CIRC_SPACE(queue->rx_prepared_head, queue->rx_tail, bp->rx_ring_size) > 0) && - (atomic_read(&queue->full_refill) != -1))) { + while (CIRC_SPACE(queue->rx_prepared_head, queue->rx_tail, + bp->rx_ring_size) > 0) { entry = macb_rx_ring_wrap(bp, queue->rx_prepared_head); /* Make hw descriptor updates visible to CPU */ @@ -1461,7 +1453,6 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi, queue->stats.rx_dropped++; break; } - /* now everything is ready for receiving packet */ queue->rx_skbuff[entry] = NULL; len = ctrl & bp->rx_frm_len_mask; From 968d32f229ca4c41487cf605041585f0b1d6b221 Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Sun, 8 Feb 2026 15:27:58 +0800 Subject: [PATCH 2/2] net: macb: Fix tx/rx malfunction after phy link down and up In commit 99537d5c476c ("net: macb: Relocate mog_init_rings() callback from macb_mac_link_up() to macb_open()"), the mog_init_rings() callback was moved from macb_mac_link_up() to macb_open() to resolve a deadlock issue. However, this change introduced a tx/rx malfunction following phy link down and up events. The issue arises from a mismatch between the software queue->tx_head, queue->tx_tail, queue->rx_prepared_head, and queue->rx_tail values and the hardware's internal tx/rx queue pointers. According to the Zynq UltraScale TRM [1], when tx/rx is disabled, the internal tx queue pointer resets to the value in the tx queue base address register, while the internal rx queue pointer remains unchanged. The following is quoted from the Zynq UltraScale TRM: When transmit is disabled, with bit [3] of the network control register set low, the transmit-buffer queue pointer resets to point to the address indicated by the transmit-buffer queue base address register. Disabling receive does not have the same effect on the receive-buffer queue pointer. Additionally, there is no need to reset the RBQP and TBQP registers in a phy event callback. Therefore, move macb_init_buffers() to macb_open(). In a phy link up event, the only required action is to reset the tx/rx software head and tail pointers to align with the hardware's behavior. [1] https://docs.amd.com/v/u/en-US/ug1085-zynq-ultrascale-trm Fixes: 99537d5c476c ("net: macb: Relocate mog_init_rings() callback from macb_mac_link_up() to macb_open()") Signed-off-by: Kevin Hao Cc: stable@vger.kernel.org --- drivers/net/ethernet/cadence/macb_main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 30f0ea8c435686..d06b6f2e52c863 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -772,14 +772,12 @@ static void macb_mac_link_up(struct phylink_config *config, if (rx_pause) ctrl |= MACB_BIT(PAE); - /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down - * cleared the pipeline and control registers. - */ - macb_init_buffers(bp); - - for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { + queue->tx_head = 0; + queue->tx_tail = 0; queue_writel(queue, IER, bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); + } } macb_or_gem_writel(bp, NCFGR, ctrl); @@ -3049,6 +3047,7 @@ static int macb_open(struct net_device *dev) } bp->macbgem_ops.mog_init_rings(bp); + macb_init_buffers(bp); for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { napi_enable(&queue->napi_rx);