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.c405
-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.c194
-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, 727 insertions, 172 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..48260c2d092a 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,19 @@ 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 },
195 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
196 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
197 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
198 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
199 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
181}; 200};
182 201
183/* policy for the key attributes */ 202/* policy for the key attributes */
@@ -220,6 +239,12 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
220 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN }, 239 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
221}; 240};
222 241
242static const struct nla_policy
243nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
244 [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY,
245 .len = IEEE80211_MAX_SSID_LEN },
246};
247
223/* ifidx get helper */ 248/* ifidx get helper */
224static int nl80211_get_ifidx(struct netlink_callback *cb) 249static int nl80211_get_ifidx(struct netlink_callback *cb)
225{ 250{
@@ -703,11 +728,21 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
703 dev->wiphy.max_scan_ie_len); 728 dev->wiphy.max_scan_ie_len);
704 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, 729 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
705 dev->wiphy.max_sched_scan_ie_len); 730 dev->wiphy.max_sched_scan_ie_len);
731 NLA_PUT_U8(msg, NL80211_ATTR_MAX_MATCH_SETS,
732 dev->wiphy.max_match_sets);
706 733
707 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) 734 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
708 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); 735 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
709 if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) 736 if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
710 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); 737 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
738 if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD)
739 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD);
740 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)
741 NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT);
742 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS)
743 NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT);
744 if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)
745 NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP);
711 746
712 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, 747 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
713 sizeof(u32) * dev->wiphy.n_cipher_suites, 748 sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -850,6 +885,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
850 } 885 }
851 CMD(set_channel, SET_CHANNEL); 886 CMD(set_channel, SET_CHANNEL);
852 CMD(set_wds_peer, SET_WDS_PEER); 887 CMD(set_wds_peer, SET_WDS_PEER);
888 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
889 CMD(tdls_mgmt, TDLS_MGMT);
890 CMD(tdls_oper, TDLS_OPER);
891 }
853 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) 892 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
854 CMD(sched_scan_start, START_SCHED_SCAN); 893 CMD(sched_scan_start, START_SCHED_SCAN);
855 894
@@ -871,8 +910,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, 910 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
872 dev->wiphy.max_remain_on_channel_duration); 911 dev->wiphy.max_remain_on_channel_duration);
873 912
874 /* for now at least assume all drivers have it */ 913 if (dev->ops->mgmt_tx_cancel_wait)
875 if (dev->ops->mgmt_tx)
876 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); 914 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
877 915
878 if (mgmt_stypes) { 916 if (mgmt_stypes) {
@@ -1210,6 +1248,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1210 goto bad_res; 1248 goto bad_res;
1211 } 1249 }
1212 1250
1251 if (!netdev) {
1252 result = -EINVAL;
1253 goto bad_res;
1254 }
1255
1213 nla_for_each_nested(nl_txq_params, 1256 nla_for_each_nested(nl_txq_params,
1214 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], 1257 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
1215 rem_txq_params) { 1258 rem_txq_params) {
@@ -1222,6 +1265,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1222 goto bad_res; 1265 goto bad_res;
1223 1266
1224 result = rdev->ops->set_txq_params(&rdev->wiphy, 1267 result = rdev->ops->set_txq_params(&rdev->wiphy,
1268 netdev,
1225 &txq_params); 1269 &txq_params);
1226 if (result) 1270 if (result)
1227 goto bad_res; 1271 goto bad_res;
@@ -1985,7 +2029,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1985 struct beacon_parameters params; 2029 struct beacon_parameters params;
1986 int haveinfo = 0, err; 2030 int haveinfo = 0, err;
1987 2031
1988 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 2032 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) ||
2033 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) ||
2034 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
2035 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]))
1989 return -EINVAL; 2036 return -EINVAL;
1990 2037
1991 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2038 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
@@ -2011,6 +2058,49 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
2011 if (err) 2058 if (err)
2012 return err; 2059 return err;
2013 2060
2061 /*
2062 * In theory, some of these attributes could be required for
2063 * NEW_BEACON, but since they were not used when the command was
2064 * originally added, keep them optional for old user space
2065 * programs to work with drivers that do not need the additional
2066 * information.
2067 */
2068 if (info->attrs[NL80211_ATTR_SSID]) {
2069 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
2070 params.ssid_len =
2071 nla_len(info->attrs[NL80211_ATTR_SSID]);
2072 if (params.ssid_len == 0 ||
2073 params.ssid_len > IEEE80211_MAX_SSID_LEN)
2074 return -EINVAL;
2075 }
2076
2077 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
2078 params.hidden_ssid = nla_get_u32(
2079 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
2080 if (params.hidden_ssid !=
2081 NL80211_HIDDEN_SSID_NOT_IN_USE &&
2082 params.hidden_ssid !=
2083 NL80211_HIDDEN_SSID_ZERO_LEN &&
2084 params.hidden_ssid !=
2085 NL80211_HIDDEN_SSID_ZERO_CONTENTS)
2086 return -EINVAL;
2087 }
2088
2089 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
2090
2091 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
2092 params.auth_type = nla_get_u32(
2093 info->attrs[NL80211_ATTR_AUTH_TYPE]);
2094 if (!nl80211_valid_auth_type(params.auth_type))
2095 return -EINVAL;
2096 } else
2097 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
2098
2099 err = nl80211_crypto_settings(rdev, info, &params.crypto,
2100 NL80211_MAX_NR_CIPHER_SUITES);
2101 if (err)
2102 return err;
2103
2014 call = rdev->ops->add_beacon; 2104 call = rdev->ops->add_beacon;
2015 break; 2105 break;
2016 case NL80211_CMD_SET_BEACON: 2106 case NL80211_CMD_SET_BEACON:
@@ -2041,6 +2131,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
2041 if (!haveinfo) 2131 if (!haveinfo)
2042 return -EINVAL; 2132 return -EINVAL;
2043 2133
2134 if (info->attrs[NL80211_ATTR_IE]) {
2135 params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2136 params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2137 }
2138
2139 if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) {
2140 params.proberesp_ies =
2141 nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
2142 params.proberesp_ies_len =
2143 nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
2144 }
2145
2146 if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
2147 params.assocresp_ies =
2148 nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2149 params.assocresp_ies_len =
2150 nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2151 }
2152
2044 err = call(&rdev->wiphy, dev, &params); 2153 err = call(&rdev->wiphy, dev, &params);
2045 if (!err && params.interval) 2154 if (!err && params.interval)
2046 wdev->beacon_interval = params.interval; 2155 wdev->beacon_interval = params.interval;
@@ -2235,8 +2344,16 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2235 2344
2236 nla_nest_end(msg, bss_param); 2345 nla_nest_end(msg, bss_param);
2237 } 2346 }
2347 if (sinfo->filled & STATION_INFO_STA_FLAGS)
2348 NLA_PUT(msg, NL80211_STA_INFO_STA_FLAGS,
2349 sizeof(struct nl80211_sta_flag_update),
2350 &sinfo->sta_flags);
2238 nla_nest_end(msg, sinfoattr); 2351 nla_nest_end(msg, sinfoattr);
2239 2352
2353 if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
2354 NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
2355 sinfo->assoc_req_ies);
2356
2240 return genlmsg_end(msg, hdr); 2357 return genlmsg_end(msg, hdr);
2241 2358
2242 nla_put_failure: 2359 nla_put_failure:
@@ -2264,6 +2381,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
2264 } 2381 }
2265 2382
2266 while (1) { 2383 while (1) {
2384 memset(&sinfo, 0, sizeof(sinfo));
2267 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, 2385 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
2268 mac_addr, &sinfo); 2386 mac_addr, &sinfo);
2269 if (err == -ENOENT) 2387 if (err == -ENOENT)
@@ -2416,18 +2534,25 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2416 break; 2534 break;
2417 case NL80211_IFTYPE_P2P_CLIENT: 2535 case NL80211_IFTYPE_P2P_CLIENT:
2418 case NL80211_IFTYPE_STATION: 2536 case NL80211_IFTYPE_STATION:
2419 /* disallow everything but AUTHORIZED flag */ 2537 /* disallow things sta doesn't support */
2420 if (params.plink_action) 2538 if (params.plink_action)
2421 err = -EINVAL; 2539 err = -EINVAL;
2422 if (params.vlan) 2540 if (params.vlan)
2423 err = -EINVAL; 2541 err = -EINVAL;
2424 if (params.supported_rates) 2542 if (params.supported_rates &&
2543 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
2425 err = -EINVAL; 2544 err = -EINVAL;
2426 if (params.ht_capa) 2545 if (params.ht_capa)
2427 err = -EINVAL; 2546 err = -EINVAL;
2428 if (params.listen_interval >= 0) 2547 if (params.listen_interval >= 0)
2429 err = -EINVAL; 2548 err = -EINVAL;
2430 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) 2549 if (params.sta_flags_mask &
2550 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
2551 BIT(NL80211_STA_FLAG_TDLS_PEER)))
2552 err = -EINVAL;
2553 /* can't change the TDLS bit */
2554 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
2555 (params.sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)))
2431 err = -EINVAL; 2556 err = -EINVAL;
2432 break; 2557 break;
2433 case NL80211_IFTYPE_MESH_POINT: 2558 case NL80211_IFTYPE_MESH_POINT:
@@ -2465,6 +2590,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2465 return err; 2590 return err;
2466} 2591}
2467 2592
2593static struct nla_policy
2594nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
2595 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
2596 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
2597};
2598
2468static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) 2599static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2469{ 2600{
2470 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2601 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2510,10 +2641,50 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2510 if (parse_station_flags(info, &params)) 2641 if (parse_station_flags(info, &params))
2511 return -EINVAL; 2642 return -EINVAL;
2512 2643
2644 /* parse WME attributes if sta is WME capable */
2645 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
2646 (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) &&
2647 info->attrs[NL80211_ATTR_STA_WME]) {
2648 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
2649 struct nlattr *nla;
2650
2651 nla = info->attrs[NL80211_ATTR_STA_WME];
2652 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
2653 nl80211_sta_wme_policy);
2654 if (err)
2655 return err;
2656
2657 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
2658 params.uapsd_queues =
2659 nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]);
2660 if (params.uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
2661 return -EINVAL;
2662
2663 if (tb[NL80211_STA_WME_MAX_SP])
2664 params.max_sp =
2665 nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
2666
2667 if (params.max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
2668 return -EINVAL;
2669
2670 params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
2671 }
2672
2513 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2673 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2514 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2674 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2515 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && 2675 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
2516 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 2676 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO &&
2677 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
2678 return -EINVAL;
2679
2680 /*
2681 * Only managed stations can add TDLS peers, and only when the
2682 * wiphy supports external TDLS setup.
2683 */
2684 if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION &&
2685 !((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
2686 (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
2687 (rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)))
2517 return -EINVAL; 2688 return -EINVAL;
2518 2689
2519 err = get_vlan(info, rdev, &params.vlan); 2690 err = get_vlan(info, rdev, &params.vlan);
@@ -2955,6 +3126,10 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
2955 cur_params.dot11MeshHWMPnetDiameterTraversalTime); 3126 cur_params.dot11MeshHWMPnetDiameterTraversalTime);
2956 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, 3127 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
2957 cur_params.dot11MeshHWMPRootMode); 3128 cur_params.dot11MeshHWMPRootMode);
3129 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3130 cur_params.dot11MeshHWMPRannInterval);
3131 NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3132 cur_params.dot11MeshGateAnnouncementProtocol);
2958 nla_nest_end(msg, pinfoattr); 3133 nla_nest_end(msg, pinfoattr);
2959 genlmsg_end(msg, hdr); 3134 genlmsg_end(msg, hdr);
2960 return genlmsg_reply(msg, info); 3135 return genlmsg_reply(msg, info);
@@ -2982,6 +3157,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
2982 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, 3157 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
2983 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, 3158 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
2984 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, 3159 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
3160 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
3161 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
3162 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
2985}; 3163};
2986 3164
2987static const struct nla_policy 3165static const struct nla_policy
@@ -3060,6 +3238,14 @@ do {\
3060 dot11MeshHWMPRootMode, mask, 3238 dot11MeshHWMPRootMode, mask,
3061 NL80211_MESHCONF_HWMP_ROOTMODE, 3239 NL80211_MESHCONF_HWMP_ROOTMODE,
3062 nla_get_u8); 3240 nla_get_u8);
3241 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3242 dot11MeshHWMPRannInterval, mask,
3243 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3244 nla_get_u16);
3245 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3246 dot11MeshGateAnnouncementProtocol, mask,
3247 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3248 nla_get_u8);
3063 if (mask_out) 3249 if (mask_out)
3064 *mask_out = mask; 3250 *mask_out = mask;
3065 3251
@@ -3477,6 +3663,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3477 } 3663 }
3478 } 3664 }
3479 3665
3666 request->no_cck =
3667 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
3668
3480 request->dev = dev; 3669 request->dev = dev;
3481 request->wiphy = &rdev->wiphy; 3670 request->wiphy = &rdev->wiphy;
3482 3671
@@ -3503,10 +3692,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3503 struct net_device *dev = info->user_ptr[1]; 3692 struct net_device *dev = info->user_ptr[1];
3504 struct nlattr *attr; 3693 struct nlattr *attr;
3505 struct wiphy *wiphy; 3694 struct wiphy *wiphy;
3506 int err, tmp, n_ssids = 0, n_channels, i; 3695 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i;
3507 u32 interval; 3696 u32 interval;
3508 enum ieee80211_band band; 3697 enum ieee80211_band band;
3509 size_t ie_len; 3698 size_t ie_len;
3699 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
3510 3700
3511 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || 3701 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
3512 !rdev->ops->sched_scan_start) 3702 !rdev->ops->sched_scan_start)
@@ -3545,6 +3735,15 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3545 if (n_ssids > wiphy->max_sched_scan_ssids) 3735 if (n_ssids > wiphy->max_sched_scan_ssids)
3546 return -EINVAL; 3736 return -EINVAL;
3547 3737
3738 if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH])
3739 nla_for_each_nested(attr,
3740 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
3741 tmp)
3742 n_match_sets++;
3743
3744 if (n_match_sets > wiphy->max_match_sets)
3745 return -EINVAL;
3746
3548 if (info->attrs[NL80211_ATTR_IE]) 3747 if (info->attrs[NL80211_ATTR_IE])
3549 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3748 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3550 else 3749 else
@@ -3562,6 +3761,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3562 3761
3563 request = kzalloc(sizeof(*request) 3762 request = kzalloc(sizeof(*request)
3564 + sizeof(*request->ssids) * n_ssids 3763 + sizeof(*request->ssids) * n_ssids
3764 + sizeof(*request->match_sets) * n_match_sets
3565 + sizeof(*request->channels) * n_channels 3765 + sizeof(*request->channels) * n_channels
3566 + ie_len, GFP_KERNEL); 3766 + ie_len, GFP_KERNEL);
3567 if (!request) { 3767 if (!request) {
@@ -3579,6 +3779,18 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3579 request->ie = (void *)(request->channels + n_channels); 3779 request->ie = (void *)(request->channels + n_channels);
3580 } 3780 }
3581 3781
3782 if (n_match_sets) {
3783 if (request->ie)
3784 request->match_sets = (void *)(request->ie + ie_len);
3785 else if (request->ssids)
3786 request->match_sets =
3787 (void *)(request->ssids + n_ssids);
3788 else
3789 request->match_sets =
3790 (void *)(request->channels + n_channels);
3791 }
3792 request->n_match_sets = n_match_sets;
3793
3582 i = 0; 3794 i = 0;
3583 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { 3795 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3584 /* user specified, bail out if channel not found */ 3796 /* user specified, bail out if channel not found */
@@ -3643,6 +3855,31 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3643 } 3855 }
3644 } 3856 }
3645 3857
3858 i = 0;
3859 if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
3860 nla_for_each_nested(attr,
3861 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
3862 tmp) {
3863 struct nlattr *ssid;
3864
3865 nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
3866 nla_data(attr), nla_len(attr),
3867 nl80211_match_policy);
3868 ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID];
3869 if (ssid) {
3870 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
3871 err = -EINVAL;
3872 goto out_free;
3873 }
3874 memcpy(request->match_sets[i].ssid.ssid,
3875 nla_data(ssid), nla_len(ssid));
3876 request->match_sets[i].ssid.ssid_len =
3877 nla_len(ssid);
3878 }
3879 i++;
3880 }
3881 }
3882
3646 if (info->attrs[NL80211_ATTR_IE]) { 3883 if (info->attrs[NL80211_ATTR_IE]) {
3647 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3884 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3648 memcpy((void *)request->ie, 3885 memcpy((void *)request->ie,
@@ -3935,22 +4172,6 @@ static bool nl80211_valid_wpa_versions(u32 wpa_versions)
3935 NL80211_WPA_VERSION_2)); 4172 NL80211_WPA_VERSION_2));
3936} 4173}
3937 4174
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) 4175static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3955{ 4176{
3956 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4177 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4083,7 +4304,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4083 memcpy(settings->ciphers_pairwise, data, len); 4304 memcpy(settings->ciphers_pairwise, data, len);
4084 4305
4085 for (i = 0; i < settings->n_ciphers_pairwise; i++) 4306 for (i = 0; i < settings->n_ciphers_pairwise; i++)
4086 if (!nl80211_valid_cipher_suite( 4307 if (!cfg80211_supported_cipher_suite(
4308 &rdev->wiphy,
4087 settings->ciphers_pairwise[i])) 4309 settings->ciphers_pairwise[i]))
4088 return -EINVAL; 4310 return -EINVAL;
4089 } 4311 }
@@ -4091,7 +4313,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4091 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) { 4313 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
4092 settings->cipher_group = 4314 settings->cipher_group =
4093 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]); 4315 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
4094 if (!nl80211_valid_cipher_suite(settings->cipher_group)) 4316 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
4317 settings->cipher_group))
4095 return -EINVAL; 4318 return -EINVAL;
4096 } 4319 }
4097 4320
@@ -4104,7 +4327,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4104 4327
4105 if (info->attrs[NL80211_ATTR_AKM_SUITES]) { 4328 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
4106 void *data; 4329 void *data;
4107 int len, i; 4330 int len;
4108 4331
4109 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]); 4332 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
4110 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]); 4333 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
@@ -4117,10 +4340,6 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4117 return -EINVAL; 4340 return -EINVAL;
4118 4341
4119 memcpy(settings->akm_suites, data, len); 4342 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 } 4343 }
4125 4344
4126 return 0; 4345 return 0;
@@ -4339,8 +4558,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4339 4558
4340 wiphy = &rdev->wiphy; 4559 wiphy = &rdev->wiphy;
4341 4560
4342 if (info->attrs[NL80211_ATTR_MAC]) 4561 if (info->attrs[NL80211_ATTR_MAC]) {
4343 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 4562 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
4563
4564 if (!is_valid_ether_addr(ibss.bssid))
4565 return -EINVAL;
4566 }
4344 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 4567 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
4345 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 4568 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
4346 4569
@@ -4777,6 +5000,57 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
4777 return rdev->ops->flush_pmksa(&rdev->wiphy, dev); 5000 return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
4778} 5001}
4779 5002
5003static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
5004{
5005 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5006 struct net_device *dev = info->user_ptr[1];
5007 u8 action_code, dialog_token;
5008 u16 status_code;
5009 u8 *peer;
5010
5011 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
5012 !rdev->ops->tdls_mgmt)
5013 return -EOPNOTSUPP;
5014
5015 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
5016 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
5017 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
5018 !info->attrs[NL80211_ATTR_IE] ||
5019 !info->attrs[NL80211_ATTR_MAC])
5020 return -EINVAL;
5021
5022 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
5023 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
5024 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
5025 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
5026
5027 return rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
5028 dialog_token, status_code,
5029 nla_data(info->attrs[NL80211_ATTR_IE]),
5030 nla_len(info->attrs[NL80211_ATTR_IE]));
5031}
5032
5033static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
5034{
5035 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5036 struct net_device *dev = info->user_ptr[1];
5037 enum nl80211_tdls_operation operation;
5038 u8 *peer;
5039
5040 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
5041 !rdev->ops->tdls_oper)
5042 return -EOPNOTSUPP;
5043
5044 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
5045 !info->attrs[NL80211_ATTR_MAC])
5046 return -EINVAL;
5047
5048 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
5049 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
5050
5051 return rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, operation);
5052}
5053
4780static int nl80211_remain_on_channel(struct sk_buff *skb, 5054static int nl80211_remain_on_channel(struct sk_buff *skb,
4781 struct genl_info *info) 5055 struct genl_info *info)
4782{ 5056{
@@ -4997,6 +5271,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4997 struct sk_buff *msg; 5271 struct sk_buff *msg;
4998 unsigned int wait = 0; 5272 unsigned int wait = 0;
4999 bool offchan; 5273 bool offchan;
5274 bool no_cck;
5000 5275
5001 if (!info->attrs[NL80211_ATTR_FRAME] || 5276 if (!info->attrs[NL80211_ATTR_FRAME] ||
5002 !info->attrs[NL80211_ATTR_WIPHY_FREQ]) 5277 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
@@ -5033,6 +5308,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5033 5308
5034 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 5309 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
5035 5310
5311 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
5312
5036 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 5313 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
5037 chan = rdev_freq_to_chan(rdev, freq, channel_type); 5314 chan = rdev_freq_to_chan(rdev, freq, channel_type);
5038 if (chan == NULL) 5315 if (chan == NULL)
@@ -5053,7 +5330,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5053 channel_type_valid, wait, 5330 channel_type_valid, wait,
5054 nla_data(info->attrs[NL80211_ATTR_FRAME]), 5331 nla_data(info->attrs[NL80211_ATTR_FRAME]),
5055 nla_len(info->attrs[NL80211_ATTR_FRAME]), 5332 nla_len(info->attrs[NL80211_ATTR_FRAME]),
5056 &cookie); 5333 no_cck, &cookie);
5057 if (err) 5334 if (err)
5058 goto free_msg; 5335 goto free_msg;
5059 5336
@@ -6089,6 +6366,22 @@ static struct genl_ops nl80211_ops[] = {
6089 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 6366 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6090 NL80211_FLAG_NEED_RTNL, 6367 NL80211_FLAG_NEED_RTNL,
6091 }, 6368 },
6369 {
6370 .cmd = NL80211_CMD_TDLS_MGMT,
6371 .doit = nl80211_tdls_mgmt,
6372 .policy = nl80211_policy,
6373 .flags = GENL_ADMIN_PERM,
6374 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6375 NL80211_FLAG_NEED_RTNL,
6376 },
6377 {
6378 .cmd = NL80211_CMD_TDLS_OPER,
6379 .doit = nl80211_tdls_oper,
6380 .policy = nl80211_policy,
6381 .flags = GENL_ADMIN_PERM,
6382 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6383 NL80211_FLAG_NEED_RTNL,
6384 },
6092}; 6385};
6093 6386
6094static struct genl_multicast_group nl80211_mlme_mcgrp = { 6387static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -7078,6 +7371,52 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
7078 nlmsg_free(msg); 7371 nlmsg_free(msg);
7079} 7372}
7080 7373
7374void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
7375 struct net_device *netdev, int index,
7376 const u8 *bssid, bool preauth, gfp_t gfp)
7377{
7378 struct sk_buff *msg;
7379 struct nlattr *attr;
7380 void *hdr;
7381
7382 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
7383 if (!msg)
7384 return;
7385
7386 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
7387 if (!hdr) {
7388 nlmsg_free(msg);
7389 return;
7390 }
7391
7392 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
7393 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
7394
7395 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
7396 if (!attr)
7397 goto nla_put_failure;
7398
7399 NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index);
7400 NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid);
7401 if (preauth)
7402 NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH);
7403
7404 nla_nest_end(msg, attr);
7405
7406 if (genlmsg_end(msg, hdr) < 0) {
7407 nlmsg_free(msg);
7408 return;
7409 }
7410
7411 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7412 nl80211_mlme_mcgrp.id, gfp);
7413 return;
7414
7415 nla_put_failure:
7416 genlmsg_cancel(msg, hdr);
7417 nlmsg_free(msg);
7418}
7419
7081void 7420void
7082nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 7421nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
7083 struct net_device *netdev, const u8 *peer, 7422 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..2f178f73943f 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;
@@ -391,8 +396,9 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
391 } 396 }
392 break; 397 break;
393 case cpu_to_le16(0): 398 case cpu_to_le16(0):
394 if (iftype != NL80211_IFTYPE_ADHOC) 399 if (iftype != NL80211_IFTYPE_ADHOC &&
395 return -1; 400 iftype != NL80211_IFTYPE_STATION)
401 return -1;
396 break; 402 break;
397 } 403 }
398 404
@@ -512,10 +518,9 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
512 if (head_need) 518 if (head_need)
513 skb_orphan(skb); 519 skb_orphan(skb);
514 520
515 if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) { 521 if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC))
516 pr_err("failed to reallocate Tx buffer\n");
517 return -ENOMEM; 522 return -ENOMEM;
518 } 523
519 skb->truesize += head_need; 524 skb->truesize += head_need;
520 } 525 }
521 526
@@ -1044,3 +1049,170 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
1044 1049
1045 return 0; 1050 return 0;
1046} 1051}
1052
1053u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
1054 struct ieee802_11_elems *elems,
1055 u64 filter, u32 crc)
1056{
1057 size_t left = len;
1058 u8 *pos = start;
1059 bool calc_crc = filter != 0;
1060
1061 memset(elems, 0, sizeof(*elems));
1062 elems->ie_start = start;
1063 elems->total_len = len;
1064
1065 while (left >= 2) {
1066 u8 id, elen;
1067
1068 id = *pos++;
1069 elen = *pos++;
1070 left -= 2;
1071
1072 if (elen > left)
1073 break;
1074
1075 if (calc_crc && id < 64 && (filter & (1ULL << id)))
1076 crc = crc32_be(crc, pos - 2, elen + 2);
1077
1078 switch (id) {
1079 case WLAN_EID_SSID:
1080 elems->ssid = pos;
1081 elems->ssid_len = elen;
1082 break;
1083 case WLAN_EID_SUPP_RATES:
1084 elems->supp_rates = pos;
1085 elems->supp_rates_len = elen;
1086 break;
1087 case WLAN_EID_FH_PARAMS:
1088 elems->fh_params = pos;
1089 elems->fh_params_len = elen;
1090 break;
1091 case WLAN_EID_DS_PARAMS:
1092 elems->ds_params = pos;
1093 elems->ds_params_len = elen;
1094 break;
1095 case WLAN_EID_CF_PARAMS:
1096 elems->cf_params = pos;
1097 elems->cf_params_len = elen;
1098 break;
1099 case WLAN_EID_TIM:
1100 if (elen >= sizeof(struct ieee80211_tim_ie)) {
1101 elems->tim = (void *)pos;
1102 elems->tim_len = elen;
1103 }
1104 break;
1105 case WLAN_EID_IBSS_PARAMS:
1106 elems->ibss_params = pos;
1107 elems->ibss_params_len = elen;
1108 break;
1109 case WLAN_EID_CHALLENGE:
1110 elems->challenge = pos;
1111 elems->challenge_len = elen;
1112 break;
1113 case WLAN_EID_VENDOR_SPECIFIC:
1114 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
1115 pos[2] == 0xf2) {
1116 /* Microsoft OUI (00:50:F2) */
1117
1118 if (calc_crc)
1119 crc = crc32_be(crc, pos - 2, elen + 2);
1120
1121 if (pos[3] == 1) {
1122 /* OUI Type 1 - WPA IE */
1123 elems->wpa = pos;
1124 elems->wpa_len = elen;
1125 } else if (elen >= 5 && pos[3] == 2) {
1126 /* OUI Type 2 - WMM IE */
1127 if (pos[4] == 0) {
1128 elems->wmm_info = pos;
1129 elems->wmm_info_len = elen;
1130 } else if (pos[4] == 1) {
1131 elems->wmm_param = pos;
1132 elems->wmm_param_len = elen;
1133 }
1134 }
1135 }
1136 break;
1137 case WLAN_EID_RSN:
1138 elems->rsn = pos;
1139 elems->rsn_len = elen;
1140 break;
1141 case WLAN_EID_ERP_INFO:
1142 elems->erp_info = pos;
1143 elems->erp_info_len = elen;
1144 break;
1145 case WLAN_EID_EXT_SUPP_RATES:
1146 elems->ext_supp_rates = pos;
1147 elems->ext_supp_rates_len = elen;
1148 break;
1149 case WLAN_EID_HT_CAPABILITY:
1150 if (elen >= sizeof(struct ieee80211_ht_cap))
1151 elems->ht_cap_elem = (void *)pos;
1152 break;
1153 case WLAN_EID_HT_INFORMATION:
1154 if (elen >= sizeof(struct ieee80211_ht_info))
1155 elems->ht_info_elem = (void *)pos;
1156 break;
1157 case WLAN_EID_MESH_ID:
1158 elems->mesh_id = pos;
1159 elems->mesh_id_len = elen;
1160 break;
1161 case WLAN_EID_MESH_CONFIG:
1162 if (elen >= sizeof(struct ieee80211_meshconf_ie))
1163 elems->mesh_config = (void *)pos;
1164 break;
1165 case WLAN_EID_PEER_MGMT:
1166 elems->peering = pos;
1167 elems->peering_len = elen;
1168 break;
1169 case WLAN_EID_PREQ:
1170 elems->preq = pos;
1171 elems->preq_len = elen;
1172 break;
1173 case WLAN_EID_PREP:
1174 elems->prep = pos;
1175 elems->prep_len = elen;
1176 break;
1177 case WLAN_EID_PERR:
1178 elems->perr = pos;
1179 elems->perr_len = elen;
1180 break;
1181 case WLAN_EID_RANN:
1182 if (elen >= sizeof(struct ieee80211_rann_ie))
1183 elems->rann = (void *)pos;
1184 break;
1185 case WLAN_EID_CHANNEL_SWITCH:
1186 elems->ch_switch_elem = pos;
1187 elems->ch_switch_elem_len = elen;
1188 break;
1189 case WLAN_EID_QUIET:
1190 if (!elems->quiet_elem) {
1191 elems->quiet_elem = pos;
1192 elems->quiet_elem_len = elen;
1193 }
1194 elems->num_of_quiet_elem++;
1195 break;
1196 case WLAN_EID_COUNTRY:
1197 elems->country_elem = pos;
1198 elems->country_elem_len = elen;
1199 break;
1200 case WLAN_EID_PWR_CONSTRAINT:
1201 elems->pwr_constr_elem = pos;
1202 elems->pwr_constr_elem_len = elen;
1203 break;
1204 case WLAN_EID_TIMEOUT_INTERVAL:
1205 elems->timeout_int = pos;
1206 elems->timeout_int_len = elen;
1207 break;
1208 default:
1209 break;
1210 }
1211
1212 left -= elen;
1213 pos += elen;
1214 }
1215
1216 return crc;
1217}
1218EXPORT_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);