1 /******************************************************************************
3 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
9 Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 The full GNU General Public License is included in this distribution in the
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
31 ******************************************************************************/
33 #include <linux/kmod.h>
34 #include <linux/module.h>
35 #include <linux/jiffies.h>
37 #include <net/lib80211.h>
38 #include <linux/wireless.h>
40 #include "ieee80211.h"
42 static const char *ieee80211_modes[] = {
43 "?", "a", "b", "ab", "g", "ag", "bg", "abg"
46 #define MAX_CUSTOM_LEN 64
47 static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
48 char *start, char *stop,
49 struct ieee80211_network *network,
50 struct iw_request_info *info)
52 char custom[MAX_CUSTOM_LEN];
56 char *current_val; /* For rates */
59 /* First entry *MUST* be the AP MAC address */
61 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
62 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
63 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
65 /* Remaining entries will be displayed in the order we provide them */
68 iwe.cmd = SIOCGIWESSID;
70 iwe.u.data.length = min(network->ssid_len, (u8) 32);
71 start = iwe_stream_add_point(info, start, stop,
74 /* Add the protocol name */
75 iwe.cmd = SIOCGIWNAME;
76 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
77 ieee80211_modes[network->mode]);
78 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
81 iwe.cmd = SIOCGIWMODE;
82 if (network->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
83 if (network->capability & WLAN_CAPABILITY_ESS)
84 iwe.u.mode = IW_MODE_MASTER;
86 iwe.u.mode = IW_MODE_ADHOC;
88 start = iwe_stream_add_event(info, start, stop,
89 &iwe, IW_EV_UINT_LEN);
92 /* Add channel and frequency */
93 /* Note : userspace automatically computes channel using iwrange */
94 iwe.cmd = SIOCGIWFREQ;
95 iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
98 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
100 /* Add encryption capability */
101 iwe.cmd = SIOCGIWENCODE;
102 if (network->capability & WLAN_CAPABILITY_PRIVACY)
103 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
105 iwe.u.data.flags = IW_ENCODE_DISABLED;
106 iwe.u.data.length = 0;
107 start = iwe_stream_add_point(info, start, stop,
108 &iwe, network->ssid);
110 /* Add basic and extended rates */
111 /* Rate : stuffing multiple values in a single event require a bit
112 * more of magic - Jean II */
113 current_val = start + iwe_stream_lcp_len(info);
114 iwe.cmd = SIOCGIWRATE;
115 /* Those two flags are ignored... */
116 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
118 for (i = 0, j = 0; i < network->rates_len;) {
119 if (j < network->rates_ex_len &&
120 ((network->rates_ex[j] & 0x7F) <
121 (network->rates[i] & 0x7F)))
122 rate = network->rates_ex[j++] & 0x7F;
124 rate = network->rates[i++] & 0x7F;
125 /* Bit rate given in 500 kb/s units (+ 0x80) */
126 iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
127 /* Add new value to event */
128 current_val = iwe_stream_add_value(info, start, current_val,
129 stop, &iwe, IW_EV_PARAM_LEN);
131 for (; j < network->rates_ex_len; j++) {
132 rate = network->rates_ex[j] & 0x7F;
133 /* Bit rate given in 500 kb/s units (+ 0x80) */
134 iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
135 /* Add new value to event */
136 current_val = iwe_stream_add_value(info, start, current_val,
137 stop, &iwe, IW_EV_PARAM_LEN);
139 /* Check if we added any rate */
140 if ((current_val - start) > iwe_stream_lcp_len(info))
143 /* Add quality statistics */
145 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
146 IW_QUAL_NOISE_UPDATED;
148 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
149 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
150 IW_QUAL_LEVEL_INVALID;
153 if (ieee->perfect_rssi == ieee->worst_rssi)
154 iwe.u.qual.qual = 100;
158 (ieee->perfect_rssi - ieee->worst_rssi) *
159 (ieee->perfect_rssi - ieee->worst_rssi) -
160 (ieee->perfect_rssi - network->stats.rssi) *
161 (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
162 62 * (ieee->perfect_rssi -
163 network->stats.rssi))) /
164 ((ieee->perfect_rssi -
165 ieee->worst_rssi) * (ieee->perfect_rssi -
167 if (iwe.u.qual.qual > 100)
168 iwe.u.qual.qual = 100;
169 else if (iwe.u.qual.qual < 1)
173 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
174 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
175 iwe.u.qual.noise = 0;
177 iwe.u.qual.noise = network->stats.noise;
180 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) {
181 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
182 iwe.u.qual.level = 0;
184 iwe.u.qual.level = network->stats.signal;
187 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
189 iwe.cmd = IWEVCUSTOM;
192 iwe.u.data.length = p - custom;
193 if (iwe.u.data.length)
194 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
196 memset(&iwe, 0, sizeof(iwe));
197 if (network->wpa_ie_len) {
198 char buf[MAX_WPA_IE_LEN];
199 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
201 iwe.u.data.length = network->wpa_ie_len;
202 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
205 memset(&iwe, 0, sizeof(iwe));
206 if (network->rsn_ie_len) {
207 char buf[MAX_WPA_IE_LEN];
208 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
210 iwe.u.data.length = network->rsn_ie_len;
211 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
214 /* Add EXTRA: Age to display seconds since last beacon/probe response
215 * for given network. */
216 iwe.cmd = IWEVCUSTOM;
218 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
219 " Last beacon: %dms ago",
220 jiffies_to_msecs(jiffies - network->last_scanned));
221 iwe.u.data.length = p - custom;
222 if (iwe.u.data.length)
223 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
225 /* Add spectrum management information */
228 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Channel flags: ");
230 if (ieee80211_get_channel_flags(ieee, network->channel) &
231 IEEE80211_CH_INVALID) {
232 iwe.cmd = IWEVCUSTOM;
233 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "INVALID ");
236 if (ieee80211_get_channel_flags(ieee, network->channel) &
237 IEEE80211_CH_RADAR_DETECT) {
238 iwe.cmd = IWEVCUSTOM;
239 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "DFS ");
242 if (iwe.cmd == IWEVCUSTOM) {
243 iwe.u.data.length = p - custom;
244 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
250 #define SCAN_ITEM_SIZE 128
252 int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
253 struct iw_request_info *info,
254 union iwreq_data *wrqu, char *extra)
256 struct ieee80211_network *network;
261 char *stop = ev + wrqu->data.length;
263 DECLARE_SSID_BUF(ssid);
265 IEEE80211_DEBUG_WX("Getting scan\n");
267 spin_lock_irqsave(&ieee->lock, flags);
269 list_for_each_entry(network, &ieee->network_list, list) {
271 if (stop - ev < SCAN_ITEM_SIZE) {
276 if (ieee->scan_age == 0 ||
277 time_after(network->last_scanned + ieee->scan_age, jiffies))
278 ev = ieee80211_translate_scan(ieee, ev, stop, network,
281 IEEE80211_DEBUG_SCAN("Not showing network '%s ("
282 "%pM)' due to age (%dms).\n",
283 print_ssid(ssid, network->ssid,
286 jiffies_to_msecs(jiffies -
291 spin_unlock_irqrestore(&ieee->lock, flags);
293 wrqu->data.length = ev - extra;
294 wrqu->data.flags = 0;
296 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
301 int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
302 struct iw_request_info *info,
303 union iwreq_data *wrqu, char *keybuf)
305 struct iw_point *erq = &(wrqu->encoding);
306 struct net_device *dev = ieee->dev;
307 struct ieee80211_security sec = {
310 int i, key, key_provided, len;
311 struct lib80211_crypt_data **crypt;
312 int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
313 DECLARE_SSID_BUF(ssid);
315 IEEE80211_DEBUG_WX("SET_ENCODE\n");
317 key = erq->flags & IW_ENCODE_INDEX;
325 key = ieee->crypt_info.tx_keyidx;
328 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
329 "provided" : "default");
331 crypt = &ieee->crypt_info.crypt[key];
333 if (erq->flags & IW_ENCODE_DISABLED) {
334 if (key_provided && *crypt) {
335 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
337 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
339 IEEE80211_DEBUG_WX("Disabling encryption.\n");
341 /* Check all the keys to see if any are still configured,
342 * and if no key index was provided, de-init them all */
343 for (i = 0; i < WEP_KEYS; i++) {
344 if (ieee->crypt_info.crypt[i] != NULL) {
347 lib80211_crypt_delayed_deinit(&ieee->crypt_info,
348 &ieee->crypt_info.crypt[i]);
355 sec.level = SEC_LEVEL_0;
356 sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT;
364 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
366 if (*crypt != NULL && (*crypt)->ops != NULL &&
367 strcmp((*crypt)->ops->name, "WEP") != 0) {
368 /* changing to use WEP; deinit previously used algorithm
370 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
373 if (*crypt == NULL && host_crypto) {
374 struct lib80211_crypt_data *new_crypt;
376 /* take WEP into use */
377 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
379 if (new_crypt == NULL)
381 new_crypt->ops = lib80211_get_crypto_ops("WEP");
382 if (!new_crypt->ops) {
383 request_module("lib80211_crypt_wep");
384 new_crypt->ops = lib80211_get_crypto_ops("WEP");
387 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
388 new_crypt->priv = new_crypt->ops->init(key);
390 if (!new_crypt->ops || !new_crypt->priv) {
394 printk(KERN_WARNING "%s: could not initialize WEP: "
395 "load module lib80211_crypt_wep\n", dev->name);
401 /* If a new key was provided, set it up */
402 if (erq->length > 0) {
403 #ifdef CONFIG_IEEE80211_DEBUG
404 DECLARE_SSID_BUF(ssid);
407 len = erq->length <= 5 ? 5 : 13;
408 memcpy(sec.keys[key], keybuf, erq->length);
409 if (len > erq->length)
410 memset(sec.keys[key] + erq->length, 0,
412 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
413 key, print_ssid(ssid, sec.keys[key], len),
415 sec.key_sizes[key] = len;
417 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
419 sec.flags |= (1 << key);
420 /* This ensures a key will be activated if no key is
422 if (key == sec.active_key)
423 sec.flags |= SEC_ACTIVE_KEY;
427 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
428 NULL, (*crypt)->priv);
430 /* Set a default key of all 0 */
431 IEEE80211_DEBUG_WX("Setting key %d to all "
433 memset(sec.keys[key], 0, 13);
434 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
436 sec.key_sizes[key] = 13;
437 sec.flags |= (1 << key);
440 /* No key data - just set the default TX key index */
442 IEEE80211_DEBUG_WX("Setting key %d to default Tx "
444 ieee->crypt_info.tx_keyidx = key;
445 sec.active_key = key;
446 sec.flags |= SEC_ACTIVE_KEY;
449 if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
450 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
451 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
452 WLAN_AUTH_SHARED_KEY;
453 sec.flags |= SEC_AUTH_MODE;
454 IEEE80211_DEBUG_WX("Auth: %s\n",
455 sec.auth_mode == WLAN_AUTH_OPEN ?
456 "OPEN" : "SHARED KEY");
459 /* For now we just support WEP, so only set that security level...
460 * TODO: When WPA is added this is one place that needs to change */
461 sec.flags |= SEC_LEVEL;
462 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
463 sec.encode_alg[key] = SEC_ALG_WEP;
466 if (ieee->set_security)
467 ieee->set_security(dev, &sec);
469 /* Do not reset port if card is in Managed mode since resetting will
470 * generate new IEEE 802.11 authentication which may end up in looping
471 * with IEEE 802.1X. If your hardware requires a reset after WEP
472 * configuration (for example... Prism2), implement the reset_port in
473 * the callbacks structures used to initialize the 802.11 stack. */
474 if (ieee->reset_on_keychange &&
475 ieee->iw_mode != IW_MODE_INFRA &&
476 ieee->reset_port && ieee->reset_port(dev)) {
477 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
483 int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
484 struct iw_request_info *info,
485 union iwreq_data *wrqu, char *keybuf)
487 struct iw_point *erq = &(wrqu->encoding);
489 struct lib80211_crypt_data *crypt;
490 struct ieee80211_security *sec = &ieee->sec;
492 IEEE80211_DEBUG_WX("GET_ENCODE\n");
494 key = erq->flags & IW_ENCODE_INDEX;
500 key = ieee->crypt_info.tx_keyidx;
502 crypt = ieee->crypt_info.crypt[key];
503 erq->flags = key + 1;
507 erq->flags |= IW_ENCODE_DISABLED;
511 len = sec->key_sizes[key];
512 memcpy(keybuf, sec->keys[key], len);
515 erq->flags |= IW_ENCODE_ENABLED;
518 erq->flags |= IW_ENCODE_OPEN;
520 erq->flags |= IW_ENCODE_RESTRICTED;
525 int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
526 struct iw_request_info *info,
527 union iwreq_data *wrqu, char *extra)
529 struct net_device *dev = ieee->dev;
530 struct iw_point *encoding = &wrqu->encoding;
531 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
534 const char *alg, *module;
535 struct lib80211_crypto_ops *ops;
536 struct lib80211_crypt_data **crypt;
538 struct ieee80211_security sec = {
542 idx = encoding->flags & IW_ENCODE_INDEX;
544 if (idx < 1 || idx > WEP_KEYS)
548 idx = ieee->crypt_info.tx_keyidx;
550 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
551 crypt = &ieee->crypt_info.crypt[idx];
554 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
555 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
557 if (ieee->iw_mode == IW_MODE_INFRA)
558 crypt = &ieee->crypt_info.crypt[idx];
563 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
564 if ((encoding->flags & IW_ENCODE_DISABLED) ||
565 ext->alg == IW_ENCODE_ALG_NONE) {
567 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
569 for (i = 0; i < WEP_KEYS; i++)
570 if (ieee->crypt_info.crypt[i] != NULL)
576 sec.level = SEC_LEVEL_0;
577 sec.flags |= SEC_LEVEL;
585 if (group_key ? !ieee->host_mc_decrypt :
586 !(ieee->host_encrypt || ieee->host_decrypt ||
587 ieee->host_encrypt_msdu))
588 goto skip_host_crypt;
591 case IW_ENCODE_ALG_WEP:
593 module = "lib80211_crypt_wep";
595 case IW_ENCODE_ALG_TKIP:
597 module = "lib80211_crypt_tkip";
599 case IW_ENCODE_ALG_CCMP:
601 module = "lib80211_crypt_ccmp";
604 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
605 dev->name, ext->alg);
610 ops = lib80211_get_crypto_ops(alg);
612 request_module(module);
613 ops = lib80211_get_crypto_ops(alg);
616 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
617 dev->name, ext->alg);
622 if (*crypt == NULL || (*crypt)->ops != ops) {
623 struct lib80211_crypt_data *new_crypt;
625 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
627 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
628 if (new_crypt == NULL) {
632 new_crypt->ops = ops;
633 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
634 new_crypt->priv = new_crypt->ops->init(idx);
635 if (new_crypt->priv == NULL) {
643 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
644 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
645 (*crypt)->priv) < 0) {
646 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
652 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
653 ieee->crypt_info.tx_keyidx = idx;
654 sec.active_key = idx;
655 sec.flags |= SEC_ACTIVE_KEY;
658 if (ext->alg != IW_ENCODE_ALG_NONE) {
659 memcpy(sec.keys[idx], ext->key, ext->key_len);
660 sec.key_sizes[idx] = ext->key_len;
661 sec.flags |= (1 << idx);
662 if (ext->alg == IW_ENCODE_ALG_WEP) {
663 sec.encode_alg[idx] = SEC_ALG_WEP;
664 sec.flags |= SEC_LEVEL;
665 sec.level = SEC_LEVEL_1;
666 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
667 sec.encode_alg[idx] = SEC_ALG_TKIP;
668 sec.flags |= SEC_LEVEL;
669 sec.level = SEC_LEVEL_2;
670 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
671 sec.encode_alg[idx] = SEC_ALG_CCMP;
672 sec.flags |= SEC_LEVEL;
673 sec.level = SEC_LEVEL_3;
675 /* Don't set sec level for group keys. */
677 sec.flags &= ~SEC_LEVEL;
680 if (ieee->set_security)
681 ieee->set_security(ieee->dev, &sec);
684 * Do not reset port if card is in Managed mode since resetting will
685 * generate new IEEE 802.11 authentication which may end up in looping
686 * with IEEE 802.1X. If your hardware requires a reset after WEP
687 * configuration (for example... Prism2), implement the reset_port in
688 * the callbacks structures used to initialize the 802.11 stack.
690 if (ieee->reset_on_keychange &&
691 ieee->iw_mode != IW_MODE_INFRA &&
692 ieee->reset_port && ieee->reset_port(dev)) {
693 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
700 int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
701 struct iw_request_info *info,
702 union iwreq_data *wrqu, char *extra)
704 struct iw_point *encoding = &wrqu->encoding;
705 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
706 struct ieee80211_security *sec = &ieee->sec;
707 int idx, max_key_len;
709 max_key_len = encoding->length - sizeof(*ext);
713 idx = encoding->flags & IW_ENCODE_INDEX;
715 if (idx < 1 || idx > WEP_KEYS)
719 idx = ieee->crypt_info.tx_keyidx;
721 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
722 ext->alg != IW_ENCODE_ALG_WEP)
723 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
726 encoding->flags = idx + 1;
727 memset(ext, 0, sizeof(*ext));
730 ext->alg = IW_ENCODE_ALG_NONE;
732 encoding->flags |= IW_ENCODE_DISABLED;
734 if (sec->encode_alg[idx] == SEC_ALG_WEP)
735 ext->alg = IW_ENCODE_ALG_WEP;
736 else if (sec->encode_alg[idx] == SEC_ALG_TKIP)
737 ext->alg = IW_ENCODE_ALG_TKIP;
738 else if (sec->encode_alg[idx] == SEC_ALG_CCMP)
739 ext->alg = IW_ENCODE_ALG_CCMP;
743 ext->key_len = sec->key_sizes[idx];
744 memcpy(ext->key, sec->keys[idx], ext->key_len);
745 encoding->flags |= IW_ENCODE_ENABLED;
747 (ext->alg == IW_ENCODE_ALG_TKIP ||
748 ext->alg == IW_ENCODE_ALG_CCMP))
749 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
756 EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
757 EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
759 EXPORT_SYMBOL(ieee80211_wx_get_scan);
760 EXPORT_SYMBOL(ieee80211_wx_set_encode);
761 EXPORT_SYMBOL(ieee80211_wx_get_encode);