diff options
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 | } |