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"
38 static const char *ieee80211_modes[] = {
39 "?", "a", "b", "ab", "g", "ag", "bg", "abg"
43 #define IN_FEDORACORE_9 1
45 #define IN_FEDORACORE_9 0
48 #define MAX_CUSTOM_LEN 64
49 static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
50 char *start, char *stop,
51 struct ieee80211_network *network,
52 struct iw_request_info *info)
54 char custom[MAX_CUSTOM_LEN];
60 /* First entry *MUST* be the AP MAC address */
62 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
63 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
64 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
65 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
67 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
70 /* Remaining entries will be displayed in the order we provide them */
73 iwe.cmd = SIOCGIWESSID;
75 //YJ,modified,080903,for hidden ap
76 //if (network->flags & NETWORK_EMPTY_ESSID) {
77 if (network->ssid_len == 0) {
78 //YJ,modified,080903,end
79 iwe.u.data.length = sizeof("<hidden>");
80 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
81 start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
83 start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
86 iwe.u.data.length = min(network->ssid_len, (u8)32);
87 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
88 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
90 start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
93 //printk("ESSID: %s\n",network->ssid);
94 /* Add the protocol name */
95 iwe.cmd = SIOCGIWNAME;
96 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
97 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
98 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
100 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
104 iwe.cmd = SIOCGIWMODE;
105 if (network->capability &
106 (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
107 if (network->capability & WLAN_CAPABILITY_BSS)
108 iwe.u.mode = IW_MODE_MASTER;
110 iwe.u.mode = IW_MODE_ADHOC;
112 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
113 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
115 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
119 /* Add frequency/channel */
120 iwe.cmd = SIOCGIWFREQ;
121 /* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
123 iwe.u.freq.m = network->channel;
126 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
127 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
129 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
132 /* Add encryption capability */
133 iwe.cmd = SIOCGIWENCODE;
134 if (network->capability & WLAN_CAPABILITY_PRIVACY)
135 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
137 iwe.u.data.flags = IW_ENCODE_DISABLED;
138 iwe.u.data.length = 0;
139 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
140 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
142 start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
145 /* Add basic and extended rates */
148 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
149 for (i = 0, j = 0; i < network->rates_len; ) {
150 if (j < network->rates_ex_len &&
151 ((network->rates_ex[j] & 0x7F) <
152 (network->rates[i] & 0x7F)))
153 rate = network->rates_ex[j++] & 0x7F;
155 rate = network->rates[i++] & 0x7F;
158 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
159 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
161 for (; j < network->rates_ex_len; j++) {
162 rate = network->rates_ex[j] & 0x7F;
163 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
164 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
169 iwe.cmd = SIOCGIWRATE;
170 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
171 iwe.u.bitrate.value = max_rate * 500000;
172 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
173 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
175 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_PARAM_LEN);
178 iwe.cmd = IWEVCUSTOM;
179 iwe.u.data.length = p - custom;
180 if (iwe.u.data.length)
181 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
182 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
184 start = iwe_stream_add_point(start, stop, &iwe, custom);
187 /* Add quality statistics */
188 /* TODO: Fix these values... */
189 if (network->stats.signal == 0 || network->stats.rssi == 0)
190 printk("========>signal:%d, rssi:%d\n", network->stats.signal, network->stats.rssi);
192 // printk("SIGNAL: %d,RSSI: %d,NOISE: %d\n",network->stats.signal,network->stats.rssi,network->stats.noise);
193 iwe.u.qual.qual = network->stats.signalstrength;
194 iwe.u.qual.level = network->stats.signal;
195 iwe.u.qual.noise = network->stats.noise;
196 iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
197 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
198 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
199 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
200 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
201 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
202 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
203 iwe.u.qual.updated = 7;
204 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
205 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
207 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
210 iwe.cmd = IWEVCUSTOM;
213 iwe.u.data.length = p - custom;
214 if (iwe.u.data.length)
215 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
216 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
218 start = iwe_stream_add_point(start, stop, &iwe, custom);
222 if (ieee->wpa_enabled && network->wpa_ie_len){
223 char buf[MAX_WPA_IE_LEN * 2 + 30];
224 // printk("WPA IE\n");
226 p += sprintf(p, "wpa_ie=");
227 for (i = 0; i < network->wpa_ie_len; i++) {
228 p += sprintf(p, "%02x", network->wpa_ie[i]);
231 memset(&iwe, 0, sizeof(iwe));
232 iwe.cmd = IWEVCUSTOM;
233 iwe.u.data.length = strlen(buf);
234 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
235 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
237 start = iwe_stream_add_point(start, stop, &iwe, buf);
241 if (ieee->wpa_enabled && network->rsn_ie_len){
242 char buf[MAX_WPA_IE_LEN * 2 + 30];
245 p += sprintf(p, "rsn_ie=");
246 for (i = 0; i < network->rsn_ie_len; i++) {
247 p += sprintf(p, "%02x", network->rsn_ie[i]);
252 memset(&iwe, 0, sizeof(iwe));
253 if (network->wpa_ie_len) {
254 // printk("wpa_ie_len:%d\n", network->wpa_ie_len);
255 char buf[MAX_WPA_IE_LEN];
256 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
258 iwe.u.data.length = network->wpa_ie_len;
259 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
260 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
262 start = iwe_stream_add_point(start, stop, &iwe, buf);
266 memset(&iwe, 0, sizeof(iwe));
267 if (network->rsn_ie_len) {
268 // printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
272 for (i=0; i<network->rsn_ie_len; i++);
273 printk("%2x ", network->rsn_ie[i]);
277 char buf[MAX_WPA_IE_LEN];
278 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
280 iwe.u.data.length = network->rsn_ie_len;
281 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
282 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
284 start = iwe_stream_add_point(start, stop, &iwe, buf);
290 /* Add EXTRA: Age to display seconds since last beacon/probe response
291 * for given network. */
292 iwe.cmd = IWEVCUSTOM;
294 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
295 " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
296 iwe.u.data.length = p - custom;
297 if (iwe.u.data.length)
298 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
299 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
301 start = iwe_stream_add_point(start, stop, &iwe, custom);
307 int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
308 struct iw_request_info *info,
309 union iwreq_data *wrqu, char *extra)
311 struct ieee80211_network *network;
315 char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
316 //char *stop = ev + IW_SCAN_MAX_DATA;
319 IEEE80211_DEBUG_WX("Getting scan\n");
321 spin_lock_irqsave(&ieee->lock, flags);
323 if(!ieee->bHwRadioOff)
325 list_for_each_entry(network, &ieee->network_list, list) {
333 if (ieee->scan_age == 0 ||
334 time_after(network->last_scanned + ieee->scan_age, jiffies))
336 ev = rtl818x_translate_scan(ieee, ev, stop, network, info);
339 IEEE80211_DEBUG_SCAN(
340 "Not showing network '%s ("
341 MAC_FMT ")' due to age (%lums).\n",
342 escape_essid(network->ssid,
344 MAC_ARG(network->bssid),
345 (jiffies - network->last_scanned) / (HZ / 100));
348 spin_unlock_irqrestore(&ieee->lock, flags);
350 wrqu->data.length = ev - extra;
351 wrqu->data.flags = 0;
352 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
357 int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
358 struct iw_request_info *info,
359 union iwreq_data *wrqu, char *keybuf)
361 struct iw_point *erq = &(wrqu->encoding);
362 struct net_device *dev = ieee->dev;
363 struct ieee80211_security sec = {
366 int i, key, key_provided, len;
367 struct ieee80211_crypt_data **crypt;
369 IEEE80211_DEBUG_WX("SET_ENCODE\n");
371 key = erq->flags & IW_ENCODE_INDEX;
379 key = ieee->tx_keyidx;
382 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
383 "provided" : "default");
385 crypt = &ieee->crypt[key];
387 if (erq->flags & IW_ENCODE_DISABLED) {
388 if (key_provided && *crypt) {
389 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
391 ieee80211_crypt_delayed_deinit(ieee, crypt);
393 IEEE80211_DEBUG_WX("Disabling encryption.\n");
395 /* Check all the keys to see if any are still configured,
396 * and if no key index was provided, de-init them all */
397 for (i = 0; i < WEP_KEYS; i++) {
398 if (ieee->crypt[i] != NULL) {
401 ieee80211_crypt_delayed_deinit(
402 ieee, &ieee->crypt[i]);
408 sec.level = SEC_LEVEL_0;
409 sec.flags |= SEC_ENABLED | SEC_LEVEL;
418 sec.flags |= SEC_ENABLED;
420 if (*crypt != NULL && (*crypt)->ops != NULL &&
421 strcmp((*crypt)->ops->name, "WEP") != 0) {
422 /* changing to use WEP; deinit previously used algorithm
424 ieee80211_crypt_delayed_deinit(ieee, crypt);
427 if (*crypt == NULL) {
428 struct ieee80211_crypt_data *new_crypt;
430 /* take WEP into use */
431 new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
433 if (new_crypt == NULL)
435 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
436 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
437 if (!new_crypt->ops) {
438 request_module("ieee80211_crypt_wep");
439 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
442 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
443 new_crypt->priv = new_crypt->ops->init(key);
445 if (!new_crypt->ops || !new_crypt->priv) {
449 printk(KERN_WARNING "%s: could not initialize WEP: "
450 "load module ieee80211_crypt_wep\n",
457 /* If a new key was provided, set it up */
458 if (erq->length > 0) {
459 len = erq->length <= 5 ? 5 : 13;
460 memcpy(sec.keys[key], keybuf, erq->length);
461 if (len > erq->length)
462 memset(sec.keys[key] + erq->length, 0,
464 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
465 key, escape_essid(sec.keys[key], len),
467 sec.key_sizes[key] = len;
468 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
470 sec.flags |= (1 << key);
471 /* This ensures a key will be activated if no key is
473 if (key == sec.active_key)
474 sec.flags |= SEC_ACTIVE_KEY;
475 ieee->tx_keyidx = key;//by wb 080312
477 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
478 NULL, (*crypt)->priv);
480 /* Set a default key of all 0 */
481 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
483 memset(sec.keys[key], 0, 13);
484 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
486 sec.key_sizes[key] = 13;
487 sec.flags |= (1 << key);
490 /* No key data - just set the default TX key index */
493 "Setting key %d to default Tx key.\n", key);
494 ieee->tx_keyidx = key;
495 sec.active_key = key;
496 sec.flags |= SEC_ACTIVE_KEY;
501 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
502 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
503 sec.flags |= SEC_AUTH_MODE;
504 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
505 "OPEN" : "SHARED KEY");
507 /* For now we just support WEP, so only set that security level...
508 * TODO: When WPA is added this is one place that needs to change */
509 sec.flags |= SEC_LEVEL;
510 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
512 if (ieee->set_security)
513 ieee->set_security(dev, &sec);
515 /* Do not reset port if card is in Managed mode since resetting will
516 * generate new IEEE 802.11 authentication which may end up in looping
517 * with IEEE 802.1X. If your hardware requires a reset after WEP
518 * configuration (for example... Prism2), implement the reset_port in
519 * the callbacks structures used to initialize the 802.11 stack. */
520 if (ieee->reset_on_keychange &&
521 ieee->iw_mode != IW_MODE_INFRA &&
522 ieee->reset_port && ieee->reset_port(dev)) {
523 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
529 int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
530 struct iw_request_info *info,
531 union iwreq_data *wrqu, char *keybuf)
533 struct iw_point *erq = &(wrqu->encoding);
535 struct ieee80211_crypt_data *crypt;
537 IEEE80211_DEBUG_WX("GET_ENCODE\n");
539 if(ieee->iw_mode == IW_MODE_MONITOR)
542 key = erq->flags & IW_ENCODE_INDEX;
548 key = ieee->tx_keyidx;
550 crypt = ieee->crypt[key];
551 erq->flags = key + 1;
553 if (crypt == NULL || crypt->ops == NULL) {
555 erq->flags |= IW_ENCODE_DISABLED;
559 if (strcmp(crypt->ops->name, "WEP") != 0) {
560 /* only WEP is supported with wireless extensions, so just
561 * report that encryption is used */
563 erq->flags |= IW_ENCODE_ENABLED;
567 len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
568 erq->length = (len >= 0 ? len : 0);
570 erq->flags |= IW_ENCODE_ENABLED;
573 erq->flags |= IW_ENCODE_OPEN;
575 erq->flags |= IW_ENCODE_RESTRICTED;
580 int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
581 struct iw_request_info *info,
582 union iwreq_data *wrqu, char *extra)
584 struct net_device *dev = ieee->dev;
585 struct iw_point *encoding = &wrqu->encoding;
586 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
589 const char *alg, *module;
590 struct ieee80211_crypto_ops *ops;
591 struct ieee80211_crypt_data **crypt;
593 struct ieee80211_security sec = {
596 //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
597 idx = encoding->flags & IW_ENCODE_INDEX;
599 if (idx < 1 || idx > WEP_KEYS)
603 idx = ieee->tx_keyidx;
605 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
606 crypt = &ieee->crypt[idx];
609 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
610 //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
611 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
613 if (ieee->iw_mode == IW_MODE_INFRA)
614 crypt = &ieee->crypt[idx];
619 sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
620 if ((encoding->flags & IW_ENCODE_DISABLED) ||
621 ext->alg == IW_ENCODE_ALG_NONE) {
623 ieee80211_crypt_delayed_deinit(ieee, crypt);
625 for (i = 0; i < WEP_KEYS; i++)
626 if (ieee->crypt[i] != NULL)
632 sec.level = SEC_LEVEL_0;
633 sec.flags |= SEC_LEVEL;
635 //printk("disabled: flag:%x\n", encoding->flags);
642 if (group_key ? !ieee->host_mc_decrypt :
643 !(ieee->host_encrypt || ieee->host_decrypt ||
644 ieee->host_encrypt_msdu))
645 goto skip_host_crypt;
648 case IW_ENCODE_ALG_WEP:
650 module = "ieee80211_crypt_wep";
652 case IW_ENCODE_ALG_TKIP:
654 module = "ieee80211_crypt_tkip";
656 case IW_ENCODE_ALG_CCMP:
658 module = "ieee80211_crypt_ccmp";
661 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
662 dev->name, ext->alg);
666 // printk("8-09-08-9=====>%s, alg name:%s\n",__func__, alg);
668 ops = ieee80211_get_crypto_ops(alg);
670 request_module(module);
671 ops = ieee80211_get_crypto_ops(alg);
674 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
675 dev->name, ext->alg);
676 printk("========>unknown crypto alg %d\n", ext->alg);
681 if (*crypt == NULL || (*crypt)->ops != ops) {
682 struct ieee80211_crypt_data *new_crypt;
684 ieee80211_crypt_delayed_deinit(ieee, crypt);
686 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
687 if (new_crypt == NULL) {
691 new_crypt->ops = ops;
692 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
693 new_crypt->priv = new_crypt->ops->init(idx);
694 if (new_crypt->priv == NULL) {
703 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
704 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
705 (*crypt)->priv) < 0) {
706 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
707 printk("key setting failed\n");
713 //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
714 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
715 ieee->tx_keyidx = idx;
716 sec.active_key = idx;
717 sec.flags |= SEC_ACTIVE_KEY;
720 if (ext->alg != IW_ENCODE_ALG_NONE) {
721 memcpy(sec.keys[idx], ext->key, ext->key_len);
722 sec.key_sizes[idx] = ext->key_len;
723 sec.flags |= (1 << idx);
724 if (ext->alg == IW_ENCODE_ALG_WEP) {
725 // sec.encode_alg[idx] = SEC_ALG_WEP;
726 sec.flags |= SEC_LEVEL;
727 sec.level = SEC_LEVEL_1;
728 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
729 // sec.encode_alg[idx] = SEC_ALG_TKIP;
730 sec.flags |= SEC_LEVEL;
731 sec.level = SEC_LEVEL_2;
732 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
733 // sec.encode_alg[idx] = SEC_ALG_CCMP;
734 sec.flags |= SEC_LEVEL;
735 sec.level = SEC_LEVEL_3;
737 /* Don't set sec level for group keys. */
739 sec.flags &= ~SEC_LEVEL;
743 if (ieee->set_security)
744 ieee->set_security(ieee->dev, &sec);
746 if (ieee->reset_on_keychange &&
747 ieee->iw_mode != IW_MODE_INFRA &&
748 ieee->reset_port && ieee->reset_port(dev)) {
749 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
755 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
756 struct iw_request_info *info,
757 union iwreq_data *wrqu, char *extra)
759 struct iw_mlme *mlme = (struct iw_mlme *) extra;
760 // printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __func__, mlme->cmd);
764 case IW_MLME_DISASSOC:
765 // printk("disassoc now\n");
766 ieee80211_disassociate(ieee);
775 int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
776 struct iw_request_info *info,
777 struct iw_param *data, char *extra)
780 struct ieee80211_security sec = {
781 .flags = SEC_AUTH_MODE,
784 //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value);
785 switch (data->flags & IW_AUTH_INDEX) {
786 case IW_AUTH_WPA_VERSION:
787 /*need to support wpa2 here*/
788 //printk("wpa version:%x\n", data->value);
790 case IW_AUTH_CIPHER_PAIRWISE:
791 case IW_AUTH_CIPHER_GROUP:
792 case IW_AUTH_KEY_MGMT:
794 * * Host AP driver does not use these parameters and allows
795 * * wpa_supplicant to control them internally.
798 case IW_AUTH_TKIP_COUNTERMEASURES:
799 ieee->tkip_countermeasures = data->value;
801 case IW_AUTH_DROP_UNENCRYPTED:
802 ieee->drop_unencrypted = data->value;
805 case IW_AUTH_80211_AUTH_ALG:
806 ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
807 //printk("open_wep:%d\n", ieee->open_wep);
811 case IW_AUTH_WPA_ENABLED:
812 ieee->wpa_enabled = (data->value)?1:0;
813 //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
817 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
818 ieee->ieee802_1x = data->value;
820 case IW_AUTH_PRIVACY_INVOKED:
821 ieee->privacy_invoked = data->value;
830 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
833 printk("====>%s()\n", __func__);
836 for (i=0; i<len; i++)
837 printk("%2x ", ie[i]&0xff);
843 if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
845 printk("return error out, len:%d\n", len);
852 printk("len:%d, ie:%d\n", len, ie[1]);
855 buf = kmalloc(len, GFP_KERNEL);
858 memcpy(buf, ie, len);
861 ieee->wpa_ie_len = len;
867 ieee->wpa_ie_len = 0;
869 // printk("<=====out %s()\n", __func__);
877 EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
878 EXPORT_SYMBOL(ieee80211_wx_set_mlme);
879 EXPORT_SYMBOL(ieee80211_wx_set_auth);
880 EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
881 EXPORT_SYMBOL(ieee80211_wx_get_scan);
882 EXPORT_SYMBOL(ieee80211_wx_set_encode);
883 EXPORT_SYMBOL(ieee80211_wx_get_encode);