diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2008-08-29 19:26:43 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-09-05 16:17:42 -0400 |
commit | f59ac0481660e66cec67f1d6b024e78b9dc715fe (patch) | |
tree | e9c69b04ac5863b1429bca5a9df1d75026703cde /net/wireless/nl80211.c | |
parent | c6e387a214f4b2c4bd48020409e366c133385d98 (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.c | 22 |
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, | |||
113 | struct nlattr *nl_bands, *nl_band; | 113 | struct nlattr *nl_bands, *nl_band; |
114 | struct nlattr *nl_freqs, *nl_freq; | 114 | struct nlattr *nl_freqs, *nl_freq; |
115 | struct nlattr *nl_rates, *nl_rate; | 115 | struct nlattr *nl_rates, *nl_rate; |
116 | struct nlattr *nl_modes; | ||
116 | enum ieee80211_band band; | 117 | enum ieee80211_band band; |
117 | struct ieee80211_channel *chan; | 118 | struct ieee80211_channel *chan; |
118 | struct ieee80211_rate *rate; | 119 | struct ieee80211_rate *rate; |
119 | int i; | 120 | int i; |
121 | u16 ifmodes = dev->wiphy.interface_modes; | ||
120 | 122 | ||
121 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); | 123 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); |
122 | if (!hdr) | 124 | if (!hdr) |
@@ -125,6 +127,20 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
125 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); | 127 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); |
126 | NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); | 128 | NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); |
127 | 129 | ||
130 | nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); | ||
131 | if (!nl_modes) | ||
132 | goto nla_put_failure; | ||
133 | |||
134 | i = 0; | ||
135 | while (ifmodes) { | ||
136 | if (ifmodes & 1) | ||
137 | NLA_PUT_FLAG(msg, i); | ||
138 | ifmodes >>= 1; | ||
139 | i++; | ||
140 | } | ||
141 | |||
142 | nla_nest_end(msg, nl_modes); | ||
143 | |||
128 | nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); | 144 | nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); |
129 | if (!nl_bands) | 145 | if (!nl_bands) |
130 | goto nla_put_failure; | 146 | goto nla_put_failure; |
@@ -415,7 +431,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | |||
415 | ifindex = dev->ifindex; | 431 | ifindex = dev->ifindex; |
416 | dev_put(dev); | 432 | dev_put(dev); |
417 | 433 | ||
418 | if (!drv->ops->change_virtual_intf) { | 434 | if (!drv->ops->change_virtual_intf || |
435 | !(drv->wiphy.interface_modes & (1 << type))) { | ||
419 | err = -EOPNOTSUPP; | 436 | err = -EOPNOTSUPP; |
420 | goto unlock; | 437 | goto unlock; |
421 | } | 438 | } |
@@ -462,7 +479,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
462 | if (IS_ERR(drv)) | 479 | if (IS_ERR(drv)) |
463 | return PTR_ERR(drv); | 480 | return PTR_ERR(drv); |
464 | 481 | ||
465 | if (!drv->ops->add_virtual_intf) { | 482 | if (!drv->ops->add_virtual_intf || |
483 | !(drv->wiphy.interface_modes & (1 << type))) { | ||
466 | err = -EOPNOTSUPP; | 484 | err = -EOPNOTSUPP; |
467 | goto unlock; | 485 | goto unlock; |
468 | } | 486 | } |