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(ð->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);
--- 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;
|