aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mlme.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2f92ae2f9706..1a59fb6630d4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -160,7 +160,8 @@ static int ecw2cw(int ecw)
160 */ 160 */
161static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, 161static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
162 struct ieee80211_ht_info *hti, 162 struct ieee80211_ht_info *hti,
163 const u8 *bssid, u16 ap_ht_cap_flags) 163 const u8 *bssid, u16 ap_ht_cap_flags,
164 bool beacon_htcap_ie)
164{ 165{
165 struct ieee80211_local *local = sdata->local; 166 struct ieee80211_local *local = sdata->local;
166 struct ieee80211_supported_band *sband; 167 struct ieee80211_supported_band *sband;
@@ -232,6 +233,21 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
232 WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); 233 WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
233 } 234 }
234 235
236 if (beacon_htcap_ie && (prev_chantype != channel_type)) {
237 /*
238 * Whenever the AP announces the HT mode change that can be
239 * 40MHz intolerant or etc., it would be safer to stop tx
240 * queues before doing hw config to avoid buffer overflow.
241 */
242 ieee80211_stop_queues_by_reason(&sdata->local->hw,
243 IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
244
245 /* flush out all packets */
246 synchronize_net();
247
248 drv_flush(local, false);
249 }
250
235 /* channel_type change automatically detected */ 251 /* channel_type change automatically detected */
236 ieee80211_hw_config(local, 0); 252 ieee80211_hw_config(local, 0);
237 253
@@ -243,6 +259,10 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
243 IEEE80211_RC_HT_CHANGED, 259 IEEE80211_RC_HT_CHANGED,
244 channel_type); 260 channel_type);
245 rcu_read_unlock(); 261 rcu_read_unlock();
262
263 if (beacon_htcap_ie)
264 ieee80211_wake_queues_by_reason(&sdata->local->hw,
265 IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
246 } 266 }
247 267
248 ht_opmode = le16_to_cpu(hti->operation_mode); 268 ht_opmode = le16_to_cpu(hti->operation_mode);
@@ -1588,7 +1608,8 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1588 (sdata->local->hw.queues >= 4) && 1608 (sdata->local->hw.queues >= 4) &&
1589 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 1609 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
1590 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, 1610 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1591 cbss->bssid, ap_ht_cap_flags); 1611 cbss->bssid, ap_ht_cap_flags,
1612 false);
1592 1613
1593 /* set AID and assoc capability, 1614 /* set AID and assoc capability,
1594 * ieee80211_set_associated() will tell the driver */ 1615 * ieee80211_set_associated() will tell the driver */
@@ -1921,24 +1942,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1921 1942
1922 rcu_read_unlock(); 1943 rcu_read_unlock();
1923 1944
1924 /*
1925 * Whenever the AP announces the HT mode change that can be
1926 * 40MHz intolerant or etc., it would be safer to stop tx
1927 * queues before doing hw config to avoid buffer overflow.
1928 */
1929 ieee80211_stop_queues_by_reason(&sdata->local->hw,
1930 IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
1931
1932 /* flush out all packets */
1933 synchronize_net();
1934
1935 drv_flush(local, false);
1936
1937 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, 1945 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1938 bssid, ap_ht_cap_flags); 1946 bssid, ap_ht_cap_flags, true);
1939
1940 ieee80211_wake_queues_by_reason(&sdata->local->hw,
1941 IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
1942 } 1947 }
1943 1948
1944 /* Note: country IE parsing is done for us by cfg80211 */ 1949 /* Note: country IE parsing is done for us by cfg80211 */