mediatek: sync and patches add support for several boards
[openwrt.git] / target / linux / mediatek / patches-4.4 / 0084-net-next-mediatek-fix-missing-free-of-scratch-memory.patch
1 From 77c5d1b00214c9e42b9bd5f0f7fc0ec14807d117 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Sat, 23 Apr 2016 09:18:28 +0200
4 Subject: [PATCH 84/90] net-next: mediatek: fix missing free of scratch memory
5
6 Scratch memory gets allocated in mtk_init_fq_dma() but the corresponding
7 code to free it is missing inside mtk_dma_free() causing a memory leak.
8
9 Signed-off-by: John Crispin <blogic@openwrt.org>
10 ---
11  drivers/net/ethernet/mediatek/mtk_eth_soc.c |   18 +++++++++++++-----
12  drivers/net/ethernet/mediatek/mtk_eth_soc.h |    2 ++
13  2 files changed, 15 insertions(+), 5 deletions(-)
14
15 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
16 index e58a634..06b9094 100644
17 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
18 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
19 @@ -469,14 +469,14 @@ static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
20  /* the qdma core needs scratch memory to be setup */
21  static int mtk_init_fq_dma(struct mtk_eth *eth)
22  {
23 -       dma_addr_t phy_ring_head, phy_ring_tail;
24 +       dma_addr_t phy_ring_tail;
25         int cnt = MTK_DMA_SIZE;
26         dma_addr_t dma_addr;
27         int i;
28  
29         eth->scratch_ring = dma_alloc_coherent(eth->dev,
30                                                cnt * sizeof(struct mtk_tx_dma),
31 -                                              &phy_ring_head,
32 +                                              &eth->phy_scratch_ring,
33                                                GFP_ATOMIC | __GFP_ZERO);
34         if (unlikely(!eth->scratch_ring))
35                 return -ENOMEM;
36 @@ -493,19 +493,19 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
37                 return -ENOMEM;
38  
39         memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
40 -       phy_ring_tail = phy_ring_head +
41 +       phy_ring_tail = eth->phy_scratch_ring +
42                         (sizeof(struct mtk_tx_dma) * (cnt - 1));
43  
44         for (i = 0; i < cnt; i++) {
45                 eth->scratch_ring[i].txd1 =
46                                         (dma_addr + (i * MTK_QDMA_PAGE_SIZE));
47                 if (i < cnt - 1)
48 -                       eth->scratch_ring[i].txd2 = (phy_ring_head +
49 +                       eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring +
50                                 ((i + 1) * sizeof(struct mtk_tx_dma)));
51                 eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
52         }
53  
54 -       mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD);
55 +       mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD);
56         mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
57         mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
58         mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
59 @@ -1205,6 +1205,14 @@ static void mtk_dma_free(struct mtk_eth *eth)
60         for (i = 0; i < MTK_MAC_COUNT; i++)
61                 if (eth->netdev[i])
62                         netdev_reset_queue(eth->netdev[i]);
63 +       if (eth->scratch_ring) {
64 +               dma_free_coherent(eth->dev,
65 +                                 MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
66 +                                 eth->scratch_ring,
67 +                                 eth->phy_scratch_ring);
68 +               eth->scratch_ring = NULL;
69 +               eth->phy_scratch_ring = 0;
70 +       }
71         mtk_tx_clean(eth);
72         mtk_rx_clean(eth);
73         kfree(eth->scratch_head);
74 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
75 index eed626d..57f7e8a 100644
76 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
77 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
78 @@ -357,6 +357,7 @@ struct mtk_rx_ring {
79   * @rx_ring:           Pointer to the memore holding info about the RX ring
80   * @rx_napi:           The NAPI struct
81   * @scratch_ring:      Newer SoCs need memory for a second HW managed TX ring
82 + * @phy_scratch_ring:  physical address of scratch_ring
83   * @scratch_head:      The scratch memory that scratch_ring points to.
84   * @clk_ethif:         The ethif clock
85   * @clk_esw:           The switch clock
86 @@ -384,6 +385,7 @@ struct mtk_eth {
87         struct mtk_rx_ring              rx_ring;
88         struct napi_struct              rx_napi;
89         struct mtk_tx_dma               *scratch_ring;
90 +       dma_addr_t                      phy_scratch_ring;
91         void                            *scratch_head;
92         struct clk                      *clk_ethif;
93         struct clk                      *clk_esw;
94 -- 
95 1.7.10.4
96