summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-05-02 00:37:20 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-20 14:46:23 -0400
commit294196ab22c91da974ba1f40d0a7cdcb0b3e6bc3 (patch)
tree10301cf8cff8c6bfa1db351f5570b9b182ad8499
parent768777ea1118f6ff3f1a013557e7bc4f5d2683a4 (diff)
downloadlinux-294196ab22c91da974ba1f40d0a7cdcb0b3e6bc3.tar.bz2
cfg80211: check allowed channel type upon userspace requests
Thanks to nl80211 userspace can be very specific upon device configuration. Before processing the request for the new HT40 channel types (HT40- or HT40+) we need to ensure we can use them regulatory-wise. This wasn't required with wireless extensions as specifying the channel type wasn't not available and configuration was done towards the end implicitly upon association or reception of beacons from the AP. For the new nl80211 we have to check this when configuring the interfaces explicitly. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/wireless/nl80211.c39
1 files changed, 17 insertions, 22 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ade40d503bf0..0e22b5f5880f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -492,7 +492,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
struct ieee80211_channel *chan;
struct ieee80211_sta_ht_cap *ht_cap;
- u32 freq, sec_freq;
+ u32 freq;
if (!rdev->ops->set_channel) {
result = -EOPNOTSUPP;
@@ -518,33 +518,28 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
goto bad_res;
- if (channel_type == NL80211_CHAN_HT40MINUS)
- sec_freq = freq - 20;
- else if (channel_type == NL80211_CHAN_HT40PLUS)
- sec_freq = freq + 20;
- else
- sec_freq = 0;
-
- ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
-
- /* no HT capabilities */
- if (channel_type != NL80211_CHAN_NO_HT &&
- !ht_cap->ht_supported)
+ if (channel_type == NL80211_CHAN_HT40MINUS &&
+ (chan->flags & IEEE80211_CHAN_NO_HT40MINUS))
+ goto bad_res;
+ else if (channel_type == NL80211_CHAN_HT40PLUS &&
+ (chan->flags & IEEE80211_CHAN_NO_HT40PLUS))
goto bad_res;
- if (sec_freq) {
- struct ieee80211_channel *schan;
+ /*
+ * At this point we know if that if HT40 was requested
+ * we are allowed to use it and the extension channel
+ * exists.
+ */
- /* no 40 MHz capabilities */
+ ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
+
+ /* no HT capabilities or intolerant */
+ if (channel_type != NL80211_CHAN_NO_HT) {
+ if (!ht_cap->ht_supported)
+ goto bad_res;
if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
(ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
goto bad_res;
-
- schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
-
- /* Secondary channel not allowed */
- if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
- goto bad_res;
}
result = rdev->ops->set_channel(&rdev->wiphy, chan,