aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-18 11:15:06 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:01:47 -0500
commit8ade00824607fcfa8842572012d4393b40a74a94 (patch)
treee88b9ce6d6743294e5287d6c3729bbb215cabb3e
parent70e3bb504ccfe6ba725ab120bdb516d205d834f9 (diff)
mac80211: fix addba timer (again...)
commit 2171abc58644e09dbba546d91366b12743115396 Author: Johannes Berg <johannes@sipsolutions.net> Date: Thu Oct 29 08:34:00 2009 +0100 mac80211: fix addba timer left a problem in there, even if the timer was never started it could be deleted and then added. Linus pointed out that del_timer_sync() isn't actually needed if we make the timer able to deal with no longer being needed when it gets queued _while_ we're in the locked section that also deletes it. For that the timer function only needs to check the HT_ADDBA_RECEIVED_MSK bit as well as the HT_ADDBA_REQUESTED_MSK bit, only if the former is clear should it do anything. Cc: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/agg-tx.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index b09948ceec4a..206fd82f0c76 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -173,12 +173,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
173 173
174 /* check if the TID waits for addBA response */ 174 /* check if the TID waits for addBA response */
175 spin_lock_bh(&sta->lock); 175 spin_lock_bh(&sta->lock);
176 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 176 if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
177 HT_ADDBA_REQUESTED_MSK) {
177 spin_unlock_bh(&sta->lock); 178 spin_unlock_bh(&sta->lock);
178 *state = HT_AGG_STATE_IDLE; 179 *state = HT_AGG_STATE_IDLE;
179#ifdef CONFIG_MAC80211_HT_DEBUG 180#ifdef CONFIG_MAC80211_HT_DEBUG
180 printk(KERN_DEBUG "timer expired on tid %d but we are not " 181 printk(KERN_DEBUG "timer expired on tid %d but we are not "
181 "expecting addBA response there", tid); 182 "(or no longer) expecting addBA response there",
183 tid);
182#endif 184#endif
183 return; 185 return;
184 } 186 }
@@ -666,21 +668,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
666 668
667 state = &sta->ampdu_mlme.tid_state_tx[tid]; 669 state = &sta->ampdu_mlme.tid_state_tx[tid];
668 670
669 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
670
671 spin_lock_bh(&sta->lock); 671 spin_lock_bh(&sta->lock);
672 672
673 if (!(*state & HT_ADDBA_REQUESTED_MSK)) 673 if (!(*state & HT_ADDBA_REQUESTED_MSK))
674 goto timer_still_needed; 674 goto out;
675 675
676 if (mgmt->u.action.u.addba_resp.dialog_token != 676 if (mgmt->u.action.u.addba_resp.dialog_token !=
677 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 677 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
678#ifdef CONFIG_MAC80211_HT_DEBUG 678#ifdef CONFIG_MAC80211_HT_DEBUG
679 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 679 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
680#endif /* CONFIG_MAC80211_HT_DEBUG */ 680#endif /* CONFIG_MAC80211_HT_DEBUG */
681 goto timer_still_needed; 681 goto out;
682 } 682 }
683 683
684 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
685
684#ifdef CONFIG_MAC80211_HT_DEBUG 686#ifdef CONFIG_MAC80211_HT_DEBUG
685 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 687 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
686#endif /* CONFIG_MAC80211_HT_DEBUG */ 688#endif /* CONFIG_MAC80211_HT_DEBUG */
@@ -699,10 +701,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
699 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 701 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
700 } 702 }
701 703
702 goto out;
703
704 timer_still_needed:
705 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
706 out: 704 out:
707 spin_unlock_bh(&sta->lock); 705 spin_unlock_bh(&sta->lock);
708} 706}