aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/adm8211.c1
-rw-r--r--drivers/net/wireless/ath5k/base.c6
-rw-r--r--drivers/net/wireless/ath9k/main.c5
-rw-r--r--drivers/net/wireless/b43/main.c7
-rw-r--r--drivers/net/wireless/b43legacy/main.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c5
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c3
-rw-r--r--drivers/net/wireless/p54/p54common.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c5
-rw-r--r--drivers/net/wireless/rtl8187_dev.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c5
-rw-r--r--include/linux/nl80211.h6
-rw-r--r--include/net/wireless.h3
-rw-r--r--net/mac80211/main.c7
-rw-r--r--net/wireless/core.c9
-rw-r--r--net/wireless/nl80211.c22
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 }