mediatek: update patches
[openwrt.git] / target / linux / mediatek / patches-4.4 / 0084-net-next-mediatek-fix-missing-free-of-scratch-memory.patch
diff --git a/target/linux/mediatek/patches-4.4/0084-net-next-mediatek-fix-missing-free-of-scratch-memory.patch b/target/linux/mediatek/patches-4.4/0084-net-next-mediatek-fix-missing-free-of-scratch-memory.patch
new file mode 100644 (file)
index 0000000..452f8d0
--- /dev/null
@@ -0,0 +1,96 @@
+From 5207debf8825a8b6f2934b7d39ef76c163dfd794 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sat, 23 Apr 2016 09:18:28 +0200
+Subject: [PATCH 84/91] net-next: mediatek: fix missing free of scratch memory
+
+Scratch memory gets allocated in mtk_init_fq_dma() but the corresponding
+code to free it is missing inside mtk_dma_free() causing a memory leak.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c |   18 +++++++++++++-----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |    2 ++
+ 2 files changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 37e9260..6896d17 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -469,14 +469,14 @@ static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
+ /* the qdma core needs scratch memory to be setup */
+ static int mtk_init_fq_dma(struct mtk_eth *eth)
+ {
+-      dma_addr_t phy_ring_head, phy_ring_tail;
++      dma_addr_t phy_ring_tail;
+       int cnt = MTK_DMA_SIZE;
+       dma_addr_t dma_addr;
+       int i;
+       eth->scratch_ring = dma_alloc_coherent(eth->dev,
+                                              cnt * sizeof(struct mtk_tx_dma),
+-                                             &phy_ring_head,
++                                             &eth->phy_scratch_ring,
+                                              GFP_ATOMIC | __GFP_ZERO);
+       if (unlikely(!eth->scratch_ring))
+               return -ENOMEM;
+@@ -493,19 +493,19 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
+               return -ENOMEM;
+       memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
+-      phy_ring_tail = phy_ring_head +
++      phy_ring_tail = eth->phy_scratch_ring +
+                       (sizeof(struct mtk_tx_dma) * (cnt - 1));
+       for (i = 0; i < cnt; i++) {
+               eth->scratch_ring[i].txd1 =
+                                       (dma_addr + (i * MTK_QDMA_PAGE_SIZE));
+               if (i < cnt - 1)
+-                      eth->scratch_ring[i].txd2 = (phy_ring_head +
++                      eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring +
+                               ((i + 1) * sizeof(struct mtk_tx_dma)));
+               eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
+       }
+-      mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD);
++      mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD);
+       mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
+       mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
+       mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
+@@ -1203,6 +1203,14 @@ static void mtk_dma_free(struct mtk_eth *eth)
+       for (i = 0; i < MTK_MAC_COUNT; i++)
+               if (eth->netdev[i])
+                       netdev_reset_queue(eth->netdev[i]);
++      if (eth->scratch_ring) {
++              dma_free_coherent(eth->dev,
++                                MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
++                                eth->scratch_ring,
++                                eth->phy_scratch_ring);
++              eth->scratch_ring = NULL;
++              eth->phy_scratch_ring = 0;
++      }
+       mtk_tx_clean(eth);
+       mtk_rx_clean(eth);
+       kfree(eth->scratch_head);
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+index eed626d..57f7e8a 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -357,6 +357,7 @@ struct mtk_rx_ring {
+  * @rx_ring:          Pointer to the memore holding info about the RX ring
+  * @rx_napi:          The NAPI struct
+  * @scratch_ring:     Newer SoCs need memory for a second HW managed TX ring
++ * @phy_scratch_ring: physical address of scratch_ring
+  * @scratch_head:     The scratch memory that scratch_ring points to.
+  * @clk_ethif:                The ethif clock
+  * @clk_esw:          The switch clock
+@@ -384,6 +385,7 @@ struct mtk_eth {
+       struct mtk_rx_ring              rx_ring;
+       struct napi_struct              rx_napi;
+       struct mtk_tx_dma               *scratch_ring;
++      dma_addr_t                      phy_scratch_ring;
+       void                            *scratch_head;
+       struct clk                      *clk_ethif;
+       struct clk                      *clk_esw;
+-- 
+1.7.10.4
+