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>
42 static struct modes_unit rtllib_modes[] = {
51 #define MAX_CUSTOM_LEN 64
52 static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
53 char *start, char *stop,
54 struct rtllib_network *network,
55 struct iw_request_info *info)
57 char custom[MAX_CUSTOM_LEN];
58 char proto_name[IFNAMSIZ];
59 char *pname = proto_name;
64 static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
66 /* First entry *MUST* be the AP MAC address */
68 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
69 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
70 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
71 /* Remaining entries will be displayed in the order we provide them */
74 iwe.cmd = SIOCGIWESSID;
76 if (network->ssid_len > 0){
77 iwe.u.data.length = min(network->ssid_len, (u8)32);
78 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, network->ssid);
79 }else if (network->hidden_ssid_len == 0){
80 iwe.u.data.length = sizeof("<hidden>");
81 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, "<hidden>");
83 iwe.u.data.length = min(network->hidden_ssid_len, (u8)32);
84 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, network->hidden_ssid);
86 /* Add the protocol name */
87 iwe.cmd = SIOCGIWNAME;
88 for (i=0; i<(sizeof(rtllib_modes)/sizeof(rtllib_modes[0])); i++) {
89 if (network->mode&(1<<i)) {
90 sprintf(pname,rtllib_modes[i].mode_string,rtllib_modes[i].mode_size);
91 pname +=rtllib_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_ESS | WLAN_CAPABILITY_IBSS)) {
101 if (network->capability & WLAN_CAPABILITY_ESS)
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 = rtllib_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);
117 /* Add encryption capability */
118 iwe.cmd = SIOCGIWENCODE;
119 if (network->capability & WLAN_CAPABILITY_PRIVACY)
120 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
122 iwe.u.data.flags = IW_ENCODE_DISABLED;
123 iwe.u.data.length = 0;
124 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, network->ssid);
125 /* Add basic and extended rates */
128 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
129 for (i = 0, j = 0; i < network->rates_len; ) {
130 if (j < network->rates_ex_len &&
131 ((network->rates_ex[j] & 0x7F) <
132 (network->rates[i] & 0x7F)))
133 rate = network->rates_ex[j++] & 0x7F;
135 rate = network->rates[i++] & 0x7F;
138 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
139 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
141 for (; j < network->rates_ex_len; j++) {
142 rate = network->rates_ex[j] & 0x7F;
143 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
144 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
149 if (network->mode >= IEEE_N_24G)
151 PHT_CAPABILITY_ELE ht_cap = NULL;
152 bool is40M = false, isShortGI = false;
154 if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
155 ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
157 ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
158 is40M = (ht_cap->ChlWidth)?1:0;
159 isShortGI = (ht_cap->ChlWidth)?
160 ((ht_cap->ShortGI40Mhz)?1:0):
161 ((ht_cap->ShortGI20Mhz)?1:0);
163 max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
164 rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f];
168 iwe.cmd = SIOCGIWRATE;
169 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
170 iwe.u.bitrate.value = max_rate * 500000;
171 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
173 iwe.cmd = IWEVCUSTOM;
174 iwe.u.data.length = p - custom;
175 if (iwe.u.data.length)
176 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, custom);
177 /* Add quality statistics */
178 /* TODO: Fix these values... */
180 iwe.u.qual.qual = network->stats.signal;
181 iwe.u.qual.level = network->stats.rssi;
182 iwe.u.qual.noise = network->stats.noise;
183 iwe.u.qual.updated = network->stats.mask & RTLLIB_STATMASK_WEMASK;
184 if (!(network->stats.mask & RTLLIB_STATMASK_RSSI))
185 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
186 if (!(network->stats.mask & RTLLIB_STATMASK_NOISE))
187 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
188 if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL))
189 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
190 iwe.u.qual.updated = 7;
191 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
193 iwe.cmd = IWEVCUSTOM;
195 iwe.u.data.length = p - custom;
196 if (iwe.u.data.length)
197 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, custom);
199 memset(&iwe, 0, sizeof(iwe));
200 if (network->wpa_ie_len)
202 char buf[MAX_WPA_IE_LEN];
203 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
205 iwe.u.data.length = network->wpa_ie_len;
206 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
208 memset(&iwe, 0, sizeof(iwe));
209 if (network->rsn_ie_len)
211 char buf[MAX_WPA_IE_LEN];
212 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
214 iwe.u.data.length = network->rsn_ie_len;
215 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
218 #ifndef CUSTOMER_ID_INTEL_CMPC
219 /* add info for WZC */
220 memset(&iwe, 0, sizeof(iwe));
221 if (network->wzc_ie_len)
223 char buf[MAX_WZC_IE_LEN];
224 memcpy(buf, network->wzc_ie, network->wzc_ie_len);
226 iwe.u.data.length = network->wzc_ie_len;
227 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
231 /* Add EXTRA: Age to display seconds since last beacon/probe response
232 * for given network. */
233 iwe.cmd = IWEVCUSTOM;
235 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
236 " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
237 iwe.u.data.length = p - custom;
238 if (iwe.u.data.length)
239 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, custom);
244 int rtllib_wx_get_scan(struct rtllib_device *ieee,
245 struct iw_request_info *info,
246 union iwreq_data *wrqu, char *extra)
248 struct rtllib_network *network;
252 char *stop = ev + wrqu->data.length;
255 RTLLIB_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);
271 "Not showing network '%s ("
272 MAC_FMT ")' due to age (%lums).\n",
273 escape_essid(network->ssid,
275 MAC_ARG(network->bssid),
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 RTLLIB_DEBUG_WX("exit: %d networks returned.\n", i);
289 int rtllib_wx_set_encode(struct rtllib_device *ieee,
290 struct iw_request_info *info,
291 union iwreq_data *wrqu, char *keybuf)
293 struct iw_point *erq = &(wrqu->encoding);
294 struct net_device *dev = ieee->dev;
295 struct rtllib_security sec = {
298 int i, key, key_provided, len;
299 struct rtllib_crypt_data **crypt;
301 RTLLIB_DEBUG_WX("SET_ENCODE\n");
303 key = erq->flags & IW_ENCODE_INDEX;
311 key = ieee->tx_keyidx;
314 RTLLIB_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
315 "provided" : "default");
316 crypt = &ieee->crypt[key];
317 if (erq->flags & IW_ENCODE_DISABLED) {
318 if (key_provided && *crypt) {
319 RTLLIB_DEBUG_WX("Disabling encryption on key %d.\n",
321 rtllib_crypt_delayed_deinit(ieee, crypt);
323 RTLLIB_DEBUG_WX("Disabling encryption.\n");
325 /* Check all the keys to see if any are still configured,
326 * and if no key index was provided, de-init them all */
327 for (i = 0; i < WEP_KEYS; i++) {
328 if (ieee->crypt[i] != NULL) {
331 rtllib_crypt_delayed_deinit(ieee, &ieee->crypt[i]);
337 sec.level = SEC_LEVEL_0;
338 sec.flags |= SEC_ENABLED | SEC_LEVEL;
347 sec.flags |= SEC_ENABLED;
349 if (*crypt != NULL && (*crypt)->ops != NULL &&
350 strcmp((*crypt)->ops->name, "WEP") != 0) {
351 /* changing to use WEP; deinit previously used algorithm
353 rtllib_crypt_delayed_deinit(ieee, crypt);
356 if (*crypt == NULL) {
357 struct rtllib_crypt_data *new_crypt;
359 /* take WEP into use */
360 new_crypt = kmalloc(sizeof(struct rtllib_crypt_data),
362 if (new_crypt == NULL)
364 memset(new_crypt, 0, sizeof(struct rtllib_crypt_data));
365 new_crypt->ops = rtllib_get_crypto_ops("WEP");
366 if (!new_crypt->ops) {
367 request_module("rtllib_crypt_wep");
368 new_crypt->ops = rtllib_get_crypto_ops("WEP");
372 new_crypt->priv = new_crypt->ops->init(key);
374 if (!new_crypt->ops || !new_crypt->priv) {
378 printk(KERN_WARNING "%s: could not initialize WEP: "
379 "load module rtllib_crypt_wep\n",
386 /* If a new key was provided, set it up */
387 if (erq->length > 0) {
388 len = erq->length <= 5 ? 5 : 13;
389 memcpy(sec.keys[key], keybuf, erq->length);
390 if (len > erq->length)
391 memset(sec.keys[key] + erq->length, 0,
393 RTLLIB_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
394 key, escape_essid(sec.keys[key], len),
396 sec.key_sizes[key] = len;
397 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
399 sec.flags |= (1 << key);
400 /* This ensures a key will be activated if no key is
402 if (key == sec.active_key)
403 sec.flags |= SEC_ACTIVE_KEY;
404 ieee->tx_keyidx = key;
407 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
408 NULL, (*crypt)->priv);
410 /* Set a default key of all 0 */
411 printk("Setting key %d to all zero.\n",
414 RTLLIB_DEBUG_WX("Setting key %d to all zero.\n",
416 memset(sec.keys[key], 0, 13);
417 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
419 sec.key_sizes[key] = 13;
420 sec.flags |= (1 << key);
423 /* No key data - just set the default TX key index */
426 "Setting key %d to default Tx key.\n", key);
427 ieee->tx_keyidx = key;
428 sec.active_key = key;
429 sec.flags |= SEC_ACTIVE_KEY;
433 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
434 ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
435 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
436 sec.flags |= SEC_AUTH_MODE;
437 RTLLIB_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
438 "OPEN" : "SHARED KEY");
440 /* For now we just support WEP, so only set that security level...
441 * TODO: When WPA is added this is one place that needs to change */
442 sec.flags |= SEC_LEVEL;
443 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
445 if (ieee->set_security)
446 ieee->set_security(dev, &sec);
448 /* Do not reset port if card is in Managed mode since resetting will
449 * generate new IEEE 802.11 authentication which may end up in looping
450 * with IEEE 802.1X. If your hardware requires a reset after WEP
451 * configuration (for example... Prism2), implement the reset_port in
452 * the callbacks structures used to initialize the 802.11 stack. */
453 if (ieee->reset_on_keychange &&
454 ieee->iw_mode != IW_MODE_INFRA &&
455 ieee->reset_port && ieee->reset_port(dev)) {
456 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
462 int rtllib_wx_get_encode(struct rtllib_device *ieee,
463 struct iw_request_info *info,
464 union iwreq_data *wrqu, char *keybuf)
466 struct iw_point *erq = &(wrqu->encoding);
468 struct rtllib_crypt_data *crypt;
470 RTLLIB_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];
485 erq->flags = key + 1;
487 if (crypt == NULL || crypt->ops == NULL) {
489 erq->flags |= IW_ENCODE_DISABLED;
492 len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
493 erq->length = (len >= 0 ? len : 0);
495 erq->flags |= IW_ENCODE_ENABLED;
498 erq->flags |= IW_ENCODE_OPEN;
500 erq->flags |= IW_ENCODE_RESTRICTED;
505 int rtllib_wx_set_encode_ext(struct rtllib_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 rtllib_crypto_ops *ops;
517 struct rtllib_crypt_data **crypt;
519 struct rtllib_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) {
531 crypt = &ieee->crypt[idx];
534 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
535 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
537 if (ieee->iw_mode == IW_MODE_INFRA)
538 crypt = &ieee->crypt[idx];
543 sec.flags |= SEC_ENABLED;
544 if ((encoding->flags & IW_ENCODE_DISABLED) ||
545 ext->alg == IW_ENCODE_ALG_NONE) {
547 rtllib_crypt_delayed_deinit(ieee, crypt);
549 for (i = 0; i < WEP_KEYS; i++) {
550 if (ieee->crypt[i] != NULL)
555 sec.level = SEC_LEVEL_0;
556 sec.flags |= SEC_LEVEL;
563 case IW_ENCODE_ALG_WEP:
565 module = "rtllib_crypt_wep";
567 case IW_ENCODE_ALG_TKIP:
569 module = "rtllib_crypt_tkip";
571 case IW_ENCODE_ALG_CCMP:
573 module = "rtllib_crypt_ccmp";
576 RTLLIB_DEBUG_WX("%s: unknown crypto alg %d\n",
577 dev->name, ext->alg);
581 printk("alg name:%s\n",alg);
583 ops = rtllib_get_crypto_ops(alg);
587 memset( tempbuf, 0x00, 100 );
588 sprintf( tempbuf, "%s", module);
589 request_module("%s",tempbuf);
590 ops = rtllib_get_crypto_ops(alg);
593 RTLLIB_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 rtllib_crypt_data *new_crypt;
603 rtllib_crypt_delayed_deinit(ieee, crypt);
605 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
606 if (new_crypt == NULL) {
610 new_crypt->ops = ops;
612 new_crypt->priv = new_crypt->ops->init(idx);
614 if (new_crypt->priv == NULL) {
623 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
624 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
625 (*crypt)->priv) < 0) {
626 RTLLIB_DEBUG_WX("%s: key setting failed\n", dev->name);
627 printk("key setting failed\n");
631 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
632 ieee->tx_keyidx = idx;
633 sec.active_key = idx;
634 sec.flags |= SEC_ACTIVE_KEY;
636 if (ext->alg != IW_ENCODE_ALG_NONE) {
637 sec.key_sizes[idx] = ext->key_len;
638 sec.flags |= (1 << idx);
639 if (ext->alg == IW_ENCODE_ALG_WEP) {
640 sec.flags |= SEC_LEVEL;
641 sec.level = SEC_LEVEL_1;
642 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
643 sec.flags |= SEC_LEVEL;
644 sec.level = SEC_LEVEL_2;
645 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
646 sec.flags |= SEC_LEVEL;
647 sec.level = SEC_LEVEL_3;
649 /* Don't set sec level for group keys. */
651 sec.flags &= ~SEC_LEVEL;
654 if (ieee->set_security)
655 ieee->set_security(ieee->dev, &sec);
657 if (ieee->reset_on_keychange &&
658 ieee->iw_mode != IW_MODE_INFRA &&
659 ieee->reset_port && ieee->reset_port(dev)) {
660 RTLLIB_DEBUG_WX("%s: reset_port failed\n", dev->name);
666 int rtllib_wx_get_encode_ext(struct rtllib_device *ieee,
667 struct iw_request_info *info,
668 union iwreq_data *wrqu, char *extra)
670 struct iw_point *encoding = &wrqu->encoding;
671 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
672 struct rtllib_crypt_data *crypt;
673 int idx, max_key_len;
675 max_key_len = encoding->length - sizeof(*ext);
679 idx = encoding->flags & IW_ENCODE_INDEX;
681 if (idx < 1 || idx > WEP_KEYS)
685 idx = ieee->tx_keyidx;
687 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
688 (ext->alg != IW_ENCODE_ALG_WEP))
689 if (idx != 0 || (ieee->iw_mode != IW_MODE_INFRA))
692 crypt = ieee->crypt[idx];
694 encoding->flags = idx + 1;
695 memset(ext, 0, sizeof(*ext));
697 if (crypt == NULL || crypt->ops == NULL ) {
698 ext->alg = IW_ENCODE_ALG_NONE;
700 encoding->flags |= IW_ENCODE_DISABLED;
702 if (strcmp(crypt->ops->name, "WEP") == 0 )
703 ext->alg = IW_ENCODE_ALG_WEP;
704 else if (strcmp(crypt->ops->name, "TKIP"))
705 ext->alg = IW_ENCODE_ALG_TKIP;
706 else if (strcmp(crypt->ops->name, "CCMP"))
707 ext->alg = IW_ENCODE_ALG_CCMP;
710 ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
711 encoding->flags |= IW_ENCODE_ENABLED;
713 (ext->alg == IW_ENCODE_ALG_TKIP ||
714 ext->alg == IW_ENCODE_ALG_CCMP))
715 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
722 int rtllib_wx_set_mlme(struct rtllib_device *ieee,
723 struct iw_request_info *info,
724 union iwreq_data *wrqu, char *extra)
728 struct iw_mlme *mlme = (struct iw_mlme *) extra;
730 if (ieee->state != RTLLIB_LINKED)
738 /* leave break out intentionly */
740 case IW_MLME_DISASSOC:
742 printk("disauth packet !\n");
744 printk("dis associate packet!\n");
746 ieee->cannot_notify = true;
748 SendDisassociation(ieee,deauth,mlme->reason_code);
749 rtllib_disassociate(ieee);
752 for (i = 0; i < 6; i++)
753 ieee->current_network.bssid[i]= 0x55;
756 ieee->current_network.ssid[0] = '\0';
757 ieee->current_network.ssid_len = 0;
769 int rtllib_wx_set_auth(struct rtllib_device *ieee,
770 struct iw_request_info *info,
771 struct iw_param *data, char *extra)
773 switch (data->flags & IW_AUTH_INDEX) {
774 case IW_AUTH_WPA_VERSION:
776 case IW_AUTH_CIPHER_PAIRWISE:
777 case IW_AUTH_CIPHER_GROUP:
778 case IW_AUTH_KEY_MGMT:
780 * Host AP driver does not use these parameters and allows
781 * wpa_supplicant to control them internally.
784 case IW_AUTH_TKIP_COUNTERMEASURES:
785 ieee->tkip_countermeasures = data->value;
787 case IW_AUTH_DROP_UNENCRYPTED:
788 ieee->drop_unencrypted = data->value;
791 case IW_AUTH_80211_AUTH_ALG:
792 if (data->value & IW_AUTH_ALG_SHARED_KEY){
796 else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM){
800 else if (data->value & IW_AUTH_ALG_LEAP){
808 case IW_AUTH_WPA_ENABLED:
809 ieee->wpa_enabled = (data->value)?1:0;
812 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
813 ieee->ieee802_1x = data->value;
815 case IW_AUTH_PRIVACY_INVOKED:
816 ieee->privacy_invoked = data->value;
824 int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
827 u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04};
829 if (len > MAX_WPA_IE_LEN || (len && ie == NULL)) {
835 if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2], wps_oui, 4))) {
837 ieee->wps_ie_len = (len < MAX_WZC_IE_LEN) ? (len):(MAX_WZC_IE_LEN);
838 buf = kmalloc(ieee->wps_ie_len, GFP_KERNEL);
841 memcpy(buf, ie, ieee->wps_ie_len);
846 ieee->wps_ie_len = 0;
851 if (len != ie[1]+2) {
854 buf = kmalloc(len, GFP_KERNEL);
857 memcpy(buf, ie, len);
860 ieee->wpa_ie_len = len;
865 ieee->wpa_ie_len = 0;