diff options
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r-- | net/mac80211/agg-tx.c | 23 |
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 | ||
348 | int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | 349 | int 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 | ||