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 | 294 | ||||
-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 | 189 | ||||
-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, 617 insertions, 166 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index c14865172da7..220f3bd176f8 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -582,7 +582,7 @@ int wiphy_register(struct wiphy *wiphy) | |||
582 | } | 582 | } |
583 | 583 | ||
584 | /* set up regulatory info */ | 584 | /* set up regulatory info */ |
585 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | 585 | regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE); |
586 | 586 | ||
587 | list_add_rcu(&rdev->list, &cfg80211_rdev_list); | 587 | list_add_rcu(&rdev->list, &cfg80211_rdev_list); |
588 | cfg80211_rdev_list_generation++; | 588 | cfg80211_rdev_list_generation++; |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 8672e028022f..b9ec3061ed72 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -279,8 +279,6 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
279 | char *newname); | 279 | char *newname); |
280 | 280 | ||
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..b85075761e24 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -23,6 +23,12 @@ | |||
23 | #include "nl80211.h" | 23 | #include "nl80211.h" |
24 | #include "reg.h" | 24 | #include "reg.h" |
25 | 25 | ||
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,14 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
178 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, | 184 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, |
179 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, | 185 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, |
180 | [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, | 186 | [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, |
187 | [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 }, | ||
188 | [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY, | ||
189 | .len = IEEE80211_MAX_DATA_LEN }, | ||
190 | [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY, | ||
191 | .len = IEEE80211_MAX_DATA_LEN }, | ||
192 | [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, | ||
193 | [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED }, | ||
194 | [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG }, | ||
181 | }; | 195 | }; |
182 | 196 | ||
183 | /* policy for the key attributes */ | 197 | /* policy for the key attributes */ |
@@ -220,6 +234,12 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { | |||
220 | [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN }, | 234 | [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN }, |
221 | }; | 235 | }; |
222 | 236 | ||
237 | static const struct nla_policy | ||
238 | nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { | ||
239 | [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY, | ||
240 | .len = IEEE80211_MAX_SSID_LEN }, | ||
241 | }; | ||
242 | |||
223 | /* ifidx get helper */ | 243 | /* ifidx get helper */ |
224 | static int nl80211_get_ifidx(struct netlink_callback *cb) | 244 | static int nl80211_get_ifidx(struct netlink_callback *cb) |
225 | { | 245 | { |
@@ -703,11 +723,18 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
703 | dev->wiphy.max_scan_ie_len); | 723 | dev->wiphy.max_scan_ie_len); |
704 | NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, | 724 | NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, |
705 | dev->wiphy.max_sched_scan_ie_len); | 725 | dev->wiphy.max_sched_scan_ie_len); |
726 | NLA_PUT_U8(msg, NL80211_ATTR_MAX_MATCH_SETS, | ||
727 | dev->wiphy.max_match_sets); | ||
706 | 728 | ||
707 | if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) | 729 | if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) |
708 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); | 730 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); |
709 | if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) | 731 | if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) |
710 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); | 732 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); |
733 | if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) | ||
734 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD); | ||
735 | |||
736 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) | ||
737 | NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT); | ||
711 | 738 | ||
712 | NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, | 739 | NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, |
713 | sizeof(u32) * dev->wiphy.n_cipher_suites, | 740 | sizeof(u32) * dev->wiphy.n_cipher_suites, |
@@ -871,8 +898,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
871 | NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, | 898 | NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, |
872 | dev->wiphy.max_remain_on_channel_duration); | 899 | dev->wiphy.max_remain_on_channel_duration); |
873 | 900 | ||
874 | /* for now at least assume all drivers have it */ | 901 | if (dev->ops->mgmt_tx_cancel_wait) |
875 | if (dev->ops->mgmt_tx) | ||
876 | NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); | 902 | NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); |
877 | 903 | ||
878 | if (mgmt_stypes) { | 904 | if (mgmt_stypes) { |
@@ -1210,6 +1236,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1210 | goto bad_res; | 1236 | goto bad_res; |
1211 | } | 1237 | } |
1212 | 1238 | ||
1239 | if (!netdev) { | ||
1240 | result = -EINVAL; | ||
1241 | goto bad_res; | ||
1242 | } | ||
1243 | |||
1213 | nla_for_each_nested(nl_txq_params, | 1244 | nla_for_each_nested(nl_txq_params, |
1214 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], | 1245 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], |
1215 | rem_txq_params) { | 1246 | rem_txq_params) { |
@@ -1222,6 +1253,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1222 | goto bad_res; | 1253 | goto bad_res; |
1223 | 1254 | ||
1224 | result = rdev->ops->set_txq_params(&rdev->wiphy, | 1255 | result = rdev->ops->set_txq_params(&rdev->wiphy, |
1256 | netdev, | ||
1225 | &txq_params); | 1257 | &txq_params); |
1226 | if (result) | 1258 | if (result) |
1227 | goto bad_res; | 1259 | goto bad_res; |
@@ -1985,7 +2017,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) | |||
1985 | struct beacon_parameters params; | 2017 | struct beacon_parameters params; |
1986 | int haveinfo = 0, err; | 2018 | int haveinfo = 0, err; |
1987 | 2019 | ||
1988 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) | 2020 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) || |
2021 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) || | ||
2022 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) || | ||
2023 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP])) | ||
1989 | return -EINVAL; | 2024 | return -EINVAL; |
1990 | 2025 | ||
1991 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 2026 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
@@ -2011,6 +2046,49 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) | |||
2011 | if (err) | 2046 | if (err) |
2012 | return err; | 2047 | return err; |
2013 | 2048 | ||
2049 | /* | ||
2050 | * In theory, some of these attributes could be required for | ||
2051 | * NEW_BEACON, but since they were not used when the command was | ||
2052 | * originally added, keep them optional for old user space | ||
2053 | * programs to work with drivers that do not need the additional | ||
2054 | * information. | ||
2055 | */ | ||
2056 | if (info->attrs[NL80211_ATTR_SSID]) { | ||
2057 | params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | ||
2058 | params.ssid_len = | ||
2059 | nla_len(info->attrs[NL80211_ATTR_SSID]); | ||
2060 | if (params.ssid_len == 0 || | ||
2061 | params.ssid_len > IEEE80211_MAX_SSID_LEN) | ||
2062 | return -EINVAL; | ||
2063 | } | ||
2064 | |||
2065 | if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) { | ||
2066 | params.hidden_ssid = nla_get_u32( | ||
2067 | info->attrs[NL80211_ATTR_HIDDEN_SSID]); | ||
2068 | if (params.hidden_ssid != | ||
2069 | NL80211_HIDDEN_SSID_NOT_IN_USE && | ||
2070 | params.hidden_ssid != | ||
2071 | NL80211_HIDDEN_SSID_ZERO_LEN && | ||
2072 | params.hidden_ssid != | ||
2073 | NL80211_HIDDEN_SSID_ZERO_CONTENTS) | ||
2074 | return -EINVAL; | ||
2075 | } | ||
2076 | |||
2077 | params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; | ||
2078 | |||
2079 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { | ||
2080 | params.auth_type = nla_get_u32( | ||
2081 | info->attrs[NL80211_ATTR_AUTH_TYPE]); | ||
2082 | if (!nl80211_valid_auth_type(params.auth_type)) | ||
2083 | return -EINVAL; | ||
2084 | } else | ||
2085 | params.auth_type = NL80211_AUTHTYPE_AUTOMATIC; | ||
2086 | |||
2087 | err = nl80211_crypto_settings(rdev, info, ¶ms.crypto, | ||
2088 | NL80211_MAX_NR_CIPHER_SUITES); | ||
2089 | if (err) | ||
2090 | return err; | ||
2091 | |||
2014 | call = rdev->ops->add_beacon; | 2092 | call = rdev->ops->add_beacon; |
2015 | break; | 2093 | break; |
2016 | case NL80211_CMD_SET_BEACON: | 2094 | case NL80211_CMD_SET_BEACON: |
@@ -2041,6 +2119,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) | |||
2041 | if (!haveinfo) | 2119 | if (!haveinfo) |
2042 | return -EINVAL; | 2120 | return -EINVAL; |
2043 | 2121 | ||
2122 | if (info->attrs[NL80211_ATTR_IE]) { | ||
2123 | params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]); | ||
2124 | params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]); | ||
2125 | } | ||
2126 | |||
2127 | if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) { | ||
2128 | params.proberesp_ies = | ||
2129 | nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); | ||
2130 | params.proberesp_ies_len = | ||
2131 | nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); | ||
2132 | } | ||
2133 | |||
2134 | if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) { | ||
2135 | params.assocresp_ies = | ||
2136 | nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); | ||
2137 | params.assocresp_ies_len = | ||
2138 | nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); | ||
2139 | } | ||
2140 | |||
2044 | err = call(&rdev->wiphy, dev, ¶ms); | 2141 | err = call(&rdev->wiphy, dev, ¶ms); |
2045 | if (!err && params.interval) | 2142 | if (!err && params.interval) |
2046 | wdev->beacon_interval = params.interval; | 2143 | wdev->beacon_interval = params.interval; |
@@ -2237,6 +2334,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, | |||
2237 | } | 2334 | } |
2238 | nla_nest_end(msg, sinfoattr); | 2335 | nla_nest_end(msg, sinfoattr); |
2239 | 2336 | ||
2337 | if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES) | ||
2338 | NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, | ||
2339 | sinfo->assoc_req_ies); | ||
2340 | |||
2240 | return genlmsg_end(msg, hdr); | 2341 | return genlmsg_end(msg, hdr); |
2241 | 2342 | ||
2242 | nla_put_failure: | 2343 | nla_put_failure: |
@@ -2264,6 +2365,7 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
2264 | } | 2365 | } |
2265 | 2366 | ||
2266 | while (1) { | 2367 | while (1) { |
2368 | memset(&sinfo, 0, sizeof(sinfo)); | ||
2267 | err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, | 2369 | err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, |
2268 | mac_addr, &sinfo); | 2370 | mac_addr, &sinfo); |
2269 | if (err == -ENOENT) | 2371 | if (err == -ENOENT) |
@@ -2465,6 +2567,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
2465 | return err; | 2567 | return err; |
2466 | } | 2568 | } |
2467 | 2569 | ||
2570 | static struct nla_policy | ||
2571 | nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = { | ||
2572 | [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 }, | ||
2573 | [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 }, | ||
2574 | }; | ||
2575 | |||
2468 | static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | 2576 | static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) |
2469 | { | 2577 | { |
2470 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2578 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
@@ -2510,6 +2618,33 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
2510 | if (parse_station_flags(info, ¶ms)) | 2618 | if (parse_station_flags(info, ¶ms)) |
2511 | return -EINVAL; | 2619 | return -EINVAL; |
2512 | 2620 | ||
2621 | /* parse WME attributes if sta is WME capable */ | ||
2622 | if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && | ||
2623 | (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) && | ||
2624 | info->attrs[NL80211_ATTR_STA_WME]) { | ||
2625 | struct nlattr *tb[NL80211_STA_WME_MAX + 1]; | ||
2626 | struct nlattr *nla; | ||
2627 | |||
2628 | nla = info->attrs[NL80211_ATTR_STA_WME]; | ||
2629 | err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla, | ||
2630 | nl80211_sta_wme_policy); | ||
2631 | if (err) | ||
2632 | return err; | ||
2633 | |||
2634 | if (tb[NL80211_STA_WME_UAPSD_QUEUES]) | ||
2635 | params.uapsd_queues = | ||
2636 | nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]); | ||
2637 | if (params.uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) | ||
2638 | return -EINVAL; | ||
2639 | |||
2640 | if (tb[NL80211_STA_WME_MAX_SP]) | ||
2641 | params.max_sp = | ||
2642 | nla_get_u8(tb[NL80211_STA_WME_MAX_SP]); | ||
2643 | |||
2644 | if (params.max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) | ||
2645 | return -EINVAL; | ||
2646 | } | ||
2647 | |||
2513 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 2648 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
2514 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 2649 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && |
2515 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && | 2650 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && |
@@ -2955,6 +3090,10 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, | |||
2955 | cur_params.dot11MeshHWMPnetDiameterTraversalTime); | 3090 | cur_params.dot11MeshHWMPnetDiameterTraversalTime); |
2956 | NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, | 3091 | NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, |
2957 | cur_params.dot11MeshHWMPRootMode); | 3092 | cur_params.dot11MeshHWMPRootMode); |
3093 | NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL, | ||
3094 | cur_params.dot11MeshHWMPRannInterval); | ||
3095 | NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, | ||
3096 | cur_params.dot11MeshGateAnnouncementProtocol); | ||
2958 | nla_nest_end(msg, pinfoattr); | 3097 | nla_nest_end(msg, pinfoattr); |
2959 | genlmsg_end(msg, hdr); | 3098 | genlmsg_end(msg, hdr); |
2960 | return genlmsg_reply(msg, info); | 3099 | return genlmsg_reply(msg, info); |
@@ -2982,6 +3121,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A | |||
2982 | [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, | 3121 | [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, |
2983 | [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, | 3122 | [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, |
2984 | [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, | 3123 | [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, |
3124 | [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 }, | ||
3125 | [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, | ||
3126 | [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, | ||
2985 | }; | 3127 | }; |
2986 | 3128 | ||
2987 | static const struct nla_policy | 3129 | static const struct nla_policy |
@@ -3060,6 +3202,14 @@ do {\ | |||
3060 | dot11MeshHWMPRootMode, mask, | 3202 | dot11MeshHWMPRootMode, mask, |
3061 | NL80211_MESHCONF_HWMP_ROOTMODE, | 3203 | NL80211_MESHCONF_HWMP_ROOTMODE, |
3062 | nla_get_u8); | 3204 | nla_get_u8); |
3205 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, | ||
3206 | dot11MeshHWMPRannInterval, mask, | ||
3207 | NL80211_MESHCONF_HWMP_RANN_INTERVAL, | ||
3208 | nla_get_u16); | ||
3209 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, | ||
3210 | dot11MeshGateAnnouncementProtocol, mask, | ||
3211 | NL80211_MESHCONF_GATE_ANNOUNCEMENTS, | ||
3212 | nla_get_u8); | ||
3063 | if (mask_out) | 3213 | if (mask_out) |
3064 | *mask_out = mask; | 3214 | *mask_out = mask; |
3065 | 3215 | ||
@@ -3477,6 +3627,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3477 | } | 3627 | } |
3478 | } | 3628 | } |
3479 | 3629 | ||
3630 | request->no_cck = | ||
3631 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | ||
3632 | |||
3480 | request->dev = dev; | 3633 | request->dev = dev; |
3481 | request->wiphy = &rdev->wiphy; | 3634 | request->wiphy = &rdev->wiphy; |
3482 | 3635 | ||
@@ -3503,10 +3656,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3503 | struct net_device *dev = info->user_ptr[1]; | 3656 | struct net_device *dev = info->user_ptr[1]; |
3504 | struct nlattr *attr; | 3657 | struct nlattr *attr; |
3505 | struct wiphy *wiphy; | 3658 | struct wiphy *wiphy; |
3506 | int err, tmp, n_ssids = 0, n_channels, i; | 3659 | int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i; |
3507 | u32 interval; | 3660 | u32 interval; |
3508 | enum ieee80211_band band; | 3661 | enum ieee80211_band band; |
3509 | size_t ie_len; | 3662 | size_t ie_len; |
3663 | struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1]; | ||
3510 | 3664 | ||
3511 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || | 3665 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || |
3512 | !rdev->ops->sched_scan_start) | 3666 | !rdev->ops->sched_scan_start) |
@@ -3545,6 +3699,15 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3545 | if (n_ssids > wiphy->max_sched_scan_ssids) | 3699 | if (n_ssids > wiphy->max_sched_scan_ssids) |
3546 | return -EINVAL; | 3700 | return -EINVAL; |
3547 | 3701 | ||
3702 | if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) | ||
3703 | nla_for_each_nested(attr, | ||
3704 | info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], | ||
3705 | tmp) | ||
3706 | n_match_sets++; | ||
3707 | |||
3708 | if (n_match_sets > wiphy->max_match_sets) | ||
3709 | return -EINVAL; | ||
3710 | |||
3548 | if (info->attrs[NL80211_ATTR_IE]) | 3711 | if (info->attrs[NL80211_ATTR_IE]) |
3549 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3712 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3550 | else | 3713 | else |
@@ -3562,6 +3725,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3562 | 3725 | ||
3563 | request = kzalloc(sizeof(*request) | 3726 | request = kzalloc(sizeof(*request) |
3564 | + sizeof(*request->ssids) * n_ssids | 3727 | + sizeof(*request->ssids) * n_ssids |
3728 | + sizeof(*request->match_sets) * n_match_sets | ||
3565 | + sizeof(*request->channels) * n_channels | 3729 | + sizeof(*request->channels) * n_channels |
3566 | + ie_len, GFP_KERNEL); | 3730 | + ie_len, GFP_KERNEL); |
3567 | if (!request) { | 3731 | if (!request) { |
@@ -3579,6 +3743,18 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3579 | request->ie = (void *)(request->channels + n_channels); | 3743 | request->ie = (void *)(request->channels + n_channels); |
3580 | } | 3744 | } |
3581 | 3745 | ||
3746 | if (n_match_sets) { | ||
3747 | if (request->ie) | ||
3748 | request->match_sets = (void *)(request->ie + ie_len); | ||
3749 | else if (request->ssids) | ||
3750 | request->match_sets = | ||
3751 | (void *)(request->ssids + n_ssids); | ||
3752 | else | ||
3753 | request->match_sets = | ||
3754 | (void *)(request->channels + n_channels); | ||
3755 | } | ||
3756 | request->n_match_sets = n_match_sets; | ||
3757 | |||
3582 | i = 0; | 3758 | i = 0; |
3583 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { | 3759 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { |
3584 | /* user specified, bail out if channel not found */ | 3760 | /* user specified, bail out if channel not found */ |
@@ -3643,6 +3819,31 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3643 | } | 3819 | } |
3644 | } | 3820 | } |
3645 | 3821 | ||
3822 | i = 0; | ||
3823 | if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { | ||
3824 | nla_for_each_nested(attr, | ||
3825 | info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], | ||
3826 | tmp) { | ||
3827 | struct nlattr *ssid; | ||
3828 | |||
3829 | nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, | ||
3830 | nla_data(attr), nla_len(attr), | ||
3831 | nl80211_match_policy); | ||
3832 | ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID]; | ||
3833 | if (ssid) { | ||
3834 | if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { | ||
3835 | err = -EINVAL; | ||
3836 | goto out_free; | ||
3837 | } | ||
3838 | memcpy(request->match_sets[i].ssid.ssid, | ||
3839 | nla_data(ssid), nla_len(ssid)); | ||
3840 | request->match_sets[i].ssid.ssid_len = | ||
3841 | nla_len(ssid); | ||
3842 | } | ||
3843 | i++; | ||
3844 | } | ||
3845 | } | ||
3846 | |||
3646 | if (info->attrs[NL80211_ATTR_IE]) { | 3847 | if (info->attrs[NL80211_ATTR_IE]) { |
3647 | request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3848 | request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3648 | memcpy((void *)request->ie, | 3849 | memcpy((void *)request->ie, |
@@ -3935,22 +4136,6 @@ static bool nl80211_valid_wpa_versions(u32 wpa_versions) | |||
3935 | NL80211_WPA_VERSION_2)); | 4136 | NL80211_WPA_VERSION_2)); |
3936 | } | 4137 | } |
3937 | 4138 | ||
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) | 4139 | static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) |
3955 | { | 4140 | { |
3956 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4141 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
@@ -4083,7 +4268,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | |||
4083 | memcpy(settings->ciphers_pairwise, data, len); | 4268 | memcpy(settings->ciphers_pairwise, data, len); |
4084 | 4269 | ||
4085 | for (i = 0; i < settings->n_ciphers_pairwise; i++) | 4270 | for (i = 0; i < settings->n_ciphers_pairwise; i++) |
4086 | if (!nl80211_valid_cipher_suite( | 4271 | if (!cfg80211_supported_cipher_suite( |
4272 | &rdev->wiphy, | ||
4087 | settings->ciphers_pairwise[i])) | 4273 | settings->ciphers_pairwise[i])) |
4088 | return -EINVAL; | 4274 | return -EINVAL; |
4089 | } | 4275 | } |
@@ -4091,7 +4277,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | |||
4091 | if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) { | 4277 | if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) { |
4092 | settings->cipher_group = | 4278 | settings->cipher_group = |
4093 | nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]); | 4279 | nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]); |
4094 | if (!nl80211_valid_cipher_suite(settings->cipher_group)) | 4280 | if (!cfg80211_supported_cipher_suite(&rdev->wiphy, |
4281 | settings->cipher_group)) | ||
4095 | return -EINVAL; | 4282 | return -EINVAL; |
4096 | } | 4283 | } |
4097 | 4284 | ||
@@ -4104,7 +4291,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | |||
4104 | 4291 | ||
4105 | if (info->attrs[NL80211_ATTR_AKM_SUITES]) { | 4292 | if (info->attrs[NL80211_ATTR_AKM_SUITES]) { |
4106 | void *data; | 4293 | void *data; |
4107 | int len, i; | 4294 | int len; |
4108 | 4295 | ||
4109 | data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]); | 4296 | data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]); |
4110 | len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]); | 4297 | len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]); |
@@ -4117,10 +4304,6 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | |||
4117 | return -EINVAL; | 4304 | return -EINVAL; |
4118 | 4305 | ||
4119 | memcpy(settings->akm_suites, data, len); | 4306 | memcpy(settings->akm_suites, data, len); |
4120 | |||
4121 | for (i = 0; i < settings->n_akm_suites; i++) | ||
4122 | if (!nl80211_valid_akm_suite(settings->akm_suites[i])) | ||
4123 | return -EINVAL; | ||
4124 | } | 4307 | } |
4125 | 4308 | ||
4126 | return 0; | 4309 | return 0; |
@@ -4339,8 +4522,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
4339 | 4522 | ||
4340 | wiphy = &rdev->wiphy; | 4523 | wiphy = &rdev->wiphy; |
4341 | 4524 | ||
4342 | if (info->attrs[NL80211_ATTR_MAC]) | 4525 | if (info->attrs[NL80211_ATTR_MAC]) { |
4343 | ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 4526 | ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
4527 | |||
4528 | if (!is_valid_ether_addr(ibss.bssid)) | ||
4529 | return -EINVAL; | ||
4530 | } | ||
4344 | ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 4531 | ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
4345 | ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); | 4532 | ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); |
4346 | 4533 | ||
@@ -4997,6 +5184,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
4997 | struct sk_buff *msg; | 5184 | struct sk_buff *msg; |
4998 | unsigned int wait = 0; | 5185 | unsigned int wait = 0; |
4999 | bool offchan; | 5186 | bool offchan; |
5187 | bool no_cck; | ||
5000 | 5188 | ||
5001 | if (!info->attrs[NL80211_ATTR_FRAME] || | 5189 | if (!info->attrs[NL80211_ATTR_FRAME] || |
5002 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) | 5190 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) |
@@ -5033,6 +5221,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5033 | 5221 | ||
5034 | offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; | 5222 | offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; |
5035 | 5223 | ||
5224 | no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | ||
5225 | |||
5036 | freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); | 5226 | freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); |
5037 | chan = rdev_freq_to_chan(rdev, freq, channel_type); | 5227 | chan = rdev_freq_to_chan(rdev, freq, channel_type); |
5038 | if (chan == NULL) | 5228 | if (chan == NULL) |
@@ -5053,7 +5243,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5053 | channel_type_valid, wait, | 5243 | channel_type_valid, wait, |
5054 | nla_data(info->attrs[NL80211_ATTR_FRAME]), | 5244 | nla_data(info->attrs[NL80211_ATTR_FRAME]), |
5055 | nla_len(info->attrs[NL80211_ATTR_FRAME]), | 5245 | nla_len(info->attrs[NL80211_ATTR_FRAME]), |
5056 | &cookie); | 5246 | no_cck, &cookie); |
5057 | if (err) | 5247 | if (err) |
5058 | goto free_msg; | 5248 | goto free_msg; |
5059 | 5249 | ||
@@ -7078,6 +7268,52 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | |||
7078 | nlmsg_free(msg); | 7268 | nlmsg_free(msg); |
7079 | } | 7269 | } |
7080 | 7270 | ||
7271 | void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | ||
7272 | struct net_device *netdev, int index, | ||
7273 | const u8 *bssid, bool preauth, gfp_t gfp) | ||
7274 | { | ||
7275 | struct sk_buff *msg; | ||
7276 | struct nlattr *attr; | ||
7277 | void *hdr; | ||
7278 | |||
7279 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); | ||
7280 | if (!msg) | ||
7281 | return; | ||
7282 | |||
7283 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE); | ||
7284 | if (!hdr) { | ||
7285 | nlmsg_free(msg); | ||
7286 | return; | ||
7287 | } | ||
7288 | |||
7289 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
7290 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | ||
7291 | |||
7292 | attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE); | ||
7293 | if (!attr) | ||
7294 | goto nla_put_failure; | ||
7295 | |||
7296 | NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index); | ||
7297 | NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid); | ||
7298 | if (preauth) | ||
7299 | NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH); | ||
7300 | |||
7301 | nla_nest_end(msg, attr); | ||
7302 | |||
7303 | if (genlmsg_end(msg, hdr) < 0) { | ||
7304 | nlmsg_free(msg); | ||
7305 | return; | ||
7306 | } | ||
7307 | |||
7308 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
7309 | nl80211_mlme_mcgrp.id, gfp); | ||
7310 | return; | ||
7311 | |||
7312 | nla_put_failure: | ||
7313 | genlmsg_cancel(msg, hdr); | ||
7314 | nlmsg_free(msg); | ||
7315 | } | ||
7316 | |||
7081 | void | 7317 | void |
7082 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | 7318 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, |
7083 | struct net_device *netdev, const u8 *peer, | 7319 | struct net_device *netdev, const u8 *peer, |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 5d69c56400ae..f24a1fbeaf19 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -113,4 +113,8 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | |||
113 | struct net_device *netdev, const u8 *bssid, | 113 | struct net_device *netdev, const u8 *bssid, |
114 | const u8 *replay_ctr, gfp_t gfp); | 114 | const u8 *replay_ctr, gfp_t gfp); |
115 | 115 | ||
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..6304ed63588a 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/bitops.h> | 6 | #include <linux/bitops.h> |
7 | #include <linux/etherdevice.h> | 7 | #include <linux/etherdevice.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/crc32.h> | ||
9 | #include <net/cfg80211.h> | 10 | #include <net/cfg80211.h> |
10 | #include <net/ip.h> | 11 | #include <net/ip.h> |
11 | #include "core.h" | 12 | #include "core.h" |
@@ -150,12 +151,19 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy) | |||
150 | set_mandatory_flags_band(wiphy->bands[band], band); | 151 | set_mandatory_flags_band(wiphy->bands[band], band); |
151 | } | 152 | } |
152 | 153 | ||
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; |
@@ -512,10 +517,9 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, | |||
512 | if (head_need) | 517 | if (head_need) |
513 | skb_orphan(skb); | 518 | skb_orphan(skb); |
514 | 519 | ||
515 | if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) { | 520 | if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) |
516 | pr_err("failed to reallocate Tx buffer\n"); | ||
517 | return -ENOMEM; | 521 | return -ENOMEM; |
518 | } | 522 | |
519 | skb->truesize += head_need; | 523 | skb->truesize += head_need; |
520 | } | 524 | } |
521 | 525 | ||
@@ -1044,3 +1048,170 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, | |||
1044 | 1048 | ||
1045 | return 0; | 1049 | return 0; |
1046 | } | 1050 | } |
1051 | |||
1052 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | ||
1053 | struct ieee802_11_elems *elems, | ||
1054 | u64 filter, u32 crc) | ||
1055 | { | ||
1056 | size_t left = len; | ||
1057 | u8 *pos = start; | ||
1058 | bool calc_crc = filter != 0; | ||
1059 | |||
1060 | memset(elems, 0, sizeof(*elems)); | ||
1061 | elems->ie_start = start; | ||
1062 | elems->total_len = len; | ||
1063 | |||
1064 | while (left >= 2) { | ||
1065 | u8 id, elen; | ||
1066 | |||
1067 | id = *pos++; | ||
1068 | elen = *pos++; | ||
1069 | left -= 2; | ||
1070 | |||
1071 | if (elen > left) | ||
1072 | break; | ||
1073 | |||
1074 | if (calc_crc && id < 64 && (filter & (1ULL << id))) | ||
1075 | crc = crc32_be(crc, pos - 2, elen + 2); | ||
1076 | |||
1077 | switch (id) { | ||
1078 | case WLAN_EID_SSID: | ||
1079 | elems->ssid = pos; | ||
1080 | elems->ssid_len = elen; | ||
1081 | break; | ||
1082 | case WLAN_EID_SUPP_RATES: | ||
1083 | elems->supp_rates = pos; | ||
1084 | elems->supp_rates_len = elen; | ||
1085 | break; | ||
1086 | case WLAN_EID_FH_PARAMS: | ||
1087 | elems->fh_params = pos; | ||
1088 | elems->fh_params_len = elen; | ||
1089 | break; | ||
1090 | case WLAN_EID_DS_PARAMS: | ||
1091 | elems->ds_params = pos; | ||
1092 | elems->ds_params_len = elen; | ||
1093 | break; | ||
1094 | case WLAN_EID_CF_PARAMS: | ||
1095 | elems->cf_params = pos; | ||
1096 | elems->cf_params_len = elen; | ||
1097 | break; | ||
1098 | case WLAN_EID_TIM: | ||
1099 | if (elen >= sizeof(struct ieee80211_tim_ie)) { | ||
1100 | elems->tim = (void *)pos; | ||
1101 | elems->tim_len = elen; | ||
1102 | } | ||
1103 | break; | ||
1104 | case WLAN_EID_IBSS_PARAMS: | ||
1105 | elems->ibss_params = pos; | ||
1106 | elems->ibss_params_len = elen; | ||
1107 | break; | ||
1108 | case WLAN_EID_CHALLENGE: | ||
1109 | elems->challenge = pos; | ||
1110 | elems->challenge_len = elen; | ||
1111 | break; | ||
1112 | case WLAN_EID_VENDOR_SPECIFIC: | ||
1113 | if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && | ||
1114 | pos[2] == 0xf2) { | ||
1115 | /* Microsoft OUI (00:50:F2) */ | ||
1116 | |||
1117 | if (calc_crc) | ||
1118 | crc = crc32_be(crc, pos - 2, elen + 2); | ||
1119 | |||
1120 | if (pos[3] == 1) { | ||
1121 | /* OUI Type 1 - WPA IE */ | ||
1122 | elems->wpa = pos; | ||
1123 | elems->wpa_len = elen; | ||
1124 | } else if (elen >= 5 && pos[3] == 2) { | ||
1125 | /* OUI Type 2 - WMM IE */ | ||
1126 | if (pos[4] == 0) { | ||
1127 | elems->wmm_info = pos; | ||
1128 | elems->wmm_info_len = elen; | ||
1129 | } else if (pos[4] == 1) { | ||
1130 | elems->wmm_param = pos; | ||
1131 | elems->wmm_param_len = elen; | ||
1132 | } | ||
1133 | } | ||
1134 | } | ||
1135 | break; | ||
1136 | case WLAN_EID_RSN: | ||
1137 | elems->rsn = pos; | ||
1138 | elems->rsn_len = elen; | ||
1139 | break; | ||
1140 | case WLAN_EID_ERP_INFO: | ||
1141 | elems->erp_info = pos; | ||
1142 | elems->erp_info_len = elen; | ||
1143 | break; | ||
1144 | case WLAN_EID_EXT_SUPP_RATES: | ||
1145 | elems->ext_supp_rates = pos; | ||
1146 | elems->ext_supp_rates_len = elen; | ||
1147 | break; | ||
1148 | case WLAN_EID_HT_CAPABILITY: | ||
1149 | if (elen >= sizeof(struct ieee80211_ht_cap)) | ||
1150 | elems->ht_cap_elem = (void *)pos; | ||
1151 | break; | ||
1152 | case WLAN_EID_HT_INFORMATION: | ||
1153 | if (elen >= sizeof(struct ieee80211_ht_info)) | ||
1154 | elems->ht_info_elem = (void *)pos; | ||
1155 | break; | ||
1156 | case WLAN_EID_MESH_ID: | ||
1157 | elems->mesh_id = pos; | ||
1158 | elems->mesh_id_len = elen; | ||
1159 | break; | ||
1160 | case WLAN_EID_MESH_CONFIG: | ||
1161 | if (elen >= sizeof(struct ieee80211_meshconf_ie)) | ||
1162 | elems->mesh_config = (void *)pos; | ||
1163 | break; | ||
1164 | case WLAN_EID_PEER_MGMT: | ||
1165 | elems->peering = pos; | ||
1166 | elems->peering_len = elen; | ||
1167 | break; | ||
1168 | case WLAN_EID_PREQ: | ||
1169 | elems->preq = pos; | ||
1170 | elems->preq_len = elen; | ||
1171 | break; | ||
1172 | case WLAN_EID_PREP: | ||
1173 | elems->prep = pos; | ||
1174 | elems->prep_len = elen; | ||
1175 | break; | ||
1176 | case WLAN_EID_PERR: | ||
1177 | elems->perr = pos; | ||
1178 | elems->perr_len = elen; | ||
1179 | break; | ||
1180 | case WLAN_EID_RANN: | ||
1181 | if (elen >= sizeof(struct ieee80211_rann_ie)) | ||
1182 | elems->rann = (void *)pos; | ||
1183 | break; | ||
1184 | case WLAN_EID_CHANNEL_SWITCH: | ||
1185 | elems->ch_switch_elem = pos; | ||
1186 | elems->ch_switch_elem_len = elen; | ||
1187 | break; | ||
1188 | case WLAN_EID_QUIET: | ||
1189 | if (!elems->quiet_elem) { | ||
1190 | elems->quiet_elem = pos; | ||
1191 | elems->quiet_elem_len = elen; | ||
1192 | } | ||
1193 | elems->num_of_quiet_elem++; | ||
1194 | break; | ||
1195 | case WLAN_EID_COUNTRY: | ||
1196 | elems->country_elem = pos; | ||
1197 | elems->country_elem_len = elen; | ||
1198 | break; | ||
1199 | case WLAN_EID_PWR_CONSTRAINT: | ||
1200 | elems->pwr_constr_elem = pos; | ||
1201 | elems->pwr_constr_elem_len = elen; | ||
1202 | break; | ||
1203 | case WLAN_EID_TIMEOUT_INTERVAL: | ||
1204 | elems->timeout_int = pos; | ||
1205 | elems->timeout_int_len = elen; | ||
1206 | break; | ||
1207 | default: | ||
1208 | break; | ||
1209 | } | ||
1210 | |||
1211 | left -= elen; | ||
1212 | pos += elen; | ||
1213 | } | ||
1214 | |||
1215 | return crc; | ||
1216 | } | ||
1217 | 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); | ||