aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r--net/mac80211/agg-tx.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 9cc472c6a6a5..63d852cb4ca2 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -190,7 +190,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
190 190
191 ret = drv_ampdu_action(local, sta->sdata, 191 ret = drv_ampdu_action(local, sta->sdata,
192 IEEE80211_AMPDU_TX_STOP, 192 IEEE80211_AMPDU_TX_STOP,
193 &sta->sta, tid, NULL); 193 &sta->sta, tid, NULL, 0);
194 194
195 /* HW shall not deny going back to legacy */ 195 /* HW shall not deny going back to legacy */
196 if (WARN_ON(ret)) { 196 if (WARN_ON(ret)) {
@@ -311,7 +311,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
311 start_seq_num = sta->tid_seq[tid] >> 4; 311 start_seq_num = sta->tid_seq[tid] >> 4;
312 312
313 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, 313 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
314 &sta->sta, tid, &start_seq_num); 314 &sta->sta, tid, &start_seq_num, 0);
315 if (ret) { 315 if (ret) {
316#ifdef CONFIG_MAC80211_HT_DEBUG 316#ifdef CONFIG_MAC80211_HT_DEBUG
317 printk(KERN_DEBUG "BA request denied - HW unavailable for" 317 printk(KERN_DEBUG "BA request denied - HW unavailable for"
@@ -342,7 +342,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
342 /* send AddBA request */ 342 /* send AddBA request */
343 ieee80211_send_addba_request(sdata, sta->sta.addr, tid, 343 ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
344 tid_tx->dialog_token, start_seq_num, 344 tid_tx->dialog_token, start_seq_num,
345 0x40, tid_tx->timeout); 345 local->hw.max_tx_aggregation_subframes,
346 tid_tx->timeout);
346} 347}
347 348
348int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, 349int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
@@ -487,7 +488,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
487 488
488 drv_ampdu_action(local, sta->sdata, 489 drv_ampdu_action(local, sta->sdata,
489 IEEE80211_AMPDU_TX_OPERATIONAL, 490 IEEE80211_AMPDU_TX_OPERATIONAL,
490 &sta->sta, tid, NULL); 491 &sta->sta, tid, NULL,
492 sta->ampdu_mlme.tid_tx[tid]->buf_size);
491 493
492 /* 494 /*
493 * synchronize with TX path, while splicing the TX path 495 * synchronize with TX path, while splicing the TX path
@@ -742,9 +744,11 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
742{ 744{
743 struct tid_ampdu_tx *tid_tx; 745 struct tid_ampdu_tx *tid_tx;
744 u16 capab, tid; 746 u16 capab, tid;
747 u8 buf_size;
745 748
746 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 749 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
747 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 750 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
751 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
748 752
749 mutex_lock(&sta->ampdu_mlme.mtx); 753 mutex_lock(&sta->ampdu_mlme.mtx);
750 754
@@ -767,12 +771,23 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
767 771
768 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 772 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
769 == WLAN_STATUS_SUCCESS) { 773 == WLAN_STATUS_SUCCESS) {
774 /*
775 * IEEE 802.11-2007 7.3.1.14:
776 * In an ADDBA Response frame, when the Status Code field
777 * is set to 0, the Buffer Size subfield is set to a value
778 * of at least 1.
779 */
780 if (!buf_size)
781 goto out;
782
770 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED, 783 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
771 &tid_tx->state)) { 784 &tid_tx->state)) {
772 /* ignore duplicate response */ 785 /* ignore duplicate response */
773 goto out; 786 goto out;
774 } 787 }
775 788
789 tid_tx->buf_size = buf_size;
790
776 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)) 791 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))
777 ieee80211_agg_tx_operational(local, sta, tid); 792 ieee80211_agg_tx_operational(local, sta, tid);
778 793