diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-03-10 13:31:34 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-03-10 13:31:34 +0000 |
commit | acd288a1454a742a0da195f1b6a840ae8c1b0bdb (patch) | |
tree | 7ed8ea19ad0e897246b0fd2bc298a3a00f647c63 /package/mac80211/patches/300-pending_work.patch | |
parent | 92e1c8bfd356f528c919e2ac91f891a05d91d33d (diff) |
rt2x00: merge a fix for random tx stalls
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30871 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mac80211/patches/300-pending_work.patch')
-rw-r--r-- | package/mac80211/patches/300-pending_work.patch | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch index 25d3b17441..30ce96e170 100644 --- a/package/mac80211/patches/300-pending_work.patch +++ b/package/mac80211/patches/300-pending_work.patch @@ -1891,3 +1891,58 @@ if (on) REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -430,10 +430,14 @@ void rt2x00lib_txdone(struct queue_entry + /* + * If the data queue was below the threshold before the txdone + * handler we must make sure the packet queue in the mac80211 stack +- * is reenabled when the txdone handler has finished. ++ * is reenabled when the txdone handler has finished. This has to be ++ * serialized with rt2x00mac_tx(), otherwise we can wake up queue ++ * before it was stopped. + */ ++ spin_lock_bh(&entry->queue->tx_lock); + if (!rt2x00queue_threshold(entry->queue)) + rt2x00queue_unpause_queue(entry->queue); ++ spin_unlock_bh(&entry->queue->tx_lock); + } + EXPORT_SYMBOL_GPL(rt2x00lib_txdone); + +--- a/drivers/net/wireless/rt2x00/rt2x00mac.c ++++ b/drivers/net/wireless/rt2x00/rt2x00mac.c +@@ -152,13 +152,22 @@ void rt2x00mac_tx(struct ieee80211_hw *h + if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) + goto exit_fail; + ++ /* ++ * Pausing queue has to be serialized with rt2x00lib_txdone(). Note ++ * we should not use spin_lock_bh variant as bottom halve was already ++ * disabled before ieee80211_xmit() call. ++ */ ++ spin_lock(&queue->tx_lock); + if (rt2x00queue_threshold(queue)) + rt2x00queue_pause_queue(queue); ++ spin_unlock(&queue->tx_lock); + + return; + + exit_fail: ++ spin_lock(&queue->tx_lock); + rt2x00queue_pause_queue(queue); ++ spin_unlock(&queue->tx_lock); + exit_free_skb: + ieee80211_free_txskb(hw, skb); + } +--- a/drivers/net/wireless/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c +@@ -619,6 +619,9 @@ int rt2x00queue_write_tx_frame(struct da + else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) + rt2x00queue_align_frame(skb); + ++ /* ++ * That function must be called with bh disabled. ++ */ + spin_lock(&queue->tx_lock); + + if (unlikely(rt2x00queue_full(queue))) { |