From 97a6ef513f45b40c635159c9b4b88f3eaa1498d2 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 30 Aug 2017 09:02:39 +0200 Subject: [PATCH] mediatek: various additional ethernet fixes * fixes default affinity * adds a napi watchdog - we were seeing stalled TX queues * adds up/down locking Signed-off-by: John Crispin --- .../mediatek/patches-4.9/0059-eth-fixes.patch | 32 ++------ .../mediatek/patches-4.9/0060-eth-debug.patch | 73 ++++++++++++++++++ .../patches-4.9/0061-eth-up_down_lock.patch | 76 +++++++++++++++++++ 3 files changed, 157 insertions(+), 24 deletions(-) create mode 100644 target/linux/mediatek/patches-4.9/0060-eth-debug.patch create mode 100644 target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch diff --git a/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch b/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch index 61b4b2615c..4991c52d36 100644 --- a/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch +++ b/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch @@ -1,5 +1,7 @@ ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +Index: linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.c +=================================================================== +--- linux-4.9.44.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -24,6 +24,7 @@ #include @@ -400,28 +402,10 @@ eth->netdev[id]->netdev_ops = &mtk_netdev_ops; eth->netdev[id]->base_addr = (unsigned long)eth->base; -@@ -2584,15 +2665,19 @@ static int mtk_probe(struct platform_dev - goto err_deinit_hw; - } - -+ cpumask_set_cpu(1, ð->affinity_mask[1]); -+ cpumask_set_cpu(0, ð->affinity_mask[2]); - err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0, - dev_name(eth->dev), eth); - if (err) - goto err_free_dev; -+ irq_set_affinity_hint(eth->irq[1], ð->affinity_mask[1]); - - err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0, - dev_name(eth->dev), eth); - if (err) - goto err_free_dev; -+ irq_set_affinity_hint(eth->irq[2], ð->affinity_mask[2]); - - err = mtk_mdio_init(eth); - if (err) ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +Index: linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.h +=================================================================== +--- linux-4.9.44.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -80,7 +80,6 @@ /* CDMP Ingress Control Register */ diff --git a/target/linux/mediatek/patches-4.9/0060-eth-debug.patch b/target/linux/mediatek/patches-4.9/0060-eth-debug.patch new file mode 100644 index 0000000000..fb36ddf380 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0060-eth-debug.patch @@ -0,0 +1,73 @@ +Index: linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.c +=================================================================== +--- linux-4.9.44.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -851,6 +851,7 @@ static void mtk_stop_queue(struct mtk_et + continue; + netif_stop_queue(eth->netdev[i]); + } ++ mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); + } + + static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) +@@ -1885,6 +1886,19 @@ static int mtk_start_dma(struct mtk_eth + return 0; + } + ++#define NAPI_TIMER_EXPIRE HZ ++ ++static void napi_timer_handler(unsigned long priv) ++{ ++ struct mtk_eth *eth = (struct mtk_eth*) priv; ++ ++ mtk_wake_queue(eth); ++ mtk_handle_irq_rx(0, eth); ++ mtk_handle_irq_tx(0, eth); ++ ++ mod_timer(ð->napi_timer, jiffies + NAPI_TIMER_EXPIRE); ++} ++ + static int mtk_open(struct net_device *dev) + { + struct mtk_mac *mac = netdev_priv(dev); +@@ -1901,6 +1915,9 @@ static int mtk_open(struct net_device *d + napi_enable(ð->rx_napi); + mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); + mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); ++ ++ setup_timer(ð->napi_timer, napi_timer_handler, (unsigned long) eth); ++ mod_timer(ð->napi_timer, jiffies + NAPI_TIMER_EXPIRE); + } + atomic_inc(ð->dma_refcnt); + +@@ -1945,6 +1962,8 @@ static int mtk_stop(struct net_device *d + if (!atomic_dec_and_test(ð->dma_refcnt)) + return 0; + ++ del_timer(ð->napi_timer); ++ + mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); + mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); + napi_disable(ð->tx_napi); +@@ -2524,7 +2543,7 @@ static int mtk_add_mac(struct mtk_eth *e + mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; + + SET_NETDEV_DEV(eth->netdev[id], eth->dev); +- eth->netdev[id]->watchdog_timeo = 15 * HZ; ++ eth->netdev[id]->watchdog_timeo = 30 * HZ; + eth->netdev[id]->netdev_ops = &mtk_netdev_ops; + eth->netdev[id]->base_addr = (unsigned long)eth->base; + +Index: linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.h +=================================================================== +--- linux-4.9.44.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -601,6 +601,8 @@ struct mtk_eth { + struct mii_bus *mii_bus; + struct work_struct pending_work; + unsigned long state; ++ ++ struct timer_list napi_timer; + }; + + /* struct mtk_mac - the structure that holds the info about the MACs of the diff --git a/target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch b/target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch new file mode 100644 index 0000000000..20f10a337a --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch @@ -0,0 +1,76 @@ +Index: linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.c +=================================================================== +--- linux-4.9.44.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1904,12 +1904,16 @@ static int mtk_open(struct net_device *d + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + ++ spin_lock(ð->iface_lock); ++ + /* we run 2 netdevs on the same dma ring so we only bring it up once */ + if (!atomic_read(ð->dma_refcnt)) { + int err = mtk_start_dma(eth); + +- if (err) ++ if (err) { ++ spin_unlock(ð->iface_lock); + return err; ++ } + + napi_enable(ð->tx_napi); + napi_enable(ð->rx_napi); +@@ -1923,6 +1927,7 @@ static int mtk_open(struct net_device *d + + phy_start(dev->phydev); + netif_start_queue(dev); ++ spin_unlock(ð->iface_lock); + + return 0; + } +@@ -1955,12 +1960,15 @@ static int mtk_stop(struct net_device *d + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + ++ spin_lock(ð->iface_lock); + netif_tx_disable(dev); + phy_stop(dev->phydev); + + /* only shutdown DMA if this is the last user */ +- if (!atomic_dec_and_test(ð->dma_refcnt)) ++ if (!atomic_dec_and_test(ð->dma_refcnt)) { ++ spin_unlock(ð->iface_lock); + return 0; ++ } + + del_timer(ð->napi_timer); + +@@ -1974,6 +1982,8 @@ static int mtk_stop(struct net_device *d + + mtk_dma_free(eth); + ++ spin_unlock(ð->iface_lock); ++ + return 0; + } + +@@ -2623,6 +2633,7 @@ static int mtk_probe(struct platform_dev + if (IS_ERR(eth->base)) + return PTR_ERR(eth->base); + ++ spin_lock_init(ð->iface_lock); + spin_lock_init(ð->page_lock); + spin_lock_init(ð->tx_irq_lock); + spin_lock_init(ð->rx_irq_lock); +Index: linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.h +=================================================================== +--- linux-4.9.44.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ linux-4.9.44/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -573,6 +573,7 @@ struct mtk_rx_ring { + struct mtk_eth { + struct device *dev; + void __iomem *base; ++ spinlock_t iface_lock; + spinlock_t page_lock; + spinlock_t tx_irq_lock; + spinlock_t rx_irq_lock; -- 2.30.2