diff options
author | Alexander Simon <an.alexsimon@googlemail.com> | 2011-11-30 10:56:32 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-06 16:05:24 -0500 |
commit | 54858ee5bf659f80a784303e41ee8898fd163f98 (patch) | |
tree | 46901bbd75f8dacfe9677e8d17085508d918d325 /net/wireless | |
parent | 2b50b8f58803f4c8521c6aa5401ed01cd36a1f77 (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.c | 12 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 32 |
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 | ||
47 | static bool can_beacon_sec_chan(struct wiphy *wiphy, | 48 | int 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 | } |
79 | EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); | ||
78 | 80 | ||
79 | int cfg80211_set_freq(struct cfg80211_registered_device *rdev, | 81 | int 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 | ||