aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/Kconfig30
-rw-r--r--net/wireless/Makefile7
-rw-r--r--net/wireless/core.c14
-rw-r--r--net/wireless/core.h13
-rw-r--r--net/wireless/lib80211.c284
-rw-r--r--net/wireless/lib80211_crypt_ccmp.c492
-rw-r--r--net/wireless/lib80211_crypt_tkip.c784
-rw-r--r--net/wireless/lib80211_crypt_wep.c296
-rw-r--r--net/wireless/nl80211.c417
-rw-r--r--net/wireless/reg.c1005
-rw-r--r--net/wireless/reg.h33
-rw-r--r--net/wireless/sysfs.c25
-rw-r--r--net/wireless/util.c19
-rw-r--r--net/wireless/wext-compat.c139
-rw-r--r--net/wireless/wext.c2
15 files changed, 3281 insertions, 279 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 646c7121dbc0..e28e2b8fa436 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -1,6 +1,15 @@
1config CFG80211 1config CFG80211
2 tristate "Improved wireless configuration API" 2 tristate "Improved wireless configuration API"
3 3
4config CFG80211_REG_DEBUG
5 bool "cfg80211 regulatory debugging"
6 depends on CFG80211
7 default n
8 ---help---
9 You can enable this if you want to debug regulatory changes.
10
11 If unsure, say N.
12
4config NL80211 13config NL80211
5 bool "nl80211 new netlink interface support" 14 bool "nl80211 new netlink interface support"
6 depends on CFG80211 15 depends on CFG80211
@@ -40,6 +49,8 @@ config WIRELESS_OLD_REGULATORY
40 ieee80211_regdom module parameter. This is being phased out and you 49 ieee80211_regdom module parameter. This is being phased out and you
41 should stop using them ASAP. 50 should stop using them ASAP.
42 51
52 Note: You will need CRDA if you want 802.11d support
53
43 Say Y unless you have installed a new userspace application. 54 Say Y unless you have installed a new userspace application.
44 Also say Y if have one currently depending on the ieee80211_regdom 55 Also say Y if have one currently depending on the ieee80211_regdom
45 module parameter and cannot port it to use the new userspace 56 module parameter and cannot port it to use the new userspace
@@ -72,3 +83,22 @@ config WIRELESS_EXT_SYSFS
72 83
73 Say Y if you have programs using it, like old versions of 84 Say Y if you have programs using it, like old versions of
74 hal. 85 hal.
86
87config LIB80211
88 tristate "Common routines for IEEE802.11 drivers"
89 default n
90 help
91 This options enables a library of common routines used
92 by IEEE802.11 wireless LAN drivers.
93
94 Drivers should select this themselves if needed. Say Y if
95 you want this built into your kernel.
96
97config LIB80211_CRYPT_WEP
98 tristate
99
100config LIB80211_CRYPT_CCMP
101 tristate
102
103config LIB80211_CRYPT_TKIP
104 tristate
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index b9f943c45f3b..938a334c8dbc 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -1,5 +1,12 @@
1obj-$(CONFIG_WIRELESS_EXT) += wext.o 1obj-$(CONFIG_WIRELESS_EXT) += wext.o
2obj-$(CONFIG_CFG80211) += cfg80211.o 2obj-$(CONFIG_CFG80211) += cfg80211.o
3obj-$(CONFIG_LIB80211) += lib80211.o
4obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
3 7
4cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o
9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
5cfg80211-$(CONFIG_NL80211) += nl80211.o 10cfg80211-$(CONFIG_NL80211) += nl80211.o
11
12ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 5031db7b275b..b96fc0c3f1c4 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -19,7 +19,6 @@
19#include "nl80211.h" 19#include "nl80211.h"
20#include "core.h" 20#include "core.h"
21#include "sysfs.h" 21#include "sysfs.h"
22#include "reg.h"
23 22
24/* name for sysfs, %d is appended */ 23/* name for sysfs, %d is appended */
25#define PHY_NAME "phy" 24#define PHY_NAME "phy"
@@ -236,8 +235,7 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
236 mutex_unlock(&cfg80211_drv_mutex); 235 mutex_unlock(&cfg80211_drv_mutex);
237 236
238 /* give it a proper name */ 237 /* give it a proper name */
239 snprintf(drv->wiphy.dev.bus_id, BUS_ID_SIZE, 238 dev_set_name(&drv->wiphy.dev, PHY_NAME "%d", drv->idx);
240 PHY_NAME "%d", drv->idx);
241 239
242 mutex_init(&drv->mtx); 240 mutex_init(&drv->mtx);
243 mutex_init(&drv->devlist_mtx); 241 mutex_init(&drv->devlist_mtx);
@@ -301,12 +299,10 @@ int wiphy_register(struct wiphy *wiphy)
301 /* check and set up bitrates */ 299 /* check and set up bitrates */
302 ieee80211_set_bitrate_flags(wiphy); 300 ieee80211_set_bitrate_flags(wiphy);
303 301
302 mutex_lock(&cfg80211_drv_mutex);
303
304 /* set up regulatory info */ 304 /* set up regulatory info */
305 mutex_lock(&cfg80211_reg_mutex);
306 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE); 305 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE);
307 mutex_unlock(&cfg80211_reg_mutex);
308
309 mutex_lock(&cfg80211_drv_mutex);
310 306
311 res = device_add(&drv->wiphy.dev); 307 res = device_add(&drv->wiphy.dev);
312 if (res) 308 if (res)
@@ -351,6 +347,10 @@ void wiphy_unregister(struct wiphy *wiphy)
351 /* unlock again before freeing */ 347 /* unlock again before freeing */
352 mutex_unlock(&drv->mtx); 348 mutex_unlock(&drv->mtx);
353 349
350 /* If this device got a regulatory hint tell core its
351 * free to listen now to a new shiny device regulatory hint */
352 reg_device_remove(wiphy);
353
354 list_del(&drv->list); 354 list_del(&drv->list);
355 device_del(&drv->wiphy.dev); 355 device_del(&drv->wiphy.dev);
356 debugfs_remove(drv->wiphy.debugfsdir); 356 debugfs_remove(drv->wiphy.debugfsdir);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 771cc5cc7658..f7fb9f413028 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -11,6 +11,7 @@
11#include <net/genetlink.h> 11#include <net/genetlink.h>
12#include <net/wireless.h> 12#include <net/wireless.h>
13#include <net/cfg80211.h> 13#include <net/cfg80211.h>
14#include "reg.h"
14 15
15struct cfg80211_registered_device { 16struct cfg80211_registered_device {
16 struct cfg80211_ops *ops; 17 struct cfg80211_ops *ops;
@@ -21,6 +22,18 @@ struct cfg80211_registered_device {
21 * any call is in progress */ 22 * any call is in progress */
22 struct mutex mtx; 23 struct mutex mtx;
23 24
25 /* ISO / IEC 3166 alpha2 for which this device is receiving
26 * country IEs on, this can help disregard country IEs from APs
27 * on the same alpha2 quickly. The alpha2 may differ from
28 * cfg80211_regdomain's alpha2 when an intersection has occurred.
29 * If the AP is reconfigured this can also be used to tell us if
30 * the country on the country IE changed. */
31 char country_ie_alpha2[2];
32
33 /* If a Country IE has been received this tells us the environment
34 * which its telling us its in. This defaults to ENVIRON_ANY */
35 enum environment_cap env;
36
24 /* wiphy index, internal only */ 37 /* wiphy index, internal only */
25 int idx; 38 int idx;
26 39
diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c
new file mode 100644
index 000000000000..97d411f74507
--- /dev/null
+++ b/net/wireless/lib80211.c
@@ -0,0 +1,284 @@
1/*
2 * lib80211 -- common bits for IEEE802.11 drivers
3 *
4 * Copyright(c) 2008 John W. Linville <linville@tuxdriver.com>
5 *
6 * Portions copied from old ieee80211 component, w/ original copyright
7 * notices below:
8 *
9 * Host AP crypto routines
10 *
11 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
12 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/ctype.h>
18#include <linux/ieee80211.h>
19#include <linux/errno.h>
20#include <linux/init.h>
21#include <linux/slab.h>
22#include <linux/string.h>
23
24#include <net/lib80211.h>
25
26#define DRV_NAME "lib80211"
27
28#define DRV_DESCRIPTION "common routines for IEEE802.11 drivers"
29
30MODULE_DESCRIPTION(DRV_DESCRIPTION);
31MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>");
32MODULE_LICENSE("GPL");
33
34struct lib80211_crypto_alg {
35 struct list_head list;
36 struct lib80211_crypto_ops *ops;
37};
38
39static LIST_HEAD(lib80211_crypto_algs);
40static DEFINE_SPINLOCK(lib80211_crypto_lock);
41
42const char *print_ssid(char *buf, const char *ssid, u8 ssid_len)
43{
44 const char *s = ssid;
45 char *d = buf;
46
47 ssid_len = min_t(u8, ssid_len, IEEE80211_MAX_SSID_LEN);
48 while (ssid_len--) {
49 if (isprint(*s)) {
50 *d++ = *s++;
51 continue;
52 }
53
54 *d++ = '\\';
55 if (*s == '\0')
56 *d++ = '0';
57 else if (*s == '\n')
58 *d++ = 'n';
59 else if (*s == '\r')
60 *d++ = 'r';
61 else if (*s == '\t')
62 *d++ = 't';
63 else if (*s == '\\')
64 *d++ = '\\';
65 else
66 d += snprintf(d, 3, "%03o", *s);
67 s++;
68 }
69 *d = '\0';
70 return buf;
71}
72EXPORT_SYMBOL(print_ssid);
73
74int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name,
75 spinlock_t *lock)
76{
77 memset(info, 0, sizeof(*info));
78
79 info->name = name;
80 info->lock = lock;
81
82 INIT_LIST_HEAD(&info->crypt_deinit_list);
83 setup_timer(&info->crypt_deinit_timer, lib80211_crypt_deinit_handler,
84 (unsigned long)info);
85
86 return 0;
87}
88EXPORT_SYMBOL(lib80211_crypt_info_init);
89
90void lib80211_crypt_info_free(struct lib80211_crypt_info *info)
91{
92 int i;
93
94 lib80211_crypt_quiescing(info);
95 del_timer_sync(&info->crypt_deinit_timer);
96 lib80211_crypt_deinit_entries(info, 1);
97
98 for (i = 0; i < NUM_WEP_KEYS; i++) {
99 struct lib80211_crypt_data *crypt = info->crypt[i];
100 if (crypt) {
101 if (crypt->ops) {
102 crypt->ops->deinit(crypt->priv);
103 module_put(crypt->ops->owner);
104 }
105 kfree(crypt);
106 info->crypt[i] = NULL;
107 }
108 }
109}
110EXPORT_SYMBOL(lib80211_crypt_info_free);
111
112void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force)
113{
114 struct lib80211_crypt_data *entry, *next;
115 unsigned long flags;
116
117 spin_lock_irqsave(info->lock, flags);
118 list_for_each_entry_safe(entry, next, &info->crypt_deinit_list, list) {
119 if (atomic_read(&entry->refcnt) != 0 && !force)
120 continue;
121
122 list_del(&entry->list);
123
124 if (entry->ops) {
125 entry->ops->deinit(entry->priv);
126 module_put(entry->ops->owner);
127 }
128 kfree(entry);
129 }
130 spin_unlock_irqrestore(info->lock, flags);
131}
132EXPORT_SYMBOL(lib80211_crypt_deinit_entries);
133
134/* After this, crypt_deinit_list won't accept new members */
135void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
136{
137 unsigned long flags;
138
139 spin_lock_irqsave(info->lock, flags);
140 info->crypt_quiesced = 1;
141 spin_unlock_irqrestore(info->lock, flags);
142}
143EXPORT_SYMBOL(lib80211_crypt_quiescing);
144
145void lib80211_crypt_deinit_handler(unsigned long data)
146{
147 struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data;
148 unsigned long flags;
149
150 lib80211_crypt_deinit_entries(info, 0);
151
152 spin_lock_irqsave(info->lock, flags);
153 if (!list_empty(&info->crypt_deinit_list) && !info->crypt_quiesced) {
154 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
155 "deletion list\n", info->name);
156 info->crypt_deinit_timer.expires = jiffies + HZ;
157 add_timer(&info->crypt_deinit_timer);
158 }
159 spin_unlock_irqrestore(info->lock, flags);
160}
161EXPORT_SYMBOL(lib80211_crypt_deinit_handler);
162
163void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
164 struct lib80211_crypt_data **crypt)
165{
166 struct lib80211_crypt_data *tmp;
167 unsigned long flags;
168
169 if (*crypt == NULL)
170 return;
171
172 tmp = *crypt;
173 *crypt = NULL;
174
175 /* must not run ops->deinit() while there may be pending encrypt or
176 * decrypt operations. Use a list of delayed deinits to avoid needing
177 * locking. */
178
179 spin_lock_irqsave(info->lock, flags);
180 if (!info->crypt_quiesced) {
181 list_add(&tmp->list, &info->crypt_deinit_list);
182 if (!timer_pending(&info->crypt_deinit_timer)) {
183 info->crypt_deinit_timer.expires = jiffies + HZ;
184 add_timer(&info->crypt_deinit_timer);
185 }
186 }
187 spin_unlock_irqrestore(info->lock, flags);
188}
189EXPORT_SYMBOL(lib80211_crypt_delayed_deinit);
190
191int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops)
192{
193 unsigned long flags;
194 struct lib80211_crypto_alg *alg;
195
196 alg = kzalloc(sizeof(*alg), GFP_KERNEL);
197 if (alg == NULL)
198 return -ENOMEM;
199
200 alg->ops = ops;
201
202 spin_lock_irqsave(&lib80211_crypto_lock, flags);
203 list_add(&alg->list, &lib80211_crypto_algs);
204 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
205
206 printk(KERN_DEBUG "lib80211_crypt: registered algorithm '%s'\n",
207 ops->name);
208
209 return 0;
210}
211EXPORT_SYMBOL(lib80211_register_crypto_ops);
212
213int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops)
214{
215 struct lib80211_crypto_alg *alg;
216 unsigned long flags;
217
218 spin_lock_irqsave(&lib80211_crypto_lock, flags);
219 list_for_each_entry(alg, &lib80211_crypto_algs, list) {
220 if (alg->ops == ops)
221 goto found;
222 }
223 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
224 return -EINVAL;
225
226 found:
227 printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm "
228 "'%s'\n", ops->name);
229 list_del(&alg->list);
230 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
231 kfree(alg);
232 return 0;
233}
234EXPORT_SYMBOL(lib80211_unregister_crypto_ops);
235
236struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name)
237{
238 struct lib80211_crypto_alg *alg;
239 unsigned long flags;
240
241 spin_lock_irqsave(&lib80211_crypto_lock, flags);
242 list_for_each_entry(alg, &lib80211_crypto_algs, list) {
243 if (strcmp(alg->ops->name, name) == 0)
244 goto found;
245 }
246 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
247 return NULL;
248
249 found:
250 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
251 return alg->ops;
252}
253EXPORT_SYMBOL(lib80211_get_crypto_ops);
254
255static void *lib80211_crypt_null_init(int keyidx)
256{
257 return (void *)1;
258}
259
260static void lib80211_crypt_null_deinit(void *priv)
261{
262}
263
264static struct lib80211_crypto_ops lib80211_crypt_null = {
265 .name = "NULL",
266 .init = lib80211_crypt_null_init,
267 .deinit = lib80211_crypt_null_deinit,
268 .owner = THIS_MODULE,
269};
270
271static int __init lib80211_init(void)
272{
273 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION "\n");
274 return lib80211_register_crypto_ops(&lib80211_crypt_null);
275}
276
277static void __exit lib80211_exit(void)
278{
279 lib80211_unregister_crypto_ops(&lib80211_crypt_null);
280 BUG_ON(!list_empty(&lib80211_crypto_algs));
281}
282
283module_init(lib80211_init);
284module_exit(lib80211_exit);
diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c
new file mode 100644
index 000000000000..db428194c16a
--- /dev/null
+++ b/net/wireless/lib80211_crypt_ccmp.c
@@ -0,0 +1,492 @@
1/*
2 * lib80211 crypt: host-based CCMP encryption implementation for lib80211
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
5 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/err.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/random.h>
19#include <linux/skbuff.h>
20#include <linux/netdevice.h>
21#include <linux/if_ether.h>
22#include <linux/if_arp.h>
23#include <asm/string.h>
24#include <linux/wireless.h>
25
26#include <linux/ieee80211.h>
27
28#include <linux/crypto.h>
29
30#include <net/lib80211.h>
31
32MODULE_AUTHOR("Jouni Malinen");
33MODULE_DESCRIPTION("Host AP crypt: CCMP");
34MODULE_LICENSE("GPL");
35
36#define AES_BLOCK_LEN 16
37#define CCMP_HDR_LEN 8
38#define CCMP_MIC_LEN 8
39#define CCMP_TK_LEN 16
40#define CCMP_PN_LEN 6
41
42struct lib80211_ccmp_data {
43 u8 key[CCMP_TK_LEN];
44 int key_set;
45
46 u8 tx_pn[CCMP_PN_LEN];
47 u8 rx_pn[CCMP_PN_LEN];
48
49 u32 dot11RSNAStatsCCMPFormatErrors;
50 u32 dot11RSNAStatsCCMPReplays;
51 u32 dot11RSNAStatsCCMPDecryptErrors;
52
53 int key_idx;
54
55 struct crypto_cipher *tfm;
56
57 /* scratch buffers for virt_to_page() (crypto API) */
58 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
59 tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
60 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
61};
62
63static inline void lib80211_ccmp_aes_encrypt(struct crypto_cipher *tfm,
64 const u8 pt[16], u8 ct[16])
65{
66 crypto_cipher_encrypt_one(tfm, ct, pt);
67}
68
69static void *lib80211_ccmp_init(int key_idx)
70{
71 struct lib80211_ccmp_data *priv;
72
73 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
74 if (priv == NULL)
75 goto fail;
76 priv->key_idx = key_idx;
77
78 priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
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;
83 goto fail;
84 }
85
86 return priv;
87
88 fail:
89 if (priv) {
90 if (priv->tfm)
91 crypto_free_cipher(priv->tfm);
92 kfree(priv);
93 }
94
95 return NULL;
96}
97
98static void lib80211_ccmp_deinit(void *priv)
99{
100 struct lib80211_ccmp_data *_priv = priv;
101 if (_priv && _priv->tfm)
102 crypto_free_cipher(_priv->tfm);
103 kfree(priv);
104}
105
106static inline void xor_block(u8 * b, u8 * a, size_t len)
107{
108 int i;
109 for (i = 0; i < len; i++)
110 b[i] ^= a[i];
111}
112
113static void ccmp_init_blocks(struct crypto_cipher *tfm,
114 struct ieee80211_hdr *hdr,
115 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
116{
117 u8 *pos, qc = 0;
118 size_t aad_len;
119 int a4_included, qc_included;
120 u8 aad[2 * AES_BLOCK_LEN];
121
122 a4_included = ieee80211_has_a4(hdr->frame_control);
123 qc_included = ieee80211_is_data_qos(hdr->frame_control);
124
125 aad_len = 22;
126 if (a4_included)
127 aad_len += 6;
128 if (qc_included) {
129 pos = (u8 *) & hdr->addr4;
130 if (a4_included)
131 pos += 6;
132 qc = *pos & 0x0f;
133 aad_len += 2;
134 }
135
136 /* CCM Initial Block:
137 * Flag (Include authentication header, M=3 (8-octet MIC),
138 * L=1 (2-octet Dlen))
139 * Nonce: 0x00 | A2 | PN
140 * Dlen */
141 b0[0] = 0x59;
142 b0[1] = qc;
143 memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
144 memcpy(b0 + 8, pn, CCMP_PN_LEN);
145 b0[14] = (dlen >> 8) & 0xff;
146 b0[15] = dlen & 0xff;
147
148 /* AAD:
149 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
150 * A1 | A2 | A3
151 * SC with bits 4..15 (seq#) masked to zero
152 * A4 (if present)
153 * QC (if present)
154 */
155 pos = (u8 *) hdr;
156 aad[0] = 0; /* aad_len >> 8 */
157 aad[1] = aad_len & 0xff;
158 aad[2] = pos[0] & 0x8f;
159 aad[3] = pos[1] & 0xc7;
160 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
161 pos = (u8 *) & hdr->seq_ctrl;
162 aad[22] = pos[0] & 0x0f;
163 aad[23] = 0; /* all bits masked */
164 memset(aad + 24, 0, 8);
165 if (a4_included)
166 memcpy(aad + 24, hdr->addr4, ETH_ALEN);
167 if (qc_included) {
168 aad[a4_included ? 30 : 24] = qc;
169 /* rest of QC masked */
170 }
171
172 /* Start with the first block and AAD */
173 lib80211_ccmp_aes_encrypt(tfm, b0, auth);
174 xor_block(auth, aad, AES_BLOCK_LEN);
175 lib80211_ccmp_aes_encrypt(tfm, auth, auth);
176 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
177 lib80211_ccmp_aes_encrypt(tfm, auth, auth);
178 b0[0] &= 0x07;
179 b0[14] = b0[15] = 0;
180 lib80211_ccmp_aes_encrypt(tfm, b0, s0);
181}
182
183static int lib80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
184 u8 *aeskey, int keylen, void *priv)
185{
186 struct lib80211_ccmp_data *key = priv;
187 int i;
188 u8 *pos;
189
190 if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
191 return -1;
192
193 if (aeskey != NULL && keylen >= CCMP_TK_LEN)
194 memcpy(aeskey, key->key, CCMP_TK_LEN);
195
196 pos = skb_push(skb, CCMP_HDR_LEN);
197 memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
198 pos += hdr_len;
199
200 i = CCMP_PN_LEN - 1;
201 while (i >= 0) {
202 key->tx_pn[i]++;
203 if (key->tx_pn[i] != 0)
204 break;
205 i--;
206 }
207
208 *pos++ = key->tx_pn[5];
209 *pos++ = key->tx_pn[4];
210 *pos++ = 0;
211 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
212 *pos++ = key->tx_pn[3];
213 *pos++ = key->tx_pn[2];
214 *pos++ = key->tx_pn[1];
215 *pos++ = key->tx_pn[0];
216
217 return CCMP_HDR_LEN;
218}
219
220static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
221{
222 struct lib80211_ccmp_data *key = priv;
223 int data_len, i, blocks, last, len;
224 u8 *pos, *mic;
225 struct ieee80211_hdr *hdr;
226 u8 *b0 = key->tx_b0;
227 u8 *b = key->tx_b;
228 u8 *e = key->tx_e;
229 u8 *s0 = key->tx_s0;
230
231 if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
232 return -1;
233
234 data_len = skb->len - hdr_len;
235 len = lib80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
236 if (len < 0)
237 return -1;
238
239 pos = skb->data + hdr_len + CCMP_HDR_LEN;
240 mic = skb_put(skb, CCMP_MIC_LEN);
241 hdr = (struct ieee80211_hdr *)skb->data;
242 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
243
244 blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
245 last = data_len % AES_BLOCK_LEN;
246
247 for (i = 1; i <= blocks; i++) {
248 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
249 /* Authentication */
250 xor_block(b, pos, len);
251 lib80211_ccmp_aes_encrypt(key->tfm, b, b);
252 /* Encryption, with counter */
253 b0[14] = (i >> 8) & 0xff;
254 b0[15] = i & 0xff;
255 lib80211_ccmp_aes_encrypt(key->tfm, b0, e);
256 xor_block(pos, e, len);
257 pos += len;
258 }
259
260 for (i = 0; i < CCMP_MIC_LEN; i++)
261 mic[i] = b[i] ^ s0[i];
262
263 return 0;
264}
265
266/*
267 * deal with seq counter wrapping correctly.
268 * refer to timer_after() for jiffies wrapping handling
269 */
270static inline int ccmp_replay_check(u8 *pn_n, u8 *pn_o)
271{
272 u32 iv32_n, iv16_n;
273 u32 iv32_o, iv16_o;
274
275 iv32_n = (pn_n[0] << 24) | (pn_n[1] << 16) | (pn_n[2] << 8) | pn_n[3];
276 iv16_n = (pn_n[4] << 8) | pn_n[5];
277
278 iv32_o = (pn_o[0] << 24) | (pn_o[1] << 16) | (pn_o[2] << 8) | pn_o[3];
279 iv16_o = (pn_o[4] << 8) | pn_o[5];
280
281 if ((s32)iv32_n - (s32)iv32_o < 0 ||
282 (iv32_n == iv32_o && iv16_n <= iv16_o))
283 return 1;
284 return 0;
285}
286
287static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
288{
289 struct lib80211_ccmp_data *key = priv;
290 u8 keyidx, *pos;
291 struct ieee80211_hdr *hdr;
292 u8 *b0 = key->rx_b0;
293 u8 *b = key->rx_b;
294 u8 *a = key->rx_a;
295 u8 pn[6];
296 int i, blocks, last, len;
297 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
298 u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
299
300 if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
301 key->dot11RSNAStatsCCMPFormatErrors++;
302 return -1;
303 }
304
305 hdr = (struct ieee80211_hdr *)skb->data;
306 pos = skb->data + hdr_len;
307 keyidx = pos[3];
308 if (!(keyidx & (1 << 5))) {
309 if (net_ratelimit()) {
310 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
311 " flag from %pM\n", hdr->addr2);
312 }
313 key->dot11RSNAStatsCCMPFormatErrors++;
314 return -2;
315 }
316 keyidx >>= 6;
317 if (key->key_idx != keyidx) {
318 printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
319 "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
320 return -6;
321 }
322 if (!key->key_set) {
323 if (net_ratelimit()) {
324 printk(KERN_DEBUG "CCMP: received packet from %pM"
325 " with keyid=%d that does not have a configured"
326 " key\n", hdr->addr2, keyidx);
327 }
328 return -3;
329 }
330
331 pn[0] = pos[7];
332 pn[1] = pos[6];
333 pn[2] = pos[5];
334 pn[3] = pos[4];
335 pn[4] = pos[1];
336 pn[5] = pos[0];
337 pos += 8;
338
339 if (ccmp_replay_check(pn, key->rx_pn)) {
340 if (net_ratelimit()) {
341 printk(KERN_DEBUG "CCMP: replay detected: STA=%pM "
342 "previous PN %02x%02x%02x%02x%02x%02x "
343 "received PN %02x%02x%02x%02x%02x%02x\n",
344 hdr->addr2,
345 key->rx_pn[0], key->rx_pn[1], key->rx_pn[2],
346 key->rx_pn[3], key->rx_pn[4], key->rx_pn[5],
347 pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]);
348 }
349 key->dot11RSNAStatsCCMPReplays++;
350 return -4;
351 }
352
353 ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
354 xor_block(mic, b, CCMP_MIC_LEN);
355
356 blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
357 last = data_len % AES_BLOCK_LEN;
358
359 for (i = 1; i <= blocks; i++) {
360 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
361 /* Decrypt, with counter */
362 b0[14] = (i >> 8) & 0xff;
363 b0[15] = i & 0xff;
364 lib80211_ccmp_aes_encrypt(key->tfm, b0, b);
365 xor_block(pos, b, len);
366 /* Authentication */
367 xor_block(a, pos, len);
368 lib80211_ccmp_aes_encrypt(key->tfm, a, a);
369 pos += len;
370 }
371
372 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
373 if (net_ratelimit()) {
374 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
375 "%pM\n", hdr->addr2);
376 }
377 key->dot11RSNAStatsCCMPDecryptErrors++;
378 return -5;
379 }
380
381 memcpy(key->rx_pn, pn, CCMP_PN_LEN);
382
383 /* Remove hdr and MIC */
384 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
385 skb_pull(skb, CCMP_HDR_LEN);
386 skb_trim(skb, skb->len - CCMP_MIC_LEN);
387
388 return keyidx;
389}
390
391static int lib80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
392{
393 struct lib80211_ccmp_data *data = priv;
394 int keyidx;
395 struct crypto_cipher *tfm = data->tfm;
396
397 keyidx = data->key_idx;
398 memset(data, 0, sizeof(*data));
399 data->key_idx = keyidx;
400 data->tfm = tfm;
401 if (len == CCMP_TK_LEN) {
402 memcpy(data->key, key, CCMP_TK_LEN);
403 data->key_set = 1;
404 if (seq) {
405 data->rx_pn[0] = seq[5];
406 data->rx_pn[1] = seq[4];
407 data->rx_pn[2] = seq[3];
408 data->rx_pn[3] = seq[2];
409 data->rx_pn[4] = seq[1];
410 data->rx_pn[5] = seq[0];
411 }
412 crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN);
413 } else if (len == 0)
414 data->key_set = 0;
415 else
416 return -1;
417
418 return 0;
419}
420
421static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
422{
423 struct lib80211_ccmp_data *data = priv;
424
425 if (len < CCMP_TK_LEN)
426 return -1;
427
428 if (!data->key_set)
429 return 0;
430 memcpy(key, data->key, CCMP_TK_LEN);
431
432 if (seq) {
433 seq[0] = data->tx_pn[5];
434 seq[1] = data->tx_pn[4];
435 seq[2] = data->tx_pn[3];
436 seq[3] = data->tx_pn[2];
437 seq[4] = data->tx_pn[1];
438 seq[5] = data->tx_pn[0];
439 }
440
441 return CCMP_TK_LEN;
442}
443
444static char *lib80211_ccmp_print_stats(char *p, void *priv)
445{
446 struct lib80211_ccmp_data *ccmp = priv;
447
448 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
449 "tx_pn=%02x%02x%02x%02x%02x%02x "
450 "rx_pn=%02x%02x%02x%02x%02x%02x "
451 "format_errors=%d replays=%d decrypt_errors=%d\n",
452 ccmp->key_idx, ccmp->key_set,
453 ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2],
454 ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5],
455 ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2],
456 ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5],
457 ccmp->dot11RSNAStatsCCMPFormatErrors,
458 ccmp->dot11RSNAStatsCCMPReplays,
459 ccmp->dot11RSNAStatsCCMPDecryptErrors);
460
461 return p;
462}
463
464static struct lib80211_crypto_ops lib80211_crypt_ccmp = {
465 .name = "CCMP",
466 .init = lib80211_ccmp_init,
467 .deinit = lib80211_ccmp_deinit,
468 .build_iv = lib80211_ccmp_hdr,
469 .encrypt_mpdu = lib80211_ccmp_encrypt,
470 .decrypt_mpdu = lib80211_ccmp_decrypt,
471 .encrypt_msdu = NULL,
472 .decrypt_msdu = NULL,
473 .set_key = lib80211_ccmp_set_key,
474 .get_key = lib80211_ccmp_get_key,
475 .print_stats = lib80211_ccmp_print_stats,
476 .extra_mpdu_prefix_len = CCMP_HDR_LEN,
477 .extra_mpdu_postfix_len = CCMP_MIC_LEN,
478 .owner = THIS_MODULE,
479};
480
481static int __init lib80211_crypto_ccmp_init(void)
482{
483 return lib80211_register_crypto_ops(&lib80211_crypt_ccmp);
484}
485
486static void __exit lib80211_crypto_ccmp_exit(void)
487{
488 lib80211_unregister_crypto_ops(&lib80211_crypt_ccmp);
489}
490
491module_init(lib80211_crypto_ccmp_init);
492module_exit(lib80211_crypto_ccmp_exit);
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c
new file mode 100644
index 000000000000..7e8e22bfed90
--- /dev/null
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -0,0 +1,784 @@
1/*
2 * lib80211 crypt: host-based TKIP encryption implementation for lib80211
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
5 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 */
12
13#include <linux/err.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/scatterlist.h>
19#include <linux/skbuff.h>
20#include <linux/netdevice.h>
21#include <linux/mm.h>
22#include <linux/if_ether.h>
23#include <linux/if_arp.h>
24#include <asm/string.h>
25
26#include <linux/wireless.h>
27#include <linux/ieee80211.h>
28#include <net/iw_handler.h>
29
30#include <linux/crypto.h>
31#include <linux/crc32.h>
32
33#include <net/lib80211.h>
34
35MODULE_AUTHOR("Jouni Malinen");
36MODULE_DESCRIPTION("lib80211 crypt: TKIP");
37MODULE_LICENSE("GPL");
38
39struct lib80211_tkip_data {
40#define TKIP_KEY_LEN 32
41 u8 key[TKIP_KEY_LEN];
42 int key_set;
43
44 u32 tx_iv32;
45 u16 tx_iv16;
46 u16 tx_ttak[5];
47 int tx_phase1_done;
48
49 u32 rx_iv32;
50 u16 rx_iv16;
51 u16 rx_ttak[5];
52 int rx_phase1_done;
53 u32 rx_iv32_new;
54 u16 rx_iv16_new;
55
56 u32 dot11RSNAStatsTKIPReplays;
57 u32 dot11RSNAStatsTKIPICVErrors;
58 u32 dot11RSNAStatsTKIPLocalMICFailures;
59
60 int key_idx;
61
62 struct crypto_blkcipher *rx_tfm_arc4;
63 struct crypto_hash *rx_tfm_michael;
64 struct crypto_blkcipher *tx_tfm_arc4;
65 struct crypto_hash *tx_tfm_michael;
66
67 /* scratch buffers for virt_to_page() (crypto API) */
68 u8 rx_hdr[16], tx_hdr[16];
69
70 unsigned long flags;
71};
72
73static unsigned long lib80211_tkip_set_flags(unsigned long flags, void *priv)
74{
75 struct lib80211_tkip_data *_priv = priv;
76 unsigned long old_flags = _priv->flags;
77 _priv->flags = flags;
78 return old_flags;
79}
80
81static unsigned long lib80211_tkip_get_flags(void *priv)
82{
83 struct lib80211_tkip_data *_priv = priv;
84 return _priv->flags;
85}
86
87static void *lib80211_tkip_init(int key_idx)
88{
89 struct lib80211_tkip_data *priv;
90
91 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
92 if (priv == NULL)
93 goto fail;
94
95 priv->key_idx = key_idx;
96
97 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
98 CRYPTO_ALG_ASYNC);
99 if (IS_ERR(priv->tx_tfm_arc4)) {
100 printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
101 "crypto API arc4\n");
102 priv->tx_tfm_arc4 = NULL;
103 goto fail;
104 }
105
106 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
107 CRYPTO_ALG_ASYNC);
108 if (IS_ERR(priv->tx_tfm_michael)) {
109 printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
110 "crypto API michael_mic\n");
111 priv->tx_tfm_michael = NULL;
112 goto fail;
113 }
114
115 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
116 CRYPTO_ALG_ASYNC);
117 if (IS_ERR(priv->rx_tfm_arc4)) {
118 printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
119 "crypto API arc4\n");
120 priv->rx_tfm_arc4 = NULL;
121 goto fail;
122 }
123
124 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
125 CRYPTO_ALG_ASYNC);
126 if (IS_ERR(priv->rx_tfm_michael)) {
127 printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
128 "crypto API michael_mic\n");
129 priv->rx_tfm_michael = NULL;
130 goto fail;
131 }
132
133 return priv;
134
135 fail:
136 if (priv) {
137 if (priv->tx_tfm_michael)
138 crypto_free_hash(priv->tx_tfm_michael);
139 if (priv->tx_tfm_arc4)
140 crypto_free_blkcipher(priv->tx_tfm_arc4);
141 if (priv->rx_tfm_michael)
142 crypto_free_hash(priv->rx_tfm_michael);
143 if (priv->rx_tfm_arc4)
144 crypto_free_blkcipher(priv->rx_tfm_arc4);
145 kfree(priv);
146 }
147
148 return NULL;
149}
150
151static void lib80211_tkip_deinit(void *priv)
152{
153 struct lib80211_tkip_data *_priv = priv;
154 if (_priv) {
155 if (_priv->tx_tfm_michael)
156 crypto_free_hash(_priv->tx_tfm_michael);
157 if (_priv->tx_tfm_arc4)
158 crypto_free_blkcipher(_priv->tx_tfm_arc4);
159 if (_priv->rx_tfm_michael)
160 crypto_free_hash(_priv->rx_tfm_michael);
161 if (_priv->rx_tfm_arc4)
162 crypto_free_blkcipher(_priv->rx_tfm_arc4);
163 }
164 kfree(priv);
165}
166
167static inline u16 RotR1(u16 val)
168{
169 return (val >> 1) | (val << 15);
170}
171
172static inline u8 Lo8(u16 val)
173{
174 return val & 0xff;
175}
176
177static inline u8 Hi8(u16 val)
178{
179 return val >> 8;
180}
181
182static inline u16 Lo16(u32 val)
183{
184 return val & 0xffff;
185}
186
187static inline u16 Hi16(u32 val)
188{
189 return val >> 16;
190}
191
192static inline u16 Mk16(u8 hi, u8 lo)
193{
194 return lo | (((u16) hi) << 8);
195}
196
197static inline u16 Mk16_le(__le16 * v)
198{
199 return le16_to_cpu(*v);
200}
201
202static const u16 Sbox[256] = {
203 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
204 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
205 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
206 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
207 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
208 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
209 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
210 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
211 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
212 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
213 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
214 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
215 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
216 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
217 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
218 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
219 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
220 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
221 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
222 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
223 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
224 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
225 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
226 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
227 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
228 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
229 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
230 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
231 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
232 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
233 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
234 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
235};
236
237static inline u16 _S_(u16 v)
238{
239 u16 t = Sbox[Hi8(v)];
240 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
241}
242
243#define PHASE1_LOOP_COUNT 8
244
245static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
246 u32 IV32)
247{
248 int i, j;
249
250 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
251 TTAK[0] = Lo16(IV32);
252 TTAK[1] = Hi16(IV32);
253 TTAK[2] = Mk16(TA[1], TA[0]);
254 TTAK[3] = Mk16(TA[3], TA[2]);
255 TTAK[4] = Mk16(TA[5], TA[4]);
256
257 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
258 j = 2 * (i & 1);
259 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
260 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
261 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
262 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
263 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
264 }
265}
266
267static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
268 u16 IV16)
269{
270 /* Make temporary area overlap WEP seed so that the final copy can be
271 * avoided on little endian hosts. */
272 u16 *PPK = (u16 *) & WEPSeed[4];
273
274 /* Step 1 - make copy of TTAK and bring in TSC */
275 PPK[0] = TTAK[0];
276 PPK[1] = TTAK[1];
277 PPK[2] = TTAK[2];
278 PPK[3] = TTAK[3];
279 PPK[4] = TTAK[4];
280 PPK[5] = TTAK[4] + IV16;
281
282 /* Step 2 - 96-bit bijective mixing using S-box */
283 PPK[0] += _S_(PPK[5] ^ Mk16_le((__le16 *) & TK[0]));
284 PPK[1] += _S_(PPK[0] ^ Mk16_le((__le16 *) & TK[2]));
285 PPK[2] += _S_(PPK[1] ^ Mk16_le((__le16 *) & TK[4]));
286 PPK[3] += _S_(PPK[2] ^ Mk16_le((__le16 *) & TK[6]));
287 PPK[4] += _S_(PPK[3] ^ Mk16_le((__le16 *) & TK[8]));
288 PPK[5] += _S_(PPK[4] ^ Mk16_le((__le16 *) & TK[10]));
289
290 PPK[0] += RotR1(PPK[5] ^ Mk16_le((__le16 *) & TK[12]));
291 PPK[1] += RotR1(PPK[0] ^ Mk16_le((__le16 *) & TK[14]));
292 PPK[2] += RotR1(PPK[1]);
293 PPK[3] += RotR1(PPK[2]);
294 PPK[4] += RotR1(PPK[3]);
295 PPK[5] += RotR1(PPK[4]);
296
297 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
298 * WEPSeed[0..2] is transmitted as WEP IV */
299 WEPSeed[0] = Hi8(IV16);
300 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
301 WEPSeed[2] = Lo8(IV16);
302 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((__le16 *) & TK[0])) >> 1);
303
304#ifdef __BIG_ENDIAN
305 {
306 int i;
307 for (i = 0; i < 6; i++)
308 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
309 }
310#endif
311}
312
313static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
314 u8 * rc4key, int keylen, void *priv)
315{
316 struct lib80211_tkip_data *tkey = priv;
317 int len;
318 u8 *pos;
319 struct ieee80211_hdr *hdr;
320
321 hdr = (struct ieee80211_hdr *)skb->data;
322
323 if (skb_headroom(skb) < 8 || skb->len < hdr_len)
324 return -1;
325
326 if (rc4key == NULL || keylen < 16)
327 return -1;
328
329 if (!tkey->tx_phase1_done) {
330 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
331 tkey->tx_iv32);
332 tkey->tx_phase1_done = 1;
333 }
334 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
335
336 len = skb->len - hdr_len;
337 pos = skb_push(skb, 8);
338 memmove(pos, pos + 8, hdr_len);
339 pos += hdr_len;
340
341 *pos++ = *rc4key;
342 *pos++ = *(rc4key + 1);
343 *pos++ = *(rc4key + 2);
344 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
345 *pos++ = tkey->tx_iv32 & 0xff;
346 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
347 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
348 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
349
350 tkey->tx_iv16++;
351 if (tkey->tx_iv16 == 0) {
352 tkey->tx_phase1_done = 0;
353 tkey->tx_iv32++;
354 }
355
356 return 8;
357}
358
359static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
360{
361 struct lib80211_tkip_data *tkey = priv;
362 struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
363 int len;
364 u8 rc4key[16], *pos, *icv;
365 u32 crc;
366 struct scatterlist sg;
367
368 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
369 if (net_ratelimit()) {
370 struct ieee80211_hdr *hdr =
371 (struct ieee80211_hdr *)skb->data;
372 printk(KERN_DEBUG ": TKIP countermeasures: dropped "
373 "TX packet to %pM\n", hdr->addr1);
374 }
375 return -1;
376 }
377
378 if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
379 return -1;
380
381 len = skb->len - hdr_len;
382 pos = skb->data + hdr_len;
383
384 if ((lib80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
385 return -1;
386
387 icv = skb_put(skb, 4);
388
389 crc = ~crc32_le(~0, pos, len);
390 icv[0] = crc;
391 icv[1] = crc >> 8;
392 icv[2] = crc >> 16;
393 icv[3] = crc >> 24;
394
395 crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
396 sg_init_one(&sg, pos, len + 4);
397 return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
398}
399
400/*
401 * deal with seq counter wrapping correctly.
402 * refer to timer_after() for jiffies wrapping handling
403 */
404static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
405 u32 iv32_o, u16 iv16_o)
406{
407 if ((s32)iv32_n - (s32)iv32_o < 0 ||
408 (iv32_n == iv32_o && iv16_n <= iv16_o))
409 return 1;
410 return 0;
411}
412
413static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
414{
415 struct lib80211_tkip_data *tkey = priv;
416 struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
417 u8 rc4key[16];
418 u8 keyidx, *pos;
419 u32 iv32;
420 u16 iv16;
421 struct ieee80211_hdr *hdr;
422 u8 icv[4];
423 u32 crc;
424 struct scatterlist sg;
425 int plen;
426
427 hdr = (struct ieee80211_hdr *)skb->data;
428
429 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
430 if (net_ratelimit()) {
431 printk(KERN_DEBUG ": TKIP countermeasures: dropped "
432 "received packet from %pM\n", hdr->addr2);
433 }
434 return -1;
435 }
436
437 if (skb->len < hdr_len + 8 + 4)
438 return -1;
439
440 pos = skb->data + hdr_len;
441 keyidx = pos[3];
442 if (!(keyidx & (1 << 5))) {
443 if (net_ratelimit()) {
444 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
445 " flag from %pM\n", hdr->addr2);
446 }
447 return -2;
448 }
449 keyidx >>= 6;
450 if (tkey->key_idx != keyidx) {
451 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
452 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
453 return -6;
454 }
455 if (!tkey->key_set) {
456 if (net_ratelimit()) {
457 printk(KERN_DEBUG "TKIP: received packet from %pM"
458 " with keyid=%d that does not have a configured"
459 " key\n", hdr->addr2, keyidx);
460 }
461 return -3;
462 }
463 iv16 = (pos[0] << 8) | pos[2];
464 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
465 pos += 8;
466
467 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
468 if (net_ratelimit()) {
469 printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
470 " previous TSC %08x%04x received TSC "
471 "%08x%04x\n", hdr->addr2,
472 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
473 }
474 tkey->dot11RSNAStatsTKIPReplays++;
475 return -4;
476 }
477
478 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
479 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
480 tkey->rx_phase1_done = 1;
481 }
482 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
483
484 plen = skb->len - hdr_len - 12;
485
486 crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
487 sg_init_one(&sg, pos, plen + 4);
488 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
489 if (net_ratelimit()) {
490 printk(KERN_DEBUG ": TKIP: failed to decrypt "
491 "received packet from %pM\n",
492 hdr->addr2);
493 }
494 return -7;
495 }
496
497 crc = ~crc32_le(~0, pos, plen);
498 icv[0] = crc;
499 icv[1] = crc >> 8;
500 icv[2] = crc >> 16;
501 icv[3] = crc >> 24;
502 if (memcmp(icv, pos + plen, 4) != 0) {
503 if (iv32 != tkey->rx_iv32) {
504 /* Previously cached Phase1 result was already lost, so
505 * it needs to be recalculated for the next packet. */
506 tkey->rx_phase1_done = 0;
507 }
508 if (net_ratelimit()) {
509 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
510 "%pM\n", hdr->addr2);
511 }
512 tkey->dot11RSNAStatsTKIPICVErrors++;
513 return -5;
514 }
515
516 /* Update real counters only after Michael MIC verification has
517 * completed */
518 tkey->rx_iv32_new = iv32;
519 tkey->rx_iv16_new = iv16;
520
521 /* Remove IV and ICV */
522 memmove(skb->data + 8, skb->data, hdr_len);
523 skb_pull(skb, 8);
524 skb_trim(skb, skb->len - 4);
525
526 return keyidx;
527}
528
529static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
530 u8 * data, size_t data_len, u8 * mic)
531{
532 struct hash_desc desc;
533 struct scatterlist sg[2];
534
535 if (tfm_michael == NULL) {
536 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
537 return -1;
538 }
539 sg_init_table(sg, 2);
540 sg_set_buf(&sg[0], hdr, 16);
541 sg_set_buf(&sg[1], data, data_len);
542
543 if (crypto_hash_setkey(tfm_michael, key, 8))
544 return -1;
545
546 desc.tfm = tfm_michael;
547 desc.flags = 0;
548 return crypto_hash_digest(&desc, sg, data_len + 16, mic);
549}
550
551static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
552{
553 struct ieee80211_hdr *hdr11;
554
555 hdr11 = (struct ieee80211_hdr *)skb->data;
556
557 switch (le16_to_cpu(hdr11->frame_control) &
558 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
559 case IEEE80211_FCTL_TODS:
560 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
561 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
562 break;
563 case IEEE80211_FCTL_FROMDS:
564 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
565 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
566 break;
567 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
568 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
569 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
570 break;
571 case 0:
572 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
573 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
574 break;
575 }
576
577 if (ieee80211_is_data_qos(hdr11->frame_control)) {
578 hdr[12] = le16_to_cpu(*ieee80211_get_qos_ctl(hdr11))
579 & IEEE80211_QOS_CTL_TID_MASK;
580 } else
581 hdr[12] = 0; /* priority */
582
583 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
584}
585
586static int lib80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
587 void *priv)
588{
589 struct lib80211_tkip_data *tkey = priv;
590 u8 *pos;
591
592 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
593 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
594 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
595 skb_tailroom(skb), hdr_len, skb->len);
596 return -1;
597 }
598
599 michael_mic_hdr(skb, tkey->tx_hdr);
600 pos = skb_put(skb, 8);
601 if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
602 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
603 return -1;
604
605 return 0;
606}
607
608static void lib80211_michael_mic_failure(struct net_device *dev,
609 struct ieee80211_hdr *hdr,
610 int keyidx)
611{
612 union iwreq_data wrqu;
613 struct iw_michaelmicfailure ev;
614
615 /* TODO: needed parameters: count, keyid, key type, TSC */
616 memset(&ev, 0, sizeof(ev));
617 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
618 if (hdr->addr1[0] & 0x01)
619 ev.flags |= IW_MICFAILURE_GROUP;
620 else
621 ev.flags |= IW_MICFAILURE_PAIRWISE;
622 ev.src_addr.sa_family = ARPHRD_ETHER;
623 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
624 memset(&wrqu, 0, sizeof(wrqu));
625 wrqu.data.length = sizeof(ev);
626 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
627}
628
629static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
630 int hdr_len, void *priv)
631{
632 struct lib80211_tkip_data *tkey = priv;
633 u8 mic[8];
634
635 if (!tkey->key_set)
636 return -1;
637
638 michael_mic_hdr(skb, tkey->rx_hdr);
639 if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
640 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
641 return -1;
642 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
643 struct ieee80211_hdr *hdr;
644 hdr = (struct ieee80211_hdr *)skb->data;
645 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
646 "MSDU from %pM keyidx=%d\n",
647 skb->dev ? skb->dev->name : "N/A", hdr->addr2,
648 keyidx);
649 if (skb->dev)
650 lib80211_michael_mic_failure(skb->dev, hdr, keyidx);
651 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
652 return -1;
653 }
654
655 /* Update TSC counters for RX now that the packet verification has
656 * completed. */
657 tkey->rx_iv32 = tkey->rx_iv32_new;
658 tkey->rx_iv16 = tkey->rx_iv16_new;
659
660 skb_trim(skb, skb->len - 8);
661
662 return 0;
663}
664
665static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
666{
667 struct lib80211_tkip_data *tkey = priv;
668 int keyidx;
669 struct crypto_hash *tfm = tkey->tx_tfm_michael;
670 struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
671 struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
672 struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
673
674 keyidx = tkey->key_idx;
675 memset(tkey, 0, sizeof(*tkey));
676 tkey->key_idx = keyidx;
677 tkey->tx_tfm_michael = tfm;
678 tkey->tx_tfm_arc4 = tfm2;
679 tkey->rx_tfm_michael = tfm3;
680 tkey->rx_tfm_arc4 = tfm4;
681 if (len == TKIP_KEY_LEN) {
682 memcpy(tkey->key, key, TKIP_KEY_LEN);
683 tkey->key_set = 1;
684 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
685 if (seq) {
686 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
687 (seq[3] << 8) | seq[2];
688 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
689 }
690 } else if (len == 0)
691 tkey->key_set = 0;
692 else
693 return -1;
694
695 return 0;
696}
697
698static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
699{
700 struct lib80211_tkip_data *tkey = priv;
701
702 if (len < TKIP_KEY_LEN)
703 return -1;
704
705 if (!tkey->key_set)
706 return 0;
707 memcpy(key, tkey->key, TKIP_KEY_LEN);
708
709 if (seq) {
710 /* Return the sequence number of the last transmitted frame. */
711 u16 iv16 = tkey->tx_iv16;
712 u32 iv32 = tkey->tx_iv32;
713 if (iv16 == 0)
714 iv32--;
715 iv16--;
716 seq[0] = tkey->tx_iv16;
717 seq[1] = tkey->tx_iv16 >> 8;
718 seq[2] = tkey->tx_iv32;
719 seq[3] = tkey->tx_iv32 >> 8;
720 seq[4] = tkey->tx_iv32 >> 16;
721 seq[5] = tkey->tx_iv32 >> 24;
722 }
723
724 return TKIP_KEY_LEN;
725}
726
727static char *lib80211_tkip_print_stats(char *p, void *priv)
728{
729 struct lib80211_tkip_data *tkip = priv;
730 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
731 "tx_pn=%02x%02x%02x%02x%02x%02x "
732 "rx_pn=%02x%02x%02x%02x%02x%02x "
733 "replays=%d icv_errors=%d local_mic_failures=%d\n",
734 tkip->key_idx, tkip->key_set,
735 (tkip->tx_iv32 >> 24) & 0xff,
736 (tkip->tx_iv32 >> 16) & 0xff,
737 (tkip->tx_iv32 >> 8) & 0xff,
738 tkip->tx_iv32 & 0xff,
739 (tkip->tx_iv16 >> 8) & 0xff,
740 tkip->tx_iv16 & 0xff,
741 (tkip->rx_iv32 >> 24) & 0xff,
742 (tkip->rx_iv32 >> 16) & 0xff,
743 (tkip->rx_iv32 >> 8) & 0xff,
744 tkip->rx_iv32 & 0xff,
745 (tkip->rx_iv16 >> 8) & 0xff,
746 tkip->rx_iv16 & 0xff,
747 tkip->dot11RSNAStatsTKIPReplays,
748 tkip->dot11RSNAStatsTKIPICVErrors,
749 tkip->dot11RSNAStatsTKIPLocalMICFailures);
750 return p;
751}
752
753static struct lib80211_crypto_ops lib80211_crypt_tkip = {
754 .name = "TKIP",
755 .init = lib80211_tkip_init,
756 .deinit = lib80211_tkip_deinit,
757 .build_iv = lib80211_tkip_hdr,
758 .encrypt_mpdu = lib80211_tkip_encrypt,
759 .decrypt_mpdu = lib80211_tkip_decrypt,
760 .encrypt_msdu = lib80211_michael_mic_add,
761 .decrypt_msdu = lib80211_michael_mic_verify,
762 .set_key = lib80211_tkip_set_key,
763 .get_key = lib80211_tkip_get_key,
764 .print_stats = lib80211_tkip_print_stats,
765 .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
766 .extra_mpdu_postfix_len = 4, /* ICV */
767 .extra_msdu_postfix_len = 8, /* MIC */
768 .get_flags = lib80211_tkip_get_flags,
769 .set_flags = lib80211_tkip_set_flags,
770 .owner = THIS_MODULE,
771};
772
773static int __init lib80211_crypto_tkip_init(void)
774{
775 return lib80211_register_crypto_ops(&lib80211_crypt_tkip);
776}
777
778static void __exit lib80211_crypto_tkip_exit(void)
779{
780 lib80211_unregister_crypto_ops(&lib80211_crypt_tkip);
781}
782
783module_init(lib80211_crypto_tkip_init);
784module_exit(lib80211_crypto_tkip_exit);
diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c
new file mode 100644
index 000000000000..6d41e05ca33b
--- /dev/null
+++ b/net/wireless/lib80211_crypt_wep.c
@@ -0,0 +1,296 @@
1/*
2 * lib80211 crypt: host-based WEP encryption implementation for lib80211
3 *
4 * Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi>
5 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 */
12
13#include <linux/err.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/scatterlist.h>
19#include <linux/skbuff.h>
20#include <linux/mm.h>
21#include <asm/string.h>
22
23#include <net/lib80211.h>
24
25#include <linux/crypto.h>
26#include <linux/crc32.h>
27
28MODULE_AUTHOR("Jouni Malinen");
29MODULE_DESCRIPTION("lib80211 crypt: WEP");
30MODULE_LICENSE("GPL");
31
32struct lib80211_wep_data {
33 u32 iv;
34#define WEP_KEY_LEN 13
35 u8 key[WEP_KEY_LEN + 1];
36 u8 key_len;
37 u8 key_idx;
38 struct crypto_blkcipher *tx_tfm;
39 struct crypto_blkcipher *rx_tfm;
40};
41
42static void *lib80211_wep_init(int keyidx)
43{
44 struct lib80211_wep_data *priv;
45
46 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
47 if (priv == NULL)
48 goto fail;
49 priv->key_idx = keyidx;
50
51 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
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;
56 goto fail;
57 }
58
59 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
60 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;
64 goto fail;
65 }
66 /* start WEP IV from a random value */
67 get_random_bytes(&priv->iv, 4);
68
69 return priv;
70
71 fail:
72 if (priv) {
73 if (priv->tx_tfm)
74 crypto_free_blkcipher(priv->tx_tfm);
75 if (priv->rx_tfm)
76 crypto_free_blkcipher(priv->rx_tfm);
77 kfree(priv);
78 }
79 return NULL;
80}
81
82static void lib80211_wep_deinit(void *priv)
83{
84 struct lib80211_wep_data *_priv = priv;
85 if (_priv) {
86 if (_priv->tx_tfm)
87 crypto_free_blkcipher(_priv->tx_tfm);
88 if (_priv->rx_tfm)
89 crypto_free_blkcipher(_priv->rx_tfm);
90 }
91 kfree(priv);
92}
93
94/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
95static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
96 u8 *key, int keylen, void *priv)
97{
98 struct lib80211_wep_data *wep = priv;
99 u32 klen, len;
100 u8 *pos;
101
102 if (skb_headroom(skb) < 4 || skb->len < hdr_len)
103 return -1;
104
105 len = skb->len - hdr_len;
106 pos = skb_push(skb, 4);
107 memmove(pos, pos + 4, hdr_len);
108 pos += hdr_len;
109
110 klen = 3 + wep->key_len;
111
112 wep->iv++;
113
114 /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
115 * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
116 * can be used to speedup attacks, so avoid using them. */
117 if ((wep->iv & 0xff00) == 0xff00) {
118 u8 B = (wep->iv >> 16) & 0xff;
119 if (B >= 3 && B < klen)
120 wep->iv += 0x0100;
121 }
122
123 /* Prepend 24-bit IV to RC4 key and TX frame */
124 *pos++ = (wep->iv >> 16) & 0xff;
125 *pos++ = (wep->iv >> 8) & 0xff;
126 *pos++ = wep->iv & 0xff;
127 *pos++ = wep->key_idx << 6;
128
129 return 0;
130}
131
132/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
133 * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
134 * so the payload length increases with 8 bytes.
135 *
136 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
137 */
138static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
139{
140 struct lib80211_wep_data *wep = priv;
141 struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
142 u32 crc, klen, len;
143 u8 *pos, *icv;
144 struct scatterlist sg;
145 u8 key[WEP_KEY_LEN + 3];
146
147 /* other checks are in lib80211_wep_build_iv */
148 if (skb_tailroom(skb) < 4)
149 return -1;
150
151 /* add the IV to the frame */
152 if (lib80211_wep_build_iv(skb, hdr_len, NULL, 0, priv))
153 return -1;
154
155 /* Copy the IV into the first 3 bytes of the key */
156 skb_copy_from_linear_data_offset(skb, hdr_len, key, 3);
157
158 /* Copy rest of the WEP key (the secret part) */
159 memcpy(key + 3, wep->key, wep->key_len);
160
161 len = skb->len - hdr_len - 4;
162 pos = skb->data + hdr_len + 4;
163 klen = 3 + wep->key_len;
164
165 /* Append little-endian CRC32 over only the data and encrypt it to produce ICV */
166 crc = ~crc32_le(~0, pos, len);
167 icv = skb_put(skb, 4);
168 icv[0] = crc;
169 icv[1] = crc >> 8;
170 icv[2] = crc >> 16;
171 icv[3] = crc >> 24;
172
173 crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
174 sg_init_one(&sg, pos, len + 4);
175 return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
176}
177
178/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
179 * the frame: IV (4 bytes), encrypted payload (including SNAP header),
180 * ICV (4 bytes). len includes both IV and ICV.
181 *
182 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
183 * failure. If frame is OK, IV and ICV will be removed.
184 */
185static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
186{
187 struct lib80211_wep_data *wep = priv;
188 struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
189 u32 crc, klen, plen;
190 u8 key[WEP_KEY_LEN + 3];
191 u8 keyidx, *pos, icv[4];
192 struct scatterlist sg;
193
194 if (skb->len < hdr_len + 8)
195 return -1;
196
197 pos = skb->data + hdr_len;
198 key[0] = *pos++;
199 key[1] = *pos++;
200 key[2] = *pos++;
201 keyidx = *pos++ >> 6;
202 if (keyidx != wep->key_idx)
203 return -1;
204
205 klen = 3 + wep->key_len;
206
207 /* Copy rest of the WEP key (the secret part) */
208 memcpy(key + 3, wep->key, wep->key_len);
209
210 /* Apply RC4 to data and compute CRC32 over decrypted data */
211 plen = skb->len - hdr_len - 8;
212
213 crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
214 sg_init_one(&sg, pos, plen + 4);
215 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
216 return -7;
217
218 crc = ~crc32_le(~0, pos, plen);
219 icv[0] = crc;
220 icv[1] = crc >> 8;
221 icv[2] = crc >> 16;
222 icv[3] = crc >> 24;
223 if (memcmp(icv, pos + plen, 4) != 0) {
224 /* ICV mismatch - drop frame */
225 return -2;
226 }
227
228 /* Remove IV and ICV */
229 memmove(skb->data + 4, skb->data, hdr_len);
230 skb_pull(skb, 4);
231 skb_trim(skb, skb->len - 4);
232
233 return 0;
234}
235
236static int lib80211_wep_set_key(void *key, int len, u8 * seq, void *priv)
237{
238 struct lib80211_wep_data *wep = priv;
239
240 if (len < 0 || len > WEP_KEY_LEN)
241 return -1;
242
243 memcpy(wep->key, key, len);
244 wep->key_len = len;
245
246 return 0;
247}
248
249static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv)
250{
251 struct lib80211_wep_data *wep = priv;
252
253 if (len < wep->key_len)
254 return -1;
255
256 memcpy(key, wep->key, wep->key_len);
257
258 return wep->key_len;
259}
260
261static char *lib80211_wep_print_stats(char *p, void *priv)
262{
263 struct lib80211_wep_data *wep = priv;
264 p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
265 return p;
266}
267
268static struct lib80211_crypto_ops lib80211_crypt_wep = {
269 .name = "WEP",
270 .init = lib80211_wep_init,
271 .deinit = lib80211_wep_deinit,
272 .build_iv = lib80211_wep_build_iv,
273 .encrypt_mpdu = lib80211_wep_encrypt,
274 .decrypt_mpdu = lib80211_wep_decrypt,
275 .encrypt_msdu = NULL,
276 .decrypt_msdu = NULL,
277 .set_key = lib80211_wep_set_key,
278 .get_key = lib80211_wep_get_key,
279 .print_stats = lib80211_wep_print_stats,
280 .extra_mpdu_prefix_len = 4, /* IV */
281 .extra_mpdu_postfix_len = 4, /* ICV */
282 .owner = THIS_MODULE,
283};
284
285static int __init lib80211_crypto_wep_init(void)
286{
287 return lib80211_register_crypto_ops(&lib80211_crypt_wep);
288}
289
290static void __exit lib80211_crypto_wep_exit(void)
291{
292 lib80211_unregister_crypto_ops(&lib80211_crypt_wep);
293}
294
295module_init(lib80211_crypto_wep_init);
296module_exit(lib80211_crypto_wep_exit);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 572793c8c7ab..1e728fff474e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -58,6 +58,9 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
58 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, 58 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
59 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, 59 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
60 .len = BUS_ID_SIZE-1 }, 60 .len = BUS_ID_SIZE-1 },
61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
61 64
62 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, 65 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
63 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 66 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -84,7 +87,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
84 .len = NL80211_MAX_SUPP_RATES }, 87 .len = NL80211_MAX_SUPP_RATES },
85 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 }, 88 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
86 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, 89 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
87 [NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED }, 90 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
88 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, 91 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
89 .len = IEEE80211_MAX_MESH_ID_LEN }, 92 .len = IEEE80211_MAX_MESH_ID_LEN },
90 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, 93 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
@@ -95,6 +98,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
95 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 }, 98 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
96 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 }, 99 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
97 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 }, 100 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
101 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
102 .len = NL80211_MAX_SUPP_RATES },
103
104 [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED },
98 105
99 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 106 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
100 .len = NL80211_HT_CAPABILITY_LEN }, 107 .len = NL80211_HT_CAPABILITY_LEN },
@@ -157,6 +164,19 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
157 if (!nl_band) 164 if (!nl_band)
158 goto nla_put_failure; 165 goto nla_put_failure;
159 166
167 /* add HT info */
168 if (dev->wiphy.bands[band]->ht_cap.ht_supported) {
169 NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET,
170 sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
171 &dev->wiphy.bands[band]->ht_cap.mcs);
172 NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA,
173 dev->wiphy.bands[band]->ht_cap.cap);
174 NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
175 dev->wiphy.bands[band]->ht_cap.ampdu_factor);
176 NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
177 dev->wiphy.bands[band]->ht_cap.ampdu_density);
178 }
179
160 /* add frequencies */ 180 /* add frequencies */
161 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS); 181 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
162 if (!nl_freqs) 182 if (!nl_freqs)
@@ -180,6 +200,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
180 if (chan->flags & IEEE80211_CHAN_RADAR) 200 if (chan->flags & IEEE80211_CHAN_RADAR)
181 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR); 201 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
182 202
203 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
204 DBM_TO_MBM(chan->max_power));
205
183 nla_nest_end(msg, nl_freq); 206 nla_nest_end(msg, nl_freq);
184 } 207 }
185 208
@@ -269,20 +292,142 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
269 return -ENOBUFS; 292 return -ENOBUFS;
270} 293}
271 294
295static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
296 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
297 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
298 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
299 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
300 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
301};
302
303static int parse_txq_params(struct nlattr *tb[],
304 struct ieee80211_txq_params *txq_params)
305{
306 if (!tb[NL80211_TXQ_ATTR_QUEUE] || !tb[NL80211_TXQ_ATTR_TXOP] ||
307 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
308 !tb[NL80211_TXQ_ATTR_AIFS])
309 return -EINVAL;
310
311 txq_params->queue = nla_get_u8(tb[NL80211_TXQ_ATTR_QUEUE]);
312 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
313 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
314 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
315 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
316
317 return 0;
318}
319
272static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) 320static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
273{ 321{
274 struct cfg80211_registered_device *rdev; 322 struct cfg80211_registered_device *rdev;
275 int result; 323 int result = 0, rem_txq_params = 0;
276 324 struct nlattr *nl_txq_params;
277 if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
278 return -EINVAL;
279 325
280 rdev = cfg80211_get_dev_from_info(info); 326 rdev = cfg80211_get_dev_from_info(info);
281 if (IS_ERR(rdev)) 327 if (IS_ERR(rdev))
282 return PTR_ERR(rdev); 328 return PTR_ERR(rdev);
283 329
284 result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); 330 if (info->attrs[NL80211_ATTR_WIPHY_NAME]) {
331 result = cfg80211_dev_rename(
332 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
333 if (result)
334 goto bad_res;
335 }
336
337 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
338 struct ieee80211_txq_params txq_params;
339 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
340
341 if (!rdev->ops->set_txq_params) {
342 result = -EOPNOTSUPP;
343 goto bad_res;
344 }
345
346 nla_for_each_nested(nl_txq_params,
347 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
348 rem_txq_params) {
349 nla_parse(tb, NL80211_TXQ_ATTR_MAX,
350 nla_data(nl_txq_params),
351 nla_len(nl_txq_params),
352 txq_params_policy);
353 result = parse_txq_params(tb, &txq_params);
354 if (result)
355 goto bad_res;
356
357 result = rdev->ops->set_txq_params(&rdev->wiphy,
358 &txq_params);
359 if (result)
360 goto bad_res;
361 }
362 }
363
364 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
365 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
366 struct ieee80211_channel *chan;
367 struct ieee80211_sta_ht_cap *ht_cap;
368 u32 freq, sec_freq;
369
370 if (!rdev->ops->set_channel) {
371 result = -EOPNOTSUPP;
372 goto bad_res;
373 }
374
375 result = -EINVAL;
376
377 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
378 channel_type = nla_get_u32(info->attrs[
379 NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
380 if (channel_type != NL80211_CHAN_NO_HT &&
381 channel_type != NL80211_CHAN_HT20 &&
382 channel_type != NL80211_CHAN_HT40PLUS &&
383 channel_type != NL80211_CHAN_HT40MINUS)
384 goto bad_res;
385 }
386
387 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
388 chan = ieee80211_get_channel(&rdev->wiphy, freq);
389
390 /* Primary channel not allowed */
391 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
392 goto bad_res;
393
394 if (channel_type == NL80211_CHAN_HT40MINUS)
395 sec_freq = freq - 20;
396 else if (channel_type == NL80211_CHAN_HT40PLUS)
397 sec_freq = freq + 20;
398 else
399 sec_freq = 0;
400
401 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
285 402
403 /* no HT capabilities */
404 if (channel_type != NL80211_CHAN_NO_HT &&
405 !ht_cap->ht_supported)
406 goto bad_res;
407
408 if (sec_freq) {
409 struct ieee80211_channel *schan;
410
411 /* no 40 MHz capabilities */
412 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
413 (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
414 goto bad_res;
415
416 schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
417
418 /* Secondary channel not allowed */
419 if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
420 goto bad_res;
421 }
422
423 result = rdev->ops->set_channel(&rdev->wiphy, chan,
424 channel_type);
425 if (result)
426 goto bad_res;
427 }
428
429
430 bad_res:
286 cfg80211_put_dev(rdev); 431 cfg80211_put_dev(rdev);
287 return result; 432 return result;
288} 433}
@@ -945,12 +1090,46 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)
945 return 0; 1090 return 0;
946} 1091}
947 1092
1093static u16 nl80211_calculate_bitrate(struct rate_info *rate)
1094{
1095 int modulation, streams, bitrate;
1096
1097 if (!(rate->flags & RATE_INFO_FLAGS_MCS))
1098 return rate->legacy;
1099
1100 /* the formula below does only work for MCS values smaller than 32 */
1101 if (rate->mcs >= 32)
1102 return 0;
1103
1104 modulation = rate->mcs & 7;
1105 streams = (rate->mcs >> 3) + 1;
1106
1107 bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
1108 13500000 : 6500000;
1109
1110 if (modulation < 4)
1111 bitrate *= (modulation + 1);
1112 else if (modulation == 4)
1113 bitrate *= (modulation + 2);
1114 else
1115 bitrate *= (modulation + 3);
1116
1117 bitrate *= streams;
1118
1119 if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
1120 bitrate = (bitrate / 9) * 10;
1121
1122 /* do NOT round down here */
1123 return (bitrate + 50000) / 100000;
1124}
1125
948static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, 1126static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
949 int flags, struct net_device *dev, 1127 int flags, struct net_device *dev,
950 u8 *mac_addr, struct station_info *sinfo) 1128 u8 *mac_addr, struct station_info *sinfo)
951{ 1129{
952 void *hdr; 1130 void *hdr;
953 struct nlattr *sinfoattr; 1131 struct nlattr *sinfoattr, *txrate;
1132 u16 bitrate;
954 1133
955 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); 1134 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
956 if (!hdr) 1135 if (!hdr)
@@ -980,7 +1159,29 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
980 if (sinfo->filled & STATION_INFO_PLINK_STATE) 1159 if (sinfo->filled & STATION_INFO_PLINK_STATE)
981 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE, 1160 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
982 sinfo->plink_state); 1161 sinfo->plink_state);
1162 if (sinfo->filled & STATION_INFO_SIGNAL)
1163 NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
1164 sinfo->signal);
1165 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
1166 txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
1167 if (!txrate)
1168 goto nla_put_failure;
1169
1170 /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
1171 bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
1172 if (bitrate > 0)
1173 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
1174
1175 if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
1176 NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
1177 sinfo->txrate.mcs);
1178 if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
1179 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
1180 if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
1181 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
983 1182
1183 nla_nest_end(msg, txrate);
1184 }
984 nla_nest_end(msg, sinfoattr); 1185 nla_nest_end(msg, sinfoattr);
985 1186
986 return genlmsg_end(msg, hdr); 1187 return genlmsg_end(msg, hdr);
@@ -1598,6 +1799,12 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1598 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]) 1799 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
1599 params.use_short_slot_time = 1800 params.use_short_slot_time =
1600 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]); 1801 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
1802 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
1803 params.basic_rates =
1804 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
1805 params.basic_rates_len =
1806 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
1807 }
1601 1808
1602 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1809 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1603 if (err) 1810 if (err)
@@ -1680,11 +1887,188 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
1680 return -EINVAL; 1887 return -EINVAL;
1681#endif 1888#endif
1682 mutex_lock(&cfg80211_drv_mutex); 1889 mutex_lock(&cfg80211_drv_mutex);
1683 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, NULL); 1890 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY);
1684 mutex_unlock(&cfg80211_drv_mutex); 1891 mutex_unlock(&cfg80211_drv_mutex);
1685 return r; 1892 return r;
1686} 1893}
1687 1894
1895static int nl80211_get_mesh_params(struct sk_buff *skb,
1896 struct genl_info *info)
1897{
1898 struct cfg80211_registered_device *drv;
1899 struct mesh_config cur_params;
1900 int err;
1901 struct net_device *dev;
1902 void *hdr;
1903 struct nlattr *pinfoattr;
1904 struct sk_buff *msg;
1905
1906 /* Look up our device */
1907 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1908 if (err)
1909 return err;
1910
1911 /* Get the mesh params */
1912 rtnl_lock();
1913 err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params);
1914 rtnl_unlock();
1915 if (err)
1916 goto out;
1917
1918 /* Draw up a netlink message to send back */
1919 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1920 if (!msg) {
1921 err = -ENOBUFS;
1922 goto out;
1923 }
1924 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
1925 NL80211_CMD_GET_MESH_PARAMS);
1926 if (!hdr)
1927 goto nla_put_failure;
1928 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
1929 if (!pinfoattr)
1930 goto nla_put_failure;
1931 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1932 NLA_PUT_U16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
1933 cur_params.dot11MeshRetryTimeout);
1934 NLA_PUT_U16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
1935 cur_params.dot11MeshConfirmTimeout);
1936 NLA_PUT_U16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
1937 cur_params.dot11MeshHoldingTimeout);
1938 NLA_PUT_U16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
1939 cur_params.dot11MeshMaxPeerLinks);
1940 NLA_PUT_U8(msg, NL80211_MESHCONF_MAX_RETRIES,
1941 cur_params.dot11MeshMaxRetries);
1942 NLA_PUT_U8(msg, NL80211_MESHCONF_TTL,
1943 cur_params.dot11MeshTTL);
1944 NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
1945 cur_params.auto_open_plinks);
1946 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
1947 cur_params.dot11MeshHWMPmaxPREQretries);
1948 NLA_PUT_U32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
1949 cur_params.path_refresh_time);
1950 NLA_PUT_U16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
1951 cur_params.min_discovery_timeout);
1952 NLA_PUT_U32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
1953 cur_params.dot11MeshHWMPactivePathTimeout);
1954 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
1955 cur_params.dot11MeshHWMPpreqMinInterval);
1956 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
1957 cur_params.dot11MeshHWMPnetDiameterTraversalTime);
1958 nla_nest_end(msg, pinfoattr);
1959 genlmsg_end(msg, hdr);
1960 err = genlmsg_unicast(msg, info->snd_pid);
1961 goto out;
1962
1963nla_put_failure:
1964 genlmsg_cancel(msg, hdr);
1965 err = -EMSGSIZE;
1966out:
1967 /* Cleanup */
1968 cfg80211_put_dev(drv);
1969 dev_put(dev);
1970 return err;
1971}
1972
1973#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
1974do {\
1975 if (table[attr_num]) {\
1976 cfg.param = nla_fn(table[attr_num]); \
1977 mask |= (1 << (attr_num - 1)); \
1978 } \
1979} while (0);\
1980
1981static struct nla_policy
1982nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] __read_mostly = {
1983 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
1984 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
1985 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
1986 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
1987 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
1988 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
1989 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
1990
1991 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
1992 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
1993 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
1994 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
1995 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
1996 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
1997};
1998
1999static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2000{
2001 int err;
2002 u32 mask;
2003 struct cfg80211_registered_device *drv;
2004 struct net_device *dev;
2005 struct mesh_config cfg;
2006 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
2007 struct nlattr *parent_attr;
2008
2009 parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS];
2010 if (!parent_attr)
2011 return -EINVAL;
2012 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
2013 parent_attr, nl80211_meshconf_params_policy))
2014 return -EINVAL;
2015
2016 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2017 if (err)
2018 return err;
2019
2020 /* This makes sure that there aren't more than 32 mesh config
2021 * parameters (otherwise our bitfield scheme would not work.) */
2022 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
2023
2024 /* Fill in the params struct */
2025 mask = 0;
2026 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
2027 mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
2028 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
2029 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16);
2030 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
2031 mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16);
2032 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
2033 mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16);
2034 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
2035 mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
2036 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
2037 mask, NL80211_MESHCONF_TTL, nla_get_u8);
2038 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
2039 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
2040 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
2041 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
2042 nla_get_u8);
2043 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
2044 mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32);
2045 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
2046 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
2047 nla_get_u16);
2048 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
2049 mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
2050 nla_get_u32);
2051 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
2052 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
2053 nla_get_u16);
2054 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
2055 dot11MeshHWMPnetDiameterTraversalTime,
2056 mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
2057 nla_get_u16);
2058
2059 /* Apply changes */
2060 rtnl_lock();
2061 err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask);
2062 rtnl_unlock();
2063
2064 /* cleanup */
2065 cfg80211_put_dev(drv);
2066 dev_put(dev);
2067 return err;
2068}
2069
2070#undef FILL_IN_MESH_PARAM_IF_SET
2071
1688static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 2072static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
1689{ 2073{
1690 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; 2074 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -1743,12 +2127,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
1743 mutex_lock(&cfg80211_drv_mutex); 2127 mutex_lock(&cfg80211_drv_mutex);
1744 r = set_regdom(rd); 2128 r = set_regdom(rd);
1745 mutex_unlock(&cfg80211_drv_mutex); 2129 mutex_unlock(&cfg80211_drv_mutex);
1746 if (r)
1747 goto bad_reg;
1748
1749 return r; 2130 return r;
1750 2131
1751bad_reg: 2132 bad_reg:
1752 kfree(rd); 2133 kfree(rd);
1753 return -EINVAL; 2134 return -EINVAL;
1754} 2135}
@@ -1902,6 +2283,18 @@ static struct genl_ops nl80211_ops[] = {
1902 .policy = nl80211_policy, 2283 .policy = nl80211_policy,
1903 .flags = GENL_ADMIN_PERM, 2284 .flags = GENL_ADMIN_PERM,
1904 }, 2285 },
2286 {
2287 .cmd = NL80211_CMD_GET_MESH_PARAMS,
2288 .doit = nl80211_get_mesh_params,
2289 .policy = nl80211_policy,
2290 /* can be retrieved by unprivileged users */
2291 },
2292 {
2293 .cmd = NL80211_CMD_SET_MESH_PARAMS,
2294 .doit = nl80211_set_mesh_params,
2295 .policy = nl80211_policy,
2296 .flags = GENL_ADMIN_PERM,
2297 },
1905}; 2298};
1906 2299
1907/* multicast groups */ 2300/* multicast groups */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index eb3b1a9f9b12..4f877535e666 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -42,17 +42,40 @@
42#include "core.h" 42#include "core.h"
43#include "reg.h" 43#include "reg.h"
44 44
45/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */ 45/**
46 * struct regulatory_request - receipt of last regulatory request
47 *
48 * @wiphy: this is set if this request's initiator is
49 * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
50 * can be used by the wireless core to deal with conflicts
51 * and potentially inform users of which devices specifically
52 * cased the conflicts.
53 * @initiator: indicates who sent this request, could be any of
54 * of those set in reg_set_by, %REGDOM_SET_BY_*
55 * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
56 * regulatory domain. We have a few special codes:
57 * 00 - World regulatory domain
58 * 99 - built by driver but a specific alpha2 cannot be determined
59 * 98 - result of an intersection between two regulatory domains
60 * @intersect: indicates whether the wireless core should intersect
61 * the requested regulatory domain with the presently set regulatory
62 * domain.
63 * @country_ie_checksum: checksum of the last processed and accepted
64 * country IE
65 * @country_ie_env: lets us know if the AP is telling us we are outdoor,
66 * indoor, or if it doesn't matter
67 */
46struct regulatory_request { 68struct regulatory_request {
47 struct list_head list;
48 struct wiphy *wiphy; 69 struct wiphy *wiphy;
49 int granted;
50 enum reg_set_by initiator; 70 enum reg_set_by initiator;
51 char alpha2[2]; 71 char alpha2[2];
72 bool intersect;
73 u32 country_ie_checksum;
74 enum environment_cap country_ie_env;
52}; 75};
53 76
54static LIST_HEAD(regulatory_requests); 77/* Receipt of information from last regulatory request */
55DEFINE_MUTEX(cfg80211_reg_mutex); 78static struct regulatory_request *last_request;
56 79
57/* To trigger userspace events */ 80/* To trigger userspace events */
58static struct platform_device *reg_pdev; 81static struct platform_device *reg_pdev;
@@ -63,13 +86,16 @@ static u32 supported_bandwidths[] = {
63 MHZ_TO_KHZ(20), 86 MHZ_TO_KHZ(20),
64}; 87};
65 88
66static struct list_head regulatory_requests;
67
68/* Central wireless core regulatory domains, we only need two, 89/* Central wireless core regulatory domains, we only need two,
69 * the current one and a world regulatory domain in case we have no 90 * the current one and a world regulatory domain in case we have no
70 * information to give us an alpha2 */ 91 * information to give us an alpha2 */
71static const struct ieee80211_regdomain *cfg80211_regdomain; 92static const struct ieee80211_regdomain *cfg80211_regdomain;
72 93
94/* We use this as a place for the rd structure built from the
95 * last parsed country IE to rest until CRDA gets back to us with
96 * what it thinks should apply for the same country */
97static const struct ieee80211_regdomain *country_ie_regdomain;
98
73/* We keep a static world regulatory domain in case of the absence of CRDA */ 99/* We keep a static world regulatory domain in case of the absence of CRDA */
74static const struct ieee80211_regdomain world_regdom = { 100static const struct ieee80211_regdomain world_regdom = {
75 .n_reg_rules = 1, 101 .n_reg_rules = 1,
@@ -204,7 +230,7 @@ static void reset_regdomains(void)
204 * core upon initialization */ 230 * core upon initialization */
205static void update_world_regdomain(const struct ieee80211_regdomain *rd) 231static void update_world_regdomain(const struct ieee80211_regdomain *rd)
206{ 232{
207 BUG_ON(list_empty(&regulatory_requests)); 233 BUG_ON(!last_request);
208 234
209 reset_regdomains(); 235 reset_regdomains();
210 236
@@ -249,6 +275,18 @@ static bool is_unknown_alpha2(const char *alpha2)
249 return false; 275 return false;
250} 276}
251 277
278static bool is_intersected_alpha2(const char *alpha2)
279{
280 if (!alpha2)
281 return false;
282 /* Special case where regulatory domain is the
283 * result of an intersection between two regulatory domain
284 * structures */
285 if (alpha2[0] == '9' && alpha2[1] == '8')
286 return true;
287 return false;
288}
289
252static bool is_an_alpha2(const char *alpha2) 290static bool is_an_alpha2(const char *alpha2)
253{ 291{
254 if (!alpha2) 292 if (!alpha2)
@@ -277,6 +315,25 @@ static bool regdom_changed(const char *alpha2)
277 return true; 315 return true;
278} 316}
279 317
318/**
319 * country_ie_integrity_changes - tells us if the country IE has changed
320 * @checksum: checksum of country IE of fields we are interested in
321 *
322 * If the country IE has not changed you can ignore it safely. This is
323 * useful to determine if two devices are seeing two different country IEs
324 * even on the same alpha2. Note that this will return false if no IE has
325 * been set on the wireless core yet.
326 */
327static bool country_ie_integrity_changes(u32 checksum)
328{
329 /* If no IE has been set then the checksum doesn't change */
330 if (unlikely(!last_request->country_ie_checksum))
331 return false;
332 if (unlikely(last_request->country_ie_checksum != checksum))
333 return true;
334 return false;
335}
336
280/* This lets us keep regulatory code which is updated on a regulatory 337/* This lets us keep regulatory code which is updated on a regulatory
281 * basis in userspace. */ 338 * basis in userspace. */
282static int call_crda(const char *alpha2) 339static int call_crda(const char *alpha2)
@@ -300,121 +357,13 @@ static int call_crda(const char *alpha2)
300 return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, envp); 357 return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, envp);
301} 358}
302 359
303/* This has the logic which determines when a new request
304 * should be ignored. */
305static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
306 char *alpha2, struct ieee80211_regdomain *rd)
307{
308 struct regulatory_request *last_request = NULL;
309
310 /* All initial requests are respected */
311 if (list_empty(&regulatory_requests))
312 return 0;
313
314 last_request = list_first_entry(&regulatory_requests,
315 struct regulatory_request, list);
316
317 switch (set_by) {
318 case REGDOM_SET_BY_INIT:
319 return -EINVAL;
320 case REGDOM_SET_BY_CORE:
321 /* Always respect new wireless core hints, should only
322 * come in for updating the world regulatory domain at init
323 * anyway */
324 return 0;
325 case REGDOM_SET_BY_COUNTRY_IE:
326 if (last_request->initiator == set_by) {
327 if (last_request->wiphy != wiphy) {
328 /* Two cards with two APs claiming different
329 * different Country IE alpha2s!
330 * You're special!! */
331 if (!alpha2_equal(last_request->alpha2,
332 cfg80211_regdomain->alpha2)) {
333 /* XXX: Deal with conflict, consider
334 * building a new one out of the
335 * intersection */
336 WARN_ON(1);
337 return -EOPNOTSUPP;
338 }
339 return -EALREADY;
340 }
341 /* Two consecutive Country IE hints on the same wiphy */
342 if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
343 return 0;
344 return -EALREADY;
345 }
346 if (WARN(!is_alpha2_set(alpha2) || !is_an_alpha2(alpha2),
347 "Invalid Country IE regulatory hint passed "
348 "to the wireless core\n"))
349 return -EINVAL;
350 /* We ignore Country IE hints for now, as we haven't yet
351 * added the dot11MultiDomainCapabilityEnabled flag
352 * for wiphys */
353 return 1;
354 case REGDOM_SET_BY_DRIVER:
355 BUG_ON(!wiphy);
356 if (last_request->initiator == set_by) {
357 /* Two separate drivers hinting different things,
358 * this is possible if you have two devices present
359 * on a system with different EEPROM regulatory
360 * readings. XXX: Do intersection, we support only
361 * the first regulatory hint for now */
362 if (last_request->wiphy != wiphy)
363 return -EALREADY;
364 if (rd)
365 return -EALREADY;
366 /* Driver should not be trying to hint different
367 * regulatory domains! */
368 BUG_ON(!alpha2_equal(alpha2,
369 cfg80211_regdomain->alpha2));
370 return -EALREADY;
371 }
372 if (last_request->initiator == REGDOM_SET_BY_CORE)
373 return 0;
374 /* XXX: Handle intersection, and add the
375 * dot11MultiDomainCapabilityEnabled flag to wiphy. For now
376 * we assume the driver has this set to false, following the
377 * 802.11d dot11MultiDomainCapabilityEnabled documentation */
378 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
379 return 0;
380 return 0;
381 case REGDOM_SET_BY_USER:
382 if (last_request->initiator == set_by ||
383 last_request->initiator == REGDOM_SET_BY_CORE)
384 return 0;
385 /* Drivers can use their wiphy's reg_notifier()
386 * to override any information */
387 if (last_request->initiator == REGDOM_SET_BY_DRIVER)
388 return 0;
389 /* XXX: Handle intersection */
390 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
391 return -EOPNOTSUPP;
392 return 0;
393 default:
394 return -EINVAL;
395 }
396}
397
398static bool __reg_is_valid_request(const char *alpha2,
399 struct regulatory_request **request)
400{
401 struct regulatory_request *req;
402 if (list_empty(&regulatory_requests))
403 return false;
404 list_for_each_entry(req, &regulatory_requests, list) {
405 if (alpha2_equal(req->alpha2, alpha2)) {
406 *request = req;
407 return true;
408 }
409 }
410 return false;
411}
412
413/* Used by nl80211 before kmalloc'ing our regulatory domain */ 360/* Used by nl80211 before kmalloc'ing our regulatory domain */
414bool reg_is_valid_request(const char *alpha2) 361bool reg_is_valid_request(const char *alpha2)
415{ 362{
416 struct regulatory_request *request = NULL; 363 if (!last_request)
417 return __reg_is_valid_request(alpha2, &request); 364 return false;
365
366 return alpha2_equal(last_request->alpha2, alpha2);
418} 367}
419 368
420/* Sanity check on a regulatory rule */ 369/* Sanity check on a regulatory rule */
@@ -423,7 +372,7 @@ static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
423 const struct ieee80211_freq_range *freq_range = &rule->freq_range; 372 const struct ieee80211_freq_range *freq_range = &rule->freq_range;
424 u32 freq_diff; 373 u32 freq_diff;
425 374
426 if (freq_range->start_freq_khz == 0 || freq_range->end_freq_khz == 0) 375 if (freq_range->start_freq_khz <= 0 || freq_range->end_freq_khz <= 0)
427 return false; 376 return false;
428 377
429 if (freq_range->start_freq_khz > freq_range->end_freq_khz) 378 if (freq_range->start_freq_khz > freq_range->end_freq_khz)
@@ -431,7 +380,7 @@ static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
431 380
432 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; 381 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
433 382
434 if (freq_range->max_bandwidth_khz > freq_diff) 383 if (freq_diff <= 0 || freq_range->max_bandwidth_khz > freq_diff)
435 return false; 384 return false;
436 385
437 return true; 386 return true;
@@ -445,6 +394,9 @@ static bool is_valid_rd(const struct ieee80211_regdomain *rd)
445 if (!rd->n_reg_rules) 394 if (!rd->n_reg_rules)
446 return false; 395 return false;
447 396
397 if (WARN_ON(rd->n_reg_rules > NL80211_MAX_SUPP_REG_RULES))
398 return false;
399
448 for (i = 0; i < rd->n_reg_rules; i++) { 400 for (i = 0; i < rd->n_reg_rules; i++) {
449 reg_rule = &rd->reg_rules[i]; 401 reg_rule = &rd->reg_rules[i];
450 if (!is_valid_reg_rule(reg_rule)) 402 if (!is_valid_reg_rule(reg_rule))
@@ -469,6 +421,311 @@ static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
469 return 0; 421 return 0;
470} 422}
471 423
424/* Converts a country IE to a regulatory domain. A regulatory domain
425 * structure has a lot of information which the IE doesn't yet have,
426 * so for the other values we use upper max values as we will intersect
427 * with our userspace regulatory agent to get lower bounds. */
428static struct ieee80211_regdomain *country_ie_2_rd(
429 u8 *country_ie,
430 u8 country_ie_len,
431 u32 *checksum)
432{
433 struct ieee80211_regdomain *rd = NULL;
434 unsigned int i = 0;
435 char alpha2[2];
436 u32 flags = 0;
437 u32 num_rules = 0, size_of_regd = 0;
438 u8 *triplets_start = NULL;
439 u8 len_at_triplet = 0;
440 /* the last channel we have registered in a subband (triplet) */
441 int last_sub_max_channel = 0;
442
443 *checksum = 0xDEADBEEF;
444
445 /* Country IE requirements */
446 BUG_ON(country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN ||
447 country_ie_len & 0x01);
448
449 alpha2[0] = country_ie[0];
450 alpha2[1] = country_ie[1];
451
452 /*
453 * Third octet can be:
454 * 'I' - Indoor
455 * 'O' - Outdoor
456 *
457 * anything else we assume is no restrictions
458 */
459 if (country_ie[2] == 'I')
460 flags = NL80211_RRF_NO_OUTDOOR;
461 else if (country_ie[2] == 'O')
462 flags = NL80211_RRF_NO_INDOOR;
463
464 country_ie += 3;
465 country_ie_len -= 3;
466
467 triplets_start = country_ie;
468 len_at_triplet = country_ie_len;
469
470 *checksum ^= ((flags ^ alpha2[0] ^ alpha2[1]) << 8);
471
472 /* We need to build a reg rule for each triplet, but first we must
473 * calculate the number of reg rules we will need. We will need one
474 * for each channel subband */
475 while (country_ie_len >= 3) {
476 struct ieee80211_country_ie_triplet *triplet =
477 (struct ieee80211_country_ie_triplet *) country_ie;
478 int cur_sub_max_channel = 0, cur_channel = 0;
479
480 if (triplet->ext.reg_extension_id >=
481 IEEE80211_COUNTRY_EXTENSION_ID) {
482 country_ie += 3;
483 country_ie_len -= 3;
484 continue;
485 }
486
487 cur_channel = triplet->chans.first_channel;
488 cur_sub_max_channel = ieee80211_channel_to_frequency(
489 cur_channel + triplet->chans.num_channels);
490
491 /* Basic sanity check */
492 if (cur_sub_max_channel < cur_channel)
493 return NULL;
494
495 /* Do not allow overlapping channels. Also channels
496 * passed in each subband must be monotonically
497 * increasing */
498 if (last_sub_max_channel) {
499 if (cur_channel <= last_sub_max_channel)
500 return NULL;
501 if (cur_sub_max_channel <= last_sub_max_channel)
502 return NULL;
503 }
504
505 /* When dot11RegulatoryClassesRequired is supported
506 * we can throw ext triplets as part of this soup,
507 * for now we don't care when those change as we
508 * don't support them */
509 *checksum ^= ((cur_channel ^ cur_sub_max_channel) << 8) |
510 ((cur_sub_max_channel ^ cur_sub_max_channel) << 16) |
511 ((triplet->chans.max_power ^ cur_sub_max_channel) << 24);
512
513 last_sub_max_channel = cur_sub_max_channel;
514
515 country_ie += 3;
516 country_ie_len -= 3;
517 num_rules++;
518
519 /* Note: this is not a IEEE requirement but
520 * simply a memory requirement */
521 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
522 return NULL;
523 }
524
525 country_ie = triplets_start;
526 country_ie_len = len_at_triplet;
527
528 size_of_regd = sizeof(struct ieee80211_regdomain) +
529 (num_rules * sizeof(struct ieee80211_reg_rule));
530
531 rd = kzalloc(size_of_regd, GFP_KERNEL);
532 if (!rd)
533 return NULL;
534
535 rd->n_reg_rules = num_rules;
536 rd->alpha2[0] = alpha2[0];
537 rd->alpha2[1] = alpha2[1];
538
539 /* This time around we fill in the rd */
540 while (country_ie_len >= 3) {
541 struct ieee80211_country_ie_triplet *triplet =
542 (struct ieee80211_country_ie_triplet *) country_ie;
543 struct ieee80211_reg_rule *reg_rule = NULL;
544 struct ieee80211_freq_range *freq_range = NULL;
545 struct ieee80211_power_rule *power_rule = NULL;
546
547 /* Must parse if dot11RegulatoryClassesRequired is true,
548 * we don't support this yet */
549 if (triplet->ext.reg_extension_id >=
550 IEEE80211_COUNTRY_EXTENSION_ID) {
551 country_ie += 3;
552 country_ie_len -= 3;
553 continue;
554 }
555
556 reg_rule = &rd->reg_rules[i];
557 freq_range = &reg_rule->freq_range;
558 power_rule = &reg_rule->power_rule;
559
560 reg_rule->flags = flags;
561
562 /* The +10 is since the regulatory domain expects
563 * the actual band edge, not the center of freq for
564 * its start and end freqs, assuming 20 MHz bandwidth on
565 * the channels passed */
566 freq_range->start_freq_khz =
567 MHZ_TO_KHZ(ieee80211_channel_to_frequency(
568 triplet->chans.first_channel) - 10);
569 freq_range->end_freq_khz =
570 MHZ_TO_KHZ(ieee80211_channel_to_frequency(
571 triplet->chans.first_channel +
572 triplet->chans.num_channels) + 10);
573
574 /* Large arbitrary values, we intersect later */
575 /* Increment this if we ever support >= 40 MHz channels
576 * in IEEE 802.11 */
577 freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40);
578 power_rule->max_antenna_gain = DBI_TO_MBI(100);
579 power_rule->max_eirp = DBM_TO_MBM(100);
580
581 country_ie += 3;
582 country_ie_len -= 3;
583 i++;
584
585 BUG_ON(i > NL80211_MAX_SUPP_REG_RULES);
586 }
587
588 return rd;
589}
590
591
592/* Helper for regdom_intersect(), this does the real
593 * mathematical intersection fun */
594static int reg_rules_intersect(
595 const struct ieee80211_reg_rule *rule1,
596 const struct ieee80211_reg_rule *rule2,
597 struct ieee80211_reg_rule *intersected_rule)
598{
599 const struct ieee80211_freq_range *freq_range1, *freq_range2;
600 struct ieee80211_freq_range *freq_range;
601 const struct ieee80211_power_rule *power_rule1, *power_rule2;
602 struct ieee80211_power_rule *power_rule;
603 u32 freq_diff;
604
605 freq_range1 = &rule1->freq_range;
606 freq_range2 = &rule2->freq_range;
607 freq_range = &intersected_rule->freq_range;
608
609 power_rule1 = &rule1->power_rule;
610 power_rule2 = &rule2->power_rule;
611 power_rule = &intersected_rule->power_rule;
612
613 freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
614 freq_range2->start_freq_khz);
615 freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
616 freq_range2->end_freq_khz);
617 freq_range->max_bandwidth_khz = min(freq_range1->max_bandwidth_khz,
618 freq_range2->max_bandwidth_khz);
619
620 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
621 if (freq_range->max_bandwidth_khz > freq_diff)
622 freq_range->max_bandwidth_khz = freq_diff;
623
624 power_rule->max_eirp = min(power_rule1->max_eirp,
625 power_rule2->max_eirp);
626 power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
627 power_rule2->max_antenna_gain);
628
629 intersected_rule->flags = (rule1->flags | rule2->flags);
630
631 if (!is_valid_reg_rule(intersected_rule))
632 return -EINVAL;
633
634 return 0;
635}
636
637/**
638 * regdom_intersect - do the intersection between two regulatory domains
639 * @rd1: first regulatory domain
640 * @rd2: second regulatory domain
641 *
642 * Use this function to get the intersection between two regulatory domains.
643 * Once completed we will mark the alpha2 for the rd as intersected, "98",
644 * as no one single alpha2 can represent this regulatory domain.
645 *
646 * Returns a pointer to the regulatory domain structure which will hold the
647 * resulting intersection of rules between rd1 and rd2. We will
648 * kzalloc() this structure for you.
649 */
650static struct ieee80211_regdomain *regdom_intersect(
651 const struct ieee80211_regdomain *rd1,
652 const struct ieee80211_regdomain *rd2)
653{
654 int r, size_of_regd;
655 unsigned int x, y;
656 unsigned int num_rules = 0, rule_idx = 0;
657 const struct ieee80211_reg_rule *rule1, *rule2;
658 struct ieee80211_reg_rule *intersected_rule;
659 struct ieee80211_regdomain *rd;
660 /* This is just a dummy holder to help us count */
661 struct ieee80211_reg_rule irule;
662
663 /* Uses the stack temporarily for counter arithmetic */
664 intersected_rule = &irule;
665
666 memset(intersected_rule, 0, sizeof(struct ieee80211_reg_rule));
667
668 if (!rd1 || !rd2)
669 return NULL;
670
671 /* First we get a count of the rules we'll need, then we actually
672 * build them. This is to so we can malloc() and free() a
673 * regdomain once. The reason we use reg_rules_intersect() here
674 * is it will return -EINVAL if the rule computed makes no sense.
675 * All rules that do check out OK are valid. */
676
677 for (x = 0; x < rd1->n_reg_rules; x++) {
678 rule1 = &rd1->reg_rules[x];
679 for (y = 0; y < rd2->n_reg_rules; y++) {
680 rule2 = &rd2->reg_rules[y];
681 if (!reg_rules_intersect(rule1, rule2,
682 intersected_rule))
683 num_rules++;
684 memset(intersected_rule, 0,
685 sizeof(struct ieee80211_reg_rule));
686 }
687 }
688
689 if (!num_rules)
690 return NULL;
691
692 size_of_regd = sizeof(struct ieee80211_regdomain) +
693 ((num_rules + 1) * sizeof(struct ieee80211_reg_rule));
694
695 rd = kzalloc(size_of_regd, GFP_KERNEL);
696 if (!rd)
697 return NULL;
698
699 for (x = 0; x < rd1->n_reg_rules; x++) {
700 rule1 = &rd1->reg_rules[x];
701 for (y = 0; y < rd2->n_reg_rules; y++) {
702 rule2 = &rd2->reg_rules[y];
703 /* This time around instead of using the stack lets
704 * write to the target rule directly saving ourselves
705 * a memcpy() */
706 intersected_rule = &rd->reg_rules[rule_idx];
707 r = reg_rules_intersect(rule1, rule2,
708 intersected_rule);
709 /* No need to memset here the intersected rule here as
710 * we're not using the stack anymore */
711 if (r)
712 continue;
713 rule_idx++;
714 }
715 }
716
717 if (rule_idx != num_rules) {
718 kfree(rd);
719 return NULL;
720 }
721
722 rd->n_reg_rules = num_rules;
723 rd->alpha2[0] = '9';
724 rd->alpha2[1] = '8';
725
726 return rd;
727}
728
472/* XXX: add support for the rest of enum nl80211_reg_rule_flags, we may 729/* XXX: add support for the rest of enum nl80211_reg_rule_flags, we may
473 * want to just have the channel structure use these */ 730 * want to just have the channel structure use these */
474static u32 map_regdom_flags(u32 rd_flags) 731static u32 map_regdom_flags(u32 rd_flags)
@@ -559,12 +816,23 @@ static void handle_band(struct ieee80211_supported_band *sband)
559 handle_channel(&sband->channels[i]); 816 handle_channel(&sband->channels[i]);
560} 817}
561 818
819static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
820{
821 if (!last_request)
822 return true;
823 if (setby == REGDOM_SET_BY_CORE &&
824 wiphy->fw_handles_regulatory)
825 return true;
826 return false;
827}
828
562static void update_all_wiphy_regulatory(enum reg_set_by setby) 829static void update_all_wiphy_regulatory(enum reg_set_by setby)
563{ 830{
564 struct cfg80211_registered_device *drv; 831 struct cfg80211_registered_device *drv;
565 832
566 list_for_each_entry(drv, &cfg80211_drv_list, list) 833 list_for_each_entry(drv, &cfg80211_drv_list, list)
567 wiphy_update_regulatory(&drv->wiphy, setby); 834 if (!ignore_reg_update(&drv->wiphy, setby))
835 wiphy_update_regulatory(&drv->wiphy, setby);
568} 836}
569 837
570void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby) 838void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
@@ -578,78 +846,237 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
578 } 846 }
579} 847}
580 848
581/* Caller must hold &cfg80211_drv_mutex */ 849/* Return value which can be used by ignore_request() to indicate
582int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by, 850 * it has been determined we should intersect two regulatory domains */
583 const char *alpha2, struct ieee80211_regdomain *rd) 851#define REG_INTERSECT 1
584{
585 struct regulatory_request *request;
586 char *rd_alpha2;
587 int r = 0;
588
589 r = ignore_request(wiphy, set_by, (char *) alpha2, rd);
590 if (r)
591 return r;
592 852
593 if (rd) 853/* This has the logic which determines when a new request
594 rd_alpha2 = rd->alpha2; 854 * should be ignored. */
595 else 855static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
596 rd_alpha2 = (char *) alpha2; 856 const char *alpha2)
857{
858 /* All initial requests are respected */
859 if (!last_request)
860 return 0;
597 861
598 switch (set_by) { 862 switch (set_by) {
863 case REGDOM_SET_BY_INIT:
864 return -EINVAL;
599 case REGDOM_SET_BY_CORE: 865 case REGDOM_SET_BY_CORE:
866 /*
867 * Always respect new wireless core hints, should only happen
868 * when updating the world regulatory domain at init.
869 */
870 return 0;
600 case REGDOM_SET_BY_COUNTRY_IE: 871 case REGDOM_SET_BY_COUNTRY_IE:
872 if (unlikely(!is_an_alpha2(alpha2)))
873 return -EINVAL;
874 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
875 if (last_request->wiphy != wiphy) {
876 /*
877 * Two cards with two APs claiming different
878 * different Country IE alpha2s. We could
879 * intersect them, but that seems unlikely
880 * to be correct. Reject second one for now.
881 */
882 if (!alpha2_equal(alpha2,
883 cfg80211_regdomain->alpha2))
884 return -EOPNOTSUPP;
885 return -EALREADY;
886 }
887 /* Two consecutive Country IE hints on the same wiphy.
888 * This should be picked up early by the driver/stack */
889 if (WARN_ON(!alpha2_equal(cfg80211_regdomain->alpha2,
890 alpha2)))
891 return 0;
892 return -EALREADY;
893 }
894 return REG_INTERSECT;
601 case REGDOM_SET_BY_DRIVER: 895 case REGDOM_SET_BY_DRIVER:
896 if (last_request->initiator == REGDOM_SET_BY_DRIVER)
897 return -EALREADY;
898 return 0;
602 case REGDOM_SET_BY_USER: 899 case REGDOM_SET_BY_USER:
603 request = kzalloc(sizeof(struct regulatory_request), 900 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
604 GFP_KERNEL); 901 return REG_INTERSECT;
605 if (!request) 902 /* If the user knows better the user should set the regdom
606 return -ENOMEM; 903 * to their country before the IE is picked up */
607 904 if (last_request->initiator == REGDOM_SET_BY_USER &&
608 request->alpha2[0] = rd_alpha2[0]; 905 last_request->intersect)
609 request->alpha2[1] = rd_alpha2[1]; 906 return -EOPNOTSUPP;
610 request->initiator = set_by; 907 return 0;
611 request->wiphy = wiphy;
612
613 list_add_tail(&request->list, &regulatory_requests);
614 if (rd)
615 break;
616 r = call_crda(alpha2);
617#ifndef CONFIG_WIRELESS_OLD_REGULATORY
618 if (r)
619 printk(KERN_ERR "cfg80211: Failed calling CRDA\n");
620#endif
621 break;
622 default:
623 r = -ENOTSUPP;
624 break;
625 } 908 }
626 909
627 return r; 910 return -EINVAL;
628} 911}
629 912
630/* If rd is not NULL and if this call fails the caller must free it */ 913/* Caller must hold &cfg80211_drv_mutex */
631int regulatory_hint(struct wiphy *wiphy, const char *alpha2, 914int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
632 struct ieee80211_regdomain *rd) 915 const char *alpha2,
916 u32 country_ie_checksum,
917 enum environment_cap env)
633{ 918{
634 int r; 919 struct regulatory_request *request;
635 BUG_ON(!rd && !alpha2); 920 bool intersect = false;
921 int r = 0;
636 922
637 mutex_lock(&cfg80211_drv_mutex); 923 r = ignore_request(wiphy, set_by, alpha2);
638 924
639 r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, rd); 925 if (r == REG_INTERSECT)
640 if (r || !rd) 926 intersect = true;
641 goto unlock_and_exit; 927 else if (r)
928 return r;
642 929
643 /* If the driver passed a regulatory domain we skipped asking 930 request = kzalloc(sizeof(struct regulatory_request),
644 * userspace for one so we can now go ahead and set it */ 931 GFP_KERNEL);
645 r = set_regdom(rd); 932 if (!request)
933 return -ENOMEM;
934
935 request->alpha2[0] = alpha2[0];
936 request->alpha2[1] = alpha2[1];
937 request->initiator = set_by;
938 request->wiphy = wiphy;
939 request->intersect = intersect;
940 request->country_ie_checksum = country_ie_checksum;
941 request->country_ie_env = env;
942
943 kfree(last_request);
944 last_request = request;
945 /*
946 * Note: When CONFIG_WIRELESS_OLD_REGULATORY is enabled
947 * AND if CRDA is NOT present nothing will happen, if someone
948 * wants to bother with 11d with OLD_REG you can add a timer.
949 * If after x amount of time nothing happens you can call:
950 *
951 * return set_regdom(country_ie_regdomain);
952 *
953 * to intersect with the static rd
954 */
955 return call_crda(alpha2);
956}
957
958void regulatory_hint(struct wiphy *wiphy, const char *alpha2)
959{
960 BUG_ON(!alpha2);
646 961
647unlock_and_exit: 962 mutex_lock(&cfg80211_drv_mutex);
963 __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, 0, ENVIRON_ANY);
648 mutex_unlock(&cfg80211_drv_mutex); 964 mutex_unlock(&cfg80211_drv_mutex);
649 return r;
650} 965}
651EXPORT_SYMBOL(regulatory_hint); 966EXPORT_SYMBOL(regulatory_hint);
652 967
968static bool reg_same_country_ie_hint(struct wiphy *wiphy,
969 u32 country_ie_checksum)
970{
971 if (!last_request->wiphy)
972 return false;
973 if (likely(last_request->wiphy != wiphy))
974 return !country_ie_integrity_changes(country_ie_checksum);
975 /* We should not have let these through at this point, they
976 * should have been picked up earlier by the first alpha2 check
977 * on the device */
978 if (WARN_ON(!country_ie_integrity_changes(country_ie_checksum)))
979 return true;
980 return false;
981}
982
983void regulatory_hint_11d(struct wiphy *wiphy,
984 u8 *country_ie,
985 u8 country_ie_len)
986{
987 struct ieee80211_regdomain *rd = NULL;
988 char alpha2[2];
989 u32 checksum = 0;
990 enum environment_cap env = ENVIRON_ANY;
991
992 if (!last_request)
993 return;
994
995 mutex_lock(&cfg80211_drv_mutex);
996
997 /* IE len must be evenly divisible by 2 */
998 if (country_ie_len & 0x01)
999 goto out;
1000
1001 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
1002 goto out;
1003
1004 /* Pending country IE processing, this can happen after we
1005 * call CRDA and wait for a response if a beacon was received before
1006 * we were able to process the last regulatory_hint_11d() call */
1007 if (country_ie_regdomain)
1008 goto out;
1009
1010 alpha2[0] = country_ie[0];
1011 alpha2[1] = country_ie[1];
1012
1013 if (country_ie[2] == 'I')
1014 env = ENVIRON_INDOOR;
1015 else if (country_ie[2] == 'O')
1016 env = ENVIRON_OUTDOOR;
1017
1018 /* We will run this for *every* beacon processed for the BSSID, so
1019 * we optimize an early check to exit out early if we don't have to
1020 * do anything */
1021 if (likely(last_request->wiphy)) {
1022 struct cfg80211_registered_device *drv_last_ie;
1023
1024 drv_last_ie = wiphy_to_dev(last_request->wiphy);
1025
1026 /* Lets keep this simple -- we trust the first AP
1027 * after we intersect with CRDA */
1028 if (likely(last_request->wiphy == wiphy)) {
1029 /* Ignore IEs coming in on this wiphy with
1030 * the same alpha2 and environment cap */
1031 if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
1032 alpha2) &&
1033 env == drv_last_ie->env)) {
1034 goto out;
1035 }
1036 /* the wiphy moved on to another BSSID or the AP
1037 * was reconfigured. XXX: We need to deal with the
1038 * case where the user suspends and goes to goes
1039 * to another country, and then gets IEs from an
1040 * AP with different settings */
1041 goto out;
1042 } else {
1043 /* Ignore IEs coming in on two separate wiphys with
1044 * the same alpha2 and environment cap */
1045 if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
1046 alpha2) &&
1047 env == drv_last_ie->env)) {
1048 goto out;
1049 }
1050 /* We could potentially intersect though */
1051 goto out;
1052 }
1053 }
1054
1055 rd = country_ie_2_rd(country_ie, country_ie_len, &checksum);
1056 if (!rd)
1057 goto out;
1058
1059 /* This will not happen right now but we leave it here for the
1060 * the future when we want to add suspend/resume support and having
1061 * the user move to another country after doing so, or having the user
1062 * move to another AP. Right now we just trust the first AP. This is why
1063 * this is marked as likley(). If we hit this before we add this support
1064 * we want to be informed of it as it would indicate a mistake in the
1065 * current design */
1066 if (likely(WARN_ON(reg_same_country_ie_hint(wiphy, checksum))))
1067 goto out;
1068
1069 /* We keep this around for when CRDA comes back with a response so
1070 * we can intersect with that */
1071 country_ie_regdomain = rd;
1072
1073 __regulatory_hint(wiphy, REGDOM_SET_BY_COUNTRY_IE,
1074 country_ie_regdomain->alpha2, checksum, env);
1075
1076out:
1077 mutex_unlock(&cfg80211_drv_mutex);
1078}
1079EXPORT_SYMBOL(regulatory_hint_11d);
653 1080
654static void print_rd_rules(const struct ieee80211_regdomain *rd) 1081static void print_rd_rules(const struct ieee80211_regdomain *rd)
655{ 1082{
@@ -689,7 +1116,25 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
689static void print_regdomain(const struct ieee80211_regdomain *rd) 1116static void print_regdomain(const struct ieee80211_regdomain *rd)
690{ 1117{
691 1118
692 if (is_world_regdom(rd->alpha2)) 1119 if (is_intersected_alpha2(rd->alpha2)) {
1120 struct wiphy *wiphy = NULL;
1121 struct cfg80211_registered_device *drv;
1122
1123 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
1124 if (last_request->wiphy) {
1125 wiphy = last_request->wiphy;
1126 drv = wiphy_to_dev(wiphy);
1127 printk(KERN_INFO "cfg80211: Current regulatory "
1128 "domain updated by AP to: %c%c\n",
1129 drv->country_ie_alpha2[0],
1130 drv->country_ie_alpha2[1]);
1131 } else
1132 printk(KERN_INFO "cfg80211: Current regulatory "
1133 "domain intersected: \n");
1134 } else
1135 printk(KERN_INFO "cfg80211: Current regulatory "
1136 "intersected: \n");
1137 } else if (is_world_regdom(rd->alpha2))
693 printk(KERN_INFO "cfg80211: World regulatory " 1138 printk(KERN_INFO "cfg80211: World regulatory "
694 "domain updated:\n"); 1139 "domain updated:\n");
695 else { 1140 else {
@@ -705,21 +1150,50 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
705 print_rd_rules(rd); 1150 print_rd_rules(rd);
706} 1151}
707 1152
708void print_regdomain_info(const struct ieee80211_regdomain *rd) 1153static void print_regdomain_info(const struct ieee80211_regdomain *rd)
709{ 1154{
710 printk(KERN_INFO "cfg80211: Regulatory domain: %c%c\n", 1155 printk(KERN_INFO "cfg80211: Regulatory domain: %c%c\n",
711 rd->alpha2[0], rd->alpha2[1]); 1156 rd->alpha2[0], rd->alpha2[1]);
712 print_rd_rules(rd); 1157 print_rd_rules(rd);
713} 1158}
714 1159
715static int __set_regdom(const struct ieee80211_regdomain *rd) 1160#ifdef CONFIG_CFG80211_REG_DEBUG
1161static void reg_country_ie_process_debug(
1162 const struct ieee80211_regdomain *rd,
1163 const struct ieee80211_regdomain *country_ie_regdomain,
1164 const struct ieee80211_regdomain *intersected_rd)
716{ 1165{
717 struct regulatory_request *request = NULL; 1166 printk(KERN_DEBUG "cfg80211: Received country IE:\n");
1167 print_regdomain_info(country_ie_regdomain);
1168 printk(KERN_DEBUG "cfg80211: CRDA thinks this should applied:\n");
1169 print_regdomain_info(rd);
1170 if (intersected_rd) {
1171 printk(KERN_DEBUG "cfg80211: We intersect both of these "
1172 "and get:\n");
1173 print_regdomain_info(rd);
1174 return;
1175 }
1176 printk(KERN_DEBUG "cfg80211: Intersection between both failed\n");
1177}
1178#else
1179static inline void reg_country_ie_process_debug(
1180 const struct ieee80211_regdomain *rd,
1181 const struct ieee80211_regdomain *country_ie_regdomain,
1182 const struct ieee80211_regdomain *intersected_rd)
1183{
1184}
1185#endif
718 1186
1187/* Takes ownership of rd only if it doesn't fail */
1188static int __set_regdom(const struct ieee80211_regdomain *rd)
1189{
1190 const struct ieee80211_regdomain *intersected_rd = NULL;
1191 struct cfg80211_registered_device *drv = NULL;
1192 struct wiphy *wiphy = NULL;
719 /* Some basic sanity checks first */ 1193 /* Some basic sanity checks first */
720 1194
721 if (is_world_regdom(rd->alpha2)) { 1195 if (is_world_regdom(rd->alpha2)) {
722 if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request))) 1196 if (WARN_ON(!reg_is_valid_request(rd->alpha2)))
723 return -EINVAL; 1197 return -EINVAL;
724 update_world_regdomain(rd); 1198 update_world_regdomain(rd);
725 return 0; 1199 return 0;
@@ -729,45 +1203,102 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
729 !is_unknown_alpha2(rd->alpha2)) 1203 !is_unknown_alpha2(rd->alpha2))
730 return -EINVAL; 1204 return -EINVAL;
731 1205
732 if (list_empty(&regulatory_requests)) 1206 if (!last_request)
733 return -EINVAL; 1207 return -EINVAL;
734 1208
735 /* allow overriding the static definitions if CRDA is present */ 1209 /* Lets only bother proceeding on the same alpha2 if the current
736 if (!is_old_static_regdom(cfg80211_regdomain) && 1210 * rd is non static (it means CRDA was present and was used last)
737 !regdom_changed(rd->alpha2)) 1211 * and the pending request came in from a country IE */
738 return -EINVAL; 1212 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE) {
1213 /* If someone else asked us to change the rd lets only bother
1214 * checking if the alpha2 changes if CRDA was already called */
1215 if (!is_old_static_regdom(cfg80211_regdomain) &&
1216 !regdom_changed(rd->alpha2))
1217 return -EINVAL;
1218 }
1219
1220 wiphy = last_request->wiphy;
739 1221
740 /* Now lets set the regulatory domain, update all driver channels 1222 /* Now lets set the regulatory domain, update all driver channels
741 * and finally inform them of what we have done, in case they want 1223 * and finally inform them of what we have done, in case they want
742 * to review or adjust their own settings based on their own 1224 * to review or adjust their own settings based on their own
743 * internal EEPROM data */ 1225 * internal EEPROM data */
744 1226
745 if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request))) 1227 if (WARN_ON(!reg_is_valid_request(rd->alpha2)))
746 return -EINVAL; 1228 return -EINVAL;
747 1229
748 reset_regdomains(); 1230 if (!is_valid_rd(rd)) {
1231 printk(KERN_ERR "cfg80211: Invalid "
1232 "regulatory domain detected:\n");
1233 print_regdomain_info(rd);
1234 return -EINVAL;
1235 }
749 1236
750 /* Country IE parsing coming soon */ 1237 if (!last_request->intersect) {
751 switch (request->initiator) { 1238 reset_regdomains();
752 case REGDOM_SET_BY_CORE: 1239 cfg80211_regdomain = rd;
753 case REGDOM_SET_BY_DRIVER: 1240 return 0;
754 case REGDOM_SET_BY_USER: 1241 }
755 if (!is_valid_rd(rd)) { 1242
756 printk(KERN_ERR "cfg80211: Invalid " 1243 /* Intersection requires a bit more work */
757 "regulatory domain detected:\n"); 1244
758 print_regdomain_info(rd); 1245 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE) {
1246
1247 intersected_rd = regdom_intersect(rd, cfg80211_regdomain);
1248 if (!intersected_rd)
759 return -EINVAL; 1249 return -EINVAL;
760 } 1250
761 break; 1251 /* We can trash what CRDA provided now */
762 case REGDOM_SET_BY_COUNTRY_IE: /* Not yet */ 1252 kfree(rd);
763 WARN_ON(1); 1253 rd = NULL;
764 default: 1254
765 return -EOPNOTSUPP; 1255 reset_regdomains();
1256 cfg80211_regdomain = intersected_rd;
1257
1258 return 0;
766 } 1259 }
767 1260
768 /* Tada! */ 1261 /*
769 cfg80211_regdomain = rd; 1262 * Country IE requests are handled a bit differently, we intersect
770 request->granted = 1; 1263 * the country IE rd with what CRDA believes that country should have
1264 */
1265
1266 BUG_ON(!country_ie_regdomain);
1267
1268 if (rd != country_ie_regdomain) {
1269 /* Intersect what CRDA returned and our what we
1270 * had built from the Country IE received */
1271
1272 intersected_rd = regdom_intersect(rd, country_ie_regdomain);
1273
1274 reg_country_ie_process_debug(rd, country_ie_regdomain,
1275 intersected_rd);
1276
1277 kfree(country_ie_regdomain);
1278 country_ie_regdomain = NULL;
1279 } else {
1280 /* This would happen when CRDA was not present and
1281 * OLD_REGULATORY was enabled. We intersect our Country
1282 * IE rd and what was set on cfg80211 originally */
1283 intersected_rd = regdom_intersect(rd, cfg80211_regdomain);
1284 }
1285
1286 if (!intersected_rd)
1287 return -EINVAL;
1288
1289 drv = wiphy_to_dev(wiphy);
1290
1291 drv->country_ie_alpha2[0] = rd->alpha2[0];
1292 drv->country_ie_alpha2[1] = rd->alpha2[1];
1293 drv->env = last_request->country_ie_env;
1294
1295 BUG_ON(intersected_rd == rd);
1296
1297 kfree(rd);
1298 rd = NULL;
1299
1300 reset_regdomains();
1301 cfg80211_regdomain = intersected_rd;
771 1302
772 return 0; 1303 return 0;
773} 1304}
@@ -775,52 +1306,41 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
775 1306
776/* Use this call to set the current regulatory domain. Conflicts with 1307/* Use this call to set the current regulatory domain. Conflicts with
777 * multiple drivers can be ironed out later. Caller must've already 1308 * multiple drivers can be ironed out later. Caller must've already
778 * kmalloc'd the rd structure. If this calls fails you should kfree() 1309 * kmalloc'd the rd structure. Caller must hold cfg80211_drv_mutex */
779 * the passed rd. Caller must hold cfg80211_drv_mutex */
780int set_regdom(const struct ieee80211_regdomain *rd) 1310int set_regdom(const struct ieee80211_regdomain *rd)
781{ 1311{
782 struct regulatory_request *this_request = NULL, *prev_request = NULL;
783 int r; 1312 int r;
784 1313
785 if (!list_empty(&regulatory_requests))
786 prev_request = list_first_entry(&regulatory_requests,
787 struct regulatory_request, list);
788
789 /* Note that this doesn't update the wiphys, this is done below */ 1314 /* Note that this doesn't update the wiphys, this is done below */
790 r = __set_regdom(rd); 1315 r = __set_regdom(rd);
791 if (r) 1316 if (r) {
1317 kfree(rd);
792 return r; 1318 return r;
793
794 BUG_ON((!__reg_is_valid_request(rd->alpha2, &this_request)));
795
796 /* The initial standard core update of the world regulatory domain, no
797 * need to keep that request info around if it didn't fail. */
798 if (is_world_regdom(rd->alpha2) &&
799 this_request->initiator == REGDOM_SET_BY_CORE &&
800 this_request->granted) {
801 list_del(&this_request->list);
802 kfree(this_request);
803 this_request = NULL;
804 }
805
806 /* Remove old requests, we only leave behind the last one */
807 if (prev_request) {
808 list_del(&prev_request->list);
809 kfree(prev_request);
810 prev_request = NULL;
811 } 1319 }
812 1320
813 /* This would make this whole thing pointless */ 1321 /* This would make this whole thing pointless */
814 BUG_ON(rd != cfg80211_regdomain); 1322 if (!last_request->intersect)
1323 BUG_ON(rd != cfg80211_regdomain);
815 1324
816 /* update all wiphys now with the new established regulatory domain */ 1325 /* update all wiphys now with the new established regulatory domain */
817 update_all_wiphy_regulatory(this_request->initiator); 1326 update_all_wiphy_regulatory(last_request->initiator);
818 1327
819 print_regdomain(rd); 1328 print_regdomain(cfg80211_regdomain);
820 1329
821 return r; 1330 return r;
822} 1331}
823 1332
1333/* Caller must hold cfg80211_drv_mutex */
1334void reg_device_remove(struct wiphy *wiphy)
1335{
1336 if (!last_request || !last_request->wiphy)
1337 return;
1338 if (last_request->wiphy != wiphy)
1339 return;
1340 last_request->wiphy = NULL;
1341 last_request->country_ie_env = ENVIRON_ANY;
1342}
1343
824int regulatory_init(void) 1344int regulatory_init(void)
825{ 1345{
826 int err; 1346 int err;
@@ -838,13 +1358,13 @@ int regulatory_init(void)
838 * you have CRDA you get it updated, otherwise you get 1358 * you have CRDA you get it updated, otherwise you get
839 * stuck with the static values. We ignore "EU" code as 1359 * stuck with the static values. We ignore "EU" code as
840 * that is not a valid ISO / IEC 3166 alpha2 */ 1360 * that is not a valid ISO / IEC 3166 alpha2 */
841 if (ieee80211_regdom[0] != 'E' && ieee80211_regdom[1] != 'U') 1361 if (ieee80211_regdom[0] != 'E' || ieee80211_regdom[1] != 'U')
842 err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, 1362 err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE,
843 ieee80211_regdom, NULL); 1363 ieee80211_regdom, 0, ENVIRON_ANY);
844#else 1364#else
845 cfg80211_regdomain = cfg80211_world_regdom; 1365 cfg80211_regdomain = cfg80211_world_regdom;
846 1366
847 err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", NULL); 1367 err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", 0, ENVIRON_ANY);
848 if (err) 1368 if (err)
849 printk(KERN_ERR "cfg80211: calling CRDA failed - " 1369 printk(KERN_ERR "cfg80211: calling CRDA failed - "
850 "unable to update world regulatory domain, " 1370 "unable to update world regulatory domain, "
@@ -856,16 +1376,15 @@ int regulatory_init(void)
856 1376
857void regulatory_exit(void) 1377void regulatory_exit(void)
858{ 1378{
859 struct regulatory_request *req, *req_tmp;
860
861 mutex_lock(&cfg80211_drv_mutex); 1379 mutex_lock(&cfg80211_drv_mutex);
862 1380
863 reset_regdomains(); 1381 reset_regdomains();
864 1382
865 list_for_each_entry_safe(req, req_tmp, &regulatory_requests, list) { 1383 kfree(country_ie_regdomain);
866 list_del(&req->list); 1384 country_ie_regdomain = NULL;
867 kfree(req); 1385
868 } 1386 kfree(last_request);
1387
869 platform_device_unregister(reg_pdev); 1388 platform_device_unregister(reg_pdev);
870 1389
871 mutex_unlock(&cfg80211_drv_mutex); 1390 mutex_unlock(&cfg80211_drv_mutex);
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index a33362872f3c..a76ea3ff7cd6 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -1,13 +1,44 @@
1#ifndef __NET_WIRELESS_REG_H 1#ifndef __NET_WIRELESS_REG_H
2#define __NET_WIRELESS_REG_H 2#define __NET_WIRELESS_REG_H
3 3
4extern struct mutex cfg80211_reg_mutex;
5bool is_world_regdom(const char *alpha2); 4bool is_world_regdom(const char *alpha2);
6bool reg_is_valid_request(const char *alpha2); 5bool reg_is_valid_request(const char *alpha2);
7 6
7void reg_device_remove(struct wiphy *wiphy);
8
8int regulatory_init(void); 9int regulatory_init(void);
9void regulatory_exit(void); 10void regulatory_exit(void);
10 11
11int set_regdom(const struct ieee80211_regdomain *rd); 12int set_regdom(const struct ieee80211_regdomain *rd);
12 13
14enum environment_cap {
15 ENVIRON_ANY,
16 ENVIRON_INDOOR,
17 ENVIRON_OUTDOOR,
18};
19
20
21/**
22 * __regulatory_hint - hint to the wireless core a regulatory domain
23 * @wiphy: if the hint comes from country information from an AP, this
24 * is required to be set to the wiphy that received the information
25 * @alpha2: the ISO/IEC 3166 alpha2 being claimed the regulatory domain
26 * should be in.
27 * @country_ie_checksum: checksum of processed country IE, set this to 0
28 * if the hint did not come from a country IE
29 * @country_ie_env: the environment the IE told us we are in, %ENVIRON_*
30 *
31 * The Wireless subsystem can use this function to hint to the wireless core
32 * what it believes should be the current regulatory domain by giving it an
33 * ISO/IEC 3166 alpha2 country code it knows its regulatory domain should be
34 * in.
35 *
36 * Returns zero if all went fine, %-EALREADY if a regulatory domain had
37 * already been set or other standard error codes.
38 *
39 */
40extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
41 const char *alpha2, u32 country_ie_checksum,
42 enum environment_cap country_ie_env);
43
13#endif /* __NET_WIRELESS_REG_H */ 44#endif /* __NET_WIRELESS_REG_H */
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 29f820e18251..79a382877641 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -23,25 +23,20 @@ static inline struct cfg80211_registered_device *dev_to_rdev(
23 return container_of(dev, struct cfg80211_registered_device, wiphy.dev); 23 return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
24} 24}
25 25
26static ssize_t _show_index(struct device *dev, struct device_attribute *attr, 26#define SHOW_FMT(name, fmt, member) \
27 char *buf) 27static ssize_t name ## _show(struct device *dev, \
28{ 28 struct device_attribute *attr, \
29 return sprintf(buf, "%d\n", dev_to_rdev(dev)->idx); 29 char *buf) \
30{ \
31 return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
30} 32}
31 33
32static ssize_t _show_permaddr(struct device *dev, 34SHOW_FMT(index, "%d", idx);
33 struct device_attribute *attr, 35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
34 char *buf)
35{
36 unsigned char *addr = dev_to_rdev(dev)->wiphy.perm_addr;
37
38 return sprintf(buf, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
39 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
40}
41 36
42static struct device_attribute ieee80211_dev_attrs[] = { 37static struct device_attribute ieee80211_dev_attrs[] = {
43 __ATTR(index, S_IRUGO, _show_index, NULL), 38 __ATTR_RO(index),
44 __ATTR(macaddress, S_IRUGO, _show_permaddr, NULL), 39 __ATTR_RO(macaddress),
45 {} 40 {}
46}; 41};
47 42
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f54424693a38..e76cc28b0345 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -7,6 +7,25 @@
7#include <asm/bitops.h> 7#include <asm/bitops.h>
8#include "core.h" 8#include "core.h"
9 9
10struct ieee80211_rate *
11ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
12 u64 basic_rates, int bitrate)
13{
14 struct ieee80211_rate *result = &sband->bitrates[0];
15 int i;
16
17 for (i = 0; i < sband->n_bitrates; i++) {
18 if (!(basic_rates & BIT(i)))
19 continue;
20 if (sband->bitrates[i].bitrate > bitrate)
21 continue;
22 result = &sband->bitrates[i];
23 }
24
25 return result;
26}
27EXPORT_SYMBOL(ieee80211_get_response_rate);
28
10int ieee80211_channel_to_frequency(int chan) 29int ieee80211_channel_to_frequency(int chan)
11{ 30{
12 if (chan < 14) 31 if (chan < 14)
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
new file mode 100644
index 000000000000..58e489fd4aed
--- /dev/null
+++ b/net/wireless/wext-compat.c
@@ -0,0 +1,139 @@
1/*
2 * cfg80211 - wext compat code
3 *
4 * This is temporary code until all wireless functionality is migrated
5 * into cfg80211, when that happens all the exports here go away and
6 * we directly assign the wireless handlers of wireless interfaces.
7 *
8 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
9 */
10
11#include <linux/wireless.h>
12#include <linux/nl80211.h>
13#include <net/iw_handler.h>
14#include <net/wireless.h>
15#include <net/cfg80211.h>
16#include "core.h"
17
18int cfg80211_wext_giwname(struct net_device *dev,
19 struct iw_request_info *info,
20 char *name, char *extra)
21{
22 struct wireless_dev *wdev = dev->ieee80211_ptr;
23 struct ieee80211_supported_band *sband;
24 bool is_ht = false, is_a = false, is_b = false, is_g = false;
25
26 if (!wdev)
27 return -EOPNOTSUPP;
28
29 sband = wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
30 if (sband) {
31 is_a = true;
32 is_ht |= sband->ht_cap.ht_supported;
33 }
34
35 sband = wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
36 if (sband) {
37 int i;
38 /* Check for mandatory rates */
39 for (i = 0; i < sband->n_bitrates; i++) {
40 if (sband->bitrates[i].bitrate == 10)
41 is_b = true;
42 if (sband->bitrates[i].bitrate == 60)
43 is_g = true;
44 }
45 is_ht |= sband->ht_cap.ht_supported;
46 }
47
48 strcpy(name, "IEEE 802.11");
49 if (is_a)
50 strcat(name, "a");
51 if (is_b)
52 strcat(name, "b");
53 if (is_g)
54 strcat(name, "g");
55 if (is_ht)
56 strcat(name, "n");
57
58 return 0;
59}
60EXPORT_SYMBOL(cfg80211_wext_giwname);
61
62int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
63 u32 *mode, char *extra)
64{
65 struct wireless_dev *wdev = dev->ieee80211_ptr;
66 struct cfg80211_registered_device *rdev;
67 struct vif_params vifparams;
68 enum nl80211_iftype type;
69
70 if (!wdev)
71 return -EOPNOTSUPP;
72
73 rdev = wiphy_to_dev(wdev->wiphy);
74
75 if (!rdev->ops->change_virtual_intf)
76 return -EOPNOTSUPP;
77
78 /* don't support changing VLANs, you just re-create them */
79 if (wdev->iftype == NL80211_IFTYPE_AP_VLAN)
80 return -EOPNOTSUPP;
81
82 switch (*mode) {
83 case IW_MODE_INFRA:
84 type = NL80211_IFTYPE_STATION;
85 break;
86 case IW_MODE_ADHOC:
87 type = NL80211_IFTYPE_ADHOC;
88 break;
89 case IW_MODE_REPEAT:
90 type = NL80211_IFTYPE_WDS;
91 break;
92 case IW_MODE_MONITOR:
93 type = NL80211_IFTYPE_MONITOR;
94 break;
95 default:
96 return -EINVAL;
97 }
98
99 memset(&vifparams, 0, sizeof(vifparams));
100
101 return rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
102 NULL, &vifparams);
103}
104EXPORT_SYMBOL(cfg80211_wext_siwmode);
105
106int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
107 u32 *mode, char *extra)
108{
109 struct wireless_dev *wdev = dev->ieee80211_ptr;
110
111 if (!wdev)
112 return -EOPNOTSUPP;
113
114 switch (wdev->iftype) {
115 case NL80211_IFTYPE_AP:
116 *mode = IW_MODE_MASTER;
117 break;
118 case NL80211_IFTYPE_STATION:
119 *mode = IW_MODE_INFRA;
120 break;
121 case NL80211_IFTYPE_ADHOC:
122 *mode = IW_MODE_ADHOC;
123 break;
124 case NL80211_IFTYPE_MONITOR:
125 *mode = IW_MODE_MONITOR;
126 break;
127 case NL80211_IFTYPE_WDS:
128 *mode = IW_MODE_REPEAT;
129 break;
130 case NL80211_IFTYPE_AP_VLAN:
131 *mode = IW_MODE_SECOND; /* FIXME */
132 break;
133 default:
134 *mode = IW_MODE_AUTO;
135 break;
136 }
137 return 0;
138}
139EXPORT_SYMBOL(cfg80211_wext_giwmode);
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index d98ffb75119a..e49a2d1ef1e4 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -64,7 +64,7 @@
64 * o Remove spy_offset from struct iw_handler_def 64 * o Remove spy_offset from struct iw_handler_def
65 * o Start deprecating dev->get_wireless_stats, output a warning 65 * o Start deprecating dev->get_wireless_stats, output a warning
66 * o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless 66 * o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless
67 * o Don't loose INVALID/DBM flags when clearing UPDATED flags (iwstats) 67 * o Don't lose INVALID/DBM flags when clearing UPDATED flags (iwstats)
68 * 68 *
69 * v8 - 17.02.06 - Jean II 69 * v8 - 17.02.06 - Jean II
70 * o RtNetlink requests support (SET/GET) 70 * o RtNetlink requests support (SET/GET)