From: Felix Fietkau Date: Sat, 10 Mar 2012 13:31:34 +0000 (+0000) Subject: rt2x00: merge a fix for random tx stalls X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=0341ff9912d93199c1c11c4e8fb5f62b5ec7767a;p=openwrt%2Fstaging%2Fyousong.git rt2x00: merge a fix for random tx stalls SVN-Revision: 30871 --- 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))) { diff --git a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch index 31e33b7818..e40d3a9342 100644 --- a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch +++ b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch @@ -239,7 +239,7 @@ .get_entry_state = rt2800pci_get_entry_state, --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c -@@ -1161,6 +1161,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de +@@ -1165,6 +1165,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_WDS); @@ -250,7 +250,7 @@ /* * Initialize work. */ -@@ -1284,6 +1288,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ +@@ -1288,6 +1292,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ */ if (rt2x00dev->drv_data) kfree(rt2x00dev->drv_data); diff --git a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch index 9056076bd4..476f730116 100644 --- a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch +++ b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch @@ -12,7 +12,7 @@ #endif /* _RT2X00_PLATFORM_H */ --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c -@@ -829,6 +829,22 @@ static int rt2x00lib_probe_hw_modes(stru +@@ -833,6 +833,22 @@ static int rt2x00lib_probe_hw_modes(stru unsigned int num_rates; unsigned int i;