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/module.h>
35 #include <linux/etherdevice.h>
41 static struct modes_unit rtllib_modes[] = {
50 #define MAX_CUSTOM_LEN 64
51 static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
52 char *start, char *stop,
53 struct rtllib_network *network,
54 struct iw_request_info *info)
56 char custom[MAX_CUSTOM_LEN];
57 char proto_name[IFNAMSIZ];
58 char *pname = proto_name;
63 static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
65 /* First entry *MUST* be the AP MAC address */
67 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
68 ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid);
69 start = iwe_stream_add_event_rsl(info, start, stop,
70 &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_t(u8, network->ssid_len, 32);
78 start = iwe_stream_add_point_rsl(info, start, stop, &iwe,
80 } else if (network->hidden_ssid_len == 0) {
81 iwe.u.data.length = sizeof("<hidden>");
82 start = iwe_stream_add_point_rsl(info, start, stop,
85 iwe.u.data.length = min_t(u8, network->hidden_ssid_len, 32);
86 start = iwe_stream_add_point_rsl(info, start, stop, &iwe,
87 network->hidden_ssid);
89 /* Add the protocol name */
90 iwe.cmd = SIOCGIWNAME;
91 for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) {
92 if (network->mode&(1<<i)) {
93 sprintf(pname, rtllib_modes[i].mode_string,
94 rtllib_modes[i].mode_size);
95 pname += rtllib_modes[i].mode_size;
99 snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
100 start = iwe_stream_add_event_rsl(info, start, stop,
101 &iwe, IW_EV_CHAR_LEN);
103 iwe.cmd = SIOCGIWMODE;
104 if (network->capability &
105 (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
106 if (network->capability & WLAN_CAPABILITY_ESS)
107 iwe.u.mode = IW_MODE_MASTER;
109 iwe.u.mode = IW_MODE_ADHOC;
110 start = iwe_stream_add_event_rsl(info, start, stop,
111 &iwe, IW_EV_UINT_LEN);
114 /* Add frequency/channel */
115 iwe.cmd = SIOCGIWFREQ;
116 iwe.u.freq.m = network->channel;
119 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
122 /* Add encryption capability */
123 iwe.cmd = SIOCGIWENCODE;
124 if (network->capability & WLAN_CAPABILITY_PRIVACY)
125 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
127 iwe.u.data.flags = IW_ENCODE_DISABLED;
128 iwe.u.data.length = 0;
129 start = iwe_stream_add_point_rsl(info, start, stop,
130 &iwe, network->ssid);
131 /* Add basic and extended rates */
134 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
135 for (i = 0, j = 0; i < network->rates_len;) {
136 if (j < network->rates_ex_len &&
137 ((network->rates_ex[j] & 0x7F) <
138 (network->rates[i] & 0x7F)))
139 rate = network->rates_ex[j++] & 0x7F;
141 rate = network->rates[i++] & 0x7F;
144 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
145 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
147 for (; j < network->rates_ex_len; j++) {
148 rate = network->rates_ex[j] & 0x7F;
149 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
150 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
155 if (network->mode >= IEEE_N_24G) {
156 struct ht_capab_ele *ht_cap = NULL;
157 bool is40M = false, isShortGI = false;
160 if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
161 ht_cap = (struct ht_capab_ele *)
162 &network->bssht.bdHTCapBuf[4];
164 ht_cap = (struct ht_capab_ele *)
165 &network->bssht.bdHTCapBuf[0];
166 is40M = (ht_cap->ChlWidth) ? 1 : 0;
167 isShortGI = (ht_cap->ChlWidth) ?
168 ((ht_cap->ShortGI40Mhz) ? 1 : 0) :
169 ((ht_cap->ShortGI20Mhz) ? 1 : 0);
171 max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS,
173 rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f];
177 iwe.cmd = SIOCGIWRATE;
178 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
179 iwe.u.bitrate.value = max_rate * 500000;
180 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
182 iwe.cmd = IWEVCUSTOM;
183 iwe.u.data.length = p - custom;
184 if (iwe.u.data.length)
185 start = iwe_stream_add_point_rsl(info, start, stop,
187 /* Add quality statistics */
188 /* TODO: Fix these values... */
190 iwe.u.qual.qual = network->stats.signal;
191 iwe.u.qual.level = network->stats.rssi;
192 iwe.u.qual.noise = network->stats.noise;
193 iwe.u.qual.updated = network->stats.mask & RTLLIB_STATMASK_WEMASK;
194 if (!(network->stats.mask & RTLLIB_STATMASK_RSSI))
195 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
196 if (!(network->stats.mask & RTLLIB_STATMASK_NOISE))
197 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
198 if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL))
199 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
200 iwe.u.qual.updated = 7;
201 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
204 iwe.cmd = IWEVCUSTOM;
206 iwe.u.data.length = p - custom;
207 if (iwe.u.data.length)
208 start = iwe_stream_add_point_rsl(info, start, stop,
211 memset(&iwe, 0, sizeof(iwe));
212 if (network->wpa_ie_len) {
213 char buf[MAX_WPA_IE_LEN];
215 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
217 iwe.u.data.length = network->wpa_ie_len;
218 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
220 memset(&iwe, 0, sizeof(iwe));
221 if (network->rsn_ie_len) {
222 char buf[MAX_WPA_IE_LEN];
224 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
226 iwe.u.data.length = network->rsn_ie_len;
227 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
230 /* add info for WZC */
231 memset(&iwe, 0, sizeof(iwe));
232 if (network->wzc_ie_len) {
233 char buf[MAX_WZC_IE_LEN];
235 memcpy(buf, network->wzc_ie, network->wzc_ie_len);
237 iwe.u.data.length = network->wzc_ie_len;
238 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
241 /* Add EXTRA: Age to display seconds since last beacon/probe response
244 iwe.cmd = IWEVCUSTOM;
246 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
247 " Last beacon: %lums ago",
248 (jiffies - network->last_scanned) / (HZ / 100));
249 iwe.u.data.length = p - custom;
250 if (iwe.u.data.length)
251 start = iwe_stream_add_point_rsl(info, start, stop,
257 int rtllib_wx_get_scan(struct rtllib_device *ieee,
258 struct iw_request_info *info,
259 union iwreq_data *wrqu, char *extra)
261 struct rtllib_network *network;
265 char *stop = ev + wrqu->data.length;
269 RTLLIB_DEBUG_WX("Getting scan\n");
271 spin_lock_irqsave(&ieee->lock, flags);
273 list_for_each_entry(network, &ieee->network_list, list) {
275 if ((stop - ev) < 200) {
279 if (ieee->scan_age == 0 ||
280 time_after(network->last_scanned + ieee->scan_age, jiffies))
281 ev = rtl819x_translate_scan(ieee, ev, stop, network,
284 RTLLIB_DEBUG_SCAN("Not showing network '%s ( %pM)' due to age (%lums).\n",
285 escape_essid(network->ssid,
288 (jiffies - network->last_scanned) / (HZ / 100));
291 spin_unlock_irqrestore(&ieee->lock, flags);
293 wrqu->data.length = ev - extra;
294 wrqu->data.flags = 0;
296 RTLLIB_DEBUG_WX("exit: %d networks returned.\n", i);
300 EXPORT_SYMBOL(rtllib_wx_get_scan);
302 int rtllib_wx_set_encode(struct rtllib_device *ieee,
303 struct iw_request_info *info,
304 union iwreq_data *wrqu, char *keybuf)
306 struct iw_point *erq = &(wrqu->encoding);
307 struct net_device *dev = ieee->dev;
308 struct rtllib_security sec = {
311 int i, key, key_provided, len;
312 struct lib80211_crypt_data **crypt;
314 RTLLIB_DEBUG_WX("SET_ENCODE\n");
316 key = erq->flags & IW_ENCODE_INDEX;
318 if (key > NUM_WEP_KEYS)
324 key = ieee->crypt_info.tx_keyidx;
327 RTLLIB_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
328 "provided" : "default");
329 crypt = &ieee->crypt_info.crypt[key];
330 if (erq->flags & IW_ENCODE_DISABLED) {
331 if (key_provided && *crypt) {
332 RTLLIB_DEBUG_WX("Disabling encryption on key %d.\n",
334 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
336 RTLLIB_DEBUG_WX("Disabling encryption.\n");
338 /* Check all the keys to see if any are still configured,
339 * and if no key index was provided, de-init them all
341 for (i = 0; i < NUM_WEP_KEYS; i++) {
342 if (ieee->crypt_info.crypt[i] != NULL) {
345 lib80211_crypt_delayed_deinit(&ieee->crypt_info,
346 &ieee->crypt_info.crypt[i]);
350 if (i == NUM_WEP_KEYS) {
352 sec.level = SEC_LEVEL_0;
353 sec.flags |= SEC_ENABLED | SEC_LEVEL;
362 sec.flags |= SEC_ENABLED;
364 if (*crypt != NULL && (*crypt)->ops != NULL &&
365 strcmp((*crypt)->ops->name, "R-WEP") != 0) {
366 /* changing to use WEP; deinit previously used algorithm
369 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
372 if (*crypt == NULL) {
373 struct lib80211_crypt_data *new_crypt;
375 /* take WEP into use */
376 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
378 if (new_crypt == NULL)
380 new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
381 if (!new_crypt->ops) {
382 request_module("rtllib_crypt_wep");
383 new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
387 new_crypt->priv = new_crypt->ops->init(key);
389 if (!new_crypt->ops || !new_crypt->priv) {
394 "%s: could not initialize WEP: load module rtllib_crypt_wep\n",
401 /* If a new key was provided, set it up */
402 if (erq->length > 0) {
403 len = erq->length <= 5 ? 5 : 13;
404 memcpy(sec.keys[key], keybuf, erq->length);
405 if (len > erq->length)
406 memset(sec.keys[key] + erq->length, 0,
408 RTLLIB_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
409 key, escape_essid(sec.keys[key], len),
411 sec.key_sizes[key] = len;
412 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
414 sec.flags |= (1 << key);
415 /* This ensures a key will be activated if no key is
418 if (key == sec.active_key)
419 sec.flags |= SEC_ACTIVE_KEY;
420 ieee->crypt_info.tx_keyidx = key;
423 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
424 NULL, (*crypt)->priv);
426 /* Set a default key of all 0 */
427 netdev_info(ieee->dev, "Setting key %d to all zero.\n",
430 memset(sec.keys[key], 0, 13);
431 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
433 sec.key_sizes[key] = 13;
434 sec.flags |= (1 << key);
437 /* No key data - just set the default TX key index */
439 RTLLIB_DEBUG_WX("Setting key %d to default Tx key.\n",
441 ieee->crypt_info.tx_keyidx = key;
442 sec.active_key = key;
443 sec.flags |= SEC_ACTIVE_KEY;
447 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
448 ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
449 WLAN_AUTH_SHARED_KEY;
450 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
451 sec.flags |= SEC_AUTH_MODE;
452 RTLLIB_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
453 "OPEN" : "SHARED KEY");
455 /* For now we just support WEP, so only set that security level...
456 * TODO: When WPA is added this is one place that needs to change
458 sec.flags |= SEC_LEVEL;
459 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
461 if (ieee->set_security)
462 ieee->set_security(dev, &sec);
464 /* Do not reset port if card is in Managed mode since resetting will
465 * generate new IEEE 802.11 authentication which may end up in looping
466 * with IEEE 802.1X. If your hardware requires a reset after WEP
467 * configuration (for example... Prism2), implement the reset_port in
468 * the callbacks structures used to initialize the 802.11 stack.
470 if (ieee->reset_on_keychange &&
471 ieee->iw_mode != IW_MODE_INFRA &&
472 ieee->reset_port && ieee->reset_port(dev)) {
473 netdev_dbg(dev, "%s: reset_port failed\n", dev->name);
478 EXPORT_SYMBOL(rtllib_wx_set_encode);
480 int rtllib_wx_get_encode(struct rtllib_device *ieee,
481 struct iw_request_info *info,
482 union iwreq_data *wrqu, char *keybuf)
484 struct iw_point *erq = &(wrqu->encoding);
486 struct lib80211_crypt_data *crypt;
488 RTLLIB_DEBUG_WX("GET_ENCODE\n");
490 if (ieee->iw_mode == IW_MODE_MONITOR)
493 key = erq->flags & IW_ENCODE_INDEX;
495 if (key > NUM_WEP_KEYS)
499 key = ieee->crypt_info.tx_keyidx;
501 crypt = ieee->crypt_info.crypt[key];
503 erq->flags = key + 1;
505 if (crypt == NULL || crypt->ops == NULL) {
507 erq->flags |= IW_ENCODE_DISABLED;
510 len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
511 erq->length = (len >= 0 ? len : 0);
513 erq->flags |= IW_ENCODE_ENABLED;
516 erq->flags |= IW_ENCODE_OPEN;
518 erq->flags |= IW_ENCODE_RESTRICTED;
522 EXPORT_SYMBOL(rtllib_wx_get_encode);
524 int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
525 struct iw_request_info *info,
526 union iwreq_data *wrqu, char *extra)
529 struct net_device *dev = ieee->dev;
530 struct iw_point *encoding = &wrqu->encoding;
531 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
534 const char *alg, *module;
535 struct lib80211_crypto_ops *ops;
536 struct lib80211_crypt_data **crypt;
538 struct rtllib_security sec = {
541 idx = encoding->flags & IW_ENCODE_INDEX;
543 if (idx < 1 || idx > NUM_WEP_KEYS)
547 idx = ieee->crypt_info.tx_keyidx;
549 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
550 crypt = &ieee->crypt_info.crypt[idx];
553 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
554 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
556 if (ieee->iw_mode == IW_MODE_INFRA)
557 crypt = &ieee->crypt_info.crypt[idx];
562 sec.flags |= SEC_ENABLED;
563 if ((encoding->flags & IW_ENCODE_DISABLED) ||
564 ext->alg == IW_ENCODE_ALG_NONE) {
566 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
568 for (i = 0; i < NUM_WEP_KEYS; i++) {
569 if (ieee->crypt_info.crypt[i] != NULL)
572 if (i == NUM_WEP_KEYS) {
574 sec.level = SEC_LEVEL_0;
575 sec.flags |= SEC_LEVEL;
582 case IW_ENCODE_ALG_WEP:
584 module = "rtllib_crypt_wep";
586 case IW_ENCODE_ALG_TKIP:
588 module = "rtllib_crypt_tkip";
590 case IW_ENCODE_ALG_CCMP:
592 module = "rtllib_crypt_ccmp";
595 RTLLIB_DEBUG_WX("%s: unknown crypto alg %d\n",
596 dev->name, ext->alg);
600 netdev_info(dev, "alg name:%s\n", alg);
602 ops = lib80211_get_crypto_ops(alg);
606 memset(tempbuf, 0x00, 100);
607 sprintf(tempbuf, "%s", module);
608 request_module("%s", tempbuf);
609 ops = lib80211_get_crypto_ops(alg);
612 netdev_info(dev, "========>unknown crypto alg %d\n", ext->alg);
617 if (*crypt == NULL || (*crypt)->ops != ops) {
618 struct lib80211_crypt_data *new_crypt;
620 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
622 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
623 if (new_crypt == NULL) {
627 new_crypt->ops = ops;
629 new_crypt->priv = new_crypt->ops->init(idx);
631 if (new_crypt->priv == NULL) {
640 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
641 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
642 (*crypt)->priv) < 0) {
643 netdev_info(dev, "key setting failed\n");
647 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
648 ieee->crypt_info.tx_keyidx = idx;
649 sec.active_key = idx;
650 sec.flags |= SEC_ACTIVE_KEY;
652 if (ext->alg != IW_ENCODE_ALG_NONE) {
653 sec.key_sizes[idx] = ext->key_len;
654 sec.flags |= (1 << idx);
655 if (ext->alg == IW_ENCODE_ALG_WEP) {
656 sec.flags |= SEC_LEVEL;
657 sec.level = SEC_LEVEL_1;
658 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
659 sec.flags |= SEC_LEVEL;
660 sec.level = SEC_LEVEL_2;
661 } else if (ext->alg == IW_ENCODE_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 RTLLIB_DEBUG_WX("%s: reset_port failed\n", dev->name);
681 EXPORT_SYMBOL(rtllib_wx_set_encode_ext);
683 int rtllib_wx_get_encode_ext(struct rtllib_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 lib80211_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 > NUM_WEP_KEYS)
702 idx = ieee->crypt_info.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_info.crypt[idx];
711 encoding->flags = idx + 1;
712 memset(ext, 0, sizeof(*ext));
714 if (crypt == NULL || crypt->ops == NULL) {
715 ext->alg = IW_ENCODE_ALG_NONE;
717 encoding->flags |= IW_ENCODE_DISABLED;
719 if (strcmp(crypt->ops->name, "R-WEP") == 0)
720 ext->alg = IW_ENCODE_ALG_WEP;
721 else if (strcmp(crypt->ops->name, "R-TKIP"))
722 ext->alg = IW_ENCODE_ALG_TKIP;
723 else if (strcmp(crypt->ops->name, "R-CCMP"))
724 ext->alg = IW_ENCODE_ALG_CCMP;
727 ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN,
729 encoding->flags |= IW_ENCODE_ENABLED;
731 (ext->alg == IW_ENCODE_ALG_TKIP ||
732 ext->alg == IW_ENCODE_ALG_CCMP))
733 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
740 int rtllib_wx_set_mlme(struct rtllib_device *ieee,
741 struct iw_request_info *info,
742 union iwreq_data *wrqu, char *extra)
746 struct iw_mlme *mlme = (struct iw_mlme *) extra;
748 if (ieee->state != RTLLIB_LINKED)
756 /* leave break out intentionly */
758 case IW_MLME_DISASSOC:
760 netdev_info(ieee->dev, "disauth packet !\n");
762 netdev_info(ieee->dev, "dis associate packet!\n");
764 ieee->cannot_notify = true;
766 SendDisassociation(ieee, deauth, mlme->reason_code);
767 rtllib_disassociate(ieee);
770 for (i = 0; i < 6; i++)
771 ieee->current_network.bssid[i] = 0x55;
774 ieee->current_network.ssid[0] = '\0';
775 ieee->current_network.ssid_len = 0;
786 EXPORT_SYMBOL(rtllib_wx_set_mlme);
788 int rtllib_wx_set_auth(struct rtllib_device *ieee,
789 struct iw_request_info *info,
790 struct iw_param *data, char *extra)
792 switch (data->flags & IW_AUTH_INDEX) {
793 case IW_AUTH_WPA_VERSION:
795 case IW_AUTH_CIPHER_PAIRWISE:
796 case IW_AUTH_CIPHER_GROUP:
797 case IW_AUTH_KEY_MGMT:
798 /* Host AP driver does not use these parameters and allows
799 * wpa_supplicant to control them internally.
802 case IW_AUTH_TKIP_COUNTERMEASURES:
803 ieee->tkip_countermeasures = data->value;
805 case IW_AUTH_DROP_UNENCRYPTED:
806 ieee->drop_unencrypted = data->value;
809 case IW_AUTH_80211_AUTH_ALG:
810 if (data->value & IW_AUTH_ALG_SHARED_KEY) {
813 } else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) {
816 } else if (data->value & IW_AUTH_ALG_LEAP) {
823 case IW_AUTH_WPA_ENABLED:
824 ieee->wpa_enabled = (data->value) ? 1 : 0;
827 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
828 ieee->ieee802_1x = data->value;
830 case IW_AUTH_PRIVACY_INVOKED:
831 ieee->privacy_invoked = data->value;
838 EXPORT_SYMBOL(rtllib_wx_set_auth);
840 int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
843 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
845 if (len > MAX_WPA_IE_LEN || (len && ie == NULL))
850 if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2],
853 ieee->wps_ie_len = (len < MAX_WZC_IE_LEN) ? (len) :
855 buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL);
862 ieee->wps_ie_len = 0;
868 buf = kmemdup(ie, len, GFP_KERNEL);
873 ieee->wpa_ie_len = len;
877 ieee->wpa_ie_len = 0;
881 EXPORT_SYMBOL(rtllib_wx_set_gen_ie);