aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/stmicro/stmmac
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2011-10-17 20:01:19 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-19 19:24:16 -0400
commita9097a9666fd7b08fd2a152b2a0b6c8d48639bb2 (patch)
tree1df8d865c78032a9bd00d49c47dd65fa87df7b8c /drivers/net/ethernet/stmicro/stmmac
parent79ee1dc32b945ad71248332f3a3b355332ad3376 (diff)
stmmac: protect tx process with lock (V4)
This patch fixes a problem raised on Orly ARM SMP platform where, in case of fragmented frames, the descriptors in the TX ring resulted broken. This was due to a missing lock protection in the tx process. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Tested-by: Srinivas Kandagatla <srinivas.kandagatla@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c8
2 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 1434bdb390d..50e95d87857 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -70,6 +70,7 @@ struct stmmac_priv {
70 70
71 u32 msg_enable; 71 u32 msg_enable;
72 spinlock_t lock; 72 spinlock_t lock;
73 spinlock_t tx_lock;
73 int wolopts; 74 int wolopts;
74 int wolenabled; 75 int wolenabled;
75 int wol_irq; 76 int wol_irq;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ae5debb1f5c..f80190d78f9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -588,6 +588,8 @@ static void stmmac_tx(struct stmmac_priv *priv)
588{ 588{
589 unsigned int txsize = priv->dma_tx_size; 589 unsigned int txsize = priv->dma_tx_size;
590 590
591 spin_lock(&priv->tx_lock);
592
591 while (priv->dirty_tx != priv->cur_tx) { 593 while (priv->dirty_tx != priv->cur_tx) {
592 int last; 594 int last;
593 unsigned int entry = priv->dirty_tx % txsize; 595 unsigned int entry = priv->dirty_tx % txsize;
@@ -651,6 +653,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
651 } 653 }
652 netif_tx_unlock(priv->dev); 654 netif_tx_unlock(priv->dev);
653 } 655 }
656 spin_unlock(&priv->tx_lock);
654} 657}
655 658
656static inline void stmmac_enable_irq(struct stmmac_priv *priv) 659static inline void stmmac_enable_irq(struct stmmac_priv *priv)
@@ -1078,6 +1081,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
1078 return NETDEV_TX_BUSY; 1081 return NETDEV_TX_BUSY;
1079 } 1082 }
1080 1083
1084 spin_lock(&priv->tx_lock);
1085
1081 entry = priv->cur_tx % txsize; 1086 entry = priv->cur_tx % txsize;
1082 1087
1083#ifdef STMMAC_XMIT_DEBUG 1088#ifdef STMMAC_XMIT_DEBUG
@@ -1166,6 +1171,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
1166 1171
1167 priv->hw->dma->enable_dma_transmission(priv->ioaddr); 1172 priv->hw->dma->enable_dma_transmission(priv->ioaddr);
1168 1173
1174 spin_unlock(&priv->tx_lock);
1175
1169 return NETDEV_TX_OK; 1176 return NETDEV_TX_OK;
1170} 1177}
1171 1178
@@ -1731,6 +1738,7 @@ static int stmmac_probe(struct net_device *dev)
1731 "please, use ifconfig or nwhwconfig!\n"); 1738 "please, use ifconfig or nwhwconfig!\n");
1732 1739
1733 spin_lock_init(&priv->lock); 1740 spin_lock_init(&priv->lock);
1741 spin_lock_init(&priv->tx_lock);
1734 1742
1735 ret = register_netdev(dev); 1743 ret = register_netdev(dev);
1736 if (ret) { 1744 if (ret) {