Skip to content

Commit

Permalink
cfg80211: check allowed channel type upon userspace requests
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Luis R. Rodriguez authored and John W. Linville committed May 20, 2009
1 parent 768777e commit 294196a
Showing 1 changed file with 17 additions and 22 deletions.
39 changes: 17 additions & 22 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down

0 comments on commit 294196a

Please sign in to comment.