]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: airoha: Add missing cleanup bits in airoha_qdma_cleanup_rx_queue()
authorLorenzo Bianconi <lorenzo@kernel.org>
Fri, 27 Mar 2026 09:48:21 +0000 (10:48 +0100)
committerJakub Kicinski <kuba@kernel.org>
Tue, 31 Mar 2026 00:29:16 +0000 (17:29 -0700)
In order to properly cleanup hw rx QDMA queues and bring the device to
the initial state, reset rx DMA queue head/tail index. Moreover, reset
queued DMA descriptor fields.

Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Tested-by: Madhur Agrawal <Madhur.Agrawal@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260327-airoha_qdma_cleanup_rx_queue-fix-v1-1-369d6ab1511a@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/airoha/airoha_eth.c

index 56cf9a926a83da38bb03373ced9728f1fecdbce7..c2a54dbcbb0d576da298f2a36a354afaef89b240 100644 (file)
@@ -794,18 +794,34 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
 
 static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
 {
-       struct airoha_eth *eth = q->qdma->eth;
+       struct airoha_qdma *qdma = q->qdma;
+       struct airoha_eth *eth = qdma->eth;
+       int qid = q - &qdma->q_rx[0];
 
        while (q->queued) {
                struct airoha_queue_entry *e = &q->entry[q->tail];
+               struct airoha_qdma_desc *desc = &q->desc[q->tail];
                struct page *page = virt_to_head_page(e->buf);
 
                dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len,
                                        page_pool_get_dma_dir(q->page_pool));
                page_pool_put_full_page(q->page_pool, page, false);
+               /* Reset DMA descriptor */
+               WRITE_ONCE(desc->ctrl, 0);
+               WRITE_ONCE(desc->addr, 0);
+               WRITE_ONCE(desc->data, 0);
+               WRITE_ONCE(desc->msg0, 0);
+               WRITE_ONCE(desc->msg1, 0);
+               WRITE_ONCE(desc->msg2, 0);
+               WRITE_ONCE(desc->msg3, 0);
+
                q->tail = (q->tail + 1) % q->ndesc;
                q->queued--;
        }
+
+       q->head = q->tail;
+       airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
+                       FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
 }
 
 static int airoha_qdma_init_rx(struct airoha_qdma *qdma)