// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright(c) 2004 Intel Corporation. All rights reserved.
 *
 * Portions of this file are based on the WEP enablement code provided by the
 * Host AP project hostap-drivers v0.1.3
 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
 * <jkmaline@cc.hut.fi>
 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
 *
 * Contact Information:
 * James P. Ketrenos <ipw2100-admin@linux.intel.com>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 */
#include <linux/wireless.h>
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/etherdevice.h>
#include "rtllib.h"

static const char * const rtllib_modes[] = {
	"a", "b", "g", "?", "N-24G", "N-5G"
};

#define MAX_CUSTOM_LEN 64
static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
					   char *start, char *stop,
					   struct rtllib_network *network,
					   struct iw_request_info *info)
{
	char custom[MAX_CUSTOM_LEN];
	char proto_name[IFNAMSIZ];
	char *pname = proto_name;
	char *p;
	struct iw_event iwe;
	int i, j;
	u16 max_rate, rate;
	static u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};

	/* First entry *MUST* be the AP MAC address */
	iwe.cmd = SIOCGIWAP;
	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
	ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid);
	start = iwe_stream_add_event_rsl(info, start, stop,
					 &iwe, IW_EV_ADDR_LEN);
	/* Remaining entries will be displayed in the order we provide them */

	/* Add the ESSID */
	iwe.cmd = SIOCGIWESSID;
	iwe.u.data.flags = 1;
	if (network->ssid_len > 0) {
		iwe.u.data.length = min_t(u8, network->ssid_len, 32);
		start = iwe_stream_add_point_rsl(info, start, stop, &iwe,
						 network->ssid);
	} else if (network->hidden_ssid_len == 0) {
		iwe.u.data.length = sizeof("<hidden>");
		start = iwe_stream_add_point_rsl(info, start, stop,
						 &iwe, "<hidden>");
	} else {
		iwe.u.data.length = min_t(u8, network->hidden_ssid_len, 32);
		start = iwe_stream_add_point_rsl(info, start, stop, &iwe,
						 network->hidden_ssid);
	}
	/* Add the protocol name */
	iwe.cmd = SIOCGIWNAME;
	for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) {
		if (network->mode & BIT(i)) {
			strcpy(pname, rtllib_modes[i]);
			pname += strlen(rtllib_modes[i]);
		}
	}
	*pname = '\0';
	snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
	start = iwe_stream_add_event_rsl(info, start, stop,
					 &iwe, IW_EV_CHAR_LEN);
	/* Add mode */
	iwe.cmd = SIOCGIWMODE;
	if (network->capability &
	    (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
		if (network->capability & WLAN_CAPABILITY_ESS)
			iwe.u.mode = IW_MODE_MASTER;
		else
			iwe.u.mode = IW_MODE_ADHOC;
		start = iwe_stream_add_event_rsl(info, start, stop,
						 &iwe, IW_EV_UINT_LEN);
	}

	/* Add frequency/channel */
	iwe.cmd = SIOCGIWFREQ;
	iwe.u.freq.m = network->channel;
	iwe.u.freq.e = 0;
	iwe.u.freq.i = 0;
	start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
					 IW_EV_FREQ_LEN);

	/* Add encryption capability */
	iwe.cmd = SIOCGIWENCODE;
	if (network->capability & WLAN_CAPABILITY_PRIVACY)
		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
	else
		iwe.u.data.flags = IW_ENCODE_DISABLED;
	iwe.u.data.length = 0;
	start = iwe_stream_add_point_rsl(info, start, stop,
					 &iwe, network->ssid);
	/* Add basic and extended rates */
	max_rate = 0;
	p = custom;
	p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
	for (i = 0, j = 0; i < network->rates_len;) {
		if (j < network->rates_ex_len &&
		    ((network->rates_ex[j] & 0x7F) <
		     (network->rates[i] & 0x7F)))
			rate = network->rates_ex[j++] & 0x7F;
		else
			rate = network->rates[i++] & 0x7F;
		if (rate > max_rate)
			max_rate = rate;
		p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
	}
	for (; j < network->rates_ex_len; j++) {
		rate = network->rates_ex[j] & 0x7F;
		p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
		if (rate > max_rate)
			max_rate = rate;
	}

	if (network->mode >= IEEE_N_24G) {
		struct ht_capab_ele *ht_cap = NULL;
		bool is40M = false, isShortGI = false;
		u8 max_mcs = 0;

		if (!memcmp(network->bssht.bd_ht_cap_buf, EWC11NHTCap, 4))
			ht_cap = (struct ht_capab_ele *)
				 &network->bssht.bd_ht_cap_buf[4];
		else
			ht_cap = (struct ht_capab_ele *)
				 &network->bssht.bd_ht_cap_buf[0];
		is40M = (ht_cap->ChlWidth) ? 1 : 0;
		isShortGI = (ht_cap->ChlWidth) ?
				((ht_cap->ShortGI40Mhz) ? 1 : 0) :
				((ht_cap->ShortGI20Mhz) ? 1 : 0);

		max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS,
					      MCS_FILTER_ALL);
		rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f];
		if (rate > max_rate)
			max_rate = rate;
	}
	iwe.cmd = SIOCGIWRATE;
	iwe.u.bitrate.disabled = 0;
	iwe.u.bitrate.fixed = 0;
	iwe.u.bitrate.value = max_rate * 500000;
	start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_PARAM_LEN);
	iwe.cmd = IWEVCUSTOM;
	iwe.u.data.length = p - custom;
	if (iwe.u.data.length)
		start = iwe_stream_add_point_rsl(info, start, stop,
						 &iwe, custom);
	/* Add quality statistics */
	/* TODO: Fix these values... */
	iwe.cmd = IWEVQUAL;
	iwe.u.qual.qual = network->stats.signal;
	iwe.u.qual.level = network->stats.rssi;
	iwe.u.qual.noise = network->stats.noise;
	iwe.u.qual.updated = network->stats.mask & RTLLIB_STATMASK_WEMASK;
	if (!(network->stats.mask & RTLLIB_STATMASK_RSSI))
		iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
	if (!(network->stats.mask & RTLLIB_STATMASK_NOISE))
		iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
	if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL))
		iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
	iwe.u.qual.updated = 7;
	start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);

	iwe.cmd = IWEVCUSTOM;
	p = custom;
	iwe.u.data.length = p - custom;
	if (iwe.u.data.length)
		start = iwe_stream_add_point_rsl(info, start, stop, &iwe, custom);

	memset(&iwe, 0, sizeof(iwe));
	if (network->wpa_ie_len) {
		char buf[MAX_WPA_IE_LEN];

		memcpy(buf, network->wpa_ie, network->wpa_ie_len);
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = network->wpa_ie_len;
		start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
	}
	memset(&iwe, 0, sizeof(iwe));
	if (network->rsn_ie_len) {
		char buf[MAX_WPA_IE_LEN];

		memcpy(buf, network->rsn_ie, network->rsn_ie_len);
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = network->rsn_ie_len;
		start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
	}

	/* add info for WZC */
	memset(&iwe, 0, sizeof(iwe));
	if (network->wzc_ie_len) {
		char buf[MAX_WZC_IE_LEN];

		memcpy(buf, network->wzc_ie, network->wzc_ie_len);
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = network->wzc_ie_len;
		start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
	}

	/* Add EXTRA: Age to display seconds since last beacon/probe response
	 * for given network.
	 */
	iwe.cmd = IWEVCUSTOM;
	p = custom;
	p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
		      " Last beacon: %lums ago",
		      (jiffies - network->last_scanned) / (HZ / 100));
	iwe.u.data.length = p - custom;
	if (iwe.u.data.length)
		start = iwe_stream_add_point_rsl(info, start, stop,
						 &iwe, custom);

	return start;
}

int rtllib_wx_get_scan(struct rtllib_device *ieee,
		       struct iw_request_info *info,
		       union iwreq_data *wrqu, char *extra)
{
	struct rtllib_network *network;
	unsigned long flags;

	char *ev = extra;
	char *stop = ev + wrqu->data.length;
	int i = 0;
	int err = 0;

	netdev_dbg(ieee->dev, "Getting scan\n");
	mutex_lock(&ieee->wx_mutex);
	spin_lock_irqsave(&ieee->lock, flags);

	list_for_each_entry(network, &ieee->network_list, list) {
		i++;
		if ((stop - ev) < 200) {
			err = -E2BIG;
			break;
		}
		if (ieee->scan_age == 0 ||
		    time_after(network->last_scanned + ieee->scan_age, jiffies))
			ev = rtl819x_translate_scan(ieee, ev, stop, network,
						    info);
		else
			netdev_dbg(ieee->dev,
				   "Network '%s ( %pM)' hidden due to age (%lums).\n",
				   escape_essid(network->ssid,
						network->ssid_len),
				   network->bssid,
				   (jiffies - network->last_scanned) /
				   (HZ / 100));
	}

	spin_unlock_irqrestore(&ieee->lock, flags);
	mutex_unlock(&ieee->wx_mutex);
	wrqu->data.length = ev -  extra;
	wrqu->data.flags = 0;

	netdev_dbg(ieee->dev, "%s(): %d networks returned.\n", __func__, i);

	return err;
}
EXPORT_SYMBOL(rtllib_wx_get_scan);

int rtllib_wx_set_encode(struct rtllib_device *ieee,
			 struct iw_request_info *info,
			 union iwreq_data *wrqu, char *keybuf)
{
	struct iw_point *erq = &wrqu->encoding;
	struct net_device *dev = ieee->dev;
	struct rtllib_security sec = {
		.flags = 0
	};
	int i, key, key_provided, len;
	struct lib80211_crypt_data **crypt;

	key = erq->flags & IW_ENCODE_INDEX;
	if (key) {
		if (key > NUM_WEP_KEYS)
			return -EINVAL;
		key--;
		key_provided = 1;
	} else {
		key_provided = 0;
		key = ieee->crypt_info.tx_keyidx;
	}

	netdev_dbg(ieee->dev, "Key: %d [%s]\n", key, key_provided ?
			   "provided" : "default");
	crypt = &ieee->crypt_info.crypt[key];
	if (erq->flags & IW_ENCODE_DISABLED) {
		if (key_provided && *crypt) {
			netdev_dbg(ieee->dev,
				   "Disabling encryption on key %d.\n", key);
			lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
		} else {
			netdev_dbg(ieee->dev, "Disabling encryption.\n");
		}

		/* Check all the keys to see if any are still configured,
		 * and if no key index was provided, de-init them all
		 */
		for (i = 0; i < NUM_WEP_KEYS; i++) {
			if (ieee->crypt_info.crypt[i]) {
				if (key_provided)
					break;
				lib80211_crypt_delayed_deinit(&ieee->crypt_info,
							      &ieee->crypt_info.crypt[i]);
			}
		}

		if (i == NUM_WEP_KEYS) {
			sec.enabled = 0;
			sec.level = SEC_LEVEL_0;
			sec.flags |= SEC_ENABLED | SEC_LEVEL;
		}

		goto done;
	}

	sec.enabled = 1;
	sec.flags |= SEC_ENABLED;

	if (*crypt && (*crypt)->ops &&
	    strcmp((*crypt)->ops->name, "R-WEP") != 0) {
		/* changing to use WEP; deinit previously used algorithm
		 * on this key
		 */
		lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
	}

	if (!*crypt) {
		struct lib80211_crypt_data *new_crypt;

		/* take WEP into use */
		new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
		if (!new_crypt)
			return -ENOMEM;
		new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
		if (!new_crypt->ops) {
			request_module("rtllib_crypt_wep");
			new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
		}

		if (new_crypt->ops)
			new_crypt->priv = new_crypt->ops->init(key);

		if (!new_crypt->ops || !new_crypt->priv) {
			kfree(new_crypt);
			new_crypt = NULL;

			netdev_warn(dev,
				    "%s: could not initialize WEP: load module rtllib_crypt_wep\n",
				    dev->name);
			return -EOPNOTSUPP;
		}
		*crypt = new_crypt;
	}

	/* If a new key was provided, set it up */
	if (erq->length > 0) {
		len = erq->length <= 5 ? 5 : 13;
		memcpy(sec.keys[key], keybuf, erq->length);
		if (len > erq->length)
			memset(sec.keys[key] + erq->length, 0,
			       len - erq->length);
		netdev_dbg(ieee->dev, "Setting key %d to '%s' (%d:%d bytes)\n",
			   key, escape_essid(sec.keys[key], len), erq->length,
			   len);
		sec.key_sizes[key] = len;
		(*crypt)->ops->set_key(sec.keys[key], len, NULL,
				       (*crypt)->priv);
		sec.flags |= (1 << key);
		/* This ensures a key will be activated if no key is
		 * explicitly set
		 */
		if (key == sec.active_key)
			sec.flags |= SEC_ACTIVE_KEY;
		ieee->crypt_info.tx_keyidx = key;

	} else {
		len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
					     NULL, (*crypt)->priv);
		if (len == 0) {
			/* Set a default key of all 0 */
			netdev_info(ieee->dev, "Setting key %d to all zero.\n", key);

			memset(sec.keys[key], 0, 13);
			(*crypt)->ops->set_key(sec.keys[key], 13, NULL,
					       (*crypt)->priv);
			sec.key_sizes[key] = 13;
			sec.flags |= (1 << key);
		}

		/* No key data - just set the default TX key index */
		if (key_provided) {
			netdev_dbg(ieee->dev,
				   "Setting key %d as default Tx key.\n", key);
			ieee->crypt_info.tx_keyidx = key;
			sec.active_key = key;
			sec.flags |= SEC_ACTIVE_KEY;
		}
	}
 done:
	ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
	ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
			  WLAN_AUTH_SHARED_KEY;
	sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
	sec.flags |= SEC_AUTH_MODE;
	netdev_dbg(ieee->dev, "Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
			   "OPEN" : "SHARED KEY");

	/* For now we just support WEP, so only set that security level...
	 * TODO: When WPA is added this is one place that needs to change
	 */
	sec.flags |= SEC_LEVEL;
	sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */

	if (ieee->set_security)
		ieee->set_security(dev, &sec);

	/* Do not reset port if card is in Managed mode since resetting will
	 * generate new IEEE 802.11 authentication which may end up in looping
	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
	 * configuration (for example... Prism2), implement the reset_port in
	 * the callbacks structures used to initialize the 802.11 stack.
	 */
	if (ieee->reset_on_keychange &&
	    ieee->iw_mode != IW_MODE_INFRA &&
	    ieee->reset_port && ieee->reset_port(dev)) {
		netdev_dbg(dev, "%s: reset_port failed\n", dev->name);
		return -EINVAL;
	}
	return 0;
}
EXPORT_SYMBOL(rtllib_wx_set_encode);

int rtllib_wx_get_encode(struct rtllib_device *ieee,
			 struct iw_request_info *info,
			 union iwreq_data *wrqu, char *keybuf)
{
	struct iw_point *erq = &wrqu->encoding;
	int len, key;
	struct lib80211_crypt_data *crypt;

	if (ieee->iw_mode == IW_MODE_MONITOR)
		return -1;

	key = erq->flags & IW_ENCODE_INDEX;
	if (key) {
		if (key > NUM_WEP_KEYS)
			return -EINVAL;
		key--;
	} else {
		key = ieee->crypt_info.tx_keyidx;
	}
	crypt = ieee->crypt_info.crypt[key];

	erq->flags = key + 1;

	if (!crypt || !crypt->ops) {
		erq->length = 0;
		erq->flags |= IW_ENCODE_DISABLED;
		return 0;
	}
	len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);

	erq->length = max(len, 0);

	erq->flags |= IW_ENCODE_ENABLED;

	if (ieee->open_wep)
		erq->flags |= IW_ENCODE_OPEN;
	else
		erq->flags |= IW_ENCODE_RESTRICTED;

	return 0;
}
EXPORT_SYMBOL(rtllib_wx_get_encode);

int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
			     struct iw_request_info *info,
			     union iwreq_data *wrqu, char *extra)
{
	int ret = 0;
	struct net_device *dev = ieee->dev;
	struct iw_point *encoding = &wrqu->encoding;
	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
	int i, idx;
	int group_key = 0;
	const char *alg, *module;
	struct lib80211_crypto_ops *ops;
	struct lib80211_crypt_data **crypt;

	struct rtllib_security sec = {
		.flags = 0,
	};
	idx = encoding->flags & IW_ENCODE_INDEX;
	if (idx) {
		if (idx < 1 || idx > NUM_WEP_KEYS)
			return -EINVAL;
		idx--;
	} else {
		idx = ieee->crypt_info.tx_keyidx;
	}
	if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
		crypt = &ieee->crypt_info.crypt[idx];
		group_key = 1;
	} else {
		/* some Cisco APs use idx>0 for unicast in dynamic WEP */
		if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
			return -EINVAL;
		if (ieee->iw_mode == IW_MODE_INFRA)
			crypt = &ieee->crypt_info.crypt[idx];
		else
			return -EINVAL;
	}

	sec.flags |= SEC_ENABLED;
	if ((encoding->flags & IW_ENCODE_DISABLED) ||
	    ext->alg == IW_ENCODE_ALG_NONE) {
		if (*crypt)
			lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);

		for (i = 0; i < NUM_WEP_KEYS; i++) {
			if (ieee->crypt_info.crypt[i])
				break;
		}
		if (i == NUM_WEP_KEYS) {
			sec.enabled = 0;
			sec.level = SEC_LEVEL_0;
			sec.flags |= SEC_LEVEL;
		}
		goto done;
	}

	sec.enabled = 1;
	switch (ext->alg) {
	case IW_ENCODE_ALG_WEP:
		alg = "R-WEP";
		module = "rtllib_crypt_wep";
		break;
	case IW_ENCODE_ALG_TKIP:
		alg = "R-TKIP";
		module = "rtllib_crypt_tkip";
		break;
	case IW_ENCODE_ALG_CCMP:
		alg = "R-CCMP";
		module = "rtllib_crypt_ccmp";
		break;
	default:
		netdev_dbg(ieee->dev, "Unknown crypto alg %d\n", ext->alg);
		ret = -EINVAL;
		goto done;
	}
	netdev_dbg(dev, "alg name:%s\n", alg);

	ops = lib80211_get_crypto_ops(alg);
	if (!ops) {
		char tempbuf[100];

		memset(tempbuf, 0x00, 100);
		sprintf(tempbuf, "%s", module);
		request_module("%s", tempbuf);
		ops = lib80211_get_crypto_ops(alg);
	}
	if (!ops) {
		netdev_info(dev, "========>unknown crypto alg %d\n", ext->alg);
		ret = -EINVAL;
		goto done;
	}

	if (!*crypt || (*crypt)->ops != ops) {
		struct lib80211_crypt_data *new_crypt;

		lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);

		new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
		if (!new_crypt) {
			ret = -ENOMEM;
			goto done;
		}
		new_crypt->ops = ops;
		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
			new_crypt->priv = new_crypt->ops->init(idx);

		if (!new_crypt->priv) {
			kfree(new_crypt);
			ret = -EINVAL;
			goto done;
		}
		*crypt = new_crypt;
	}

	if (ext->key_len > 0 && (*crypt)->ops->set_key &&
	    (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
				   (*crypt)->priv) < 0) {
		netdev_info(dev, "key setting failed\n");
		ret = -EINVAL;
		goto done;
	}
	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
		ieee->crypt_info.tx_keyidx = idx;
		sec.active_key = idx;
		sec.flags |= SEC_ACTIVE_KEY;
	}
	if (ext->alg != IW_ENCODE_ALG_NONE) {
		sec.key_sizes[idx] = ext->key_len;
		sec.flags |= (1 << idx);
		if (ext->alg == IW_ENCODE_ALG_WEP) {
			sec.flags |= SEC_LEVEL;
			sec.level = SEC_LEVEL_1;
		} else if (ext->alg == IW_ENCODE_ALG_TKIP) {
			sec.flags |= SEC_LEVEL;
			sec.level = SEC_LEVEL_2;
		} else if (ext->alg == IW_ENCODE_ALG_CCMP) {
			sec.flags |= SEC_LEVEL;
			sec.level = SEC_LEVEL_3;
		}
		/* Don't set sec level for group keys. */
		if (group_key)
			sec.flags &= ~SEC_LEVEL;
	}
done:
	if (ieee->set_security)
		ieee->set_security(ieee->dev, &sec);

	if (ieee->reset_on_keychange &&
	    ieee->iw_mode != IW_MODE_INFRA &&
	    ieee->reset_port && ieee->reset_port(dev)) {
		netdev_dbg(ieee->dev, "Port reset failed\n");
		return -EINVAL;
	}
	return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_encode_ext);

int rtllib_wx_set_mlme(struct rtllib_device *ieee,
		       struct iw_request_info *info,
		       union iwreq_data *wrqu, char *extra)
{
	u8 i = 0;
	bool deauth = false;
	struct iw_mlme *mlme = (struct iw_mlme *)extra;

	if (ieee->state != RTLLIB_LINKED)
		return -ENOLINK;

	mutex_lock(&ieee->wx_mutex);

	switch (mlme->cmd) {
	case IW_MLME_DEAUTH:
		deauth = true;
		fallthrough;
	case IW_MLME_DISASSOC:
		if (deauth)
			netdev_info(ieee->dev, "disauth packet !\n");
		else
			netdev_info(ieee->dev, "dis associate packet!\n");

		ieee->cannot_notify = true;

		SendDisassociation(ieee, deauth, mlme->reason_code);
		rtllib_disassociate(ieee);

		ieee->wap_set = 0;
		for (i = 0; i < 6; i++)
			ieee->current_network.bssid[i] = 0x55;

		ieee->ssid_set = 0;
		ieee->current_network.ssid[0] = '\0';
		ieee->current_network.ssid_len = 0;
		break;
	default:
		mutex_unlock(&ieee->wx_mutex);
		return -EOPNOTSUPP;
	}

	mutex_unlock(&ieee->wx_mutex);

	return 0;
}
EXPORT_SYMBOL(rtllib_wx_set_mlme);

int rtllib_wx_set_auth(struct rtllib_device *ieee,
		       struct iw_request_info *info,
		       struct iw_param *data, char *extra)
{
	switch (data->flags & IW_AUTH_INDEX) {
	case IW_AUTH_WPA_VERSION:
		break;
	case IW_AUTH_CIPHER_PAIRWISE:
	case IW_AUTH_CIPHER_GROUP:
	case IW_AUTH_KEY_MGMT:
		/* Host AP driver does not use these parameters and allows
		 * wpa_supplicant to control them internally.
		 */
		break;
	case IW_AUTH_TKIP_COUNTERMEASURES:
		ieee->tkip_countermeasures = data->value;
		break;
	case IW_AUTH_DROP_UNENCRYPTED:
		ieee->drop_unencrypted = data->value;
		break;

	case IW_AUTH_80211_AUTH_ALG:
		if (data->value & IW_AUTH_ALG_SHARED_KEY) {
			ieee->open_wep = 0;
			ieee->auth_mode = 1;
		} else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) {
			ieee->open_wep = 1;
			ieee->auth_mode = 0;
		} else if (data->value & IW_AUTH_ALG_LEAP) {
			ieee->open_wep = 1;
			ieee->auth_mode = 2;
		} else {
			return -EINVAL;
		}
		break;

	case IW_AUTH_WPA_ENABLED:
		ieee->wpa_enabled = (data->value) ? 1 : 0;
		break;

	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
		ieee->ieee802_1x = data->value;
		break;
	case IW_AUTH_PRIVACY_INVOKED:
		ieee->privacy_invoked = data->value;
		break;
	default:
		return -EOPNOTSUPP;
	}
	return 0;
}
EXPORT_SYMBOL(rtllib_wx_set_auth);

int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
{
	u8 *buf;
	u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};

	if (len > MAX_WPA_IE_LEN || (len && !ie))
		return -EINVAL;

	if (len) {
		eid = ie[0];
		if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2], wps_oui, 4))) {
			ieee->wps_ie_len = min_t(size_t, len, MAX_WZC_IE_LEN);
			buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL);
			if (!buf)
				return -ENOMEM;
			ieee->wps_ie = buf;
			return 0;
		}
	}
	ieee->wps_ie_len = 0;
	kfree(ieee->wps_ie);
	ieee->wps_ie = NULL;
	if (len) {
		if (len != ie[1] + 2)
			return -EINVAL;
		buf = kmemdup(ie, len, GFP_KERNEL);
		if (!buf)
			return -ENOMEM;
		kfree(ieee->wpa_ie);
		ieee->wpa_ie = buf;
		ieee->wpa_ie_len = len;
	} else {
		kfree(ieee->wpa_ie);
		ieee->wpa_ie = NULL;
		ieee->wpa_ie_len = 0;
	}
	return 0;
}
EXPORT_SYMBOL(rtllib_wx_set_gen_ie);
