aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-tx.c
diff options
context:
space:
mode:
authorNikolay Martynov <mar.kolya@gmail.com>2011-11-22 21:50:28 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-28 14:43:49 -0500
commit285fa6958c1d56469ec8a0e879ae7487a4e62840 (patch)
treec0c335499809c2b90ef145576e726543c508e67c /net/mac80211/agg-tx.c
parent94c2fb82bd7c9055bec8e410c387befce33d1299 (diff)
mac80211: timeout tx agg sessions in way similar to rx agg sessions
Currently tx aggregation is not being timed out even if timeout is specified when aggregation is opened. Tx tid stays active until delba arrives from recipient (i.e. recipient times out tid when it is inactive). The problem with this approach is that delba can get lost in the air and tx tid will stay perpetually opened on the originator while closed on recipient thus all data sent via this tid will be lost. This patch implements tx tid timeouting in way very similar to rx tid timeouting. Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r--net/mac80211/agg-tx.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 39d72ccaffb3..a2d9654aabcb 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -180,6 +180,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
180 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); 180 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
181 181
182 del_timer_sync(&tid_tx->addba_resp_timer); 182 del_timer_sync(&tid_tx->addba_resp_timer);
183 del_timer_sync(&tid_tx->session_timer);
183 184
184 /* 185 /*
185 * After this packets are no longer handed right through 186 * After this packets are no longer handed right through
@@ -349,6 +350,28 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
349 tid_tx->timeout); 350 tid_tx->timeout);
350} 351}
351 352
353/*
354 * After accepting the AddBA Response we activated a timer,
355 * resetting it after each frame that we send.
356 */
357static void sta_tx_agg_session_timer_expired(unsigned long data)
358{
359 /* not an elegant detour, but there is no choice as the timer passes
360 * only one argument, and various sta_info are needed here, so init
361 * flow in sta_info_create gives the TID as data, while the timer_to_id
362 * array gives the sta through container_of */
363 u8 *ptid = (u8 *)data;
364 u8 *timer_to_id = ptid - *ptid;
365 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
366 timer_to_tid[0]);
367
368#ifdef CONFIG_MAC80211_HT_DEBUG
369 printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid);
370#endif
371
372 ieee80211_stop_tx_ba_session(&sta->sta, *ptid);
373}
374
352int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, 375int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
353 u16 timeout) 376 u16 timeout)
354{ 377{
@@ -418,11 +441,16 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
418 441
419 tid_tx->timeout = timeout; 442 tid_tx->timeout = timeout;
420 443
421 /* Tx timer */ 444 /* response timer */
422 tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired; 445 tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
423 tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid]; 446 tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
424 init_timer(&tid_tx->addba_resp_timer); 447 init_timer(&tid_tx->addba_resp_timer);
425 448
449 /* tx timer */
450 tid_tx->session_timer.function = sta_tx_agg_session_timer_expired;
451 tid_tx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
452 init_timer(&tid_tx->session_timer);
453
426 /* assign a dialog token */ 454 /* assign a dialog token */
427 sta->ampdu_mlme.dialog_token_allocator++; 455 sta->ampdu_mlme.dialog_token_allocator++;
428 tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator; 456 tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator;
@@ -778,6 +806,11 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
778 ieee80211_agg_tx_operational(local, sta, tid); 806 ieee80211_agg_tx_operational(local, sta, tid);
779 807
780 sta->ampdu_mlme.addba_req_num[tid] = 0; 808 sta->ampdu_mlme.addba_req_num[tid] = 0;
809
810 if (tid_tx->timeout)
811 mod_timer(&tid_tx->session_timer,
812 TU_TO_EXP_TIME(tid_tx->timeout));
813
781 } else { 814 } else {
782 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 815 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
783 true); 816 true);