mirror of
https://github.com/LiBwrt-op/openwrt-6.x.git
synced 2025-12-17 09:16:59 +00:00
Changes: * removed upstreamed patches, * rebased local patches, * fix en7581_evb/an7583_evb booting issues * enable position independent code Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> Link: https://github.com/openwrt/openwrt/pull/20400 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
94 lines
3.6 KiB
Diff
94 lines
3.6 KiB
Diff
From e7b7bd119b68fe9106a1c9a45a7eba811fc40ce0 Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
|
Date: Fri, 3 Oct 2025 20:12:06 +0300
|
|
Subject: [PATCH v2 1/2] net: airoha: simplify rx/free packet logic a bit
|
|
|
|
The commit 997786bbf473 ("drivers/net/airoha_eth: fix stalling in package
|
|
receiving") can be improved. Instead of returning previous descriptor
|
|
it's possible:
|
|
* do nothing in even descriptor case
|
|
* return 2 descriptor to the queue (current and previous) in the odd
|
|
descriptor case.
|
|
|
|
This patch:
|
|
* implements above approach
|
|
* remove logic not required within new approach
|
|
* adds note that PKTBUFSRX must be even and larger than 7
|
|
for reliable driver operations
|
|
|
|
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
|
---
|
|
drivers/net/airoha_eth.c | 40 +++++++++++++++++++++-------------------
|
|
1 file changed, 21 insertions(+), 19 deletions(-)
|
|
|
|
--- a/drivers/net/airoha_eth.c
|
|
+++ b/drivers/net/airoha_eth.c
|
|
@@ -492,14 +492,10 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
|
|
RX_RING_SIZE_MASK,
|
|
FIELD_PREP(RX_RING_SIZE_MASK, ndesc));
|
|
|
|
- /*
|
|
- * See arht_eth_free_pkt() for the reasons used to fill
|
|
- * REG_RX_CPU_IDX(qid) register.
|
|
- */
|
|
airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK,
|
|
FIELD_PREP(RX_RING_THR_MASK, 0));
|
|
airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
|
|
- FIELD_PREP(RX_RING_CPU_IDX_MASK, q->ndesc - 3));
|
|
+ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->ndesc - 1));
|
|
airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
|
|
FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head));
|
|
|
|
@@ -1010,7 +1006,6 @@ static int arht_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
|
|
struct airoha_qdma *qdma = ð->qdma[0];
|
|
struct airoha_queue *q;
|
|
int qid;
|
|
- u16 prev, pprev;
|
|
|
|
if (!packet)
|
|
return 0;
|
|
@@ -1020,22 +1015,29 @@ static int arht_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
|
|
|
|
/*
|
|
* Due to cpu cache issue the airoha_qdma_reset_rx_desc() function
|
|
- * will always touch 2 descriptors:
|
|
- * - if current descriptor is even, then the previous and the one
|
|
- * before previous descriptors will be touched (previous cacheline)
|
|
- * - if current descriptor is odd, then only current and previous
|
|
- * descriptors will be touched (current cacheline)
|
|
+ * will always touch 2 descriptors placed on the same cacheline:
|
|
+ * - if current descriptor is even, then current and next
|
|
+ * descriptors will be touched
|
|
+ * - if current descriptor is odd, then current and previous
|
|
+ * descriptors will be touched
|
|
*
|
|
- * Thus, to prevent possible destroying of rx queue, only (q->ndesc - 2)
|
|
- * descriptors might be used for packet receiving.
|
|
+ * Thus, to prevent possible destroying of rx queue, we should:
|
|
+ * - do nothing in the even descriptor case,
|
|
+ * - utilize 2 descriptors (current and previous one) in the
|
|
+ * odd descriptor case.
|
|
+ *
|
|
+ * WARNING: Observations shows that PKTBUFSRX must be even and
|
|
+ * larger than 7 for reliable driver operations.
|
|
*/
|
|
- prev = (q->head + q->ndesc - 1) % q->ndesc;
|
|
- pprev = (q->head + q->ndesc - 2) % q->ndesc;
|
|
- q->head = (q->head + 1) % q->ndesc;
|
|
+ if (q->head & 0x01) {
|
|
+ airoha_qdma_reset_rx_desc(q, q->head - 1);
|
|
+ airoha_qdma_reset_rx_desc(q, q->head);
|
|
|
|
- airoha_qdma_reset_rx_desc(q, prev);
|
|
- airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
|
|
- FIELD_PREP(RX_RING_CPU_IDX_MASK, pprev));
|
|
+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
|
|
+ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
|
|
+ }
|
|
+
|
|
+ q->head = (q->head + 1) % q->ndesc;
|
|
|
|
return 0;
|
|
}
|
|
|