summaryrefslogtreecommitdiff
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2008-08-29 16:26:43 -0700
committerJohn W. Linville <linville@tuxdriver.com>2008-09-05 16:17:42 -0400
commitf59ac0481660e66cec67f1d6b024e78b9dc715fe (patch)
treee9c69b04ac5863b1429bca5a9df1d75026703cde /net/wireless/nl80211.c
parentc6e387a214f4b2c4bd48020409e366c133385d98 (diff)
cfg80211: keep track of supported interface modes
It is obviously good for userspace to know up front which interface modes a given piece of hardware might support (even if adding such an interface might fail later because of concurrency issues), so let's make cfg80211 aware of that. For good measure, disallow adding interfaces in all other modes so drivers don't forget to announce support for one mode when they add it. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Stephen Blackheath <tramp.enshrine.stephen@blacksapphire.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4d6c02afd6f5..77880ba8b619 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -113,10 +113,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
struct nlattr *nl_bands, *nl_band;
struct nlattr *nl_freqs, *nl_freq;
struct nlattr *nl_rates, *nl_rate;
+ struct nlattr *nl_modes;
enum ieee80211_band band;
struct ieee80211_channel *chan;
struct ieee80211_rate *rate;
int i;
+ u16 ifmodes = dev->wiphy.interface_modes;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
if (!hdr)
@@ -125,6 +127,20 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
+ nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
+ if (!nl_modes)
+ goto nla_put_failure;
+
+ i = 0;
+ while (ifmodes) {
+ if (ifmodes & 1)
+ NLA_PUT_FLAG(msg, i);
+ ifmodes >>= 1;
+ i++;
+ }
+
+ nla_nest_end(msg, nl_modes);
+
nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
if (!nl_bands)
goto nla_put_failure;
@@ -415,7 +431,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
ifindex = dev->ifindex;
dev_put(dev);
- if (!drv->ops->change_virtual_intf) {
+ if (!drv->ops->change_virtual_intf ||
+ !(drv->wiphy.interface_modes & (1 << type))) {
err = -EOPNOTSUPP;
goto unlock;
}
@@ -462,7 +479,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
if (IS_ERR(drv))
return PTR_ERR(drv);
- if (!drv->ops->add_virtual_intf) {
+ if (!drv->ops->add_virtual_intf ||
+ !(drv->wiphy.interface_modes & (1 << type))) {
err = -EOPNOTSUPP;
goto unlock;
}