aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch
blob: e6f1cf69d6488e6af721e9bcfe40d8b0df397fee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/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(&eth->iface_lock);
+
 	/* we run 2 netdevs on the same dma ring so we only bring it up once */
 	if (!atomic_read(&eth->dma_refcnt)) {
 		int err = mtk_start_dma(eth);
 
-		if (err)
+		if (err) {
+			spin_unlock(&eth->iface_lock);
 			return err;
+		}
 
 		napi_enable(&eth->tx_napi);
 		napi_enable(&eth->rx_napi);
@@ -1923,6 +1927,7 @@ static int mtk_open(struct net_device *d
 
 	phy_start(dev->phydev);
 	netif_start_queue(dev);
+	spin_unlock(&eth->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(&eth->iface_lock);
 	netif_tx_disable(dev);
 	phy_stop(dev->phydev);
 
 	/* only shutdown DMA if this is the last user */
-	if (!atomic_dec_and_test(&eth->dma_refcnt))
+	if (!atomic_dec_and_test(&eth->dma_refcnt)) {
+		spin_unlock(&eth->iface_lock);
 		return 0;
+	}
 
 	del_timer(&eth->napi_timer);
 
@@ -1974,6 +1982,8 @@ static int mtk_stop(struct net_device *d
 
 	mtk_dma_free(eth);
 
+	spin_unlock(&eth->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(&eth->iface_lock);
 	spin_lock_init(&eth->page_lock);
 	spin_lock_init(&eth->tx_irq_lock);
 	spin_lock_init(&eth->rx_irq_lock);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/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;