Commit 0418a445 authored by Simon Wunderlich's avatar Simon Wunderlich Committed by Johannes Berg

mac80211: fix various components for the new 5 and 10 MHz widths

This is a collection of minor fixes:
 * don't allow HT IEs in IBSS for 5/10 MHz
 * don't allow HT IEs in Mesh for 5/10 MHz
 * don't downgrade from/to 5 and 10 MHz channels
 * don't try HT rates for 5 and 10 MHz channels when selecting rates
Signed-off-by: default avatarSimon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: default avatarMathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 30e74732
...@@ -176,6 +176,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -176,6 +176,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
/* add HT capability and information IEs */ /* add HT capability and information IEs */
if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
chandef.width != NL80211_CHAN_WIDTH_5 &&
chandef.width != NL80211_CHAN_WIDTH_10 &&
sband->ht_cap.ht_supported) { sband->ht_cap.ht_supported) {
pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
sband->ht_cap.cap); sband->ht_cap.cap);
......
...@@ -416,7 +416,9 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata, ...@@ -416,7 +416,9 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
sband = local->hw.wiphy->bands[band]; sband = local->hw.wiphy->bands[band];
if (!sband->ht_cap.ht_supported || if (!sband->ht_cap.ht_supported ||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
return 0; return 0;
if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
......
...@@ -154,8 +154,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) ...@@ -154,8 +154,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
u16 ht_opmode; u16 ht_opmode;
bool non_ht_sta = false, ht20_sta = false; bool non_ht_sta = false, ht20_sta = false;
if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) switch (sdata->vif.bss_conf.chandef.width) {
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
return 0; return 0;
default:
break;
}
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(sta, &local->sta_list, list) { list_for_each_entry_rcu(sta, &local->sta_list, list) {
......
...@@ -190,6 +190,12 @@ static u32 chandef_downgrade(struct cfg80211_chan_def *c) ...@@ -190,6 +190,12 @@ static u32 chandef_downgrade(struct cfg80211_chan_def *c)
c->width = NL80211_CHAN_WIDTH_20_NOHT; c->width = NL80211_CHAN_WIDTH_20_NOHT;
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
break; break;
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
WARN_ON_ONCE(1);
/* keep c->width */
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
break;
} }
WARN_ON_ONCE(!cfg80211_chandef_valid(c)); WARN_ON_ONCE(!cfg80211_chandef_valid(c));
...@@ -3771,6 +3777,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, ...@@ -3771,6 +3777,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
*/ */
ret = ieee80211_vif_use_channel(sdata, &chandef, ret = ieee80211_vif_use_channel(sdata, &chandef,
IEEE80211_CHANCTX_SHARED); IEEE80211_CHANCTX_SHARED);
/* don't downgrade for 5 and 10 MHz channels, though. */
if (chandef.width == NL80211_CHAN_WIDTH_5 ||
chandef.width == NL80211_CHAN_WIDTH_10)
return ret;
while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
ifmgd->flags |= chandef_downgrade(&chandef); ifmgd->flags |= chandef_downgrade(&chandef);
ret = ieee80211_vif_use_channel(sdata, &chandef, ret = ieee80211_vif_use_channel(sdata, &chandef,
......
...@@ -397,8 +397,14 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, ...@@ -397,8 +397,14 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
return; return;
/* if HT BSS, and we handle a data frame, also try HT rates */ /* if HT BSS, and we handle a data frame, also try HT rates */
if (chan_width == NL80211_CHAN_WIDTH_20_NOHT) switch (chan_width) {
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
return; return;
default:
break;
}
alt_rate.idx = 0; alt_rate.idx = 0;
/* keep protection flags */ /* keep protection flags */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment