summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2014-12-11 23:48:55 +0200
committerJiri Slaby <jslaby@suse.cz>2015-04-09 14:13:39 +0200
commit4fd4c6b42691a657dd28b02cc7b66f01e87cb492 (patch)
treebe85671d01e564b25ce2817f5539b60efe3feea8
parent7ad45878fff07f03049e1c2cd11eca03a27122f7 (diff)
cfg80211: Fix 160 MHz channels with 80+80 and 160 MHz drivers
commit 08f6f147773b23b765b94633a8eaa82e7defcf4c upstream. The VHT supported channel width field is a two bit integer, not a bitfield. cfg80211_chandef_usable() was interpreting it incorrectly and ended up rejecting 160 MHz channel width if the driver indicated support for both 160 and 80+80 MHz channels. Cc: stable@vger.kernel.org (3.16+) Fixes: 3d9d1d6656a73 ("nl80211/cfg80211: support VHT channel configuration") (however, no real drivers had 160 MHz support it until 3.16) Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
-rw-r--r--net/wireless/chan.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 50f6195c8b70..e5af85d10212 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -368,7 +368,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
{
struct ieee80211_sta_ht_cap *ht_cap;
struct ieee80211_sta_vht_cap *vht_cap;
- u32 width, control_freq;
+ u32 width, control_freq, cap;
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
return false;
@@ -406,7 +406,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
return false;
break;
case NL80211_CHAN_WIDTH_80P80:
- if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
+ cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+ if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
return false;
case NL80211_CHAN_WIDTH_80:
if (!vht_cap->vht_supported)
@@ -417,7 +418,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
case NL80211_CHAN_WIDTH_160:
if (!vht_cap->vht_supported)
return false;
- if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
+ cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+ if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
+ cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
return false;
prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
width = 160;