mac80211: fix addba timer (again...)
commit 2171abc586
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>
This commit is contained in:
parent
70e3bb504c
commit
8ade008246
1 changed files with 8 additions and 10 deletions
|
@ -173,12 +173,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
|
||||||
|
|
||||||
/* check if the TID waits for addBA response */
|
/* check if the TID waits for addBA response */
|
||||||
spin_lock_bh(&sta->lock);
|
spin_lock_bh(&sta->lock);
|
||||||
if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
|
if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
|
||||||
|
HT_ADDBA_REQUESTED_MSK) {
|
||||||
spin_unlock_bh(&sta->lock);
|
spin_unlock_bh(&sta->lock);
|
||||||
*state = HT_AGG_STATE_IDLE;
|
*state = HT_AGG_STATE_IDLE;
|
||||||
#ifdef CONFIG_MAC80211_HT_DEBUG
|
#ifdef CONFIG_MAC80211_HT_DEBUG
|
||||||
printk(KERN_DEBUG "timer expired on tid %d but we are not "
|
printk(KERN_DEBUG "timer expired on tid %d but we are not "
|
||||||
"expecting addBA response there", tid);
|
"(or no longer) expecting addBA response there",
|
||||||
|
tid);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -666,21 +668,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
|
||||||
|
|
||||||
state = &sta->ampdu_mlme.tid_state_tx[tid];
|
state = &sta->ampdu_mlme.tid_state_tx[tid];
|
||||||
|
|
||||||
del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
|
|
||||||
|
|
||||||
spin_lock_bh(&sta->lock);
|
spin_lock_bh(&sta->lock);
|
||||||
|
|
||||||
if (!(*state & HT_ADDBA_REQUESTED_MSK))
|
if (!(*state & HT_ADDBA_REQUESTED_MSK))
|
||||||
goto timer_still_needed;
|
goto out;
|
||||||
|
|
||||||
if (mgmt->u.action.u.addba_resp.dialog_token !=
|
if (mgmt->u.action.u.addba_resp.dialog_token !=
|
||||||
sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
|
sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
|
||||||
#ifdef CONFIG_MAC80211_HT_DEBUG
|
#ifdef CONFIG_MAC80211_HT_DEBUG
|
||||||
printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
|
printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
|
||||||
#endif /* CONFIG_MAC80211_HT_DEBUG */
|
#endif /* CONFIG_MAC80211_HT_DEBUG */
|
||||||
goto timer_still_needed;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
|
||||||
|
|
||||||
#ifdef CONFIG_MAC80211_HT_DEBUG
|
#ifdef CONFIG_MAC80211_HT_DEBUG
|
||||||
printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
|
printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
|
||||||
#endif /* CONFIG_MAC80211_HT_DEBUG */
|
#endif /* CONFIG_MAC80211_HT_DEBUG */
|
||||||
|
@ -699,10 +701,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
|
||||||
___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
|
___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
timer_still_needed:
|
|
||||||
add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
|
|
||||||
out:
|
out:
|
||||||
spin_unlock_bh(&sta->lock);
|
spin_unlock_bh(&sta->lock);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue