aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ht.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ht.c')
-rw-r--r--net/mac80211/ht.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 75d679d75e63..591add22bcc0 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -66,6 +66,9 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
66 /* own MCS TX capabilities */ 66 /* own MCS TX capabilities */
67 tx_mcs_set_cap = sband->ht_cap.mcs.tx_params; 67 tx_mcs_set_cap = sband->ht_cap.mcs.tx_params;
68 68
69 /* Copy peer MCS TX capabilities, the driver might need them. */
70 ht_cap->mcs.tx_params = ht_cap_ie->mcs.tx_params;
71
69 /* can we TX with MCS rates? */ 72 /* can we TX with MCS rates? */
70 if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED)) 73 if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED))
71 return; 74 return;
@@ -79,7 +82,7 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
79 max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS; 82 max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS;
80 83
81 /* 84 /*
82 * 802.11n D5.0 20.3.5 / 20.6 says: 85 * 802.11n-2009 20.3.5 / 20.6 says:
83 * - indices 0 to 7 and 32 are single spatial stream 86 * - indices 0 to 7 and 32 are single spatial stream
84 * - 8 to 31 are multiple spatial streams using equal modulation 87 * - 8 to 31 are multiple spatial streams using equal modulation
85 * [8..15 for two streams, 16..23 for three and 24..31 for four] 88 * [8..15 for two streams, 16..23 for three and 24..31 for four]
@@ -137,14 +140,29 @@ void ieee80211_ba_session_work(struct work_struct *work)
137 sta, tid, WLAN_BACK_RECIPIENT, 140 sta, tid, WLAN_BACK_RECIPIENT,
138 WLAN_REASON_QSTA_TIMEOUT, true); 141 WLAN_REASON_QSTA_TIMEOUT, true);
139 142
140 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 143 tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
141 if (!tid_tx) 144 if (tid_tx) {
142 continue; 145 /*
146 * Assign it over to the normal tid_tx array
147 * where it "goes live".
148 */
149 spin_lock_bh(&sta->lock);
150
151 sta->ampdu_mlme.tid_start_tx[tid] = NULL;
152 /* could there be a race? */
153 if (sta->ampdu_mlme.tid_tx[tid])
154 kfree(tid_tx);
155 else
156 ieee80211_assign_tid_tx(sta, tid, tid_tx);
157 spin_unlock_bh(&sta->lock);
143 158
144 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state))
145 ieee80211_tx_ba_session_handle_start(sta, tid); 159 ieee80211_tx_ba_session_handle_start(sta, tid);
146 else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, 160 continue;
147 &tid_tx->state)) 161 }
162
163 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
164 if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
165 &tid_tx->state))
148 ___ieee80211_stop_tx_ba_session(sta, tid, 166 ___ieee80211_stop_tx_ba_session(sta, tid,
149 WLAN_BACK_INITIATOR, 167 WLAN_BACK_INITIATOR,
150 true); 168 true);