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.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 9cc472c6a6a5..42f7c9007331 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"
@@ -487,7 +487,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
487 487
488 drv_ampdu_action(local, sta->sdata, 488 drv_ampdu_action(local, sta->sdata,
489 IEEE80211_AMPDU_TX_OPERATIONAL, 489 IEEE80211_AMPDU_TX_OPERATIONAL,
490 &sta->sta, tid, NULL); 490 &sta->sta, tid, NULL,
491 sta->ampdu_mlme.tid_tx[tid]->buf_size);
491 492
492 /* 493 /*
493 * synchronize with TX path, while splicing the TX path 494 * synchronize with TX path, while splicing the TX path
@@ -742,9 +743,11 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
742{ 743{
743 struct tid_ampdu_tx *tid_tx; 744 struct tid_ampdu_tx *tid_tx;
744 u16 capab, tid; 745 u16 capab, tid;
746 u8 buf_size;
745 747
746 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 748 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
747 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 749 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
750 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
748 751
749 mutex_lock(&sta->ampdu_mlme.mtx); 752 mutex_lock(&sta->ampdu_mlme.mtx);
750 753
@@ -767,12 +770,23 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
767 770
768 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 771 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
769 == WLAN_STATUS_SUCCESS) { 772 == WLAN_STATUS_SUCCESS) {
773 /*
774 * IEEE 802.11-2007 7.3.1.14:
775 * In an ADDBA Response frame, when the Status Code field
776 * is set to 0, the Buffer Size subfield is set to a value
777 * of at least 1.
778 */
779 if (!buf_size)
780 goto out;
781
770 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED, 782 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
771 &tid_tx->state)) { 783 &tid_tx->state)) {
772 /* ignore duplicate response */ 784 /* ignore duplicate response */
773 goto out; 785 goto out;
774 } 786 }
775 787
788 tid_tx->buf_size = buf_size;
789
776 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)) 790 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))
777 ieee80211_agg_tx_operational(local, sta, tid); 791 ieee80211_agg_tx_operational(local, sta, tid);
778 792