// SPDX-License-Identifier: GPL-2.0
/*
 * cfg80211 scan result handling
 *
 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 * Copyright 2016	Intel Deutschland GmbH
 * Copyright (C) 2018-2024 Intel Corporation
 */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/nl80211.h>
#include <linux/etherdevice.h>
#include <linux/crc32.h>
#include <linux/bitfield.h>
#include <net/arp.h>
#include <net/cfg80211.h>
#include <net/cfg80211-wext.h>
#include <net/iw_handler.h>
#include <kunit/visibility.h>
#include "core.h"
#include "nl80211.h"
#include "wext-compat.h"
#include "rdev-ops.h"

/**
 * DOC: BSS tree/list structure
 *
 * At the top level, the BSS list is kept in both a list in each
 * registered device (@bss_list) as well as an RB-tree for faster
 * lookup. In the RB-tree, entries can be looked up using their
 * channel, MESHID, MESHCONF (for MBSSes) or channel, BSSID, SSID
 * for other BSSes.
 *
 * Due to the possibility of hidden SSIDs, there's a second level
 * structure, the "hidden_list" and "hidden_beacon_bss" pointer.
 * The hidden_list connects all BSSes belonging to a single AP
 * that has a hidden SSID, and connects beacon and probe response
 * entries. For a probe response entry for a hidden SSID, the
 * hidden_beacon_bss pointer points to the BSS struct holding the
 * beacon's information.
 *
 * Reference counting is done for all these references except for
 * the hidden_list, so that a beacon BSS struct that is otherwise
 * not referenced has one reference for being on the bss_list and
 * one for each probe response entry that points to it using the
 * hidden_beacon_bss pointer. When a BSS struct that has such a
 * pointer is get/put, the refcount update is also propagated to
 * the referenced struct, this ensure that it cannot get removed
 * while somebody is using the probe response version.
 *
 * Note that the hidden_beacon_bss pointer never changes, due to
 * the reference counting. Therefore, no locking is needed for
 * it.
 *
 * Also note that the hidden_beacon_bss pointer is only relevant
 * if the driver uses something other than the IEs, e.g. private
 * data stored in the BSS struct, since the beacon IEs are
 * also linked into the probe response struct.
 */

/*
 * Limit the number of BSS entries stored in mac80211. Each one is
 * a bit over 4k at most, so this limits to roughly 4-5M of memory.
 * If somebody wants to really attack this though, they'd likely
 * use small beacons, and only one type of frame, limiting each of
 * the entries to a much smaller size (in order to generate more
 * entries in total, so overhead is bigger.)
 */
static int bss_entries_limit = 1000;
module_param(bss_entries_limit, int, 0644);
MODULE_PARM_DESC(bss_entries_limit,
                 "limit to number of scan BSS entries (per wiphy, default 1000)");

#define IEEE80211_SCAN_RESULT_EXPIRE	(30 * HZ)

static void bss_free(struct cfg80211_internal_bss *bss)
{
	struct cfg80211_bss_ies *ies;

	if (WARN_ON(atomic_read(&bss->hold)))
		return;

	ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
	if (ies && !bss->pub.hidden_beacon_bss)
		kfree_rcu(ies, rcu_head);
	ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
	if (ies)
		kfree_rcu(ies, rcu_head);

	/*
	 * This happens when the module is removed, it doesn't
	 * really matter any more save for completeness
	 */
	if (!list_empty(&bss->hidden_list))
		list_del(&bss->hidden_list);

	kfree(bss);
}

static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
			       struct cfg80211_internal_bss *bss)
{
	lockdep_assert_held(&rdev->bss_lock);

	bss->refcount++;

	if (bss->pub.hidden_beacon_bss)
		bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;

	if (bss->pub.transmitted_bss)
		bss_from_pub(bss->pub.transmitted_bss)->refcount++;
}

static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
			       struct cfg80211_internal_bss *bss)
{
	lockdep_assert_held(&rdev->bss_lock);

	if (bss->pub.hidden_beacon_bss) {
		struct cfg80211_internal_bss *hbss;

		hbss = bss_from_pub(bss->pub.hidden_beacon_bss);
		hbss->refcount--;
		if (hbss->refcount == 0)
			bss_free(hbss);
	}

	if (bss->pub.transmitted_bss) {
		struct cfg80211_internal_bss *tbss;

		tbss = bss_from_pub(bss->pub.transmitted_bss);
		tbss->refcount--;
		if (tbss->refcount == 0)
			bss_free(tbss);
	}

	bss->refcount--;
	if (bss->refcount == 0)
		bss_free(bss);
}

static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
				  struct cfg80211_internal_bss *bss)
{
	lockdep_assert_held(&rdev->bss_lock);

	if (!list_empty(&bss->hidden_list)) {
		/*
		 * don't remove the beacon entry if it has
		 * probe responses associated with it
		 */
		if (!bss->pub.hidden_beacon_bss)
			return false;
		/*
		 * if it's a probe response entry break its
		 * link to the other entries in the group
		 */
		list_del_init(&bss->hidden_list);
	}

	list_del_init(&bss->list);
	list_del_init(&bss->pub.nontrans_list);
	rb_erase(&bss->rbn, &rdev->bss_tree);
	rdev->bss_entries--;
	WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list),
		  "rdev bss entries[%d]/list[empty:%d] corruption\n",
		  rdev->bss_entries, list_empty(&rdev->bss_list));
	bss_ref_put(rdev, bss);
	return true;
}

bool cfg80211_is_element_inherited(const struct element *elem,
				   const struct element *non_inherit_elem)
{
	u8 id_len, ext_id_len, i, loop_len, id;
	const u8 *list;

	if (elem->id == WLAN_EID_MULTIPLE_BSSID)
		return false;

	if (elem->id == WLAN_EID_EXTENSION && elem->datalen > 1 &&
	    elem->data[0] == WLAN_EID_EXT_EHT_MULTI_LINK)
		return false;

	if (!non_inherit_elem || non_inherit_elem->datalen < 2)
		return true;

	/*
	 * non inheritance element format is:
	 * ext ID (56) | IDs list len | list | extension IDs list len | list
	 * Both lists are optional. Both lengths are mandatory.
	 * This means valid length is:
	 * elem_len = 1 (extension ID) + 2 (list len fields) + list lengths
	 */
	id_len = non_inherit_elem->data[1];
	if (non_inherit_elem->datalen < 3 + id_len)
		return true;

	ext_id_len = non_inherit_elem->data[2 + id_len];
	if (non_inherit_elem->datalen < 3 + id_len + ext_id_len)
		return true;

	if (elem->id == WLAN_EID_EXTENSION) {
		if (!ext_id_len)
			return true;
		loop_len = ext_id_len;
		list = &non_inherit_elem->data[3 + id_len];
		id = elem->data[0];
	} else {
		if (!id_len)
			return true;
		loop_len = id_len;
		list = &non_inherit_elem->data[2];
		id = elem->id;
	}

	for (i = 0; i < loop_len; i++) {
		if (list[i] == id)
			return false;
	}

	return true;
}
EXPORT_SYMBOL(cfg80211_is_element_inherited);

static size_t cfg80211_copy_elem_with_frags(const struct element *elem,
					    const u8 *ie, size_t ie_len,
					    u8 **pos, u8 *buf, size_t buf_len)
{
	if (WARN_ON((u8 *)elem < ie || elem->data > ie + ie_len ||
		    elem->data + elem->datalen > ie + ie_len))
		return 0;

	if (elem->datalen + 2 > buf + buf_len - *pos)
		return 0;

	memcpy(*pos, elem, elem->datalen + 2);
	*pos += elem->datalen + 2;

	/* Finish if it is not fragmented  */
	if (elem->datalen != 255)
		return *pos - buf;

	ie_len = ie + ie_len - elem->data - elem->datalen;
	ie = (const u8 *)elem->data + elem->datalen;

	for_each_element(elem, ie, ie_len) {
		if (elem->id != WLAN_EID_FRAGMENT)
			break;

		if (elem->datalen + 2 > buf + buf_len - *pos)
			return 0;

		memcpy(*pos, elem, elem->datalen + 2);
		*pos += elem->datalen + 2;

		if (elem->datalen != 255)
			break;
	}

	return *pos - buf;
}

VISIBLE_IF_CFG80211_KUNIT size_t
cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
		    const u8 *subie, size_t subie_len,
		    u8 *new_ie, size_t new_ie_len)
{
	const struct element *non_inherit_elem, *parent, *sub;
	u8 *pos = new_ie;
	u8 id, ext_id;
	unsigned int match_len;

	non_inherit_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
						  subie, subie_len);

	/* We copy the elements one by one from the parent to the generated
	 * elements.
	 * If they are not inherited (included in subie or in the non
	 * inheritance element), then we copy all occurrences the first time
	 * we see this element type.
	 */
	for_each_element(parent, ie, ielen) {
		if (parent->id == WLAN_EID_FRAGMENT)
			continue;

		if (parent->id == WLAN_EID_EXTENSION) {
			if (parent->datalen < 1)
				continue;

			id = WLAN_EID_EXTENSION;
			ext_id = parent->data[0];
			match_len = 1;
		} else {
			id = parent->id;
			match_len = 0;
		}

		/* Find first occurrence in subie */
		sub = cfg80211_find_elem_match(id, subie, subie_len,
					       &ext_id, match_len, 0);

		/* Copy from parent if not in subie and inherited */
		if (!sub &&
		    cfg80211_is_element_inherited(parent, non_inherit_elem)) {
			if (!cfg80211_copy_elem_with_frags(parent,
							   ie, ielen,
							   &pos, new_ie,
							   new_ie_len))
				return 0;

			continue;
		}

		/* Already copied if an earlier element had the same type */
		if (cfg80211_find_elem_match(id, ie, (u8 *)parent - ie,
					     &ext_id, match_len, 0))
			continue;

		/* Not inheriting, copy all similar elements from subie */
		while (sub) {
			if (!cfg80211_copy_elem_with_frags(sub,
							   subie, subie_len,
							   &pos, new_ie,
							   new_ie_len))
				return 0;

			sub = cfg80211_find_elem_match(id,
						       sub->data + sub->datalen,
						       subie_len + subie -
						       (sub->data +
							sub->datalen),
						       &ext_id, match_len, 0);
		}
	}

	/* The above misses elements that are included in subie but not in the
	 * parent, so do a pass over subie and append those.
	 * Skip the non-tx BSSID caps and non-inheritance element.
	 */
	for_each_element(sub, subie, subie_len) {
		if (sub->id == WLAN_EID_NON_TX_BSSID_CAP)
			continue;

		if (sub->id == WLAN_EID_FRAGMENT)
			continue;

		if (sub->id == WLAN_EID_EXTENSION) {
			if (sub->datalen < 1)
				continue;

			id = WLAN_EID_EXTENSION;
			ext_id = sub->data[0];
			match_len = 1;

			if (ext_id == WLAN_EID_EXT_NON_INHERITANCE)
				continue;
		} else {
			id = sub->id;
			match_len = 0;
		}

		/* Processed if one was included in the parent */
		if (cfg80211_find_elem_match(id, ie, ielen,
					     &ext_id, match_len, 0))
			continue;

		if (!cfg80211_copy_elem_with_frags(sub, subie, subie_len,
						   &pos, new_ie, new_ie_len))
			return 0;
	}

	return pos - new_ie;
}
EXPORT_SYMBOL_IF_CFG80211_KUNIT(cfg80211_gen_new_ie);

static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
		   const u8 *ssid, size_t ssid_len)
{
	const struct cfg80211_bss_ies *ies;
	const struct element *ssid_elem;

	if (bssid && !ether_addr_equal(a->bssid, bssid))
		return false;

	if (!ssid)
		return true;

	ies = rcu_access_pointer(a->ies);
	if (!ies)
		return false;
	ssid_elem = cfg80211_find_elem(WLAN_EID_SSID, ies->data, ies->len);
	if (!ssid_elem)
		return false;
	if (ssid_elem->datalen != ssid_len)
		return false;
	return memcmp(ssid_elem->data, ssid, ssid_len) == 0;
}

static int
cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
			   struct cfg80211_bss *nontrans_bss)
{
	const struct element *ssid_elem;
	struct cfg80211_bss *bss = NULL;

	rcu_read_lock();
	ssid_elem = ieee80211_bss_get_elem(nontrans_bss, WLAN_EID_SSID);
	if (!ssid_elem) {
		rcu_read_unlock();
		return -EINVAL;
	}

	/* check if nontrans_bss is in the list */
	list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) {
		if (is_bss(bss, nontrans_bss->bssid, ssid_elem->data,
			   ssid_elem->datalen)) {
			rcu_read_unlock();
			return 0;
		}
	}

	rcu_read_unlock();

	/*
	 * This is a bit weird - it's not on the list, but already on another
	 * one! The only way that could happen is if there's some BSSID/SSID
	 * shared by multiple APs in their multi-BSSID profiles, potentially
	 * with hidden SSID mixed in ... ignore it.
	 */
	if (!list_empty(&nontrans_bss->nontrans_list))
		return -EINVAL;

	/* add to the list */
	list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
	return 0;
}

static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev,
				  unsigned long expire_time)
{
	struct cfg80211_internal_bss *bss, *tmp;
	bool expired = false;

	lockdep_assert_held(&rdev->bss_lock);

	list_for_each_entry_safe(bss, tmp, &rdev->bss_list, list) {
		if (atomic_read(&bss->hold))
			continue;
		if (!time_after(expire_time, bss->ts))
			continue;

		if (__cfg80211_unlink_bss(rdev, bss))
			expired = true;
	}

	if (expired)
		rdev->bss_generation++;
}

static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev)
{
	struct cfg80211_internal_bss *bss, *oldest = NULL;
	bool ret;

	lockdep_assert_held(&rdev->bss_lock);

	list_for_each_entry(bss, &rdev->bss_list, list) {
		if (atomic_read(&bss->hold))
			continue;

		if (!list_empty(&bss->hidden_list) &&
		    !bss->pub.hidden_beacon_bss)
			continue;

		if (oldest && time_before(oldest->ts, bss->ts))
			continue;
		oldest = bss;
	}

	if (WARN_ON(!oldest))
		return false;

	/*
	 * The callers make sure to increase rdev->bss_generation if anything
	 * gets removed (and a new entry added), so there's no need to also do
	 * it here.
	 */

	ret = __cfg80211_unlink_bss(rdev, oldest);
	WARN_ON(!ret);
	return ret;
}

static u8 cfg80211_parse_bss_param(u8 data,
				   struct cfg80211_colocated_ap *coloc_ap)
{
	coloc_ap->oct_recommended =
		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_OCT_RECOMMENDED);
	coloc_ap->same_ssid =
		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_SAME_SSID);
	coloc_ap->multi_bss =
		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID);
	coloc_ap->transmitted_bssid =
		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID);
	coloc_ap->unsolicited_probe =
		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE);
	coloc_ap->colocated_ess =
		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_COLOC_ESS);

	return u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_COLOC_AP);
}

static int cfg80211_calc_short_ssid(const struct cfg80211_bss_ies *ies,
				    const struct element **elem, u32 *s_ssid)
{

	*elem = cfg80211_find_elem(WLAN_EID_SSID, ies->data, ies->len);
	if (!*elem || (*elem)->datalen > IEEE80211_MAX_SSID_LEN)
		return -EINVAL;

	*s_ssid = ~crc32_le(~0, (*elem)->data, (*elem)->datalen);
	return 0;
}

VISIBLE_IF_CFG80211_KUNIT void
cfg80211_free_coloc_ap_list(struct list_head *coloc_ap_list)
{
	struct cfg80211_colocated_ap *ap, *tmp_ap;

	list_for_each_entry_safe(ap, tmp_ap, coloc_ap_list, list) {
		list_del(&ap->list);
		kfree(ap);
	}
}
EXPORT_SYMBOL_IF_CFG80211_KUNIT(cfg80211_free_coloc_ap_list);

static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
				  const u8 *pos, u8 length,
				  const struct element *ssid_elem,
				  u32 s_ssid_tmp)
{
	u8 bss_params;

	entry->psd_20 = IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED;

	/* The length is already verified by the caller to contain bss_params */
	if (length > sizeof(struct ieee80211_tbtt_info_7_8_9)) {
		struct ieee80211_tbtt_info_ge_11 *tbtt_info = (void *)pos;

		memcpy(entry->bssid, tbtt_info->bssid, ETH_ALEN);
		entry->short_ssid = le32_to_cpu(tbtt_info->short_ssid);
		entry->short_ssid_valid = true;

		bss_params = tbtt_info->bss_params;

		/* Ignore disabled links */
		if (length >= offsetofend(typeof(*tbtt_info), mld_params)) {
			if (le16_get_bits(tbtt_info->mld_params.params,
					  IEEE80211_RNR_MLD_PARAMS_DISABLED_LINK))
				return -EINVAL;
		}

		if (length >= offsetofend(struct ieee80211_tbtt_info_ge_11,
					  psd_20))
			entry->psd_20 = tbtt_info->psd_20;
	} else {
		struct ieee80211_tbtt_info_7_8_9 *tbtt_info = (void *)pos;

		memcpy(entry->bssid, tbtt_info->bssid, ETH_ALEN);

		bss_params = tbtt_info->bss_params;

		if (length == offsetofend(struct ieee80211_tbtt_info_7_8_9,
					  psd_20))
			entry->psd_20 = tbtt_info->psd_20;
	}

	/* ignore entries with invalid BSSID */
	if (!is_valid_ether_addr(entry->bssid))
		return -EINVAL;

	/* skip non colocated APs */
	if (!cfg80211_parse_bss_param(bss_params, entry))
		return -EINVAL;

	/* no information about the short ssid. Consider the entry valid
	 * for now. It would later be dropped in case there are explicit
	 * SSIDs that need to be matched
	 */
	if (!entry->same_ssid && !entry->short_ssid_valid)
		return 0;

	if (entry->same_ssid) {
		entry->short_ssid = s_ssid_tmp;
		entry->short_ssid_valid = true;

		/*
		 * This is safe because we validate datalen in
		 * cfg80211_parse_colocated_ap(), before calling this
		 * function.
		 */
		memcpy(&entry->ssid, &ssid_elem->data, ssid_elem->datalen);
		entry->ssid_len = ssid_elem->datalen;
	}

	return 0;
}

bool cfg80211_iter_rnr(const u8 *elems, size_t elems_len,
		       enum cfg80211_rnr_iter_ret
		       (*iter)(void *data, u8 type,
			       const struct ieee80211_neighbor_ap_info *info,
			       const u8 *tbtt_info, u8 tbtt_info_len),
		       void *iter_data)
{
	const struct element *rnr;
	const u8 *pos, *end;

	for_each_element_id(rnr, WLAN_EID_REDUCED_NEIGHBOR_REPORT,
			    elems, elems_len) {
		const struct ieee80211_neighbor_ap_info *info;

		pos = rnr->data;
		end = rnr->data + rnr->datalen;

		/* RNR IE may contain more than one NEIGHBOR_AP_INFO */
		while (sizeof(*info) <= end - pos) {
			u8 length, i, count;
			u8 type;

			info = (void *)pos;
			count = u8_get_bits(info->tbtt_info_hdr,
					    IEEE80211_AP_INFO_TBTT_HDR_COUNT) +
				1;
			length = info->tbtt_info_len;

			pos += sizeof(*info);

			if (count * length > end - pos)
				return false;

			type = u8_get_bits(info->tbtt_info_hdr,
					   IEEE80211_AP_INFO_TBTT_HDR_TYPE);

			for (i = 0; i < count; i++) {
				switch (iter(iter_data, type, info,
					     pos, length)) {
				case RNR_ITER_CONTINUE:
					break;
				case RNR_ITER_BREAK:
					return true;
				case RNR_ITER_ERROR:
					return false;
				}

				pos += length;
			}
		}

		if (pos != end)
			return false;
	}

	return true;
}
EXPORT_SYMBOL_GPL(cfg80211_iter_rnr);

struct colocated_ap_data {
	const struct element *ssid_elem;
	struct list_head ap_list;
	u32 s_ssid_tmp;
	int n_coloc;
};

static enum cfg80211_rnr_iter_ret
cfg80211_parse_colocated_ap_iter(void *_data, u8 type,
				 const struct ieee80211_neighbor_ap_info *info,
				 const u8 *tbtt_info, u8 tbtt_info_len)
{
	struct colocated_ap_data *data = _data;
	struct cfg80211_colocated_ap *entry;
	enum nl80211_band band;

	if (type != IEEE80211_TBTT_INFO_TYPE_TBTT)
		return RNR_ITER_CONTINUE;

	if (!ieee80211_operating_class_to_band(info->op_class, &band))
		return RNR_ITER_CONTINUE;

	/* TBTT info must include bss param + BSSID + (short SSID or
	 * same_ssid bit to be set). Ignore other options, and move to
	 * the next AP info
	 */
	if (band != NL80211_BAND_6GHZ ||
	    !(tbtt_info_len == offsetofend(struct ieee80211_tbtt_info_7_8_9,
					   bss_params) ||
	      tbtt_info_len == sizeof(struct ieee80211_tbtt_info_7_8_9) ||
	      tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11,
					   bss_params)))
		return RNR_ITER_CONTINUE;

	entry = kzalloc(sizeof(*entry) + IEEE80211_MAX_SSID_LEN, GFP_ATOMIC);
	if (!entry)
		return RNR_ITER_ERROR;

	entry->center_freq =
		ieee80211_channel_to_frequency(info->channel, band);

	if (!cfg80211_parse_ap_info(entry, tbtt_info, tbtt_info_len,
				    data->ssid_elem, data->s_ssid_tmp)) {
		data->n_coloc++;
		list_add_tail(&entry->list, &data->ap_list);
	} else {
		kfree(entry);
	}

	return RNR_ITER_CONTINUE;
}

VISIBLE_IF_CFG80211_KUNIT int
cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies,
			    struct list_head *list)
{
	struct colocated_ap_data data = {};
	int ret;

	INIT_LIST_HEAD(&data.ap_list);

	ret = cfg80211_calc_short_ssid(ies, &data.ssid_elem, &data.s_ssid_tmp);
	if (ret)
		return 0;

	if (!cfg80211_iter_rnr(ies->data, ies->len,
			       cfg80211_parse_colocated_ap_iter, &data)) {
		cfg80211_free_coloc_ap_list(&data.ap_list);
		return 0;
	}

	list_splice_tail(&data.ap_list, list);
	return data.n_coloc;
}
EXPORT_SYMBOL_IF_CFG80211_KUNIT(cfg80211_parse_colocated_ap);

static  void cfg80211_scan_req_add_chan(struct cfg80211_scan_request *request,
					struct ieee80211_channel *chan,
					bool add_to_6ghz)
{
	int i;
	u32 n_channels = request->n_channels;
	struct cfg80211_scan_6ghz_params *params =
		&request->scan_6ghz_params[request->n_6ghz_params];

	for (i = 0; i < n_channels; i++) {
		if (request->channels[i] == chan) {
			if (add_to_6ghz)
				params->channel_idx = i;
			return;
		}
	}

	request->channels[n_channels] = chan;
	if (add_to_6ghz)
		request->scan_6ghz_params[request->n_6ghz_params].channel_idx =
			n_channels;

	request->n_channels++;
}

static bool cfg80211_find_ssid_match(struct cfg80211_colocated_ap *ap,
				     struct cfg80211_scan_request *request)
{
	int i;
	u32 s_ssid;

	for (i = 0; i < request->n_ssids; i++) {
		/* wildcard ssid in the scan request */
		if (!request->ssids[i].ssid_len) {
			if (ap->multi_bss && !ap->transmitted_bssid)
				continue;

			return true;
		}

		if (ap->ssid_len &&
		    ap->ssid_len == request->ssids[i].ssid_len) {
			if (!memcmp(request->ssids[i].ssid, ap->ssid,
				    ap->ssid_len))
				return true;
		} else if (ap->short_ssid_valid) {
			s_ssid = ~crc32_le(~0, request->ssids[i].ssid,
					   request->ssids[i].ssid_len);

			if (ap->short_ssid == s_ssid)
				return true;
		}
	}

	return false;
}

static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
{
	u8 i;
	struct cfg80211_colocated_ap *ap;
	int n_channels, count = 0, err;
	struct cfg80211_scan_request *request, *rdev_req = rdev->scan_req;
	LIST_HEAD(coloc_ap_list);
	bool need_scan_psc = true;
	const struct ieee80211_sband_iftype_data *iftd;
	size_t size, offs_ssids, offs_6ghz_params, offs_ies;

	rdev_req->scan_6ghz = true;

	if (!rdev->wiphy.bands[NL80211_BAND_6GHZ])
		return -EOPNOTSUPP;

	iftd = ieee80211_get_sband_iftype_data(rdev->wiphy.bands[NL80211_BAND_6GHZ],
					       rdev_req->wdev->iftype);
	if (!iftd || !iftd->he_cap.has_he)
		return -EOPNOTSUPP;

	n_channels = rdev->wiphy.bands[NL80211_BAND_6GHZ]->n_channels;

	if (rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) {
		struct cfg80211_internal_bss *intbss;

		spin_lock_bh(&rdev->bss_lock);
		list_for_each_entry(intbss, &rdev->bss_list, list) {
			struct cfg80211_bss *res = &intbss->pub;
			const struct cfg80211_bss_ies *ies;
			const struct element *ssid_elem;
			struct cfg80211_colocated_ap *entry;
			u32 s_ssid_tmp;
			int ret;

			ies = rcu_access_pointer(res->ies);
			count += cfg80211_parse_colocated_ap(ies,
							     &coloc_ap_list);

			/* In case the scan request specified a specific BSSID
			 * and the BSS is found and operating on 6GHz band then
			 * add this AP to the collocated APs list.
			 * This is relevant for ML probe requests when the lower
			 * band APs have not been discovered.
			 */
			if (is_broadcast_ether_addr(rdev_req->bssid) ||
			    !ether_addr_equal(rdev_req->bssid, res->bssid) ||
			    res->channel->band != NL80211_BAND_6GHZ)
				continue;

			ret = cfg80211_calc_short_ssid(ies, &ssid_elem,
						       &s_ssid_tmp);
			if (ret)
				continue;

			entry = kzalloc(sizeof(*entry) + IEEE80211_MAX_SSID_LEN,
					GFP_ATOMIC);

			if (!entry)
				continue;

			memcpy(entry->bssid, res->bssid, ETH_ALEN);
			entry->short_ssid = s_ssid_tmp;
			memcpy(entry->ssid, ssid_elem->data,
			       ssid_elem->datalen);
			entry->ssid_len = ssid_elem->datalen;
			entry->short_ssid_valid = true;
			entry->center_freq = res->channel->center_freq;

			list_add_tail(&entry->list, &coloc_ap_list);
			count++;
		}
		spin_unlock_bh(&rdev->bss_lock);
	}

	size = struct_size(request, channels, n_channels);
	offs_ssids = size;
	size += sizeof(*request->ssids) * rdev_req->n_ssids;
	offs_6ghz_params = size;
	size += sizeof(*request->scan_6ghz_params) * count;
	offs_ies = size;
	size += rdev_req->ie_len;

	request = kzalloc(size, GFP_KERNEL);
	if (!request) {
		cfg80211_free_coloc_ap_list(&coloc_ap_list);
		return -ENOMEM;
	}

	*request = *rdev_req;
	request->n_channels = 0;
	request->n_6ghz_params = 0;
	if (rdev_req->n_ssids) {
		/*
		 * Add the ssids from the parent scan request to the new
		 * scan request, so the driver would be able to use them
		 * in its probe requests to discover hidden APs on PSC
		 * channels.
		 */
		request->ssids = (void *)request + offs_ssids;
		memcpy(request->ssids, rdev_req->ssids,
		       sizeof(*request->ssids) * request->n_ssids);
	}
	request->scan_6ghz_params = (void *)request + offs_6ghz_params;

	if (rdev_req->ie_len) {
		void *ie = (void *)request + offs_ies;

		memcpy(ie, rdev_req->ie, rdev_req->ie_len);
		request->ie = ie;
	}

	/*
	 * PSC channels should not be scanned in case of direct scan with 1 SSID
	 * and at least one of the reported co-located APs with same SSID
	 * indicating that all APs in the same ESS are co-located
	 */
	if (count && request->n_ssids == 1 && request->ssids[0].ssid_len) {
		list_for_each_entry(ap, &coloc_ap_list, list) {
			if (ap->colocated_ess &&
			    cfg80211_find_ssid_match(ap, request)) {
				need_scan_psc = false;
				break;
			}
		}
	}

	/*
	 * add to the scan request the channels that need to be scanned
	 * regardless of the collocated APs (PSC channels or all channels
	 * in case that NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set)
	 */
	for (i = 0; i < rdev_req->n_channels; i++) {
		if (rdev_req->channels[i]->band == NL80211_BAND_6GHZ &&
		    ((need_scan_psc &&
		      cfg80211_channel_is_psc(rdev_req->channels[i])) ||
		     !(rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))) {
			cfg80211_scan_req_add_chan(request,
						   rdev_req->channels[i],
						   false);
		}
	}

	if (!(rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))
		goto skip;

	list_for_each_entry(ap, &coloc_ap_list, list) {
		bool found = false;
		struct cfg80211_scan_6ghz_params *scan_6ghz_params =
			&request->scan_6ghz_params[request->n_6ghz_params];
		struct ieee80211_channel *chan =
			ieee80211_get_channel(&rdev->wiphy, ap->center_freq);

		if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
			continue;

		for (i = 0; i < rdev_req->n_channels; i++) {
			if (rdev_req->channels[i] == chan)
				found = true;
		}

		if (!found)
			continue;

		if (request->n_ssids > 0 &&
		    !cfg80211_find_ssid_match(ap, request))
			continue;

		if (!is_broadcast_ether_addr(request->bssid) &&
		    !ether_addr_equal(request->bssid, ap->bssid))
			continue;

		if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid)
			continue;

		cfg80211_scan_req_add_chan(request, chan, true);
		memcpy(scan_6ghz_params->bssid, ap->bssid, ETH_ALEN);
		scan_6ghz_params->short_ssid = ap->short_ssid;
		scan_6ghz_params->short_ssid_valid = ap->short_ssid_valid;
		scan_6ghz_params->unsolicited_probe = ap->unsolicited_probe;
		scan_6ghz_params->psd_20 = ap->psd_20;

		/*
		 * If a PSC channel is added to the scan and 'need_scan_psc' is
		 * set to false, then all the APs that the scan logic is
		 * interested with on the channel are collocated and thus there
		 * is no need to perform the initial PSC channel listen.
		 */
		if (cfg80211_channel_is_psc(chan) && !need_scan_psc)
			scan_6ghz_params->psc_no_listen = true;

		request->n_6ghz_params++;
	}

skip:
	cfg80211_free_coloc_ap_list(&coloc_ap_list);

	if (request->n_channels) {
		struct cfg80211_scan_request *old = rdev->int_scan_req;

		rdev->int_scan_req = request;

		/*
		 * If this scan follows a previous scan, save the scan start
		 * info from the first part of the scan
		 */
		if (old)
			rdev->int_scan_req->info = old->info;

		err = rdev_scan(rdev, request);
		if (err) {
			rdev->int_scan_req = old;
			kfree(request);
		} else {
			kfree(old);
		}

		return err;
	}

	kfree(request);
	return -EINVAL;
}

int cfg80211_scan(struct cfg80211_registered_device *rdev)
{
	struct cfg80211_scan_request *request;
	struct cfg80211_scan_request *rdev_req = rdev->scan_req;
	u32 n_channels = 0, idx, i;

	if (!(rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ))
		return rdev_scan(rdev, rdev_req);

	for (i = 0; i < rdev_req->n_channels; i++) {
		if (rdev_req->channels[i]->band != NL80211_BAND_6GHZ)
			n_channels++;
	}

	if (!n_channels)
		return cfg80211_scan_6ghz(rdev);

	request = kzalloc(struct_size(request, channels, n_channels),
			  GFP_KERNEL);
	if (!request)
		return -ENOMEM;

	*request = *rdev_req;
	request->n_channels = n_channels;

	for (i = idx = 0; i < rdev_req->n_channels; i++) {
		if (rdev_req->channels[i]->band != NL80211_BAND_6GHZ)
			request->channels[idx++] = rdev_req->channels[i];
	}

	rdev_req->scan_6ghz = false;
	rdev->int_scan_req = request;
	return rdev_scan(rdev, request);
}

void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
			   bool send_message)
{
	struct cfg80211_scan_request *request, *rdev_req;
	struct wireless_dev *wdev;
	struct sk_buff *msg;
#ifdef CONFIG_CFG80211_WEXT
	union iwreq_data wrqu;
#endif

	lockdep_assert_held(&rdev->wiphy.mtx);

	if (rdev->scan_msg) {
		nl80211_send_scan_msg(rdev, rdev->scan_msg);
		rdev->scan_msg = NULL;
		return;
	}

	rdev_req = rdev->scan_req;
	if (!rdev_req)
		return;

	wdev = rdev_req->wdev;
	request = rdev->int_scan_req ? rdev->int_scan_req : rdev_req;

	if (wdev_running(wdev) &&
	    (rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ) &&
	    !rdev_req->scan_6ghz && !request->info.aborted &&
	    !cfg80211_scan_6ghz(rdev))
		return;

	/*
	 * This must be before sending the other events!
	 * Otherwise, wpa_supplicant gets completely confused with
	 * wext events.
	 */
	if (wdev->netdev)
		cfg80211_sme_scan_done(wdev->netdev);

	if (!request->info.aborted &&
	    request->flags & NL80211_SCAN_FLAG_FLUSH) {
		/* flush entries from previous scans */
		spin_lock_bh(&rdev->bss_lock);
		__cfg80211_bss_expire(rdev, request->scan_start);
		spin_unlock_bh(&rdev->bss_lock);
	}

	msg = nl80211_build_scan_msg(rdev, wdev, request->info.aborted);

#ifdef CONFIG_CFG80211_WEXT
	if (wdev->netdev && !request->info.aborted) {
		memset(&wrqu, 0, sizeof(wrqu));

		wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
	}
#endif

	dev_put(wdev->netdev);

	kfree(rdev->int_scan_req);
	rdev->int_scan_req = NULL;

	kfree(rdev->scan_req);
	rdev->scan_req = NULL;

	if (!send_message)
		rdev->scan_msg = msg;
	else
		nl80211_send_scan_msg(rdev, msg);
}

void __cfg80211_scan_done(struct wiphy *wiphy, struct wiphy_work *wk)
{
	___cfg80211_scan_done(wiphy_to_rdev(wiphy), true);
}

void cfg80211_scan_done(struct cfg80211_scan_request *request,
			struct cfg80211_scan_info *info)
{
	struct cfg80211_scan_info old_info = request->info;

	trace_cfg80211_scan_done(request, info);
	WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req &&
		request != wiphy_to_rdev(request->wiphy)->int_scan_req);

	request->info = *info;

	/*
	 * In case the scan is split, the scan_start_tsf and tsf_bssid should
	 * be of the first part. In such a case old_info.scan_start_tsf should
	 * be non zero.
	 */
	if (request->scan_6ghz && old_info.scan_start_tsf) {
		request->info.scan_start_tsf = old_info.scan_start_tsf;
		memcpy(request->info.tsf_bssid, old_info.tsf_bssid,
		       sizeof(request->info.tsf_bssid));
	}

	request->notified = true;
	wiphy_work_queue(request->wiphy,
			 &wiphy_to_rdev(request->wiphy)->scan_done_wk);
}
EXPORT_SYMBOL(cfg80211_scan_done);

void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
				 struct cfg80211_sched_scan_request *req)
{
	lockdep_assert_held(&rdev->wiphy.mtx);

	list_add_rcu(&req->list, &rdev->sched_scan_req_list);
}

static void cfg80211_del_sched_scan_req(struct cfg80211_registered_device *rdev,
					struct cfg80211_sched_scan_request *req)
{
	lockdep_assert_held(&rdev->wiphy.mtx);

	list_del_rcu(&req->list);
	kfree_rcu(req, rcu_head);
}

static struct cfg80211_sched_scan_request *
cfg80211_find_sched_scan_req(struct cfg80211_registered_device *rdev, u64 reqid)
{
	struct cfg80211_sched_scan_request *pos;

	list_for_each_entry_rcu(pos, &rdev->sched_scan_req_list, list,
				lockdep_is_held(&rdev->wiphy.mtx)) {
		if (pos->reqid == reqid)
			return pos;
	}
	return NULL;
}

/*
 * Determines if a scheduled scan request can be handled. When a legacy
 * scheduled scan is running no other scheduled scan is allowed regardless
 * whether the request is for legacy or multi-support scan. When a multi-support
 * scheduled scan is running a request for legacy scan is not allowed. In this
 * case a request for multi-support scan can be handled if resources are
 * available, ie. struct wiphy::max_sched_scan_reqs limit is not yet reached.
 */
int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
				     bool want_multi)
{
	struct cfg80211_sched_scan_request *pos;
	int i = 0;

	list_for_each_entry(pos, &rdev->sched_scan_req_list, list) {
		/* request id zero means legacy in progress */
		if (!i && !pos->reqid)
			return -EINPROGRESS;
		i++;
	}

	if (i) {
		/* no legacy allowed when multi request(s) are active */
		if (!want_multi)
			return -EINPROGRESS;

		/* resource limit reached */
		if (i == rdev->wiphy.max_sched_scan_reqs)
			return -ENOSPC;
	}
	return 0;
}

void cfg80211_sched_scan_results_wk(struct work_struct *work)
{
	struct cfg80211_registered_device *rdev;
	struct cfg80211_sched_scan_request *req, *tmp;

	rdev = container_of(work, struct cfg80211_registered_device,
			   sched_scan_res_wk);

	wiphy_lock(&rdev->wiphy);
	list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
		if (req->report_results) {
			req->report_results = false;
			if (req->flags & NL80211_SCAN_FLAG_FLUSH) {
				/* flush entries from previous scans */
				spin_lock_bh(&rdev->bss_lock);
				__cfg80211_bss_expire(rdev, req->scan_start);
				spin_unlock_bh(&rdev->bss_lock);
				req->scan_start = jiffies;
			}
			nl80211_send_sched_scan(req,
						NL80211_CMD_SCHED_SCAN_RESULTS);
		}
	}
	wiphy_unlock(&rdev->wiphy);
}

void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct cfg80211_sched_scan_request *request;

	trace_cfg80211_sched_scan_results(wiphy, reqid);
	/* ignore if we're not scanning */

	rcu_read_lock();
	request = cfg80211_find_sched_scan_req(rdev, reqid);
	if (request) {
		request->report_results = true;
		queue_work(cfg80211_wq, &rdev->sched_scan_res_wk);
	}
	rcu_read_unlock();
}
EXPORT_SYMBOL(cfg80211_sched_scan_results);

void cfg80211_sched_scan_stopped_locked(struct wiphy *wiphy, u64 reqid)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);

	lockdep_assert_held(&wiphy->mtx);

	trace_cfg80211_sched_scan_stopped(wiphy, reqid);

	__cfg80211_stop_sched_scan(rdev, reqid, true);
}
EXPORT_SYMBOL(cfg80211_sched_scan_stopped_locked);

void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid)
{
	wiphy_lock(wiphy);
	cfg80211_sched_scan_stopped_locked(wiphy, reqid);
	wiphy_unlock(wiphy);
}
EXPORT_SYMBOL(cfg80211_sched_scan_stopped);

int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
				 struct cfg80211_sched_scan_request *req,
				 bool driver_initiated)
{
	lockdep_assert_held(&rdev->wiphy.mtx);

	if (!driver_initiated) {
		int err = rdev_sched_scan_stop(rdev, req->dev, req->reqid);
		if (err)
			return err;
	}

	nl80211_send_sched_scan(req, NL80211_CMD_SCHED_SCAN_STOPPED);

	cfg80211_del_sched_scan_req(rdev, req);

	return 0;
}

int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
			       u64 reqid, bool driver_initiated)
{
	struct cfg80211_sched_scan_request *sched_scan_req;

	lockdep_assert_held(&rdev->wiphy.mtx);

	sched_scan_req = cfg80211_find_sched_scan_req(rdev, reqid);
	if (!sched_scan_req)
		return -ENOENT;

	return cfg80211_stop_sched_scan_req(rdev, sched_scan_req,
					    driver_initiated);
}

void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
                      unsigned long age_secs)
{
	struct cfg80211_internal_bss *bss;
	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);

	spin_lock_bh(&rdev->bss_lock);
	list_for_each_entry(bss, &rdev->bss_list, list)
		bss->ts -= age_jiffies;
	spin_unlock_bh(&rdev->bss_lock);
}

void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
{
	__cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
}

void cfg80211_bss_flush(struct wiphy *wiphy)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);

	spin_lock_bh(&rdev->bss_lock);
	__cfg80211_bss_expire(rdev, jiffies);
	spin_unlock_bh(&rdev->bss_lock);
}
EXPORT_SYMBOL(cfg80211_bss_flush);

const struct element *
cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
			 const u8 *match, unsigned int match_len,
			 unsigned int match_offset)
{
	const struct element *elem;

	for_each_element_id(elem, eid, ies, len) {
		if (elem->datalen >= match_offset + match_len &&
		    !memcmp(elem->data + match_offset, match, match_len))
			return elem;
	}

	return NULL;
}
EXPORT_SYMBOL(cfg80211_find_elem_match);

const struct element *cfg80211_find_vendor_elem(unsigned int oui, int oui_type,
						const u8 *ies,
						unsigned int len)
{
	const struct element *elem;
	u8 match[] = { oui >> 16, oui >> 8, oui, oui_type };
	int match_len = (oui_type < 0) ? 3 : sizeof(match);

	if (WARN_ON(oui_type > 0xff))
		return NULL;

	elem = cfg80211_find_elem_match(WLAN_EID_VENDOR_SPECIFIC, ies, len,
					match, match_len, 0);

	if (!elem || elem->datalen < 4)
		return NULL;

	return elem;
}
EXPORT_SYMBOL(cfg80211_find_vendor_elem);

/**
 * enum bss_compare_mode - BSS compare mode
 * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find)
 * @BSS_CMP_HIDE_ZLEN: find hidden SSID with zero-length mode
 * @BSS_CMP_HIDE_NUL: find hidden SSID with NUL-ed out mode
 */
enum bss_compare_mode {
	BSS_CMP_REGULAR,
	BSS_CMP_HIDE_ZLEN,
	BSS_CMP_HIDE_NUL,
};

static int cmp_bss(struct cfg80211_bss *a,
		   struct cfg80211_bss *b,
		   enum bss_compare_mode mode)
{
	const struct cfg80211_bss_ies *a_ies, *b_ies;
	const u8 *ie1 = NULL;
	const u8 *ie2 = NULL;
	int i, r;

	if (a->channel != b->channel)
		return (b->channel->center_freq * 1000 + b->channel->freq_offset) -
		       (a->channel->center_freq * 1000 + a->channel->freq_offset);

	a_ies = rcu_access_pointer(a->ies);
	if (!a_ies)
		return -1;
	b_ies = rcu_access_pointer(b->ies);
	if (!b_ies)
		return 1;

	if (WLAN_CAPABILITY_IS_STA_BSS(a->capability))
		ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID,
				       a_ies->data, a_ies->len);
	if (WLAN_CAPABILITY_IS_STA_BSS(b->capability))
		ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID,
				       b_ies->data, b_ies->len);
	if (ie1 && ie2) {
		int mesh_id_cmp;

		if (ie1[1] == ie2[1])
			mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]);
		else
			mesh_id_cmp = ie2[1] - ie1[1];

		ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
				       a_ies->data, a_ies->len);
		ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
				       b_ies->data, b_ies->len);
		if (ie1 && ie2) {
			if (mesh_id_cmp)
				return mesh_id_cmp;
			if (ie1[1] != ie2[1])
				return ie2[1] - ie1[1];
			return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
		}
	}

	r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
	if (r)
		return r;

	ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
	ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);

	if (!ie1 && !ie2)
		return 0;

	/*
	 * Note that with "hide_ssid", the function returns a match if
	 * the already-present BSS ("b") is a hidden SSID beacon for
	 * the new BSS ("a").
	 */

	/* sort missing IE before (left of) present IE */
	if (!ie1)
		return -1;
	if (!ie2)
		return 1;

	switch (mode) {
	case BSS_CMP_HIDE_ZLEN:
		/*
		 * In ZLEN mode we assume the BSS entry we're
		 * looking for has a zero-length SSID. So if
		 * the one we're looking at right now has that,
		 * return 0. Otherwise, return the difference
		 * in length, but since we're looking for the
		 * 0-length it's really equivalent to returning
		 * the length of the one we're looking at.
		 *
		 * No content comparison is needed as we assume
		 * the content length is zero.
		 */
		return ie2[1];
	case BSS_CMP_REGULAR:
	default:
		/* sort by length first, then by contents */
		if (ie1[1] != ie2[1])
			return ie2[1] - ie1[1];
		return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
	case BSS_CMP_HIDE_NUL:
		if (ie1[1] != ie2[1])
			return ie2[1] - ie1[1];
		/* this is equivalent to memcmp(zeroes, ie2 + 2, len) */
		for (i = 0; i < ie2[1]; i++)
			if (ie2[i + 2])
				return -1;
		return 0;
	}
}

static bool cfg80211_bss_type_match(u16 capability,
				    enum nl80211_band band,
				    enum ieee80211_bss_type bss_type)
{
	bool ret = true;
	u16 mask, val;

	if (bss_type == IEEE80211_BSS_TYPE_ANY)
		return ret;

	if (band == NL80211_BAND_60GHZ) {
		mask = WLAN_CAPABILITY_DMG_TYPE_MASK;
		switch (bss_type) {
		case IEEE80211_BSS_TYPE_ESS:
			val = WLAN_CAPABILITY_DMG_TYPE_AP;
			break;
		case IEEE80211_BSS_TYPE_PBSS:
			val = WLAN_CAPABILITY_DMG_TYPE_PBSS;
			break;
		case IEEE80211_BSS_TYPE_IBSS:
			val = WLAN_CAPABILITY_DMG_TYPE_IBSS;
			break;
		default:
			return false;
		}
	} else {
		mask = WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS;
		switch (bss_type) {
		case IEEE80211_BSS_TYPE_ESS:
			val = WLAN_CAPABILITY_ESS;
			break;
		case IEEE80211_BSS_TYPE_IBSS:
			val = WLAN_CAPABILITY_IBSS;
			break;
		case IEEE80211_BSS_TYPE_MBSS:
			val = 0;
			break;
		default:
			return false;
		}
	}

	ret = ((capability & mask) == val);
	return ret;
}

/* Returned bss is reference counted and must be cleaned up appropriately. */
struct cfg80211_bss *__cfg80211_get_bss(struct wiphy *wiphy,
					struct ieee80211_channel *channel,
					const u8 *bssid,
					const u8 *ssid, size_t ssid_len,
					enum ieee80211_bss_type bss_type,
					enum ieee80211_privacy privacy,
					u32 use_for)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct cfg80211_internal_bss *bss, *res = NULL;
	unsigned long now = jiffies;
	int bss_privacy;

	trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type,
			       privacy);

	spin_lock_bh(&rdev->bss_lock);

	list_for_each_entry(bss, &rdev->bss_list, list) {
		if (!cfg80211_bss_type_match(bss->pub.capability,
					     bss->pub.channel->band, bss_type))
			continue;

		bss_privacy = (bss->pub.capability & WLAN_CAPABILITY_PRIVACY);
		if ((privacy == IEEE80211_PRIVACY_ON && !bss_privacy) ||
		    (privacy == IEEE80211_PRIVACY_OFF && bss_privacy))
			continue;
		if (channel && bss->pub.channel != channel)
			continue;
		if (!is_valid_ether_addr(bss->pub.bssid))
			continue;
		if ((bss->pub.use_for & use_for) != use_for)
			continue;
		/* Don't get expired BSS structs */
		if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
		    !atomic_read(&bss->hold))
			continue;
		if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
			res = bss;
			bss_ref_get(rdev, res);
			break;
		}
	}

	spin_unlock_bh(&rdev->bss_lock);
	if (!res)
		return NULL;
	trace_cfg80211_return_bss(&res->pub);
	return &res->pub;
}
EXPORT_SYMBOL(__cfg80211_get_bss);

static bool rb_insert_bss(struct cfg80211_registered_device *rdev,
			  struct cfg80211_internal_bss *bss)
{
	struct rb_node **p = &rdev->bss_tree.rb_node;
	struct rb_node *parent = NULL;
	struct cfg80211_internal_bss *tbss;
	int cmp;

	while (*p) {
		parent = *p;
		tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);

		cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);

		if (WARN_ON(!cmp)) {
			/* will sort of leak this BSS */
			return false;
		}

		if (cmp < 0)
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}

	rb_link_node(&bss->rbn, parent, p);
	rb_insert_color(&bss->rbn, &rdev->bss_tree);
	return true;
}

static struct cfg80211_internal_bss *
rb_find_bss(struct cfg80211_registered_device *rdev,
	    struct cfg80211_internal_bss *res,
	    enum bss_compare_mode mode)
{
	struct rb_node *n = rdev->bss_tree.rb_node;
	struct cfg80211_internal_bss *bss;
	int r;

	while (n) {
		bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
		r = cmp_bss(&res->pub, &bss->pub, mode);

		if (r == 0)
			return bss;
		else if (r < 0)
			n = n->rb_left;
		else
			n = n->rb_right;
	}

	return NULL;
}

static void cfg80211_insert_bss(struct cfg80211_registered_device *rdev,
				struct cfg80211_internal_bss *bss)
{
	lockdep_assert_held(&rdev->bss_lock);

	if (!rb_insert_bss(rdev, bss))
		return;
	list_add_tail(&bss->list, &rdev->bss_list);
	rdev->bss_entries++;
}

static void cfg80211_rehash_bss(struct cfg80211_registered_device *rdev,
                                struct cfg80211_internal_bss *bss)
{
	lockdep_assert_held(&rdev->bss_lock);

	rb_erase(&bss->rbn, &rdev->bss_tree);
	if (!rb_insert_bss(rdev, bss)) {
		list_del(&bss->list);
		if (!list_empty(&bss->hidden_list))
			list_del_init(&bss->hidden_list);
		if (!list_empty(&bss->pub.nontrans_list))
			list_del_init(&bss->pub.nontrans_list);
		rdev->bss_entries--;
	}
	rdev->bss_generation++;
}

static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
				   struct cfg80211_internal_bss *new)
{
	const struct cfg80211_bss_ies *ies;
	struct cfg80211_internal_bss *bss;
	const u8 *ie;
	int i, ssidlen;
	u8 fold = 0;
	u32 n_entries = 0;

	ies = rcu_access_pointer(new->pub.beacon_ies);
	if (WARN_ON(!ies))
		return false;

	ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
	if (!ie) {
		/* nothing to do */
		return true;
	}

	ssidlen = ie[1];
	for (i = 0; i < ssidlen; i++)
		fold |= ie[2 + i];

	if (fold) {
		/* not a hidden SSID */
		return true;
	}

	/* This is the bad part ... */

	list_for_each_entry(bss, &rdev->bss_list, list) {
		/*
		 * we're iterating all the entries anyway, so take the
		 * opportunity to validate the list length accounting
		 */
		n_entries++;

		if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
			continue;
		if (bss->pub.channel != new->pub.channel)
			continue;
		if (rcu_access_pointer(bss->pub.beacon_ies))
			continue;
		ies = rcu_access_pointer(bss->pub.ies);
		if (!ies)
			continue;
		ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
		if (!ie)
			continue;
		if (ssidlen && ie[1] != ssidlen)
			continue;
		if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
			continue;
		if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
			list_del(&bss->hidden_list);
		/* combine them */
		list_add(&bss->hidden_list, &new->hidden_list);
		bss->pub.hidden_beacon_bss = &new->pub;
		new->refcount += bss->refcount;
		rcu_assign_pointer(bss->pub.beacon_ies,
				   new->pub.beacon_ies);
	}

	WARN_ONCE(n_entries != rdev->bss_entries,
		  "rdev bss entries[%d]/list[len:%d] corruption\n",
		  rdev->bss_entries, n_entries);

	return true;
}

static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
					 const struct cfg80211_bss_ies *new_ies,
					 const struct cfg80211_bss_ies *old_ies)
{
	struct cfg80211_internal_bss *bss;

	/* Assign beacon IEs to all sub entries */
	list_for_each_entry(bss, &known->hidden_list, hidden_list) {
		const struct cfg80211_bss_ies *ies;

		ies = rcu_access_pointer(bss->pub.beacon_ies);
		WARN_ON(ies != old_ies);

		rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
	}
}

static void cfg80211_check_stuck_ecsa(struct cfg80211_registered_device *rdev,
				      struct cfg80211_internal_bss *known,
				      const struct cfg80211_bss_ies *old)
{
	const struct ieee80211_ext_chansw_ie *ecsa;
	const struct element *elem_new, *elem_old;
	const struct cfg80211_bss_ies *new, *bcn;

	if (known->pub.proberesp_ecsa_stuck)
		return;

	new = rcu_dereference_protected(known->pub.proberesp_ies,
					lockdep_is_held(&rdev->bss_lock));
	if (WARN_ON(!new))
		return;

	if (new->tsf - old->tsf < USEC_PER_SEC)
		return;

	elem_old = cfg80211_find_elem(WLAN_EID_EXT_CHANSWITCH_ANN,
				      old->data, old->len);
	if (!elem_old)
		return;

	elem_new = cfg80211_find_elem(WLAN_EID_EXT_CHANSWITCH_ANN,
				      new->data, new->len);
	if (!elem_new)
		return;

	bcn = rcu_dereference_protected(known->pub.beacon_ies,
					lockdep_is_held(&rdev->bss_lock));
	if (bcn &&
	    cfg80211_find_elem(WLAN_EID_EXT_CHANSWITCH_ANN,
			       bcn->data, bcn->len))
		return;

	if (elem_new->datalen != elem_old->datalen)
		return;
	if (elem_new->datalen < sizeof(struct ieee80211_ext_chansw_ie))
		return;
	if (memcmp(elem_new->data, elem_old->data, elem_new->datalen))
		return;

	ecsa = (void *)elem_new->data;

	if (!ecsa->mode)
		return;

	if (ecsa->new_ch_num !=
	    ieee80211_frequency_to_channel(known->pub.channel->center_freq))
		return;

	known->pub.proberesp_ecsa_stuck = 1;
}

static bool
cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
			  struct cfg80211_internal_bss *known,
			  struct cfg80211_internal_bss *new,
			  bool signal_valid)
{
	lockdep_assert_held(&rdev->bss_lock);

	/* Update IEs */
	if (rcu_access_pointer(new->pub.proberesp_ies)) {
		const struct cfg80211_bss_ies *old;

		old = rcu_access_pointer(known->pub.proberesp_ies);

		rcu_assign_pointer(known->pub.proberesp_ies,
				   new->pub.proberesp_ies);
		/* Override possible earlier Beacon frame IEs */
		rcu_assign_pointer(known->pub.ies,
				   new->pub.proberesp_ies);
		if (old) {
			cfg80211_check_stuck_ecsa(rdev, known, old);
			kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
		}
	}

	if (rcu_access_pointer(new->pub.beacon_ies)) {
		const struct cfg80211_bss_ies *old;

		if (known->pub.hidden_beacon_bss &&
		    !list_empty(&known->hidden_list)) {
			const struct cfg80211_bss_ies *f;

			/* The known BSS struct is one of the probe
			 * response members of a group, but we're
			 * receiving a beacon (beacon_ies in the new
			 * bss is used). This can only mean that the
			 * AP changed its beacon from not having an
			 * SSID to showing it, which is confusing so
			 * drop this information.
			 */

			f = rcu_access_pointer(new->pub.beacon_ies);
			kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
			return false;
		}

		old = rcu_access_pointer(known->pub.beacon_ies);

		rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);

		/* Override IEs if they were from a beacon before */
		if (old == rcu_access_pointer(known->pub.ies))
			rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);

		cfg80211_update_hidden_bsses(known,
					     rcu_access_pointer(new->pub.beacon_ies),
					     old);

		if (old)
			kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
	}

	known->pub.beacon_interval = new->pub.beacon_interval;

	/* don't update the signal if beacon was heard on
	 * adjacent channel.
	 */
	if (signal_valid)
		known->pub.signal = new->pub.signal;
	known->pub.capability = new->pub.capability;
	known->ts = new->ts;
	known->ts_boottime = new->ts_boottime;
	known->parent_tsf = new->parent_tsf;
	known->pub.chains = new->pub.chains;
	memcpy(known->pub.chain_signal, new->pub.chain_signal,
	       IEEE80211_MAX_CHAINS);
	ether_addr_copy(known->parent_bssid, new->parent_bssid);
	known->pub.max_bssid_indicator = new->pub.max_bssid_indicator;
	known->pub.bssid_index = new->pub.bssid_index;
	known->pub.use_for &= new->pub.use_for;
	known->pub.cannot_use_reasons = new->pub.cannot_use_reasons;

	return true;
}

/* Returned bss is reference counted and must be cleaned up appropriately. */
static struct cfg80211_internal_bss *
__cfg80211_bss_update(struct cfg80211_registered_device *rdev,
		      struct cfg80211_internal_bss *tmp,
		      bool signal_valid, unsigned long ts)
{
	struct cfg80211_internal_bss *found = NULL;
	struct cfg80211_bss_ies *ies;

	if (WARN_ON(!tmp->pub.channel))
		goto free_ies;

	tmp->ts = ts;

	if (WARN_ON(!rcu_access_pointer(tmp->pub.ies)))
		goto free_ies;

	found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);

	if (found) {
		if (!cfg80211_update_known_bss(rdev, found, tmp, signal_valid))
			return NULL;
	} else {
		struct cfg80211_internal_bss *new;
		struct cfg80211_internal_bss *hidden;

		/*
		 * create a copy -- the "res" variable that is passed in
		 * is allocated on the stack since it's not needed in the
		 * more common case of an update
		 */
		new = kzalloc(sizeof(*new) + rdev->wiphy.bss_priv_size,
			      GFP_ATOMIC);
		if (!new)
			goto free_ies;
		memcpy(new, tmp, sizeof(*new));
		new->refcount = 1;
		INIT_LIST_HEAD(&new->hidden_list);
		INIT_LIST_HEAD(&new->pub.nontrans_list);
		/* we'll set this later if it was non-NULL */
		new->pub.transmitted_bss = NULL;

		if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
			hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
			if (!hidden)
				hidden = rb_find_bss(rdev, tmp,
						     BSS_CMP_HIDE_NUL);
			if (hidden) {
				new->pub.hidden_beacon_bss = &hidden->pub;
				list_add(&new->hidden_list,
					 &hidden->hidden_list);
				hidden->refcount++;

				ies = (void *)rcu_access_pointer(new->pub.beacon_ies);
				rcu_assign_pointer(new->pub.beacon_ies,
						   hidden->pub.beacon_ies);
				if (ies)
					kfree_rcu(ies, rcu_head);
			}
		} else {
			/*
			 * Ok so we found a beacon, and don't have an entry. If
			 * it's a beacon with hidden SSID, we might be in for an
			 * expensive search for any probe responses that should
			 * be grouped with this beacon for updates ...
			 */
			if (!cfg80211_combine_bsses(rdev, new)) {
				bss_ref_put(rdev, new);
				return NULL;
			}
		}

		if (rdev->bss_entries >= bss_entries_limit &&
		    !cfg80211_bss_expire_oldest(rdev)) {
			bss_ref_put(rdev, new);
			return NULL;
		}

		/* This must be before the call to bss_ref_get */
		if (tmp->pub.transmitted_bss) {
			new->pub.transmitted_bss = tmp->pub.transmitted_bss;
			bss_ref_get(rdev, bss_from_pub(tmp->pub.transmitted_bss));
		}

		cfg80211_insert_bss(rdev, new);
		found = new;
	}

	rdev->bss_generation++;
	bss_ref_get(rdev, found);

	return found;

free_ies:
	ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
	if (ies)
		kfree_rcu(ies, rcu_head);
	ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
	if (ies)
		kfree_rcu(ies, rcu_head);

	return NULL;
}

struct cfg80211_internal_bss *
cfg80211_bss_update(struct cfg80211_registered_device *rdev,
		    struct cfg80211_internal_bss *tmp,
		    bool signal_valid, unsigned long ts)
{
	struct cfg80211_internal_bss *res;

	spin_lock_bh(&rdev->bss_lock);
	res = __cfg80211_bss_update(rdev, tmp, signal_valid, ts);
	spin_unlock_bh(&rdev->bss_lock);

	return res;
}

int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen,
				    enum nl80211_band band)
{
	const struct element *tmp;

	if (band == NL80211_BAND_6GHZ) {
		struct ieee80211_he_operation *he_oper;

		tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie,
					     ielen);
		if (tmp && tmp->datalen >= sizeof(*he_oper) &&
		    tmp->datalen >= ieee80211_he_oper_size(&tmp->data[1])) {
			const struct ieee80211_he_6ghz_oper *he_6ghz_oper;

			he_oper = (void *)&tmp->data[1];

			he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
			if (!he_6ghz_oper)
				return -1;

			return he_6ghz_oper->primary;
		}
	} else if (band == NL80211_BAND_S1GHZ) {
		tmp = cfg80211_find_elem(WLAN_EID_S1G_OPERATION, ie, ielen);
		if (tmp && tmp->datalen >= sizeof(struct ieee80211_s1g_oper_ie)) {
			struct ieee80211_s1g_oper_ie *s1gop = (void *)tmp->data;

			return s1gop->oper_ch;
		}
	} else {
		tmp = cfg80211_find_elem(WLAN_EID_DS_PARAMS, ie, ielen);
		if (tmp && tmp->datalen == 1)
			return tmp->data[0];

		tmp = cfg80211_find_elem(WLAN_EID_HT_OPERATION, ie, ielen);
		if (tmp &&
		    tmp->datalen >= sizeof(struct ieee80211_ht_operation)) {
			struct ieee80211_ht_operation *htop = (void *)tmp->data;

			return htop->primary_chan;
		}
	}

	return -1;
}
EXPORT_SYMBOL(cfg80211_get_ies_channel_number);

/*
 * Update RX channel information based on the available frame payload
 * information. This is mainly for the 2.4 GHz band where frames can be received
 * from neighboring channels and the Beacon frames use the DSSS Parameter Set
 * element to indicate the current (transmitting) channel, but this might also
 * be needed on other bands if RX frequency does not match with the actual
 * operating channel of a BSS, or if the AP reports a different primary channel.
 */
static struct ieee80211_channel *
cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
			 struct ieee80211_channel *channel)
{
	u32 freq;
	int channel_number;
	struct ieee80211_channel *alt_channel;

	channel_number = cfg80211_get_ies_channel_number(ie, ielen,
							 channel->band);

	if (channel_number < 0) {
		/* No channel information in frame payload */
		return channel;
	}

	freq = ieee80211_channel_to_freq_khz(channel_number, channel->band);

	/*
	 * Frame info (beacon/prob res) is the same as received channel,
	 * no need for further processing.
	 */
	if (freq == ieee80211_channel_to_khz(channel))
		return channel;

	alt_channel = ieee80211_get_channel_khz(wiphy, freq);
	if (!alt_channel) {
		if (channel->band == NL80211_BAND_2GHZ ||
		    channel->band == NL80211_BAND_6GHZ) {
			/*
			 * Better not allow unexpected channels when that could
			 * be going beyond the 1-11 range (e.g., discovering
			 * BSS on channel 12 when radio is configured for
			 * channel 11) or beyond the 6 GHz channel range.
			 */
			return NULL;
		}

		/* No match for the payload channel number - ignore it */
		return channel;
	}

	/*
	 * Use the channel determined through the payload channel number
	 * instead of the RX channel reported by the driver.
	 */
	if (alt_channel->flags & IEEE80211_CHAN_DISABLED)
		return NULL;
	return alt_channel;
}

struct cfg80211_inform_single_bss_data {
	struct cfg80211_inform_bss *drv_data;
	enum cfg80211_bss_frame_type ftype;
	struct ieee80211_channel *channel;
	u8 bssid[ETH_ALEN];
	u64 tsf;
	u16 capability;
	u16 beacon_interval;
	const u8 *ie;
	size_t ielen;

	enum {
		BSS_SOURCE_DIRECT = 0,
		BSS_SOURCE_MBSSID,
		BSS_SOURCE_STA_PROFILE,
	} bss_source;
	/* Set if reporting bss_source != BSS_SOURCE_DIRECT */
	struct cfg80211_bss *source_bss;
	u8 max_bssid_indicator;
	u8 bssid_index;

	u8 use_for;
	u64 cannot_use_reasons;
};

enum ieee80211_ap_reg_power
cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len)
{
	const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
	struct ieee80211_he_operation *he_oper;
	const struct element *tmp;

	tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION,
				     elems, elems_len);
	if (!tmp || tmp->datalen < sizeof(*he_oper) + 1 ||
	    tmp->datalen < ieee80211_he_oper_size(tmp->data + 1))
		return IEEE80211_REG_UNSET_AP;

	he_oper = (void *)&tmp->data[1];
	he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);

	if (!he_6ghz_oper)
		return IEEE80211_REG_UNSET_AP;

	switch (u8_get_bits(he_6ghz_oper->control,
			    IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) {
	case IEEE80211_6GHZ_CTRL_REG_LPI_AP:
	case IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP:
		return IEEE80211_REG_LPI_AP;
	case IEEE80211_6GHZ_CTRL_REG_SP_AP:
	case IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP:
		return IEEE80211_REG_SP_AP;
	case IEEE80211_6GHZ_CTRL_REG_VLP_AP:
		return IEEE80211_REG_VLP_AP;
	default:
		return IEEE80211_REG_UNSET_AP;
	}
}

static bool cfg80211_6ghz_power_type_valid(const u8 *elems, size_t elems_len,
					   const u32 flags)
{
	switch (cfg80211_get_6ghz_power_type(elems, elems_len)) {
	case IEEE80211_REG_LPI_AP:
		return true;
	case IEEE80211_REG_SP_AP:
		return !(flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT);
	case IEEE80211_REG_VLP_AP:
		return !(flags & IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT);
	default:
		return false;
	}
}

/* Returned bss is reference counted and must be cleaned up appropriately. */
static struct cfg80211_bss *
cfg80211_inform_single_bss_data(struct wiphy *wiphy,
				struct cfg80211_inform_single_bss_data *data,
				gfp_t gfp)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct cfg80211_inform_bss *drv_data = data->drv_data;
	struct cfg80211_bss_ies *ies;
	struct ieee80211_channel *channel;
	struct cfg80211_internal_bss tmp = {}, *res;
	int bss_type;
	bool signal_valid;
	unsigned long ts;

	if (WARN_ON(!wiphy))
		return NULL;

	if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
		    (drv_data->signal < 0 || drv_data->signal > 100)))
		return NULL;

	if (WARN_ON(data->bss_source != BSS_SOURCE_DIRECT && !data->source_bss))
		return NULL;

	channel = data->channel;
	if (!channel)
		channel = cfg80211_get_bss_channel(wiphy, data->ie, data->ielen,
						   drv_data->chan);
	if (!channel)
		return NULL;

	if (channel->band == NL80211_BAND_6GHZ &&
	    !cfg80211_6ghz_power_type_valid(data->ie, data->ielen,
					    channel->flags)) {
		data->use_for = 0;
		data->cannot_use_reasons =
			NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH;
	}

	memcpy(tmp.pub.bssid, data->bssid, ETH_ALEN);
	tmp.pub.channel = channel;
	if (data->bss_source != BSS_SOURCE_STA_PROFILE)
		tmp.pub.signal = drv_data->signal;
	else
		tmp.pub.signal = 0;
	tmp.pub.beacon_interval = data->beacon_interval;
	tmp.pub.capability = data->capability;
	tmp.ts_boottime = drv_data->boottime_ns;
	tmp.parent_tsf = drv_data->parent_tsf;
	ether_addr_copy(tmp.parent_bssid, drv_data->parent_bssid);
	tmp.pub.chains = drv_data->chains;
	memcpy(tmp.pub.chain_signal, drv_data->chain_signal,
	       IEEE80211_MAX_CHAINS);
	tmp.pub.use_for = data->use_for;
	tmp.pub.cannot_use_reasons = data->cannot_use_reasons;

	switch (data->bss_source) {
	case BSS_SOURCE_MBSSID:
		tmp.pub.transmitted_bss = data->source_bss;
		fallthrough;
	case BSS_SOURCE_STA_PROFILE:
		ts = bss_from_pub(data->source_bss)->ts;
		tmp.pub.bssid_index = data->bssid_index;
		tmp.pub.max_bssid_indicator = data->max_bssid_indicator;
		break;
	case BSS_SOURCE_DIRECT:
		ts = jiffies;

		if (channel->band == NL80211_BAND_60GHZ) {
			bss_type = data->capability &
				   WLAN_CAPABILITY_DMG_TYPE_MASK;
			if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
			    bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
				regulatory_hint_found_beacon(wiphy, channel,
							     gfp);
		} else {
			if (data->capability & WLAN_CAPABILITY_ESS)
				regulatory_hint_found_beacon(wiphy, channel,
							     gfp);
		}
		break;
	}

	/*
	 * If we do not know here whether the IEs are from a Beacon or Probe
	 * Response frame, we need to pick one of the options and only use it
	 * with the driver that does not provide the full Beacon/Probe Response
	 * frame. Use Beacon frame pointer to avoid indicating that this should
	 * override the IEs pointer should we have received an earlier
	 * indication of Probe Response data.
	 */
	ies = kzalloc(sizeof(*ies) + data->ielen, gfp);
	if (!ies)
		return NULL;
	ies->len = data->ielen;
	ies->tsf = data->tsf;
	ies->from_beacon = false;
	memcpy(ies->data, data->ie, data->ielen);

	switch (data->ftype) {
	case CFG80211_BSS_FTYPE_BEACON:
	case CFG80211_BSS_FTYPE_S1G_BEACON:
		ies->from_beacon = true;
		fallthrough;
	case CFG80211_BSS_FTYPE_UNKNOWN:
		rcu_assign_pointer(tmp.pub.beacon_ies, ies);
		break;
	case CFG80211_BSS_FTYPE_PRESP:
		rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
		break;
	}
	rcu_assign_pointer(tmp.pub.ies, ies);

	signal_valid = drv_data->chan == channel;
	spin_lock_bh(&rdev->bss_lock);
	res = __cfg80211_bss_update(rdev, &tmp, signal_valid, ts);
	if (!res)
		goto drop;

	rdev_inform_bss(rdev, &res->pub, ies, drv_data->drv_data);

	if (data->bss_source == BSS_SOURCE_MBSSID) {
		/* this is a nontransmitting bss, we need to add it to
		 * transmitting bss' list if it is not there
		 */
		if (cfg80211_add_nontrans_list(data->source_bss, &res->pub)) {
			if (__cfg80211_unlink_bss(rdev, res)) {
				rdev->bss_generation++;
				res = NULL;
			}
		}

		if (!res)
			goto drop;
	}
	spin_unlock_bh(&rdev->bss_lock);

	trace_cfg80211_return_bss(&res->pub);
	/* __cfg80211_bss_update gives us a referenced result */
	return &res->pub;

drop:
	spin_unlock_bh(&rdev->bss_lock);
	return NULL;
}

static const struct element
*cfg80211_get_profile_continuation(const u8 *ie, size_t ielen,
				   const struct element *mbssid_elem,
				   const struct element *sub_elem)
{
	const u8 *mbssid_end = mbssid_elem->data + mbssid_elem->datalen;
	const struct element *next_mbssid;
	const struct element *next_sub;

	next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
					 mbssid_end,
					 ielen - (mbssid_end - ie));

	/*
	 * If it is not the last subelement in current MBSSID IE or there isn't
	 * a next MBSSID IE - profile is complete.
	*/
	if ((sub_elem->data + sub_elem->datalen < mbssid_end - 1) ||
	    !next_mbssid)
		return NULL;

	/* For any length error, just return NULL */

	if (next_mbssid->datalen < 4)
		return NULL;

	next_sub = (void *)&next_mbssid->data[1];

	if (next_mbssid->data + next_mbssid->datalen <
	    next_sub->data + next_sub->datalen)
		return NULL;

	if (next_sub->id != 0 || next_sub->datalen < 2)
		return NULL;

	/*
	 * Check if the first element in the next sub element is a start
	 * of a new profile
	 */
	return next_sub->data[0] == WLAN_EID_NON_TX_BSSID_CAP ?
	       NULL : next_mbssid;
}

size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
			      const struct element *mbssid_elem,
			      const struct element *sub_elem,
			      u8 *merged_ie, size_t max_copy_len)
{
	size_t copied_len = sub_elem->datalen;
	const struct element *next_mbssid;

	if (sub_elem->datalen > max_copy_len)
		return 0;

	memcpy(merged_ie, sub_elem->data, sub_elem->datalen);

	while ((next_mbssid = cfg80211_get_profile_continuation(ie, ielen,
								mbssid_elem,
								sub_elem))) {
		const struct element *next_sub = (void *)&next_mbssid->data[1];

		if (copied_len + next_sub->datalen > max_copy_len)
			break;
		memcpy(merged_ie + copied_len, next_sub->data,
		       next_sub->datalen);
		copied_len += next_sub->datalen;
	}

	return copied_len;
}
EXPORT_SYMBOL(cfg80211_merge_profile);

static void
cfg80211_parse_mbssid_data(struct wiphy *wiphy,
			   struct cfg80211_inform_single_bss_data *tx_data,
			   struct cfg80211_bss *source_bss,
			   gfp_t gfp)
{
	struct cfg80211_inform_single_bss_data data = {
		.drv_data = tx_data->drv_data,
		.ftype = tx_data->ftype,
		.tsf = tx_data->tsf,
		.beacon_interval = tx_data->beacon_interval,
		.source_bss = source_bss,
		.bss_source = BSS_SOURCE_MBSSID,
		.use_for = tx_data->use_for,
		.cannot_use_reasons = tx_data->cannot_use_reasons,
	};
	const u8 *mbssid_index_ie;
	const struct element *elem, *sub;
	u8 *new_ie, *profile;
	u64 seen_indices = 0;
	struct cfg80211_bss *bss;

	if (!source_bss)
		return;
	if (!cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
				tx_data->ie, tx_data->ielen))
		return;
	if (!wiphy->support_mbssid)
		return;
	if (wiphy->support_only_he_mbssid &&
	    !cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY,
				    tx_data->ie, tx_data->ielen))
		return;

	new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
	if (!new_ie)
		return;

	profile = kmalloc(tx_data->ielen, gfp);
	if (!profile)
		goto out;

	for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID,
			    tx_data->ie, tx_data->ielen) {
		if (elem->datalen < 4)
			continue;
		if (elem->data[0] < 1 || (int)elem->data[0] > 8)
			continue;
		for_each_element(sub, elem->data + 1, elem->datalen - 1) {
			u8 profile_len;

			if (sub->id != 0 || sub->datalen < 4) {
				/* not a valid BSS profile */
				continue;
			}

			if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
			    sub->data[1] != 2) {
				/* The first element within the Nontransmitted
				 * BSSID Profile is not the Nontransmitted
				 * BSSID Capability element.
				 */
				continue;
			}

			memset(profile, 0, tx_data->ielen);
			profile_len = cfg80211_merge_profile(tx_data->ie,
							     tx_data->ielen,
							     elem,
							     sub,
							     profile,
							     tx_data->ielen);

			/* found a Nontransmitted BSSID Profile */
			mbssid_index_ie = cfg80211_find_ie
				(WLAN_EID_MULTI_BSSID_IDX,
				 profile, profile_len);
			if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
			    mbssid_index_ie[2] == 0 ||
			    mbssid_index_ie[2] > 46 ||
			    mbssid_index_ie[2] >= (1 << elem->data[0])) {
				/* No valid Multiple BSSID-Index element */
				continue;
			}

			if (seen_indices & BIT_ULL(mbssid_index_ie[2]))
				/* We don't support legacy split of a profile */
				net_dbg_ratelimited("Partial info for BSSID index %d\n",
						    mbssid_index_ie[2]);

			seen_indices |= BIT_ULL(mbssid_index_ie[2]);

			data.bssid_index = mbssid_index_ie[2];
			data.max_bssid_indicator = elem->data[0];

			cfg80211_gen_new_bssid(tx_data->bssid,
					       data.max_bssid_indicator,
					       data.bssid_index,
					       data.bssid);

			memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
			data.ie = new_ie;
			data.ielen = cfg80211_gen_new_ie(tx_data->ie,
							 tx_data->ielen,
							 profile,
							 profile_len,
							 new_ie,
							 IEEE80211_MAX_DATA_LEN);
			if (!data.ielen)
				continue;

			data.capability = get_unaligned_le16(profile + 2);
			bss = cfg80211_inform_single_bss_data(wiphy, &data, gfp);
			if (!bss)
				break;
			cfg80211_put_bss(wiphy, bss);
		}
	}

out:
	kfree(new_ie);
	kfree(profile);
}

ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies,
				    size_t ieslen, u8 *data, size_t data_len,
				    u8 frag_id)
{
	const struct element *next;
	ssize_t copied;
	u8 elem_datalen;

	if (!elem)
		return -EINVAL;

	/* elem might be invalid after the memmove */
	next = (void *)(elem->data + elem->datalen);
	elem_datalen = elem->datalen;

	if (elem->id == WLAN_EID_EXTENSION) {
		copied = elem->datalen - 1;

		if (data) {
			if (copied > data_len)
				return -ENOSPC;

			memmove(data, elem->data + 1, copied);
		}
	} else {
		copied = elem->datalen;

		if (data) {
			if (copied > data_len)
				return -ENOSPC;

			memmove(data, elem->data, copied);
		}
	}

	/* Fragmented elements must have 255 bytes */
	if (elem_datalen < 255)
		return copied;

	for (elem = next;
	     elem->data < ies + ieslen &&
		elem->data + elem->datalen <= ies + ieslen;
	     elem = next) {
		/* elem might be invalid after the memmove */
		next = (void *)(elem->data + elem->datalen);

		if (elem->id != frag_id)
			break;

		elem_datalen = elem->datalen;

		if (data) {
			if (copied + elem_datalen > data_len)
				return -ENOSPC;

			memmove(data + copied, elem->data, elem_datalen);
		}

		copied += elem_datalen;

		/* Only the last fragment may be short */
		if (elem_datalen != 255)
			break;
	}

	return copied;
}
EXPORT_SYMBOL(cfg80211_defragment_element);

struct cfg80211_mle {
	struct ieee80211_multi_link_elem *mle;
	struct ieee80211_mle_per_sta_profile
		*sta_prof[IEEE80211_MLD_MAX_NUM_LINKS];
	ssize_t sta_prof_len[IEEE80211_MLD_MAX_NUM_LINKS];

	u8 data[];
};

static struct cfg80211_mle *
cfg80211_defrag_mle(const struct element *mle, const u8 *ie, size_t ielen,
		    gfp_t gfp)
{
	const struct element *elem;
	struct cfg80211_mle *res;
	size_t buf_len;
	ssize_t mle_len;
	u8 common_size, idx;

	if (!mle || !ieee80211_mle_size_ok(mle->data + 1, mle->datalen - 1))
		return NULL;

	/* Required length for first defragmentation */
	buf_len = mle->datalen - 1;
	for_each_element(elem, mle->data + mle->datalen,
			 ielen - sizeof(*mle) + mle->datalen) {
		if (elem->id != WLAN_EID_FRAGMENT)
			break;

		buf_len += elem->datalen;
	}

	res = kzalloc(struct_size(res, data, buf_len), gfp);
	if (!res)
		return NULL;

	mle_len = cfg80211_defragment_element(mle, ie, ielen,
					      res->data, buf_len,
					      WLAN_EID_FRAGMENT);
	if (mle_len < 0)
		goto error;

	res->mle = (void *)res->data;

	/* Find the sub-element area in the buffer */
	common_size = ieee80211_mle_common_size((u8 *)res->mle);
	ie = res->data + common_size;
	ielen = mle_len - common_size;

	idx = 0;
	for_each_element_id(elem, IEEE80211_MLE_SUBELEM_PER_STA_PROFILE,
			    ie, ielen) {
		res->sta_prof[idx] = (void *)elem->data;
		res->sta_prof_len[idx] = elem->datalen;

		idx++;
		if (idx >= IEEE80211_MLD_MAX_NUM_LINKS)
			break;
	}
	if (!for_each_element_completed(elem, ie, ielen))
		goto error;

	/* Defragment sta_info in-place */
	for (idx = 0; idx < IEEE80211_MLD_MAX_NUM_LINKS && res->sta_prof[idx];
	     idx++) {
		if (res->sta_prof_len[idx] < 255)
			continue;

		elem = (void *)res->sta_prof[idx] - 2;

		if (idx + 1 < ARRAY_SIZE(res->sta_prof) &&
		    res->sta_prof[idx + 1])
			buf_len = (u8 *)res->sta_prof[idx + 1] -
				  (u8 *)res->sta_prof[idx];
		else
			buf_len = ielen + ie - (u8 *)elem;

		res->sta_prof_len[idx] =
			cfg80211_defragment_element(elem,
						    (u8 *)elem, buf_len,
						    (u8 *)res->sta_prof[idx],
						    buf_len,
						    IEEE80211_MLE_SUBELEM_FRAGMENT);
		if (res->sta_prof_len[idx] < 0)
			goto error;
	}

	return res;

error:
	kfree(res);
	return NULL;
}

struct tbtt_info_iter_data {
	const struct ieee80211_neighbor_ap_info *ap_info;
	u8 param_ch_count;
	u32 use_for;
	u8 mld_id, link_id;
	bool non_tx;
};

static enum cfg80211_rnr_iter_ret
cfg802121_mld_ap_rnr_iter(void *_data, u8 type,
			  const struct ieee80211_neighbor_ap_info *info,
			  const u8 *tbtt_info, u8 tbtt_info_len)
{
	const struct ieee80211_rnr_mld_params *mld_params;
	struct tbtt_info_iter_data *data = _data;
	u8 link_id;
	bool non_tx = false;

	if (type == IEEE80211_TBTT_INFO_TYPE_TBTT &&
	    tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11,
					 mld_params)) {
		const struct ieee80211_tbtt_info_ge_11 *tbtt_info_ge_11 =
			(void *)tbtt_info;

		non_tx = (tbtt_info_ge_11->bss_params &
			  (IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID |
			   IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID)) ==
			 IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID;
		mld_params = &tbtt_info_ge_11->mld_params;
	} else if (type == IEEE80211_TBTT_INFO_TYPE_MLD &&
		 tbtt_info_len >= sizeof(struct ieee80211_rnr_mld_params))
		mld_params = (void *)tbtt_info;
	else
		return RNR_ITER_CONTINUE;

	link_id = le16_get_bits(mld_params->params,
				IEEE80211_RNR_MLD_PARAMS_LINK_ID);

	if (data->mld_id != mld_params->mld_id)
		return RNR_ITER_CONTINUE;

	if (data->link_id != link_id)
		return RNR_ITER_CONTINUE;

	data->ap_info = info;
	data->param_ch_count =
		le16_get_bits(mld_params->params,
			      IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT);
	data->non_tx = non_tx;

	if (type == IEEE80211_TBTT_INFO_TYPE_TBTT)
		data->use_for = NL80211_BSS_USE_FOR_ALL;
	else
		data->use_for = NL80211_BSS_USE_FOR_MLD_LINK;
	return RNR_ITER_BREAK;
}

static u8
cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
			     const struct ieee80211_neighbor_ap_info **ap_info,
			     u8 *param_ch_count, bool *non_tx)
{
	struct tbtt_info_iter_data data = {
		.mld_id = mld_id,
		.link_id = link_id,
	};

	cfg80211_iter_rnr(ie, ielen, cfg802121_mld_ap_rnr_iter, &data);

	*ap_info = data.ap_info;
	*param_ch_count = data.param_ch_count;
	*non_tx = data.non_tx;

	return data.use_for;
}

static struct element *
cfg80211_gen_reporter_rnr(struct cfg80211_bss *source_bss, bool is_mbssid,
			  bool same_mld, u8 link_id, u8 bss_change_count,
			  gfp_t gfp)
{
	const struct cfg80211_bss_ies *ies;
	struct ieee80211_neighbor_ap_info ap_info;
	struct ieee80211_tbtt_info_ge_11 tbtt_info;
	u32 short_ssid;
	const struct element *elem;
	struct element *res;

	/*
	 * We only generate the RNR to permit ML lookups. For that we do not
	 * need an entry for the corresponding transmitting BSS, lets just skip
	 * it even though it would be easy to add.
	 */
	if (!same_mld)
		return NULL;

	/* We could use tx_data->ies if we change cfg80211_calc_short_ssid */
	rcu_read_lock();
	ies = rcu_dereference(source_bss->ies);

	ap_info.tbtt_info_len = offsetofend(typeof(tbtt_info), mld_params);
	ap_info.tbtt_info_hdr =
			u8_encode_bits(IEEE80211_TBTT_INFO_TYPE_TBTT,
				       IEEE80211_AP_INFO_TBTT_HDR_TYPE) |
			u8_encode_bits(0, IEEE80211_AP_INFO_TBTT_HDR_COUNT);

	ap_info.channel = ieee80211_frequency_to_channel(source_bss->channel->center_freq);

	/* operating class */
	elem = cfg80211_find_elem(WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
				  ies->data, ies->len);
	if (elem && elem->datalen >= 1) {
		ap_info.op_class = elem->data[0];
	} else {
		struct cfg80211_chan_def chandef;

		/* The AP is not providing us with anything to work with. So
		 * make up a somewhat reasonable operating class, but don't
		 * bother with it too much as no one will ever use the
		 * information.
		 */
		cfg80211_chandef_create(&chandef, source_bss->channel,
					NL80211_CHAN_NO_HT);

		if (!ieee80211_chandef_to_operating_class(&chandef,
							  &ap_info.op_class))
			goto out_unlock;
	}

	/* Just set TBTT offset and PSD 20 to invalid/unknown */
	tbtt_info.tbtt_offset = 255;
	tbtt_info.psd_20 = IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED;

	memcpy(tbtt_info.bssid, source_bss->bssid, ETH_ALEN);
	if (cfg80211_calc_short_ssid(ies, &elem, &short_ssid))
		goto out_unlock;

	rcu_read_unlock();

	tbtt_info.short_ssid = cpu_to_le32(short_ssid);

	tbtt_info.bss_params = IEEE80211_RNR_TBTT_PARAMS_SAME_SSID;

	if (is_mbssid) {
		tbtt_info.bss_params |= IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID;
		tbtt_info.bss_params |= IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID;
	}

	tbtt_info.mld_params.mld_id = 0;
	tbtt_info.mld_params.params =
		le16_encode_bits(link_id, IEEE80211_RNR_MLD_PARAMS_LINK_ID) |
		le16_encode_bits(bss_change_count,
				 IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT);

	res = kzalloc(struct_size(res, data,
				  sizeof(ap_info) + ap_info.tbtt_info_len),
		      gfp);
	if (!res)
		return NULL;

	/* Copy the data */
	res->id = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
	res->datalen = sizeof(ap_info) + ap_info.tbtt_info_len;
	memcpy(res->data, &ap_info, sizeof(ap_info));
	memcpy(res->data + sizeof(ap_info), &tbtt_info, ap_info.tbtt_info_len);

	return res;

out_unlock:
	rcu_read_unlock();
	return NULL;
}

static void
cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy,
				struct cfg80211_inform_single_bss_data *tx_data,
				struct cfg80211_bss *source_bss,
				const struct element *elem,
				gfp_t gfp)
{
	struct cfg80211_inform_single_bss_data data = {
		.drv_data = tx_data->drv_data,
		.ftype = tx_data->ftype,
		.source_bss = source_bss,
		.bss_source = BSS_SOURCE_STA_PROFILE,
	};
	struct element *reporter_rnr = NULL;
	struct ieee80211_multi_link_elem *ml_elem;
	struct cfg80211_mle *mle;
	u16 control;
	u8 ml_common_len;
	u8 *new_ie = NULL;
	struct cfg80211_bss *bss;
	u8 mld_id, reporter_link_id, bss_change_count;
	u16 seen_links = 0;
	u8 i;

	if (!ieee80211_mle_type_ok(elem->data + 1,
				   IEEE80211_ML_CONTROL_TYPE_BASIC,
				   elem->datalen - 1))
		return;

	ml_elem = (void *)(elem->data + 1);
	control = le16_to_cpu(ml_elem->control);
	ml_common_len = ml_elem->variable[0];

	/* Must be present when transmitted by an AP (in a probe response) */
	if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) ||
	    !(control & IEEE80211_MLC_BASIC_PRES_LINK_ID) ||
	    !(control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP))
		return;

	reporter_link_id = ieee80211_mle_get_link_id(elem->data + 1);
	bss_change_count = ieee80211_mle_get_bss_param_ch_cnt(elem->data + 1);

	/*
	 * The MLD ID of the reporting AP is always zero. It is set if the AP
	 * is part of an MBSSID set and will be non-zero for ML Elements
	 * relating to a nontransmitted BSS (matching the Multi-BSSID Index,
	 * Draft P802.11be_D3.2, 35.3.4.2)
	 */
	mld_id = ieee80211_mle_get_mld_id(elem->data + 1);

	/* Fully defrag the ML element for sta information/profile iteration */
	mle = cfg80211_defrag_mle(elem, tx_data->ie, tx_data->ielen, gfp);
	if (!mle)
		return;

	/* No point in doing anything if there is no per-STA profile */
	if (!mle->sta_prof[0])
		goto out;

	new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
	if (!new_ie)
		goto out;

	reporter_rnr = cfg80211_gen_reporter_rnr(source_bss,
						 u16_get_bits(control,
							      IEEE80211_MLC_BASIC_PRES_MLD_ID),
						 mld_id == 0, reporter_link_id,
						 bss_change_count,
						 gfp);

	for (i = 0; i < ARRAY_SIZE(mle->sta_prof) && mle->sta_prof[i]; i++) {
		const struct ieee80211_neighbor_ap_info *ap_info;
		enum nl80211_band band;
		u32 freq;
		const u8 *profile;
		ssize_t profile_len;
		u8 param_ch_count;
		u8 link_id, use_for;
		bool non_tx;

		if (!ieee80211_mle_basic_sta_prof_size_ok((u8 *)mle->sta_prof[i],
							  mle->sta_prof_len[i]))
			continue;

		control = le16_to_cpu(mle->sta_prof[i]->control);

		if (!(control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE))
			continue;

		link_id = u16_get_bits(control,
				       IEEE80211_MLE_STA_CONTROL_LINK_ID);
		if (seen_links & BIT(link_id))
			break;
		seen_links |= BIT(link_id);

		if (!(control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) ||
		    !(control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) ||
		    !(control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT))
			continue;

		memcpy(data.bssid, mle->sta_prof[i]->variable, ETH_ALEN);
		data.beacon_interval =
			get_unaligned_le16(mle->sta_prof[i]->variable + 6);
		data.tsf = tx_data->tsf +
			   get_unaligned_le64(mle->sta_prof[i]->variable + 8);

		/* sta_info_len counts itself */
		profile = mle->sta_prof[i]->variable +
			  mle->sta_prof[i]->sta_info_len - 1;
		profile_len = (u8 *)mle->sta_prof[i] + mle->sta_prof_len[i] -
			      profile;

		if (profile_len < 2)
			continue;

		data.capability = get_unaligned_le16(profile);
		profile += 2;
		profile_len -= 2;

		/* Find in RNR to look up channel information */
		use_for = cfg80211_rnr_info_for_mld_ap(tx_data->ie,
						       tx_data->ielen,
						       mld_id, link_id,
						       &ap_info,
						       &param_ch_count,
						       &non_tx);
		if (!use_for)
			continue;

		/*
		 * As of 802.11be_D5.0, the specification does not give us any
		 * way of discovering both the MaxBSSID and the Multiple-BSSID
		 * Index. It does seem like the Multiple-BSSID Index element
		 * may be provided, but section 9.4.2.45 explicitly forbids
		 * including a Multiple-BSSID Element (in this case without any
		 * subelements).
		 * Without both pieces of information we cannot calculate the
		 * reference BSSID, so simply ignore the BSS.
		 */
		if (non_tx)
			continue;

		/* We could sanity check the BSSID is included */

		if (!ieee80211_operating_class_to_band(ap_info->op_class,
						       &band))
			continue;

		freq = ieee80211_channel_to_freq_khz(ap_info->channel, band);
		data.channel = ieee80211_get_channel_khz(wiphy, freq);

		if (use_for == NL80211_BSS_USE_FOR_MLD_LINK &&
		    !(wiphy->flags & WIPHY_FLAG_SUPPORTS_NSTR_NONPRIMARY)) {
			use_for = 0;
			data.cannot_use_reasons =
				NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY;
		}
		data.use_for = use_for;

		/* Generate new elements */
		memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
		data.ie = new_ie;
		data.ielen = cfg80211_gen_new_ie(tx_data->ie, tx_data->ielen,
						 profile, profile_len,
						 new_ie,
						 IEEE80211_MAX_DATA_LEN);
		if (!data.ielen)
			continue;

		/* The generated elements do not contain:
		 *  - Basic ML element
		 *  - A TBTT entry in the RNR for the transmitting AP
		 *
		 * This information is needed both internally and in userspace
		 * as such, we should append it here.
		 */
		if (data.ielen + 3 + sizeof(*ml_elem) + ml_common_len >
		    IEEE80211_MAX_DATA_LEN)
			continue;

		/* Copy the Basic Multi-Link element including the common
		 * information, and then fix up the link ID and BSS param
		 * change count.
		 * Note that the ML element length has been verified and we
		 * also checked that it contains the link ID.
		 */
		new_ie[data.ielen++] = WLAN_EID_EXTENSION;
		new_ie[data.ielen++] = 1 + sizeof(*ml_elem) + ml_common_len;
		new_ie[data.ielen++] = WLAN_EID_EXT_EHT_MULTI_LINK;
		memcpy(new_ie + data.ielen, ml_elem,
		       sizeof(*ml_elem) + ml_common_len);

		new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN] = link_id;
		new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN + 1] =
			param_ch_count;

		data.ielen += sizeof(*ml_elem) + ml_common_len;

		if (reporter_rnr && (use_for & NL80211_BSS_USE_FOR_NORMAL)) {
			if (data.ielen + sizeof(struct element) +
			    reporter_rnr->datalen > IEEE80211_MAX_DATA_LEN)
				continue;

			memcpy(new_ie + data.ielen, reporter_rnr,
			       sizeof(struct element) + reporter_rnr->datalen);
			data.ielen += sizeof(struct element) +
				      reporter_rnr->datalen;
		}

		bss = cfg80211_inform_single_bss_data(wiphy, &data, gfp);
		if (!bss)
			break;
		cfg80211_put_bss(wiphy, bss);
	}

out:
	kfree(reporter_rnr);
	kfree(new_ie);
	kfree(mle);
}

static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
				       struct cfg80211_inform_single_bss_data *tx_data,
				       struct cfg80211_bss *source_bss,
				       gfp_t gfp)
{
	const struct element *elem;

	if (!source_bss)
		return;

	if (tx_data->ftype != CFG80211_BSS_FTYPE_PRESP)
		return;

	for_each_element_extid(elem, WLAN_EID_EXT_EHT_MULTI_LINK,
			       tx_data->ie, tx_data->ielen)
		cfg80211_parse_ml_elem_sta_data(wiphy, tx_data, source_bss,
						elem, gfp);
}

struct cfg80211_bss *
cfg80211_inform_bss_data(struct wiphy *wiphy,
			 struct cfg80211_inform_bss *data,
			 enum cfg80211_bss_frame_type ftype,
			 const u8 *bssid, u64 tsf, u16 capability,
			 u16 beacon_interval, const u8 *ie, size_t ielen,
			 gfp_t gfp)
{
	struct cfg80211_inform_single_bss_data inform_data = {
		.drv_data = data,
		.ftype = ftype,
		.tsf = tsf,
		.capability = capability,
		.beacon_interval = beacon_interval,
		.ie = ie,
		.ielen = ielen,
		.use_for = data->restrict_use ?
				data->use_for :
				NL80211_BSS_USE_FOR_ALL,
		.cannot_use_reasons = data->cannot_use_reasons,
	};
	struct cfg80211_bss *res;

	memcpy(inform_data.bssid, bssid, ETH_ALEN);

	res = cfg80211_inform_single_bss_data(wiphy, &inform_data, gfp);
	if (!res)
		return NULL;

	/* don't do any further MBSSID/ML handling for S1G */
	if (ftype == CFG80211_BSS_FTYPE_S1G_BEACON)
		return res;

	cfg80211_parse_mbssid_data(wiphy, &inform_data, res, gfp);

	cfg80211_parse_ml_sta_data(wiphy, &inform_data, res, gfp);

	return res;
}
EXPORT_SYMBOL(cfg80211_inform_bss_data);

struct cfg80211_bss *
cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
			       struct cfg80211_inform_bss *data,
			       struct ieee80211_mgmt *mgmt, size_t len,
			       gfp_t gfp)
{
	size_t min_hdr_len;
	struct ieee80211_ext *ext = NULL;
	enum cfg80211_bss_frame_type ftype;
	u16 beacon_interval;
	const u8 *bssid;
	u16 capability;
	const u8 *ie;
	size_t ielen;
	u64 tsf;

	if (WARN_ON(!mgmt))
		return NULL;

	if (WARN_ON(!wiphy))
		return NULL;

	BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
		     offsetof(struct ieee80211_mgmt, u.beacon.variable));

	trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len);

	if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
		ext = (void *) mgmt;
		if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
			min_hdr_len = offsetof(struct ieee80211_ext,
					       u.s1g_short_beacon.variable);
		else
			min_hdr_len = offsetof(struct ieee80211_ext,
					       u.s1g_beacon.variable);
	} else {
		/* same for beacons */
		min_hdr_len = offsetof(struct ieee80211_mgmt,
				       u.probe_resp.variable);
	}

	if (WARN_ON(len < min_hdr_len))
		return NULL;

	ielen = len - min_hdr_len;
	ie = mgmt->u.probe_resp.variable;
	if (ext) {
		const struct ieee80211_s1g_bcn_compat_ie *compat;
		const struct element *elem;

		if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
			ie = ext->u.s1g_short_beacon.variable;
		else
			ie = ext->u.s1g_beacon.variable;

		elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, ie, ielen);
		if (!elem)
			return NULL;
		if (elem->datalen < sizeof(*compat))
			return NULL;
		compat = (void *)elem->data;
		bssid = ext->u.s1g_beacon.sa;
		capability = le16_to_cpu(compat->compat_info);
		beacon_interval = le16_to_cpu(compat->beacon_int);
	} else {
		bssid = mgmt->bssid;
		beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
		capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
	}

	tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);

	if (ieee80211_is_probe_resp(mgmt->frame_control))
		ftype = CFG80211_BSS_FTYPE_PRESP;
	else if (ext)
		ftype = CFG80211_BSS_FTYPE_S1G_BEACON;
	else
		ftype = CFG80211_BSS_FTYPE_BEACON;

	return cfg80211_inform_bss_data(wiphy, data, ftype,
					bssid, tsf, capability,
					beacon_interval, ie, ielen,
					gfp);
}
EXPORT_SYMBOL(cfg80211_inform_bss_frame_data);

void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);

	if (!pub)
		return;

	spin_lock_bh(&rdev->bss_lock);
	bss_ref_get(rdev, bss_from_pub(pub));
	spin_unlock_bh(&rdev->bss_lock);
}
EXPORT_SYMBOL(cfg80211_ref_bss);

void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);

	if (!pub)
		return;

	spin_lock_bh(&rdev->bss_lock);
	bss_ref_put(rdev, bss_from_pub(pub));
	spin_unlock_bh(&rdev->bss_lock);
}
EXPORT_SYMBOL(cfg80211_put_bss);

void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct cfg80211_internal_bss *bss, *tmp1;
	struct cfg80211_bss *nontrans_bss, *tmp;

	if (WARN_ON(!pub))
		return;

	bss = bss_from_pub(pub);

	spin_lock_bh(&rdev->bss_lock);
	if (list_empty(&bss->list))
		goto out;

	list_for_each_entry_safe(nontrans_bss, tmp,
				 &pub->nontrans_list,
				 nontrans_list) {
		tmp1 = bss_from_pub(nontrans_bss);
		if (__cfg80211_unlink_bss(rdev, tmp1))
			rdev->bss_generation++;
	}

	if (__cfg80211_unlink_bss(rdev, bss))
		rdev->bss_generation++;
out:
	spin_unlock_bh(&rdev->bss_lock);
}
EXPORT_SYMBOL(cfg80211_unlink_bss);

void cfg80211_bss_iter(struct wiphy *wiphy,
		       struct cfg80211_chan_def *chandef,
		       void (*iter)(struct wiphy *wiphy,
				    struct cfg80211_bss *bss,
				    void *data),
		       void *iter_data)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct cfg80211_internal_bss *bss;

	spin_lock_bh(&rdev->bss_lock);

	list_for_each_entry(bss, &rdev->bss_list, list) {
		if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel,
						     false))
			iter(wiphy, &bss->pub, iter_data);
	}

	spin_unlock_bh(&rdev->bss_lock);
}
EXPORT_SYMBOL(cfg80211_bss_iter);

void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
				     unsigned int link_id,
				     struct ieee80211_channel *chan)
{
	struct wiphy *wiphy = wdev->wiphy;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct cfg80211_internal_bss *cbss = wdev->links[link_id].client.current_bss;
	struct cfg80211_internal_bss *new = NULL;
	struct cfg80211_internal_bss *bss;
	struct cfg80211_bss *nontrans_bss;
	struct cfg80211_bss *tmp;

	spin_lock_bh(&rdev->bss_lock);

	/*
	 * Some APs use CSA also for bandwidth changes, i.e., without actually
	 * changing the control channel, so no need to update in such a case.
	 */
	if (cbss->pub.channel == chan)
		goto done;

	/* use transmitting bss */
	if (cbss->pub.transmitted_bss)
		cbss = bss_from_pub(cbss->pub.transmitted_bss);

	cbss->pub.channel = chan;

	list_for_each_entry(bss, &rdev->bss_list, list) {
		if (!cfg80211_bss_type_match(bss->pub.capability,
					     bss->pub.channel->band,
					     wdev->conn_bss_type))
			continue;

		if (bss == cbss)
			continue;

		if (!cmp_bss(&bss->pub, &cbss->pub, BSS_CMP_REGULAR)) {
			new = bss;
			break;
		}
	}

	if (new) {
		/* to save time, update IEs for transmitting bss only */
		cfg80211_update_known_bss(rdev, cbss, new, false);
		new->pub.proberesp_ies = NULL;
		new->pub.beacon_ies = NULL;

		list_for_each_entry_safe(nontrans_bss, tmp,
					 &new->pub.nontrans_list,
					 nontrans_list) {
			bss = bss_from_pub(nontrans_bss);
			if (__cfg80211_unlink_bss(rdev, bss))
				rdev->bss_generation++;
		}

		WARN_ON(atomic_read(&new->hold));
		if (!WARN_ON(!__cfg80211_unlink_bss(rdev, new)))
			rdev->bss_generation++;
	}
	cfg80211_rehash_bss(rdev, cbss);

	list_for_each_entry_safe(nontrans_bss, tmp,
				 &cbss->pub.nontrans_list,
				 nontrans_list) {
		bss = bss_from_pub(nontrans_bss);
		bss->pub.channel = chan;
		cfg80211_rehash_bss(rdev, bss);
	}

done:
	spin_unlock_bh(&rdev->bss_lock);
}

#ifdef CONFIG_CFG80211_WEXT
static struct cfg80211_registered_device *
cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
{
	struct cfg80211_registered_device *rdev;
	struct net_device *dev;

	ASSERT_RTNL();

	dev = dev_get_by_index(net, ifindex);
	if (!dev)
		return ERR_PTR(-ENODEV);
	if (dev->ieee80211_ptr)
		rdev = wiphy_to_rdev(dev->ieee80211_ptr->wiphy);
	else
		rdev = ERR_PTR(-ENODEV);
	dev_put(dev);
	return rdev;
}

int cfg80211_wext_siwscan(struct net_device *dev,
			  struct iw_request_info *info,
			  union iwreq_data *wrqu, char *extra)
{
	struct cfg80211_registered_device *rdev;
	struct wiphy *wiphy;
	struct iw_scan_req *wreq = NULL;
	struct cfg80211_scan_request *creq;
	int i, err, n_channels = 0;
	enum nl80211_band band;

	if (!netif_running(dev))
		return -ENETDOWN;

	if (wrqu->data.length == sizeof(struct iw_scan_req))
		wreq = (struct iw_scan_req *)extra;

	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);

	if (IS_ERR(rdev))
		return PTR_ERR(rdev);

	if (rdev->scan_req || rdev->scan_msg)
		return -EBUSY;

	wiphy = &rdev->wiphy;

	/* Determine number of channels, needed to allocate creq */
	if (wreq && wreq->num_channels) {
		/* Passed from userspace so should be checked */
		if (unlikely(wreq->num_channels > IW_MAX_FREQUENCIES))
			return -EINVAL;
		n_channels = wreq->num_channels;
	} else {
		n_channels = ieee80211_get_num_supported_channels(wiphy);
	}

	creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
		       n_channels * sizeof(void *),
		       GFP_ATOMIC);
	if (!creq)
		return -ENOMEM;

	creq->wiphy = wiphy;
	creq->wdev = dev->ieee80211_ptr;
	/* SSIDs come after channels */
	creq->ssids = (void *)&creq->channels[n_channels];
	creq->n_channels = n_channels;
	creq->n_ssids = 1;
	creq->scan_start = jiffies;

	/* translate "Scan on frequencies" request */
	i = 0;
	for (band = 0; band < NUM_NL80211_BANDS; band++) {
		int j;

		if (!wiphy->bands[band])
			continue;

		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
			/* ignore disabled channels */
			if (wiphy->bands[band]->channels[j].flags &
						IEEE80211_CHAN_DISABLED)
				continue;

			/* If we have a wireless request structure and the
			 * wireless request specifies frequencies, then search
			 * for the matching hardware channel.
			 */
			if (wreq && wreq->num_channels) {
				int k;
				int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
				for (k = 0; k < wreq->num_channels; k++) {
					struct iw_freq *freq =
						&wreq->channel_list[k];
					int wext_freq =
						cfg80211_wext_freq(freq);

					if (wext_freq == wiphy_freq)
						goto wext_freq_found;
				}
				goto wext_freq_not_found;
			}

		wext_freq_found:
			creq->channels[i] = &wiphy->bands[band]->channels[j];
			i++;
		wext_freq_not_found: ;
		}
	}
	/* No channels found? */
	if (!i) {
		err = -EINVAL;
		goto out;
	}

	/* Set real number of channels specified in creq->channels[] */
	creq->n_channels = i;

	/* translate "Scan for SSID" request */
	if (wreq) {
		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
				err = -EINVAL;
				goto out;
			}
			memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
			creq->ssids[0].ssid_len = wreq->essid_len;
		}
		if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) {
			creq->ssids = NULL;
			creq->n_ssids = 0;
		}
	}

	for (i = 0; i < NUM_NL80211_BANDS; i++)
		if (wiphy->bands[i])
			creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;

	eth_broadcast_addr(creq->bssid);

	wiphy_lock(&rdev->wiphy);

	rdev->scan_req = creq;
	err = rdev_scan(rdev, creq);
	if (err) {
		rdev->scan_req = NULL;
		/* creq will be freed below */
	} else {
		nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
		/* creq now owned by driver */
		creq = NULL;
		dev_hold(dev);
	}
	wiphy_unlock(&rdev->wiphy);
 out:
	kfree(creq);
	return err;
}
EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan);

static char *ieee80211_scan_add_ies(struct iw_request_info *info,
				    const struct cfg80211_bss_ies *ies,
				    char *current_ev, char *end_buf)
{
	const u8 *pos, *end, *next;
	struct iw_event iwe;

	if (!ies)
		return current_ev;

	/*
	 * If needed, fragment the IEs buffer (at IE boundaries) into short
	 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
	 */
	pos = ies->data;
	end = pos + ies->len;

	while (end - pos > IW_GENERIC_IE_MAX) {
		next = pos + 2 + pos[1];
		while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
			next = next + 2 + next[1];

		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = next - pos;
		current_ev = iwe_stream_add_point_check(info, current_ev,
							end_buf, &iwe,
							(void *)pos);
		if (IS_ERR(current_ev))
			return current_ev;
		pos = next;
	}

	if (end > pos) {
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = end - pos;
		current_ev = iwe_stream_add_point_check(info, current_ev,
							end_buf, &iwe,
							(void *)pos);
		if (IS_ERR(current_ev))
			return current_ev;
	}

	return current_ev;
}

static char *
ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
	      struct cfg80211_internal_bss *bss, char *current_ev,
	      char *end_buf)
{
	const struct cfg80211_bss_ies *ies;
	struct iw_event iwe;
	const u8 *ie;
	u8 buf[50];
	u8 *cfg, *p, *tmp;
	int rem, i, sig;
	bool ismesh = false;

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWAP;
	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
	memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
						IW_EV_ADDR_LEN);
	if (IS_ERR(current_ev))
		return current_ev;

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
	iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
	iwe.u.freq.e = 0;
	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
						IW_EV_FREQ_LEN);
	if (IS_ERR(current_ev))
		return current_ev;

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
	iwe.u.freq.m = bss->pub.channel->center_freq;
	iwe.u.freq.e = 6;
	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
						IW_EV_FREQ_LEN);
	if (IS_ERR(current_ev))
		return current_ev;

	if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVQUAL;
		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
				     IW_QUAL_NOISE_INVALID |
				     IW_QUAL_QUAL_UPDATED;
		switch (wiphy->signal_type) {
		case CFG80211_SIGNAL_TYPE_MBM:
			sig = bss->pub.signal / 100;
			iwe.u.qual.level = sig;
			iwe.u.qual.updated |= IW_QUAL_DBM;
			if (sig < -110)		/* rather bad */
				sig = -110;
			else if (sig > -40)	/* perfect */
				sig = -40;
			/* will give a range of 0 .. 70 */
			iwe.u.qual.qual = sig + 110;
			break;
		case CFG80211_SIGNAL_TYPE_UNSPEC:
			iwe.u.qual.level = bss->pub.signal;
			/* will give range 0 .. 100 */
			iwe.u.qual.qual = bss->pub.signal;
			break;
		default:
			/* not reached */
			break;
		}
		current_ev = iwe_stream_add_event_check(info, current_ev,
							end_buf, &iwe,
							IW_EV_QUAL_LEN);
		if (IS_ERR(current_ev))
			return current_ev;
	}

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWENCODE;
	if (bss->pub.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;
	current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
						&iwe, "");
	if (IS_ERR(current_ev))
		return current_ev;

	rcu_read_lock();
	ies = rcu_dereference(bss->pub.ies);
	rem = ies->len;
	ie = ies->data;

	while (rem >= 2) {
		/* invalid data */
		if (ie[1] > rem - 2)
			break;

		switch (ie[0]) {
		case WLAN_EID_SSID:
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = SIOCGIWESSID;
			iwe.u.data.length = ie[1];
			iwe.u.data.flags = 1;
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf, &iwe,
								(u8 *)ie + 2);
			if (IS_ERR(current_ev))
				goto unlock;
			break;
		case WLAN_EID_MESH_ID:
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = SIOCGIWESSID;
			iwe.u.data.length = ie[1];
			iwe.u.data.flags = 1;
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf, &iwe,
								(u8 *)ie + 2);
			if (IS_ERR(current_ev))
				goto unlock;
			break;
		case WLAN_EID_MESH_CONFIG:
			ismesh = true;
			if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
				break;
			cfg = (u8 *)ie + 2;
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = IWEVCUSTOM;
			iwe.u.data.length = sprintf(buf,
						    "Mesh Network Path Selection Protocol ID: 0x%02X",
						    cfg[0]);
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf,
								&iwe, buf);
			if (IS_ERR(current_ev))
				goto unlock;
			iwe.u.data.length = sprintf(buf,
						    "Path Selection Metric ID: 0x%02X",
						    cfg[1]);
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf,
								&iwe, buf);
			if (IS_ERR(current_ev))
				goto unlock;
			iwe.u.data.length = sprintf(buf,
						    "Congestion Control Mode ID: 0x%02X",
						    cfg[2]);
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf,
								&iwe, buf);
			if (IS_ERR(current_ev))
				goto unlock;
			iwe.u.data.length = sprintf(buf,
						    "Synchronization ID: 0x%02X",
						    cfg[3]);
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf,
								&iwe, buf);
			if (IS_ERR(current_ev))
				goto unlock;
			iwe.u.data.length = sprintf(buf,
						    "Authentication ID: 0x%02X",
						    cfg[4]);
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf,
								&iwe, buf);
			if (IS_ERR(current_ev))
				goto unlock;
			iwe.u.data.length = sprintf(buf,
						    "Formation Info: 0x%02X",
						    cfg[5]);
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf,
								&iwe, buf);
			if (IS_ERR(current_ev))
				goto unlock;
			iwe.u.data.length = sprintf(buf,
						    "Capabilities: 0x%02X",
						    cfg[6]);
			current_ev = iwe_stream_add_point_check(info,
								current_ev,
								end_buf,
								&iwe, buf);
			if (IS_ERR(current_ev))
				goto unlock;
			break;
		case WLAN_EID_SUPP_RATES:
		case WLAN_EID_EXT_SUPP_RATES:
			/* display all supported rates in readable format */
			p = current_ev + iwe_stream_lcp_len(info);

			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = SIOCGIWRATE;
			/* Those two flags are ignored... */
			iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;

			for (i = 0; i < ie[1]; i++) {
				iwe.u.bitrate.value =
					((ie[i + 2] & 0x7f) * 500000);
				tmp = p;
				p = iwe_stream_add_value(info, current_ev, p,
							 end_buf, &iwe,
							 IW_EV_PARAM_LEN);
				if (p == tmp) {
					current_ev = ERR_PTR(-E2BIG);
					goto unlock;
				}
			}
			current_ev = p;
			break;
		}
		rem -= ie[1] + 2;
		ie += ie[1] + 2;
	}

	if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
	    ismesh) {
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = SIOCGIWMODE;
		if (ismesh)
			iwe.u.mode = IW_MODE_MESH;
		else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
			iwe.u.mode = IW_MODE_MASTER;
		else
			iwe.u.mode = IW_MODE_ADHOC;
		current_ev = iwe_stream_add_event_check(info, current_ev,
							end_buf, &iwe,
							IW_EV_UINT_LEN);
		if (IS_ERR(current_ev))
			goto unlock;
	}

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = IWEVCUSTOM;
	iwe.u.data.length = sprintf(buf, "tsf=%016llx",
				    (unsigned long long)(ies->tsf));
	current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
						&iwe, buf);
	if (IS_ERR(current_ev))
		goto unlock;
	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = IWEVCUSTOM;
	iwe.u.data.length = sprintf(buf, " Last beacon: %ums ago",
				    elapsed_jiffies_msecs(bss->ts));
	current_ev = iwe_stream_add_point_check(info, current_ev,
						end_buf, &iwe, buf);
	if (IS_ERR(current_ev))
		goto unlock;

	current_ev = ieee80211_scan_add_ies(info, ies, current_ev, end_buf);

 unlock:
	rcu_read_unlock();
	return current_ev;
}


static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
				  struct iw_request_info *info,
				  char *buf, size_t len)
{
	char *current_ev = buf;
	char *end_buf = buf + len;
	struct cfg80211_internal_bss *bss;
	int err = 0;

	spin_lock_bh(&rdev->bss_lock);
	cfg80211_bss_expire(rdev);

	list_for_each_entry(bss, &rdev->bss_list, list) {
		if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
			err = -E2BIG;
			break;
		}
		current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
					   current_ev, end_buf);
		if (IS_ERR(current_ev)) {
			err = PTR_ERR(current_ev);
			break;
		}
	}
	spin_unlock_bh(&rdev->bss_lock);

	if (err)
		return err;
	return current_ev - buf;
}


int cfg80211_wext_giwscan(struct net_device *dev,
			  struct iw_request_info *info,
			  union iwreq_data *wrqu, char *extra)
{
	struct iw_point *data = &wrqu->data;
	struct cfg80211_registered_device *rdev;
	int res;

	if (!netif_running(dev))
		return -ENETDOWN;

	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);

	if (IS_ERR(rdev))
		return PTR_ERR(rdev);

	if (rdev->scan_req || rdev->scan_msg)
		return -EAGAIN;

	res = ieee80211_scan_results(rdev, info, extra, data->length);
	data->length = 0;
	if (res >= 0) {
		data->length = res;
		res = 0;
	}

	return res;
}
EXPORT_WEXT_HANDLER(cfg80211_wext_giwscan);
#endif
