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
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 The full GNU General Public License is included in this distribution in the
25 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 ******************************************************************************/
28 #include <linux/wireless.h>
29 #include <linux/kmod.h>
30 #include <linux/module.h>
31 #include <linux/etherdevice.h>
37 static struct modes_unit rtllib_modes[] = {
46 #define MAX_CUSTOM_LEN 64
47 static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
48 char *start, char *stop,
49 struct rtllib_network *network,
50 struct iw_request_info *info)
52 char custom[MAX_CUSTOM_LEN];
53 char proto_name[IFNAMSIZ];
54 char *pname = proto_name;
59 static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
61 /* First entry *MUST* be the AP MAC address */
63 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
64 ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid);
65 start = iwe_stream_add_event_rsl(info, start, stop,
66 &iwe, IW_EV_ADDR_LEN);
67 /* Remaining entries will be displayed in the order we provide them */
70 iwe.cmd = SIOCGIWESSID;
72 if (network->ssid_len > 0) {
73 iwe.u.data.length = min_t(u8, network->ssid_len, 32);
74 start = iwe_stream_add_point_rsl(info, start, stop, &iwe,
76 } else if (network->hidden_ssid_len == 0) {
77 iwe.u.data.length = sizeof("<hidden>");
78 start = iwe_stream_add_point_rsl(info, start, stop,
81 iwe.u.data.length = min_t(u8, network->hidden_ssid_len, 32);
82 start = iwe_stream_add_point_rsl(info, start, stop, &iwe,
83 network->hidden_ssid);
85 /* Add the protocol name */
86 iwe.cmd = SIOCGIWNAME;
87 for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) {
88 if (network->mode&(1<<i)) {
89 sprintf(pname, rtllib_modes[i].mode_string,
90 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,
97 &iwe, IW_EV_CHAR_LEN);
99 iwe.cmd = SIOCGIWMODE;
100 if (network->capability &
101 (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
102 if (network->capability & WLAN_CAPABILITY_ESS)
103 iwe.u.mode = IW_MODE_MASTER;
105 iwe.u.mode = IW_MODE_ADHOC;
106 start = iwe_stream_add_event_rsl(info, start, stop,
107 &iwe, IW_EV_UINT_LEN);
110 /* Add frequency/channel */
111 iwe.cmd = SIOCGIWFREQ;
112 iwe.u.freq.m = network->channel;
115 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
118 /* Add encryption capability */
119 iwe.cmd = SIOCGIWENCODE;
120 if (network->capability & WLAN_CAPABILITY_PRIVACY)
121 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
123 iwe.u.data.flags = IW_ENCODE_DISABLED;
124 iwe.u.data.length = 0;
125 start = iwe_stream_add_point_rsl(info, start, stop,
126 &iwe, network->ssid);
127 /* Add basic and extended rates */
130 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
131 for (i = 0, j = 0; i < network->rates_len;) {
132 if (j < network->rates_ex_len &&
133 ((network->rates_ex[j] & 0x7F) <
134 (network->rates[i] & 0x7F)))
135 rate = network->rates_ex[j++] & 0x7F;
137 rate = network->rates[i++] & 0x7F;
140 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
141 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
143 for (; j < network->rates_ex_len; j++) {
144 rate = network->rates_ex[j] & 0x7F;
145 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
146 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
151 if (network->mode >= IEEE_N_24G) {
152 struct ht_capab_ele *ht_cap = NULL;
153 bool is40M = false, isShortGI = false;
156 if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
157 ht_cap = (struct ht_capab_ele *)
158 &network->bssht.bdHTCapBuf[4];
160 ht_cap = (struct ht_capab_ele *)
161 &network->bssht.bdHTCapBuf[0];
162 is40M = (ht_cap->ChlWidth) ? 1 : 0;
163 isShortGI = (ht_cap->ChlWidth) ?
164 ((ht_cap->ShortGI40Mhz) ? 1 : 0) :
165 ((ht_cap->ShortGI20Mhz) ? 1 : 0);
167 max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS,
169 rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f];
173 iwe.cmd = SIOCGIWRATE;
174 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
175 iwe.u.bitrate.value = max_rate * 500000;
176 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
178 iwe.cmd = IWEVCUSTOM;
179 iwe.u.data.length = p - custom;
180 if (iwe.u.data.length)
181 start = iwe_stream_add_point_rsl(info, start, stop,
183 /* Add quality statistics */
184 /* TODO: Fix these values... */
186 iwe.u.qual.qual = network->stats.signal;
187 iwe.u.qual.level = network->stats.rssi;
188 iwe.u.qual.noise = network->stats.noise;
189 iwe.u.qual.updated = network->stats.mask & RTLLIB_STATMASK_WEMASK;
190 if (!(network->stats.mask & RTLLIB_STATMASK_RSSI))
191 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
192 if (!(network->stats.mask & RTLLIB_STATMASK_NOISE))
193 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
194 if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL))
195 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
196 iwe.u.qual.updated = 7;
197 start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
200 iwe.cmd = IWEVCUSTOM;
202 iwe.u.data.length = p - custom;
203 if (iwe.u.data.length)
204 start = iwe_stream_add_point_rsl(info, start, stop,
207 memset(&iwe, 0, sizeof(iwe));
208 if (network->wpa_ie_len) {
209 char buf[MAX_WPA_IE_LEN];
211 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
213 iwe.u.data.length = network->wpa_ie_len;
214 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
216 memset(&iwe, 0, sizeof(iwe));
217 if (network->rsn_ie_len) {
218 char buf[MAX_WPA_IE_LEN];
220 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
222 iwe.u.data.length = network->rsn_ie_len;
223 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
226 /* add info for WZC */
227 memset(&iwe, 0, sizeof(iwe));
228 if (network->wzc_ie_len) {
229 char buf[MAX_WZC_IE_LEN];
231 memcpy(buf, network->wzc_ie, network->wzc_ie_len);
233 iwe.u.data.length = network->wzc_ie_len;
234 start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
237 /* Add EXTRA: Age to display seconds since last beacon/probe response
240 iwe.cmd = IWEVCUSTOM;
242 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
243 " Last beacon: %lums ago",
244 (jiffies - network->last_scanned) / (HZ / 100));
245 iwe.u.data.length = p - custom;
246 if (iwe.u.data.length)
247 start = iwe_stream_add_point_rsl(info, start, stop,
253 int rtllib_wx_get_scan(struct rtllib_device *ieee,
254 struct iw_request_info *info,
255 union iwreq_data *wrqu, char *extra)
257 struct rtllib_network *network;
261 char *stop = ev + wrqu->data.length;
265 netdev_dbg(ieee->dev, "Getting scan\n");
267 spin_lock_irqsave(&ieee->lock, flags);
269 list_for_each_entry(network, &ieee->network_list, list) {
271 if ((stop - ev) < 200) {
275 if (ieee->scan_age == 0 ||
276 time_after(network->last_scanned + ieee->scan_age, jiffies))
277 ev = rtl819x_translate_scan(ieee, ev, stop, network,
280 netdev_dbg(ieee->dev,
281 "Network '%s ( %pM)' hidden due to age (%lums).\n",
282 escape_essid(network->ssid,
285 (jiffies - network->last_scanned) /
289 spin_unlock_irqrestore(&ieee->lock, flags);
291 wrqu->data.length = ev - extra;
292 wrqu->data.flags = 0;
294 netdev_dbg(ieee->dev, "%s(): %d networks returned.\n", __func__, i);
298 EXPORT_SYMBOL(rtllib_wx_get_scan);
300 int rtllib_wx_set_encode(struct rtllib_device *ieee,
301 struct iw_request_info *info,
302 union iwreq_data *wrqu, char *keybuf)
304 struct iw_point *erq = &(wrqu->encoding);
305 struct net_device *dev = ieee->dev;
306 struct rtllib_security sec = {
309 int i, key, key_provided, len;
310 struct lib80211_crypt_data **crypt;
312 netdev_dbg(ieee->dev, "%s()\n", __func__);
314 key = erq->flags & IW_ENCODE_INDEX;
316 if (key > NUM_WEP_KEYS)
322 key = ieee->crypt_info.tx_keyidx;
325 netdev_dbg(ieee->dev, "Key: %d [%s]\n", key, key_provided ?
326 "provided" : "default");
327 crypt = &ieee->crypt_info.crypt[key];
328 if (erq->flags & IW_ENCODE_DISABLED) {
329 if (key_provided && *crypt) {
330 netdev_dbg(ieee->dev,
331 "Disabling encryption on key %d.\n", key);
332 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
334 netdev_dbg(ieee->dev, "Disabling encryption.\n");
336 /* Check all the keys to see if any are still configured,
337 * and if no key index was provided, de-init them all
339 for (i = 0; i < NUM_WEP_KEYS; i++) {
340 if (ieee->crypt_info.crypt[i] != NULL) {
343 lib80211_crypt_delayed_deinit(&ieee->crypt_info,
344 &ieee->crypt_info.crypt[i]);
348 if (i == NUM_WEP_KEYS) {
350 sec.level = SEC_LEVEL_0;
351 sec.flags |= SEC_ENABLED | SEC_LEVEL;
360 sec.flags |= SEC_ENABLED;
362 if (*crypt != NULL && (*crypt)->ops != NULL &&
363 strcmp((*crypt)->ops->name, "R-WEP") != 0) {
364 /* changing to use WEP; deinit previously used algorithm
367 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
370 if (*crypt == NULL) {
371 struct lib80211_crypt_data *new_crypt;
373 /* take WEP into use */
374 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
376 if (new_crypt == NULL)
378 new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
379 if (!new_crypt->ops) {
380 request_module("rtllib_crypt_wep");
381 new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
385 new_crypt->priv = new_crypt->ops->init(key);
387 if (!new_crypt->ops || !new_crypt->priv) {
392 "%s: could not initialize WEP: load module rtllib_crypt_wep\n",
399 /* If a new key was provided, set it up */
400 if (erq->length > 0) {
401 len = erq->length <= 5 ? 5 : 13;
402 memcpy(sec.keys[key], keybuf, erq->length);
403 if (len > erq->length)
404 memset(sec.keys[key] + erq->length, 0,
406 netdev_dbg(ieee->dev, "Setting key %d to '%s' (%d:%d bytes)\n",
407 key, escape_essid(sec.keys[key], len), erq->length,
409 sec.key_sizes[key] = len;
410 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
412 sec.flags |= (1 << key);
413 /* This ensures a key will be activated if no key is
416 if (key == sec.active_key)
417 sec.flags |= SEC_ACTIVE_KEY;
418 ieee->crypt_info.tx_keyidx = key;
421 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
422 NULL, (*crypt)->priv);
424 /* Set a default key of all 0 */
425 netdev_info(ieee->dev, "Setting key %d to all zero.\n",
428 memset(sec.keys[key], 0, 13);
429 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
431 sec.key_sizes[key] = 13;
432 sec.flags |= (1 << key);
435 /* No key data - just set the default TX key index */
437 netdev_dbg(ieee->dev,
438 "Setting key %d as default Tx key.\n", key);
439 ieee->crypt_info.tx_keyidx = key;
440 sec.active_key = key;
441 sec.flags |= SEC_ACTIVE_KEY;
445 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
446 ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
447 WLAN_AUTH_SHARED_KEY;
448 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
449 sec.flags |= SEC_AUTH_MODE;
450 netdev_dbg(ieee->dev, "Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
451 "OPEN" : "SHARED KEY");
453 /* For now we just support WEP, so only set that security level...
454 * TODO: When WPA is added this is one place that needs to change
456 sec.flags |= SEC_LEVEL;
457 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
459 if (ieee->set_security)
460 ieee->set_security(dev, &sec);
462 /* Do not reset port if card is in Managed mode since resetting will
463 * generate new IEEE 802.11 authentication which may end up in looping
464 * with IEEE 802.1X. If your hardware requires a reset after WEP
465 * configuration (for example... Prism2), implement the reset_port in
466 * the callbacks structures used to initialize the 802.11 stack.
468 if (ieee->reset_on_keychange &&
469 ieee->iw_mode != IW_MODE_INFRA &&
470 ieee->reset_port && ieee->reset_port(dev)) {
471 netdev_dbg(dev, "%s: reset_port failed\n", dev->name);
476 EXPORT_SYMBOL(rtllib_wx_set_encode);
478 int rtllib_wx_get_encode(struct rtllib_device *ieee,
479 struct iw_request_info *info,
480 union iwreq_data *wrqu, char *keybuf)
482 struct iw_point *erq = &(wrqu->encoding);
484 struct lib80211_crypt_data *crypt;
486 netdev_dbg(ieee->dev, "%s()\n", __func__);
488 if (ieee->iw_mode == IW_MODE_MONITOR)
491 key = erq->flags & IW_ENCODE_INDEX;
493 if (key > NUM_WEP_KEYS)
497 key = ieee->crypt_info.tx_keyidx;
499 crypt = ieee->crypt_info.crypt[key];
501 erq->flags = key + 1;
503 if (crypt == NULL || crypt->ops == NULL) {
505 erq->flags |= IW_ENCODE_DISABLED;
508 len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
510 erq->length = max(len, 0);
512 erq->flags |= IW_ENCODE_ENABLED;
515 erq->flags |= IW_ENCODE_OPEN;
517 erq->flags |= IW_ENCODE_RESTRICTED;
521 EXPORT_SYMBOL(rtllib_wx_get_encode);
523 int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
524 struct iw_request_info *info,
525 union iwreq_data *wrqu, char *extra)
528 struct net_device *dev = ieee->dev;
529 struct iw_point *encoding = &wrqu->encoding;
530 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
533 const char *alg, *module;
534 struct lib80211_crypto_ops *ops;
535 struct lib80211_crypt_data **crypt;
537 struct rtllib_security sec = {
540 idx = encoding->flags & IW_ENCODE_INDEX;
542 if (idx < 1 || idx > NUM_WEP_KEYS)
546 idx = ieee->crypt_info.tx_keyidx;
548 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
549 crypt = &ieee->crypt_info.crypt[idx];
552 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
553 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
555 if (ieee->iw_mode == IW_MODE_INFRA)
556 crypt = &ieee->crypt_info.crypt[idx];
561 sec.flags |= SEC_ENABLED;
562 if ((encoding->flags & IW_ENCODE_DISABLED) ||
563 ext->alg == IW_ENCODE_ALG_NONE) {
565 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
567 for (i = 0; i < NUM_WEP_KEYS; i++) {
568 if (ieee->crypt_info.crypt[i] != NULL)
571 if (i == NUM_WEP_KEYS) {
573 sec.level = SEC_LEVEL_0;
574 sec.flags |= SEC_LEVEL;
581 case IW_ENCODE_ALG_WEP:
583 module = "rtllib_crypt_wep";
585 case IW_ENCODE_ALG_TKIP:
587 module = "rtllib_crypt_tkip";
589 case IW_ENCODE_ALG_CCMP:
591 module = "rtllib_crypt_ccmp";
594 netdev_dbg(ieee->dev, "Unknown crypto alg %d\n", ext->alg);
598 netdev_info(dev, "alg name:%s\n", alg);
600 ops = lib80211_get_crypto_ops(alg);
604 memset(tempbuf, 0x00, 100);
605 sprintf(tempbuf, "%s", module);
606 request_module("%s", tempbuf);
607 ops = lib80211_get_crypto_ops(alg);
610 netdev_info(dev, "========>unknown crypto alg %d\n", ext->alg);
615 if (*crypt == NULL || (*crypt)->ops != ops) {
616 struct lib80211_crypt_data *new_crypt;
618 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
620 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
621 if (new_crypt == NULL) {
625 new_crypt->ops = ops;
627 new_crypt->priv = new_crypt->ops->init(idx);
629 if (new_crypt->priv == NULL) {
638 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
639 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
640 (*crypt)->priv) < 0) {
641 netdev_info(dev, "key setting failed\n");
645 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
646 ieee->crypt_info.tx_keyidx = idx;
647 sec.active_key = idx;
648 sec.flags |= SEC_ACTIVE_KEY;
650 if (ext->alg != IW_ENCODE_ALG_NONE) {
651 sec.key_sizes[idx] = ext->key_len;
652 sec.flags |= (1 << idx);
653 if (ext->alg == IW_ENCODE_ALG_WEP) {
654 sec.flags |= SEC_LEVEL;
655 sec.level = SEC_LEVEL_1;
656 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
657 sec.flags |= SEC_LEVEL;
658 sec.level = SEC_LEVEL_2;
659 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
660 sec.flags |= SEC_LEVEL;
661 sec.level = SEC_LEVEL_3;
663 /* Don't set sec level for group keys. */
665 sec.flags &= ~SEC_LEVEL;
668 if (ieee->set_security)
669 ieee->set_security(ieee->dev, &sec);
671 if (ieee->reset_on_keychange &&
672 ieee->iw_mode != IW_MODE_INFRA &&
673 ieee->reset_port && ieee->reset_port(dev)) {
674 netdev_dbg(ieee->dev, "Port reset failed\n");
679 EXPORT_SYMBOL(rtllib_wx_set_encode_ext);
681 int rtllib_wx_set_mlme(struct rtllib_device *ieee,
682 struct iw_request_info *info,
683 union iwreq_data *wrqu, char *extra)
687 struct iw_mlme *mlme = (struct iw_mlme *) extra;
689 if (ieee->state != RTLLIB_LINKED)
697 /* leave break out intentionly */
699 case IW_MLME_DISASSOC:
701 netdev_info(ieee->dev, "disauth packet !\n");
703 netdev_info(ieee->dev, "dis associate packet!\n");
705 ieee->cannot_notify = true;
707 SendDisassociation(ieee, deauth, mlme->reason_code);
708 rtllib_disassociate(ieee);
711 for (i = 0; i < 6; i++)
712 ieee->current_network.bssid[i] = 0x55;
715 ieee->current_network.ssid[0] = '\0';
716 ieee->current_network.ssid_len = 0;
727 EXPORT_SYMBOL(rtllib_wx_set_mlme);
729 int rtllib_wx_set_auth(struct rtllib_device *ieee,
730 struct iw_request_info *info,
731 struct iw_param *data, char *extra)
733 switch (data->flags & IW_AUTH_INDEX) {
734 case IW_AUTH_WPA_VERSION:
736 case IW_AUTH_CIPHER_PAIRWISE:
737 case IW_AUTH_CIPHER_GROUP:
738 case IW_AUTH_KEY_MGMT:
739 /* Host AP driver does not use these parameters and allows
740 * wpa_supplicant to control them internally.
743 case IW_AUTH_TKIP_COUNTERMEASURES:
744 ieee->tkip_countermeasures = data->value;
746 case IW_AUTH_DROP_UNENCRYPTED:
747 ieee->drop_unencrypted = data->value;
750 case IW_AUTH_80211_AUTH_ALG:
751 if (data->value & IW_AUTH_ALG_SHARED_KEY) {
754 } else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) {
757 } else if (data->value & IW_AUTH_ALG_LEAP) {
764 case IW_AUTH_WPA_ENABLED:
765 ieee->wpa_enabled = (data->value) ? 1 : 0;
768 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
769 ieee->ieee802_1x = data->value;
771 case IW_AUTH_PRIVACY_INVOKED:
772 ieee->privacy_invoked = data->value;
779 EXPORT_SYMBOL(rtllib_wx_set_auth);
781 int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
784 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
786 if (len > MAX_WPA_IE_LEN || (len && ie == NULL))
791 if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2],
794 ieee->wps_ie_len = min_t(size_t, len, MAX_WZC_IE_LEN);
795 buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL);
802 ieee->wps_ie_len = 0;
808 buf = kmemdup(ie, len, GFP_KERNEL);
813 ieee->wpa_ie_len = len;
817 ieee->wpa_ie_len = 0;
821 EXPORT_SYMBOL(rtllib_wx_set_gen_ie);