mediatek: update patches
[openwrt/svn-archive/archive.git] / target / linux / mediatek / patches-4.4 / 0074-net-mediatek-fix-mtk_pending_work.patch
diff --git a/target/linux/mediatek/patches-4.4/0074-net-mediatek-fix-mtk_pending_work.patch b/target/linux/mediatek/patches-4.4/0074-net-mediatek-fix-mtk_pending_work.patch
new file mode 100644 (file)
index 0000000..c084ba8
--- /dev/null
@@ -0,0 +1,63 @@
+From 46e02ea6c0468ce01b6e370a20f01a7f7311af34 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 29 Mar 2016 17:00:47 +0200
+Subject: [PATCH 74/91] net: mediatek: fix mtk_pending_work
+
+The driver supports 2 MACs. Both run on the same DMA ring. If we hit a TX
+timeout we need to stop both netdevs before retarting them again. If we
+dont do thsi, mtk_stop() wont shutdown DMA and the consecutive call to
+mtk_open() wont restart DMA and enable IRQs.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c |   30 +++++++++++++++++++--------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 04bdb9d..26eeb1a 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1430,19 +1430,31 @@ static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ static void mtk_pending_work(struct work_struct *work)
+ {
+-      struct mtk_mac *mac = container_of(work, struct mtk_mac, pending_work);
+-      struct mtk_eth *eth = mac->hw;
+-      struct net_device *dev = eth->netdev[mac->id];
+-      int err;
++      struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
++      int err, i;
++      unsigned long restart = 0;
+       rtnl_lock();
+-      mtk_stop(dev);
+-      err = mtk_open(dev);
+-      if (err) {
+-              netif_alert(eth, ifup, dev,
++      /* stop all devices to make sure that dma is properly shut down */
++      for (i = 0; i < MTK_MAC_COUNT; i++) {
++              if (!netif_oper_up(eth->netdev[i]))
++                      continue;
++              mtk_stop(eth->netdev[i]);
++              __set_bit(i, &restart);
++      }
++
++
++      /* restart DMA and enable IRQs */
++      for (i = 0; i < MTK_MAC_COUNT; i++) {
++              if (!test_bit(i, &restart))
++                      continue;
++              err = mtk_open(eth->netdev[i]);
++              if (err) {
++                      netif_alert(eth, ifup, eth->netdev[i],
+                           "Driver up/down cycle failed, closing device.\n");
+-              dev_close(dev);
++                      dev_close(eth->netdev[i]);
++              }
+       }
+       rtnl_unlock();
+ }
+-- 
+1.7.10.4
+