From: Lorenzo Bianconi Date: Tue, 29 Oct 2024 12:17:09 +0000 (+0100) Subject: net: airoha: Read completion queue data in airoha_qdma_tx_napi_poll() X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=3affa310de523d63e52ea8e2efb3c476df29e414;p=users%2Fjedix%2Flinux-maple.git net: airoha: Read completion queue data in airoha_qdma_tx_napi_poll() In order to avoid any possible race, read completion queue head and pending entry in airoha_qdma_tx_napi_poll routine instead of doing it in airoha_irq_handler. Remove unused airoha_tx_irq_queue unused fields. This is a preliminary patch to add Qdisc offload for airoha_eth driver. Signed-off-by: Lorenzo Bianconi Link: https://patch.msgid.link/20241029-airoha-en7581-tx-napi-work-v1-1-96ad1686b946@kernel.org Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c index f463a505f5ba..6cd8901ed38f 100644 --- a/drivers/net/ethernet/mediatek/airoha_eth.c +++ b/drivers/net/ethernet/mediatek/airoha_eth.c @@ -752,11 +752,9 @@ struct airoha_tx_irq_queue { struct airoha_qdma *qdma; struct napi_struct napi; - u32 *q; int size; - int queued; - u16 head; + u32 *q; }; struct airoha_hw_stats { @@ -1656,25 +1654,31 @@ static int airoha_qdma_init_rx(struct airoha_qdma *qdma) static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget) { struct airoha_tx_irq_queue *irq_q; + int id, done = 0, irq_queued; struct airoha_qdma *qdma; struct airoha_eth *eth; - int id, done = 0; + u32 status, head; irq_q = container_of(napi, struct airoha_tx_irq_queue, napi); qdma = irq_q->qdma; id = irq_q - &qdma->q_tx_irq[0]; eth = qdma->eth; - while (irq_q->queued > 0 && done < budget) { - u32 qid, last, val = irq_q->q[irq_q->head]; + status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(id)); + head = FIELD_GET(IRQ_HEAD_IDX_MASK, status); + head = head % irq_q->size; + irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); + + while (irq_queued > 0 && done < budget) { + u32 qid, last, val = irq_q->q[head]; struct airoha_queue *q; if (val == 0xff) break; - irq_q->q[irq_q->head] = 0xff; /* mark as done */ - irq_q->head = (irq_q->head + 1) % irq_q->size; - irq_q->queued--; + irq_q->q[head] = 0xff; /* mark as done */ + head = (head + 1) % irq_q->size; + irq_queued--; done++; last = FIELD_GET(IRQ_DESC_IDX_MASK, val); @@ -2026,20 +2030,11 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance) if (intr[0] & INT_TX_MASK) { for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { - struct airoha_tx_irq_queue *irq_q = &qdma->q_tx_irq[i]; - u32 status, head; - if (!(intr[0] & TX_DONE_INT_MASK(i))) continue; airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0, TX_DONE_INT_MASK(i)); - - status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(i)); - head = FIELD_GET(IRQ_HEAD_IDX_MASK, status); - irq_q->head = head % irq_q->size; - irq_q->queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); - napi_schedule(&qdma->q_tx_irq[i].napi); } }