aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-5.10/610-v5.13-46-net-ethernet-mtk_eth_soc-cache-HW-pointer-of-last-fr.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/backport-5.10/610-v5.13-46-net-ethernet-mtk_eth_soc-cache-HW-pointer-of-last-fr.patch')
-rw-r--r--target/linux/generic/backport-5.10/610-v5.13-46-net-ethernet-mtk_eth_soc-cache-HW-pointer-of-last-fr.patch73
1 files changed, 73 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.10/610-v5.13-46-net-ethernet-mtk_eth_soc-cache-HW-pointer-of-last-fr.patch b/target/linux/generic/backport-5.10/610-v5.13-46-net-ethernet-mtk_eth_soc-cache-HW-pointer-of-last-fr.patch
new file mode 100644
index 0000000000..db21878e92
--- /dev/null
+++ b/target/linux/generic/backport-5.10/610-v5.13-46-net-ethernet-mtk_eth_soc-cache-HW-pointer-of-last-fr.patch
@@ -0,0 +1,73 @@
+From 4e6bf609569c59b6bd6acf4a607c096cbd820d79 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 22 Apr 2021 22:21:03 -0700
+Subject: [PATCH] net: ethernet: mtk_eth_soc: cache HW pointer of last freed TX
+ descriptor
+
+The value is only updated by the CPU, so it is cheaper to access from the
+ring data structure than from a hardware register.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1364,7 +1364,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
+ struct mtk_tx_buf *tx_buf;
+ u32 cpu, dma;
+
+- cpu = mtk_r32(eth, MTK_QTX_CRX_PTR);
++ cpu = ring->last_free_ptr;
+ dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
+
+ desc = mtk_qdma_phys_to_virt(ring, cpu);
+@@ -1398,6 +1398,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
+ cpu = next_cpu;
+ }
+
++ ring->last_free_ptr = cpu;
+ mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
+
+ return budget;
+@@ -1598,6 +1599,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+ atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
+ ring->next_free = &ring->dma[0];
+ ring->last_free = &ring->dma[MTK_DMA_SIZE - 1];
++ ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz));
+ ring->thresh = MAX_SKB_FRAGS;
+
+ /* make sure that all changes to the dma ring are flushed before we
+@@ -1611,9 +1613,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+ mtk_w32(eth,
+ ring->phys + ((MTK_DMA_SIZE - 1) * sz),
+ MTK_QTX_CRX_PTR);
+- mtk_w32(eth,
+- ring->phys + ((MTK_DMA_SIZE - 1) * sz),
+- MTK_QTX_DRX_PTR);
++ mtk_w32(eth, ring->last_free_ptr, MTK_QTX_DRX_PTR);
+ mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
+ MTK_QTX_CFG(0));
+ } else {
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -636,6 +636,7 @@ struct mtk_tx_buf {
+ * @phys: The physical addr of tx_buf
+ * @next_free: Pointer to the next free descriptor
+ * @last_free: Pointer to the last free descriptor
++ * @last_free_ptr: Hardware pointer value of the last free descriptor
+ * @thresh: The threshold of minimum amount of free descriptors
+ * @free_count: QDMA uses a linked list. Track how many free descriptors
+ * are present
+@@ -646,6 +647,7 @@ struct mtk_tx_ring {
+ dma_addr_t phys;
+ struct mtk_tx_dma *next_free;
+ struct mtk_tx_dma *last_free;
++ u32 last_free_ptr;
+ u16 thresh;
+ atomic_t free_count;
+ int dma_size;