summaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch')
-rw-r--r--target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch63
1 files changed, 63 insertions, 0 deletions
diff --git a/target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch b/target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch
new file mode 100644
index 0000000000..197419573b
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch
@@ -0,0 +1,63 @@
+From e2cc73e6ddb0cc39b8f58654a449651a621916a9 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 29 Mar 2016 17:00:47 +0200
+Subject: [PATCH 066/102] 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
+