aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c2
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/lib80211.c15
-rw-r--r--net/wireless/lib80211_crypt_ccmp.c2
-rw-r--r--net/wireless/lib80211_crypt_tkip.c4
-rw-r--r--net/wireless/lib80211_crypt_wep.c4
-rw-r--r--net/wireless/mesh.c3
-rw-r--r--net/wireless/mlme.c16
-rw-r--r--net/wireless/nl80211.c294
-rw-r--r--net/wireless/nl80211.h4
-rw-r--r--net/wireless/reg.c47
-rw-r--r--net/wireless/reg.h2
-rw-r--r--net/wireless/scan.c28
-rw-r--r--net/wireless/sme.c19
-rw-r--r--net/wireless/util.c189
-rw-r--r--net/wireless/wext-compat.c137
-rw-r--r--net/wireless/wext-compat.h8
-rw-r--r--net/wireless/wext-sme.c3
18 files changed, 617 insertions, 166 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index c14865172da7..220f3bd176f8 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -582,7 +582,7 @@ int wiphy_register(struct wiphy *wiphy)
582 } 582 }
583 583
584 /* set up regulatory info */ 584 /* set up regulatory info */
585 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); 585 regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE);
586 586
587 list_add_rcu(&rdev->list, &cfg80211_rdev_list); 587 list_add_rcu(&rdev->list, &cfg80211_rdev_list);
588 cfg80211_rdev_list_generation++; 588 cfg80211_rdev_list_generation++;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 8672e028022f..b9ec3061ed72 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -279,8 +279,6 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
279 char *newname); 279 char *newname);
280 280
281void ieee80211_set_bitrate_flags(struct wiphy *wiphy); 281void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
282void wiphy_update_regulatory(struct wiphy *wiphy,
283 enum nl80211_reg_initiator setby);
284 282
285void cfg80211_bss_expire(struct cfg80211_registered_device *dev); 283void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
286void cfg80211_bss_age(struct cfg80211_registered_device *dev, 284void cfg80211_bss_age(struct cfg80211_registered_device *dev,
@@ -377,7 +375,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
377 struct ieee80211_channel *chan, bool offchan, 375 struct ieee80211_channel *chan, bool offchan,
378 enum nl80211_channel_type channel_type, 376 enum nl80211_channel_type channel_type,
379 bool channel_type_valid, unsigned int wait, 377 bool channel_type_valid, unsigned int wait,
380 const u8 *buf, size_t len, u64 *cookie); 378 const u8 *buf, size_t len, bool no_cck,
379 u64 *cookie);
381 380
382/* SME */ 381/* SME */
383int __cfg80211_connect(struct cfg80211_registered_device *rdev, 382int __cfg80211_connect(struct cfg80211_registered_device *rdev,
@@ -408,6 +407,7 @@ void cfg80211_sme_failed_assoc(struct wireless_dev *wdev);
408bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); 407bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
409 408
410/* internal helpers */ 409/* internal helpers */
410bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
411int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 411int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
412 struct key_params *params, int key_idx, 412 struct key_params *params, int key_idx,
413 bool pairwise, const u8 *mac_addr); 413 bool pairwise, const u8 *mac_addr);
diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c
index 3268fac5ab22..a55c27b75ee5 100644
--- a/net/wireless/lib80211.c
+++ b/net/wireless/lib80211.c
@@ -41,6 +41,11 @@ struct lib80211_crypto_alg {
41static LIST_HEAD(lib80211_crypto_algs); 41static LIST_HEAD(lib80211_crypto_algs);
42static DEFINE_SPINLOCK(lib80211_crypto_lock); 42static DEFINE_SPINLOCK(lib80211_crypto_lock);
43 43
44static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info,
45 int force);
46static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info);
47static void lib80211_crypt_deinit_handler(unsigned long data);
48
44const char *print_ssid(char *buf, const char *ssid, u8 ssid_len) 49const char *print_ssid(char *buf, const char *ssid, u8 ssid_len)
45{ 50{
46 const char *s = ssid; 51 const char *s = ssid;
@@ -111,7 +116,8 @@ void lib80211_crypt_info_free(struct lib80211_crypt_info *info)
111} 116}
112EXPORT_SYMBOL(lib80211_crypt_info_free); 117EXPORT_SYMBOL(lib80211_crypt_info_free);
113 118
114void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force) 119static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info,
120 int force)
115{ 121{
116 struct lib80211_crypt_data *entry, *next; 122 struct lib80211_crypt_data *entry, *next;
117 unsigned long flags; 123 unsigned long flags;
@@ -131,10 +137,9 @@ void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force)
131 } 137 }
132 spin_unlock_irqrestore(info->lock, flags); 138 spin_unlock_irqrestore(info->lock, flags);
133} 139}
134EXPORT_SYMBOL(lib80211_crypt_deinit_entries);
135 140
136/* After this, crypt_deinit_list won't accept new members */ 141/* After this, crypt_deinit_list won't accept new members */
137void lib80211_crypt_quiescing(struct lib80211_crypt_info *info) 142static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
138{ 143{
139 unsigned long flags; 144 unsigned long flags;
140 145
@@ -142,9 +147,8 @@ void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
142 info->crypt_quiesced = 1; 147 info->crypt_quiesced = 1;
143 spin_unlock_irqrestore(info->lock, flags); 148 spin_unlock_irqrestore(info->lock, flags);
144} 149}
145EXPORT_SYMBOL(lib80211_crypt_quiescing);
146 150
147void lib80211_crypt_deinit_handler(unsigned long data) 151static void lib80211_crypt_deinit_handler(unsigned long data)
148{ 152{
149 struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data; 153 struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data;
150 unsigned long flags; 154 unsigned long flags;
@@ -160,7 +164,6 @@ void lib80211_crypt_deinit_handler(unsigned long data)
160 } 164 }
161 spin_unlock_irqrestore(info->lock, flags); 165 spin_unlock_irqrestore(info->lock, flags);
162} 166}
163EXPORT_SYMBOL(lib80211_crypt_deinit_handler);
164 167
165void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, 168void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
166 struct lib80211_crypt_data **crypt) 169 struct lib80211_crypt_data **crypt)
diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c
index dacb3b4b1bdb..755738d26bb4 100644
--- a/net/wireless/lib80211_crypt_ccmp.c
+++ b/net/wireless/lib80211_crypt_ccmp.c
@@ -77,8 +77,6 @@ static void *lib80211_ccmp_init(int key_idx)
77 77
78 priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); 78 priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
79 if (IS_ERR(priv->tfm)) { 79 if (IS_ERR(priv->tfm)) {
80 printk(KERN_DEBUG "lib80211_crypt_ccmp: could not allocate "
81 "crypto API aes\n");
82 priv->tfm = NULL; 80 priv->tfm = NULL;
83 goto fail; 81 goto fail;
84 } 82 }
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c
index 7ea4f2b0770e..38734846c19e 100644
--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -101,7 +101,6 @@ static void *lib80211_tkip_init(int key_idx)
101 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, 101 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
102 CRYPTO_ALG_ASYNC); 102 CRYPTO_ALG_ASYNC);
103 if (IS_ERR(priv->tx_tfm_arc4)) { 103 if (IS_ERR(priv->tx_tfm_arc4)) {
104 printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n"));
105 priv->tx_tfm_arc4 = NULL; 104 priv->tx_tfm_arc4 = NULL;
106 goto fail; 105 goto fail;
107 } 106 }
@@ -109,7 +108,6 @@ static void *lib80211_tkip_init(int key_idx)
109 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, 108 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
110 CRYPTO_ALG_ASYNC); 109 CRYPTO_ALG_ASYNC);
111 if (IS_ERR(priv->tx_tfm_michael)) { 110 if (IS_ERR(priv->tx_tfm_michael)) {
112 printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n"));
113 priv->tx_tfm_michael = NULL; 111 priv->tx_tfm_michael = NULL;
114 goto fail; 112 goto fail;
115 } 113 }
@@ -117,7 +115,6 @@ static void *lib80211_tkip_init(int key_idx)
117 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, 115 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
118 CRYPTO_ALG_ASYNC); 116 CRYPTO_ALG_ASYNC);
119 if (IS_ERR(priv->rx_tfm_arc4)) { 117 if (IS_ERR(priv->rx_tfm_arc4)) {
120 printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n"));
121 priv->rx_tfm_arc4 = NULL; 118 priv->rx_tfm_arc4 = NULL;
122 goto fail; 119 goto fail;
123 } 120 }
@@ -125,7 +122,6 @@ static void *lib80211_tkip_init(int key_idx)
125 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, 122 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
126 CRYPTO_ALG_ASYNC); 123 CRYPTO_ALG_ASYNC);
127 if (IS_ERR(priv->rx_tfm_michael)) { 124 if (IS_ERR(priv->rx_tfm_michael)) {
128 printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n"));
129 priv->rx_tfm_michael = NULL; 125 priv->rx_tfm_michael = NULL;
130 goto fail; 126 goto fail;
131 } 127 }
diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c
index 2f265e033ae2..c1304018fc1c 100644
--- a/net/wireless/lib80211_crypt_wep.c
+++ b/net/wireless/lib80211_crypt_wep.c
@@ -50,16 +50,12 @@ static void *lib80211_wep_init(int keyidx)
50 50
51 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); 51 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
52 if (IS_ERR(priv->tx_tfm)) { 52 if (IS_ERR(priv->tx_tfm)) {
53 printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate "
54 "crypto API arc4\n");
55 priv->tx_tfm = NULL; 53 priv->tx_tfm = NULL;
56 goto fail; 54 goto fail;
57 } 55 }
58 56
59 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); 57 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
60 if (IS_ERR(priv->rx_tfm)) { 58 if (IS_ERR(priv->rx_tfm)) {
61 printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate "
62 "crypto API arc4\n");
63 priv->rx_tfm = NULL; 59 priv->rx_tfm = NULL;
64 goto fail; 60 goto fail;
65 } 61 }
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 5c116083eeca..4423e64c7d98 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -12,6 +12,7 @@
12#define MESH_HOLD_T 100 12#define MESH_HOLD_T 100
13 13
14#define MESH_PATH_TIMEOUT 5000 14#define MESH_PATH_TIMEOUT 5000
15#define MESH_RANN_INTERVAL 5000
15 16
16/* 17/*
17 * Minimum interval between two consecutive PREQs originated by the same 18 * Minimum interval between two consecutive PREQs originated by the same
@@ -49,6 +50,8 @@ const struct mesh_config default_mesh_config = {
49 .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, 50 .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES,
50 .path_refresh_time = MESH_PATH_REFRESH_TIME, 51 .path_refresh_time = MESH_PATH_REFRESH_TIME,
51 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, 52 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
53 .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
54 .dot11MeshGateAnnouncementProtocol = false,
52}; 55};
53 56
54const struct mesh_setup default_mesh_setup = { 57const struct mesh_setup default_mesh_setup = {
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 832f6574e4ed..21fc9702f81c 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -900,7 +900,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
900 struct ieee80211_channel *chan, bool offchan, 900 struct ieee80211_channel *chan, bool offchan,
901 enum nl80211_channel_type channel_type, 901 enum nl80211_channel_type channel_type,
902 bool channel_type_valid, unsigned int wait, 902 bool channel_type_valid, unsigned int wait,
903 const u8 *buf, size_t len, u64 *cookie) 903 const u8 *buf, size_t len, bool no_cck,
904 u64 *cookie)
904{ 905{
905 struct wireless_dev *wdev = dev->ieee80211_ptr; 906 struct wireless_dev *wdev = dev->ieee80211_ptr;
906 const struct ieee80211_mgmt *mgmt; 907 const struct ieee80211_mgmt *mgmt;
@@ -991,7 +992,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
991 /* Transmit the Action frame as requested by user space */ 992 /* Transmit the Action frame as requested by user space */
992 return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, 993 return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
993 channel_type, channel_type_valid, 994 channel_type, channel_type_valid,
994 wait, buf, len, cookie); 995 wait, buf, len, no_cck, cookie);
995} 996}
996 997
997bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, 998bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
@@ -1095,3 +1096,14 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
1095 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); 1096 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
1096} 1097}
1097EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); 1098EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
1099
1100void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
1101 const u8 *bssid, bool preauth, gfp_t gfp)
1102{
1103 struct wireless_dev *wdev = dev->ieee80211_ptr;
1104 struct wiphy *wiphy = wdev->wiphy;
1105 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1106
1107 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
1108}
1109EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ea40d540a990..b85075761e24 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -23,6 +23,12 @@
23#include "nl80211.h" 23#include "nl80211.h"
24#include "reg.h" 24#include "reg.h"
25 25
26static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type);
27static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
28 struct genl_info *info,
29 struct cfg80211_crypto_settings *settings,
30 int cipher_limit);
31
26static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, 32static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
27 struct genl_info *info); 33 struct genl_info *info);
28static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, 34static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
@@ -178,6 +184,14 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
178 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, 184 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
179 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, 185 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
180 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, 186 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
187 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
188 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
189 .len = IEEE80211_MAX_DATA_LEN },
190 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
191 .len = IEEE80211_MAX_DATA_LEN },
192 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
193 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
194 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
181}; 195};
182 196
183/* policy for the key attributes */ 197/* policy for the key attributes */
@@ -220,6 +234,12 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
220 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN }, 234 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
221}; 235};
222 236
237static const struct nla_policy
238nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
239 [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY,
240 .len = IEEE80211_MAX_SSID_LEN },
241};
242
223/* ifidx get helper */ 243/* ifidx get helper */
224static int nl80211_get_ifidx(struct netlink_callback *cb) 244static int nl80211_get_ifidx(struct netlink_callback *cb)
225{ 245{
@@ -703,11 +723,18 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
703 dev->wiphy.max_scan_ie_len); 723 dev->wiphy.max_scan_ie_len);
704 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, 724 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
705 dev->wiphy.max_sched_scan_ie_len); 725 dev->wiphy.max_sched_scan_ie_len);
726 NLA_PUT_U8(msg, NL80211_ATTR_MAX_MATCH_SETS,
727 dev->wiphy.max_match_sets);
706 728
707 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) 729 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
708 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); 730 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
709 if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) 731 if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
710 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); 732 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
733 if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD)
734 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD);
735
736 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)
737 NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT);
711 738
712 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, 739 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
713 sizeof(u32) * dev->wiphy.n_cipher_suites, 740 sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -871,8 +898,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
871 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, 898 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
872 dev->wiphy.max_remain_on_channel_duration); 899 dev->wiphy.max_remain_on_channel_duration);
873 900
874 /* for now at least assume all drivers have it */ 901 if (dev->ops->mgmt_tx_cancel_wait)
875 if (dev->ops->mgmt_tx)
876 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); 902 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
877 903
878 if (mgmt_stypes) { 904 if (mgmt_stypes) {
@@ -1210,6 +1236,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1210 goto bad_res; 1236 goto bad_res;
1211 } 1237 }
1212 1238
1239 if (!netdev) {
1240 result = -EINVAL;
1241 goto bad_res;
1242 }
1243
1213 nla_for_each_nested(nl_txq_params, 1244 nla_for_each_nested(nl_txq_params,
1214 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], 1245 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
1215 rem_txq_params) { 1246 rem_txq_params) {
@@ -1222,6 +1253,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1222 goto bad_res; 1253 goto bad_res;
1223 1254
1224 result = rdev->ops->set_txq_params(&rdev->wiphy, 1255 result = rdev->ops->set_txq_params(&rdev->wiphy,
1256 netdev,
1225 &txq_params); 1257 &txq_params);
1226 if (result) 1258 if (result)
1227 goto bad_res; 1259 goto bad_res;
@@ -1985,7 +2017,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1985 struct beacon_parameters params; 2017 struct beacon_parameters params;
1986 int haveinfo = 0, err; 2018 int haveinfo = 0, err;
1987 2019
1988 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 2020 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) ||
2021 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) ||
2022 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
2023 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]))
1989 return -EINVAL; 2024 return -EINVAL;
1990 2025
1991 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2026 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
@@ -2011,6 +2046,49 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
2011 if (err) 2046 if (err)
2012 return err; 2047 return err;
2013 2048
2049 /*
2050 * In theory, some of these attributes could be required for
2051 * NEW_BEACON, but since they were not used when the command was
2052 * originally added, keep them optional for old user space
2053 * programs to work with drivers that do not need the additional
2054 * information.
2055 */
2056 if (info->attrs[NL80211_ATTR_SSID]) {
2057 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
2058 params.ssid_len =
2059 nla_len(info->attrs[NL80211_ATTR_SSID]);
2060 if (params.ssid_len == 0 ||
2061 params.ssid_len > IEEE80211_MAX_SSID_LEN)
2062 return -EINVAL;
2063 }
2064
2065 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
2066 params.hidden_ssid = nla_get_u32(
2067 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
2068 if (params.hidden_ssid !=
2069 NL80211_HIDDEN_SSID_NOT_IN_USE &&
2070 params.hidden_ssid !=
2071 NL80211_HIDDEN_SSID_ZERO_LEN &&
2072 params.hidden_ssid !=
2073 NL80211_HIDDEN_SSID_ZERO_CONTENTS)
2074 return -EINVAL;
2075 }
2076
2077 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
2078
2079 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
2080 params.auth_type = nla_get_u32(
2081 info->attrs[NL80211_ATTR_AUTH_TYPE]);
2082 if (!nl80211_valid_auth_type(params.auth_type))
2083 return -EINVAL;
2084 } else
2085 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
2086
2087 err = nl80211_crypto_settings(rdev, info, &params.crypto,
2088 NL80211_MAX_NR_CIPHER_SUITES);
2089 if (err)
2090 return err;
2091
2014 call = rdev->ops->add_beacon; 2092 call = rdev->ops->add_beacon;
2015 break; 2093 break;
2016 case NL80211_CMD_SET_BEACON: 2094 case NL80211_CMD_SET_BEACON:
@@ -2041,6 +2119,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
2041 if (!haveinfo) 2119 if (!haveinfo)
2042 return -EINVAL; 2120 return -EINVAL;
2043 2121
2122 if (info->attrs[NL80211_ATTR_IE]) {
2123 params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2124 params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2125 }
2126
2127 if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) {
2128 params.proberesp_ies =
2129 nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
2130 params.proberesp_ies_len =
2131 nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
2132 }
2133
2134 if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
2135 params.assocresp_ies =
2136 nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2137 params.assocresp_ies_len =
2138 nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2139 }
2140
2044 err = call(&rdev->wiphy, dev, &params); 2141 err = call(&rdev->wiphy, dev, &params);
2045 if (!err && params.interval) 2142 if (!err && params.interval)
2046 wdev->beacon_interval = params.interval; 2143 wdev->beacon_interval = params.interval;
@@ -2237,6 +2334,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2237 } 2334 }
2238 nla_nest_end(msg, sinfoattr); 2335 nla_nest_end(msg, sinfoattr);
2239 2336
2337 if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
2338 NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
2339 sinfo->assoc_req_ies);
2340
2240 return genlmsg_end(msg, hdr); 2341 return genlmsg_end(msg, hdr);
2241 2342
2242 nla_put_failure: 2343 nla_put_failure:
@@ -2264,6 +2365,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
2264 } 2365 }
2265 2366
2266 while (1) { 2367 while (1) {
2368 memset(&sinfo, 0, sizeof(sinfo));
2267 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, 2369 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
2268 mac_addr, &sinfo); 2370 mac_addr, &sinfo);
2269 if (err == -ENOENT) 2371 if (err == -ENOENT)
@@ -2465,6 +2567,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2465 return err; 2567 return err;
2466} 2568}
2467 2569
2570static struct nla_policy
2571nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
2572 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
2573 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
2574};
2575
2468static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) 2576static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2469{ 2577{
2470 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2578 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2510,6 +2618,33 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2510 if (parse_station_flags(info, &params)) 2618 if (parse_station_flags(info, &params))
2511 return -EINVAL; 2619 return -EINVAL;
2512 2620
2621 /* parse WME attributes if sta is WME capable */
2622 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
2623 (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) &&
2624 info->attrs[NL80211_ATTR_STA_WME]) {
2625 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
2626 struct nlattr *nla;
2627
2628 nla = info->attrs[NL80211_ATTR_STA_WME];
2629 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
2630 nl80211_sta_wme_policy);
2631 if (err)
2632 return err;
2633
2634 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
2635 params.uapsd_queues =
2636 nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]);
2637 if (params.uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
2638 return -EINVAL;
2639
2640 if (tb[NL80211_STA_WME_MAX_SP])
2641 params.max_sp =
2642 nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
2643
2644 if (params.max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
2645 return -EINVAL;
2646 }
2647
2513 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2648 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2514 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2649 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2515 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && 2650 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
@@ -2955,6 +3090,10 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
2955 cur_params.dot11MeshHWMPnetDiameterTraversalTime); 3090 cur_params.dot11MeshHWMPnetDiameterTraversalTime);
2956 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, 3091 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
2957 cur_params.dot11MeshHWMPRootMode); 3092 cur_params.dot11MeshHWMPRootMode);
3093 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3094 cur_params.dot11MeshHWMPRannInterval);
3095 NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3096 cur_params.dot11MeshGateAnnouncementProtocol);
2958 nla_nest_end(msg, pinfoattr); 3097 nla_nest_end(msg, pinfoattr);
2959 genlmsg_end(msg, hdr); 3098 genlmsg_end(msg, hdr);
2960 return genlmsg_reply(msg, info); 3099 return genlmsg_reply(msg, info);
@@ -2982,6 +3121,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
2982 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, 3121 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
2983 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, 3122 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
2984 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, 3123 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
3124 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
3125 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
3126 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
2985}; 3127};
2986 3128
2987static const struct nla_policy 3129static const struct nla_policy
@@ -3060,6 +3202,14 @@ do {\
3060 dot11MeshHWMPRootMode, mask, 3202 dot11MeshHWMPRootMode, mask,
3061 NL80211_MESHCONF_HWMP_ROOTMODE, 3203 NL80211_MESHCONF_HWMP_ROOTMODE,
3062 nla_get_u8); 3204 nla_get_u8);
3205 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3206 dot11MeshHWMPRannInterval, mask,
3207 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3208 nla_get_u16);
3209 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3210 dot11MeshGateAnnouncementProtocol, mask,
3211 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3212 nla_get_u8);
3063 if (mask_out) 3213 if (mask_out)
3064 *mask_out = mask; 3214 *mask_out = mask;
3065 3215
@@ -3477,6 +3627,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3477 } 3627 }
3478 } 3628 }
3479 3629
3630 request->no_cck =
3631 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
3632
3480 request->dev = dev; 3633 request->dev = dev;
3481 request->wiphy = &rdev->wiphy; 3634 request->wiphy = &rdev->wiphy;
3482 3635
@@ -3503,10 +3656,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3503 struct net_device *dev = info->user_ptr[1]; 3656 struct net_device *dev = info->user_ptr[1];
3504 struct nlattr *attr; 3657 struct nlattr *attr;
3505 struct wiphy *wiphy; 3658 struct wiphy *wiphy;
3506 int err, tmp, n_ssids = 0, n_channels, i; 3659 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i;
3507 u32 interval; 3660 u32 interval;
3508 enum ieee80211_band band; 3661 enum ieee80211_band band;
3509 size_t ie_len; 3662 size_t ie_len;
3663 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
3510 3664
3511 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || 3665 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
3512 !rdev->ops->sched_scan_start) 3666 !rdev->ops->sched_scan_start)
@@ -3545,6 +3699,15 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3545 if (n_ssids > wiphy->max_sched_scan_ssids) 3699 if (n_ssids > wiphy->max_sched_scan_ssids)
3546 return -EINVAL; 3700 return -EINVAL;
3547 3701
3702 if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH])
3703 nla_for_each_nested(attr,
3704 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
3705 tmp)
3706 n_match_sets++;
3707
3708 if (n_match_sets > wiphy->max_match_sets)
3709 return -EINVAL;
3710
3548 if (info->attrs[NL80211_ATTR_IE]) 3711 if (info->attrs[NL80211_ATTR_IE])
3549 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3712 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3550 else 3713 else
@@ -3562,6 +3725,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3562 3725
3563 request = kzalloc(sizeof(*request) 3726 request = kzalloc(sizeof(*request)
3564 + sizeof(*request->ssids) * n_ssids 3727 + sizeof(*request->ssids) * n_ssids
3728 + sizeof(*request->match_sets) * n_match_sets
3565 + sizeof(*request->channels) * n_channels 3729 + sizeof(*request->channels) * n_channels
3566 + ie_len, GFP_KERNEL); 3730 + ie_len, GFP_KERNEL);
3567 if (!request) { 3731 if (!request) {
@@ -3579,6 +3743,18 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3579 request->ie = (void *)(request->channels + n_channels); 3743 request->ie = (void *)(request->channels + n_channels);
3580 } 3744 }
3581 3745
3746 if (n_match_sets) {
3747 if (request->ie)
3748 request->match_sets = (void *)(request->ie + ie_len);
3749 else if (request->ssids)
3750 request->match_sets =
3751 (void *)(request->ssids + n_ssids);
3752 else
3753 request->match_sets =
3754 (void *)(request->channels + n_channels);
3755 }
3756 request->n_match_sets = n_match_sets;
3757
3582 i = 0; 3758 i = 0;
3583 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { 3759 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3584 /* user specified, bail out if channel not found */ 3760 /* user specified, bail out if channel not found */
@@ -3643,6 +3819,31 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3643 } 3819 }
3644 } 3820 }
3645 3821
3822 i = 0;
3823 if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
3824 nla_for_each_nested(attr,
3825 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
3826 tmp) {
3827 struct nlattr *ssid;
3828
3829 nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
3830 nla_data(attr), nla_len(attr),
3831 nl80211_match_policy);
3832 ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID];
3833 if (ssid) {
3834 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
3835 err = -EINVAL;
3836 goto out_free;
3837 }
3838 memcpy(request->match_sets[i].ssid.ssid,
3839 nla_data(ssid), nla_len(ssid));
3840 request->match_sets[i].ssid.ssid_len =
3841 nla_len(ssid);
3842 }
3843 i++;
3844 }
3845 }
3846
3646 if (info->attrs[NL80211_ATTR_IE]) { 3847 if (info->attrs[NL80211_ATTR_IE]) {
3647 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3848 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3648 memcpy((void *)request->ie, 3849 memcpy((void *)request->ie,
@@ -3935,22 +4136,6 @@ static bool nl80211_valid_wpa_versions(u32 wpa_versions)
3935 NL80211_WPA_VERSION_2)); 4136 NL80211_WPA_VERSION_2));
3936} 4137}
3937 4138
3938static bool nl80211_valid_akm_suite(u32 akm)
3939{
3940 return akm == WLAN_AKM_SUITE_8021X ||
3941 akm == WLAN_AKM_SUITE_PSK;
3942}
3943
3944static bool nl80211_valid_cipher_suite(u32 cipher)
3945{
3946 return cipher == WLAN_CIPHER_SUITE_WEP40 ||
3947 cipher == WLAN_CIPHER_SUITE_WEP104 ||
3948 cipher == WLAN_CIPHER_SUITE_TKIP ||
3949 cipher == WLAN_CIPHER_SUITE_CCMP ||
3950 cipher == WLAN_CIPHER_SUITE_AES_CMAC;
3951}
3952
3953
3954static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) 4139static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3955{ 4140{
3956 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4141 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4083,7 +4268,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4083 memcpy(settings->ciphers_pairwise, data, len); 4268 memcpy(settings->ciphers_pairwise, data, len);
4084 4269
4085 for (i = 0; i < settings->n_ciphers_pairwise; i++) 4270 for (i = 0; i < settings->n_ciphers_pairwise; i++)
4086 if (!nl80211_valid_cipher_suite( 4271 if (!cfg80211_supported_cipher_suite(
4272 &rdev->wiphy,
4087 settings->ciphers_pairwise[i])) 4273 settings->ciphers_pairwise[i]))
4088 return -EINVAL; 4274 return -EINVAL;
4089 } 4275 }
@@ -4091,7 +4277,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4091 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) { 4277 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
4092 settings->cipher_group = 4278 settings->cipher_group =
4093 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]); 4279 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
4094 if (!nl80211_valid_cipher_suite(settings->cipher_group)) 4280 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
4281 settings->cipher_group))
4095 return -EINVAL; 4282 return -EINVAL;
4096 } 4283 }
4097 4284
@@ -4104,7 +4291,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4104 4291
4105 if (info->attrs[NL80211_ATTR_AKM_SUITES]) { 4292 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
4106 void *data; 4293 void *data;
4107 int len, i; 4294 int len;
4108 4295
4109 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]); 4296 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
4110 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]); 4297 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
@@ -4117,10 +4304,6 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4117 return -EINVAL; 4304 return -EINVAL;
4118 4305
4119 memcpy(settings->akm_suites, data, len); 4306 memcpy(settings->akm_suites, data, len);
4120
4121 for (i = 0; i < settings->n_akm_suites; i++)
4122 if (!nl80211_valid_akm_suite(settings->akm_suites[i]))
4123 return -EINVAL;
4124 } 4307 }
4125 4308
4126 return 0; 4309 return 0;
@@ -4339,8 +4522,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4339 4522
4340 wiphy = &rdev->wiphy; 4523 wiphy = &rdev->wiphy;
4341 4524
4342 if (info->attrs[NL80211_ATTR_MAC]) 4525 if (info->attrs[NL80211_ATTR_MAC]) {
4343 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 4526 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
4527
4528 if (!is_valid_ether_addr(ibss.bssid))
4529 return -EINVAL;
4530 }
4344 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 4531 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
4345 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 4532 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
4346 4533
@@ -4997,6 +5184,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4997 struct sk_buff *msg; 5184 struct sk_buff *msg;
4998 unsigned int wait = 0; 5185 unsigned int wait = 0;
4999 bool offchan; 5186 bool offchan;
5187 bool no_cck;
5000 5188
5001 if (!info->attrs[NL80211_ATTR_FRAME] || 5189 if (!info->attrs[NL80211_ATTR_FRAME] ||
5002 !info->attrs[NL80211_ATTR_WIPHY_FREQ]) 5190 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
@@ -5033,6 +5221,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5033 5221
5034 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 5222 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
5035 5223
5224 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
5225
5036 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 5226 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
5037 chan = rdev_freq_to_chan(rdev, freq, channel_type); 5227 chan = rdev_freq_to_chan(rdev, freq, channel_type);
5038 if (chan == NULL) 5228 if (chan == NULL)
@@ -5053,7 +5243,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5053 channel_type_valid, wait, 5243 channel_type_valid, wait,
5054 nla_data(info->attrs[NL80211_ATTR_FRAME]), 5244 nla_data(info->attrs[NL80211_ATTR_FRAME]),
5055 nla_len(info->attrs[NL80211_ATTR_FRAME]), 5245 nla_len(info->attrs[NL80211_ATTR_FRAME]),
5056 &cookie); 5246 no_cck, &cookie);
5057 if (err) 5247 if (err)
5058 goto free_msg; 5248 goto free_msg;
5059 5249
@@ -7078,6 +7268,52 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
7078 nlmsg_free(msg); 7268 nlmsg_free(msg);
7079} 7269}
7080 7270
7271void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
7272 struct net_device *netdev, int index,
7273 const u8 *bssid, bool preauth, gfp_t gfp)
7274{
7275 struct sk_buff *msg;
7276 struct nlattr *attr;
7277 void *hdr;
7278
7279 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
7280 if (!msg)
7281 return;
7282
7283 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
7284 if (!hdr) {
7285 nlmsg_free(msg);
7286 return;
7287 }
7288
7289 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
7290 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
7291
7292 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
7293 if (!attr)
7294 goto nla_put_failure;
7295
7296 NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index);
7297 NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid);
7298 if (preauth)
7299 NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH);
7300
7301 nla_nest_end(msg, attr);
7302
7303 if (genlmsg_end(msg, hdr) < 0) {
7304 nlmsg_free(msg);
7305 return;
7306 }
7307
7308 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7309 nl80211_mlme_mcgrp.id, gfp);
7310 return;
7311
7312 nla_put_failure:
7313 genlmsg_cancel(msg, hdr);
7314 nlmsg_free(msg);
7315}
7316
7081void 7317void
7082nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 7318nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
7083 struct net_device *netdev, const u8 *peer, 7319 struct net_device *netdev, const u8 *peer,
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 5d69c56400ae..f24a1fbeaf19 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -113,4 +113,8 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
113 struct net_device *netdev, const u8 *bssid, 113 struct net_device *netdev, const u8 *bssid,
114 const u8 *replay_ctr, gfp_t gfp); 114 const u8 *replay_ctr, gfp_t gfp);
115 115
116void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
117 struct net_device *netdev, int index,
118 const u8 *bssid, bool preauth, gfp_t gfp);
119
116#endif /* __NET_WIRELESS_NL80211_H */ 120#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 68a471ba193f..2520a1b7e7db 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -49,10 +49,8 @@
49#include "nl80211.h" 49#include "nl80211.h"
50 50
51#ifdef CONFIG_CFG80211_REG_DEBUG 51#ifdef CONFIG_CFG80211_REG_DEBUG
52#define REG_DBG_PRINT(format, args...) \ 52#define REG_DBG_PRINT(format, args...) \
53 do { \ 53 printk(KERN_DEBUG pr_fmt(format), ##args)
54 printk(KERN_DEBUG pr_fmt(format), ##args); \
55 } while (0)
56#else 54#else
57#define REG_DBG_PRINT(args...) 55#define REG_DBG_PRINT(args...)
58#endif 56#endif
@@ -753,9 +751,10 @@ static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
753 chan->center_freq, 751 chan->center_freq,
754 KHZ_TO_MHZ(desired_bw_khz)); 752 KHZ_TO_MHZ(desired_bw_khz));
755 753
756 REG_DBG_PRINT("%d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n", 754 REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n",
757 freq_range->start_freq_khz, 755 freq_range->start_freq_khz,
758 freq_range->end_freq_khz, 756 freq_range->end_freq_khz,
757 freq_range->max_bandwidth_khz,
759 max_antenna_gain, 758 max_antenna_gain,
760 power_rule->max_eirp); 759 power_rule->max_eirp);
761} 760}
@@ -891,7 +890,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
891 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { 890 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
892 REG_DBG_PRINT("Ignoring regulatory request %s " 891 REG_DBG_PRINT("Ignoring regulatory request %s "
893 "since the driver uses its own custom " 892 "since the driver uses its own custom "
894 "regulatory domain ", 893 "regulatory domain\n",
895 reg_initiator_name(initiator)); 894 reg_initiator_name(initiator));
896 return true; 895 return true;
897 } 896 }
@@ -905,7 +904,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
905 !is_world_regdom(last_request->alpha2)) { 904 !is_world_regdom(last_request->alpha2)) {
906 REG_DBG_PRINT("Ignoring regulatory request %s " 905 REG_DBG_PRINT("Ignoring regulatory request %s "
907 "since the driver requires its own regulatory " 906 "since the driver requires its own regulatory "
908 "domain to be set first", 907 "domain to be set first\n",
909 reg_initiator_name(initiator)); 908 reg_initiator_name(initiator));
910 return true; 909 return true;
911 } 910 }
@@ -913,14 +912,6 @@ static bool ignore_reg_update(struct wiphy *wiphy,
913 return false; 912 return false;
914} 913}
915 914
916static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
917{
918 struct cfg80211_registered_device *rdev;
919
920 list_for_each_entry(rdev, &cfg80211_rdev_list, list)
921 wiphy_update_regulatory(&rdev->wiphy, initiator);
922}
923
924static void handle_reg_beacon(struct wiphy *wiphy, 915static void handle_reg_beacon(struct wiphy *wiphy,
925 unsigned int chan_idx, 916 unsigned int chan_idx,
926 struct reg_beacon *reg_beacon) 917 struct reg_beacon *reg_beacon)
@@ -1120,11 +1111,13 @@ static void reg_process_ht_flags(struct wiphy *wiphy)
1120 1111
1121} 1112}
1122 1113
1123void wiphy_update_regulatory(struct wiphy *wiphy, 1114static void wiphy_update_regulatory(struct wiphy *wiphy,
1124 enum nl80211_reg_initiator initiator) 1115 enum nl80211_reg_initiator initiator)
1125{ 1116{
1126 enum ieee80211_band band; 1117 enum ieee80211_band band;
1127 1118
1119 assert_reg_lock();
1120
1128 if (ignore_reg_update(wiphy, initiator)) 1121 if (ignore_reg_update(wiphy, initiator))
1129 return; 1122 return;
1130 1123
@@ -1139,6 +1132,22 @@ void wiphy_update_regulatory(struct wiphy *wiphy,
1139 wiphy->reg_notifier(wiphy, last_request); 1132 wiphy->reg_notifier(wiphy, last_request);
1140} 1133}
1141 1134
1135void regulatory_update(struct wiphy *wiphy,
1136 enum nl80211_reg_initiator setby)
1137{
1138 mutex_lock(&reg_mutex);
1139 wiphy_update_regulatory(wiphy, setby);
1140 mutex_unlock(&reg_mutex);
1141}
1142
1143static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
1144{
1145 struct cfg80211_registered_device *rdev;
1146
1147 list_for_each_entry(rdev, &cfg80211_rdev_list, list)
1148 wiphy_update_regulatory(&rdev->wiphy, initiator);
1149}
1150
1142static void handle_channel_custom(struct wiphy *wiphy, 1151static void handle_channel_custom(struct wiphy *wiphy,
1143 enum ieee80211_band band, 1152 enum ieee80211_band band,
1144 unsigned int chan_idx, 1153 unsigned int chan_idx,
@@ -1475,7 +1484,7 @@ static void reg_process_pending_hints(void)
1475 /* When last_request->processed becomes true this will be rescheduled */ 1484 /* When last_request->processed becomes true this will be rescheduled */
1476 if (last_request && !last_request->processed) { 1485 if (last_request && !last_request->processed) {
1477 REG_DBG_PRINT("Pending regulatory request, waiting " 1486 REG_DBG_PRINT("Pending regulatory request, waiting "
1478 "for it to be processed..."); 1487 "for it to be processed...\n");
1479 goto out; 1488 goto out;
1480 } 1489 }
1481 1490
@@ -2188,7 +2197,7 @@ out:
2188static void reg_timeout_work(struct work_struct *work) 2197static void reg_timeout_work(struct work_struct *work)
2189{ 2198{
2190 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, " 2199 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, "
2191 "restoring regulatory settings"); 2200 "restoring regulatory settings\n");
2192 restore_regulatory_settings(true); 2201 restore_regulatory_settings(true);
2193} 2202}
2194 2203
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index b67d1c3a2fb9..4a56799d868d 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -16,6 +16,8 @@ void regulatory_exit(void);
16 16
17int set_regdom(const struct ieee80211_regdomain *rd); 17int set_regdom(const struct ieee80211_regdomain *rd);
18 18
19void regulatory_update(struct wiphy *wiphy, enum nl80211_reg_initiator setby);
20
19/** 21/**
20 * regulatory_hint_found_beacon - hints a beacon was found on a channel 22 * regulatory_hint_found_beacon - hints a beacon was found on a channel
21 * @wiphy: the wireless device where the beacon was found on 23 * @wiphy: the wireless device where the beacon was found on
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 2936cb809152..0fb142410404 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -12,6 +12,7 @@
12#include <linux/etherdevice.h> 12#include <linux/etherdevice.h>
13#include <net/arp.h> 13#include <net/arp.h>
14#include <net/cfg80211.h> 14#include <net/cfg80211.h>
15#include <net/cfg80211-wext.h>
15#include <net/iw_handler.h> 16#include <net/iw_handler.h>
16#include "core.h" 17#include "core.h"
17#include "nl80211.h" 18#include "nl80211.h"
@@ -227,6 +228,33 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
227} 228}
228EXPORT_SYMBOL(cfg80211_find_ie); 229EXPORT_SYMBOL(cfg80211_find_ie);
229 230
231const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
232 const u8 *ies, int len)
233{
234 struct ieee80211_vendor_ie *ie;
235 const u8 *pos = ies, *end = ies + len;
236 int ie_oui;
237
238 while (pos < end) {
239 pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos,
240 end - pos);
241 if (!pos)
242 return NULL;
243
244 if (end - pos < sizeof(*ie))
245 return NULL;
246
247 ie = (struct ieee80211_vendor_ie *)pos;
248 ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2];
249 if (ie_oui == oui && ie->oui_type == oui_type)
250 return pos;
251
252 pos += 2 + ie->len;
253 }
254 return NULL;
255}
256EXPORT_SYMBOL(cfg80211_find_vendor_ie);
257
230static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) 258static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
231{ 259{
232 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); 260 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index dec0fa28372e..6e86d5acf145 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -110,17 +110,22 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
110 else { 110 else {
111 int i = 0, j; 111 int i = 0, j;
112 enum ieee80211_band band; 112 enum ieee80211_band band;
113 struct ieee80211_supported_band *bands;
114 struct ieee80211_channel *channel;
113 115
114 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 116 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
115 if (!wdev->wiphy->bands[band]) 117 bands = wdev->wiphy->bands[band];
118 if (!bands)
116 continue; 119 continue;
117 for (j = 0; j < wdev->wiphy->bands[band]->n_channels; 120 for (j = 0; j < bands->n_channels; j++) {
118 i++, j++) 121 channel = &bands->channels[j];
119 request->channels[i] = 122 if (channel->flags & IEEE80211_CHAN_DISABLED)
120 &wdev->wiphy->bands[band]->channels[j]; 123 continue;
121 request->rates[band] = 124 request->channels[i++] = channel;
122 (1 << wdev->wiphy->bands[band]->n_bitrates) - 1; 125 }
126 request->rates[band] = (1 << bands->n_bitrates) - 1;
123 } 127 }
128 n_channels = i;
124 } 129 }
125 request->n_channels = n_channels; 130 request->n_channels = n_channels;
126 request->ssids = (void *)&request->channels[n_channels]; 131 request->ssids = (void *)&request->channels[n_channels];
diff --git a/net/wireless/util.c b/net/wireless/util.c
index be75a3a0424e..6304ed63588a 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -6,6 +6,7 @@
6#include <linux/bitops.h> 6#include <linux/bitops.h>
7#include <linux/etherdevice.h> 7#include <linux/etherdevice.h>
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <linux/crc32.h>
9#include <net/cfg80211.h> 10#include <net/cfg80211.h>
10#include <net/ip.h> 11#include <net/ip.h>
11#include "core.h" 12#include "core.h"
@@ -150,12 +151,19 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
150 set_mandatory_flags_band(wiphy->bands[band], band); 151 set_mandatory_flags_band(wiphy->bands[band], band);
151} 152}
152 153
154bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher)
155{
156 int i;
157 for (i = 0; i < wiphy->n_cipher_suites; i++)
158 if (cipher == wiphy->cipher_suites[i])
159 return true;
160 return false;
161}
162
153int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 163int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
154 struct key_params *params, int key_idx, 164 struct key_params *params, int key_idx,
155 bool pairwise, const u8 *mac_addr) 165 bool pairwise, const u8 *mac_addr)
156{ 166{
157 int i;
158
159 if (key_idx > 5) 167 if (key_idx > 5)
160 return -EINVAL; 168 return -EINVAL;
161 169
@@ -225,10 +233,7 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
225 } 233 }
226 } 234 }
227 235
228 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) 236 if (!cfg80211_supported_cipher_suite(&rdev->wiphy, params->cipher))
229 if (params->cipher == rdev->wiphy.cipher_suites[i])
230 break;
231 if (i == rdev->wiphy.n_cipher_suites)
232 return -EINVAL; 237 return -EINVAL;
233 238
234 return 0; 239 return 0;
@@ -512,10 +517,9 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
512 if (head_need) 517 if (head_need)
513 skb_orphan(skb); 518 skb_orphan(skb);
514 519
515 if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) { 520 if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC))
516 pr_err("failed to reallocate Tx buffer\n");
517 return -ENOMEM; 521 return -ENOMEM;
518 } 522
519 skb->truesize += head_need; 523 skb->truesize += head_need;
520 } 524 }
521 525
@@ -1044,3 +1048,170 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
1044 1048
1045 return 0; 1049 return 0;
1046} 1050}
1051
1052u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
1053 struct ieee802_11_elems *elems,
1054 u64 filter, u32 crc)
1055{
1056 size_t left = len;
1057 u8 *pos = start;
1058 bool calc_crc = filter != 0;
1059
1060 memset(elems, 0, sizeof(*elems));
1061 elems->ie_start = start;
1062 elems->total_len = len;
1063
1064 while (left >= 2) {
1065 u8 id, elen;
1066
1067 id = *pos++;
1068 elen = *pos++;
1069 left -= 2;
1070
1071 if (elen > left)
1072 break;
1073
1074 if (calc_crc && id < 64 && (filter & (1ULL << id)))
1075 crc = crc32_be(crc, pos - 2, elen + 2);
1076
1077 switch (id) {
1078 case WLAN_EID_SSID:
1079 elems->ssid = pos;
1080 elems->ssid_len = elen;
1081 break;
1082 case WLAN_EID_SUPP_RATES:
1083 elems->supp_rates = pos;
1084 elems->supp_rates_len = elen;
1085 break;
1086 case WLAN_EID_FH_PARAMS:
1087 elems->fh_params = pos;
1088 elems->fh_params_len = elen;
1089 break;
1090 case WLAN_EID_DS_PARAMS:
1091 elems->ds_params = pos;
1092 elems->ds_params_len = elen;
1093 break;
1094 case WLAN_EID_CF_PARAMS:
1095 elems->cf_params = pos;
1096 elems->cf_params_len = elen;
1097 break;
1098 case WLAN_EID_TIM:
1099 if (elen >= sizeof(struct ieee80211_tim_ie)) {
1100 elems->tim = (void *)pos;
1101 elems->tim_len = elen;
1102 }
1103 break;
1104 case WLAN_EID_IBSS_PARAMS:
1105 elems->ibss_params = pos;
1106 elems->ibss_params_len = elen;
1107 break;
1108 case WLAN_EID_CHALLENGE:
1109 elems->challenge = pos;
1110 elems->challenge_len = elen;
1111 break;
1112 case WLAN_EID_VENDOR_SPECIFIC:
1113 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
1114 pos[2] == 0xf2) {
1115 /* Microsoft OUI (00:50:F2) */
1116
1117 if (calc_crc)
1118 crc = crc32_be(crc, pos - 2, elen + 2);
1119
1120 if (pos[3] == 1) {
1121 /* OUI Type 1 - WPA IE */
1122 elems->wpa = pos;
1123 elems->wpa_len = elen;
1124 } else if (elen >= 5 && pos[3] == 2) {
1125 /* OUI Type 2 - WMM IE */
1126 if (pos[4] == 0) {
1127 elems->wmm_info = pos;
1128 elems->wmm_info_len = elen;
1129 } else if (pos[4] == 1) {
1130 elems->wmm_param = pos;
1131 elems->wmm_param_len = elen;
1132 }
1133 }
1134 }
1135 break;
1136 case WLAN_EID_RSN:
1137 elems->rsn = pos;
1138 elems->rsn_len = elen;
1139 break;
1140 case WLAN_EID_ERP_INFO:
1141 elems->erp_info = pos;
1142 elems->erp_info_len = elen;
1143 break;
1144 case WLAN_EID_EXT_SUPP_RATES:
1145 elems->ext_supp_rates = pos;
1146 elems->ext_supp_rates_len = elen;
1147 break;
1148 case WLAN_EID_HT_CAPABILITY:
1149 if (elen >= sizeof(struct ieee80211_ht_cap))
1150 elems->ht_cap_elem = (void *)pos;
1151 break;
1152 case WLAN_EID_HT_INFORMATION:
1153 if (elen >= sizeof(struct ieee80211_ht_info))
1154 elems->ht_info_elem = (void *)pos;
1155 break;
1156 case WLAN_EID_MESH_ID:
1157 elems->mesh_id = pos;
1158 elems->mesh_id_len = elen;
1159 break;
1160 case WLAN_EID_MESH_CONFIG:
1161 if (elen >= sizeof(struct ieee80211_meshconf_ie))
1162 elems->mesh_config = (void *)pos;
1163 break;
1164 case WLAN_EID_PEER_MGMT:
1165 elems->peering = pos;
1166 elems->peering_len = elen;
1167 break;
1168 case WLAN_EID_PREQ:
1169 elems->preq = pos;
1170 elems->preq_len = elen;
1171 break;
1172 case WLAN_EID_PREP:
1173 elems->prep = pos;
1174 elems->prep_len = elen;
1175 break;
1176 case WLAN_EID_PERR:
1177 elems->perr = pos;
1178 elems->perr_len = elen;
1179 break;
1180 case WLAN_EID_RANN:
1181 if (elen >= sizeof(struct ieee80211_rann_ie))
1182 elems->rann = (void *)pos;
1183 break;
1184 case WLAN_EID_CHANNEL_SWITCH:
1185 elems->ch_switch_elem = pos;
1186 elems->ch_switch_elem_len = elen;
1187 break;
1188 case WLAN_EID_QUIET:
1189 if (!elems->quiet_elem) {
1190 elems->quiet_elem = pos;
1191 elems->quiet_elem_len = elen;
1192 }
1193 elems->num_of_quiet_elem++;
1194 break;
1195 case WLAN_EID_COUNTRY:
1196 elems->country_elem = pos;
1197 elems->country_elem_len = elen;
1198 break;
1199 case WLAN_EID_PWR_CONSTRAINT:
1200 elems->pwr_constr_elem = pos;
1201 elems->pwr_constr_elem_len = elen;
1202 break;
1203 case WLAN_EID_TIMEOUT_INTERVAL:
1204 elems->timeout_int = pos;
1205 elems->timeout_int_len = elen;
1206 break;
1207 default:
1208 break;
1209 }
1210
1211 left -= elen;
1212 pos += elen;
1213 }
1214
1215 return crc;
1216}
1217EXPORT_SYMBOL(ieee802_11_parse_elems_crc);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 0bf169bb770e..62f121d1d9cb 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <net/iw_handler.h> 16#include <net/iw_handler.h>
17#include <net/cfg80211.h> 17#include <net/cfg80211.h>
18#include <net/cfg80211-wext.h>
18#include "wext-compat.h" 19#include "wext-compat.h"
19#include "core.h" 20#include "core.h"
20 21
@@ -363,9 +364,9 @@ int cfg80211_wext_giwfrag(struct net_device *dev,
363} 364}
364EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag); 365EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag);
365 366
366int cfg80211_wext_siwretry(struct net_device *dev, 367static int cfg80211_wext_siwretry(struct net_device *dev,
367 struct iw_request_info *info, 368 struct iw_request_info *info,
368 struct iw_param *retry, char *extra) 369 struct iw_param *retry, char *extra)
369{ 370{
370 struct wireless_dev *wdev = dev->ieee80211_ptr; 371 struct wireless_dev *wdev = dev->ieee80211_ptr;
371 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 372 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -402,7 +403,6 @@ int cfg80211_wext_siwretry(struct net_device *dev,
402 403
403 return err; 404 return err;
404} 405}
405EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry);
406 406
407int cfg80211_wext_giwretry(struct net_device *dev, 407int cfg80211_wext_giwretry(struct net_device *dev,
408 struct iw_request_info *info, 408 struct iw_request_info *info,
@@ -593,9 +593,9 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
593 return err; 593 return err;
594} 594}
595 595
596int cfg80211_wext_siwencode(struct net_device *dev, 596static int cfg80211_wext_siwencode(struct net_device *dev,
597 struct iw_request_info *info, 597 struct iw_request_info *info,
598 struct iw_point *erq, char *keybuf) 598 struct iw_point *erq, char *keybuf)
599{ 599{
600 struct wireless_dev *wdev = dev->ieee80211_ptr; 600 struct wireless_dev *wdev = dev->ieee80211_ptr;
601 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 601 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -652,11 +652,10 @@ int cfg80211_wext_siwencode(struct net_device *dev,
652 wdev->wext.default_key == -1, 652 wdev->wext.default_key == -1,
653 idx, &params); 653 idx, &params);
654} 654}
655EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode);
656 655
657int cfg80211_wext_siwencodeext(struct net_device *dev, 656static int cfg80211_wext_siwencodeext(struct net_device *dev,
658 struct iw_request_info *info, 657 struct iw_request_info *info,
659 struct iw_point *erq, char *extra) 658 struct iw_point *erq, char *extra)
660{ 659{
661 struct wireless_dev *wdev = dev->ieee80211_ptr; 660 struct wireless_dev *wdev = dev->ieee80211_ptr;
662 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 661 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -744,11 +743,10 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
744 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, 743 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
745 idx, &params); 744 idx, &params);
746} 745}
747EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
748 746
749int cfg80211_wext_giwencode(struct net_device *dev, 747static int cfg80211_wext_giwencode(struct net_device *dev,
750 struct iw_request_info *info, 748 struct iw_request_info *info,
751 struct iw_point *erq, char *keybuf) 749 struct iw_point *erq, char *keybuf)
752{ 750{
753 struct wireless_dev *wdev = dev->ieee80211_ptr; 751 struct wireless_dev *wdev = dev->ieee80211_ptr;
754 int idx; 752 int idx;
@@ -782,11 +780,10 @@ int cfg80211_wext_giwencode(struct net_device *dev,
782 780
783 return 0; 781 return 0;
784} 782}
785EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
786 783
787int cfg80211_wext_siwfreq(struct net_device *dev, 784static int cfg80211_wext_siwfreq(struct net_device *dev,
788 struct iw_request_info *info, 785 struct iw_request_info *info,
789 struct iw_freq *wextfreq, char *extra) 786 struct iw_freq *wextfreq, char *extra)
790{ 787{
791 struct wireless_dev *wdev = dev->ieee80211_ptr; 788 struct wireless_dev *wdev = dev->ieee80211_ptr;
792 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 789 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -815,11 +812,10 @@ int cfg80211_wext_siwfreq(struct net_device *dev,
815 return -EOPNOTSUPP; 812 return -EOPNOTSUPP;
816 } 813 }
817} 814}
818EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
819 815
820int cfg80211_wext_giwfreq(struct net_device *dev, 816static int cfg80211_wext_giwfreq(struct net_device *dev,
821 struct iw_request_info *info, 817 struct iw_request_info *info,
822 struct iw_freq *freq, char *extra) 818 struct iw_freq *freq, char *extra)
823{ 819{
824 struct wireless_dev *wdev = dev->ieee80211_ptr; 820 struct wireless_dev *wdev = dev->ieee80211_ptr;
825 821
@@ -836,11 +832,10 @@ int cfg80211_wext_giwfreq(struct net_device *dev,
836 return 0; 832 return 0;
837 } 833 }
838} 834}
839EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
840 835
841int cfg80211_wext_siwtxpower(struct net_device *dev, 836static int cfg80211_wext_siwtxpower(struct net_device *dev,
842 struct iw_request_info *info, 837 struct iw_request_info *info,
843 union iwreq_data *data, char *extra) 838 union iwreq_data *data, char *extra)
844{ 839{
845 struct wireless_dev *wdev = dev->ieee80211_ptr; 840 struct wireless_dev *wdev = dev->ieee80211_ptr;
846 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 841 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -889,11 +884,10 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
889 884
890 return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm)); 885 return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm));
891} 886}
892EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower);
893 887
894int cfg80211_wext_giwtxpower(struct net_device *dev, 888static int cfg80211_wext_giwtxpower(struct net_device *dev,
895 struct iw_request_info *info, 889 struct iw_request_info *info,
896 union iwreq_data *data, char *extra) 890 union iwreq_data *data, char *extra)
897{ 891{
898 struct wireless_dev *wdev = dev->ieee80211_ptr; 892 struct wireless_dev *wdev = dev->ieee80211_ptr;
899 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 893 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -919,7 +913,6 @@ int cfg80211_wext_giwtxpower(struct net_device *dev,
919 913
920 return 0; 914 return 0;
921} 915}
922EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower);
923 916
924static int cfg80211_set_auth_alg(struct wireless_dev *wdev, 917static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
925 s32 auth_alg) 918 s32 auth_alg)
@@ -1070,9 +1063,9 @@ static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
1070 return 0; 1063 return 0;
1071} 1064}
1072 1065
1073int cfg80211_wext_siwauth(struct net_device *dev, 1066static int cfg80211_wext_siwauth(struct net_device *dev,
1074 struct iw_request_info *info, 1067 struct iw_request_info *info,
1075 struct iw_param *data, char *extra) 1068 struct iw_param *data, char *extra)
1076{ 1069{
1077 struct wireless_dev *wdev = dev->ieee80211_ptr; 1070 struct wireless_dev *wdev = dev->ieee80211_ptr;
1078 1071
@@ -1102,21 +1095,19 @@ int cfg80211_wext_siwauth(struct net_device *dev,
1102 return -EOPNOTSUPP; 1095 return -EOPNOTSUPP;
1103 } 1096 }
1104} 1097}
1105EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth);
1106 1098
1107int cfg80211_wext_giwauth(struct net_device *dev, 1099static int cfg80211_wext_giwauth(struct net_device *dev,
1108 struct iw_request_info *info, 1100 struct iw_request_info *info,
1109 struct iw_param *data, char *extra) 1101 struct iw_param *data, char *extra)
1110{ 1102{
1111 /* XXX: what do we need? */ 1103 /* XXX: what do we need? */
1112 1104
1113 return -EOPNOTSUPP; 1105 return -EOPNOTSUPP;
1114} 1106}
1115EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
1116 1107
1117int cfg80211_wext_siwpower(struct net_device *dev, 1108static int cfg80211_wext_siwpower(struct net_device *dev,
1118 struct iw_request_info *info, 1109 struct iw_request_info *info,
1119 struct iw_param *wrq, char *extra) 1110 struct iw_param *wrq, char *extra)
1120{ 1111{
1121 struct wireless_dev *wdev = dev->ieee80211_ptr; 1112 struct wireless_dev *wdev = dev->ieee80211_ptr;
1122 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1113 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1160,11 +1151,10 @@ int cfg80211_wext_siwpower(struct net_device *dev,
1160 return 0; 1151 return 0;
1161 1152
1162} 1153}
1163EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower);
1164 1154
1165int cfg80211_wext_giwpower(struct net_device *dev, 1155static int cfg80211_wext_giwpower(struct net_device *dev,
1166 struct iw_request_info *info, 1156 struct iw_request_info *info,
1167 struct iw_param *wrq, char *extra) 1157 struct iw_param *wrq, char *extra)
1168{ 1158{
1169 struct wireless_dev *wdev = dev->ieee80211_ptr; 1159 struct wireless_dev *wdev = dev->ieee80211_ptr;
1170 1160
@@ -1172,7 +1162,6 @@ int cfg80211_wext_giwpower(struct net_device *dev,
1172 1162
1173 return 0; 1163 return 0;
1174} 1164}
1175EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
1176 1165
1177static int cfg80211_wds_wext_siwap(struct net_device *dev, 1166static int cfg80211_wds_wext_siwap(struct net_device *dev,
1178 struct iw_request_info *info, 1167 struct iw_request_info *info,
@@ -1218,9 +1207,9 @@ static int cfg80211_wds_wext_giwap(struct net_device *dev,
1218 return 0; 1207 return 0;
1219} 1208}
1220 1209
1221int cfg80211_wext_siwrate(struct net_device *dev, 1210static int cfg80211_wext_siwrate(struct net_device *dev,
1222 struct iw_request_info *info, 1211 struct iw_request_info *info,
1223 struct iw_param *rate, char *extra) 1212 struct iw_param *rate, char *extra)
1224{ 1213{
1225 struct wireless_dev *wdev = dev->ieee80211_ptr; 1214 struct wireless_dev *wdev = dev->ieee80211_ptr;
1226 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1215 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1268,11 +1257,10 @@ int cfg80211_wext_siwrate(struct net_device *dev,
1268 1257
1269 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask); 1258 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask);
1270} 1259}
1271EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate);
1272 1260
1273int cfg80211_wext_giwrate(struct net_device *dev, 1261static int cfg80211_wext_giwrate(struct net_device *dev,
1274 struct iw_request_info *info, 1262 struct iw_request_info *info,
1275 struct iw_param *rate, char *extra) 1263 struct iw_param *rate, char *extra)
1276{ 1264{
1277 struct wireless_dev *wdev = dev->ieee80211_ptr; 1265 struct wireless_dev *wdev = dev->ieee80211_ptr;
1278 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1266 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1308,10 +1296,9 @@ int cfg80211_wext_giwrate(struct net_device *dev,
1308 1296
1309 return 0; 1297 return 0;
1310} 1298}
1311EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate);
1312 1299
1313/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ 1300/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
1314struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) 1301static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1315{ 1302{
1316 struct wireless_dev *wdev = dev->ieee80211_ptr; 1303 struct wireless_dev *wdev = dev->ieee80211_ptr;
1317 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1304 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1376,11 +1363,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1376 1363
1377 return &wstats; 1364 return &wstats;
1378} 1365}
1379EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
1380 1366
1381int cfg80211_wext_siwap(struct net_device *dev, 1367static int cfg80211_wext_siwap(struct net_device *dev,
1382 struct iw_request_info *info, 1368 struct iw_request_info *info,
1383 struct sockaddr *ap_addr, char *extra) 1369 struct sockaddr *ap_addr, char *extra)
1384{ 1370{
1385 struct wireless_dev *wdev = dev->ieee80211_ptr; 1371 struct wireless_dev *wdev = dev->ieee80211_ptr;
1386 1372
@@ -1395,11 +1381,10 @@ int cfg80211_wext_siwap(struct net_device *dev,
1395 return -EOPNOTSUPP; 1381 return -EOPNOTSUPP;
1396 } 1382 }
1397} 1383}
1398EXPORT_SYMBOL_GPL(cfg80211_wext_siwap);
1399 1384
1400int cfg80211_wext_giwap(struct net_device *dev, 1385static int cfg80211_wext_giwap(struct net_device *dev,
1401 struct iw_request_info *info, 1386 struct iw_request_info *info,
1402 struct sockaddr *ap_addr, char *extra) 1387 struct sockaddr *ap_addr, char *extra)
1403{ 1388{
1404 struct wireless_dev *wdev = dev->ieee80211_ptr; 1389 struct wireless_dev *wdev = dev->ieee80211_ptr;
1405 1390
@@ -1414,11 +1399,10 @@ int cfg80211_wext_giwap(struct net_device *dev,
1414 return -EOPNOTSUPP; 1399 return -EOPNOTSUPP;
1415 } 1400 }
1416} 1401}
1417EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
1418 1402
1419int cfg80211_wext_siwessid(struct net_device *dev, 1403static int cfg80211_wext_siwessid(struct net_device *dev,
1420 struct iw_request_info *info, 1404 struct iw_request_info *info,
1421 struct iw_point *data, char *ssid) 1405 struct iw_point *data, char *ssid)
1422{ 1406{
1423 struct wireless_dev *wdev = dev->ieee80211_ptr; 1407 struct wireless_dev *wdev = dev->ieee80211_ptr;
1424 1408
@@ -1431,11 +1415,10 @@ int cfg80211_wext_siwessid(struct net_device *dev,
1431 return -EOPNOTSUPP; 1415 return -EOPNOTSUPP;
1432 } 1416 }
1433} 1417}
1434EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid);
1435 1418
1436int cfg80211_wext_giwessid(struct net_device *dev, 1419static int cfg80211_wext_giwessid(struct net_device *dev,
1437 struct iw_request_info *info, 1420 struct iw_request_info *info,
1438 struct iw_point *data, char *ssid) 1421 struct iw_point *data, char *ssid)
1439{ 1422{
1440 struct wireless_dev *wdev = dev->ieee80211_ptr; 1423 struct wireless_dev *wdev = dev->ieee80211_ptr;
1441 1424
@@ -1451,11 +1434,10 @@ int cfg80211_wext_giwessid(struct net_device *dev,
1451 return -EOPNOTSUPP; 1434 return -EOPNOTSUPP;
1452 } 1435 }
1453} 1436}
1454EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
1455 1437
1456int cfg80211_wext_siwpmksa(struct net_device *dev, 1438static int cfg80211_wext_siwpmksa(struct net_device *dev,
1457 struct iw_request_info *info, 1439 struct iw_request_info *info,
1458 struct iw_point *data, char *extra) 1440 struct iw_point *data, char *extra)
1459{ 1441{
1460 struct wireless_dev *wdev = dev->ieee80211_ptr; 1442 struct wireless_dev *wdev = dev->ieee80211_ptr;
1461 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1443 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1493,7 +1475,6 @@ int cfg80211_wext_siwpmksa(struct net_device *dev,
1493 return -EOPNOTSUPP; 1475 return -EOPNOTSUPP;
1494 } 1476 }
1495} 1477}
1496EXPORT_SYMBOL_GPL(cfg80211_wext_siwpmksa);
1497 1478
1498static const iw_handler cfg80211_handlers[] = { 1479static const iw_handler cfg80211_handlers[] = {
1499 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname, 1480 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,
diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h
index 20b3daef6964..5d766b0118e8 100644
--- a/net/wireless/wext-compat.h
+++ b/net/wireless/wext-compat.h
@@ -42,6 +42,14 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
42 struct iw_request_info *info, 42 struct iw_request_info *info,
43 struct iw_point *data, char *ssid); 43 struct iw_point *data, char *ssid);
44 44
45int cfg80211_wext_siwmlme(struct net_device *dev,
46 struct iw_request_info *info,
47 struct iw_point *data, char *extra);
48int cfg80211_wext_siwgenie(struct net_device *dev,
49 struct iw_request_info *info,
50 struct iw_point *data, char *extra);
51
52
45int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); 53int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq);
46 54
47 55
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 6fffe62d7c25..0d4b8c3033ff 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -9,6 +9,7 @@
9#include <linux/if_arp.h> 9#include <linux/if_arp.h>
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include <net/cfg80211.h> 11#include <net/cfg80211.h>
12#include <net/cfg80211-wext.h>
12#include "wext-compat.h" 13#include "wext-compat.h"
13#include "nl80211.h" 14#include "nl80211.h"
14 15
@@ -365,7 +366,6 @@ int cfg80211_wext_siwgenie(struct net_device *dev,
365 wdev_unlock(wdev); 366 wdev_unlock(wdev);
366 return err; 367 return err;
367} 368}
368EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie);
369 369
370int cfg80211_wext_siwmlme(struct net_device *dev, 370int cfg80211_wext_siwmlme(struct net_device *dev,
371 struct iw_request_info *info, 371 struct iw_request_info *info,
@@ -402,4 +402,3 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
402 402
403 return err; 403 return err;
404} 404}
405EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);