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/kmod.h>
34 #include <linux/slab.h>
35 #include <linux/module.h>
37 #include "ieee80211.h"
42 static struct modes_unit ieee80211_modes[] = {
51 #define iwe_stream_add_event_rsl iwe_stream_add_event
53 #define MAX_CUSTOM_LEN 64
54 static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
55 char *start, char *stop,
56 struct ieee80211_network *network,
57 struct iw_request_info *info)
59 char custom[MAX_CUSTOM_LEN];
60 char proto_name[IFNAMSIZ];
61 char *pname = proto_name;
66 static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
68 /* First entry *MUST* be the AP MAC address */
70 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
71 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
72 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
73 /* Remaining entries will be displayed in the order we provide them */
76 iwe.cmd = SIOCGIWESSID;
78 // if (network->flags & NETWORK_EMPTY_ESSID) {
79 if (network->ssid_len == 0) {
80 iwe.u.data.length = sizeof("<hidden>");
81 start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
83 iwe.u.data.length = min(network->ssid_len, (u8)32);
84 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
86 /* Add the protocol name */
87 iwe.cmd = SIOCGIWNAME;
88 for(i=0; i<ARRAY_SIZE(ieee80211_modes); i++) {
89 if(network->mode&(1<<i)) {
90 sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
91 pname +=ieee80211_modes[i].mode_size;
95 snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
96 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
98 iwe.cmd = SIOCGIWMODE;
99 if (network->capability &
100 (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
101 if (network->capability & WLAN_CAPABILITY_BSS)
102 iwe.u.mode = IW_MODE_MASTER;
104 iwe.u.mode = IW_MODE_ADHOC;
105 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
108 /* Add frequency/channel */
109 iwe.cmd = SIOCGIWFREQ;
110 /* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
112 iwe.u.freq.m = network->channel;
115 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
116 /* Add encryption capability */
117 iwe.cmd = SIOCGIWENCODE;
118 if (network->capability & WLAN_CAPABILITY_PRIVACY)
119 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
121 iwe.u.data.flags = IW_ENCODE_DISABLED;
122 iwe.u.data.length = 0;
123 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
124 /* Add basic and extended rates */
127 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
128 for (i = 0, j = 0; i < network->rates_len; ) {
129 if (j < network->rates_ex_len &&
130 ((network->rates_ex[j] & 0x7F) <
131 (network->rates[i] & 0x7F)))
132 rate = network->rates_ex[j++] & 0x7F;
134 rate = network->rates[i++] & 0x7F;
137 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
138 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
140 for (; j < network->rates_ex_len; j++) {
141 rate = network->rates_ex[j] & 0x7F;
142 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
143 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
148 if (network->mode >= IEEE_N_24G)//add N rate here;
150 PHT_CAPABILITY_ELE ht_cap = NULL;
151 bool is40M = false, isShortGI = false;
153 if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
154 ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
156 ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
157 is40M = (ht_cap->ChlWidth)?1:0;
158 isShortGI = (ht_cap->ChlWidth)?
159 ((ht_cap->ShortGI40Mhz)?1:0):
160 ((ht_cap->ShortGI20Mhz)?1:0);
162 max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
163 rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f];
167 iwe.cmd = SIOCGIWRATE;
168 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
169 iwe.u.bitrate.value = max_rate * 500000;
170 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
172 iwe.cmd = IWEVCUSTOM;
173 iwe.u.data.length = p - custom;
174 if (iwe.u.data.length)
175 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
176 /* Add quality statistics */
177 /* TODO: Fix these values... */
179 iwe.u.qual.qual = network->stats.signal;
180 iwe.u.qual.level = network->stats.rssi;
181 iwe.u.qual.noise = network->stats.noise;
182 iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
183 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
184 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
185 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
186 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
187 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
188 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
189 iwe.u.qual.updated = 7;
190 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
191 iwe.cmd = IWEVCUSTOM;
194 iwe.u.data.length = p - custom;
195 if (iwe.u.data.length)
196 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
198 if (ieee->wpa_enabled && network->wpa_ie_len){
199 char buf[MAX_WPA_IE_LEN * 2 + 30];
200 // printk("WPA IE\n");
202 p += sprintf(p, "wpa_ie=");
203 for (i = 0; i < network->wpa_ie_len; i++) {
204 p += sprintf(p, "%02x", network->wpa_ie[i]);
207 memset(&iwe, 0, sizeof(iwe));
208 iwe.cmd = IWEVCUSTOM;
209 iwe.u.data.length = strlen(buf);
210 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
213 if (ieee->wpa_enabled && network->rsn_ie_len){
214 char buf[MAX_WPA_IE_LEN * 2 + 30];
217 p += sprintf(p, "rsn_ie=");
218 for (i = 0; i < network->rsn_ie_len; i++) {
219 p += sprintf(p, "%02x", network->rsn_ie[i]);
222 memset(&iwe, 0, sizeof(iwe));
223 iwe.cmd = IWEVCUSTOM;
224 iwe.u.data.length = strlen(buf);
225 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
229 /* Add EXTRA: Age to display seconds since last beacon/probe response
230 * for given network. */
231 iwe.cmd = IWEVCUSTOM;
233 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
234 " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
235 iwe.u.data.length = p - custom;
236 if (iwe.u.data.length)
237 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
242 int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
243 struct iw_request_info *info,
244 union iwreq_data *wrqu, char *extra)
246 struct ieee80211_network *network;
250 // char *stop = ev + IW_SCAN_MAX_DATA;
251 char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
252 //char *stop = ev + IW_SCAN_MAX_DATA;
255 IEEE80211_DEBUG_WX("Getting scan\n");
256 mutex_lock(&ieee->wx_mutex);
257 spin_lock_irqsave(&ieee->lock, flags);
259 list_for_each_entry(network, &ieee->network_list, list) {
266 if (ieee->scan_age == 0 ||
267 time_after(network->last_scanned + ieee->scan_age, jiffies))
268 ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
270 IEEE80211_DEBUG_SCAN(
271 "Not showing network '%s ("
272 "%pM)' due to age (%lums).\n",
273 escape_essid(network->ssid,
276 (jiffies - network->last_scanned) / (HZ / 100));
279 spin_unlock_irqrestore(&ieee->lock, flags);
280 mutex_unlock(&ieee->wx_mutex);
281 wrqu->data.length = ev - extra;
282 wrqu->data.flags = 0;
284 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
288 EXPORT_SYMBOL(ieee80211_wx_get_scan);
290 int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
291 struct iw_request_info *info,
292 union iwreq_data *wrqu, char *keybuf)
294 struct iw_point *erq = &(wrqu->encoding);
295 struct net_device *dev = ieee->dev;
296 struct ieee80211_security sec = {
299 int i, key, key_provided, len;
300 struct ieee80211_crypt_data **crypt;
302 IEEE80211_DEBUG_WX("SET_ENCODE\n");
304 key = erq->flags & IW_ENCODE_INDEX;
312 key = ieee->tx_keyidx;
315 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
316 "provided" : "default");
317 crypt = &ieee->crypt[key];
319 if (erq->flags & IW_ENCODE_DISABLED) {
320 if (key_provided && *crypt) {
321 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
323 ieee80211_crypt_delayed_deinit(ieee, crypt);
325 IEEE80211_DEBUG_WX("Disabling encryption.\n");
327 /* Check all the keys to see if any are still configured,
328 * and if no key index was provided, de-init them all */
329 for (i = 0; i < WEP_KEYS; i++) {
330 if (ieee->crypt[i] != NULL) {
333 ieee80211_crypt_delayed_deinit(
334 ieee, &ieee->crypt[i]);
340 sec.level = SEC_LEVEL_0;
341 sec.flags |= SEC_ENABLED | SEC_LEVEL;
350 sec.flags |= SEC_ENABLED;
352 if (*crypt != NULL && (*crypt)->ops != NULL &&
353 strcmp((*crypt)->ops->name, "WEP") != 0) {
354 /* changing to use WEP; deinit previously used algorithm
356 ieee80211_crypt_delayed_deinit(ieee, crypt);
359 if (*crypt == NULL) {
360 struct ieee80211_crypt_data *new_crypt;
362 /* take WEP into use */
363 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
367 new_crypt->ops = try_then_request_module(ieee80211_get_crypto_ops("WEP"),
368 "ieee80211_crypt_wep");
369 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
370 new_crypt->priv = new_crypt->ops->init(key);
372 if (!new_crypt->ops || !new_crypt->priv) {
376 printk(KERN_WARNING "%s: could not initialize WEP: "
377 "load module ieee80211_crypt_wep\n",
384 /* If a new key was provided, set it up */
385 if (erq->length > 0) {
386 len = erq->length <= 5 ? 5 : 13;
387 memcpy(sec.keys[key], keybuf, erq->length);
388 if (len > erq->length)
389 memset(sec.keys[key] + erq->length, 0,
391 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
392 key, escape_essid(sec.keys[key], len),
394 sec.key_sizes[key] = len;
395 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
397 sec.flags |= (1 << key);
398 /* This ensures a key will be activated if no key is
400 if (key == sec.active_key)
401 sec.flags |= SEC_ACTIVE_KEY;
402 ieee->tx_keyidx = key;
405 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
406 NULL, (*crypt)->priv);
408 /* Set a default key of all 0 */
409 printk("Setting key %d to all zero.\n",
412 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
414 memset(sec.keys[key], 0, 13);
415 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
417 sec.key_sizes[key] = 13;
418 sec.flags |= (1 << key);
421 /* No key data - just set the default TX key index */
424 "Setting key %d to default Tx key.\n", key);
425 ieee->tx_keyidx = key;
426 sec.active_key = key;
427 sec.flags |= SEC_ACTIVE_KEY;
432 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
433 ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
434 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
435 sec.flags |= SEC_AUTH_MODE;
436 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
437 "OPEN" : "SHARED KEY");
439 /* For now we just support WEP, so only set that security level...
440 * TODO: When WPA is added this is one place that needs to change */
441 sec.flags |= SEC_LEVEL;
442 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
444 if (ieee->set_security)
445 ieee->set_security(dev, &sec);
447 /* Do not reset port if card is in Managed mode since resetting will
448 * generate new IEEE 802.11 authentication which may end up in looping
449 * with IEEE 802.1X. If your hardware requires a reset after WEP
450 * configuration (for example... Prism2), implement the reset_port in
451 * the callbacks structures used to initialize the 802.11 stack. */
452 if (ieee->reset_on_keychange &&
453 ieee->iw_mode != IW_MODE_INFRA &&
454 ieee->reset_port && ieee->reset_port(dev)) {
455 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
460 EXPORT_SYMBOL(ieee80211_wx_set_encode);
462 int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
463 struct iw_request_info *info,
464 union iwreq_data *wrqu, char *keybuf)
466 struct iw_point *erq = &(wrqu->encoding);
468 struct ieee80211_crypt_data *crypt;
470 IEEE80211_DEBUG_WX("GET_ENCODE\n");
472 if(ieee->iw_mode == IW_MODE_MONITOR)
475 key = erq->flags & IW_ENCODE_INDEX;
481 key = ieee->tx_keyidx;
483 crypt = ieee->crypt[key];
484 erq->flags = key + 1;
486 if (crypt == NULL || crypt->ops == NULL) {
488 erq->flags |= IW_ENCODE_DISABLED;
491 len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
492 erq->length = (len >= 0 ? len : 0);
494 erq->flags |= IW_ENCODE_ENABLED;
497 erq->flags |= IW_ENCODE_OPEN;
499 erq->flags |= IW_ENCODE_RESTRICTED;
503 EXPORT_SYMBOL(ieee80211_wx_get_encode);
505 int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
506 struct iw_request_info *info,
507 union iwreq_data *wrqu, char *extra)
510 struct net_device *dev = ieee->dev;
511 struct iw_point *encoding = &wrqu->encoding;
512 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
515 const char *alg, *module;
516 struct ieee80211_crypto_ops *ops;
517 struct ieee80211_crypt_data **crypt;
519 struct ieee80211_security sec = {
522 idx = encoding->flags & IW_ENCODE_INDEX;
524 if (idx < 1 || idx > WEP_KEYS)
528 idx = ieee->tx_keyidx;
530 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
532 crypt = &ieee->crypt[idx];
536 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
537 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
539 if (ieee->iw_mode == IW_MODE_INFRA)
541 crypt = &ieee->crypt[idx];
547 sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
548 if ((encoding->flags & IW_ENCODE_DISABLED) ||
549 ext->alg == IW_ENCODE_ALG_NONE) {
551 ieee80211_crypt_delayed_deinit(ieee, crypt);
553 for (i = 0; i < WEP_KEYS; i++)
555 if (ieee->crypt[i] != NULL)
562 sec.level = SEC_LEVEL_0;
563 sec.flags |= SEC_LEVEL;
571 case IW_ENCODE_ALG_WEP:
573 module = "ieee80211_crypt_wep";
575 case IW_ENCODE_ALG_TKIP:
577 module = "ieee80211_crypt_tkip";
579 case IW_ENCODE_ALG_CCMP:
581 module = "ieee80211_crypt_ccmp";
584 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
585 dev->name, ext->alg);
589 printk("alg name:%s\n",alg);
591 ops = try_then_request_module(ieee80211_get_crypto_ops(alg), module);
593 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
594 dev->name, ext->alg);
595 printk("========>unknown crypto alg %d\n", ext->alg);
600 if (*crypt == NULL || (*crypt)->ops != ops) {
601 struct ieee80211_crypt_data *new_crypt;
603 ieee80211_crypt_delayed_deinit(ieee, crypt);
605 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
610 new_crypt->ops = ops;
611 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
612 new_crypt->priv = new_crypt->ops->init(idx);
613 if (new_crypt->priv == NULL) {
621 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
622 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
623 (*crypt)->priv) < 0) {
624 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
625 printk("key setting failed\n");
630 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
631 ieee->tx_keyidx = idx;
632 sec.active_key = idx;
633 sec.flags |= SEC_ACTIVE_KEY;
636 if (ext->alg != IW_ENCODE_ALG_NONE) {
637 //memcpy(sec.keys[idx], ext->key, ext->key_len);
638 sec.key_sizes[idx] = ext->key_len;
639 sec.flags |= (1 << idx);
640 if (ext->alg == IW_ENCODE_ALG_WEP) {
641 // sec.encode_alg[idx] = SEC_ALG_WEP;
642 sec.flags |= SEC_LEVEL;
643 sec.level = SEC_LEVEL_1;
644 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
645 // sec.encode_alg[idx] = SEC_ALG_TKIP;
646 sec.flags |= SEC_LEVEL;
647 sec.level = SEC_LEVEL_2;
648 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
649 // sec.encode_alg[idx] = SEC_ALG_CCMP;
650 sec.flags |= SEC_LEVEL;
651 sec.level = SEC_LEVEL_3;
653 /* Don't set sec level for group keys. */
655 sec.flags &= ~SEC_LEVEL;
658 if (ieee->set_security)
659 ieee->set_security(ieee->dev, &sec);
661 if (ieee->reset_on_keychange &&
662 ieee->iw_mode != IW_MODE_INFRA &&
663 ieee->reset_port && ieee->reset_port(dev)) {
664 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
669 EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
671 int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
672 struct iw_request_info *info,
673 union iwreq_data *wrqu, char *extra)
675 struct iw_point *encoding = &wrqu->encoding;
676 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
677 struct ieee80211_crypt_data *crypt;
678 int idx, max_key_len;
680 max_key_len = encoding->length - sizeof(*ext);
684 idx = encoding->flags & IW_ENCODE_INDEX;
686 if (idx < 1 || idx > WEP_KEYS)
690 idx = ieee->tx_keyidx;
692 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
693 ext->alg != IW_ENCODE_ALG_WEP)
694 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
697 crypt = ieee->crypt[idx];
698 encoding->flags = idx + 1;
699 memset(ext, 0, sizeof(*ext));
701 if (crypt == NULL || crypt->ops == NULL ) {
702 ext->alg = IW_ENCODE_ALG_NONE;
704 encoding->flags |= IW_ENCODE_DISABLED;
706 if (strcmp(crypt->ops->name, "WEP") == 0 )
707 ext->alg = IW_ENCODE_ALG_WEP;
708 else if (strcmp(crypt->ops->name, "TKIP"))
709 ext->alg = IW_ENCODE_ALG_TKIP;
710 else if (strcmp(crypt->ops->name, "CCMP"))
711 ext->alg = IW_ENCODE_ALG_CCMP;
714 ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
715 encoding->flags |= IW_ENCODE_ENABLED;
717 (ext->alg == IW_ENCODE_ALG_TKIP ||
718 ext->alg == IW_ENCODE_ALG_CCMP))
719 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
724 EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
726 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
727 struct iw_request_info *info,
728 union iwreq_data *wrqu, char *extra)
730 struct iw_mlme *mlme = (struct iw_mlme *) extra;
733 case IW_MLME_DISASSOC:
734 ieee80211_disassociate(ieee);
741 EXPORT_SYMBOL(ieee80211_wx_set_mlme);
743 int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
744 struct iw_request_info *info,
745 struct iw_param *data, char *extra)
747 switch (data->flags & IW_AUTH_INDEX) {
748 case IW_AUTH_WPA_VERSION:
749 /*need to support wpa2 here*/
751 case IW_AUTH_CIPHER_PAIRWISE:
752 case IW_AUTH_CIPHER_GROUP:
753 case IW_AUTH_KEY_MGMT:
755 * * Host AP driver does not use these parameters and allows
756 * * wpa_supplicant to control them internally.
759 case IW_AUTH_TKIP_COUNTERMEASURES:
760 ieee->tkip_countermeasures = data->value;
762 case IW_AUTH_DROP_UNENCRYPTED:
763 ieee->drop_unencrypted = data->value;
766 case IW_AUTH_80211_AUTH_ALG:
767 //printk("======>%s():data->value is %d\n",__func__,data->value);
768 // ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
769 if(data->value & IW_AUTH_ALG_SHARED_KEY){
773 else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
777 else if(data->value & IW_AUTH_ALG_LEAP){
785 case IW_AUTH_WPA_ENABLED:
786 ieee->wpa_enabled = (data->value)?1:0;
789 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
790 ieee->ieee802_1x = data->value;
792 case IW_AUTH_PRIVACY_INVOKED:
793 ieee->privacy_invoked = data->value;
800 EXPORT_SYMBOL(ieee80211_wx_set_auth);
802 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
806 if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
808 // printk("return error out, len:%d\n", len);
817 printk("len:%zu, ie:%d\n", len, ie[1]);
820 buf = kmemdup(ie, len, GFP_KERNEL);
825 ieee->wpa_ie_len = len;
830 ieee->wpa_ie_len = 0;
834 EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);