// 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-2025 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;
	const u8 *mbssid_index_ie;
	u8 id, ext_id, bssid_index = 255;
	unsigned int match_len;

	non_inherit_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
						  subie, subie_len);

	mbssid_index_ie = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX, subie,
					   subie_len);
	if (mbssid_index_ie && mbssid_index_ie[1] > 0 &&
	    mbssid_index_ie[2] > 0 && mbssid_index_ie[2] <= 46)
		bssid_index = mbssid_index_ie[2];

	/* 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;
		}

		/* For ML probe response, match the MLE in the frame body with
		 * MLD id being 'bssid_index'
		 */
		if (parent->id == WLAN_EID_EXTENSION && parent->datalen > 1 &&
		    parent->data[0] == WLAN_EID_EXT_EHT_MULTI_LINK &&
		    bssid_index == ieee80211_mle_get_mld_id(parent->data + 1)) {
			if (!cfg80211_copy_elem_with_frags(parent,
							   ie, ielen,
							   &pos, new_ie,
							   new_ie_len))
				return 0;

			/* Continue here to prevent processing the MLE in
			 * sub-element, which AP MLD should not carry
			 */
			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), 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)) {
		struct cfg80211_colocated_ap *tmp;

		/* Don't add duplicate BSSIDs on the same channel. */
		list_for_each_entry(tmp, &data->ap_list, list) {
			if (ether_addr_equal(tmp->bssid, entry->bssid) &&
			    tmp->center_freq == entry->center_freq) {
				kfree(entry);
				return RNR_ITER_CONTINUE;
			}
		}

		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->n_channels++;
	request->channels[n_channels] = chan;
	if (add_to_6ghz)
		request->scan_6ghz_params[request->n_6ghz_params].channel_idx =
			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,
			      bool first_part)
{
	u8 i;
	struct cfg80211_colocated_ap *ap;
	int n_channels, count = 0, err;
	struct cfg80211_scan_request_int *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->req.scan_6ghz = true;
	rdev_req->req.first_part = first_part;

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

	iftd = ieee80211_get_sband_iftype_data(rdev->wiphy.bands[NL80211_BAND_6GHZ],
					       rdev_req->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->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->req.bssid) ||
			    !ether_addr_equal(rdev_req->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), 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, req.channels, n_channels);
	offs_ssids = size;
	size += sizeof(*request->req.ssids) * rdev_req->req.n_ssids;
	offs_6ghz_params = size;
	size += sizeof(*request->req.scan_6ghz_params) * count;
	offs_ies = size;
	size += rdev_req->req.ie_len;

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

	*request = *rdev_req;
	request->req.n_channels = 0;
	request->req.n_6ghz_params = 0;
	if (rdev_req->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->req.ssids = (void *)request + offs_ssids;
		memcpy(request->req.ssids, rdev_req->req.ssids,
		       sizeof(*request->req.ssids) * request->req.n_ssids);
	}
	request->req.scan_6ghz_params = (void *)request + offs_6ghz_params;

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

		memcpy(ie, rdev_req->req.ie, rdev_req->req.ie_len);
		request->req.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->req.n_ssids == 1 &&
	    request->req.ssids[0].ssid_len) {
		list_for_each_entry(ap, &coloc_ap_list, list) {
			if (ap->colocated_ess &&
			    cfg80211_find_ssid_match(ap, &request->req)) {
				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->req.n_channels; i++) {
		if (rdev_req->req.channels[i]->band == NL80211_BAND_6GHZ &&
		    ((need_scan_psc &&
		      cfg80211_channel_is_psc(rdev_req->req.channels[i])) ||
		     !(rdev_req->req.flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))) {
			cfg80211_scan_req_add_chan(&request->req,
						   rdev_req->req.channels[i],
						   false);
		}
	}

	if (!(rdev_req->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->req.scan_6ghz_params[request->req.n_6ghz_params];
		struct ieee80211_channel *chan =
			ieee80211_get_channel(&rdev->wiphy, ap->center_freq);

		if (!chan || chan->flags & IEEE80211_CHAN_DISABLED ||
		    !cfg80211_wdev_channel_allowed(rdev_req->req.wdev, chan))
			continue;

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

		if (!found)
			continue;

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

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

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

		cfg80211_scan_req_add_chan(&request->req, 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->req.n_6ghz_params++;
	}

skip:
	cfg80211_free_coloc_ap_list(&coloc_ap_list);

	if (request->req.n_channels) {
		struct cfg80211_scan_request_int *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 (!first_part && !WARN_ON(!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_int *request;
	struct cfg80211_scan_request_int *rdev_req = rdev->scan_req;
	u32 n_channels = 0, idx, i;

	if (!(rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ)) {
		rdev_req->req.first_part = true;
		return rdev_scan(rdev, rdev_req);
	}

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

	if (!n_channels)
		return cfg80211_scan_6ghz(rdev, true);

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

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

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

	rdev_req->req.scan_6ghz = false;
	rdev_req->req.first_part = true;
	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_int *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->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->req.scan_6ghz && !request->info.aborted &&
	    !cfg80211_scan_6ghz(rdev, false))
		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->req.flags & NL80211_SCAN_FLAG_FLUSH) {
		/* flush entries from previous scans */
		spin_lock_bh(&rdev->bss_lock);
		__cfg80211_bss_expire(rdev, request->req.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_request_int *intreq =
		container_of(request, struct cfg80211_scan_request_int, req);
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(request->wiphy);
	struct cfg80211_scan_info old_info = intreq->info;

	trace_cfg80211_scan_done(intreq, info);
	WARN_ON(intreq != rdev->scan_req &&
		intreq != rdev->int_scan_req);

	intreq->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) {
		intreq->info.scan_start_tsf = old_info.scan_start_tsf;
		memcpy(intreq->info.tsf_bssid, old_info.tsf_bssid,
		       sizeof(intreq->info.tsf_bssid));
	}

	intreq->notified = true;
	wiphy_work_queue(request->wiphy, &rdev->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);

	guard(wiphy)(&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);
		}
	}
}

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)
{
	guard(wiphy)(wiphy);

	cfg80211_sched_scan_stopped_locked(wiphy, reqid);
}
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 = secs_to_jiffies(age_secs);

	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);

		bss->ts = known->ts;
		bss->pub.ts_boottime = known->pub.ts_boottime;
	}
}

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 time stamps */
	known->ts = new->ts;
	known->pub.ts_boottime = new->pub.ts_boottime;

	/* 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);
			if (!new->pub.hidden_beacon_bss)
				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->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;
	known->bss_source = new->bss_source;

	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_access_pointer(tmp->pub.beacon_ies);
	if (ies)
		kfree_rcu(ies, rcu_head);
	ies = (void *)rcu_access_pointer(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_type 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,
			     u32 client_flags)
{
	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;

	return cfg80211_6ghz_power_type(he_6ghz_oper->control, client_flags);
}

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, flags)) {
	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.pub.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;
	tmp.bss_source = data->bss_source;

	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,
			 ie + ielen - mle->data - 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;
	const struct element *ssid_elem;
	const u8 *ssid = NULL;
	size_t ssid_len = 0;
	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);

	ssid_elem = cfg80211_find_elem(WLAN_EID_SSID, tx_data->ie,
				       tx_data->ielen);
	if (ssid_elem) {
		ssid = ssid_elem->data;
		ssid_len = ssid_elem->datalen;
	}

	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);

		/* Skip if RNR element specifies an unsupported channel */
		if (!data.channel)
			continue;

		/* Skip if BSS entry generated from MBSSID or DIRECT source
		 * frame data available already.
		 */
		bss = cfg80211_get_bss(wiphy, data.channel, data.bssid, ssid,
				       ssid_len, IEEE80211_BSS_TYPE_ANY,
				       IEEE80211_PRIVACY_ANY);
		if (bss) {
			struct cfg80211_internal_bss *ibss = bss_from_pub(bss);

			if (data.capability == bss->capability &&
			    ibss->bss_source != BSS_SOURCE_STA_PROFILE) {
				cfg80211_put_bss(wiphy, bss);
				continue;
			}
			cfg80211_put_bss(wiphy, bss);
		}

		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;
	size_t s1g_optional_len;

	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;
		s1g_optional_len =
			ieee80211_s1g_optional_len(ext->frame_control);
		min_hdr_len =
			offsetof(struct ieee80211_ext, u.s1g_beacon.variable) +
			s1g_optional_len;
	} 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;

		ie = ext->u.s1g_beacon.variable + s1g_optional_len;
		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_int *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(struct_size(creq, req.channels, n_channels) +
		       sizeof(struct cfg80211_ssid),
		       GFP_ATOMIC);
	if (!creq)
		return -ENOMEM;

	creq->req.wiphy = wiphy;
	creq->req.wdev = dev->ieee80211_ptr;
	/* SSIDs come after channels */
	creq->req.ssids = (void *)creq +
			  struct_size(creq, req.channels, n_channels);
	creq->req.n_channels = n_channels;
	creq->req.n_ssids = 1;
	creq->req.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++) {
			struct ieee80211_channel *chan;

			/* ignore disabled channels */
			chan = &wiphy->bands[band]->channels[j];
			if (chan->flags & IEEE80211_CHAN_DISABLED ||
			    !cfg80211_wdev_channel_allowed(creq->req.wdev, chan))
				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->req.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->req.channels[] */
	creq->req.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)
				return -EINVAL;
			memcpy(creq->req.ssids[0].ssid, wreq->essid,
			       wreq->essid_len);
			creq->req.ssids[0].ssid_len = wreq->essid_len;
		}
		if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) {
			creq->req.ssids = NULL;
			creq->req.n_ssids = 0;
		}
	}

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

	eth_broadcast_addr(creq->req.bssid);

	scoped_guard(wiphy, &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);
		}
	}

 out:
	kfree(creq);
	return err;
}

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;
}
#endif
