diff options
| -rw-r--r-- | drivers/net/wireless/iwlegacy/3945-mac.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlegacy/3945.c | 7 | ||||
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 6 | ||||
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 9 | ||||
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 3 |
5 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 54b2d391e91a..a7dfba8d164e 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c | |||
| @@ -2475,7 +2475,7 @@ il3945_bg_alive_start(struct work_struct *data) | |||
| 2475 | container_of(data, struct il_priv, alive_start.work); | 2475 | container_of(data, struct il_priv, alive_start.work); |
| 2476 | 2476 | ||
| 2477 | mutex_lock(&il->mutex); | 2477 | mutex_lock(&il->mutex); |
| 2478 | if (test_bit(S_EXIT_PENDING, &il->status)) | 2478 | if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL) |
| 2479 | goto out; | 2479 | goto out; |
| 2480 | 2480 | ||
| 2481 | il3945_alive_start(il); | 2481 | il3945_alive_start(il); |
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 1489b1573a6a..c80eb9b31551 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c | |||
| @@ -1870,11 +1870,12 @@ il3945_bg_reg_txpower_periodic(struct work_struct *work) | |||
| 1870 | struct il_priv *il = container_of(work, struct il_priv, | 1870 | struct il_priv *il = container_of(work, struct il_priv, |
| 1871 | _3945.thermal_periodic.work); | 1871 | _3945.thermal_periodic.work); |
| 1872 | 1872 | ||
| 1873 | if (test_bit(S_EXIT_PENDING, &il->status)) | ||
| 1874 | return; | ||
| 1875 | |||
| 1876 | mutex_lock(&il->mutex); | 1873 | mutex_lock(&il->mutex); |
| 1874 | if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL) | ||
| 1875 | goto out; | ||
| 1876 | |||
| 1877 | il3945_reg_txpower_periodic(il); | 1877 | il3945_reg_txpower_periodic(il); |
| 1878 | out: | ||
| 1878 | mutex_unlock(&il->mutex); | 1879 | mutex_unlock(&il->mutex); |
| 1879 | } | 1880 | } |
| 1880 | 1881 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index d2a1ea98d0f2..fd356b7c0476 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
| @@ -426,10 +426,14 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
| 426 | /* | 426 | /* |
| 427 | * If the data queue was below the threshold before the txdone | 427 | * If the data queue was below the threshold before the txdone |
| 428 | * handler we must make sure the packet queue in the mac80211 stack | 428 | * handler we must make sure the packet queue in the mac80211 stack |
| 429 | * is reenabled when the txdone handler has finished. | 429 | * is reenabled when the txdone handler has finished. This has to be |
| 430 | * serialized with rt2x00mac_tx(), otherwise we can wake up queue | ||
| 431 | * before it was stopped. | ||
| 430 | */ | 432 | */ |
| 433 | spin_lock_bh(&entry->queue->tx_lock); | ||
| 431 | if (!rt2x00queue_threshold(entry->queue)) | 434 | if (!rt2x00queue_threshold(entry->queue)) |
| 432 | rt2x00queue_unpause_queue(entry->queue); | 435 | rt2x00queue_unpause_queue(entry->queue); |
| 436 | spin_unlock_bh(&entry->queue->tx_lock); | ||
| 433 | } | 437 | } |
| 434 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 438 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
| 435 | 439 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index ede3c58e6783..2df2eb6d3e06 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
| @@ -152,13 +152,22 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 152 | if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) | 152 | if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) |
| 153 | goto exit_fail; | 153 | goto exit_fail; |
| 154 | 154 | ||
| 155 | /* | ||
| 156 | * Pausing queue has to be serialized with rt2x00lib_txdone(). Note | ||
| 157 | * we should not use spin_lock_bh variant as bottom halve was already | ||
| 158 | * disabled before ieee80211_xmit() call. | ||
| 159 | */ | ||
| 160 | spin_lock(&queue->tx_lock); | ||
| 155 | if (rt2x00queue_threshold(queue)) | 161 | if (rt2x00queue_threshold(queue)) |
| 156 | rt2x00queue_pause_queue(queue); | 162 | rt2x00queue_pause_queue(queue); |
| 163 | spin_unlock(&queue->tx_lock); | ||
| 157 | 164 | ||
| 158 | return; | 165 | return; |
| 159 | 166 | ||
| 160 | exit_fail: | 167 | exit_fail: |
| 168 | spin_lock(&queue->tx_lock); | ||
| 161 | rt2x00queue_pause_queue(queue); | 169 | rt2x00queue_pause_queue(queue); |
| 170 | spin_unlock(&queue->tx_lock); | ||
| 162 | exit_free_skb: | 171 | exit_free_skb: |
| 163 | ieee80211_free_txskb(hw, skb); | 172 | ieee80211_free_txskb(hw, skb); |
| 164 | } | 173 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 5adfb3eab9cd..9b1b2b7a7807 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
| @@ -619,6 +619,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
| 619 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) | 619 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) |
| 620 | rt2x00queue_align_frame(skb); | 620 | rt2x00queue_align_frame(skb); |
| 621 | 621 | ||
| 622 | /* | ||
| 623 | * That function must be called with bh disabled. | ||
| 624 | */ | ||
| 622 | spin_lock(&queue->tx_lock); | 625 | spin_lock(&queue->tx_lock); |
| 623 | 626 | ||
| 624 | if (unlikely(rt2x00queue_full(queue))) { | 627 | if (unlikely(rt2x00queue_full(queue))) { |
