diff options
author | Jouni Malinen <jouni@qca.qualcomm.com> | 2014-12-11 16:48:55 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-12-12 06:18:47 -0500 |
commit | 08f6f147773b23b765b94633a8eaa82e7defcf4c (patch) | |
tree | fb4e885a02084e3606f679d72833137a1243853a /net | |
parent | d025933e29872cb1fe19fc54d80e4dfa4ee5779c (diff) |
cfg80211: Fix 160 MHz channels with 80+80 and 160 MHz drivers
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/wireless/chan.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 85506f1d0789..7aaf7415dc4c 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -603,7 +603,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
603 | { | 603 | { |
604 | struct ieee80211_sta_ht_cap *ht_cap; | 604 | struct ieee80211_sta_ht_cap *ht_cap; |
605 | struct ieee80211_sta_vht_cap *vht_cap; | 605 | struct ieee80211_sta_vht_cap *vht_cap; |
606 | u32 width, control_freq; | 606 | u32 width, control_freq, cap; |
607 | 607 | ||
608 | if (WARN_ON(!cfg80211_chandef_valid(chandef))) | 608 | if (WARN_ON(!cfg80211_chandef_valid(chandef))) |
609 | return false; | 609 | return false; |
@@ -643,7 +643,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
643 | return false; | 643 | return false; |
644 | break; | 644 | break; |
645 | case NL80211_CHAN_WIDTH_80P80: | 645 | case NL80211_CHAN_WIDTH_80P80: |
646 | if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) | 646 | cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; |
647 | if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) | ||
647 | return false; | 648 | return false; |
648 | case NL80211_CHAN_WIDTH_80: | 649 | case NL80211_CHAN_WIDTH_80: |
649 | if (!vht_cap->vht_supported) | 650 | if (!vht_cap->vht_supported) |
@@ -654,7 +655,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
654 | case NL80211_CHAN_WIDTH_160: | 655 | case NL80211_CHAN_WIDTH_160: |
655 | if (!vht_cap->vht_supported) | 656 | if (!vht_cap->vht_supported) |
656 | return false; | 657 | return false; |
657 | if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)) | 658 | cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; |
659 | if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ && | ||
660 | cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) | ||
658 | return false; | 661 | return false; |
659 | prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; | 662 | prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; |
660 | width = 160; | 663 | width = 160; |