c84bfbfd08f44e09a2e6ff2351aa35f2a1252a99
[librecmc/librecmc.git] /
1 From 4e6bf609569c59b6bd6acf4a607c096cbd820d79 Mon Sep 17 00:00:00 2001
2 From: Felix Fietkau <nbd@nbd.name>
3 Date: Thu, 22 Apr 2021 22:21:03 -0700
4 Subject: [PATCH] net: ethernet: mtk_eth_soc: cache HW pointer of last freed TX
5  descriptor
6
7 The value is only updated by the CPU, so it is cheaper to access from the
8 ring data structure than from a hardware register.
9
10 Signed-off-by: Felix Fietkau <nbd@nbd.name>
11 Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
13 ---
14  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++----
15  drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
16  2 files changed, 6 insertions(+), 4 deletions(-)
17
18 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
19 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
20 @@ -1399,7 +1399,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
21         struct mtk_tx_buf *tx_buf;
22         u32 cpu, dma;
23  
24 -       cpu = mtk_r32(eth, MTK_QTX_CRX_PTR);
25 +       cpu = ring->last_free_ptr;
26         dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
27  
28         desc = mtk_qdma_phys_to_virt(ring, cpu);
29 @@ -1433,6 +1433,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
30                 cpu = next_cpu;
31         }
32  
33 +       ring->last_free_ptr = cpu;
34         mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
35  
36         return budget;
37 @@ -1633,6 +1634,7 @@ static int mtk_tx_alloc(struct mtk_eth *
38         atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
39         ring->next_free = &ring->dma[0];
40         ring->last_free = &ring->dma[MTK_DMA_SIZE - 1];
41 +       ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz));
42         ring->thresh = MAX_SKB_FRAGS;
43  
44         /* make sure that all changes to the dma ring are flushed before we
45 @@ -1646,9 +1648,7 @@ static int mtk_tx_alloc(struct mtk_eth *
46                 mtk_w32(eth,
47                         ring->phys + ((MTK_DMA_SIZE - 1) * sz),
48                         MTK_QTX_CRX_PTR);
49 -               mtk_w32(eth,
50 -                       ring->phys + ((MTK_DMA_SIZE - 1) * sz),
51 -                       MTK_QTX_DRX_PTR);
52 +               mtk_w32(eth, ring->last_free_ptr, MTK_QTX_DRX_PTR);
53                 mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
54                         MTK_QTX_CFG(0));
55         } else {
56 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
57 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
58 @@ -656,6 +656,7 @@ struct mtk_tx_buf {
59   * @phys:              The physical addr of tx_buf
60   * @next_free:         Pointer to the next free descriptor
61   * @last_free:         Pointer to the last free descriptor
62 + * @last_free_ptr:     Hardware pointer value of the last free descriptor
63   * @thresh:            The threshold of minimum amount of free descriptors
64   * @free_count:                QDMA uses a linked list. Track how many free descriptors
65   *                     are present
66 @@ -666,6 +667,7 @@ struct mtk_tx_ring {
67         dma_addr_t phys;
68         struct mtk_tx_dma *next_free;
69         struct mtk_tx_dma *last_free;
70 +       u32 last_free_ptr;
71         u16 thresh;
72         atomic_t free_count;
73         int dma_size;