Commit 306d6112 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

cfg80211: fix nl80211 frequency handling

Fix two small bugs with HT frequency setting:
 * HT is accepted even when the driver is incapable
 * HT40 is accepted when the driver cannot do 40 MHz
 (both on the selected band)

Also simplify the code a little.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7ba1c04e
...@@ -365,6 +365,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) ...@@ -365,6 +365,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
enum nl80211_sec_chan_offset sec_chan_offset = enum nl80211_sec_chan_offset sec_chan_offset =
NL80211_SEC_CHAN_NO_HT; NL80211_SEC_CHAN_NO_HT;
struct ieee80211_channel *chan; struct ieee80211_channel *chan;
struct ieee80211_sta_ht_cap *ht_cap;
u32 freq, sec_freq; u32 freq, sec_freq;
if (!rdev->ops->set_channel) { if (!rdev->ops->set_channel) {
...@@ -372,26 +373,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) ...@@ -372,26 +373,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
goto bad_res; goto bad_res;
} }
result = -EINVAL;
if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) { if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) {
sec_chan_offset = nla_get_u32( sec_chan_offset = nla_get_u32(info->attrs[
info->attrs[
NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]); NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]);
if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT && if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
sec_chan_offset != NL80211_SEC_CHAN_DISABLED && sec_chan_offset != NL80211_SEC_CHAN_DISABLED &&
sec_chan_offset != NL80211_SEC_CHAN_BELOW && sec_chan_offset != NL80211_SEC_CHAN_BELOW &&
sec_chan_offset != NL80211_SEC_CHAN_ABOVE) { sec_chan_offset != NL80211_SEC_CHAN_ABOVE)
result = -EINVAL;
goto bad_res; goto bad_res;
} }
}
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
chan = ieee80211_get_channel(&rdev->wiphy, freq); chan = ieee80211_get_channel(&rdev->wiphy, freq);
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
/* Primary channel not allowed */ /* Primary channel not allowed */
result = -EINVAL; if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
goto bad_res; goto bad_res;
}
if (sec_chan_offset == NL80211_SEC_CHAN_BELOW) if (sec_chan_offset == NL80211_SEC_CHAN_BELOW)
sec_freq = freq - 20; sec_freq = freq - 20;
else if (sec_chan_offset == NL80211_SEC_CHAN_ABOVE) else if (sec_chan_offset == NL80211_SEC_CHAN_ABOVE)
...@@ -399,15 +399,27 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) ...@@ -399,15 +399,27 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
else else
sec_freq = 0; sec_freq = 0;
ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
/* no HT capabilities */
if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
!ht_cap->ht_supported)
goto bad_res;
if (sec_freq) { if (sec_freq) {
struct ieee80211_channel *schan; struct ieee80211_channel *schan;
/* no 40 MHz capabilities */
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); schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
if (!schan || schan->flags & IEEE80211_CHAN_DISABLED) {
/* Secondary channel not allowed */ /* Secondary channel not allowed */
result = -EINVAL; if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
goto bad_res; goto bad_res;
} }
}
result = rdev->ops->set_channel(&rdev->wiphy, chan, result = rdev->ops->set_channel(&rdev->wiphy, chan,
sec_chan_offset); sec_chan_offset);
...@@ -416,7 +428,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) ...@@ -416,7 +428,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
} }
bad_res: bad_res:
cfg80211_put_dev(rdev); cfg80211_put_dev(rdev);
return result; return result;
} }
......
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