aboutsummaryrefslogtreecommitdiffstats
path: root/net
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 /net
parent768777ea1118f6ff3f1a013557e7bc4f5d2683a4 (diff)
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>
Diffstat (limited to 'net')
-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)
492 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 492 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
493 struct ieee80211_channel *chan; 493 struct ieee80211_channel *chan;
494 struct ieee80211_sta_ht_cap *ht_cap; 494 struct ieee80211_sta_ht_cap *ht_cap;
495 u32 freq, sec_freq; 495 u32 freq;
496 496
497 if (!rdev->ops->set_channel) { 497 if (!rdev->ops->set_channel) {
498 result = -EOPNOTSUPP; 498 result = -EOPNOTSUPP;
@@ -518,33 +518,28 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
518 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) 518 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
519 goto bad_res; 519 goto bad_res;
520 520
521 if (channel_type == NL80211_CHAN_HT40MINUS) 521 if (channel_type == NL80211_CHAN_HT40MINUS &&
522 sec_freq = freq - 20; 522 (chan->flags & IEEE80211_CHAN_NO_HT40MINUS))
523 else if (channel_type == NL80211_CHAN_HT40PLUS) 523 goto bad_res;
524 sec_freq = freq + 20; 524 else if (channel_type == NL80211_CHAN_HT40PLUS &&
525 else 525 (chan->flags & IEEE80211_CHAN_NO_HT40PLUS))
526 sec_freq = 0;
527
528 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
529
530 /* no HT capabilities */
531 if (channel_type != NL80211_CHAN_NO_HT &&
532 !ht_cap->ht_supported)
533 goto bad_res; 526 goto bad_res;
534 527
535 if (sec_freq) { 528 /*
536 struct ieee80211_channel *schan; 529 * At this point we know if that if HT40 was requested
530 * we are allowed to use it and the extension channel
531 * exists.
532 */
537 533
538 /* no 40 MHz capabilities */ 534 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
535
536 /* no HT capabilities or intolerant */
537 if (channel_type != NL80211_CHAN_NO_HT) {
538 if (!ht_cap->ht_supported)
539 goto bad_res;
539 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || 540 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
540 (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)) 541 (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
541 goto bad_res; 542 goto bad_res;
542
543 schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
544
545 /* Secondary channel not allowed */
546 if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
547 goto bad_res;
548 } 543 }
549 544
550 result = rdev->ops->set_channel(&rdev->wiphy, chan, 545 result = rdev->ops->set_channel(&rdev->wiphy, chan,