Commit fff82448 authored by Jouni Malinen's avatar Jouni Malinen Committed by Greg Kroah-Hartman

cfg80211: Fix 160 MHz channels with 80+80 and 160 MHz drivers

commit 08f6f147 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.

Fixes: 3d9d1d66 ("nl80211/cfg80211: support VHT channel configuration")
       (however, no real drivers had 160 MHz support it until 3.16)
Signed-off-by: default avatarJouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a7b2c7ff
...@@ -602,7 +602,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, ...@@ -602,7 +602,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
{ {
struct ieee80211_sta_ht_cap *ht_cap; struct ieee80211_sta_ht_cap *ht_cap;
struct ieee80211_sta_vht_cap *vht_cap; struct ieee80211_sta_vht_cap *vht_cap;
u32 width, control_freq; u32 width, control_freq, cap;
if (WARN_ON(!cfg80211_chandef_valid(chandef))) if (WARN_ON(!cfg80211_chandef_valid(chandef)))
return false; return false;
...@@ -642,7 +642,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, ...@@ -642,7 +642,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
return false; return false;
break; break;
case NL80211_CHAN_WIDTH_80P80: 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; return false;
case NL80211_CHAN_WIDTH_80: case NL80211_CHAN_WIDTH_80:
if (!vht_cap->vht_supported) if (!vht_cap->vht_supported)
...@@ -653,7 +654,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, ...@@ -653,7 +654,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
case NL80211_CHAN_WIDTH_160: case NL80211_CHAN_WIDTH_160:
if (!vht_cap->vht_supported) if (!vht_cap->vht_supported)
return false; 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; return false;
prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
width = 160; width = 160;
......
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