aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/vht.c
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2014-12-14 04:05:51 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-12-17 09:45:16 -0500
commit1c45c5ce324fec967dca5993f79b54769da410dc (patch)
tree0dc0d83ef40d736f205d1570aec856d6b6d2889f /net/mac80211/vht.c
parenta5fee9cb6255b9bba5a977f92cb4807eafb89db0 (diff)
mac80211: update sta bw on ht chanwidth action frame
Commit e1a0c6b ("mac80211: stop toggling IEEE80211_HT_CAP_SUP_WIDTH_20_40") mistakenly removed the actual update of sta->sta.bandwidth. Refactor ieee80211_sta_cur_vht_bw() into multiple functions (calculate caps-bw and chandef-bw separately, and min them with cur_max_bandwidth). On ht chanwidth action frame set only cur_max_bandwidth (according to the sta capabilities) and recalc the sta bw. Signed-off-by: Eliad Peller <eliadx.peller@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/vht.c')
-rw-r--r--net/mac80211/vht.c73
1 files changed, 38 insertions, 35 deletions
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index bc9e8fc48785..85f9596da07b 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -269,51 +269,54 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
269 sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); 269 sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta);
270} 270}
271 271
272enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) 272enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta)
273{ 273{
274 struct ieee80211_sub_if_data *sdata = sta->sdata; 274 struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
275 u32 cap = sta->sta.vht_cap.cap; 275 u32 cap_width;
276 enum ieee80211_sta_rx_bandwidth bw;
277 276
278 if (!sta->sta.vht_cap.vht_supported) { 277 if (!vht_cap->vht_supported)
279 bw = sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? 278 return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
280 IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; 279 IEEE80211_STA_RX_BW_40 :
281 goto check_max; 280 IEEE80211_STA_RX_BW_20;
282 }
283 281
284 switch (sdata->vif.bss_conf.chandef.width) { 282 cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
285 default: 283
286 WARN_ON_ONCE(1); 284 if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ||
287 /* fall through */ 285 cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
286 return IEEE80211_STA_RX_BW_160;
287
288 return IEEE80211_STA_RX_BW_80;
289}
290
291static enum ieee80211_sta_rx_bandwidth
292ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
293{
294 switch (width) {
288 case NL80211_CHAN_WIDTH_20_NOHT: 295 case NL80211_CHAN_WIDTH_20_NOHT:
289 case NL80211_CHAN_WIDTH_20: 296 case NL80211_CHAN_WIDTH_20:
290 bw = IEEE80211_STA_RX_BW_20; 297 return IEEE80211_STA_RX_BW_20;
291 break;
292 case NL80211_CHAN_WIDTH_40: 298 case NL80211_CHAN_WIDTH_40:
293 bw = sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? 299 return IEEE80211_STA_RX_BW_40;
294 IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; 300 case NL80211_CHAN_WIDTH_80:
295 break; 301 return IEEE80211_STA_RX_BW_80;
296 case NL80211_CHAN_WIDTH_160: 302 case NL80211_CHAN_WIDTH_160:
297 if ((cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) ==
298 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) {
299 bw = IEEE80211_STA_RX_BW_160;
300 break;
301 }
302 /* fall through */
303 case NL80211_CHAN_WIDTH_80P80: 303 case NL80211_CHAN_WIDTH_80P80:
304 if ((cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 304 return IEEE80211_STA_RX_BW_160;
305 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) { 305 default:
306 bw = IEEE80211_STA_RX_BW_160; 306 WARN_ON_ONCE(1);
307 break; 307 return IEEE80211_STA_RX_BW_20;
308 }
309 /* fall through */
310 case NL80211_CHAN_WIDTH_80:
311 bw = IEEE80211_STA_RX_BW_80;
312 } 308 }
309}
310
311enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta)
312{
313 struct ieee80211_sub_if_data *sdata = sta->sdata;
314 enum ieee80211_sta_rx_bandwidth bw;
315
316 bw = ieee80211_chan_width_to_rx_bw(sdata->vif.bss_conf.chandef.width);
317 bw = min(bw, ieee80211_sta_cap_rx_bw(sta));
318 bw = min(bw, sta->cur_max_bandwidth);
313 319
314 check_max:
315 if (bw > sta->cur_max_bandwidth)
316 bw = sta->cur_max_bandwidth;
317 return bw; 320 return bw;
318} 321}
319 322