diff options
-rw-r--r-- | drivers/net/wireless/adm8211.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/rtl8187_dev.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 5 | ||||
-rw-r--r-- | include/linux/nl80211.h | 6 | ||||
-rw-r--r-- | include/net/wireless.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 7 | ||||
-rw-r--r-- | net/wireless/core.c | 9 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 22 |
17 files changed, 95 insertions, 3 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 3333d4596b8..c6a55cd12db 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -1884,6 +1884,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1884 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); | 1884 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); |
1885 | /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ | 1885 | /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ |
1886 | dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; | 1886 | dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; |
1887 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | ||
1887 | 1888 | ||
1888 | dev->channel_change_time = 1000; | 1889 | dev->channel_change_time = 1000; |
1889 | dev->max_signal = 100; /* FIXME: find better value */ | 1890 | dev->max_signal = 100; /* FIXME: find better value */ |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 7989ab5c2bb..85260c39aa2 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -485,6 +485,12 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
485 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 485 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
486 | IEEE80211_HW_SIGNAL_DBM | | 486 | IEEE80211_HW_SIGNAL_DBM | |
487 | IEEE80211_HW_NOISE_DBM; | 487 | IEEE80211_HW_NOISE_DBM; |
488 | |||
489 | hw->wiphy->interface_modes = | ||
490 | BIT(NL80211_IFTYPE_STATION) | | ||
491 | BIT(NL80211_IFTYPE_ADHOC) | | ||
492 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
493 | |||
488 | hw->extra_tx_headroom = 2; | 494 | hw->extra_tx_headroom = 2; |
489 | hw->channel_change_time = 5000; | 495 | hw->channel_change_time = 5000; |
490 | sc = hw->priv; | 496 | sc = hw->priv; |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index dc45eef3289..39a4a70d013 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -1482,6 +1482,11 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1482 | IEEE80211_HW_SIGNAL_DBM | | 1482 | IEEE80211_HW_SIGNAL_DBM | |
1483 | IEEE80211_HW_NOISE_DBM; | 1483 | IEEE80211_HW_NOISE_DBM; |
1484 | 1484 | ||
1485 | hw->wiphy->interface_modes = | ||
1486 | BIT(NL80211_IFTYPE_AP) | | ||
1487 | BIT(NL80211_IFTYPE_STATION) | | ||
1488 | BIT(NL80211_IFTYPE_ADHOC); | ||
1489 | |||
1485 | SET_IEEE80211_DEV(hw, &pdev->dev); | 1490 | SET_IEEE80211_DEV(hw, &pdev->dev); |
1486 | pci_set_drvdata(pdev, hw); | 1491 | pci_set_drvdata(pdev, hw); |
1487 | 1492 | ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 63bafc2f3f0..2d915c1a82a 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4569,6 +4569,13 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4569 | IEEE80211_HW_SIGNAL_DBM | | 4569 | IEEE80211_HW_SIGNAL_DBM | |
4570 | IEEE80211_HW_NOISE_DBM; | 4570 | IEEE80211_HW_NOISE_DBM; |
4571 | 4571 | ||
4572 | hw->wiphy->interface_modes = | ||
4573 | BIT(NL80211_IFTYPE_AP) | | ||
4574 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
4575 | BIT(NL80211_IFTYPE_STATION) | | ||
4576 | BIT(NL80211_IFTYPE_WDS) | | ||
4577 | BIT(NL80211_IFTYPE_ADHOC); | ||
4578 | |||
4572 | hw->queues = b43_modparam_qos ? 4 : 1; | 4579 | hw->queues = b43_modparam_qos ? 4 : 1; |
4573 | SET_IEEE80211_DEV(hw, dev->dev); | 4580 | SET_IEEE80211_DEV(hw, dev->dev); |
4574 | if (is_valid_ether_addr(sprom->et1mac)) | 4581 | if (is_valid_ether_addr(sprom->et1mac)) |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1cb77db5c29..68f63f5093a 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3704,6 +3704,11 @@ static int b43legacy_wireless_init(struct ssb_device *dev) | |||
3704 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 3704 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
3705 | IEEE80211_HW_SIGNAL_DBM | | 3705 | IEEE80211_HW_SIGNAL_DBM | |
3706 | IEEE80211_HW_NOISE_DBM; | 3706 | IEEE80211_HW_NOISE_DBM; |
3707 | hw->wiphy->interface_modes = | ||
3708 | BIT(NL80211_IFTYPE_AP) | | ||
3709 | BIT(NL80211_IFTYPE_STATION) | | ||
3710 | BIT(NL80211_IFTYPE_WDS) | | ||
3711 | BIT(NL80211_IFTYPE_ADHOC); | ||
3707 | hw->queues = 1; /* FIXME: hardware has more queues */ | 3712 | hw->queues = 1; /* FIXME: hardware has more queues */ |
3708 | SET_IEEE80211_DEV(hw, dev->dev); | 3713 | SET_IEEE80211_DEV(hw, dev->dev); |
3709 | if (is_valid_ether_addr(sprom->et1mac)) | 3714 | if (is_valid_ether_addr(sprom->et1mac)) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index fbf75a62958..0a511ef8e35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -819,6 +819,10 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
819 | /* Tell mac80211 our characteristics */ | 819 | /* Tell mac80211 our characteristics */ |
820 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 820 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
821 | IEEE80211_HW_NOISE_DBM; | 821 | IEEE80211_HW_NOISE_DBM; |
822 | hw->wiphy->interface_modes = | ||
823 | BIT(NL80211_IFTYPE_AP) | | ||
824 | BIT(NL80211_IFTYPE_STATION) | | ||
825 | BIT(NL80211_IFTYPE_ADHOC); | ||
822 | /* Default value; 4 EDCA QOS priorities */ | 826 | /* Default value; 4 EDCA QOS priorities */ |
823 | hw->queues = 4; | 827 | hw->queues = 4; |
824 | /* queues to support 11n aggregation */ | 828 | /* queues to support 11n aggregation */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a622fc33590..cee3045f160 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -7888,6 +7888,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7888 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 7888 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
7889 | IEEE80211_HW_NOISE_DBM; | 7889 | IEEE80211_HW_NOISE_DBM; |
7890 | 7890 | ||
7891 | hw->wiphy->interface_modes = | ||
7892 | BIT(NL80211_IFTYPE_AP) | | ||
7893 | BIT(NL80211_IFTYPE_STATION) | | ||
7894 | BIT(NL80211_IFTYPE_ADHOC); | ||
7895 | |||
7891 | /* 4 EDCA QOS priorities */ | 7896 | /* 4 EDCA QOS priorities */ |
7892 | hw->queues = 4; | 7897 | hw->queues = 4; |
7893 | 7898 | ||
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 732429d4912..6ba50f087f7 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -447,6 +447,9 @@ static int __init init_mac80211_hwsim(void) | |||
447 | 447 | ||
448 | hw->channel_change_time = 1; | 448 | hw->channel_change_time = 1; |
449 | hw->queues = 4; | 449 | hw->queues = 4; |
450 | hw->wiphy->interface_modes = | ||
451 | BIT(NL80211_IFTYPE_STATION) | | ||
452 | BIT(NL80211_IFTYPE_AP); | ||
450 | hw->ampdu_queues = 1; | 453 | hw->ampdu_queues = 1; |
451 | 454 | ||
452 | memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); | 455 | memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 17e06bbc996..6da98e6e6a9 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -1072,6 +1072,9 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
1072 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ | 1072 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ |
1073 | IEEE80211_HW_RX_INCLUDES_FCS | | 1073 | IEEE80211_HW_RX_INCLUDES_FCS | |
1074 | IEEE80211_HW_SIGNAL_UNSPEC; | 1074 | IEEE80211_HW_SIGNAL_UNSPEC; |
1075 | |||
1076 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | ||
1077 | |||
1075 | dev->channel_change_time = 1000; /* TODO: find actual value */ | 1078 | dev->channel_change_time = 1000; /* TODO: find actual value */ |
1076 | dev->max_signal = 127; | 1079 | dev->max_signal = 127; |
1077 | 1080 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 369b0b2d864..2f3bfc60688 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1052,6 +1052,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1052 | */ | 1052 | */ |
1053 | rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); | 1053 | rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); |
1054 | 1054 | ||
1055 | rt2x00dev->hw->wiphy->interface_modes = | ||
1056 | BIT(NL80211_IFTYPE_AP) | | ||
1057 | BIT(NL80211_IFTYPE_STATION) | | ||
1058 | BIT(NL80211_IFTYPE_ADHOC); | ||
1059 | |||
1055 | /* | 1060 | /* |
1056 | * Let the driver probe the device to detect the capabilities. | 1061 | * Let the driver probe the device to detect the capabilities. |
1057 | */ | 1062 | */ |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 060a2650535..8a42bfa6d4f 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -1184,6 +1184,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1184 | dev->max_signal = 65; | 1184 | dev->max_signal = 65; |
1185 | } | 1185 | } |
1186 | 1186 | ||
1187 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | ||
1188 | |||
1187 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) | 1189 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) |
1188 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" | 1190 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" |
1189 | " info!\n"); | 1191 | " info!\n"); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 4d7b98b0503..e019102b228 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -937,6 +937,11 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
937 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 937 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
938 | IEEE80211_HW_SIGNAL_DB; | 938 | IEEE80211_HW_SIGNAL_DB; |
939 | 939 | ||
940 | hw->wiphy->interface_modes = | ||
941 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
942 | BIT(NL80211_IFTYPE_STATION) | | ||
943 | BIT(NL80211_IFTYPE_ADHOC); | ||
944 | |||
940 | hw->max_signal = 100; | 945 | hw->max_signal = 100; |
941 | hw->queues = 1; | 946 | hw->queues = 1; |
942 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); | 947 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 0c1147de3ec..5e51f4e7600 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -210,6 +210,10 @@ enum nl80211_commands { | |||
210 | * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from | 210 | * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from |
211 | * association request when used with NL80211_CMD_NEW_STATION) | 211 | * association request when used with NL80211_CMD_NEW_STATION) |
212 | * | 212 | * |
213 | * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all | ||
214 | * supported interface types, each a flag attribute with the number | ||
215 | * of the interface mode. | ||
216 | * | ||
213 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 217 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
214 | * @__NL80211_ATTR_AFTER_LAST: internal use | 218 | * @__NL80211_ATTR_AFTER_LAST: internal use |
215 | */ | 219 | */ |
@@ -259,6 +263,8 @@ enum nl80211_attrs { | |||
259 | 263 | ||
260 | NL80211_ATTR_HT_CAPABILITY, | 264 | NL80211_ATTR_HT_CAPABILITY, |
261 | 265 | ||
266 | NL80211_ATTR_SUPPORTED_IFTYPES, | ||
267 | |||
262 | /* add attributes here, update the policy in nl80211.c */ | 268 | /* add attributes here, update the policy in nl80211.c */ |
263 | 269 | ||
264 | __NL80211_ATTR_AFTER_LAST, | 270 | __NL80211_ATTR_AFTER_LAST, |
diff --git a/include/net/wireless.h b/include/net/wireless.h index 9324f8dd183..1dc8ec3daa2 100644 --- a/include/net/wireless.h +++ b/include/net/wireless.h | |||
@@ -185,6 +185,9 @@ struct wiphy { | |||
185 | /* permanent MAC address */ | 185 | /* permanent MAC address */ |
186 | u8 perm_addr[ETH_ALEN]; | 186 | u8 perm_addr[ETH_ALEN]; |
187 | 187 | ||
188 | /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ | ||
189 | u16 interface_modes; | ||
190 | |||
188 | /* If multiple wiphys are registered and you're handed e.g. | 191 | /* If multiple wiphys are registered and you're handed e.g. |
189 | * a regular netdev with assigned ieee80211_ptr, you won't | 192 | * a regular netdev with assigned ieee80211_ptr, you won't |
190 | * know whether it points to a wiphy your driver has registered | 193 | * know whether it points to a wiphy your driver has registered |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 638b75f36e2..396cfb2d0f4 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1675,6 +1675,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1675 | } | 1675 | } |
1676 | } | 1676 | } |
1677 | 1677 | ||
1678 | /* if low-level driver supports AP, we also support VLAN */ | ||
1679 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) | ||
1680 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); | ||
1681 | |||
1682 | /* mac80211 always supports monitor */ | ||
1683 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); | ||
1684 | |||
1678 | result = wiphy_register(local->hw.wiphy); | 1685 | result = wiphy_register(local->hw.wiphy); |
1679 | if (result < 0) | 1686 | if (result < 0) |
1680 | return result; | 1687 | return result; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index f1da0b93bc5..7e995ac06a0 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * This is the linux wireless configuration interface. | 2 | * This is the linux wireless configuration interface. |
3 | * | 3 | * |
4 | * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/if.h> | 7 | #include <linux/if.h> |
@@ -259,6 +259,13 @@ int wiphy_register(struct wiphy *wiphy) | |||
259 | struct ieee80211_supported_band *sband; | 259 | struct ieee80211_supported_band *sband; |
260 | bool have_band = false; | 260 | bool have_band = false; |
261 | int i; | 261 | int i; |
262 | u16 ifmodes = wiphy->interface_modes; | ||
263 | |||
264 | /* sanity check ifmodes */ | ||
265 | WARN_ON(!ifmodes); | ||
266 | ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; | ||
267 | if (WARN_ON(ifmodes != wiphy->interface_modes)) | ||
268 | wiphy->interface_modes = ifmodes; | ||
262 | 269 | ||
263 | /* sanity check supported bands/channels */ | 270 | /* sanity check supported bands/channels */ |
264 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 271 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4d6c02afd6f..77880ba8b61 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 | } |