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);
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 EXPORT_SYMBOL(rtllib_wx_get_encode);
526 int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
527 struct iw_request_info *info,
528 union iwreq_data *wrqu, char *extra)
531 struct net_device *dev = ieee->dev;
532 struct iw_point *encoding = &wrqu->encoding;
533 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
536 const char *alg, *module;
537 struct lib80211_crypto_ops *ops;
538 struct lib80211_crypt_data **crypt;
540 struct rtllib_security sec = {
543 idx = encoding->flags & IW_ENCODE_INDEX;
545 if (idx < 1 || idx > NUM_WEP_KEYS)
549 idx = ieee->crypt_info.tx_keyidx;
551 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
552 crypt = &ieee->crypt_info.crypt[idx];
555 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
556 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
558 if (ieee->iw_mode == IW_MODE_INFRA)
559 crypt = &ieee->crypt_info.crypt[idx];
564 sec.flags |= SEC_ENABLED;
565 if ((encoding->flags & IW_ENCODE_DISABLED) ||
566 ext->alg == IW_ENCODE_ALG_NONE) {
568 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
570 for (i = 0; i < NUM_WEP_KEYS; i++) {
571 if (ieee->crypt_info.crypt[i] != NULL)
574 if (i == NUM_WEP_KEYS) {
576 sec.level = SEC_LEVEL_0;
577 sec.flags |= SEC_LEVEL;
584 case IW_ENCODE_ALG_WEP:
586 module = "rtllib_crypt_wep";
588 case IW_ENCODE_ALG_TKIP:
590 module = "rtllib_crypt_tkip";
592 case IW_ENCODE_ALG_CCMP:
594 module = "rtllib_crypt_ccmp";
597 netdev_dbg(ieee->dev, "Unknown crypto alg %d\n", ext->alg);
601 netdev_info(dev, "alg name:%s\n", alg);
603 ops = lib80211_get_crypto_ops(alg);
607 memset(tempbuf, 0x00, 100);
608 sprintf(tempbuf, "%s", module);
609 request_module("%s", tempbuf);
610 ops = lib80211_get_crypto_ops(alg);
613 netdev_info(dev, "========>unknown crypto alg %d\n", ext->alg);
618 if (*crypt == NULL || (*crypt)->ops != ops) {
619 struct lib80211_crypt_data *new_crypt;
621 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
623 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
624 if (new_crypt == NULL) {
628 new_crypt->ops = ops;
630 new_crypt->priv = new_crypt->ops->init(idx);
632 if (new_crypt->priv == NULL) {
641 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
642 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
643 (*crypt)->priv) < 0) {
644 netdev_info(dev, "key setting failed\n");
648 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
649 ieee->crypt_info.tx_keyidx = idx;
650 sec.active_key = idx;
651 sec.flags |= SEC_ACTIVE_KEY;
653 if (ext->alg != IW_ENCODE_ALG_NONE) {
654 sec.key_sizes[idx] = ext->key_len;
655 sec.flags |= (1 << idx);
656 if (ext->alg == IW_ENCODE_ALG_WEP) {
657 sec.flags |= SEC_LEVEL;
658 sec.level = SEC_LEVEL_1;
659 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
660 sec.flags |= SEC_LEVEL;
661 sec.level = SEC_LEVEL_2;
662 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
663 sec.flags |= SEC_LEVEL;
664 sec.level = SEC_LEVEL_3;
666 /* Don't set sec level for group keys. */
668 sec.flags &= ~SEC_LEVEL;
671 if (ieee->set_security)
672 ieee->set_security(ieee->dev, &sec);
674 if (ieee->reset_on_keychange &&
675 ieee->iw_mode != IW_MODE_INFRA &&
676 ieee->reset_port && ieee->reset_port(dev)) {
677 netdev_dbg(ieee->dev, "Port reset failed\n");
682 EXPORT_SYMBOL(rtllib_wx_set_encode_ext);
684 int rtllib_wx_get_encode_ext(struct rtllib_device *ieee,
685 struct iw_request_info *info,
686 union iwreq_data *wrqu, char *extra)
688 struct iw_point *encoding = &wrqu->encoding;
689 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
690 struct lib80211_crypt_data *crypt;
691 int idx, max_key_len;
693 max_key_len = encoding->length - sizeof(*ext);
697 idx = encoding->flags & IW_ENCODE_INDEX;
699 if (idx < 1 || idx > NUM_WEP_KEYS)
703 idx = ieee->crypt_info.tx_keyidx;
705 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
706 (ext->alg != IW_ENCODE_ALG_WEP))
707 if (idx != 0 || (ieee->iw_mode != IW_MODE_INFRA))
710 crypt = ieee->crypt_info.crypt[idx];
712 encoding->flags = idx + 1;
713 memset(ext, 0, sizeof(*ext));
715 if (crypt == NULL || crypt->ops == NULL) {
716 ext->alg = IW_ENCODE_ALG_NONE;
718 encoding->flags |= IW_ENCODE_DISABLED;
720 if (strcmp(crypt->ops->name, "R-WEP") == 0)
721 ext->alg = IW_ENCODE_ALG_WEP;
722 else if (strcmp(crypt->ops->name, "R-TKIP"))
723 ext->alg = IW_ENCODE_ALG_TKIP;
724 else if (strcmp(crypt->ops->name, "R-CCMP"))
725 ext->alg = IW_ENCODE_ALG_CCMP;
728 ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN,
730 encoding->flags |= IW_ENCODE_ENABLED;
732 (ext->alg == IW_ENCODE_ALG_TKIP ||
733 ext->alg == IW_ENCODE_ALG_CCMP))
734 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
741 int rtllib_wx_set_mlme(struct rtllib_device *ieee,
742 struct iw_request_info *info,
743 union iwreq_data *wrqu, char *extra)
747 struct iw_mlme *mlme = (struct iw_mlme *) extra;
749 if (ieee->state != RTLLIB_LINKED)
757 /* leave break out intentionly */
759 case IW_MLME_DISASSOC:
761 netdev_info(ieee->dev, "disauth packet !\n");
763 netdev_info(ieee->dev, "dis associate packet!\n");
765 ieee->cannot_notify = true;
767 SendDisassociation(ieee, deauth, mlme->reason_code);
768 rtllib_disassociate(ieee);
771 for (i = 0; i < 6; i++)
772 ieee->current_network.bssid[i] = 0x55;
775 ieee->current_network.ssid[0] = '\0';
776 ieee->current_network.ssid_len = 0;
787 EXPORT_SYMBOL(rtllib_wx_set_mlme);
789 int rtllib_wx_set_auth(struct rtllib_device *ieee,
790 struct iw_request_info *info,
791 struct iw_param *data, char *extra)
793 switch (data->flags & IW_AUTH_INDEX) {
794 case IW_AUTH_WPA_VERSION:
796 case IW_AUTH_CIPHER_PAIRWISE:
797 case IW_AUTH_CIPHER_GROUP:
798 case IW_AUTH_KEY_MGMT:
799 /* Host AP driver does not use these parameters and allows
800 * wpa_supplicant to control them internally.
803 case IW_AUTH_TKIP_COUNTERMEASURES:
804 ieee->tkip_countermeasures = data->value;
806 case IW_AUTH_DROP_UNENCRYPTED:
807 ieee->drop_unencrypted = data->value;
810 case IW_AUTH_80211_AUTH_ALG:
811 if (data->value & IW_AUTH_ALG_SHARED_KEY) {
814 } else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) {
817 } else if (data->value & IW_AUTH_ALG_LEAP) {
824 case IW_AUTH_WPA_ENABLED:
825 ieee->wpa_enabled = (data->value) ? 1 : 0;
828 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
829 ieee->ieee802_1x = data->value;
831 case IW_AUTH_PRIVACY_INVOKED:
832 ieee->privacy_invoked = data->value;
839 EXPORT_SYMBOL(rtllib_wx_set_auth);
841 int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
844 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
846 if (len > MAX_WPA_IE_LEN || (len && ie == NULL))
851 if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2],
854 ieee->wps_ie_len = min_t(size_t, len, MAX_WZC_IE_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);