1 /******************************************************************************
3 Copyright(c) 2004 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 <jkmaline@cc.hut.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 ******************************************************************************/
32 #include <linux/wireless.h>
33 #include <linux/version.h>
34 #include <linux/kmod.h>
35 #include <linux/module.h>
37 #include "ieee80211.h"
43 struct modes_unit ieee80211_modes[] = {
52 #define iwe_stream_add_event_rsl iwe_stream_add_event
54 #define MAX_CUSTOM_LEN 64
55 static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
56 char *start, char *stop,
57 struct ieee80211_network *network,
58 struct iw_request_info *info)
60 char custom[MAX_CUSTOM_LEN];
61 char proto_name[IFNAMSIZ];
62 char *pname = proto_name;
67 static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
69 /* First entry *MUST* be the AP MAC address */
71 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
72 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
73 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
75 /* Remaining entries will be displayed in the order we provide them */
78 iwe.cmd = SIOCGIWESSID;
80 // if (network->flags & NETWORK_EMPTY_ESSID) {
81 if (network->ssid_len == 0) {
82 iwe.u.data.length = sizeof("<hidden>");
83 start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
85 iwe.u.data.length = min(network->ssid_len, (u8)32);
86 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
88 /* Add the protocol name */
89 iwe.cmd = SIOCGIWNAME;
90 for(i=0; i<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); i++) {
91 if(network->mode&(1<<i)) {
92 sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
93 pname +=ieee80211_modes[i].mode_size;
97 snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
98 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
100 iwe.cmd = SIOCGIWMODE;
101 if (network->capability &
102 (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
103 if (network->capability & WLAN_CAPABILITY_BSS)
104 iwe.u.mode = IW_MODE_MASTER;
106 iwe.u.mode = IW_MODE_ADHOC;
107 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
110 /* Add frequency/channel */
111 iwe.cmd = SIOCGIWFREQ;
112 /* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
114 iwe.u.freq.m = network->channel;
117 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
118 /* Add encryption capability */
119 iwe.cmd = SIOCGIWENCODE;
120 if (network->capability & WLAN_CAPABILITY_PRIVACY)
121 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
123 iwe.u.data.flags = IW_ENCODE_DISABLED;
124 iwe.u.data.length = 0;
125 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
126 /* Add basic and extended rates */
129 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
130 for (i = 0, j = 0; i < network->rates_len; ) {
131 if (j < network->rates_ex_len &&
132 ((network->rates_ex[j] & 0x7F) <
133 (network->rates[i] & 0x7F)))
134 rate = network->rates_ex[j++] & 0x7F;
136 rate = network->rates[i++] & 0x7F;
139 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
140 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
142 for (; j < network->rates_ex_len; j++) {
143 rate = network->rates_ex[j] & 0x7F;
144 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
145 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
150 if (network->mode >= IEEE_N_24G)//add N rate here;
152 PHT_CAPABILITY_ELE ht_cap = NULL;
153 bool is40M = false, isShortGI = false;
155 if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
156 ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
158 ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
159 is40M = (ht_cap->ChlWidth)?1:0;
160 isShortGI = (ht_cap->ChlWidth)?
161 ((ht_cap->ShortGI40Mhz)?1:0):
162 ((ht_cap->ShortGI20Mhz)?1:0);
164 max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
165 rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f];
170 iwe.cmd = SIOCGIWRATE;
171 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
172 iwe.u.bitrate.value = max_rate * 500000;
173 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
176 iwe.cmd = IWEVCUSTOM;
177 iwe.u.data.length = p - custom;
178 if (iwe.u.data.length)
179 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
181 /* Add quality statistics */
182 /* TODO: Fix these values... */
184 iwe.u.qual.qual = network->stats.signal;
185 iwe.u.qual.level = network->stats.rssi;
186 iwe.u.qual.noise = network->stats.noise;
187 iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
188 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
189 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
190 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
191 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
192 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
193 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
194 iwe.u.qual.updated = 7;
195 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
196 iwe.cmd = IWEVCUSTOM;
199 iwe.u.data.length = p - custom;
200 if (iwe.u.data.length)
201 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
203 memset(&iwe, 0, sizeof(iwe));
204 if (network->wpa_ie_len)
206 char buf[MAX_WPA_IE_LEN];
207 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
209 iwe.u.data.length = network->wpa_ie_len;
210 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
212 memset(&iwe, 0, sizeof(iwe));
213 if (network->rsn_ie_len)
215 char buf[MAX_WPA_IE_LEN];
216 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
218 iwe.u.data.length = network->rsn_ie_len;
219 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
222 /* Add EXTRA: Age to display seconds since last beacon/probe response
223 * for given network. */
224 iwe.cmd = IWEVCUSTOM;
226 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
227 " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
228 iwe.u.data.length = p - custom;
229 if (iwe.u.data.length)
230 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
235 int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
236 struct iw_request_info *info,
237 union iwreq_data *wrqu, char *extra)
239 struct ieee80211_network *network;
243 // char *stop = ev + IW_SCAN_MAX_DATA;
244 char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
245 //char *stop = ev + IW_SCAN_MAX_DATA;
248 IEEE80211_DEBUG_WX("Getting scan\n");
250 spin_lock_irqsave(&ieee->lock, flags);
252 list_for_each_entry(network, &ieee->network_list, list) {
259 if (ieee->scan_age == 0 ||
260 time_after(network->last_scanned + ieee->scan_age, jiffies))
261 ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
263 IEEE80211_DEBUG_SCAN(
264 "Not showing network '%s ("
265 MAC_FMT ")' due to age (%lums).\n",
266 escape_essid(network->ssid,
268 MAC_ARG(network->bssid),
269 (jiffies - network->last_scanned) / (HZ / 100));
272 spin_unlock_irqrestore(&ieee->lock, flags);
274 wrqu->data.length = ev - extra;
275 wrqu->data.flags = 0;
277 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
282 int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
283 struct iw_request_info *info,
284 union iwreq_data *wrqu, char *keybuf)
286 struct iw_point *erq = &(wrqu->encoding);
287 struct net_device *dev = ieee->dev;
288 struct ieee80211_security sec = {
291 int i, key, key_provided, len;
292 struct ieee80211_crypt_data **crypt;
294 IEEE80211_DEBUG_WX("SET_ENCODE\n");
296 key = erq->flags & IW_ENCODE_INDEX;
304 key = ieee->tx_keyidx;
307 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
308 "provided" : "default");
309 crypt = &ieee->crypt[key];
311 if (erq->flags & IW_ENCODE_DISABLED) {
312 if (key_provided && *crypt) {
313 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
315 ieee80211_crypt_delayed_deinit(ieee, crypt);
317 IEEE80211_DEBUG_WX("Disabling encryption.\n");
319 /* Check all the keys to see if any are still configured,
320 * and if no key index was provided, de-init them all */
321 for (i = 0; i < WEP_KEYS; i++) {
322 if (ieee->crypt[i] != NULL) {
325 ieee80211_crypt_delayed_deinit(
326 ieee, &ieee->crypt[i]);
332 sec.level = SEC_LEVEL_0;
333 sec.flags |= SEC_ENABLED | SEC_LEVEL;
342 sec.flags |= SEC_ENABLED;
344 if (*crypt != NULL && (*crypt)->ops != NULL &&
345 strcmp((*crypt)->ops->name, "WEP") != 0) {
346 /* changing to use WEP; deinit previously used algorithm
348 ieee80211_crypt_delayed_deinit(ieee, crypt);
351 if (*crypt == NULL) {
352 struct ieee80211_crypt_data *new_crypt;
354 /* take WEP into use */
355 new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
357 if (new_crypt == NULL)
359 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
360 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
361 if (!new_crypt->ops) {
362 request_module("ieee80211_crypt_wep");
363 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
365 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
366 new_crypt->priv = new_crypt->ops->init(key);
368 if (!new_crypt->ops || !new_crypt->priv) {
372 printk(KERN_WARNING "%s: could not initialize WEP: "
373 "load module ieee80211_crypt_wep\n",
380 /* If a new key was provided, set it up */
381 if (erq->length > 0) {
382 len = erq->length <= 5 ? 5 : 13;
383 memcpy(sec.keys[key], keybuf, erq->length);
384 if (len > erq->length)
385 memset(sec.keys[key] + erq->length, 0,
387 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
388 key, escape_essid(sec.keys[key], len),
390 sec.key_sizes[key] = len;
391 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
393 sec.flags |= (1 << key);
394 /* This ensures a key will be activated if no key is
396 if (key == sec.active_key)
397 sec.flags |= SEC_ACTIVE_KEY;
398 ieee->tx_keyidx = key;
401 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
402 NULL, (*crypt)->priv);
404 /* Set a default key of all 0 */
405 printk("Setting key %d to all zero.\n",
408 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
410 memset(sec.keys[key], 0, 13);
411 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
413 sec.key_sizes[key] = 13;
414 sec.flags |= (1 << key);
417 /* No key data - just set the default TX key index */
420 "Setting key %d to default Tx key.\n", key);
421 ieee->tx_keyidx = key;
422 sec.active_key = key;
423 sec.flags |= SEC_ACTIVE_KEY;
428 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
429 ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
430 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
431 sec.flags |= SEC_AUTH_MODE;
432 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
433 "OPEN" : "SHARED KEY");
435 /* For now we just support WEP, so only set that security level...
436 * TODO: When WPA is added this is one place that needs to change */
437 sec.flags |= SEC_LEVEL;
438 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
440 if (ieee->set_security)
441 ieee->set_security(dev, &sec);
443 /* Do not reset port if card is in Managed mode since resetting will
444 * generate new IEEE 802.11 authentication which may end up in looping
445 * with IEEE 802.1X. If your hardware requires a reset after WEP
446 * configuration (for example... Prism2), implement the reset_port in
447 * the callbacks structures used to initialize the 802.11 stack. */
448 if (ieee->reset_on_keychange &&
449 ieee->iw_mode != IW_MODE_INFRA &&
450 ieee->reset_port && ieee->reset_port(dev)) {
451 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
457 int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
458 struct iw_request_info *info,
459 union iwreq_data *wrqu, char *keybuf)
461 struct iw_point *erq = &(wrqu->encoding);
463 struct ieee80211_crypt_data *crypt;
465 IEEE80211_DEBUG_WX("GET_ENCODE\n");
467 if(ieee->iw_mode == IW_MODE_MONITOR)
470 key = erq->flags & IW_ENCODE_INDEX;
476 key = ieee->tx_keyidx;
478 crypt = ieee->crypt[key];
479 erq->flags = key + 1;
481 if (crypt == NULL || crypt->ops == NULL) {
483 erq->flags |= IW_ENCODE_DISABLED;
487 len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
488 erq->length = (len >= 0 ? len : 0);
490 erq->flags |= IW_ENCODE_ENABLED;
493 erq->flags |= IW_ENCODE_OPEN;
495 erq->flags |= IW_ENCODE_RESTRICTED;
500 int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
501 struct iw_request_info *info,
502 union iwreq_data *wrqu, char *extra)
505 struct net_device *dev = ieee->dev;
506 struct iw_point *encoding = &wrqu->encoding;
507 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
510 const char *alg, *module;
511 struct ieee80211_crypto_ops *ops;
512 struct ieee80211_crypt_data **crypt;
514 struct ieee80211_security sec = {
517 //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
518 idx = encoding->flags & IW_ENCODE_INDEX;
520 if (idx < 1 || idx > WEP_KEYS)
524 idx = ieee->tx_keyidx;
526 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
528 crypt = &ieee->crypt[idx];
532 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
533 //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
534 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
536 if (ieee->iw_mode == IW_MODE_INFRA)
538 crypt = &ieee->crypt[idx];
544 sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
545 if ((encoding->flags & IW_ENCODE_DISABLED) ||
546 ext->alg == IW_ENCODE_ALG_NONE) {
548 ieee80211_crypt_delayed_deinit(ieee, crypt);
550 for (i = 0; i < WEP_KEYS; i++)
552 if (ieee->crypt[i] != NULL)
559 sec.level = SEC_LEVEL_0;
560 sec.flags |= SEC_LEVEL;
562 //printk("disabled: flag:%x\n", encoding->flags);
570 case IW_ENCODE_ALG_WEP:
572 module = "ieee80211_crypt_wep";
574 case IW_ENCODE_ALG_TKIP:
576 module = "ieee80211_crypt_tkip";
578 case IW_ENCODE_ALG_CCMP:
580 module = "ieee80211_crypt_ccmp";
583 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
584 dev->name, ext->alg);
588 printk("alg name:%s\n",alg);
590 ops = ieee80211_get_crypto_ops(alg);
592 request_module("%s", module);
593 ops = ieee80211_get_crypto_ops(alg);
596 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
597 dev->name, ext->alg);
598 printk("========>unknown crypto alg %d\n", ext->alg);
603 if (*crypt == NULL || (*crypt)->ops != ops) {
604 struct ieee80211_crypt_data *new_crypt;
606 ieee80211_crypt_delayed_deinit(ieee, crypt);
608 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
609 if (new_crypt == NULL) {
613 new_crypt->ops = ops;
614 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
615 new_crypt->priv = new_crypt->ops->init(idx);
616 if (new_crypt->priv == NULL) {
625 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
626 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
627 (*crypt)->priv) < 0) {
628 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
629 printk("key setting failed\n");
635 //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
636 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
637 ieee->tx_keyidx = idx;
638 sec.active_key = idx;
639 sec.flags |= SEC_ACTIVE_KEY;
642 if (ext->alg != IW_ENCODE_ALG_NONE) {
643 //memcpy(sec.keys[idx], ext->key, ext->key_len);
644 sec.key_sizes[idx] = ext->key_len;
645 sec.flags |= (1 << idx);
646 if (ext->alg == IW_ENCODE_ALG_WEP) {
647 // sec.encode_alg[idx] = SEC_ALG_WEP;
648 sec.flags |= SEC_LEVEL;
649 sec.level = SEC_LEVEL_1;
650 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
651 // sec.encode_alg[idx] = SEC_ALG_TKIP;
652 sec.flags |= SEC_LEVEL;
653 sec.level = SEC_LEVEL_2;
654 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
655 // sec.encode_alg[idx] = SEC_ALG_CCMP;
656 sec.flags |= SEC_LEVEL;
657 sec.level = SEC_LEVEL_3;
659 /* Don't set sec level for group keys. */
661 sec.flags &= ~SEC_LEVEL;
665 if (ieee->set_security)
666 ieee->set_security(ieee->dev, &sec);
668 if (ieee->reset_on_keychange &&
669 ieee->iw_mode != IW_MODE_INFRA &&
670 ieee->reset_port && ieee->reset_port(dev)) {
671 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
678 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
679 struct iw_request_info *info,
680 union iwreq_data *wrqu, char *extra)
682 struct iw_mlme *mlme = (struct iw_mlme *) extra;
686 case IW_MLME_DISASSOC:
687 ieee80211_disassociate(ieee);
696 int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
697 struct iw_request_info *info,
698 struct iw_param *data, char *extra)
700 switch (data->flags & IW_AUTH_INDEX) {
701 case IW_AUTH_WPA_VERSION:
702 /*need to support wpa2 here*/
703 //printk("wpa version:%x\n", data->value);
705 case IW_AUTH_CIPHER_PAIRWISE:
706 case IW_AUTH_CIPHER_GROUP:
707 case IW_AUTH_KEY_MGMT:
709 * * Host AP driver does not use these parameters and allows
710 * * wpa_supplicant to control them internally.
713 case IW_AUTH_TKIP_COUNTERMEASURES:
714 ieee->tkip_countermeasures = data->value;
716 case IW_AUTH_DROP_UNENCRYPTED:
717 ieee->drop_unencrypted = data->value;
720 case IW_AUTH_80211_AUTH_ALG:
721 //printk("======>%s():data->value is %d\n",__FUNCTION__,data->value);
722 // ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
723 if(data->value & IW_AUTH_ALG_SHARED_KEY){
727 else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
731 else if(data->value & IW_AUTH_ALG_LEAP){
734 //printk("hahahaa:LEAP\n");
738 //printk("open_wep:%d\n", ieee->open_wep);
742 case IW_AUTH_WPA_ENABLED:
743 ieee->wpa_enabled = (data->value)?1:0;
744 //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
748 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
749 ieee->ieee802_1x = data->value;
751 case IW_AUTH_PRIVACY_INVOKED:
752 ieee->privacy_invoked = data->value;
762 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
766 if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
768 // printk("return error out, len:%d\n", len);
777 printk("len:%d, ie:%d\n", len, ie[1]);
780 buf = kmalloc(len, GFP_KERNEL);
783 memcpy(buf, ie, len);
786 ieee->wpa_ie_len = len;
792 ieee->wpa_ie_len = 0;