From: Ben Greear <greearb@xxxxxxxxxxxxxxx> This allows one to disable VHT160 (or 80+80) on hardware that might otherwise try to use it. Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> --- v2: Change description include/linux/ieee80211.h | 1 + net/mac80211/main.c | 1 + net/mac80211/vht.c | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index a80516f..e5dc3a8 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1542,6 +1542,7 @@ struct ieee80211_vht_operation { #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004 #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008 #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK 0x0000000C +#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT 2 #define IEEE80211_VHT_CAP_RXLDPC 0x00000010 #define IEEE80211_VHT_CAP_SHORT_GI_80 0x00000020 #define IEEE80211_VHT_CAP_SHORT_GI_160 0x00000040 diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ec5587d..1447b47 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -464,6 +464,7 @@ static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = { static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = { .vht_cap_info = cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC | + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK | IEEE80211_VHT_CAP_SHORT_GI_80 | IEEE80211_VHT_CAP_SHORT_GI_160 | IEEE80211_VHT_CAP_RXSTBC_1 | diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 720c64c..5684e13 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -56,6 +56,29 @@ void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata, __check_vhtcap_disable(sdata, vht_cap, IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN); + /* Allow disabling 160Mhz or 80+80 */ + if (sdata->u.mgd.vht_capa_mask.vht_cap_info & + cpu_to_le32(IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) { + u32 cap, n; + + n = le32_to_cpu(sdata->u.mgd.vht_capa.vht_cap_info) & + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; + n >>= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT; + cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; + cap >>= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT; + + if (n < cap) { + vht_cap->cap &= + ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; + vht_cap->cap |= + n << IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT; + + /* Cannot do short GI 160 if we cannot do 160 or 80+80 */ + if (n == 0) + vht_cap->cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160; + } + } + /* Allow user to decrease AMPDU length exponent */ if (sdata->u.mgd.vht_capa_mask.vht_cap_info & cpu_to_le32(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK)) { -- 2.4.11