aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorAlexander Simon <an.alexsimon@googlemail.com>2011-11-30 10:56:32 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-06 16:05:24 -0500
commit54858ee5bf659f80a784303e41ee8898fd163f98 (patch)
tree46901bbd75f8dacfe9677e8d17085508d918d325 /net/wireless
parent2b50b8f58803f4c8521c6aa5401ed01cd36a1f77 (diff)
nl80211: Parse channel type attribute in an ibss join request
Prepare cfg80211 for IBSS HT: * extend cfg80211 ibss struct with channel_type * Check if extension channel can be used * Export can_beacon_sec_chan for use in mac80211 (will be called from ibss.c later). Signed-off-by: Alexander Simon <an.alexsimon@googlemail.com> [siwu@hrz.tu-chemnitz.de: Updates] * fix cfg80211_can_beacon_ext_chan comment * remove implicit channel_type enum assumptions * remove radar channel flags check * add HT IBSS feature flag * reword commit message Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de> Reviewed-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/chan.c12
-rw-r--r--net/wireless/nl80211.c32
2 files changed, 37 insertions, 7 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 17cd0c04d139..2fcfe0993ca2 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -6,6 +6,7 @@
6 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 6 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
7 */ 7 */
8 8
9#include <linux/export.h>
9#include <net/cfg80211.h> 10#include <net/cfg80211.h>
10#include "core.h" 11#include "core.h"
11 12
@@ -44,9 +45,9 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
44 return chan; 45 return chan;
45} 46}
46 47
47static bool can_beacon_sec_chan(struct wiphy *wiphy, 48int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
48 struct ieee80211_channel *chan, 49 struct ieee80211_channel *chan,
49 enum nl80211_channel_type channel_type) 50 enum nl80211_channel_type channel_type)
50{ 51{
51 struct ieee80211_channel *sec_chan; 52 struct ieee80211_channel *sec_chan;
52 int diff; 53 int diff;
@@ -75,6 +76,7 @@ static bool can_beacon_sec_chan(struct wiphy *wiphy,
75 76
76 return true; 77 return true;
77} 78}
79EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan);
78 80
79int cfg80211_set_freq(struct cfg80211_registered_device *rdev, 81int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
80 struct wireless_dev *wdev, int freq, 82 struct wireless_dev *wdev, int freq,
@@ -109,8 +111,8 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
109 switch (channel_type) { 111 switch (channel_type) {
110 case NL80211_CHAN_HT40PLUS: 112 case NL80211_CHAN_HT40PLUS:
111 case NL80211_CHAN_HT40MINUS: 113 case NL80211_CHAN_HT40MINUS:
112 if (!can_beacon_sec_chan(&rdev->wiphy, chan, 114 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan,
113 channel_type)) { 115 channel_type)) {
114 printk(KERN_DEBUG 116 printk(KERN_DEBUG
115 "cfg80211: Secondary channel not " 117 "cfg80211: Secondary channel not "
116 "allowed to initiate communication\n"); 118 "allowed to initiate communication\n");
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8a9b4d817ae6..ba439664c2e0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4682,13 +4682,41 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4682 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 4682 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
4683 } 4683 }
4684 4684
4685 ibss.channel = ieee80211_get_channel(wiphy, 4685 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
4686 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 4686 enum nl80211_channel_type channel_type;
4687
4688 channel_type = nla_get_u32(
4689 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
4690 if (channel_type != NL80211_CHAN_NO_HT &&
4691 channel_type != NL80211_CHAN_HT20 &&
4692 channel_type != NL80211_CHAN_HT40MINUS &&
4693 channel_type != NL80211_CHAN_HT40PLUS)
4694 return -EINVAL;
4695
4696 if (channel_type != NL80211_CHAN_NO_HT &&
4697 !(wiphy->features & NL80211_FEATURE_HT_IBSS))
4698 return -EINVAL;
4699
4700 ibss.channel_type = channel_type;
4701 } else {
4702 ibss.channel_type = NL80211_CHAN_NO_HT;
4703 }
4704
4705 ibss.channel = rdev_freq_to_chan(rdev,
4706 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
4707 ibss.channel_type);
4687 if (!ibss.channel || 4708 if (!ibss.channel ||
4688 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || 4709 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
4689 ibss.channel->flags & IEEE80211_CHAN_DISABLED) 4710 ibss.channel->flags & IEEE80211_CHAN_DISABLED)
4690 return -EINVAL; 4711 return -EINVAL;
4691 4712
4713 /* Both channels should be able to initiate communication */
4714 if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
4715 ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
4716 !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
4717 ibss.channel_type))
4718 return -EINVAL;
4719
4692 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 4720 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
4693 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 4721 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
4694 4722