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 netdev_dbg(ieee->dev, "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 netdev_dbg(ieee->dev,
285 "Network '%s ( %pM)' hidden due to age (%lums).\n",
286 escape_essid(network->ssid,
289 (jiffies - network->last_scanned) /
293 spin_unlock_irqrestore(&ieee->lock, flags);
295 wrqu->data.length = ev - extra;
296 wrqu->data.flags = 0;
298 netdev_dbg(ieee->dev, "%s(): %d networks returned.\n", __func__, i);
302 EXPORT_SYMBOL(rtllib_wx_get_scan);
304 int rtllib_wx_set_encode(struct rtllib_device *ieee,
305 struct iw_request_info *info,
306 union iwreq_data *wrqu, char *keybuf)
308 struct iw_point *erq = &(wrqu->encoding);
309 struct net_device *dev = ieee->dev;
310 struct rtllib_security sec = {
313 int i, key, key_provided, len;
314 struct lib80211_crypt_data **crypt;
316 netdev_dbg(ieee->dev, "%s()\n", __func__);
318 key = erq->flags & IW_ENCODE_INDEX;
320 if (key > NUM_WEP_KEYS)
326 key = ieee->crypt_info.tx_keyidx;
329 netdev_dbg(ieee->dev, "Key: %d [%s]\n", key, key_provided ?
330 "provided" : "default");
331 crypt = &ieee->crypt_info.crypt[key];
332 if (erq->flags & IW_ENCODE_DISABLED) {
333 if (key_provided && *crypt) {
334 netdev_dbg(ieee->dev,
335 "Disabling encryption on key %d.\n", key);
336 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
338 netdev_dbg(ieee->dev, "Disabling encryption.\n");
340 /* Check all the keys to see if any are still configured,
341 * and if no key index was provided, de-init them all
343 for (i = 0; i < NUM_WEP_KEYS; i++) {
344 if (ieee->crypt_info.crypt[i] != NULL) {
347 lib80211_crypt_delayed_deinit(&ieee->crypt_info,
348 &ieee->crypt_info.crypt[i]);
352 if (i == NUM_WEP_KEYS) {
354 sec.level = SEC_LEVEL_0;
355 sec.flags |= SEC_ENABLED | SEC_LEVEL;
364 sec.flags |= SEC_ENABLED;
366 if (*crypt != NULL && (*crypt)->ops != NULL &&
367 strcmp((*crypt)->ops->name, "R-WEP") != 0) {
368 /* changing to use WEP; deinit previously used algorithm
371 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
374 if (*crypt == NULL) {
375 struct lib80211_crypt_data *new_crypt;
377 /* take WEP into use */
378 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
380 if (new_crypt == NULL)
382 new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
383 if (!new_crypt->ops) {
384 request_module("rtllib_crypt_wep");
385 new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
389 new_crypt->priv = new_crypt->ops->init(key);
391 if (!new_crypt->ops || !new_crypt->priv) {
396 "%s: could not initialize WEP: load module rtllib_crypt_wep\n",
403 /* If a new key was provided, set it up */
404 if (erq->length > 0) {
405 len = erq->length <= 5 ? 5 : 13;
406 memcpy(sec.keys[key], keybuf, erq->length);
407 if (len > erq->length)
408 memset(sec.keys[key] + erq->length, 0,
410 netdev_dbg(ieee->dev, "Setting key %d to '%s' (%d:%d bytes)\n",
411 key, escape_essid(sec.keys[key], len), erq->length,
413 sec.key_sizes[key] = len;
414 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
416 sec.flags |= (1 << key);
417 /* This ensures a key will be activated if no key is
420 if (key == sec.active_key)
421 sec.flags |= SEC_ACTIVE_KEY;
422 ieee->crypt_info.tx_keyidx = key;
425 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
426 NULL, (*crypt)->priv);
428 /* Set a default key of all 0 */
429 netdev_info(ieee->dev, "Setting key %d to all zero.\n",
432 memset(sec.keys[key], 0, 13);
433 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
435 sec.key_sizes[key] = 13;
436 sec.flags |= (1 << key);
439 /* No key data - just set the default TX key index */
441 netdev_dbg(ieee->dev,
442 "Setting key %d as default Tx key.\n", key);
443 ieee->crypt_info.tx_keyidx = key;
444 sec.active_key = key;
445 sec.flags |= SEC_ACTIVE_KEY;
449 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
450 ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
451 WLAN_AUTH_SHARED_KEY;
452 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
453 sec.flags |= SEC_AUTH_MODE;
454 netdev_dbg(ieee->dev, "Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
455 "OPEN" : "SHARED KEY");
457 /* For now we just support WEP, so only set that security level...
458 * TODO: When WPA is added this is one place that needs to change
460 sec.flags |= SEC_LEVEL;
461 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
463 if (ieee->set_security)
464 ieee->set_security(dev, &sec);
466 /* Do not reset port if card is in Managed mode since resetting will
467 * generate new IEEE 802.11 authentication which may end up in looping
468 * with IEEE 802.1X. If your hardware requires a reset after WEP
469 * configuration (for example... Prism2), implement the reset_port in
470 * the callbacks structures used to initialize the 802.11 stack.
472 if (ieee->reset_on_keychange &&
473 ieee->iw_mode != IW_MODE_INFRA &&
474 ieee->reset_port && ieee->reset_port(dev)) {
475 netdev_dbg(dev, "%s: reset_port failed\n", dev->name);
480 EXPORT_SYMBOL(rtllib_wx_set_encode);
482 int rtllib_wx_get_encode(struct rtllib_device *ieee,
483 struct iw_request_info *info,
484 union iwreq_data *wrqu, char *keybuf)
486 struct iw_point *erq = &(wrqu->encoding);
488 struct lib80211_crypt_data *crypt;
490 netdev_dbg(ieee->dev, "%s()\n", __func__);
492 if (ieee->iw_mode == IW_MODE_MONITOR)
495 key = erq->flags & IW_ENCODE_INDEX;
497 if (key > NUM_WEP_KEYS)
501 key = ieee->crypt_info.tx_keyidx;
503 crypt = ieee->crypt_info.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);
514 erq->length = max(len, 0);
516 erq->flags |= IW_ENCODE_ENABLED;
519 erq->flags |= IW_ENCODE_OPEN;
521 erq->flags |= IW_ENCODE_RESTRICTED;
525 EXPORT_SYMBOL(rtllib_wx_get_encode);
527 int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
528 struct iw_request_info *info,
529 union iwreq_data *wrqu, char *extra)
532 struct net_device *dev = ieee->dev;
533 struct iw_point *encoding = &wrqu->encoding;
534 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
537 const char *alg, *module;
538 struct lib80211_crypto_ops *ops;
539 struct lib80211_crypt_data **crypt;
541 struct rtllib_security sec = {
544 idx = encoding->flags & IW_ENCODE_INDEX;
546 if (idx < 1 || idx > NUM_WEP_KEYS)
550 idx = ieee->crypt_info.tx_keyidx;
552 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
553 crypt = &ieee->crypt_info.crypt[idx];
556 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
557 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
559 if (ieee->iw_mode == IW_MODE_INFRA)
560 crypt = &ieee->crypt_info.crypt[idx];
565 sec.flags |= SEC_ENABLED;
566 if ((encoding->flags & IW_ENCODE_DISABLED) ||
567 ext->alg == IW_ENCODE_ALG_NONE) {
569 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
571 for (i = 0; i < NUM_WEP_KEYS; i++) {
572 if (ieee->crypt_info.crypt[i] != NULL)
575 if (i == NUM_WEP_KEYS) {
577 sec.level = SEC_LEVEL_0;
578 sec.flags |= SEC_LEVEL;
585 case IW_ENCODE_ALG_WEP:
587 module = "rtllib_crypt_wep";
589 case IW_ENCODE_ALG_TKIP:
591 module = "rtllib_crypt_tkip";
593 case IW_ENCODE_ALG_CCMP:
595 module = "rtllib_crypt_ccmp";
598 netdev_dbg(ieee->dev, "Unknown crypto alg %d\n", ext->alg);
602 netdev_info(dev, "alg name:%s\n", alg);
604 ops = lib80211_get_crypto_ops(alg);
608 memset(tempbuf, 0x00, 100);
609 sprintf(tempbuf, "%s", module);
610 request_module("%s", tempbuf);
611 ops = lib80211_get_crypto_ops(alg);
614 netdev_info(dev, "========>unknown crypto alg %d\n", ext->alg);
619 if (*crypt == NULL || (*crypt)->ops != ops) {
620 struct lib80211_crypt_data *new_crypt;
622 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
624 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
625 if (new_crypt == NULL) {
629 new_crypt->ops = ops;
631 new_crypt->priv = new_crypt->ops->init(idx);
633 if (new_crypt->priv == NULL) {
642 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
643 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
644 (*crypt)->priv) < 0) {
645 netdev_info(dev, "key setting failed\n");
649 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
650 ieee->crypt_info.tx_keyidx = idx;
651 sec.active_key = idx;
652 sec.flags |= SEC_ACTIVE_KEY;
654 if (ext->alg != IW_ENCODE_ALG_NONE) {
655 sec.key_sizes[idx] = ext->key_len;
656 sec.flags |= (1 << idx);
657 if (ext->alg == IW_ENCODE_ALG_WEP) {
658 sec.flags |= SEC_LEVEL;
659 sec.level = SEC_LEVEL_1;
660 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
661 sec.flags |= SEC_LEVEL;
662 sec.level = SEC_LEVEL_2;
663 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
664 sec.flags |= SEC_LEVEL;
665 sec.level = SEC_LEVEL_3;
667 /* Don't set sec level for group keys. */
669 sec.flags &= ~SEC_LEVEL;
672 if (ieee->set_security)
673 ieee->set_security(ieee->dev, &sec);
675 if (ieee->reset_on_keychange &&
676 ieee->iw_mode != IW_MODE_INFRA &&
677 ieee->reset_port && ieee->reset_port(dev)) {
678 netdev_dbg(ieee->dev, "Port reset failed\n");
683 EXPORT_SYMBOL(rtllib_wx_set_encode_ext);
685 int rtllib_wx_get_encode_ext(struct rtllib_device *ieee,
686 struct iw_request_info *info,
687 union iwreq_data *wrqu, char *extra)
689 struct iw_point *encoding = &wrqu->encoding;
690 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
691 struct lib80211_crypt_data *crypt;
692 int idx, max_key_len;
694 max_key_len = encoding->length - sizeof(*ext);
698 idx = encoding->flags & IW_ENCODE_INDEX;
700 if (idx < 1 || idx > NUM_WEP_KEYS)
704 idx = ieee->crypt_info.tx_keyidx;
706 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
707 (ext->alg != IW_ENCODE_ALG_WEP))
708 if (idx != 0 || (ieee->iw_mode != IW_MODE_INFRA))
711 crypt = ieee->crypt_info.crypt[idx];
713 encoding->flags = idx + 1;
714 memset(ext, 0, sizeof(*ext));
716 if (crypt == NULL || crypt->ops == NULL) {
717 ext->alg = IW_ENCODE_ALG_NONE;
719 encoding->flags |= IW_ENCODE_DISABLED;
721 if (strcmp(crypt->ops->name, "R-WEP") == 0)
722 ext->alg = IW_ENCODE_ALG_WEP;
723 else if (strcmp(crypt->ops->name, "R-TKIP"))
724 ext->alg = IW_ENCODE_ALG_TKIP;
725 else if (strcmp(crypt->ops->name, "R-CCMP"))
726 ext->alg = IW_ENCODE_ALG_CCMP;
729 ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN,
731 encoding->flags |= IW_ENCODE_ENABLED;
733 (ext->alg == IW_ENCODE_ALG_TKIP ||
734 ext->alg == IW_ENCODE_ALG_CCMP))
735 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
742 int rtllib_wx_set_mlme(struct rtllib_device *ieee,
743 struct iw_request_info *info,
744 union iwreq_data *wrqu, char *extra)
748 struct iw_mlme *mlme = (struct iw_mlme *) extra;
750 if (ieee->state != RTLLIB_LINKED)
758 /* leave break out intentionly */
760 case IW_MLME_DISASSOC:
762 netdev_info(ieee->dev, "disauth packet !\n");
764 netdev_info(ieee->dev, "dis associate packet!\n");
766 ieee->cannot_notify = true;
768 SendDisassociation(ieee, deauth, mlme->reason_code);
769 rtllib_disassociate(ieee);
772 for (i = 0; i < 6; i++)
773 ieee->current_network.bssid[i] = 0x55;
776 ieee->current_network.ssid[0] = '\0';
777 ieee->current_network.ssid_len = 0;
788 EXPORT_SYMBOL(rtllib_wx_set_mlme);
790 int rtllib_wx_set_auth(struct rtllib_device *ieee,
791 struct iw_request_info *info,
792 struct iw_param *data, char *extra)
794 switch (data->flags & IW_AUTH_INDEX) {
795 case IW_AUTH_WPA_VERSION:
797 case IW_AUTH_CIPHER_PAIRWISE:
798 case IW_AUTH_CIPHER_GROUP:
799 case IW_AUTH_KEY_MGMT:
800 /* Host AP driver does not use these parameters and allows
801 * wpa_supplicant to control them internally.
804 case IW_AUTH_TKIP_COUNTERMEASURES:
805 ieee->tkip_countermeasures = data->value;
807 case IW_AUTH_DROP_UNENCRYPTED:
808 ieee->drop_unencrypted = data->value;
811 case IW_AUTH_80211_AUTH_ALG:
812 if (data->value & IW_AUTH_ALG_SHARED_KEY) {
815 } else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) {
818 } else if (data->value & IW_AUTH_ALG_LEAP) {
825 case IW_AUTH_WPA_ENABLED:
826 ieee->wpa_enabled = (data->value) ? 1 : 0;
829 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
830 ieee->ieee802_1x = data->value;
832 case IW_AUTH_PRIVACY_INVOKED:
833 ieee->privacy_invoked = data->value;
840 EXPORT_SYMBOL(rtllib_wx_set_auth);
842 int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
845 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
847 if (len > MAX_WPA_IE_LEN || (len && ie == NULL))
852 if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2],
855 ieee->wps_ie_len = min_t(size_t, len, MAX_WZC_IE_LEN);
856 buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL);
863 ieee->wps_ie_len = 0;
869 buf = kmemdup(ie, len, GFP_KERNEL);
874 ieee->wpa_ie_len = len;
878 ieee->wpa_ie_len = 0;
882 EXPORT_SYMBOL(rtllib_wx_set_gen_ie);