diff options
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.c | 2 | ||||
-rw-r--r-- | net/wireless/core.h | 6 | ||||
-rw-r--r-- | net/wireless/lib80211.c | 15 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_ccmp.c | 2 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_tkip.c | 4 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_wep.c | 4 | ||||
-rw-r--r-- | net/wireless/mesh.c | 3 | ||||
-rw-r--r-- | net/wireless/mlme.c | 16 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 405 | ||||
-rw-r--r-- | net/wireless/nl80211.h | 4 | ||||
-rw-r--r-- | net/wireless/reg.c | 47 | ||||
-rw-r--r-- | net/wireless/reg.h | 2 | ||||
-rw-r--r-- | net/wireless/scan.c | 28 | ||||
-rw-r--r-- | net/wireless/sme.c | 19 | ||||
-rw-r--r-- | net/wireless/util.c | 194 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 137 | ||||
-rw-r--r-- | net/wireless/wext-compat.h | 8 | ||||
-rw-r--r-- | net/wireless/wext-sme.c | 3 |
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 | ||
281 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy); | 281 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy); |
282 | void wiphy_update_regulatory(struct wiphy *wiphy, | ||
283 | enum nl80211_reg_initiator setby); | ||
284 | 282 | ||
285 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev); | 283 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev); |
286 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, | 284 | void 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 */ |
383 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, | 382 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, |
@@ -408,6 +407,7 @@ void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); | |||
408 | bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); | 407 | bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); |
409 | 408 | ||
410 | /* internal helpers */ | 409 | /* internal helpers */ |
410 | bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); | ||
411 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | 411 | int 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 { | |||
41 | static LIST_HEAD(lib80211_crypto_algs); | 41 | static LIST_HEAD(lib80211_crypto_algs); |
42 | static DEFINE_SPINLOCK(lib80211_crypto_lock); | 42 | static DEFINE_SPINLOCK(lib80211_crypto_lock); |
43 | 43 | ||
44 | static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, | ||
45 | int force); | ||
46 | static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info); | ||
47 | static void lib80211_crypt_deinit_handler(unsigned long data); | ||
48 | |||
44 | const char *print_ssid(char *buf, const char *ssid, u8 ssid_len) | 49 | const 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 | } |
112 | EXPORT_SYMBOL(lib80211_crypt_info_free); | 117 | EXPORT_SYMBOL(lib80211_crypt_info_free); |
113 | 118 | ||
114 | void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force) | 119 | static 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 | } |
134 | EXPORT_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 */ |
137 | void lib80211_crypt_quiescing(struct lib80211_crypt_info *info) | 142 | static 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 | } |
145 | EXPORT_SYMBOL(lib80211_crypt_quiescing); | ||
146 | 150 | ||
147 | void lib80211_crypt_deinit_handler(unsigned long data) | 151 | static 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 | } |
163 | EXPORT_SYMBOL(lib80211_crypt_deinit_handler); | ||
164 | 167 | ||
165 | void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, | 168 | void 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 | ||
54 | const struct mesh_setup default_mesh_setup = { | 57 | const 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 | ||
997 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | 998 | bool 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 | } |
1097 | EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); | 1098 | EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); |
1099 | |||
1100 | void 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 | } | ||
1109 | EXPORT_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 | ||
26 | static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type); | ||
27 | static 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 | |||
26 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | 32 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, |
27 | struct genl_info *info); | 33 | struct genl_info *info); |
28 | static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, | 34 | static 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 | ||
242 | static const struct nla_policy | ||
243 | nl80211_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 */ |
224 | static int nl80211_get_ifidx(struct netlink_callback *cb) | 249 | static 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, ¶ms.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, ¶ms); | 2153 | err = call(&rdev->wiphy, dev, ¶ms); |
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 | ||
2593 | static struct nla_policy | ||
2594 | nl80211_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 | |||
2468 | static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | 2599 | static 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, ¶ms)) | 2641 | if (parse_station_flags(info, ¶ms)) |
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, ¶ms.vlan); | 2690 | err = get_vlan(info, rdev, ¶ms.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 | ||
2987 | static const struct nla_policy | 3165 | static 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 | ||
3938 | static bool nl80211_valid_akm_suite(u32 akm) | ||
3939 | { | ||
3940 | return akm == WLAN_AKM_SUITE_8021X || | ||
3941 | akm == WLAN_AKM_SUITE_PSK; | ||
3942 | } | ||
3943 | |||
3944 | static 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 | |||
3954 | static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | 4175 | static 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 | ||
5003 | static 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 | |||
5033 | static 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 | |||
4780 | static int nl80211_remain_on_channel(struct sk_buff *skb, | 5054 | static 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 | ||
6094 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 6387 | static 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 | ||
7374 | void 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 | |||
7081 | void | 7420 | void |
7082 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | 7421 | nl80211_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 | ||
116 | void 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 | ||
916 | static 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 | |||
924 | static void handle_reg_beacon(struct wiphy *wiphy, | 915 | static 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 | ||
1123 | void wiphy_update_regulatory(struct wiphy *wiphy, | 1114 | static 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 | ||
1135 | void regulatory_update(struct wiphy *wiphy, | ||
1136 | enum nl80211_reg_initiator setby) | ||
1137 | { | ||
1138 | mutex_lock(®_mutex); | ||
1139 | wiphy_update_regulatory(wiphy, setby); | ||
1140 | mutex_unlock(®_mutex); | ||
1141 | } | ||
1142 | |||
1143 | static 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 | |||
1142 | static void handle_channel_custom(struct wiphy *wiphy, | 1151 | static 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: | |||
2188 | static void reg_timeout_work(struct work_struct *work) | 2197 | static 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 | ||
17 | int set_regdom(const struct ieee80211_regdomain *rd); | 17 | int set_regdom(const struct ieee80211_regdomain *rd); |
18 | 18 | ||
19 | void 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 | } |
228 | EXPORT_SYMBOL(cfg80211_find_ie); | 229 | EXPORT_SYMBOL(cfg80211_find_ie); |
229 | 230 | ||
231 | const 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 | } | ||
256 | EXPORT_SYMBOL(cfg80211_find_vendor_ie); | ||
257 | |||
230 | static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) | 258 | static 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 | ||
154 | bool 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 | |||
153 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | 163 | int 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 | |||
1053 | u32 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 | } | ||
1218 | EXPORT_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 | } |
364 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag); | 365 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag); |
365 | 366 | ||
366 | int cfg80211_wext_siwretry(struct net_device *dev, | 367 | static 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 | } |
405 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry); | ||
406 | 406 | ||
407 | int cfg80211_wext_giwretry(struct net_device *dev, | 407 | int 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 | ||
596 | int cfg80211_wext_siwencode(struct net_device *dev, | 596 | static 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, ¶ms); | 653 | idx, ¶ms); |
654 | } | 654 | } |
655 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode); | ||
656 | 655 | ||
657 | int cfg80211_wext_siwencodeext(struct net_device *dev, | 656 | static 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, ¶ms); | 744 | idx, ¶ms); |
746 | } | 745 | } |
747 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext); | ||
748 | 746 | ||
749 | int cfg80211_wext_giwencode(struct net_device *dev, | 747 | static 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 | } |
785 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); | ||
786 | 783 | ||
787 | int cfg80211_wext_siwfreq(struct net_device *dev, | 784 | static 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 | } |
818 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq); | ||
819 | 815 | ||
820 | int cfg80211_wext_giwfreq(struct net_device *dev, | 816 | static 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 | } |
839 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq); | ||
840 | 835 | ||
841 | int cfg80211_wext_siwtxpower(struct net_device *dev, | 836 | static 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 | } |
892 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower); | ||
893 | 887 | ||
894 | int cfg80211_wext_giwtxpower(struct net_device *dev, | 888 | static 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 | } |
922 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower); | ||
923 | 916 | ||
924 | static int cfg80211_set_auth_alg(struct wireless_dev *wdev, | 917 | static 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 | ||
1073 | int cfg80211_wext_siwauth(struct net_device *dev, | 1066 | static 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 | } |
1105 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth); | ||
1106 | 1098 | ||
1107 | int cfg80211_wext_giwauth(struct net_device *dev, | 1099 | static 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 | } |
1115 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth); | ||
1116 | 1107 | ||
1117 | int cfg80211_wext_siwpower(struct net_device *dev, | 1108 | static 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 | } |
1163 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower); | ||
1164 | 1154 | ||
1165 | int cfg80211_wext_giwpower(struct net_device *dev, | 1155 | static 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 | } |
1175 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); | ||
1176 | 1165 | ||
1177 | static int cfg80211_wds_wext_siwap(struct net_device *dev, | 1166 | static 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 | ||
1221 | int cfg80211_wext_siwrate(struct net_device *dev, | 1210 | static 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 | } |
1271 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate); | ||
1272 | 1260 | ||
1273 | int cfg80211_wext_giwrate(struct net_device *dev, | 1261 | static 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 | } |
1311 | EXPORT_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 */ |
1314 | struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) | 1301 | static 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 | } |
1379 | EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); | ||
1380 | 1366 | ||
1381 | int cfg80211_wext_siwap(struct net_device *dev, | 1367 | static 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 | } |
1398 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwap); | ||
1399 | 1384 | ||
1400 | int cfg80211_wext_giwap(struct net_device *dev, | 1385 | static 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 | } |
1417 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwap); | ||
1418 | 1402 | ||
1419 | int cfg80211_wext_siwessid(struct net_device *dev, | 1403 | static 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 | } |
1434 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid); | ||
1435 | 1418 | ||
1436 | int cfg80211_wext_giwessid(struct net_device *dev, | 1419 | static 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 | } |
1454 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid); | ||
1455 | 1437 | ||
1456 | int cfg80211_wext_siwpmksa(struct net_device *dev, | 1438 | static 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 | } |
1496 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwpmksa); | ||
1497 | 1478 | ||
1498 | static const iw_handler cfg80211_handlers[] = { | 1479 | static 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 | ||
45 | int cfg80211_wext_siwmlme(struct net_device *dev, | ||
46 | struct iw_request_info *info, | ||
47 | struct iw_point *data, char *extra); | ||
48 | int cfg80211_wext_siwgenie(struct net_device *dev, | ||
49 | struct iw_request_info *info, | ||
50 | struct iw_point *data, char *extra); | ||
51 | |||
52 | |||
45 | int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); | 53 | int 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 | } |
368 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie); | ||
369 | 369 | ||
370 | int cfg80211_wext_siwmlme(struct net_device *dev, | 370 | int 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 | } |
405 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme); | ||