diff options
Diffstat (limited to 'net/mac80211/ht.c')
-rw-r--r-- | net/mac80211/ht.c | 32 |
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); |