aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54pci.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2010-01-22 02:01:11 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-22 16:11:41 -0500
commitb92f7d30830a319148df2943b7565989494e5ad1 (patch)
tree1f03218a846f242f735bad31347a59138753a92c /drivers/net/wireless/p54/p54pci.c
parent59af099b1956086b06c0d0f32ea99ce136b415b7 (diff)
p54pci: revise tx locking
This patch continues the effort which began with: "[PATCH] p54pci: move tx cleanup into tasklet". Thanks to these changes, p54pci's interrupt & tx cleanup routines can be made lock-less. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54/p54pci.c')
-rw-r--r--drivers/net/wireless/p54/p54pci.c16
1 files changed, 4 insertions, 12 deletions
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 48cae48ed6eb..bda29c00f3ef 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -238,7 +238,6 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
238 int ring_index, struct p54p_desc *ring, u32 ring_limit, 238 int ring_index, struct p54p_desc *ring, u32 ring_limit,
239 struct sk_buff **tx_buf) 239 struct sk_buff **tx_buf)
240{ 240{
241 unsigned long flags;
242 struct p54p_priv *priv = dev->priv; 241 struct p54p_priv *priv = dev->priv;
243 struct p54p_ring_control *ring_control = priv->ring_control; 242 struct p54p_ring_control *ring_control = priv->ring_control;
244 struct p54p_desc *desc; 243 struct p54p_desc *desc;
@@ -249,7 +248,6 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
249 (*index) = idx = le32_to_cpu(ring_control->device_idx[1]); 248 (*index) = idx = le32_to_cpu(ring_control->device_idx[1]);
250 idx %= ring_limit; 249 idx %= ring_limit;
251 250
252 spin_lock_irqsave(&priv->lock, flags);
253 while (i != idx) { 251 while (i != idx) {
254 desc = &ring[i]; 252 desc = &ring[i];
255 253
@@ -264,16 +262,12 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
264 desc->len = 0; 262 desc->len = 0;
265 desc->flags = 0; 263 desc->flags = 0;
266 264
267 if (skb && FREE_AFTER_TX(skb)) { 265 if (skb && FREE_AFTER_TX(skb))
268 spin_unlock_irqrestore(&priv->lock, flags);
269 p54_free_skb(dev, skb); 266 p54_free_skb(dev, skb);
270 spin_lock_irqsave(&priv->lock, flags);
271 }
272 267
273 i++; 268 i++;
274 i %= ring_limit; 269 i %= ring_limit;
275 } 270 }
276 spin_unlock_irqrestore(&priv->lock, flags);
277} 271}
278 272
279static void p54p_tasklet(unsigned long dev_id) 273static void p54p_tasklet(unsigned long dev_id)
@@ -306,7 +300,6 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
306 struct p54p_priv *priv = dev->priv; 300 struct p54p_priv *priv = dev->priv;
307 __le32 reg; 301 __le32 reg;
308 302
309 spin_lock(&priv->lock);
310 reg = P54P_READ(int_ident); 303 reg = P54P_READ(int_ident);
311 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) { 304 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
312 goto out; 305 goto out;
@@ -321,15 +314,14 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
321 complete(&priv->boot_comp); 314 complete(&priv->boot_comp);
322 315
323out: 316out:
324 spin_unlock(&priv->lock);
325 return reg ? IRQ_HANDLED : IRQ_NONE; 317 return reg ? IRQ_HANDLED : IRQ_NONE;
326} 318}
327 319
328static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 320static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
329{ 321{
322 unsigned long flags;
330 struct p54p_priv *priv = dev->priv; 323 struct p54p_priv *priv = dev->priv;
331 struct p54p_ring_control *ring_control = priv->ring_control; 324 struct p54p_ring_control *ring_control = priv->ring_control;
332 unsigned long flags;
333 struct p54p_desc *desc; 325 struct p54p_desc *desc;
334 dma_addr_t mapping; 326 dma_addr_t mapping;
335 u32 device_idx, idx, i; 327 u32 device_idx, idx, i;
@@ -370,14 +362,14 @@ static void p54p_stop(struct ieee80211_hw *dev)
370 unsigned int i; 362 unsigned int i;
371 struct p54p_desc *desc; 363 struct p54p_desc *desc;
372 364
373 tasklet_kill(&priv->tasklet);
374
375 P54P_WRITE(int_enable, cpu_to_le32(0)); 365 P54P_WRITE(int_enable, cpu_to_le32(0));
376 P54P_READ(int_enable); 366 P54P_READ(int_enable);
377 udelay(10); 367 udelay(10);
378 368
379 free_irq(priv->pdev->irq, dev); 369 free_irq(priv->pdev->irq, dev);
380 370
371 tasklet_kill(&priv->tasklet);
372
381 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); 373 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
382 374
383 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) { 375 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {