mirror of https://github.com/hak5/openwrt-owl.git
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 <john@phrozen.org>owl
parent
7a9410618d
commit
97a6ef513f
|
@ -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 <linux/tcp.h>
|
||||
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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
|
|
@ -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;
|
Loading…
Reference in New Issue