base-files: fix some failsafe issues
[openwrt/openwrt.git] / target / linux / mediatek / patches-4.4 / 0084-net-next-mediatek-fix-missing-free-of-scratch-memory.patch
1 From 2d22628561299e1c7d71e16262131127de3c4216 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/91] 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 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
16 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
17 @@ -469,14 +469,14 @@ static inline void mtk_rx_get_desc(struc
18 /* the qdma core needs scratch memory to be setup */
19 static int mtk_init_fq_dma(struct mtk_eth *eth)
20 {
21 - dma_addr_t phy_ring_head, phy_ring_tail;
22 + dma_addr_t phy_ring_tail;
23 int cnt = MTK_DMA_SIZE;
24 dma_addr_t dma_addr;
25 int i;
26
27 eth->scratch_ring = dma_alloc_coherent(eth->dev,
28 cnt * sizeof(struct mtk_tx_dma),
29 - &phy_ring_head,
30 + &eth->phy_scratch_ring,
31 GFP_ATOMIC | __GFP_ZERO);
32 if (unlikely(!eth->scratch_ring))
33 return -ENOMEM;
34 @@ -493,19 +493,19 @@ static int mtk_init_fq_dma(struct mtk_et
35 return -ENOMEM;
36
37 memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
38 - phy_ring_tail = phy_ring_head +
39 + phy_ring_tail = eth->phy_scratch_ring +
40 (sizeof(struct mtk_tx_dma) * (cnt - 1));
41
42 for (i = 0; i < cnt; i++) {
43 eth->scratch_ring[i].txd1 =
44 (dma_addr + (i * MTK_QDMA_PAGE_SIZE));
45 if (i < cnt - 1)
46 - eth->scratch_ring[i].txd2 = (phy_ring_head +
47 + eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring +
48 ((i + 1) * sizeof(struct mtk_tx_dma)));
49 eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
50 }
51
52 - mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD);
53 + mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD);
54 mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
55 mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
56 mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
57 @@ -1205,6 +1205,14 @@ static void mtk_dma_free(struct mtk_eth
58 for (i = 0; i < MTK_MAC_COUNT; i++)
59 if (eth->netdev[i])
60 netdev_reset_queue(eth->netdev[i]);
61 + if (eth->scratch_ring) {
62 + dma_free_coherent(eth->dev,
63 + MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
64 + eth->scratch_ring,
65 + eth->phy_scratch_ring);
66 + eth->scratch_ring = NULL;
67 + eth->phy_scratch_ring = 0;
68 + }
69 mtk_tx_clean(eth);
70 mtk_rx_clean(eth);
71 kfree(eth->scratch_head);
72 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
73 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
74 @@ -357,6 +357,7 @@ struct mtk_rx_ring {
75 * @rx_ring: Pointer to the memore holding info about the RX ring
76 * @rx_napi: The NAPI struct
77 * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
78 + * @phy_scratch_ring: physical address of scratch_ring
79 * @scratch_head: The scratch memory that scratch_ring points to.
80 * @clk_ethif: The ethif clock
81 * @clk_esw: The switch clock
82 @@ -384,6 +385,7 @@ struct mtk_eth {
83 struct mtk_rx_ring rx_ring;
84 struct napi_struct rx_napi;
85 struct mtk_tx_dma *scratch_ring;
86 + dma_addr_t phy_scratch_ring;
87 void *scratch_head;
88 struct clk *clk_ethif;
89 struct clk *clk_esw;