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 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<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); 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);
197 #if (WIRELESS_EXT < 18)
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);
228 memset(&iwe, 0, sizeof(iwe));
229 if (network->wpa_ie_len)
231 char buf[MAX_WPA_IE_LEN];
232 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
234 iwe.u.data.length = network->wpa_ie_len;
235 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
237 memset(&iwe, 0, sizeof(iwe));
238 if (network->rsn_ie_len)
240 char buf[MAX_WPA_IE_LEN];
241 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
243 iwe.u.data.length = network->rsn_ie_len;
244 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
249 /* Add EXTRA: Age to display seconds since last beacon/probe response
250 * for given network. */
251 iwe.cmd = IWEVCUSTOM;
253 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
254 " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
255 iwe.u.data.length = p - custom;
256 if (iwe.u.data.length)
257 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
262 int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
263 struct iw_request_info *info,
264 union iwreq_data *wrqu, char *extra)
266 struct ieee80211_network *network;
270 // char *stop = ev + IW_SCAN_MAX_DATA;
271 char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
272 //char *stop = ev + IW_SCAN_MAX_DATA;
275 IEEE80211_DEBUG_WX("Getting scan\n");
277 spin_lock_irqsave(&ieee->lock, flags);
279 list_for_each_entry(network, &ieee->network_list, list) {
286 if (ieee->scan_age == 0 ||
287 time_after(network->last_scanned + ieee->scan_age, jiffies))
288 ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
290 IEEE80211_DEBUG_SCAN(
291 "Not showing network '%s ("
292 "%pM)' due to age (%lums).\n",
293 escape_essid(network->ssid,
296 (jiffies - network->last_scanned) / (HZ / 100));
299 spin_unlock_irqrestore(&ieee->lock, flags);
301 wrqu->data.length = ev - extra;
302 wrqu->data.flags = 0;
304 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
309 int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
310 struct iw_request_info *info,
311 union iwreq_data *wrqu, char *keybuf)
313 struct iw_point *erq = &(wrqu->encoding);
314 struct net_device *dev = ieee->dev;
315 struct ieee80211_security sec = {
318 int i, key, key_provided, len;
319 struct ieee80211_crypt_data **crypt;
321 IEEE80211_DEBUG_WX("SET_ENCODE\n");
323 key = erq->flags & IW_ENCODE_INDEX;
331 key = ieee->tx_keyidx;
334 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
335 "provided" : "default");
336 crypt = &ieee->crypt[key];
338 if (erq->flags & IW_ENCODE_DISABLED) {
339 if (key_provided && *crypt) {
340 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
342 ieee80211_crypt_delayed_deinit(ieee, crypt);
344 IEEE80211_DEBUG_WX("Disabling encryption.\n");
346 /* Check all the keys to see if any are still configured,
347 * and if no key index was provided, de-init them all */
348 for (i = 0; i < WEP_KEYS; i++) {
349 if (ieee->crypt[i] != NULL) {
352 ieee80211_crypt_delayed_deinit(
353 ieee, &ieee->crypt[i]);
359 sec.level = SEC_LEVEL_0;
360 sec.flags |= SEC_ENABLED | SEC_LEVEL;
369 sec.flags |= SEC_ENABLED;
371 if (*crypt != NULL && (*crypt)->ops != NULL &&
372 strcmp((*crypt)->ops->name, "WEP") != 0) {
373 /* changing to use WEP; deinit previously used algorithm
375 ieee80211_crypt_delayed_deinit(ieee, crypt);
378 if (*crypt == NULL) {
379 struct ieee80211_crypt_data *new_crypt;
381 /* take WEP into use */
382 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
384 if (new_crypt == NULL)
386 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
387 if (!new_crypt->ops) {
388 request_module("ieee80211_crypt_wep");
389 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
391 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
392 new_crypt->priv = new_crypt->ops->init(key);
394 if (!new_crypt->ops || !new_crypt->priv) {
398 printk(KERN_WARNING "%s: could not initialize WEP: "
399 "load module ieee80211_crypt_wep\n",
406 /* If a new key was provided, set it up */
407 if (erq->length > 0) {
408 len = erq->length <= 5 ? 5 : 13;
409 memcpy(sec.keys[key], keybuf, erq->length);
410 if (len > erq->length)
411 memset(sec.keys[key] + erq->length, 0,
413 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
414 key, escape_essid(sec.keys[key], len),
416 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;
424 ieee->tx_keyidx = 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 printk("Setting key %d to all zero.\n",
434 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
436 memset(sec.keys[key], 0, 13);
437 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
439 sec.key_sizes[key] = 13;
440 sec.flags |= (1 << key);
443 /* No key data - just set the default TX key index */
446 "Setting key %d to default Tx key.\n", key);
447 ieee->tx_keyidx = key;
448 sec.active_key = key;
449 sec.flags |= SEC_ACTIVE_KEY;
454 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
455 ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
456 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
457 sec.flags |= SEC_AUTH_MODE;
458 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
459 "OPEN" : "SHARED KEY");
461 /* For now we just support WEP, so only set that security level...
462 * TODO: When WPA is added this is one place that needs to change */
463 sec.flags |= SEC_LEVEL;
464 sec.level = SEC_LEVEL_1; /* 40 and 104 bit 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 ieee80211_crypt_data *crypt;
491 IEEE80211_DEBUG_WX("GET_ENCODE\n");
493 if(ieee->iw_mode == IW_MODE_MONITOR)
496 key = erq->flags & IW_ENCODE_INDEX;
502 key = ieee->tx_keyidx;
504 crypt = ieee->crypt[key];
505 erq->flags = key + 1;
507 if (crypt == NULL || crypt->ops == NULL) {
509 erq->flags |= IW_ENCODE_DISABLED;
512 len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
513 erq->length = (len >= 0 ? len : 0);
515 erq->flags |= IW_ENCODE_ENABLED;
518 erq->flags |= IW_ENCODE_OPEN;
520 erq->flags |= IW_ENCODE_RESTRICTED;
524 #if (WIRELESS_EXT >= 18)
525 int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
526 struct iw_request_info *info,
527 union iwreq_data *wrqu, char *extra)
530 struct net_device *dev = ieee->dev;
531 struct iw_point *encoding = &wrqu->encoding;
532 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
535 const char *alg, *module;
536 struct ieee80211_crypto_ops *ops;
537 struct ieee80211_crypt_data **crypt;
539 struct ieee80211_security sec = {
542 //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
543 idx = encoding->flags & IW_ENCODE_INDEX;
545 if (idx < 1 || idx > WEP_KEYS)
549 idx = ieee->tx_keyidx;
551 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
553 crypt = &ieee->crypt[idx];
557 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
558 //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
559 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
561 if (ieee->iw_mode == IW_MODE_INFRA)
563 crypt = &ieee->crypt[idx];
569 sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
570 if ((encoding->flags & IW_ENCODE_DISABLED) ||
571 ext->alg == IW_ENCODE_ALG_NONE) {
573 ieee80211_crypt_delayed_deinit(ieee, crypt);
575 for (i = 0; i < WEP_KEYS; i++)
577 if (ieee->crypt[i] != NULL)
584 sec.level = SEC_LEVEL_0;
585 sec.flags |= SEC_LEVEL;
587 //printk("disabled: flag:%x\n", encoding->flags);
594 case IW_ENCODE_ALG_WEP:
596 module = "ieee80211_crypt_wep";
598 case IW_ENCODE_ALG_TKIP:
600 module = "ieee80211_crypt_tkip";
602 case IW_ENCODE_ALG_CCMP:
604 module = "ieee80211_crypt_ccmp";
607 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
608 dev->name, ext->alg);
612 printk("alg name:%s\n",alg);
614 ops = ieee80211_get_crypto_ops(alg);
616 request_module(module);
617 ops = ieee80211_get_crypto_ops(alg);
620 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
621 dev->name, ext->alg);
622 printk("========>unknown crypto alg %d\n", ext->alg);
627 if (*crypt == NULL || (*crypt)->ops != ops) {
628 struct ieee80211_crypt_data *new_crypt;
630 ieee80211_crypt_delayed_deinit(ieee, crypt);
632 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
633 if (new_crypt == NULL) {
637 new_crypt->ops = ops;
638 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
639 new_crypt->priv = new_crypt->ops->init(idx);
640 if (new_crypt->priv == NULL) {
649 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
650 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
651 (*crypt)->priv) < 0) {
652 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
653 printk("key setting failed\n");
658 //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
659 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
660 ieee->tx_keyidx = idx;
661 sec.active_key = idx;
662 sec.flags |= SEC_ACTIVE_KEY;
665 if (ext->alg != IW_ENCODE_ALG_NONE) {
666 //memcpy(sec.keys[idx], ext->key, ext->key_len);
667 sec.key_sizes[idx] = ext->key_len;
668 sec.flags |= (1 << idx);
669 if (ext->alg == IW_ENCODE_ALG_WEP) {
670 // sec.encode_alg[idx] = SEC_ALG_WEP;
671 sec.flags |= SEC_LEVEL;
672 sec.level = SEC_LEVEL_1;
673 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
674 // sec.encode_alg[idx] = SEC_ALG_TKIP;
675 sec.flags |= SEC_LEVEL;
676 sec.level = SEC_LEVEL_2;
677 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
678 // sec.encode_alg[idx] = SEC_ALG_CCMP;
679 sec.flags |= SEC_LEVEL;
680 sec.level = SEC_LEVEL_3;
682 /* Don't set sec level for group keys. */
684 sec.flags &= ~SEC_LEVEL;
687 if (ieee->set_security)
688 ieee->set_security(ieee->dev, &sec);
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);
699 int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
700 struct iw_request_info *info,
701 union iwreq_data *wrqu, char *extra)
703 struct iw_point *encoding = &wrqu->encoding;
704 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
705 struct ieee80211_crypt_data *crypt;
706 int idx, max_key_len;
708 max_key_len = encoding->length - sizeof(*ext);
712 idx = encoding->flags & IW_ENCODE_INDEX;
714 if (idx < 1 || idx > WEP_KEYS)
718 idx = ieee->tx_keyidx;
720 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
721 ext->alg != IW_ENCODE_ALG_WEP)
722 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
725 crypt = ieee->crypt[idx];
726 encoding->flags = idx + 1;
727 memset(ext, 0, sizeof(*ext));
729 if (crypt == NULL || crypt->ops == NULL ) {
730 ext->alg = IW_ENCODE_ALG_NONE;
732 encoding->flags |= IW_ENCODE_DISABLED;
734 if (strcmp(crypt->ops->name, "WEP") == 0 )
735 ext->alg = IW_ENCODE_ALG_WEP;
736 else if (strcmp(crypt->ops->name, "TKIP"))
737 ext->alg = IW_ENCODE_ALG_TKIP;
738 else if (strcmp(crypt->ops->name, "CCMP"))
739 ext->alg = IW_ENCODE_ALG_CCMP;
742 ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
743 encoding->flags |= IW_ENCODE_ENABLED;
745 (ext->alg == IW_ENCODE_ALG_TKIP ||
746 ext->alg == IW_ENCODE_ALG_CCMP))
747 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
754 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
755 struct iw_request_info *info,
756 union iwreq_data *wrqu, char *extra)
758 struct iw_mlme *mlme = (struct iw_mlme *) extra;
761 case IW_MLME_DISASSOC:
762 ieee80211_disassociate(ieee);
770 int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
771 struct iw_request_info *info,
772 struct iw_param *data, char *extra)
774 switch (data->flags & IW_AUTH_INDEX) {
775 case IW_AUTH_WPA_VERSION:
776 /*need to support wpa2 here*/
777 //printk("wpa version:%x\n", data->value);
779 case IW_AUTH_CIPHER_PAIRWISE:
780 case IW_AUTH_CIPHER_GROUP:
781 case IW_AUTH_KEY_MGMT:
783 * * Host AP driver does not use these parameters and allows
784 * * wpa_supplicant to control them internally.
787 case IW_AUTH_TKIP_COUNTERMEASURES:
788 ieee->tkip_countermeasures = data->value;
790 case IW_AUTH_DROP_UNENCRYPTED:
791 ieee->drop_unencrypted = data->value;
794 case IW_AUTH_80211_AUTH_ALG:
795 //printk("======>%s():data->value is %d\n",__FUNCTION__,data->value);
796 // ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
797 if(data->value & IW_AUTH_ALG_SHARED_KEY){
801 else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
805 else if(data->value & IW_AUTH_ALG_LEAP){
808 //printk("hahahaa:LEAP\n");
812 //printk("open_wep:%d\n", ieee->open_wep);
815 case IW_AUTH_WPA_ENABLED:
816 ieee->wpa_enabled = (data->value)?1:0;
817 //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
820 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
821 ieee->ieee802_1x = data->value;
823 case IW_AUTH_PRIVACY_INVOKED:
824 ieee->privacy_invoked = data->value;
832 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
836 if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
838 // printk("return error out, len:%d\n", len);
847 printk("len:%zu, ie:%d\n", len, ie[1]);
850 buf = kmalloc(len, GFP_KERNEL);
853 memcpy(buf, ie, len);
856 ieee->wpa_ie_len = len;
862 ieee->wpa_ie_len = 0;
868 EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
869 #if (WIRELESS_EXT >= 18)
870 EXPORT_SYMBOL(ieee80211_wx_set_mlme);
871 EXPORT_SYMBOL(ieee80211_wx_set_auth);
872 EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
873 EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
875 EXPORT_SYMBOL(ieee80211_wx_get_scan);
876 EXPORT_SYMBOL(ieee80211_wx_set_encode);
877 EXPORT_SYMBOL(ieee80211_wx_get_encode);