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: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
committed by
Johannes Berg
parent
30e7473263
commit
0418a44583
@@ -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,
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
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 */
|
||||||
|
Reference in New Issue
Block a user