[][MT76][WED][Fix ccif tx ring cleanup error]
[Description]
Fix ccif tx ring cleanup error
[Release-log]
N/A
Change-Id: I907e2d016e6389034dd35eac11eb6d2dec067102
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6435524
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9997-add-wed-rx-support-for-mt7896.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9997-add-wed-rx-support-for-mt7896.patch
old mode 100755
new mode 100644
index 5da593d..8af3142
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9997-add-wed-rx-support-for-mt7896.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9997-add-wed-rx-support-for-mt7896.patch
@@ -8,7 +8,7 @@
arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 42 +-
arch/arm64/boot/dts/mediatek/mt7986b.dtsi | 42 +-
drivers/net/ethernet/mediatek/Makefile | 2 +-
- drivers/net/ethernet/mediatek/mtk_wed.c | 627 ++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_wed.c | 631 ++++++++++++++++--
drivers/net/ethernet/mediatek/mtk_wed.h | 51 ++
drivers/net/ethernet/mediatek/mtk_wed_ccif.c | 133 ++++
drivers/net/ethernet/mediatek/mtk_wed_ccif.h | 45 ++
@@ -16,8 +16,8 @@
drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 586 ++++++++++++++++
drivers/net/ethernet/mediatek/mtk_wed_mcu.h | 125 ++++
drivers/net/ethernet/mediatek/mtk_wed_regs.h | 145 +++-
- drivers/net/ethernet/mediatek/mtk_wed_wo.c | 581 ++++++++++++++++
- drivers/net/ethernet/mediatek/mtk_wed_wo.h | 327 +++++++++
+ drivers/net/ethernet/mediatek/mtk_wed_wo.c | 573 ++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_wed_wo.h | 336 ++++++++++
include/linux/soc/mediatek/mtk_wed.h | 75 ++-
14 files changed, 2796 insertions(+), 75 deletions(-)
create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ccif.c
@@ -324,10 +324,11 @@
int i;
if (!page_list)
-@@ -187,6 +291,13 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
+@@ -187,7 +291,14 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
if (!desc)
goto free_pagelist;
+- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
+ if (dev->ver == MTK_WED_V1) {
+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
+ } else {
@@ -335,10 +336,19 @@
+ MTK_WED_WDMA_RING_SIZE * 2;
+ }
+
- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
++ for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
void *page = page_list[page_idx++];
-@@ -205,6 +316,42 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
+ if (!page)
+@@ -198,13 +309,49 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
+ __free_page(page);
+ }
+
+- dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc),
++ dma_free_coherent(dev->hw->dev, ring_size * sizeof(*desc),
+ desc, dev->buf_ring.desc_phys);
+
+ free_pagelist:
kfree(page_list);
}
@@ -2552,7 +2562,7 @@
index 000000000..67dcffb26
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
-@@ -0,0 +1,581 @@
+@@ -0,0 +1,573 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/kernel.h>
@@ -2602,8 +2612,6 @@
+ woccif_w32(wo, q->regs->desc_base, q->desc_dma);
+ woccif_w32(wo, q->regs->ring_size, q->ndesc);
+
-+ /* wo fw start from 1 */
-+ q->tail = q->head = 1;
+}
+
+static void
@@ -2653,6 +2661,9 @@
+ }
+ dma_sync_single_for_cpu(wo->hw->dev, addr, len,
+ DMA_TO_DEVICE);
++
++ q->head = (q->head + 1) % q->ndesc;
++
+ desc = &q->desc[q->head];
+ entry = &q->entry[q->head];
+
@@ -2669,7 +2680,6 @@
+ q->queued++;
+ q->entry[q->head].buf = buf;
+
-+ q->head = (q->head + 1) % q->ndesc;
+ frames++;
+ }
+
@@ -2754,18 +2764,16 @@
+ if (flush)
+ last = -1;
+ else
-+ last = readl(&q->regs->dma_idx);
++ last = woccif_r32(wo, q->regs->dma_idx);
+
+ while (q->queued > 0 && q->tail != last) {
+ struct wed_wo_queue_entry *e;
+
-+ e = &q->entry[q->tail];
++ e = &q->entry[q->tail + 1];
+
+ dma_unmap_single(wo->hw->dev, e->dma_addr, e->dma_len,
+ DMA_TO_DEVICE);
+
-+ if (e->skb)
-+ dev_kfree_skb(e->skb);
+
+ memset(e, 0, sizeof(*e));
+
@@ -2774,8 +2782,6 @@
+ q->queued--;
+ spin_unlock_bh(&q->lock);
+
-+ if (!flush && q->tail == last)
-+ last = readl(&q->regs->dma_idx);
+ }
+ spin_unlock_bh(&q->cleanup_lock);
+
@@ -2794,7 +2800,7 @@
+ int buf_len = SKB_WITH_OVERHEAD(q->buf_size);
+ struct wed_wo_queue_entry *e;
+ struct wed_wo_desc *desc;
-+ int idx = q->tail;
++ int idx = (q->tail + 1) % q->ndesc;;
+ void *buf;
+
+ *more = false;
@@ -2806,7 +2812,7 @@
+ else if (!(q->desc[idx].ctrl & cpu_to_le32(WED_CTL_DMA_DONE)))
+ return NULL;
+
-+ q->tail = (q->tail + 1) % q->ndesc;
++ q->tail = idx;
+ q->queued--;
+
+ desc = &q->desc[idx];
@@ -2911,19 +2917,16 @@
+ goto error;
+
+ /* packet tx, force trigger tx clean. */
-+ if (q->queued + MTK_WED_WO_TXQ_FREE_THR >= q->ndesc - 1)
+ woif_q_tx_clean(wo, q, false);
+
-+ if (q->queued + 1 >= q->ndesc - 1) {
++ if (q->queued >= q->ndesc) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ spin_lock_bh(&q->lock);
+
-+ dma_sync_single_for_device(wo->hw->dev, addr, len,
-+ DMA_TO_DEVICE);
-+
++ q->head = (q->head + 1) % q->ndesc;
+ idx = q->head;
+
+ desc = &q->desc[idx];
@@ -2945,7 +2948,6 @@
+ woif_q_kick(wo, q, 0);
+ wo->drv_ops->kickout(wo);
+
-+ q->head = (q->head + 1) % q->ndesc;
+ spin_unlock_bh(&q->lock);
+ return 0;
+