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");
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);
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),
365 if (new_crypt == NULL)
367 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
368 if (!new_crypt->ops) {
369 request_module("ieee80211_crypt_wep");
370 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
372 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
373 new_crypt->priv = new_crypt->ops->init(key);
375 if (!new_crypt->ops || !new_crypt->priv) {
379 printk(KERN_WARNING "%s: could not initialize WEP: "
380 "load module ieee80211_crypt_wep\n",
387 /* If a new key was provided, set it up */
388 if (erq->length > 0) {
389 len = erq->length <= 5 ? 5 : 13;
390 memcpy(sec.keys[key], keybuf, erq->length);
391 if (len > erq->length)
392 memset(sec.keys[key] + erq->length, 0,
394 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
395 key, escape_essid(sec.keys[key], len),
397 sec.key_sizes[key] = len;
398 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
400 sec.flags |= (1 << key);
401 /* This ensures a key will be activated if no key is
403 if (key == sec.active_key)
404 sec.flags |= SEC_ACTIVE_KEY;
405 ieee->tx_keyidx = key;
408 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
409 NULL, (*crypt)->priv);
411 /* Set a default key of all 0 */
412 printk("Setting key %d to all zero.\n",
415 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
417 memset(sec.keys[key], 0, 13);
418 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
420 sec.key_sizes[key] = 13;
421 sec.flags |= (1 << key);
424 /* No key data - just set the default TX key index */
427 "Setting key %d to default Tx key.\n", key);
428 ieee->tx_keyidx = key;
429 sec.active_key = key;
430 sec.flags |= SEC_ACTIVE_KEY;
435 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
436 ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
437 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
438 sec.flags |= SEC_AUTH_MODE;
439 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
440 "OPEN" : "SHARED KEY");
442 /* For now we just support WEP, so only set that security level...
443 * TODO: When WPA is added this is one place that needs to change */
444 sec.flags |= SEC_LEVEL;
445 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
447 if (ieee->set_security)
448 ieee->set_security(dev, &sec);
450 /* Do not reset port if card is in Managed mode since resetting will
451 * generate new IEEE 802.11 authentication which may end up in looping
452 * with IEEE 802.1X. If your hardware requires a reset after WEP
453 * configuration (for example... Prism2), implement the reset_port in
454 * the callbacks structures used to initialize the 802.11 stack. */
455 if (ieee->reset_on_keychange &&
456 ieee->iw_mode != IW_MODE_INFRA &&
457 ieee->reset_port && ieee->reset_port(dev)) {
458 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
463 EXPORT_SYMBOL(ieee80211_wx_set_encode);
465 int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
466 struct iw_request_info *info,
467 union iwreq_data *wrqu, char *keybuf)
469 struct iw_point *erq = &(wrqu->encoding);
471 struct ieee80211_crypt_data *crypt;
473 IEEE80211_DEBUG_WX("GET_ENCODE\n");
475 if(ieee->iw_mode == IW_MODE_MONITOR)
478 key = erq->flags & IW_ENCODE_INDEX;
484 key = ieee->tx_keyidx;
486 crypt = ieee->crypt[key];
487 erq->flags = key + 1;
489 if (crypt == NULL || crypt->ops == NULL) {
491 erq->flags |= IW_ENCODE_DISABLED;
494 len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
495 erq->length = (len >= 0 ? len : 0);
497 erq->flags |= IW_ENCODE_ENABLED;
500 erq->flags |= IW_ENCODE_OPEN;
502 erq->flags |= IW_ENCODE_RESTRICTED;
506 EXPORT_SYMBOL(ieee80211_wx_get_encode);
508 int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
509 struct iw_request_info *info,
510 union iwreq_data *wrqu, char *extra)
513 struct net_device *dev = ieee->dev;
514 struct iw_point *encoding = &wrqu->encoding;
515 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
518 const char *alg, *module;
519 struct ieee80211_crypto_ops *ops;
520 struct ieee80211_crypt_data **crypt;
522 struct ieee80211_security sec = {
525 //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
526 idx = encoding->flags & IW_ENCODE_INDEX;
528 if (idx < 1 || idx > WEP_KEYS)
532 idx = ieee->tx_keyidx;
534 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
536 crypt = &ieee->crypt[idx];
540 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
541 //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
542 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
544 if (ieee->iw_mode == IW_MODE_INFRA)
546 crypt = &ieee->crypt[idx];
552 sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
553 if ((encoding->flags & IW_ENCODE_DISABLED) ||
554 ext->alg == IW_ENCODE_ALG_NONE) {
556 ieee80211_crypt_delayed_deinit(ieee, crypt);
558 for (i = 0; i < WEP_KEYS; i++)
560 if (ieee->crypt[i] != NULL)
567 sec.level = SEC_LEVEL_0;
568 sec.flags |= SEC_LEVEL;
570 //printk("disabled: flag:%x\n", encoding->flags);
577 case IW_ENCODE_ALG_WEP:
579 module = "ieee80211_crypt_wep";
581 case IW_ENCODE_ALG_TKIP:
583 module = "ieee80211_crypt_tkip";
585 case IW_ENCODE_ALG_CCMP:
587 module = "ieee80211_crypt_ccmp";
590 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
591 dev->name, ext->alg);
595 printk("alg name:%s\n",alg);
597 ops = ieee80211_get_crypto_ops(alg);
599 request_module(module);
600 ops = ieee80211_get_crypto_ops(alg);
603 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
604 dev->name, ext->alg);
605 printk("========>unknown crypto alg %d\n", ext->alg);
610 if (*crypt == NULL || (*crypt)->ops != ops) {
611 struct ieee80211_crypt_data *new_crypt;
613 ieee80211_crypt_delayed_deinit(ieee, crypt);
615 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
616 if (new_crypt == NULL) {
620 new_crypt->ops = ops;
621 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
622 new_crypt->priv = new_crypt->ops->init(idx);
623 if (new_crypt->priv == NULL) {
632 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
633 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
634 (*crypt)->priv) < 0) {
635 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
636 printk("key setting failed\n");
641 //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
642 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
643 ieee->tx_keyidx = idx;
644 sec.active_key = idx;
645 sec.flags |= SEC_ACTIVE_KEY;
648 if (ext->alg != IW_ENCODE_ALG_NONE) {
649 //memcpy(sec.keys[idx], ext->key, ext->key_len);
650 sec.key_sizes[idx] = ext->key_len;
651 sec.flags |= (1 << idx);
652 if (ext->alg == IW_ENCODE_ALG_WEP) {
653 // sec.encode_alg[idx] = SEC_ALG_WEP;
654 sec.flags |= SEC_LEVEL;
655 sec.level = SEC_LEVEL_1;
656 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
657 // sec.encode_alg[idx] = SEC_ALG_TKIP;
658 sec.flags |= SEC_LEVEL;
659 sec.level = SEC_LEVEL_2;
660 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
661 // sec.encode_alg[idx] = SEC_ALG_CCMP;
662 sec.flags |= SEC_LEVEL;
663 sec.level = SEC_LEVEL_3;
665 /* Don't set sec level for group keys. */
667 sec.flags &= ~SEC_LEVEL;
670 if (ieee->set_security)
671 ieee->set_security(ieee->dev, &sec);
673 if (ieee->reset_on_keychange &&
674 ieee->iw_mode != IW_MODE_INFRA &&
675 ieee->reset_port && ieee->reset_port(dev)) {
676 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
681 EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
683 int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
684 struct iw_request_info *info,
685 union iwreq_data *wrqu, char *extra)
687 struct iw_point *encoding = &wrqu->encoding;
688 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
689 struct ieee80211_crypt_data *crypt;
690 int idx, max_key_len;
692 max_key_len = encoding->length - sizeof(*ext);
696 idx = encoding->flags & IW_ENCODE_INDEX;
698 if (idx < 1 || idx > WEP_KEYS)
702 idx = ieee->tx_keyidx;
704 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
705 ext->alg != IW_ENCODE_ALG_WEP)
706 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
709 crypt = ieee->crypt[idx];
710 encoding->flags = idx + 1;
711 memset(ext, 0, sizeof(*ext));
713 if (crypt == NULL || crypt->ops == NULL ) {
714 ext->alg = IW_ENCODE_ALG_NONE;
716 encoding->flags |= IW_ENCODE_DISABLED;
718 if (strcmp(crypt->ops->name, "WEP") == 0 )
719 ext->alg = IW_ENCODE_ALG_WEP;
720 else if (strcmp(crypt->ops->name, "TKIP"))
721 ext->alg = IW_ENCODE_ALG_TKIP;
722 else if (strcmp(crypt->ops->name, "CCMP"))
723 ext->alg = IW_ENCODE_ALG_CCMP;
726 ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
727 encoding->flags |= IW_ENCODE_ENABLED;
729 (ext->alg == IW_ENCODE_ALG_TKIP ||
730 ext->alg == IW_ENCODE_ALG_CCMP))
731 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
737 EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
739 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
740 struct iw_request_info *info,
741 union iwreq_data *wrqu, char *extra)
743 struct iw_mlme *mlme = (struct iw_mlme *) extra;
746 case IW_MLME_DISASSOC:
747 ieee80211_disassociate(ieee);
754 EXPORT_SYMBOL(ieee80211_wx_set_mlme);
756 int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
757 struct iw_request_info *info,
758 struct iw_param *data, char *extra)
760 switch (data->flags & IW_AUTH_INDEX) {
761 case IW_AUTH_WPA_VERSION:
762 /*need to support wpa2 here*/
763 //printk("wpa version:%x\n", data->value);
765 case IW_AUTH_CIPHER_PAIRWISE:
766 case IW_AUTH_CIPHER_GROUP:
767 case IW_AUTH_KEY_MGMT:
769 * * Host AP driver does not use these parameters and allows
770 * * wpa_supplicant to control them internally.
773 case IW_AUTH_TKIP_COUNTERMEASURES:
774 ieee->tkip_countermeasures = data->value;
776 case IW_AUTH_DROP_UNENCRYPTED:
777 ieee->drop_unencrypted = data->value;
780 case IW_AUTH_80211_AUTH_ALG:
781 //printk("======>%s():data->value is %d\n",__func__,data->value);
782 // ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
783 if(data->value & IW_AUTH_ALG_SHARED_KEY){
787 else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
791 else if(data->value & IW_AUTH_ALG_LEAP){
794 //printk("hahahaa:LEAP\n");
798 //printk("open_wep:%d\n", ieee->open_wep);
801 case IW_AUTH_WPA_ENABLED:
802 ieee->wpa_enabled = (data->value)?1:0;
803 //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
806 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
807 ieee->ieee802_1x = data->value;
809 case IW_AUTH_PRIVACY_INVOKED:
810 ieee->privacy_invoked = data->value;
817 EXPORT_SYMBOL(ieee80211_wx_set_auth);
819 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
823 if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
825 // printk("return error out, len:%d\n", len);
834 printk("len:%zu, ie:%d\n", len, ie[1]);
837 buf = kmemdup(ie, len, GFP_KERNEL);
842 ieee->wpa_ie_len = len;
847 ieee->wpa_ie_len = 0;
852 EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);