// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005-2006, Devicescape Software, Inc.
 * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
 * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 * Copyright (C) 2015-2017	Intel Deutschland GmbH
 * Copyright (C) 2018-2023 Intel Corporation
 *
 * utilities for mac80211
 */

#include <net/mac80211.h>
#include <linux/netdevice.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/bitmap.h>
#include <linux/crc32.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
#include <net/rtnetlink.h>
#include <kunit/visibility.h>

#include "ieee80211_i.h"
#include "driver-ops.h"
#include "rate.h"
#include "mesh.h"
#include "wme.h"
#include "led.h"
#include "wep.h"

/* privid for wiphys to determine whether they belong to us or not */
const void *const mac80211_wiphy_privid = &mac80211_wiphy_privid;

struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy)
{
	struct ieee80211_local *local;

	local = wiphy_priv(wiphy);
	return &local->hw;
}
EXPORT_SYMBOL(wiphy_to_ieee80211_hw);

u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
			enum nl80211_iftype type)
{
	__le16 fc = hdr->frame_control;

	if (ieee80211_is_data(fc)) {
		if (len < 24) /* drop incorrect hdr len (data) */
			return NULL;

		if (ieee80211_has_a4(fc))
			return NULL;
		if (ieee80211_has_tods(fc))
			return hdr->addr1;
		if (ieee80211_has_fromds(fc))
			return hdr->addr2;

		return hdr->addr3;
	}

	if (ieee80211_is_s1g_beacon(fc)) {
		struct ieee80211_ext *ext = (void *) hdr;

		return ext->u.s1g_beacon.sa;
	}

	if (ieee80211_is_mgmt(fc)) {
		if (len < 24) /* drop incorrect hdr len (mgmt) */
			return NULL;
		return hdr->addr3;
	}

	if (ieee80211_is_ctl(fc)) {
		if (ieee80211_is_pspoll(fc))
			return hdr->addr1;

		if (ieee80211_is_back_req(fc)) {
			switch (type) {
			case NL80211_IFTYPE_STATION:
				return hdr->addr2;
			case NL80211_IFTYPE_AP:
			case NL80211_IFTYPE_AP_VLAN:
				return hdr->addr1;
			default:
				break; /* fall through to the return */
			}
		}
	}

	return NULL;
}
EXPORT_SYMBOL(ieee80211_get_bssid);

void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
{
	struct sk_buff *skb;
	struct ieee80211_hdr *hdr;

	skb_queue_walk(&tx->skbs, skb) {
		hdr = (struct ieee80211_hdr *) skb->data;
		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
	}
}

int ieee80211_frame_duration(enum nl80211_band band, size_t len,
			     int rate, int erp, int short_preamble)
{
	int dur;

	/* calculate duration (in microseconds, rounded up to next higher
	 * integer if it includes a fractional microsecond) to send frame of
	 * len bytes (does not include FCS) at the given rate. Duration will
	 * also include SIFS.
	 *
	 * rate is in 100 kbps, so divident is multiplied by 10 in the
	 * DIV_ROUND_UP() operations.
	 */

	if (band == NL80211_BAND_5GHZ || erp) {
		/*
		 * OFDM:
		 *
		 * N_DBPS = DATARATE x 4
		 * N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS)
		 *	(16 = SIGNAL time, 6 = tail bits)
		 * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext
		 *
		 * T_SYM = 4 usec
		 * 802.11a - 18.5.2: aSIFSTime = 16 usec
		 * 802.11g - 19.8.4: aSIFSTime = 10 usec +
		 *	signal ext = 6 usec
		 */
		dur = 16; /* SIFS + signal ext */
		dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */
		dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */

		/* rates should already consider the channel bandwidth,
		 * don't apply divisor again.
		 */
		dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
					4 * rate); /* T_SYM x N_SYM */
	} else {
		/*
		 * 802.11b or 802.11g with 802.11b compatibility:
		 * 18.3.4: TXTIME = PreambleLength + PLCPHeaderTime +
		 * Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0.
		 *
		 * 802.11 (DS): 15.3.3, 802.11b: 18.3.4
		 * aSIFSTime = 10 usec
		 * aPreambleLength = 144 usec or 72 usec with short preamble
		 * aPLCPHeaderLength = 48 usec or 24 usec with short preamble
		 */
		dur = 10; /* aSIFSTime = 10 usec */
		dur += short_preamble ? (72 + 24) : (144 + 48);

		dur += DIV_ROUND_UP(8 * (len + 4) * 10, rate);
	}

	return dur;
}

/* Exported duration function for driver use */
__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
					struct ieee80211_vif *vif,
					enum nl80211_band band,
					size_t frame_len,
					struct ieee80211_rate *rate)
{
	struct ieee80211_sub_if_data *sdata;
	u16 dur;
	int erp;
	bool short_preamble = false;

	erp = 0;
	if (vif) {
		sdata = vif_to_sdata(vif);
		short_preamble = sdata->vif.bss_conf.use_short_preamble;
		if (sdata->deflink.operating_11g_mode)
			erp = rate->flags & IEEE80211_RATE_ERP_G;
	}

	dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp,
				       short_preamble);

	return cpu_to_le16(dur);
}
EXPORT_SYMBOL(ieee80211_generic_frame_duration);

__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
			      struct ieee80211_vif *vif, size_t frame_len,
			      const struct ieee80211_tx_info *frame_txctl)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_rate *rate;
	struct ieee80211_sub_if_data *sdata;
	bool short_preamble;
	int erp, bitrate;
	u16 dur;
	struct ieee80211_supported_band *sband;

	sband = local->hw.wiphy->bands[frame_txctl->band];

	short_preamble = false;

	rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];

	erp = 0;
	if (vif) {
		sdata = vif_to_sdata(vif);
		short_preamble = sdata->vif.bss_conf.use_short_preamble;
		if (sdata->deflink.operating_11g_mode)
			erp = rate->flags & IEEE80211_RATE_ERP_G;
	}

	bitrate = rate->bitrate;

	/* CTS duration */
	dur = ieee80211_frame_duration(sband->band, 10, bitrate,
				       erp, short_preamble);
	/* Data frame duration */
	dur += ieee80211_frame_duration(sband->band, frame_len, bitrate,
					erp, short_preamble);
	/* ACK duration */
	dur += ieee80211_frame_duration(sband->band, 10, bitrate,
					erp, short_preamble);

	return cpu_to_le16(dur);
}
EXPORT_SYMBOL(ieee80211_rts_duration);

__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
				    struct ieee80211_vif *vif,
				    size_t frame_len,
				    const struct ieee80211_tx_info *frame_txctl)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_rate *rate;
	struct ieee80211_sub_if_data *sdata;
	bool short_preamble;
	int erp, bitrate;
	u16 dur;
	struct ieee80211_supported_band *sband;

	sband = local->hw.wiphy->bands[frame_txctl->band];

	short_preamble = false;

	rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
	erp = 0;
	if (vif) {
		sdata = vif_to_sdata(vif);
		short_preamble = sdata->vif.bss_conf.use_short_preamble;
		if (sdata->deflink.operating_11g_mode)
			erp = rate->flags & IEEE80211_RATE_ERP_G;
	}

	bitrate = rate->bitrate;

	/* Data frame duration */
	dur = ieee80211_frame_duration(sband->band, frame_len, bitrate,
				       erp, short_preamble);
	if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
		/* ACK duration */
		dur += ieee80211_frame_duration(sband->band, 10, bitrate,
						erp, short_preamble);
	}

	return cpu_to_le16(dur);
}
EXPORT_SYMBOL(ieee80211_ctstoself_duration);

static void wake_tx_push_queue(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata,
			       struct ieee80211_txq *queue)
{
	struct ieee80211_tx_control control = {
		.sta = queue->sta,
	};
	struct sk_buff *skb;

	while (1) {
		skb = ieee80211_tx_dequeue(&local->hw, queue);
		if (!skb)
			break;

		drv_tx(local, &control, skb);
	}
}

/* wake_tx_queue handler for driver not implementing a custom one*/
void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
				    struct ieee80211_txq *txq)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
	struct ieee80211_txq *queue;

	spin_lock(&local->handle_wake_tx_queue_lock);

	/* Use ieee80211_next_txq() for airtime fairness accounting */
	ieee80211_txq_schedule_start(hw, txq->ac);
	while ((queue = ieee80211_next_txq(hw, txq->ac))) {
		wake_tx_push_queue(local, sdata, queue);
		ieee80211_return_txq(hw, queue, false);
	}
	ieee80211_txq_schedule_end(hw, txq->ac);
	spin_unlock(&local->handle_wake_tx_queue_lock);
}
EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue);

static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_vif *vif = &sdata->vif;
	struct fq *fq = &local->fq;
	struct ps_data *ps = NULL;
	struct txq_info *txqi;
	struct sta_info *sta;
	int i;

	local_bh_disable();
	spin_lock(&fq->lock);

	if (!test_bit(SDATA_STATE_RUNNING, &sdata->state))
		goto out;

	if (sdata->vif.type == NL80211_IFTYPE_AP)
		ps = &sdata->bss->ps;

	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sdata != sta->sdata)
			continue;

		for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
			struct ieee80211_txq *txq = sta->sta.txq[i];

			if (!txq)
				continue;

			txqi = to_txq_info(txq);

			if (ac != txq->ac)
				continue;

			if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY,
						&txqi->flags))
				continue;

			spin_unlock(&fq->lock);
			drv_wake_tx_queue(local, txqi);
			spin_lock(&fq->lock);
		}
	}

	if (!vif->txq)
		goto out;

	txqi = to_txq_info(vif->txq);

	if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY, &txqi->flags) ||
	    (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac)
		goto out;

	spin_unlock(&fq->lock);

	drv_wake_tx_queue(local, txqi);
	local_bh_enable();
	return;
out:
	spin_unlock(&fq->lock);
	local_bh_enable();
}

static void
__releases(&local->queue_stop_reason_lock)
__acquires(&local->queue_stop_reason_lock)
_ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags)
{
	struct ieee80211_sub_if_data *sdata;
	int n_acs = IEEE80211_NUM_ACS;
	int i;

	rcu_read_lock();

	if (local->hw.queues < IEEE80211_NUM_ACS)
		n_acs = 1;

	for (i = 0; i < local->hw.queues; i++) {
		if (local->queue_stop_reasons[i])
			continue;

		spin_unlock_irqrestore(&local->queue_stop_reason_lock, *flags);
		list_for_each_entry_rcu(sdata, &local->interfaces, list) {
			int ac;

			for (ac = 0; ac < n_acs; ac++) {
				int ac_queue = sdata->vif.hw_queue[ac];

				if (ac_queue == i ||
				    sdata->vif.cab_queue == i)
					__ieee80211_wake_txqs(sdata, ac);
			}
		}
		spin_lock_irqsave(&local->queue_stop_reason_lock, *flags);
	}

	rcu_read_unlock();
}

void ieee80211_wake_txqs(struct tasklet_struct *t)
{
	struct ieee80211_local *local = from_tasklet(local, t,
						     wake_txqs_tasklet);
	unsigned long flags;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	_ieee80211_wake_txqs(local, &flags);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
				   enum queue_stop_reason reason,
				   bool refcounted,
				   unsigned long *flags)
{
	struct ieee80211_local *local = hw_to_local(hw);

	trace_wake_queue(local, queue, reason);

	if (WARN_ON(queue >= hw->queues))
		return;

	if (!test_bit(reason, &local->queue_stop_reasons[queue]))
		return;

	if (!refcounted) {
		local->q_stop_reasons[queue][reason] = 0;
	} else {
		local->q_stop_reasons[queue][reason]--;
		if (WARN_ON(local->q_stop_reasons[queue][reason] < 0))
			local->q_stop_reasons[queue][reason] = 0;
	}

	if (local->q_stop_reasons[queue][reason] == 0)
		__clear_bit(reason, &local->queue_stop_reasons[queue]);

	if (local->queue_stop_reasons[queue] != 0)
		/* someone still has this queue stopped */
		return;

	if (!skb_queue_empty(&local->pending[queue]))
		tasklet_schedule(&local->tx_pending_tasklet);

	/*
	 * Calling _ieee80211_wake_txqs here can be a problem because it may
	 * release queue_stop_reason_lock which has been taken by
	 * __ieee80211_wake_queue's caller. It is certainly not very nice to
	 * release someone's lock, but it is fine because all the callers of
	 * __ieee80211_wake_queue call it right before releasing the lock.
	 */
	if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER)
		tasklet_schedule(&local->wake_txqs_tasklet);
	else
		_ieee80211_wake_txqs(local, flags);
}

void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
				    enum queue_stop_reason reason,
				    bool refcounted)
{
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	__ieee80211_wake_queue(hw, queue, reason, refcounted, &flags);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
{
	ieee80211_wake_queue_by_reason(hw, queue,
				       IEEE80211_QUEUE_STOP_REASON_DRIVER,
				       false);
}
EXPORT_SYMBOL(ieee80211_wake_queue);

static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
				   enum queue_stop_reason reason,
				   bool refcounted)
{
	struct ieee80211_local *local = hw_to_local(hw);

	trace_stop_queue(local, queue, reason);

	if (WARN_ON(queue >= hw->queues))
		return;

	if (!refcounted)
		local->q_stop_reasons[queue][reason] = 1;
	else
		local->q_stop_reasons[queue][reason]++;

	set_bit(reason, &local->queue_stop_reasons[queue]);
}

void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
				    enum queue_stop_reason reason,
				    bool refcounted)
{
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	__ieee80211_stop_queue(hw, queue, reason, refcounted);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
{
	ieee80211_stop_queue_by_reason(hw, queue,
				       IEEE80211_QUEUE_STOP_REASON_DRIVER,
				       false);
}
EXPORT_SYMBOL(ieee80211_stop_queue);

void ieee80211_add_pending_skb(struct ieee80211_local *local,
			       struct sk_buff *skb)
{
	struct ieee80211_hw *hw = &local->hw;
	unsigned long flags;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	int queue = info->hw_queue;

	if (WARN_ON(!info->control.vif)) {
		ieee80211_free_txskb(&local->hw, skb);
		return;
	}

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	__ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
			       false);
	__skb_queue_tail(&local->pending[queue], skb);
	__ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
			       false, &flags);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_add_pending_skbs(struct ieee80211_local *local,
				struct sk_buff_head *skbs)
{
	struct ieee80211_hw *hw = &local->hw;
	struct sk_buff *skb;
	unsigned long flags;
	int queue, i;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	while ((skb = skb_dequeue(skbs))) {
		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

		if (WARN_ON(!info->control.vif)) {
			ieee80211_free_txskb(&local->hw, skb);
			continue;
		}

		queue = info->hw_queue;

		__ieee80211_stop_queue(hw, queue,
				IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
				false);

		__skb_queue_tail(&local->pending[queue], skb);
	}

	for (i = 0; i < hw->queues; i++)
		__ieee80211_wake_queue(hw, i,
			IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
			false, &flags);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
				     unsigned long queues,
				     enum queue_stop_reason reason,
				     bool refcounted)
{
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;
	int i;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);

	for_each_set_bit(i, &queues, hw->queues)
		__ieee80211_stop_queue(hw, i, reason, refcounted);

	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_stop_queues(struct ieee80211_hw *hw)
{
	ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
					IEEE80211_QUEUE_STOP_REASON_DRIVER,
					false);
}
EXPORT_SYMBOL(ieee80211_stop_queues);

int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
{
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;
	int ret;

	if (WARN_ON(queue >= hw->queues))
		return true;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	ret = test_bit(IEEE80211_QUEUE_STOP_REASON_DRIVER,
		       &local->queue_stop_reasons[queue]);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
	return ret;
}
EXPORT_SYMBOL(ieee80211_queue_stopped);

void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
				     unsigned long queues,
				     enum queue_stop_reason reason,
				     bool refcounted)
{
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;
	int i;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);

	for_each_set_bit(i, &queues, hw->queues)
		__ieee80211_wake_queue(hw, i, reason, refcounted, &flags);

	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_wake_queues(struct ieee80211_hw *hw)
{
	ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
					IEEE80211_QUEUE_STOP_REASON_DRIVER,
					false);
}
EXPORT_SYMBOL(ieee80211_wake_queues);

static unsigned int
ieee80211_get_vif_queues(struct ieee80211_local *local,
			 struct ieee80211_sub_if_data *sdata)
{
	unsigned int queues;

	if (sdata && ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
		int ac;

		queues = 0;

		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
			queues |= BIT(sdata->vif.hw_queue[ac]);
		if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE)
			queues |= BIT(sdata->vif.cab_queue);
	} else {
		/* all queues */
		queues = BIT(local->hw.queues) - 1;
	}

	return queues;
}

void __ieee80211_flush_queues(struct ieee80211_local *local,
			      struct ieee80211_sub_if_data *sdata,
			      unsigned int queues, bool drop)
{
	if (!local->ops->flush)
		return;

	/*
	 * If no queue was set, or if the HW doesn't support
	 * IEEE80211_HW_QUEUE_CONTROL - flush all queues
	 */
	if (!queues || !ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
		queues = ieee80211_get_vif_queues(local, sdata);

	ieee80211_stop_queues_by_reason(&local->hw, queues,
					IEEE80211_QUEUE_STOP_REASON_FLUSH,
					false);

	if (drop) {
		struct sta_info *sta;

		/* Purge the queues, so the frames on them won't be
		 * sent during __ieee80211_wake_queue()
		 */
		list_for_each_entry(sta, &local->sta_list, list) {
			if (sdata != sta->sdata)
				continue;
			ieee80211_purge_sta_txqs(sta);
		}
	}

	drv_flush(local, sdata, queues, drop);

	ieee80211_wake_queues_by_reason(&local->hw, queues,
					IEEE80211_QUEUE_STOP_REASON_FLUSH,
					false);
}

void ieee80211_flush_queues(struct ieee80211_local *local,
			    struct ieee80211_sub_if_data *sdata, bool drop)
{
	__ieee80211_flush_queues(local, sdata, 0, drop);
}

void ieee80211_stop_vif_queues(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata,
			       enum queue_stop_reason reason)
{
	ieee80211_stop_queues_by_reason(&local->hw,
					ieee80211_get_vif_queues(local, sdata),
					reason, true);
}

void ieee80211_wake_vif_queues(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata,
			       enum queue_stop_reason reason)
{
	ieee80211_wake_queues_by_reason(&local->hw,
					ieee80211_get_vif_queues(local, sdata),
					reason, true);
}

static void __iterate_interfaces(struct ieee80211_local *local,
				 u32 iter_flags,
				 void (*iterator)(void *data, u8 *mac,
						  struct ieee80211_vif *vif),
				 void *data)
{
	struct ieee80211_sub_if_data *sdata;
	bool active_only = iter_flags & IEEE80211_IFACE_ITER_ACTIVE;

	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
		switch (sdata->vif.type) {
		case NL80211_IFTYPE_MONITOR:
			if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
				continue;
			break;
		case NL80211_IFTYPE_AP_VLAN:
			continue;
		default:
			break;
		}
		if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) &&
		    active_only && !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
			continue;
		if ((iter_flags & IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER) &&
		    !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
			continue;
		if (ieee80211_sdata_running(sdata) || !active_only)
			iterator(data, sdata->vif.addr,
				 &sdata->vif);
	}

	sdata = rcu_dereference_check(local->monitor_sdata,
				      lockdep_is_held(&local->iflist_mtx) ||
				      lockdep_is_held(&local->hw.wiphy->mtx));
	if (sdata &&
	    (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only ||
	     sdata->flags & IEEE80211_SDATA_IN_DRIVER))
		iterator(data, sdata->vif.addr, &sdata->vif);
}

void ieee80211_iterate_interfaces(
	struct ieee80211_hw *hw, u32 iter_flags,
	void (*iterator)(void *data, u8 *mac,
			 struct ieee80211_vif *vif),
	void *data)
{
	struct ieee80211_local *local = hw_to_local(hw);

	mutex_lock(&local->iflist_mtx);
	__iterate_interfaces(local, iter_flags, iterator, data);
	mutex_unlock(&local->iflist_mtx);
}
EXPORT_SYMBOL_GPL(ieee80211_iterate_interfaces);

void ieee80211_iterate_active_interfaces_atomic(
	struct ieee80211_hw *hw, u32 iter_flags,
	void (*iterator)(void *data, u8 *mac,
			 struct ieee80211_vif *vif),
	void *data)
{
	struct ieee80211_local *local = hw_to_local(hw);

	rcu_read_lock();
	__iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE,
			     iterator, data);
	rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);

void ieee80211_iterate_active_interfaces_mtx(
	struct ieee80211_hw *hw, u32 iter_flags,
	void (*iterator)(void *data, u8 *mac,
			 struct ieee80211_vif *vif),
	void *data)
{
	struct ieee80211_local *local = hw_to_local(hw);

	lockdep_assert_wiphy(hw->wiphy);

	__iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE,
			     iterator, data);
}
EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_mtx);

static void __iterate_stations(struct ieee80211_local *local,
			       void (*iterator)(void *data,
						struct ieee80211_sta *sta),
			       void *data)
{
	struct sta_info *sta;

	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (!sta->uploaded)
			continue;

		iterator(data, &sta->sta);
	}
}

void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
			void (*iterator)(void *data,
					 struct ieee80211_sta *sta),
			void *data)
{
	struct ieee80211_local *local = hw_to_local(hw);

	rcu_read_lock();
	__iterate_stations(local, iterator, data);
	rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic);

struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);

	if (!ieee80211_sdata_running(sdata) ||
	    !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
		return NULL;
	return &sdata->vif;
}
EXPORT_SYMBOL_GPL(wdev_to_ieee80211_vif);

struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
{
	if (!vif)
		return NULL;

	return &vif_to_sdata(vif)->wdev;
}
EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev);

/*
 * Nothing should have been stuffed into the workqueue during
 * the suspend->resume cycle. Since we can't check each caller
 * of this function if we are already quiescing / suspended,
 * check here and don't WARN since this can actually happen when
 * the rx path (for example) is racing against __ieee80211_suspend
 * and suspending / quiescing was set after the rx path checked
 * them.
 */
static bool ieee80211_can_queue_work(struct ieee80211_local *local)
{
	if (local->quiescing || (local->suspended && !local->resuming)) {
		pr_warn("queueing ieee80211 work while going to suspend\n");
		return false;
	}

	return true;
}

void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
{
	struct ieee80211_local *local = hw_to_local(hw);

	if (!ieee80211_can_queue_work(local))
		return;

	queue_work(local->workqueue, work);
}
EXPORT_SYMBOL(ieee80211_queue_work);

void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
				  struct delayed_work *dwork,
				  unsigned long delay)
{
	struct ieee80211_local *local = hw_to_local(hw);

	if (!ieee80211_can_queue_work(local))
		return;

	queue_delayed_work(local->workqueue, dwork, delay);
}
EXPORT_SYMBOL(ieee80211_queue_delayed_work);

static void
ieee80211_parse_extension_element(u32 *crc,
				  const struct element *elem,
				  struct ieee802_11_elems *elems,
				  struct ieee80211_elems_parse_params *params)
{
	const void *data = elem->data + 1;
	bool calc_crc = false;
	u8 len;

	if (!elem->datalen)
		return;

	len = elem->datalen - 1;

	switch (elem->data[0]) {
	case WLAN_EID_EXT_HE_MU_EDCA:
		calc_crc = true;
		if (len >= sizeof(*elems->mu_edca_param_set))
			elems->mu_edca_param_set = data;
		break;
	case WLAN_EID_EXT_HE_CAPABILITY:
		if (ieee80211_he_capa_size_ok(data, len)) {
			elems->he_cap = data;
			elems->he_cap_len = len;
		}
		break;
	case WLAN_EID_EXT_HE_OPERATION:
		calc_crc = true;
		if (len >= sizeof(*elems->he_operation) &&
		    len >= ieee80211_he_oper_size(data) - 1)
			elems->he_operation = data;
		break;
	case WLAN_EID_EXT_UORA:
		if (len >= 1)
			elems->uora_element = data;
		break;
	case WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME:
		if (len == 3)
			elems->max_channel_switch_time = data;
		break;
	case WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION:
		if (len >= sizeof(*elems->mbssid_config_ie))
			elems->mbssid_config_ie = data;
		break;
	case WLAN_EID_EXT_HE_SPR:
		if (len >= sizeof(*elems->he_spr) &&
		    len >= ieee80211_he_spr_size(data))
			elems->he_spr = data;
		break;
	case WLAN_EID_EXT_HE_6GHZ_CAPA:
		if (len >= sizeof(*elems->he_6ghz_capa))
			elems->he_6ghz_capa = data;
		break;
	case WLAN_EID_EXT_EHT_CAPABILITY:
		if (ieee80211_eht_capa_size_ok(elems->he_cap,
					       data, len,
					       params->from_ap)) {
			elems->eht_cap = data;
			elems->eht_cap_len = len;
		}
		break;
	case WLAN_EID_EXT_EHT_OPERATION:
		if (ieee80211_eht_oper_size_ok(data, len))
			elems->eht_operation = data;
		calc_crc = true;
		break;
	case WLAN_EID_EXT_EHT_MULTI_LINK:
		calc_crc = true;

		if (ieee80211_mle_size_ok(data, len)) {
			const struct ieee80211_multi_link_elem *mle =
				(void *)data;

			switch (le16_get_bits(mle->control,
					      IEEE80211_ML_CONTROL_TYPE)) {
			case IEEE80211_ML_CONTROL_TYPE_BASIC:
				elems->ml_basic_elem = (void *)elem;
				elems->ml_basic = data;
				elems->ml_basic_len = len;
				break;
			case IEEE80211_ML_CONTROL_TYPE_RECONF:
				elems->ml_reconf_elem = (void *)elem;
				elems->ml_reconf = data;
				elems->ml_reconf_len = len;
				break;
			default:
				break;
			}
		}
		break;
	case WLAN_EID_EXT_BANDWIDTH_INDICATION:
		if (ieee80211_bandwidth_indication_size_ok(data, len))
			elems->bandwidth_indication = data;
		calc_crc = true;
		break;
	case WLAN_EID_EXT_TID_TO_LINK_MAPPING:
		calc_crc = true;
		if (ieee80211_tid_to_link_map_size_ok(data, len) &&
		    elems->ttlm_num < ARRAY_SIZE(elems->ttlm)) {
			elems->ttlm[elems->ttlm_num] = (void *)data;
			elems->ttlm_num++;
		}
		break;
	}

	if (crc && calc_crc)
		*crc = crc32_be(*crc, (void *)elem, elem->datalen + 2);
}

static u32
_ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
			     struct ieee802_11_elems *elems,
			     const struct element *check_inherit)
{
	const struct element *elem;
	bool calc_crc = params->filter != 0;
	DECLARE_BITMAP(seen_elems, 256);
	u32 crc = params->crc;

	bitmap_zero(seen_elems, 256);

	for_each_element(elem, params->start, params->len) {
		const struct element *subelem;
		bool elem_parse_failed;
		u8 id = elem->id;
		u8 elen = elem->datalen;
		const u8 *pos = elem->data;

		if (check_inherit &&
		    !cfg80211_is_element_inherited(elem,
						   check_inherit))
			continue;

		switch (id) {
		case WLAN_EID_SSID:
		case WLAN_EID_SUPP_RATES:
		case WLAN_EID_FH_PARAMS:
		case WLAN_EID_DS_PARAMS:
		case WLAN_EID_CF_PARAMS:
		case WLAN_EID_TIM:
		case WLAN_EID_IBSS_PARAMS:
		case WLAN_EID_CHALLENGE:
		case WLAN_EID_RSN:
		case WLAN_EID_ERP_INFO:
		case WLAN_EID_EXT_SUPP_RATES:
		case WLAN_EID_HT_CAPABILITY:
		case WLAN_EID_HT_OPERATION:
		case WLAN_EID_VHT_CAPABILITY:
		case WLAN_EID_VHT_OPERATION:
		case WLAN_EID_MESH_ID:
		case WLAN_EID_MESH_CONFIG:
		case WLAN_EID_PEER_MGMT:
		case WLAN_EID_PREQ:
		case WLAN_EID_PREP:
		case WLAN_EID_PERR:
		case WLAN_EID_RANN:
		case WLAN_EID_CHANNEL_SWITCH:
		case WLAN_EID_EXT_CHANSWITCH_ANN:
		case WLAN_EID_COUNTRY:
		case WLAN_EID_PWR_CONSTRAINT:
		case WLAN_EID_TIMEOUT_INTERVAL:
		case WLAN_EID_SECONDARY_CHANNEL_OFFSET:
		case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
		case WLAN_EID_CHAN_SWITCH_PARAM:
		case WLAN_EID_EXT_CAPABILITY:
		case WLAN_EID_CHAN_SWITCH_TIMING:
		case WLAN_EID_LINK_ID:
		case WLAN_EID_BSS_MAX_IDLE_PERIOD:
		case WLAN_EID_RSNX:
		case WLAN_EID_S1G_BCN_COMPAT:
		case WLAN_EID_S1G_CAPABILITIES:
		case WLAN_EID_S1G_OPERATION:
		case WLAN_EID_AID_RESPONSE:
		case WLAN_EID_S1G_SHORT_BCN_INTERVAL:
		/*
		 * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible
		 * that if the content gets bigger it might be needed more than once
		 */
			if (test_bit(id, seen_elems)) {
				elems->parse_error = true;
				continue;
			}
			break;
		}

		if (calc_crc && id < 64 && (params->filter & (1ULL << id)))
			crc = crc32_be(crc, pos - 2, elen + 2);

		elem_parse_failed = false;

		switch (id) {
		case WLAN_EID_LINK_ID:
			if (elen + 2 < sizeof(struct ieee80211_tdls_lnkie)) {
				elem_parse_failed = true;
				break;
			}
			elems->lnk_id = (void *)(pos - 2);
			break;
		case WLAN_EID_CHAN_SWITCH_TIMING:
			if (elen < sizeof(struct ieee80211_ch_switch_timing)) {
				elem_parse_failed = true;
				break;
			}
			elems->ch_sw_timing = (void *)pos;
			break;
		case WLAN_EID_EXT_CAPABILITY:
			elems->ext_capab = pos;
			elems->ext_capab_len = elen;
			break;
		case WLAN_EID_SSID:
			elems->ssid = pos;
			elems->ssid_len = elen;
			break;
		case WLAN_EID_SUPP_RATES:
			elems->supp_rates = pos;
			elems->supp_rates_len = elen;
			break;
		case WLAN_EID_DS_PARAMS:
			if (elen >= 1)
				elems->ds_params = pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_TIM:
			if (elen >= sizeof(struct ieee80211_tim_ie)) {
				elems->tim = (void *)pos;
				elems->tim_len = elen;
			} else
				elem_parse_failed = true;
			break;
		case WLAN_EID_VENDOR_SPECIFIC:
			if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
			    pos[2] == 0xf2) {
				/* Microsoft OUI (00:50:F2) */

				if (calc_crc)
					crc = crc32_be(crc, pos - 2, elen + 2);

				if (elen >= 5 && pos[3] == 2) {
					/* OUI Type 2 - WMM IE */
					if (pos[4] == 0) {
						elems->wmm_info = pos;
						elems->wmm_info_len = elen;
					} else if (pos[4] == 1) {
						elems->wmm_param = pos;
						elems->wmm_param_len = elen;
					}
				}
			}
			break;
		case WLAN_EID_RSN:
			elems->rsn = pos;
			elems->rsn_len = elen;
			break;
		case WLAN_EID_ERP_INFO:
			if (elen >= 1)
				elems->erp_info = pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_EXT_SUPP_RATES:
			elems->ext_supp_rates = pos;
			elems->ext_supp_rates_len = elen;
			break;
		case WLAN_EID_HT_CAPABILITY:
			if (elen >= sizeof(struct ieee80211_ht_cap))
				elems->ht_cap_elem = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_HT_OPERATION:
			if (elen >= sizeof(struct ieee80211_ht_operation))
				elems->ht_operation = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_VHT_CAPABILITY:
			if (elen >= sizeof(struct ieee80211_vht_cap))
				elems->vht_cap_elem = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_VHT_OPERATION:
			if (elen >= sizeof(struct ieee80211_vht_operation)) {
				elems->vht_operation = (void *)pos;
				if (calc_crc)
					crc = crc32_be(crc, pos - 2, elen + 2);
				break;
			}
			elem_parse_failed = true;
			break;
		case WLAN_EID_OPMODE_NOTIF:
			if (elen > 0) {
				elems->opmode_notif = pos;
				if (calc_crc)
					crc = crc32_be(crc, pos - 2, elen + 2);
				break;
			}
			elem_parse_failed = true;
			break;
		case WLAN_EID_MESH_ID:
			elems->mesh_id = pos;
			elems->mesh_id_len = elen;
			break;
		case WLAN_EID_MESH_CONFIG:
			if (elen >= sizeof(struct ieee80211_meshconf_ie))
				elems->mesh_config = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_PEER_MGMT:
			elems->peering = pos;
			elems->peering_len = elen;
			break;
		case WLAN_EID_MESH_AWAKE_WINDOW:
			if (elen >= 2)
				elems->awake_window = (void *)pos;
			break;
		case WLAN_EID_PREQ:
			elems->preq = pos;
			elems->preq_len = elen;
			break;
		case WLAN_EID_PREP:
			elems->prep = pos;
			elems->prep_len = elen;
			break;
		case WLAN_EID_PERR:
			elems->perr = pos;
			elems->perr_len = elen;
			break;
		case WLAN_EID_RANN:
			if (elen >= sizeof(struct ieee80211_rann_ie))
				elems->rann = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_CHANNEL_SWITCH:
			if (elen != sizeof(struct ieee80211_channel_sw_ie)) {
				elem_parse_failed = true;
				break;
			}
			elems->ch_switch_ie = (void *)pos;
			break;
		case WLAN_EID_EXT_CHANSWITCH_ANN:
			if (elen != sizeof(struct ieee80211_ext_chansw_ie)) {
				elem_parse_failed = true;
				break;
			}
			elems->ext_chansw_ie = (void *)pos;
			break;
		case WLAN_EID_SECONDARY_CHANNEL_OFFSET:
			if (elen != sizeof(struct ieee80211_sec_chan_offs_ie)) {
				elem_parse_failed = true;
				break;
			}
			elems->sec_chan_offs = (void *)pos;
			break;
		case WLAN_EID_CHAN_SWITCH_PARAM:
			if (elen <
			    sizeof(*elems->mesh_chansw_params_ie)) {
				elem_parse_failed = true;
				break;
			}
			elems->mesh_chansw_params_ie = (void *)pos;
			break;
		case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
			if (!params->action ||
			    elen < sizeof(*elems->wide_bw_chansw_ie)) {
				elem_parse_failed = true;
				break;
			}
			elems->wide_bw_chansw_ie = (void *)pos;
			break;
		case WLAN_EID_CHANNEL_SWITCH_WRAPPER:
			if (params->action) {
				elem_parse_failed = true;
				break;
			}
			/*
			 * This is a bit tricky, but as we only care about
			 * a few elements, parse them out manually.
			 */
			subelem = cfg80211_find_elem(WLAN_EID_WIDE_BW_CHANNEL_SWITCH,
						     pos, elen);
			if (subelem) {
				if (subelem->datalen >= sizeof(*elems->wide_bw_chansw_ie))
					elems->wide_bw_chansw_ie =
						(void *)subelem->data;
				else
					elem_parse_failed = true;
			}

			subelem = cfg80211_find_ext_elem(WLAN_EID_EXT_BANDWIDTH_INDICATION,
							 pos, elen);
			if (subelem) {
				const void *edata = subelem->data + 1;
				u8 edatalen = subelem->datalen - 1;

				if (ieee80211_bandwidth_indication_size_ok(edata,
									   edatalen))
					elems->bandwidth_indication = edata;
				else
					elem_parse_failed = true;
			}
			break;
		case WLAN_EID_COUNTRY:
			elems->country_elem = pos;
			elems->country_elem_len = elen;
			break;
		case WLAN_EID_PWR_CONSTRAINT:
			if (elen != 1) {
				elem_parse_failed = true;
				break;
			}
			elems->pwr_constr_elem = pos;
			break;
		case WLAN_EID_CISCO_VENDOR_SPECIFIC:
			/* Lots of different options exist, but we only care
			 * about the Dynamic Transmit Power Control element.
			 * First check for the Cisco OUI, then for the DTPC
			 * tag (0x00).
			 */
			if (elen < 4) {
				elem_parse_failed = true;
				break;
			}

			if (pos[0] != 0x00 || pos[1] != 0x40 ||
			    pos[2] != 0x96 || pos[3] != 0x00)
				break;

			if (elen != 6) {
				elem_parse_failed = true;
				break;
			}

			if (calc_crc)
				crc = crc32_be(crc, pos - 2, elen + 2);

			elems->cisco_dtpc_elem = pos;
			break;
		case WLAN_EID_ADDBA_EXT:
			if (elen < sizeof(struct ieee80211_addba_ext_ie)) {
				elem_parse_failed = true;
				break;
			}
			elems->addba_ext_ie = (void *)pos;
			break;
		case WLAN_EID_TIMEOUT_INTERVAL:
			if (elen >= sizeof(struct ieee80211_timeout_interval_ie))
				elems->timeout_int = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_BSS_MAX_IDLE_PERIOD:
			if (elen >= sizeof(*elems->max_idle_period_ie))
				elems->max_idle_period_ie = (void *)pos;
			break;
		case WLAN_EID_RSNX:
			elems->rsnx = pos;
			elems->rsnx_len = elen;
			break;
		case WLAN_EID_TX_POWER_ENVELOPE:
			if (elen < 1 ||
			    elen > sizeof(struct ieee80211_tx_pwr_env))
				break;

			if (elems->tx_pwr_env_num >= ARRAY_SIZE(elems->tx_pwr_env))
				break;

			elems->tx_pwr_env[elems->tx_pwr_env_num] = (void *)pos;
			elems->tx_pwr_env_len[elems->tx_pwr_env_num] = elen;
			elems->tx_pwr_env_num++;
			break;
		case WLAN_EID_EXTENSION:
			ieee80211_parse_extension_element(calc_crc ?
								&crc : NULL,
							  elem, elems, params);
			break;
		case WLAN_EID_S1G_CAPABILITIES:
			if (elen >= sizeof(*elems->s1g_capab))
				elems->s1g_capab = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_S1G_OPERATION:
			if (elen == sizeof(*elems->s1g_oper))
				elems->s1g_oper = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_S1G_BCN_COMPAT:
			if (elen == sizeof(*elems->s1g_bcn_compat))
				elems->s1g_bcn_compat = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		case WLAN_EID_AID_RESPONSE:
			if (elen == sizeof(struct ieee80211_aid_response_ie))
				elems->aid_resp = (void *)pos;
			else
				elem_parse_failed = true;
			break;
		default:
			break;
		}

		if (elem_parse_failed)
			elems->parse_error = true;
		else
			__set_bit(id, seen_elems);
	}

	if (!for_each_element_completed(elem, params->start, params->len))
		elems->parse_error = true;

	return crc;
}

static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
					    struct ieee802_11_elems *elems,
					    struct cfg80211_bss *bss,
					    u8 *nontransmitted_profile)
{
	const struct element *elem, *sub;
	size_t profile_len = 0;
	bool found = false;

	if (!bss || !bss->transmitted_bss)
		return profile_len;

	for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
		if (elem->datalen < 2)
			continue;
		if (elem->data[0] < 1 || elem->data[0] > 8)
			continue;

		for_each_element(sub, elem->data + 1, elem->datalen - 1) {
			u8 new_bssid[ETH_ALEN];
			const u8 *index;

			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 of the
				 * Nontransmitted BSSID Profile is not
				 * the Nontransmitted BSSID Capability
				 * element.
				 */
				continue;
			}

			memset(nontransmitted_profile, 0, len);
			profile_len = cfg80211_merge_profile(start, len,
							     elem,
							     sub,
							     nontransmitted_profile,
							     len);

			/* found a Nontransmitted BSSID Profile */
			index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
						 nontransmitted_profile,
						 profile_len);
			if (!index || index[1] < 1 || index[2] == 0) {
				/* Invalid MBSSID Index element */
				continue;
			}

			cfg80211_gen_new_bssid(bss->transmitted_bss->bssid,
					       elem->data[0],
					       index[2],
					       new_bssid);
			if (ether_addr_equal(new_bssid, bss->bssid)) {
				found = true;
				elems->bssid_index_len = index[1];
				elems->bssid_index = (void *)&index[2];
				break;
			}
		}
	}

	return found ? profile_len : 0;
}

static void ieee80211_mle_get_sta_prof(struct ieee802_11_elems *elems,
				       u8 link_id)
{
	const struct ieee80211_multi_link_elem *ml = elems->ml_basic;
	ssize_t ml_len = elems->ml_basic_len;
	const struct element *sub;

	if (!ml || !ml_len)
		return;

	if (le16_get_bits(ml->control, IEEE80211_ML_CONTROL_TYPE) !=
	    IEEE80211_ML_CONTROL_TYPE_BASIC)
		return;

	for_each_mle_subelement(sub, (u8 *)ml, ml_len) {
		struct ieee80211_mle_per_sta_profile *prof = (void *)sub->data;
		ssize_t sta_prof_len;
		u16 control;

		if (sub->id != IEEE80211_MLE_SUBELEM_PER_STA_PROFILE)
			continue;

		if (!ieee80211_mle_basic_sta_prof_size_ok(sub->data,
							  sub->datalen))
			return;

		control = le16_to_cpu(prof->control);

		if (link_id != u16_get_bits(control,
					    IEEE80211_MLE_STA_CONTROL_LINK_ID))
			continue;

		if (!(control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE))
			return;

		/* the sub element can be fragmented */
		sta_prof_len =
			cfg80211_defragment_element(sub,
						    (u8 *)ml, ml_len,
						    elems->scratch_pos,
						    elems->scratch +
							elems->scratch_len -
							elems->scratch_pos,
						    IEEE80211_MLE_SUBELEM_FRAGMENT);

		if (sta_prof_len < 0)
			return;

		elems->prof = (void *)elems->scratch_pos;
		elems->sta_prof_len = sta_prof_len;
		elems->scratch_pos += sta_prof_len;

		return;
	}
}

static void ieee80211_mle_parse_link(struct ieee802_11_elems *elems,
				     struct ieee80211_elems_parse_params *params)
{
	struct ieee80211_mle_per_sta_profile *prof;
	struct ieee80211_elems_parse_params sub = {
		.action = params->action,
		.from_ap = params->from_ap,
		.link_id = -1,
	};
	ssize_t ml_len = elems->ml_basic_len;
	const struct element *non_inherit = NULL;
	const u8 *end;

	if (params->link_id == -1)
		return;

	ml_len = cfg80211_defragment_element(elems->ml_basic_elem,
					     elems->ie_start,
					     elems->total_len,
					     elems->scratch_pos,
					     elems->scratch +
						elems->scratch_len -
						elems->scratch_pos,
					     WLAN_EID_FRAGMENT);

	if (ml_len < 0)
		return;

	elems->ml_basic = (const void *)elems->scratch_pos;
	elems->ml_basic_len = ml_len;

	ieee80211_mle_get_sta_prof(elems, params->link_id);
	prof = elems->prof;

	if (!prof)
		return;

	/* check if we have the 4 bytes for the fixed part in assoc response */
	if (elems->sta_prof_len < sizeof(*prof) + prof->sta_info_len - 1 + 4) {
		elems->prof = NULL;
		elems->sta_prof_len = 0;
		return;
	}

	/*
	 * Skip the capability information and the status code that are expected
	 * as part of the station profile in association response frames. Note
	 * the -1 is because the 'sta_info_len' is accounted to as part of the
	 * per-STA profile, but not part of the 'u8 variable[]' portion.
	 */
	sub.start = prof->variable + prof->sta_info_len - 1 + 4;
	end = (const u8 *)prof + elems->sta_prof_len;
	sub.len = end - sub.start;

	non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
					     sub.start, sub.len);
	_ieee802_11_parse_elems_full(&sub, elems, non_inherit);
}

struct ieee802_11_elems *
ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
{
	struct ieee802_11_elems *elems;
	const struct element *non_inherit = NULL;
	u8 *nontransmitted_profile;
	int nontransmitted_profile_len = 0;
	size_t scratch_len = 3 * params->len;

	elems = kzalloc(struct_size(elems, scratch, scratch_len), GFP_ATOMIC);
	if (!elems)
		return NULL;
	elems->ie_start = params->start;
	elems->total_len = params->len;
	elems->scratch_len = scratch_len;
	elems->scratch_pos = elems->scratch;

	nontransmitted_profile = elems->scratch_pos;
	nontransmitted_profile_len =
		ieee802_11_find_bssid_profile(params->start, params->len,
					      elems, params->bss,
					      nontransmitted_profile);
	elems->scratch_pos += nontransmitted_profile_len;
	elems->scratch_len -= nontransmitted_profile_len;
	non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
					     nontransmitted_profile,
					     nontransmitted_profile_len);

	elems->crc = _ieee802_11_parse_elems_full(params, elems, non_inherit);

	/* Override with nontransmitted profile, if found */
	if (nontransmitted_profile_len) {
		struct ieee80211_elems_parse_params sub = {
			.start = nontransmitted_profile,
			.len = nontransmitted_profile_len,
			.action = params->action,
			.link_id = params->link_id,
		};

		_ieee802_11_parse_elems_full(&sub, elems, NULL);
	}

	ieee80211_mle_parse_link(elems, params);

	if (elems->tim && !elems->parse_error) {
		const struct ieee80211_tim_ie *tim_ie = elems->tim;

		elems->dtim_period = tim_ie->dtim_period;
		elems->dtim_count = tim_ie->dtim_count;
	}

	/* Override DTIM period and count if needed */
	if (elems->bssid_index &&
	    elems->bssid_index_len >=
	    offsetofend(struct ieee80211_bssid_index, dtim_period))
		elems->dtim_period = elems->bssid_index->dtim_period;

	if (elems->bssid_index &&
	    elems->bssid_index_len >=
	    offsetofend(struct ieee80211_bssid_index, dtim_count))
		elems->dtim_count = elems->bssid_index->dtim_count;

	return elems;
}
EXPORT_SYMBOL_IF_KUNIT(ieee802_11_parse_elems_full);

void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
					   struct ieee80211_tx_queue_params
					   *qparam, int ac)
{
	struct ieee80211_chanctx_conf *chanctx_conf;
	const struct ieee80211_reg_rule *rrule;
	const struct ieee80211_wmm_ac *wmm_ac;
	u16 center_freq = 0;

	if (sdata->vif.type != NL80211_IFTYPE_AP &&
	    sdata->vif.type != NL80211_IFTYPE_STATION)
		return;

	rcu_read_lock();
	chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
	if (chanctx_conf)
		center_freq = chanctx_conf->def.chan->center_freq;

	if (!center_freq) {
		rcu_read_unlock();
		return;
	}

	rrule = freq_reg_info(sdata->wdev.wiphy, MHZ_TO_KHZ(center_freq));

	if (IS_ERR_OR_NULL(rrule) || !rrule->has_wmm) {
		rcu_read_unlock();
		return;
	}

	if (sdata->vif.type == NL80211_IFTYPE_AP)
		wmm_ac = &rrule->wmm_rule.ap[ac];
	else
		wmm_ac = &rrule->wmm_rule.client[ac];
	qparam->cw_min = max_t(u16, qparam->cw_min, wmm_ac->cw_min);
	qparam->cw_max = max_t(u16, qparam->cw_max, wmm_ac->cw_max);
	qparam->aifs = max_t(u8, qparam->aifs, wmm_ac->aifsn);
	qparam->txop = min_t(u16, qparam->txop, wmm_ac->cot / 32);
	rcu_read_unlock();
}

void ieee80211_set_wmm_default(struct ieee80211_link_data *link,
			       bool bss_notify, bool enable_qos)
{
	struct ieee80211_sub_if_data *sdata = link->sdata;
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_tx_queue_params qparam;
	struct ieee80211_chanctx_conf *chanctx_conf;
	int ac;
	bool use_11b;
	bool is_ocb; /* Use another EDCA parameters if dot11OCBActivated=true */
	int aCWmin, aCWmax;

	if (!local->ops->conf_tx)
		return;

	if (local->hw.queues < IEEE80211_NUM_ACS)
		return;

	memset(&qparam, 0, sizeof(qparam));

	rcu_read_lock();
	chanctx_conf = rcu_dereference(link->conf->chanctx_conf);
	use_11b = (chanctx_conf &&
		   chanctx_conf->def.chan->band == NL80211_BAND_2GHZ) &&
		 !link->operating_11g_mode;
	rcu_read_unlock();

	is_ocb = (sdata->vif.type == NL80211_IFTYPE_OCB);

	/* Set defaults according to 802.11-2007 Table 7-37 */
	aCWmax = 1023;
	if (use_11b)
		aCWmin = 31;
	else
		aCWmin = 15;

	/* Confiure old 802.11b/g medium access rules. */
	qparam.cw_max = aCWmax;
	qparam.cw_min = aCWmin;
	qparam.txop = 0;
	qparam.aifs = 2;

	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
		/* Update if QoS is enabled. */
		if (enable_qos) {
			switch (ac) {
			case IEEE80211_AC_BK:
				qparam.cw_max = aCWmax;
				qparam.cw_min = aCWmin;
				qparam.txop = 0;
				if (is_ocb)
					qparam.aifs = 9;
				else
					qparam.aifs = 7;
				break;
			/* never happens but let's not leave undefined */
			default:
			case IEEE80211_AC_BE:
				qparam.cw_max = aCWmax;
				qparam.cw_min = aCWmin;
				qparam.txop = 0;
				if (is_ocb)
					qparam.aifs = 6;
				else
					qparam.aifs = 3;
				break;
			case IEEE80211_AC_VI:
				qparam.cw_max = aCWmin;
				qparam.cw_min = (aCWmin + 1) / 2 - 1;
				if (is_ocb)
					qparam.txop = 0;
				else if (use_11b)
					qparam.txop = 6016/32;
				else
					qparam.txop = 3008/32;

				if (is_ocb)
					qparam.aifs = 3;
				else
					qparam.aifs = 2;
				break;
			case IEEE80211_AC_VO:
				qparam.cw_max = (aCWmin + 1) / 2 - 1;
				qparam.cw_min = (aCWmin + 1) / 4 - 1;
				if (is_ocb)
					qparam.txop = 0;
				else if (use_11b)
					qparam.txop = 3264/32;
				else
					qparam.txop = 1504/32;
				qparam.aifs = 2;
				break;
			}
		}
		ieee80211_regulatory_limit_wmm_params(sdata, &qparam, ac);

		qparam.uapsd = false;

		link->tx_conf[ac] = qparam;
		drv_conf_tx(local, link, ac, &qparam);
	}

	if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
	    sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
	    sdata->vif.type != NL80211_IFTYPE_NAN) {
		link->conf->qos = enable_qos;
		if (bss_notify)
			ieee80211_link_info_change_notify(sdata, link,
							  BSS_CHANGED_QOS);
	}
}

void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
			 u16 transaction, u16 auth_alg, u16 status,
			 const u8 *extra, size_t extra_len, const u8 *da,
			 const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx,
			 u32 tx_flags)
{
	struct ieee80211_local *local = sdata->local;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	bool multi_link = ieee80211_vif_is_mld(&sdata->vif);
	struct {
		u8 id;
		u8 len;
		u8 ext_id;
		struct ieee80211_multi_link_elem ml;
		struct ieee80211_mle_basic_common_info basic;
	} __packed mle = {
		.id = WLAN_EID_EXTENSION,
		.len = sizeof(mle) - 2,
		.ext_id = WLAN_EID_EXT_EHT_MULTI_LINK,
		.ml.control = cpu_to_le16(IEEE80211_ML_CONTROL_TYPE_BASIC),
		.basic.len = sizeof(mle.basic),
	};
	int err;

	memcpy(mle.basic.mld_mac_addr, sdata->vif.addr, ETH_ALEN);

	/* 24 + 6 = header + auth_algo + auth_transaction + status_code */
	skb = dev_alloc_skb(local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN +
			    24 + 6 + extra_len + IEEE80211_WEP_ICV_LEN +
			    multi_link * sizeof(mle));
	if (!skb)
		return;

	skb_reserve(skb, local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN);

	mgmt = skb_put_zero(skb, 24 + 6);
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_AUTH);
	memcpy(mgmt->da, da, ETH_ALEN);
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
	memcpy(mgmt->bssid, bssid, ETH_ALEN);
	mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg);
	mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
	mgmt->u.auth.status_code = cpu_to_le16(status);
	if (extra)
		skb_put_data(skb, extra, extra_len);
	if (multi_link)
		skb_put_data(skb, &mle, sizeof(mle));

	if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
		mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
		err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
		if (WARN_ON(err)) {
			kfree_skb(skb);
			return;
		}
	}

	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
					tx_flags;
	ieee80211_tx_skb(sdata, skb);
}

void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
				    const u8 *da, const u8 *bssid,
				    u16 stype, u16 reason,
				    bool send_frame, u8 *frame_buf)
{
	struct ieee80211_local *local = sdata->local;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt = (void *)frame_buf;

	/* build frame */
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
	mgmt->duration = 0; /* initialize only */
	mgmt->seq_ctrl = 0; /* initialize only */
	memcpy(mgmt->da, da, ETH_ALEN);
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
	memcpy(mgmt->bssid, bssid, ETH_ALEN);
	/* u.deauth.reason_code == u.disassoc.reason_code */
	mgmt->u.deauth.reason_code = cpu_to_le16(reason);

	if (send_frame) {
		skb = dev_alloc_skb(local->hw.extra_tx_headroom +
				    IEEE80211_DEAUTH_FRAME_LEN);
		if (!skb)
			return;

		skb_reserve(skb, local->hw.extra_tx_headroom);

		/* copy in frame */
		skb_put_data(skb, mgmt, IEEE80211_DEAUTH_FRAME_LEN);

		if (sdata->vif.type != NL80211_IFTYPE_STATION ||
		    !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
			IEEE80211_SKB_CB(skb)->flags |=
				IEEE80211_TX_INTFL_DONT_ENCRYPT;

		ieee80211_tx_skb(sdata, skb);
	}
}

u8 *ieee80211_write_he_6ghz_cap(u8 *pos, __le16 cap, u8 *end)
{
	if ((end - pos) < 5)
		return pos;

	*pos++ = WLAN_EID_EXTENSION;
	*pos++ = 1 + sizeof(cap);
	*pos++ = WLAN_EID_EXT_HE_6GHZ_CAPA;
	memcpy(pos, &cap, sizeof(cap));

	return pos + 2;
}

static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
					 u8 *buffer, size_t buffer_len,
					 const u8 *ie, size_t ie_len,
					 enum nl80211_band band,
					 u32 rate_mask,
					 struct cfg80211_chan_def *chandef,
					 size_t *offset, u32 flags)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_supported_band *sband;
	const struct ieee80211_sta_he_cap *he_cap;
	const struct ieee80211_sta_eht_cap *eht_cap;
	u8 *pos = buffer, *end = buffer + buffer_len;
	size_t noffset;
	int supp_rates_len, i;
	u8 rates[32];
	int num_rates;
	int ext_rates_len;
	u32 rate_flags;
	bool have_80mhz = false;

	*offset = 0;

	sband = local->hw.wiphy->bands[band];
	if (WARN_ON_ONCE(!sband))
		return 0;

	rate_flags = ieee80211_chandef_rate_flags(chandef);

	/* For direct scan add S1G IE and consider its override bits */
	if (band == NL80211_BAND_S1GHZ) {
		if (end - pos < 2 + sizeof(struct ieee80211_s1g_cap))
			goto out_err;
		pos = ieee80211_ie_build_s1g_cap(pos, &sband->s1g_cap);
		goto done;
	}

	num_rates = 0;
	for (i = 0; i < sband->n_bitrates; i++) {
		if ((BIT(i) & rate_mask) == 0)
			continue; /* skip rate */
		if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
			continue;

		rates[num_rates++] =
			(u8) DIV_ROUND_UP(sband->bitrates[i].bitrate, 5);
	}

	supp_rates_len = min_t(int, num_rates, 8);

	if (end - pos < 2 + supp_rates_len)
		goto out_err;
	*pos++ = WLAN_EID_SUPP_RATES;
	*pos++ = supp_rates_len;
	memcpy(pos, rates, supp_rates_len);
	pos += supp_rates_len;

	/* insert "request information" if in custom IEs */
	if (ie && ie_len) {
		static const u8 before_extrates[] = {
			WLAN_EID_SSID,
			WLAN_EID_SUPP_RATES,
			WLAN_EID_REQUEST,
		};
		noffset = ieee80211_ie_split(ie, ie_len,
					     before_extrates,
					     ARRAY_SIZE(before_extrates),
					     *offset);
		if (end - pos < noffset - *offset)
			goto out_err;
		memcpy(pos, ie + *offset, noffset - *offset);
		pos += noffset - *offset;
		*offset = noffset;
	}

	ext_rates_len = num_rates - supp_rates_len;
	if (ext_rates_len > 0) {
		if (end - pos < 2 + ext_rates_len)
			goto out_err;
		*pos++ = WLAN_EID_EXT_SUPP_RATES;
		*pos++ = ext_rates_len;
		memcpy(pos, rates + supp_rates_len, ext_rates_len);
		pos += ext_rates_len;
	}

	if (chandef->chan && sband->band == NL80211_BAND_2GHZ) {
		if (end - pos < 3)
			goto out_err;
		*pos++ = WLAN_EID_DS_PARAMS;
		*pos++ = 1;
		*pos++ = ieee80211_frequency_to_channel(
				chandef->chan->center_freq);
	}

	if (flags & IEEE80211_PROBE_FLAG_MIN_CONTENT)
		goto done;

	/* insert custom IEs that go before HT */
	if (ie && ie_len) {
		static const u8 before_ht[] = {
			/*
			 * no need to list the ones split off already
			 * (or generated here)
			 */
			WLAN_EID_DS_PARAMS,
			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
		};
		noffset = ieee80211_ie_split(ie, ie_len,
					     before_ht, ARRAY_SIZE(before_ht),
					     *offset);
		if (end - pos < noffset - *offset)
			goto out_err;
		memcpy(pos, ie + *offset, noffset - *offset);
		pos += noffset - *offset;
		*offset = noffset;
	}

	if (sband->ht_cap.ht_supported) {
		if (end - pos < 2 + sizeof(struct ieee80211_ht_cap))
			goto out_err;
		pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
						sband->ht_cap.cap);
	}

	/* insert custom IEs that go before VHT */
	if (ie && ie_len) {
		static const u8 before_vht[] = {
			/*
			 * no need to list the ones split off already
			 * (or generated here)
			 */
			WLAN_EID_BSS_COEX_2040,
			WLAN_EID_EXT_CAPABILITY,
			WLAN_EID_SSID_LIST,
			WLAN_EID_CHANNEL_USAGE,
			WLAN_EID_INTERWORKING,
			WLAN_EID_MESH_ID,
			/* 60 GHz (Multi-band, DMG, MMS) can't happen */
		};
		noffset = ieee80211_ie_split(ie, ie_len,
					     before_vht, ARRAY_SIZE(before_vht),
					     *offset);
		if (end - pos < noffset - *offset)
			goto out_err;
		memcpy(pos, ie + *offset, noffset - *offset);
		pos += noffset - *offset;
		*offset = noffset;
	}

	/* Check if any channel in this sband supports at least 80 MHz */
	for (i = 0; i < sband->n_channels; i++) {
		if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
						IEEE80211_CHAN_NO_80MHZ))
			continue;

		have_80mhz = true;
		break;
	}

	if (sband->vht_cap.vht_supported && have_80mhz) {
		if (end - pos < 2 + sizeof(struct ieee80211_vht_cap))
			goto out_err;
		pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,
						 sband->vht_cap.cap);
	}

	/* insert custom IEs that go before HE */
	if (ie && ie_len) {
		static const u8 before_he[] = {
			/*
			 * no need to list the ones split off before VHT
			 * or generated here
			 */
			WLAN_EID_EXTENSION, WLAN_EID_EXT_FILS_REQ_PARAMS,
			WLAN_EID_AP_CSN,
			/* TODO: add 11ah/11aj/11ak elements */
		};
		noffset = ieee80211_ie_split(ie, ie_len,
					     before_he, ARRAY_SIZE(before_he),
					     *offset);
		if (end - pos < noffset - *offset)
			goto out_err;
		memcpy(pos, ie + *offset, noffset - *offset);
		pos += noffset - *offset;
		*offset = noffset;
	}

	he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
	if (he_cap &&
	    cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
					 IEEE80211_CHAN_NO_HE)) {
		pos = ieee80211_ie_build_he_cap(0, pos, he_cap, end);
		if (!pos)
			goto out_err;
	}

	eht_cap = ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif);

	if (eht_cap &&
	    cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
					 IEEE80211_CHAN_NO_HE |
					 IEEE80211_CHAN_NO_EHT)) {
		pos = ieee80211_ie_build_eht_cap(pos, he_cap, eht_cap, end,
						 sdata->vif.type == NL80211_IFTYPE_AP);
		if (!pos)
			goto out_err;
	}

	if (cfg80211_any_usable_channels(local->hw.wiphy,
					 BIT(NL80211_BAND_6GHZ),
					 IEEE80211_CHAN_NO_HE)) {
		struct ieee80211_supported_band *sband6;

		sband6 = local->hw.wiphy->bands[NL80211_BAND_6GHZ];
		he_cap = ieee80211_get_he_iftype_cap_vif(sband6, &sdata->vif);

		if (he_cap) {
			enum nl80211_iftype iftype =
				ieee80211_vif_type_p2p(&sdata->vif);
			__le16 cap = ieee80211_get_he_6ghz_capa(sband6, iftype);

			pos = ieee80211_write_he_6ghz_cap(pos, cap, end);
		}
	}

	/*
	 * If adding more here, adjust code in main.c
	 * that calculates local->scan_ies_len.
	 */

	return pos - buffer;
 out_err:
	WARN_ONCE(1, "not enough space for preq IEs\n");
 done:
	return pos - buffer;
}

int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer,
			     size_t buffer_len,
			     struct ieee80211_scan_ies *ie_desc,
			     const u8 *ie, size_t ie_len,
			     u8 bands_used, u32 *rate_masks,
			     struct cfg80211_chan_def *chandef,
			     u32 flags)
{
	size_t pos = 0, old_pos = 0, custom_ie_offset = 0;
	int i;

	memset(ie_desc, 0, sizeof(*ie_desc));

	for (i = 0; i < NUM_NL80211_BANDS; i++) {
		if (bands_used & BIT(i)) {
			pos += ieee80211_build_preq_ies_band(sdata,
							     buffer + pos,
							     buffer_len - pos,
							     ie, ie_len, i,
							     rate_masks[i],
							     chandef,
							     &custom_ie_offset,
							     flags);
			ie_desc->ies[i] = buffer + old_pos;
			ie_desc->len[i] = pos - old_pos;
			old_pos = pos;
		}
	}

	/* add any remaining custom IEs */
	if (ie && ie_len) {
		if (WARN_ONCE(buffer_len - pos < ie_len - custom_ie_offset,
			      "not enough space for preq custom IEs\n"))
			return pos;
		memcpy(buffer + pos, ie + custom_ie_offset,
		       ie_len - custom_ie_offset);
		ie_desc->common_ies = buffer + pos;
		ie_desc->common_ie_len = ie_len - custom_ie_offset;
		pos += ie_len - custom_ie_offset;
	}

	return pos;
};

struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
					  const u8 *src, const u8 *dst,
					  u32 ratemask,
					  struct ieee80211_channel *chan,
					  const u8 *ssid, size_t ssid_len,
					  const u8 *ie, size_t ie_len,
					  u32 flags)
{
	struct ieee80211_local *local = sdata->local;
	struct cfg80211_chan_def chandef;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	int ies_len;
	u32 rate_masks[NUM_NL80211_BANDS] = {};
	struct ieee80211_scan_ies dummy_ie_desc;

	/*
	 * Do not send DS Channel parameter for directed probe requests
	 * in order to maximize the chance that we get a response.  Some
	 * badly-behaved APs don't respond when this parameter is included.
	 */
	chandef.width = sdata->vif.bss_conf.chandef.width;
	if (flags & IEEE80211_PROBE_FLAG_DIRECTED)
		chandef.chan = NULL;
	else
		chandef.chan = chan;

	skb = ieee80211_probereq_get(&local->hw, src, ssid, ssid_len,
				     local->scan_ies_len + ie_len);
	if (!skb)
		return NULL;

	rate_masks[chan->band] = ratemask;
	ies_len = ieee80211_build_preq_ies(sdata, skb_tail_pointer(skb),
					   skb_tailroom(skb), &dummy_ie_desc,
					   ie, ie_len, BIT(chan->band),
					   rate_masks, &chandef, flags);
	skb_put(skb, ies_len);

	if (dst) {
		mgmt = (struct ieee80211_mgmt *) skb->data;
		memcpy(mgmt->da, dst, ETH_ALEN);
		memcpy(mgmt->bssid, dst, ETH_ALEN);
	}

	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;

	return skb;
}

u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
			    struct ieee802_11_elems *elems,
			    enum nl80211_band band, u32 *basic_rates)
{
	struct ieee80211_supported_band *sband;
	size_t num_rates;
	u32 supp_rates, rate_flags;
	int i, j;

	sband = sdata->local->hw.wiphy->bands[band];
	if (WARN_ON(!sband))
		return 1;

	rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);

	num_rates = sband->n_bitrates;
	supp_rates = 0;
	for (i = 0; i < elems->supp_rates_len +
		     elems->ext_supp_rates_len; i++) {
		u8 rate = 0;
		int own_rate;
		bool is_basic;
		if (i < elems->supp_rates_len)
			rate = elems->supp_rates[i];
		else if (elems->ext_supp_rates)
			rate = elems->ext_supp_rates
				[i - elems->supp_rates_len];
		own_rate = 5 * (rate & 0x7f);
		is_basic = !!(rate & 0x80);

		if (is_basic && (rate & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
			continue;

		for (j = 0; j < num_rates; j++) {
			int brate;
			if ((rate_flags & sband->bitrates[j].flags)
			    != rate_flags)
				continue;

			brate = sband->bitrates[j].bitrate;

			if (brate == own_rate) {
				supp_rates |= BIT(j);
				if (basic_rates && is_basic)
					*basic_rates |= BIT(j);
			}
		}
	}
	return supp_rates;
}

void ieee80211_stop_device(struct ieee80211_local *local)
{
	ieee80211_led_radio(local, false);
	ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO);

	wiphy_work_cancel(local->hw.wiphy, &local->reconfig_filter);

	flush_workqueue(local->workqueue);
	wiphy_work_flush(local->hw.wiphy, NULL);
	drv_stop(local);
}

static void ieee80211_flush_completed_scan(struct ieee80211_local *local,
					   bool aborted)
{
	/* It's possible that we don't handle the scan completion in
	 * time during suspend, so if it's still marked as completed
	 * here, queue the work and flush it to clean things up.
	 * Instead of calling the worker function directly here, we
	 * really queue it to avoid potential races with other flows
	 * scheduling the same work.
	 */
	if (test_bit(SCAN_COMPLETED, &local->scanning)) {
		/* If coming from reconfiguration failure, abort the scan so
		 * we don't attempt to continue a partial HW scan - which is
		 * possible otherwise if (e.g.) the 2.4 GHz portion was the
		 * completed scan, and a 5 GHz portion is still pending.
		 */
		if (aborted)
			set_bit(SCAN_ABORTED, &local->scanning);
		wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0);
		wiphy_delayed_work_flush(local->hw.wiphy, &local->scan_work);
	}
}

static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_chanctx *ctx;

	lockdep_assert_wiphy(local->hw.wiphy);

	/*
	 * We get here if during resume the device can't be restarted properly.
	 * We might also get here if this happens during HW reset, which is a
	 * slightly different situation and we need to drop all connections in
	 * the latter case.
	 *
	 * Ask cfg80211 to turn off all interfaces, this will result in more
	 * warnings but at least we'll then get into a clean stopped state.
	 */

	local->resuming = false;
	local->suspended = false;
	local->in_reconfig = false;
	local->reconfig_failure = true;

	ieee80211_flush_completed_scan(local, true);

	/* scheduled scan clearly can't be running any more, but tell
	 * cfg80211 and clear local state
	 */
	ieee80211_sched_scan_end(local);

	list_for_each_entry(sdata, &local->interfaces, list)
		sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;

	/* Mark channel contexts as not being in the driver any more to avoid
	 * removing them from the driver during the shutdown process...
	 */
	list_for_each_entry(ctx, &local->chanctx_list, list)
		ctx->driver_present = false;
}

static void ieee80211_assign_chanctx(struct ieee80211_local *local,
				     struct ieee80211_sub_if_data *sdata,
				     struct ieee80211_link_data *link)
{
	struct ieee80211_chanctx_conf *conf;
	struct ieee80211_chanctx *ctx;

	lockdep_assert_wiphy(local->hw.wiphy);

	if (!local->use_chanctx)
		return;

	conf = rcu_dereference_protected(link->conf->chanctx_conf,
					 lockdep_is_held(&local->hw.wiphy->mtx));
	if (conf) {
		ctx = container_of(conf, struct ieee80211_chanctx, conf);
		drv_assign_vif_chanctx(local, sdata, link->conf, ctx);
	}
}

static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct sta_info *sta;

	lockdep_assert_wiphy(local->hw.wiphy);

	/* add STAs back */
	list_for_each_entry(sta, &local->sta_list, list) {
		enum ieee80211_sta_state state;

		if (!sta->uploaded || sta->sdata != sdata)
			continue;

		for (state = IEEE80211_STA_NOTEXIST;
		     state < sta->sta_state; state++)
			WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
					      state + 1));
	}
}

static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata)
{
	struct cfg80211_nan_func *func, **funcs;
	int res, id, i = 0;

	res = drv_start_nan(sdata->local, sdata,
			    &sdata->u.nan.conf);
	if (WARN_ON(res))
		return res;

	funcs = kcalloc(sdata->local->hw.max_nan_de_entries + 1,
			sizeof(*funcs),
			GFP_KERNEL);
	if (!funcs)
		return -ENOMEM;

	/* Add all the functions:
	 * This is a little bit ugly. We need to call a potentially sleeping
	 * callback for each NAN function, so we can't hold the spinlock.
	 */
	spin_lock_bh(&sdata->u.nan.func_lock);

	idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id)
		funcs[i++] = func;

	spin_unlock_bh(&sdata->u.nan.func_lock);

	for (i = 0; funcs[i]; i++) {
		res = drv_add_nan_func(sdata->local, sdata, funcs[i]);
		if (WARN_ON(res))
			ieee80211_nan_func_terminated(&sdata->vif,
						      funcs[i]->instance_id,
						      NL80211_NAN_FUNC_TERM_REASON_ERROR,
						      GFP_KERNEL);
	}

	kfree(funcs);

	return 0;
}

static void ieee80211_reconfig_ap_links(struct ieee80211_local *local,
					struct ieee80211_sub_if_data *sdata,
					u64 changed)
{
	int link_id;

	for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
		struct ieee80211_link_data *link;

		if (!(sdata->vif.active_links & BIT(link_id)))
			continue;

		link = sdata_dereference(sdata->link[link_id], sdata);
		if (!link)
			continue;

		if (rcu_access_pointer(link->u.ap.beacon))
			drv_start_ap(local, sdata, link->conf);

		if (!link->conf->enable_beacon)
			continue;

		changed |= BSS_CHANGED_BEACON |
			   BSS_CHANGED_BEACON_ENABLED;

		ieee80211_link_info_change_notify(sdata, link, changed);
	}
}

int ieee80211_reconfig(struct ieee80211_local *local)
{
	struct ieee80211_hw *hw = &local->hw;
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_chanctx *ctx;
	struct sta_info *sta;
	int res, i;
	bool reconfig_due_to_wowlan = false;
	struct ieee80211_sub_if_data *sched_scan_sdata;
	struct cfg80211_sched_scan_request *sched_scan_req;
	bool sched_scan_stopped = false;
	bool suspended = local->suspended;
	bool in_reconfig = false;

	lockdep_assert_wiphy(local->hw.wiphy);

	/* nothing to do if HW shouldn't run */
	if (!local->open_count)
		goto wake_up;

#ifdef CONFIG_PM
	if (suspended)
		local->resuming = true;

	if (local->wowlan) {
		/*
		 * In the wowlan case, both mac80211 and the device
		 * are functional when the resume op is called, so
		 * clear local->suspended so the device could operate
		 * normally (e.g. pass rx frames).
		 */
		local->suspended = false;
		res = drv_resume(local);
		local->wowlan = false;
		if (res < 0) {
			local->resuming = false;
			return res;
		}
		if (res == 0)
			goto wake_up;
		WARN_ON(res > 1);
		/*
		 * res is 1, which means the driver requested
		 * to go through a regular reset on wakeup.
		 * restore local->suspended in this case.
		 */
		reconfig_due_to_wowlan = true;
		local->suspended = true;
	}
#endif

	/*
	 * In case of hw_restart during suspend (without wowlan),
	 * cancel restart work, as we are reconfiguring the device
	 * anyway.
	 * Note that restart_work is scheduled on a frozen workqueue,
	 * so we can't deadlock in this case.
	 */
	if (suspended && local->in_reconfig && !reconfig_due_to_wowlan)
		cancel_work_sync(&local->restart_work);

	local->started = false;

	/*
	 * Upon resume hardware can sometimes be goofy due to
	 * various platform / driver / bus issues, so restarting
	 * the device may at times not work immediately. Propagate
	 * the error.
	 */
	res = drv_start(local);
	if (res) {
		if (suspended)
			WARN(1, "Hardware became unavailable upon resume. This could be a software issue prior to suspend or a hardware issue.\n");
		else
			WARN(1, "Hardware became unavailable during restart.\n");
		ieee80211_handle_reconfig_failure(local);
		return res;
	}

	/* setup fragmentation threshold */
	drv_set_frag_threshold(local, hw->wiphy->frag_threshold);

	/* setup RTS threshold */
	drv_set_rts_threshold(local, hw->wiphy->rts_threshold);

	/* reset coverage class */
	drv_set_coverage_class(local, hw->wiphy->coverage_class);

	ieee80211_led_radio(local, true);
	ieee80211_mod_tpt_led_trig(local,
				   IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);

	/* add interfaces */
	sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
	if (sdata) {
		/* in HW restart it exists already */
		WARN_ON(local->resuming);
		res = drv_add_interface(local, sdata);
		if (WARN_ON(res)) {
			RCU_INIT_POINTER(local->monitor_sdata, NULL);
			synchronize_net();
			kfree(sdata);
		}
	}

	list_for_each_entry(sdata, &local->interfaces, list) {
		if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
		    sdata->vif.type != NL80211_IFTYPE_MONITOR &&
		    ieee80211_sdata_running(sdata)) {
			res = drv_add_interface(local, sdata);
			if (WARN_ON(res))
				break;
		}
	}

	/* If adding any of the interfaces failed above, roll back and
	 * report failure.
	 */
	if (res) {
		list_for_each_entry_continue_reverse(sdata, &local->interfaces,
						     list)
			if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
			    sdata->vif.type != NL80211_IFTYPE_MONITOR &&
			    ieee80211_sdata_running(sdata))
				drv_remove_interface(local, sdata);
		ieee80211_handle_reconfig_failure(local);
		return res;
	}

	/* add channel contexts */
	if (local->use_chanctx) {
		list_for_each_entry(ctx, &local->chanctx_list, list)
			if (ctx->replace_state !=
			    IEEE80211_CHANCTX_REPLACES_OTHER)
				WARN_ON(drv_add_chanctx(local, ctx));

		sdata = wiphy_dereference(local->hw.wiphy,
					  local->monitor_sdata);
		if (sdata && ieee80211_sdata_running(sdata))
			ieee80211_assign_chanctx(local, sdata, &sdata->deflink);
	}

	/* reconfigure hardware */
	ieee80211_hw_config(local, ~0);

	ieee80211_configure_filter(local);

	/* Finally also reconfigure all the BSS information */
	list_for_each_entry(sdata, &local->interfaces, list) {
		/* common change flags for all interface types - link only */
		u64 changed = BSS_CHANGED_ERP_CTS_PROT |
			      BSS_CHANGED_ERP_PREAMBLE |
			      BSS_CHANGED_ERP_SLOT |
			      BSS_CHANGED_HT |
			      BSS_CHANGED_BASIC_RATES |
			      BSS_CHANGED_BEACON_INT |
			      BSS_CHANGED_BSSID |
			      BSS_CHANGED_CQM |
			      BSS_CHANGED_QOS |
			      BSS_CHANGED_TXPOWER |
			      BSS_CHANGED_MCAST_RATE;
		struct ieee80211_link_data *link = NULL;
		unsigned int link_id;
		u32 active_links = 0;

		if (!ieee80211_sdata_running(sdata))
			continue;

		if (ieee80211_vif_is_mld(&sdata->vif)) {
			struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS] = {
				[0] = &sdata->vif.bss_conf,
			};

			if (sdata->vif.type == NL80211_IFTYPE_STATION) {
				/* start with a single active link */
				active_links = sdata->vif.active_links;
				link_id = ffs(active_links) - 1;
				sdata->vif.active_links = BIT(link_id);
			}

			drv_change_vif_links(local, sdata, 0,
					     sdata->vif.active_links,
					     old);
		}

		for (link_id = 0;
		     link_id < ARRAY_SIZE(sdata->vif.link_conf);
		     link_id++) {
			if (ieee80211_vif_is_mld(&sdata->vif) &&
			    !(sdata->vif.active_links & BIT(link_id)))
				continue;

			link = sdata_dereference(sdata->link[link_id], sdata);
			if (!link)
				continue;

			ieee80211_assign_chanctx(local, sdata, link);
		}

		switch (sdata->vif.type) {
		case NL80211_IFTYPE_AP_VLAN:
		case NL80211_IFTYPE_MONITOR:
			break;
		case NL80211_IFTYPE_ADHOC:
			if (sdata->vif.cfg.ibss_joined)
				WARN_ON(drv_join_ibss(local, sdata));
			fallthrough;
		default:
			ieee80211_reconfig_stations(sdata);
			fallthrough;
		case NL80211_IFTYPE_AP: /* AP stations are handled later */
			for (i = 0; i < IEEE80211_NUM_ACS; i++)
				drv_conf_tx(local, &sdata->deflink, i,
					    &sdata->deflink.tx_conf[i]);
			break;
		}

		if (sdata->vif.bss_conf.mu_mimo_owner)
			changed |= BSS_CHANGED_MU_GROUPS;

		if (!ieee80211_vif_is_mld(&sdata->vif))
			changed |= BSS_CHANGED_IDLE;

		switch (sdata->vif.type) {
		case NL80211_IFTYPE_STATION:
			if (!ieee80211_vif_is_mld(&sdata->vif)) {
				changed |= BSS_CHANGED_ASSOC |
					   BSS_CHANGED_ARP_FILTER |
					   BSS_CHANGED_PS;

				/* Re-send beacon info report to the driver */
				if (sdata->deflink.u.mgd.have_beacon)
					changed |= BSS_CHANGED_BEACON_INFO;

				if (sdata->vif.bss_conf.max_idle_period ||
				    sdata->vif.bss_conf.protected_keep_alive)
					changed |= BSS_CHANGED_KEEP_ALIVE;

				if (sdata->vif.bss_conf.eht_puncturing)
					changed |= BSS_CHANGED_EHT_PUNCTURING;

				ieee80211_bss_info_change_notify(sdata,
								 changed);
			} else if (!WARN_ON(!link)) {
				ieee80211_link_info_change_notify(sdata, link,
								  changed);
				changed = BSS_CHANGED_ASSOC |
					  BSS_CHANGED_IDLE |
					  BSS_CHANGED_PS |
					  BSS_CHANGED_ARP_FILTER;
				ieee80211_vif_cfg_change_notify(sdata, changed);
			}
			break;
		case NL80211_IFTYPE_OCB:
			changed |= BSS_CHANGED_OCB;
			ieee80211_bss_info_change_notify(sdata, changed);
			break;
		case NL80211_IFTYPE_ADHOC:
			changed |= BSS_CHANGED_IBSS;
			fallthrough;
		case NL80211_IFTYPE_AP:
			changed |= BSS_CHANGED_P2P_PS;

			if (ieee80211_vif_is_mld(&sdata->vif))
				ieee80211_vif_cfg_change_notify(sdata,
								BSS_CHANGED_SSID);
			else
				changed |= BSS_CHANGED_SSID;

			if (sdata->vif.bss_conf.ftm_responder == 1 &&
			    wiphy_ext_feature_isset(sdata->local->hw.wiphy,
					NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
				changed |= BSS_CHANGED_FTM_RESPONDER;

			if (sdata->vif.type == NL80211_IFTYPE_AP) {
				changed |= BSS_CHANGED_AP_PROBE_RESP;

				if (ieee80211_vif_is_mld(&sdata->vif)) {
					ieee80211_reconfig_ap_links(local,
								    sdata,
								    changed);
					break;
				}

				if (rcu_access_pointer(sdata->deflink.u.ap.beacon))
					drv_start_ap(local, sdata,
						     sdata->deflink.conf);
			}
			fallthrough;
		case NL80211_IFTYPE_MESH_POINT:
			if (sdata->vif.bss_conf.enable_beacon) {
				changed |= BSS_CHANGED_BEACON |
					   BSS_CHANGED_BEACON_ENABLED;
				ieee80211_bss_info_change_notify(sdata, changed);
			}
			break;
		case NL80211_IFTYPE_NAN:
			res = ieee80211_reconfig_nan(sdata);
			if (res < 0) {
				ieee80211_handle_reconfig_failure(local);
				return res;
			}
			break;
		case NL80211_IFTYPE_AP_VLAN:
		case NL80211_IFTYPE_MONITOR:
		case NL80211_IFTYPE_P2P_DEVICE:
			/* nothing to do */
			break;
		case NL80211_IFTYPE_UNSPECIFIED:
		case NUM_NL80211_IFTYPES:
		case NL80211_IFTYPE_P2P_CLIENT:
		case NL80211_IFTYPE_P2P_GO:
		case NL80211_IFTYPE_WDS:
			WARN_ON(1);
			break;
		}

		if (active_links)
			ieee80211_set_active_links(&sdata->vif, active_links);
	}

	ieee80211_recalc_ps(local);

	/*
	 * The sta might be in psm against the ap (e.g. because
	 * this was the state before a hw restart), so we
	 * explicitly send a null packet in order to make sure
	 * it'll sync against the ap (and get out of psm).
	 */
	if (!(local->hw.conf.flags & IEEE80211_CONF_PS)) {
		list_for_each_entry(sdata, &local->interfaces, list) {
			if (sdata->vif.type != NL80211_IFTYPE_STATION)
				continue;
			if (!sdata->u.mgd.associated)
				continue;

			ieee80211_send_nullfunc(local, sdata, false);
		}
	}

	/* APs are now beaconing, add back stations */
	list_for_each_entry(sdata, &local->interfaces, list) {
		if (!ieee80211_sdata_running(sdata))
			continue;

		switch (sdata->vif.type) {
		case NL80211_IFTYPE_AP_VLAN:
		case NL80211_IFTYPE_AP:
			ieee80211_reconfig_stations(sdata);
			break;
		default:
			break;
		}
	}

	/* add back keys */
	list_for_each_entry(sdata, &local->interfaces, list)
		ieee80211_reenable_keys(sdata);

	/* Reconfigure sched scan if it was interrupted by FW restart */
	sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata,
						lockdep_is_held(&local->hw.wiphy->mtx));
	sched_scan_req = rcu_dereference_protected(local->sched_scan_req,
						lockdep_is_held(&local->hw.wiphy->mtx));
	if (sched_scan_sdata && sched_scan_req)
		/*
		 * Sched scan stopped, but we don't want to report it. Instead,
		 * we're trying to reschedule. However, if more than one scan
		 * plan was set, we cannot reschedule since we don't know which
		 * scan plan was currently running (and some scan plans may have
		 * already finished).
		 */
		if (sched_scan_req->n_scan_plans > 1 ||
		    __ieee80211_request_sched_scan_start(sched_scan_sdata,
							 sched_scan_req)) {
			RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
			RCU_INIT_POINTER(local->sched_scan_req, NULL);
			sched_scan_stopped = true;
		}

	if (sched_scan_stopped)
		cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0);

 wake_up:

	if (local->monitors == local->open_count && local->monitors > 0)
		ieee80211_add_virtual_monitor(local);

	/*
	 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
	 * sessions can be established after a resume.
	 *
	 * Also tear down aggregation sessions since reconfiguring
	 * them in a hardware restart scenario is not easily done
	 * right now, and the hardware will have lost information
	 * about the sessions, but we and the AP still think they
	 * are active. This is really a workaround though.
	 */
	if (ieee80211_hw_check(hw, AMPDU_AGGREGATION)) {
		list_for_each_entry(sta, &local->sta_list, list) {
			if (!local->resuming)
				ieee80211_sta_tear_down_BA_sessions(
						sta, AGG_STOP_LOCAL_REQUEST);
			clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
		}
	}

	/*
	 * If this is for hw restart things are still running.
	 * We may want to change that later, however.
	 */
	if (local->open_count && (!suspended || reconfig_due_to_wowlan))
		drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);

	if (local->in_reconfig) {
		in_reconfig = local->in_reconfig;
		local->in_reconfig = false;
		barrier();

		/* Restart deferred ROCs */
		ieee80211_start_next_roc(local);

		/* Requeue all works */
		list_for_each_entry(sdata, &local->interfaces, list)
			wiphy_work_queue(local->hw.wiphy, &sdata->work);
	}

	ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
					IEEE80211_QUEUE_STOP_REASON_SUSPEND,
					false);

	if (in_reconfig) {
		list_for_each_entry(sdata, &local->interfaces, list) {
			if (!ieee80211_sdata_running(sdata))
				continue;
			if (sdata->vif.type == NL80211_IFTYPE_STATION)
				ieee80211_sta_restart(sdata);
		}
	}

	if (!suspended)
		return 0;

#ifdef CONFIG_PM
	/* first set suspended false, then resuming */
	local->suspended = false;
	mb();
	local->resuming = false;

	ieee80211_flush_completed_scan(local, false);

	if (local->open_count && !reconfig_due_to_wowlan)
		drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);

	list_for_each_entry(sdata, &local->interfaces, list) {
		if (!ieee80211_sdata_running(sdata))
			continue;
		if (sdata->vif.type == NL80211_IFTYPE_STATION)
			ieee80211_sta_restart(sdata);
	}

	mod_timer(&local->sta_cleanup, jiffies + 1);
#else
	WARN_ON(1);
#endif

	return 0;
}

static void ieee80211_reconfig_disconnect(struct ieee80211_vif *vif, u8 flag)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_local *local;
	struct ieee80211_key *key;

	if (WARN_ON(!vif))
		return;

	sdata = vif_to_sdata(vif);
	local = sdata->local;

	lockdep_assert_wiphy(local->hw.wiphy);

	if (WARN_ON(flag & IEEE80211_SDATA_DISCONNECT_RESUME &&
		    !local->resuming))
		return;

	if (WARN_ON(flag & IEEE80211_SDATA_DISCONNECT_HW_RESTART &&
		    !local->in_reconfig))
		return;

	if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
		return;

	sdata->flags |= flag;

	list_for_each_entry(key, &sdata->key_list, list)
		key->flags |= KEY_FLAG_TAINTED;
}

void ieee80211_hw_restart_disconnect(struct ieee80211_vif *vif)
{
	ieee80211_reconfig_disconnect(vif, IEEE80211_SDATA_DISCONNECT_HW_RESTART);
}
EXPORT_SYMBOL_GPL(ieee80211_hw_restart_disconnect);

void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
{
	ieee80211_reconfig_disconnect(vif, IEEE80211_SDATA_DISCONNECT_RESUME);
}
EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);

void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata,
			   struct ieee80211_link_data *link)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_chanctx_conf *chanctx_conf;
	struct ieee80211_chanctx *chanctx;

	lockdep_assert_wiphy(local->hw.wiphy);

	chanctx_conf = rcu_dereference_protected(link->conf->chanctx_conf,
						 lockdep_is_held(&local->hw.wiphy->mtx));

	/*
	 * This function can be called from a work, thus it may be possible
	 * that the chanctx_conf is removed (due to a disconnection, for
	 * example).
	 * So nothing should be done in such case.
	 */
	if (!chanctx_conf)
		return;

	chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
	ieee80211_recalc_smps_chanctx(local, chanctx);
}

void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata,
				  int link_id)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_chanctx_conf *chanctx_conf;
	struct ieee80211_chanctx *chanctx;
	int i;

	lockdep_assert_wiphy(local->hw.wiphy);

	for (i = 0; i < ARRAY_SIZE(sdata->vif.link_conf); i++) {
		struct ieee80211_bss_conf *bss_conf;

		if (link_id >= 0 && link_id != i)
			continue;

		rcu_read_lock();
		bss_conf = rcu_dereference(sdata->vif.link_conf[i]);
		if (!bss_conf) {
			rcu_read_unlock();
			continue;
		}

		chanctx_conf = rcu_dereference_protected(bss_conf->chanctx_conf,
							 lockdep_is_held(&local->hw.wiphy->mtx));
		/*
		 * Since we hold the wiphy mutex (checked above)
		 * we can take the chanctx_conf pointer out of the
		 * RCU critical section, it cannot go away without
		 * the mutex. Just the way we reached it could - in
		 * theory - go away, but we don't really care and
		 * it really shouldn't happen anyway.
		 */
		rcu_read_unlock();

		if (!chanctx_conf)
			return;

		chanctx = container_of(chanctx_conf, struct ieee80211_chanctx,
				       conf);
		ieee80211_recalc_chanctx_min_def(local, chanctx, NULL);
	}
}

size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
{
	size_t pos = offset;

	while (pos < ielen && ies[pos] != WLAN_EID_VENDOR_SPECIFIC)
		pos += 2 + ies[pos + 1];

	return pos;
}

u8 *ieee80211_ie_build_s1g_cap(u8 *pos, struct ieee80211_sta_s1g_cap *s1g_cap)
{
	*pos++ = WLAN_EID_S1G_CAPABILITIES;
	*pos++ = sizeof(struct ieee80211_s1g_cap);
	memset(pos, 0, sizeof(struct ieee80211_s1g_cap));

	memcpy(pos, &s1g_cap->cap, sizeof(s1g_cap->cap));
	pos += sizeof(s1g_cap->cap);

	memcpy(pos, &s1g_cap->nss_mcs, sizeof(s1g_cap->nss_mcs));
	pos += sizeof(s1g_cap->nss_mcs);

	return pos;
}

u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
			      u16 cap)
{
	__le16 tmp;

	*pos++ = WLAN_EID_HT_CAPABILITY;
	*pos++ = sizeof(struct ieee80211_ht_cap);
	memset(pos, 0, sizeof(struct ieee80211_ht_cap));

	/* capability flags */
	tmp = cpu_to_le16(cap);
	memcpy(pos, &tmp, sizeof(u16));
	pos += sizeof(u16);

	/* AMPDU parameters */
	*pos++ = ht_cap->ampdu_factor |
		 (ht_cap->ampdu_density <<
			IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);

	/* MCS set */
	memcpy(pos, &ht_cap->mcs, sizeof(ht_cap->mcs));
	pos += sizeof(ht_cap->mcs);

	/* extended capabilities */
	pos += sizeof(__le16);

	/* BF capabilities */
	pos += sizeof(__le32);

	/* antenna selection */
	pos += sizeof(u8);

	return pos;
}

u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
			       u32 cap)
{
	__le32 tmp;

	*pos++ = WLAN_EID_VHT_CAPABILITY;
	*pos++ = sizeof(struct ieee80211_vht_cap);
	memset(pos, 0, sizeof(struct ieee80211_vht_cap));

	/* capability flags */
	tmp = cpu_to_le32(cap);
	memcpy(pos, &tmp, sizeof(u32));
	pos += sizeof(u32);

	/* VHT MCS set */
	memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs));
	pos += sizeof(vht_cap->vht_mcs);

	return pos;
}

u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype)
{
	const struct ieee80211_sta_he_cap *he_cap;
	struct ieee80211_supported_band *sband;
	u8 n;

	sband = ieee80211_get_sband(sdata);
	if (!sband)
		return 0;

	he_cap = ieee80211_get_he_iftype_cap(sband, iftype);
	if (!he_cap)
		return 0;

	n = ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem);
	return 2 + 1 +
	       sizeof(he_cap->he_cap_elem) + n +
	       ieee80211_he_ppe_size(he_cap->ppe_thres[0],
				     he_cap->he_cap_elem.phy_cap_info);
}

u8 *ieee80211_ie_build_he_cap(ieee80211_conn_flags_t disable_flags, u8 *pos,
			      const struct ieee80211_sta_he_cap *he_cap,
			      u8 *end)
{
	struct ieee80211_he_cap_elem elem;
	u8 n;
	u8 ie_len;
	u8 *orig_pos = pos;

	/* Make sure we have place for the IE */
	/*
	 * TODO: the 1 added is because this temporarily is under the EXTENSION
	 * IE. Get rid of it when it moves.
	 */
	if (!he_cap)
		return orig_pos;

	/* modify on stack first to calculate 'n' and 'ie_len' correctly */
	elem = he_cap->he_cap_elem;

	if (disable_flags & IEEE80211_CONN_DISABLE_40MHZ)
		elem.phy_cap_info[0] &=
			~(IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
			  IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G);

	if (disable_flags & IEEE80211_CONN_DISABLE_160MHZ)
		elem.phy_cap_info[0] &=
			~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;

	if (disable_flags & IEEE80211_CONN_DISABLE_80P80MHZ)
		elem.phy_cap_info[0] &=
			~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;

	n = ieee80211_he_mcs_nss_size(&elem);
	ie_len = 2 + 1 +
		 sizeof(he_cap->he_cap_elem) + n +
		 ieee80211_he_ppe_size(he_cap->ppe_thres[0],
				       he_cap->he_cap_elem.phy_cap_info);

	if ((end - pos) < ie_len)
		return orig_pos;

	*pos++ = WLAN_EID_EXTENSION;
	pos++; /* We'll set the size later below */
	*pos++ = WLAN_EID_EXT_HE_CAPABILITY;

	/* Fixed data */
	memcpy(pos, &elem, sizeof(elem));
	pos += sizeof(elem);

	memcpy(pos, &he_cap->he_mcs_nss_supp, n);
	pos += n;

	/* Check if PPE Threshold should be present */
	if ((he_cap->he_cap_elem.phy_cap_info[6] &
	     IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) == 0)
		goto end;

	/*
	 * Calculate how many PPET16/PPET8 pairs are to come. Algorithm:
	 * (NSS_M1 + 1) x (num of 1 bits in RU_INDEX_BITMASK)
	 */
	n = hweight8(he_cap->ppe_thres[0] &
		     IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK);
	n *= (1 + ((he_cap->ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) >>
		   IEEE80211_PPE_THRES_NSS_POS));

	/*
	 * Each pair is 6 bits, and we need to add the 7 "header" bits to the
	 * total size.
	 */
	n = (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) + 7;
	n = DIV_ROUND_UP(n, 8);

	/* Copy PPE Thresholds */
	memcpy(pos, &he_cap->ppe_thres, n);
	pos += n;

end:
	orig_pos[1] = (pos - orig_pos) - 2;
	return pos;
}

void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
				    enum ieee80211_smps_mode smps_mode,
				    struct sk_buff *skb)
{
	struct ieee80211_supported_band *sband;
	const struct ieee80211_sband_iftype_data *iftd;
	enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
	u8 *pos;
	u16 cap;

	if (!cfg80211_any_usable_channels(sdata->local->hw.wiphy,
					  BIT(NL80211_BAND_6GHZ),
					  IEEE80211_CHAN_NO_HE))
		return;

	sband = sdata->local->hw.wiphy->bands[NL80211_BAND_6GHZ];

	iftd = ieee80211_get_sband_iftype_data(sband, iftype);
	if (!iftd)
		return;

	/* Check for device HE 6 GHz capability before adding element */
	if (!iftd->he_6ghz_capa.capa)
		return;

	cap = le16_to_cpu(iftd->he_6ghz_capa.capa);
	cap &= ~IEEE80211_HE_6GHZ_CAP_SM_PS;

	switch (smps_mode) {
	case IEEE80211_SMPS_AUTOMATIC:
	case IEEE80211_SMPS_NUM_MODES:
		WARN_ON(1);
		fallthrough;
	case IEEE80211_SMPS_OFF:
		cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DISABLED,
				       IEEE80211_HE_6GHZ_CAP_SM_PS);
		break;
	case IEEE80211_SMPS_STATIC:
		cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_STATIC,
				       IEEE80211_HE_6GHZ_CAP_SM_PS);
		break;
	case IEEE80211_SMPS_DYNAMIC:
		cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DYNAMIC,
				       IEEE80211_HE_6GHZ_CAP_SM_PS);
		break;
	}

	pos = skb_put(skb, 2 + 1 + sizeof(cap));
	ieee80211_write_he_6ghz_cap(pos, cpu_to_le16(cap),
				    pos + 2 + 1 + sizeof(cap));
}

u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
			       const struct cfg80211_chan_def *chandef,
			       u16 prot_mode, bool rifs_mode)
{
	struct ieee80211_ht_operation *ht_oper;
	/* Build HT Information */
	*pos++ = WLAN_EID_HT_OPERATION;
	*pos++ = sizeof(struct ieee80211_ht_operation);
	ht_oper = (struct ieee80211_ht_operation *)pos;
	ht_oper->primary_chan = ieee80211_frequency_to_channel(
					chandef->chan->center_freq);
	switch (chandef->width) {
	case NL80211_CHAN_WIDTH_160:
	case NL80211_CHAN_WIDTH_80P80:
	case NL80211_CHAN_WIDTH_80:
	case NL80211_CHAN_WIDTH_40:
		if (chandef->center_freq1 > chandef->chan->center_freq)
			ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
		else
			ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
		break;
	case NL80211_CHAN_WIDTH_320:
		/* HT information element should not be included on 6GHz */
		WARN_ON(1);
		return pos;
	default:
		ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
		break;
	}
	if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
	    chandef->width != NL80211_CHAN_WIDTH_20_NOHT &&
	    chandef->width != NL80211_CHAN_WIDTH_20)
		ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;

	if (rifs_mode)
		ht_oper->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE;

	ht_oper->operation_mode = cpu_to_le16(prot_mode);
	ht_oper->stbc_param = 0x0000;

	/* It seems that Basic MCS set and Supported MCS set
	   are identical for the first 10 bytes */
	memset(&ht_oper->basic_set, 0, 16);
	memcpy(&ht_oper->basic_set, &ht_cap->mcs, 10);

	return pos + sizeof(struct ieee80211_ht_operation);
}

void ieee80211_ie_build_wide_bw_cs(u8 *pos,
				   const struct cfg80211_chan_def *chandef)
{
	*pos++ = WLAN_EID_WIDE_BW_CHANNEL_SWITCH;	/* EID */
	*pos++ = 3;					/* IE length */
	/* New channel width */
	switch (chandef->width) {
	case NL80211_CHAN_WIDTH_80:
		*pos++ = IEEE80211_VHT_CHANWIDTH_80MHZ;
		break;
	case NL80211_CHAN_WIDTH_160:
		*pos++ = IEEE80211_VHT_CHANWIDTH_160MHZ;
		break;
	case NL80211_CHAN_WIDTH_80P80:
		*pos++ = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
		break;
	case NL80211_CHAN_WIDTH_320:
		/* The behavior is not defined for 320 MHz channels */
		WARN_ON(1);
		fallthrough;
	default:
		*pos++ = IEEE80211_VHT_CHANWIDTH_USE_HT;
	}

	/* new center frequency segment 0 */
	*pos++ = ieee80211_frequency_to_channel(chandef->center_freq1);
	/* new center frequency segment 1 */
	if (chandef->center_freq2)
		*pos++ = ieee80211_frequency_to_channel(chandef->center_freq2);
	else
		*pos++ = 0;
}

u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
				const struct cfg80211_chan_def *chandef)
{
	struct ieee80211_vht_operation *vht_oper;

	*pos++ = WLAN_EID_VHT_OPERATION;
	*pos++ = sizeof(struct ieee80211_vht_operation);
	vht_oper = (struct ieee80211_vht_operation *)pos;
	vht_oper->center_freq_seg0_idx = ieee80211_frequency_to_channel(
							chandef->center_freq1);
	if (chandef->center_freq2)
		vht_oper->center_freq_seg1_idx =
			ieee80211_frequency_to_channel(chandef->center_freq2);
	else
		vht_oper->center_freq_seg1_idx = 0x00;

	switch (chandef->width) {
	case NL80211_CHAN_WIDTH_160:
		/*
		 * Convert 160 MHz channel width to new style as interop
		 * workaround.
		 */
		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
		vht_oper->center_freq_seg1_idx = vht_oper->center_freq_seg0_idx;
		if (chandef->chan->center_freq < chandef->center_freq1)
			vht_oper->center_freq_seg0_idx -= 8;
		else
			vht_oper->center_freq_seg0_idx += 8;
		break;
	case NL80211_CHAN_WIDTH_80P80:
		/*
		 * Convert 80+80 MHz channel width to new style as interop
		 * workaround.
		 */
		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
		break;
	case NL80211_CHAN_WIDTH_80:
		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
		break;
	case NL80211_CHAN_WIDTH_320:
		/* VHT information element should not be included on 6GHz */
		WARN_ON(1);
		return pos;
	default:
		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
		break;
	}

	/* don't require special VHT peer rates */
	vht_oper->basic_mcs_set = cpu_to_le16(0xffff);

	return pos + sizeof(struct ieee80211_vht_operation);
}

u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef)
{
	struct ieee80211_he_operation *he_oper;
	struct ieee80211_he_6ghz_oper *he_6ghz_op;
	u32 he_oper_params;
	u8 ie_len = 1 + sizeof(struct ieee80211_he_operation);

	if (chandef->chan->band == NL80211_BAND_6GHZ)
		ie_len += sizeof(struct ieee80211_he_6ghz_oper);

	*pos++ = WLAN_EID_EXTENSION;
	*pos++ = ie_len;
	*pos++ = WLAN_EID_EXT_HE_OPERATION;

	he_oper_params = 0;
	he_oper_params |= u32_encode_bits(1023, /* disabled */
				IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
	he_oper_params |= u32_encode_bits(1,
				IEEE80211_HE_OPERATION_ER_SU_DISABLE);
	he_oper_params |= u32_encode_bits(1,
				IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
	if (chandef->chan->band == NL80211_BAND_6GHZ)
		he_oper_params |= u32_encode_bits(1,
				IEEE80211_HE_OPERATION_6GHZ_OP_INFO);

	he_oper = (struct ieee80211_he_operation *)pos;
	he_oper->he_oper_params = cpu_to_le32(he_oper_params);

	/* don't require special HE peer rates */
	he_oper->he_mcs_nss_set = cpu_to_le16(0xffff);
	pos += sizeof(struct ieee80211_he_operation);

	if (chandef->chan->band != NL80211_BAND_6GHZ)
		goto out;

	/* TODO add VHT operational */
	he_6ghz_op = (struct ieee80211_he_6ghz_oper *)pos;
	he_6ghz_op->minrate = 6; /* 6 Mbps */
	he_6ghz_op->primary =
		ieee80211_frequency_to_channel(chandef->chan->center_freq);
	he_6ghz_op->ccfs0 =
		ieee80211_frequency_to_channel(chandef->center_freq1);
	if (chandef->center_freq2)
		he_6ghz_op->ccfs1 =
			ieee80211_frequency_to_channel(chandef->center_freq2);
	else
		he_6ghz_op->ccfs1 = 0;

	switch (chandef->width) {
	case NL80211_CHAN_WIDTH_320:
		/*
		 * TODO: mesh operation is not defined over 6GHz 320 MHz
		 * channels.
		 */
		WARN_ON(1);
		break;
	case NL80211_CHAN_WIDTH_160:
		/* Convert 160 MHz channel width to new style as interop
		 * workaround.
		 */
		he_6ghz_op->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
		he_6ghz_op->ccfs1 = he_6ghz_op->ccfs0;
		if (chandef->chan->center_freq < chandef->center_freq1)
			he_6ghz_op->ccfs0 -= 8;
		else
			he_6ghz_op->ccfs0 += 8;
		fallthrough;
	case NL80211_CHAN_WIDTH_80P80:
		he_6ghz_op->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
		break;
	case NL80211_CHAN_WIDTH_80:
		he_6ghz_op->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ;
		break;
	case NL80211_CHAN_WIDTH_40:
		he_6ghz_op->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ;
		break;
	default:
		he_6ghz_op->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ;
		break;
	}

	pos += sizeof(struct ieee80211_he_6ghz_oper);

out:
	return pos;
}

u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef,
				const struct ieee80211_sta_eht_cap *eht_cap)

{
	const struct ieee80211_eht_mcs_nss_supp_20mhz_only *eht_mcs_nss =
					&eht_cap->eht_mcs_nss_supp.only_20mhz;
	struct ieee80211_eht_operation *eht_oper;
	struct ieee80211_eht_operation_info *eht_oper_info;
	u8 eht_oper_len = offsetof(struct ieee80211_eht_operation, optional);
	u8 eht_oper_info_len =
		offsetof(struct ieee80211_eht_operation_info, optional);
	u8 chan_width = 0;

	*pos++ = WLAN_EID_EXTENSION;
	*pos++ = 1 + eht_oper_len + eht_oper_info_len;
	*pos++ = WLAN_EID_EXT_EHT_OPERATION;

	eht_oper = (struct ieee80211_eht_operation *)pos;

	memcpy(&eht_oper->basic_mcs_nss, eht_mcs_nss, sizeof(*eht_mcs_nss));
	eht_oper->params |= IEEE80211_EHT_OPER_INFO_PRESENT;
	pos += eht_oper_len;

	eht_oper_info =
		(struct ieee80211_eht_operation_info *)eht_oper->optional;

	eht_oper_info->ccfs0 =
		ieee80211_frequency_to_channel(chandef->center_freq1);
	if (chandef->center_freq2)
		eht_oper_info->ccfs1 =
			ieee80211_frequency_to_channel(chandef->center_freq2);
	else
		eht_oper_info->ccfs1 = 0;

	switch (chandef->width) {
	case NL80211_CHAN_WIDTH_320:
		chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ;
		eht_oper_info->ccfs1 = eht_oper_info->ccfs0;
		if (chandef->chan->center_freq < chandef->center_freq1)
			eht_oper_info->ccfs0 -= 16;
		else
			eht_oper_info->ccfs0 += 16;
		break;
	case NL80211_CHAN_WIDTH_160:
		eht_oper_info->ccfs1 = eht_oper_info->ccfs0;
		if (chandef->chan->center_freq < chandef->center_freq1)
			eht_oper_info->ccfs0 -= 8;
		else
			eht_oper_info->ccfs0 += 8;
		fallthrough;
	case NL80211_CHAN_WIDTH_80P80:
		chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_160MHZ;
		break;
	case NL80211_CHAN_WIDTH_80:
		chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ;
		break;
	case NL80211_CHAN_WIDTH_40:
		chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_40MHZ;
		break;
	default:
		chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_20MHZ;
		break;
	}
	eht_oper_info->control = chan_width;
	pos += eht_oper_info_len;

	/* TODO: eht_oper_info->optional */

	return pos;
}

bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
			       struct cfg80211_chan_def *chandef)
{
	enum nl80211_channel_type channel_type;

	if (!ht_oper)
		return false;

	switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
	case IEEE80211_HT_PARAM_CHA_SEC_NONE:
		channel_type = NL80211_CHAN_HT20;
		break;
	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
		channel_type = NL80211_CHAN_HT40PLUS;
		break;
	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
		channel_type = NL80211_CHAN_HT40MINUS;
		break;
	default:
		return false;
	}

	cfg80211_chandef_create(chandef, chandef->chan, channel_type);
	return true;
}

bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info,
				const struct ieee80211_vht_operation *oper,
				const struct ieee80211_ht_operation *htop,
				struct cfg80211_chan_def *chandef)
{
	struct cfg80211_chan_def new = *chandef;
	int cf0, cf1;
	int ccfs0, ccfs1, ccfs2;
	int ccf0, ccf1;
	u32 vht_cap;
	bool support_80_80 = false;
	bool support_160 = false;
	u8 ext_nss_bw_supp = u32_get_bits(vht_cap_info,
					  IEEE80211_VHT_CAP_EXT_NSS_BW_MASK);
	u8 supp_chwidth = u32_get_bits(vht_cap_info,
				       IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK);

	if (!oper || !htop)
		return false;

	vht_cap = hw->wiphy->bands[chandef->chan->band]->vht_cap.cap;
	support_160 = (vht_cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK |
				  IEEE80211_VHT_CAP_EXT_NSS_BW_MASK));
	support_80_80 = ((vht_cap &
			 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) ||
			(vht_cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
			 vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) ||
			((vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >>
				    IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT > 1));
	ccfs0 = oper->center_freq_seg0_idx;
	ccfs1 = oper->center_freq_seg1_idx;
	ccfs2 = (le16_to_cpu(htop->operation_mode) &
				IEEE80211_HT_OP_MODE_CCFS2_MASK)
			>> IEEE80211_HT_OP_MODE_CCFS2_SHIFT;

	ccf0 = ccfs0;

	/* if not supported, parse as though we didn't understand it */
	if (!ieee80211_hw_check(hw, SUPPORTS_VHT_EXT_NSS_BW))
		ext_nss_bw_supp = 0;

	/*
	 * Cf. IEEE 802.11 Table 9-250
	 *
	 * We really just consider that because it's inefficient to connect
	 * at a higher bandwidth than we'll actually be able to use.
	 */
	switch ((supp_chwidth << 4) | ext_nss_bw_supp) {
	default:
	case 0x00:
		ccf1 = 0;
		support_160 = false;
		support_80_80 = false;
		break;
	case 0x01:
		support_80_80 = false;
		fallthrough;
	case 0x02:
	case 0x03:
		ccf1 = ccfs2;
		break;
	case 0x10:
		ccf1 = ccfs1;
		break;
	case 0x11:
	case 0x12:
		if (!ccfs1)
			ccf1 = ccfs2;
		else
			ccf1 = ccfs1;
		break;
	case 0x13:
	case 0x20:
	case 0x23:
		ccf1 = ccfs1;
		break;
	}

	cf0 = ieee80211_channel_to_frequency(ccf0, chandef->chan->band);
	cf1 = ieee80211_channel_to_frequency(ccf1, chandef->chan->band);

	switch (oper->chan_width) {
	case IEEE80211_VHT_CHANWIDTH_USE_HT:
		/* just use HT information directly */
		break;
	case IEEE80211_VHT_CHANWIDTH_80MHZ:
		new.width = NL80211_CHAN_WIDTH_80;
		new.center_freq1 = cf0;
		/* If needed, adjust based on the newer interop workaround. */
		if (ccf1) {
			unsigned int diff;

			diff = abs(ccf1 - ccf0);
			if ((diff == 8) && support_160) {
				new.width = NL80211_CHAN_WIDTH_160;
				new.center_freq1 = cf1;
			} else if ((diff > 8) && support_80_80) {
				new.width = NL80211_CHAN_WIDTH_80P80;
				new.center_freq2 = cf1;
			}
		}
		break;
	case IEEE80211_VHT_CHANWIDTH_160MHZ:
		/* deprecated encoding */
		new.width = NL80211_CHAN_WIDTH_160;
		new.center_freq1 = cf0;
		break;
	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
		/* deprecated encoding */
		new.width = NL80211_CHAN_WIDTH_80P80;
		new.center_freq1 = cf0;
		new.center_freq2 = cf1;
		break;
	default:
		return false;
	}

	if (!cfg80211_chandef_valid(&new))
		return false;

	*chandef = new;
	return true;
}

void ieee80211_chandef_eht_oper(const struct ieee80211_eht_operation_info *info,
				bool support_160, bool support_320,
				struct cfg80211_chan_def *chandef)
{
	chandef->center_freq1 =
		ieee80211_channel_to_frequency(info->ccfs0,
					       chandef->chan->band);

	switch (u8_get_bits(info->control,
			    IEEE80211_EHT_OPER_CHAN_WIDTH)) {
	case IEEE80211_EHT_OPER_CHAN_WIDTH_20MHZ:
		chandef->width = NL80211_CHAN_WIDTH_20;
		break;
	case IEEE80211_EHT_OPER_CHAN_WIDTH_40MHZ:
		chandef->width = NL80211_CHAN_WIDTH_40;
		break;
	case IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ:
		chandef->width = NL80211_CHAN_WIDTH_80;
		break;
	case IEEE80211_EHT_OPER_CHAN_WIDTH_160MHZ:
		if (support_160) {
			chandef->width = NL80211_CHAN_WIDTH_160;
			chandef->center_freq1 =
				ieee80211_channel_to_frequency(info->ccfs1,
							       chandef->chan->band);
		} else {
			chandef->width = NL80211_CHAN_WIDTH_80;
		}
		break;
	case IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ:
		if (support_320) {
			chandef->width = NL80211_CHAN_WIDTH_320;
			chandef->center_freq1 =
				ieee80211_channel_to_frequency(info->ccfs1,
							       chandef->chan->band);
		} else if (support_160) {
			chandef->width = NL80211_CHAN_WIDTH_160;
		} else {
			chandef->width = NL80211_CHAN_WIDTH_80;

			if (chandef->center_freq1 > chandef->chan->center_freq)
				chandef->center_freq1 -= 40;
			else
				chandef->center_freq1 += 40;
		}
		break;
	}
}

bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
				    const struct ieee80211_he_operation *he_oper,
				    const struct ieee80211_eht_operation *eht_oper,
				    struct cfg80211_chan_def *chandef)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_supported_band *sband;
	enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
	const struct ieee80211_sta_he_cap *he_cap;
	const struct ieee80211_sta_eht_cap *eht_cap;
	struct cfg80211_chan_def he_chandef = *chandef;
	const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
	bool support_80_80, support_160, support_320;
	u8 he_phy_cap, eht_phy_cap;
	u32 freq;

	if (chandef->chan->band != NL80211_BAND_6GHZ)
		return true;

	sband = local->hw.wiphy->bands[NL80211_BAND_6GHZ];

	he_cap = ieee80211_get_he_iftype_cap(sband, iftype);
	if (!he_cap) {
		sdata_info(sdata, "Missing iftype sband data/HE cap");
		return false;
	}

	he_phy_cap = he_cap->he_cap_elem.phy_cap_info[0];
	support_160 =
		he_phy_cap &
		IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
	support_80_80 =
		he_phy_cap &
		IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;

	if (!he_oper) {
		sdata_info(sdata,
			   "HE is not advertised on (on %d MHz), expect issues\n",
			   chandef->chan->center_freq);
		return false;
	}

	eht_cap = ieee80211_get_eht_iftype_cap(sband, iftype);
	if (!eht_cap)
		eht_oper = NULL;

	he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);

	if (!he_6ghz_oper) {
		sdata_info(sdata,
			   "HE 6GHz operation missing (on %d MHz), expect issues\n",
			   chandef->chan->center_freq);
		return false;
	}

	/*
	 * The EHT operation IE does not contain the primary channel so the
	 * primary channel frequency should be taken from the 6 GHz operation
	 * information.
	 */
	freq = ieee80211_channel_to_frequency(he_6ghz_oper->primary,
					      NL80211_BAND_6GHZ);
	he_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq);

	switch (u8_get_bits(he_6ghz_oper->control,
			    IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) {
	case IEEE80211_6GHZ_CTRL_REG_LPI_AP:
		bss_conf->power_type = IEEE80211_REG_LPI_AP;
		break;
	case IEEE80211_6GHZ_CTRL_REG_SP_AP:
		bss_conf->power_type = IEEE80211_REG_SP_AP;
		break;
	default:
		bss_conf->power_type = IEEE80211_REG_UNSET_AP;
		break;
	}

	if (!eht_oper ||
	    !(eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT)) {
		switch (u8_get_bits(he_6ghz_oper->control,
				    IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH)) {
		case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ:
			he_chandef.width = NL80211_CHAN_WIDTH_20;
			break;
		case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ:
			he_chandef.width = NL80211_CHAN_WIDTH_40;
			break;
		case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ:
			he_chandef.width = NL80211_CHAN_WIDTH_80;
			break;
		case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ:
			he_chandef.width = NL80211_CHAN_WIDTH_80;
			if (!he_6ghz_oper->ccfs1)
				break;
			if (abs(he_6ghz_oper->ccfs1 - he_6ghz_oper->ccfs0) == 8) {
				if (support_160)
					he_chandef.width = NL80211_CHAN_WIDTH_160;
			} else {
				if (support_80_80)
					he_chandef.width = NL80211_CHAN_WIDTH_80P80;
			}
			break;
		}

		if (he_chandef.width == NL80211_CHAN_WIDTH_160) {
			he_chandef.center_freq1 =
				ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
							       NL80211_BAND_6GHZ);
		} else {
			he_chandef.center_freq1 =
				ieee80211_channel_to_frequency(he_6ghz_oper->ccfs0,
							       NL80211_BAND_6GHZ);
			if (support_80_80 || support_160)
				he_chandef.center_freq2 =
					ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
								       NL80211_BAND_6GHZ);
		}
	} else {
		eht_phy_cap = eht_cap->eht_cap_elem.phy_cap_info[0];
		support_320 =
			eht_phy_cap & IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;

		ieee80211_chandef_eht_oper((const void *)eht_oper->optional,
					   support_160, support_320,
					   &he_chandef);
	}

	if (!cfg80211_chandef_valid(&he_chandef)) {
		sdata_info(sdata,
			   "HE 6GHz operation resulted in invalid chandef: %d MHz/%d/%d MHz/%d MHz\n",
			   he_chandef.chan ? he_chandef.chan->center_freq : 0,
			   he_chandef.width,
			   he_chandef.center_freq1,
			   he_chandef.center_freq2);
		return false;
	}

	*chandef = he_chandef;

	return true;
}

bool ieee80211_chandef_s1g_oper(const struct ieee80211_s1g_oper_ie *oper,
				struct cfg80211_chan_def *chandef)
{
	u32 oper_freq;

	if (!oper)
		return false;

	switch (FIELD_GET(S1G_OPER_CH_WIDTH_OPER, oper->ch_width)) {
	case IEEE80211_S1G_CHANWIDTH_1MHZ:
		chandef->width = NL80211_CHAN_WIDTH_1;
		break;
	case IEEE80211_S1G_CHANWIDTH_2MHZ:
		chandef->width = NL80211_CHAN_WIDTH_2;
		break;
	case IEEE80211_S1G_CHANWIDTH_4MHZ:
		chandef->width = NL80211_CHAN_WIDTH_4;
		break;
	case IEEE80211_S1G_CHANWIDTH_8MHZ:
		chandef->width = NL80211_CHAN_WIDTH_8;
		break;
	case IEEE80211_S1G_CHANWIDTH_16MHZ:
		chandef->width = NL80211_CHAN_WIDTH_16;
		break;
	default:
		return false;
	}

	oper_freq = ieee80211_channel_to_freq_khz(oper->oper_ch,
						  NL80211_BAND_S1GHZ);
	chandef->center_freq1 = KHZ_TO_MHZ(oper_freq);
	chandef->freq1_offset = oper_freq % 1000;

	return true;
}

int ieee80211_parse_bitrates(enum nl80211_chan_width width,
			     const struct ieee80211_supported_band *sband,
			     const u8 *srates, int srates_len, u32 *rates)
{
	u32 rate_flags = ieee80211_chanwidth_rate_flags(width);
	struct ieee80211_rate *br;
	int brate, rate, i, j, count = 0;

	*rates = 0;

	for (i = 0; i < srates_len; i++) {
		rate = srates[i] & 0x7f;

		for (j = 0; j < sband->n_bitrates; j++) {
			br = &sband->bitrates[j];
			if ((rate_flags & br->flags) != rate_flags)
				continue;

			brate = DIV_ROUND_UP(br->bitrate, 5);
			if (brate == rate) {
				*rates |= BIT(j);
				count++;
				break;
			}
		}
	}
	return count;
}

int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
			    struct sk_buff *skb, bool need_basic,
			    enum nl80211_band band)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_supported_band *sband;
	int rate;
	u8 i, rates, *pos;
	u32 basic_rates = sdata->vif.bss_conf.basic_rates;
	u32 rate_flags;

	rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
	sband = local->hw.wiphy->bands[band];
	rates = 0;
	for (i = 0; i < sband->n_bitrates; i++) {
		if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
			continue;
		rates++;
	}
	if (rates > 8)
		rates = 8;

	if (skb_tailroom(skb) < rates + 2)
		return -ENOMEM;

	pos = skb_put(skb, rates + 2);
	*pos++ = WLAN_EID_SUPP_RATES;
	*pos++ = rates;
	for (i = 0; i < rates; i++) {
		u8 basic = 0;
		if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
			continue;

		if (need_basic && basic_rates & BIT(i))
			basic = 0x80;
		rate = DIV_ROUND_UP(sband->bitrates[i].bitrate, 5);
		*pos++ = basic | (u8) rate;
	}

	return 0;
}

int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
				struct sk_buff *skb, bool need_basic,
				enum nl80211_band band)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_supported_band *sband;
	int rate;
	u8 i, exrates, *pos;
	u32 basic_rates = sdata->vif.bss_conf.basic_rates;
	u32 rate_flags;

	rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);

	sband = local->hw.wiphy->bands[band];
	exrates = 0;
	for (i = 0; i < sband->n_bitrates; i++) {
		if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
			continue;
		exrates++;
	}

	if (exrates > 8)
		exrates -= 8;
	else
		exrates = 0;

	if (skb_tailroom(skb) < exrates + 2)
		return -ENOMEM;

	if (exrates) {
		pos = skb_put(skb, exrates + 2);
		*pos++ = WLAN_EID_EXT_SUPP_RATES;
		*pos++ = exrates;
		for (i = 8; i < sband->n_bitrates; i++) {
			u8 basic = 0;
			if ((rate_flags & sband->bitrates[i].flags)
			    != rate_flags)
				continue;
			if (need_basic && basic_rates & BIT(i))
				basic = 0x80;
			rate = DIV_ROUND_UP(sband->bitrates[i].bitrate, 5);
			*pos++ = basic | (u8) rate;
		}
	}
	return 0;
}

int ieee80211_ave_rssi(struct ieee80211_vif *vif)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);

	if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION))
		return 0;

	return -ewma_beacon_signal_read(&sdata->deflink.u.mgd.ave_beacon_signal);
}
EXPORT_SYMBOL_GPL(ieee80211_ave_rssi);

u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs)
{
	if (!mcs)
		return 1;

	/* TODO: consider rx_highest */

	if (mcs->rx_mask[3])
		return 4;
	if (mcs->rx_mask[2])
		return 3;
	if (mcs->rx_mask[1])
		return 2;
	return 1;
}

/**
 * ieee80211_calculate_rx_timestamp - calculate timestamp in frame
 * @local: mac80211 hw info struct
 * @status: RX status
 * @mpdu_len: total MPDU length (including FCS)
 * @mpdu_offset: offset into MPDU to calculate timestamp at
 *
 * This function calculates the RX timestamp at the given MPDU offset, taking
 * into account what the RX timestamp was. An offset of 0 will just normalize
 * the timestamp to TSF at beginning of MPDU reception.
 *
 * Returns: the calculated timestamp
 */
u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
				     struct ieee80211_rx_status *status,
				     unsigned int mpdu_len,
				     unsigned int mpdu_offset)
{
	u64 ts = status->mactime;
	bool mactime_plcp_start;
	struct rate_info ri;
	u16 rate;
	u8 n_ltf;

	if (WARN_ON(!ieee80211_have_rx_timestamp(status)))
		return 0;

	mactime_plcp_start = (status->flag & RX_FLAG_MACTIME) ==
				RX_FLAG_MACTIME_PLCP_START;

	memset(&ri, 0, sizeof(ri));

	ri.bw = status->bw;

	/* Fill cfg80211 rate info */
	switch (status->encoding) {
	case RX_ENC_EHT:
		ri.flags |= RATE_INFO_FLAGS_EHT_MCS;
		ri.mcs = status->rate_idx;
		ri.nss = status->nss;
		ri.eht_ru_alloc = status->eht.ru;
		if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
			ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
		/* TODO/FIXME: is this right? handle other PPDUs */
		if (mactime_plcp_start) {
			mpdu_offset += 2;
			ts += 36;
		}
		break;
	case RX_ENC_HE:
		ri.flags |= RATE_INFO_FLAGS_HE_MCS;
		ri.mcs = status->rate_idx;
		ri.nss = status->nss;
		ri.he_ru_alloc = status->he_ru;
		if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
			ri.flags |= RATE_INFO_FLAGS_SHORT_GI;

		/*
		 * See P802.11ax_D6.0, section 27.3.4 for
		 * VHT PPDU format.
		 */
		if (mactime_plcp_start) {
			mpdu_offset += 2;
			ts += 36;

			/*
			 * TODO:
			 * For HE MU PPDU, add the HE-SIG-B.
			 * For HE ER PPDU, add 8us for the HE-SIG-A.
			 * For HE TB PPDU, add 4us for the HE-STF.
			 * Add the HE-LTF durations - variable.
			 */
		}

		break;
	case RX_ENC_HT:
		ri.mcs = status->rate_idx;
		ri.flags |= RATE_INFO_FLAGS_MCS;
		if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
			ri.flags |= RATE_INFO_FLAGS_SHORT_GI;

		/*
		 * See P802.11REVmd_D3.0, section 19.3.2 for
		 * HT PPDU format.
		 */
		if (mactime_plcp_start) {
			mpdu_offset += 2;
			if (status->enc_flags & RX_ENC_FLAG_HT_GF)
				ts += 24;
			else
				ts += 32;

			/*
			 * Add Data HT-LTFs per streams
			 * TODO: add Extension HT-LTFs, 4us per LTF
			 */
			n_ltf = ((ri.mcs >> 3) & 3) + 1;
			n_ltf = n_ltf == 3 ? 4 : n_ltf;
			ts += n_ltf * 4;
		}

		break;
	case RX_ENC_VHT:
		ri.flags |= RATE_INFO_FLAGS_VHT_MCS;
		ri.mcs = status->rate_idx;
		ri.nss = status->nss;
		if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
			ri.flags |= RATE_INFO_FLAGS_SHORT_GI;

		/*
		 * See P802.11REVmd_D3.0, section 21.3.2 for
		 * VHT PPDU format.
		 */
		if (mactime_plcp_start) {
			mpdu_offset += 2;
			ts += 36;

			/*
			 * Add VHT-LTFs per streams
			 */
			n_ltf = (ri.nss != 1) && (ri.nss % 2) ?
				ri.nss + 1 : ri.nss;
			ts += 4 * n_ltf;
		}

		break;
	default:
		WARN_ON(1);
		fallthrough;
	case RX_ENC_LEGACY: {
		struct ieee80211_supported_band *sband;

		sband = local->hw.wiphy->bands[status->band];
		ri.legacy = sband->bitrates[status->rate_idx].bitrate;

		if (mactime_plcp_start) {
			if (status->band == NL80211_BAND_5GHZ) {
				ts += 20;
				mpdu_offset += 2;
			} else if (status->enc_flags & RX_ENC_FLAG_SHORTPRE) {
				ts += 96;
			} else {
				ts += 192;
			}
		}
		break;
		}
	}

	rate = cfg80211_calculate_bitrate(&ri);
	if (WARN_ONCE(!rate,
		      "Invalid bitrate: flags=0x%llx, idx=%d, vht_nss=%d\n",
		      (unsigned long long)status->flag, status->rate_idx,
		      status->nss))
		return 0;

	/* rewind from end of MPDU */
	if ((status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_END)
		ts -= mpdu_len * 8 * 10 / rate;

	ts += mpdu_offset * 8 * 10 / rate;

	return ts;
}

void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata;
	struct cfg80211_chan_def chandef;

	lockdep_assert_wiphy(local->hw.wiphy);

	list_for_each_entry(sdata, &local->interfaces, list) {
		/* it might be waiting for the local->mtx, but then
		 * by the time it gets it, sdata->wdev.cac_started
		 * will no longer be true
		 */
		wiphy_delayed_work_cancel(local->hw.wiphy,
					  &sdata->deflink.dfs_cac_timer_work);

		if (sdata->wdev.cac_started) {
			chandef = sdata->vif.bss_conf.chandef;
			ieee80211_link_release_channel(&sdata->deflink);
			cfg80211_cac_event(sdata->dev,
					   &chandef,
					   NL80211_RADAR_CAC_ABORTED,
					   GFP_KERNEL);
		}
	}
}

void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
				       struct wiphy_work *work)
{
	struct ieee80211_local *local =
		container_of(work, struct ieee80211_local, radar_detected_work);
	struct cfg80211_chan_def chandef = local->hw.conf.chandef;
	struct ieee80211_chanctx *ctx;
	int num_chanctx = 0;

	lockdep_assert_wiphy(local->hw.wiphy);

	list_for_each_entry(ctx, &local->chanctx_list, list) {
		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
			continue;

		num_chanctx++;
		chandef = ctx->conf.def;
	}

	ieee80211_dfs_cac_cancel(local);

	if (num_chanctx > 1)
		/* XXX: multi-channel is not supported yet */
		WARN_ON(1);
	else
		cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
}

void ieee80211_radar_detected(struct ieee80211_hw *hw)
{
	struct ieee80211_local *local = hw_to_local(hw);

	trace_api_radar_detected(local);

	wiphy_work_queue(hw->wiphy, &local->radar_detected_work);
}
EXPORT_SYMBOL(ieee80211_radar_detected);

ieee80211_conn_flags_t ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
{
	ieee80211_conn_flags_t ret;
	int tmp;

	switch (c->width) {
	case NL80211_CHAN_WIDTH_20:
		c->width = NL80211_CHAN_WIDTH_20_NOHT;
		ret = IEEE80211_CONN_DISABLE_HT | IEEE80211_CONN_DISABLE_VHT;
		break;
	case NL80211_CHAN_WIDTH_40:
		c->width = NL80211_CHAN_WIDTH_20;
		c->center_freq1 = c->chan->center_freq;
		ret = IEEE80211_CONN_DISABLE_40MHZ |
		      IEEE80211_CONN_DISABLE_VHT;
		break;
	case NL80211_CHAN_WIDTH_80:
		tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
		/* n_P40 */
		tmp /= 2;
		/* freq_P40 */
		c->center_freq1 = c->center_freq1 - 20 + 40 * tmp;
		c->width = NL80211_CHAN_WIDTH_40;
		ret = IEEE80211_CONN_DISABLE_VHT;
		break;
	case NL80211_CHAN_WIDTH_80P80:
		c->center_freq2 = 0;
		c->width = NL80211_CHAN_WIDTH_80;
		ret = IEEE80211_CONN_DISABLE_80P80MHZ |
		      IEEE80211_CONN_DISABLE_160MHZ;
		break;
	case NL80211_CHAN_WIDTH_160:
		/* n_P20 */
		tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
		/* n_P80 */
		tmp /= 4;
		c->center_freq1 = c->center_freq1 - 40 + 80 * tmp;
		c->width = NL80211_CHAN_WIDTH_80;
		ret = IEEE80211_CONN_DISABLE_80P80MHZ |
		      IEEE80211_CONN_DISABLE_160MHZ;
		break;
	case NL80211_CHAN_WIDTH_320:
		/* n_P20 */
		tmp = (150 + c->chan->center_freq - c->center_freq1) / 20;
		/* n_P160 */
		tmp /= 8;
		c->center_freq1 = c->center_freq1 - 80 + 160 * tmp;
		c->width = NL80211_CHAN_WIDTH_160;
		ret = IEEE80211_CONN_DISABLE_320MHZ;
		break;
	default:
	case NL80211_CHAN_WIDTH_20_NOHT:
		WARN_ON_ONCE(1);
		c->width = NL80211_CHAN_WIDTH_20_NOHT;
		ret = IEEE80211_CONN_DISABLE_HT | IEEE80211_CONN_DISABLE_VHT;
		break;
	case NL80211_CHAN_WIDTH_1:
	case NL80211_CHAN_WIDTH_2:
	case NL80211_CHAN_WIDTH_4:
	case NL80211_CHAN_WIDTH_8:
	case NL80211_CHAN_WIDTH_16:
	case NL80211_CHAN_WIDTH_5:
	case NL80211_CHAN_WIDTH_10:
		WARN_ON_ONCE(1);
		/* keep c->width */
		ret = IEEE80211_CONN_DISABLE_HT | IEEE80211_CONN_DISABLE_VHT;
		break;
	}

	WARN_ON_ONCE(!cfg80211_chandef_valid(c));

	return ret;
}

/*
 * Returns true if smps_mode_new is strictly more restrictive than
 * smps_mode_old.
 */
bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old,
				   enum ieee80211_smps_mode smps_mode_new)
{
	if (WARN_ON_ONCE(smps_mode_old == IEEE80211_SMPS_AUTOMATIC ||
			 smps_mode_new == IEEE80211_SMPS_AUTOMATIC))
		return false;

	switch (smps_mode_old) {
	case IEEE80211_SMPS_STATIC:
		return false;
	case IEEE80211_SMPS_DYNAMIC:
		return smps_mode_new == IEEE80211_SMPS_STATIC;
	case IEEE80211_SMPS_OFF:
		return smps_mode_new != IEEE80211_SMPS_OFF;
	default:
		WARN_ON(1);
	}

	return false;
}

int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
			      struct cfg80211_csa_settings *csa_settings)
{
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	struct ieee80211_local *local = sdata->local;
	int freq;
	int hdr_len = offsetofend(struct ieee80211_mgmt,
				  u.action.u.chan_switch);
	u8 *pos;

	if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
	    sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
		return -EOPNOTSUPP;

	skb = dev_alloc_skb(local->tx_headroom + hdr_len +
			    5 + /* channel switch announcement element */
			    3 + /* secondary channel offset element */
			    5 + /* wide bandwidth channel switch announcement */
			    8); /* mesh channel switch parameters element */
	if (!skb)
		return -ENOMEM;

	skb_reserve(skb, local->tx_headroom);
	mgmt = skb_put_zero(skb, hdr_len);
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);

	eth_broadcast_addr(mgmt->da);
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
	if (ieee80211_vif_is_mesh(&sdata->vif)) {
		memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
	} else {
		struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
		memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
	}
	mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
	mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
	pos = skb_put(skb, 5);
	*pos++ = WLAN_EID_CHANNEL_SWITCH;			/* EID */
	*pos++ = 3;						/* IE length */
	*pos++ = csa_settings->block_tx ? 1 : 0;		/* CSA mode */
	freq = csa_settings->chandef.chan->center_freq;
	*pos++ = ieee80211_frequency_to_channel(freq);		/* channel */
	*pos++ = csa_settings->count;				/* count */

	if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) {
		enum nl80211_channel_type ch_type;

		skb_put(skb, 3);
		*pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET;	/* EID */
		*pos++ = 1;					/* IE length */
		ch_type = cfg80211_get_chandef_type(&csa_settings->chandef);
		if (ch_type == NL80211_CHAN_HT40PLUS)
			*pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
		else
			*pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
	}

	if (ieee80211_vif_is_mesh(&sdata->vif)) {
		struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;

		skb_put(skb, 8);
		*pos++ = WLAN_EID_CHAN_SWITCH_PARAM;		/* EID */
		*pos++ = 6;					/* IE length */
		*pos++ = sdata->u.mesh.mshcfg.dot11MeshTTL;	/* Mesh TTL */
		*pos = 0x00;	/* Mesh Flag: Tx Restrict, Initiator, Reason */
		*pos |= WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
		*pos++ |= csa_settings->block_tx ?
			  WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
		put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
		pos += 2;
		put_unaligned_le16(ifmsh->pre_value, pos);/* Precedence Value */
		pos += 2;
	}

	if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_80 ||
	    csa_settings->chandef.width == NL80211_CHAN_WIDTH_80P80 ||
	    csa_settings->chandef.width == NL80211_CHAN_WIDTH_160) {
		skb_put(skb, 5);
		ieee80211_ie_build_wide_bw_cs(pos, &csa_settings->chandef);
	}

	ieee80211_tx_skb(sdata, skb);
	return 0;
}

static bool
ieee80211_extend_noa_desc(struct ieee80211_noa_data *data, u32 tsf, int i)
{
	s32 end = data->desc[i].start + data->desc[i].duration - (tsf + 1);
	int skip;

	if (end > 0)
		return false;

	/* One shot NOA  */
	if (data->count[i] == 1)
		return false;

	if (data->desc[i].interval == 0)
		return false;

	/* End time is in the past, check for repetitions */
	skip = DIV_ROUND_UP(-end, data->desc[i].interval);
	if (data->count[i] < 255) {
		if (data->count[i] <= skip) {
			data->count[i] = 0;
			return false;
		}

		data->count[i] -= skip;
	}

	data->desc[i].start += skip * data->desc[i].interval;

	return true;
}

static bool
ieee80211_extend_absent_time(struct ieee80211_noa_data *data, u32 tsf,
			     s32 *offset)
{
	bool ret = false;
	int i;

	for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) {
		s32 cur;

		if (!data->count[i])
			continue;

		if (ieee80211_extend_noa_desc(data, tsf + *offset, i))
			ret = true;

		cur = data->desc[i].start - tsf;
		if (cur > *offset)
			continue;

		cur = data->desc[i].start + data->desc[i].duration - tsf;
		if (cur > *offset)
			*offset = cur;
	}

	return ret;
}

static u32
ieee80211_get_noa_absent_time(struct ieee80211_noa_data *data, u32 tsf)
{
	s32 offset = 0;
	int tries = 0;
	/*
	 * arbitrary limit, used to avoid infinite loops when combined NoA
	 * descriptors cover the full time period.
	 */
	int max_tries = 5;

	ieee80211_extend_absent_time(data, tsf, &offset);
	do {
		if (!ieee80211_extend_absent_time(data, tsf, &offset))
			break;

		tries++;
	} while (tries < max_tries);

	return offset;
}

void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf)
{
	u32 next_offset = BIT(31) - 1;
	int i;

	data->absent = 0;
	data->has_next_tsf = false;
	for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) {
		s32 start;

		if (!data->count[i])
			continue;

		ieee80211_extend_noa_desc(data, tsf, i);
		start = data->desc[i].start - tsf;
		if (start <= 0)
			data->absent |= BIT(i);

		if (next_offset > start)
			next_offset = start;

		data->has_next_tsf = true;
	}

	if (data->absent)
		next_offset = ieee80211_get_noa_absent_time(data, tsf);

	data->next_tsf = tsf + next_offset;
}
EXPORT_SYMBOL(ieee80211_update_p2p_noa);

int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr,
			    struct ieee80211_noa_data *data, u32 tsf)
{
	int ret = 0;
	int i;

	memset(data, 0, sizeof(*data));

	for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) {
		const struct ieee80211_p2p_noa_desc *desc = &attr->desc[i];

		if (!desc->count || !desc->duration)
			continue;

		data->count[i] = desc->count;
		data->desc[i].start = le32_to_cpu(desc->start_time);
		data->desc[i].duration = le32_to_cpu(desc->duration);
		data->desc[i].interval = le32_to_cpu(desc->interval);

		if (data->count[i] > 1 &&
		    data->desc[i].interval < data->desc[i].duration)
			continue;

		ieee80211_extend_noa_desc(data, tsf, i);
		ret++;
	}

	if (ret)
		ieee80211_update_p2p_noa(data, tsf);

	return ret;
}
EXPORT_SYMBOL(ieee80211_parse_p2p_noa);

void ieee80211_recalc_dtim(struct ieee80211_local *local,
			   struct ieee80211_sub_if_data *sdata)
{
	u64 tsf = drv_get_tsf(local, sdata);
	u64 dtim_count = 0;
	u16 beacon_int = sdata->vif.bss_conf.beacon_int * 1024;
	u8 dtim_period = sdata->vif.bss_conf.dtim_period;
	struct ps_data *ps;
	u8 bcns_from_dtim;

	if (tsf == -1ULL || !beacon_int || !dtim_period)
		return;

	if (sdata->vif.type == NL80211_IFTYPE_AP ||
	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
		if (!sdata->bss)
			return;

		ps = &sdata->bss->ps;
	} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
		ps = &sdata->u.mesh.ps;
	} else {
		return;
	}

	/*
	 * actually finds last dtim_count, mac80211 will update in
	 * __beacon_add_tim().
	 * dtim_count = dtim_period - (tsf / bcn_int) % dtim_period
	 */
	do_div(tsf, beacon_int);
	bcns_from_dtim = do_div(tsf, dtim_period);
	/* just had a DTIM */
	if (!bcns_from_dtim)
		dtim_count = 0;
	else
		dtim_count = dtim_period - bcns_from_dtim;

	ps->dtim_count = dtim_count;
}

static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local,
					 struct ieee80211_chanctx *ctx)
{
	struct ieee80211_link_data *link;
	u8 radar_detect = 0;

	lockdep_assert_wiphy(local->hw.wiphy);

	if (WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED))
		return 0;

	list_for_each_entry(link, &ctx->reserved_links, reserved_chanctx_list)
		if (link->reserved_radar_required)
			radar_detect |= BIT(link->reserved_chandef.width);

	/*
	 * An in-place reservation context should not have any assigned vifs
	 * until it replaces the other context.
	 */
	WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER &&
		!list_empty(&ctx->assigned_links));

	list_for_each_entry(link, &ctx->assigned_links, assigned_chanctx_list) {
		if (!link->radar_required)
			continue;

		radar_detect |=
			BIT(link->conf->chandef.width);
	}

	return radar_detect;
}

int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
				 const struct cfg80211_chan_def *chandef,
				 enum ieee80211_chanctx_mode chanmode,
				 u8 radar_detect)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sub_if_data *sdata_iter;
	enum nl80211_iftype iftype = sdata->wdev.iftype;
	struct ieee80211_chanctx *ctx;
	int total = 1;
	struct iface_combination_params params = {
		.radar_detect = radar_detect,
	};

	lockdep_assert_wiphy(local->hw.wiphy);

	if (WARN_ON(hweight32(radar_detect) > 1))
		return -EINVAL;

	if (WARN_ON(chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
		    !chandef->chan))
		return -EINVAL;

	if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
		return -EINVAL;

	if (sdata->vif.type == NL80211_IFTYPE_AP ||
	    sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
		/*
		 * always passing this is harmless, since it'll be the
		 * same value that cfg80211 finds if it finds the same
		 * interface ... and that's always allowed
		 */
		params.new_beacon_int = sdata->vif.bss_conf.beacon_int;
	}

	/* Always allow software iftypes */
	if (cfg80211_iftype_allowed(local->hw.wiphy, iftype, 0, 1)) {
		if (radar_detect)
			return -EINVAL;
		return 0;
	}

	if (chandef)
		params.num_different_channels = 1;

	if (iftype != NL80211_IFTYPE_UNSPECIFIED)
		params.iftype_num[iftype] = 1;

	list_for_each_entry(ctx, &local->chanctx_list, list) {
		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
			continue;
		params.radar_detect |=
			ieee80211_chanctx_radar_detect(local, ctx);
		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
			params.num_different_channels++;
			continue;
		}
		if (chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
		    cfg80211_chandef_compatible(chandef,
						&ctx->conf.def))
			continue;
		params.num_different_channels++;
	}

	list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) {
		struct wireless_dev *wdev_iter;

		wdev_iter = &sdata_iter->wdev;

		if (sdata_iter == sdata ||
		    !ieee80211_sdata_running(sdata_iter) ||
		    cfg80211_iftype_allowed(local->hw.wiphy,
					    wdev_iter->iftype, 0, 1))
			continue;

		params.iftype_num[wdev_iter->iftype]++;
		total++;
	}

	if (total == 1 && !params.radar_detect)
		return 0;

	return cfg80211_check_combinations(local->hw.wiphy, &params);
}

static void
ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c,
			 void *data)
{
	u32 *max_num_different_channels = data;

	*max_num_different_channels = max(*max_num_different_channels,
					  c->num_different_channels);
}

int ieee80211_max_num_channels(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_chanctx *ctx;
	u32 max_num_different_channels = 1;
	int err;
	struct iface_combination_params params = {0};

	lockdep_assert_wiphy(local->hw.wiphy);

	list_for_each_entry(ctx, &local->chanctx_list, list) {
		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
			continue;

		params.num_different_channels++;

		params.radar_detect |=
			ieee80211_chanctx_radar_detect(local, ctx);
	}

	list_for_each_entry_rcu(sdata, &local->interfaces, list)
		params.iftype_num[sdata->wdev.iftype]++;

	err = cfg80211_iter_combinations(local->hw.wiphy, &params,
					 ieee80211_iter_max_chans,
					 &max_num_different_channels);
	if (err < 0)
		return err;

	return max_num_different_channels;
}

void ieee80211_add_s1g_capab_ie(struct ieee80211_sub_if_data *sdata,
				struct ieee80211_sta_s1g_cap *caps,
				struct sk_buff *skb)
{
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	struct ieee80211_s1g_cap s1g_capab;
	u8 *pos;
	int i;

	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
		return;

	if (!caps->s1g)
		return;

	memcpy(s1g_capab.capab_info, caps->cap, sizeof(caps->cap));
	memcpy(s1g_capab.supp_mcs_nss, caps->nss_mcs, sizeof(caps->nss_mcs));

	/* override the capability info */
	for (i = 0; i < sizeof(ifmgd->s1g_capa.capab_info); i++) {
		u8 mask = ifmgd->s1g_capa_mask.capab_info[i];

		s1g_capab.capab_info[i] &= ~mask;
		s1g_capab.capab_info[i] |= ifmgd->s1g_capa.capab_info[i] & mask;
	}

	/* then MCS and NSS set */
	for (i = 0; i < sizeof(ifmgd->s1g_capa.supp_mcs_nss); i++) {
		u8 mask = ifmgd->s1g_capa_mask.supp_mcs_nss[i];

		s1g_capab.supp_mcs_nss[i] &= ~mask;
		s1g_capab.supp_mcs_nss[i] |=
			ifmgd->s1g_capa.supp_mcs_nss[i] & mask;
	}

	pos = skb_put(skb, 2 + sizeof(s1g_capab));
	*pos++ = WLAN_EID_S1G_CAPABILITIES;
	*pos++ = sizeof(s1g_capab);

	memcpy(pos, &s1g_capab, sizeof(s1g_capab));
}

void ieee80211_add_aid_request_ie(struct ieee80211_sub_if_data *sdata,
				  struct sk_buff *skb)
{
	u8 *pos = skb_put(skb, 3);

	*pos++ = WLAN_EID_AID_REQUEST;
	*pos++ = 1;
	*pos++ = 0;
}

u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo)
{
	*buf++ = WLAN_EID_VENDOR_SPECIFIC;
	*buf++ = 7; /* len */
	*buf++ = 0x00; /* Microsoft OUI 00:50:F2 */
	*buf++ = 0x50;
	*buf++ = 0xf2;
	*buf++ = 2; /* WME */
	*buf++ = 0; /* WME info */
	*buf++ = 1; /* WME ver */
	*buf++ = qosinfo; /* U-APSD no in use */

	return buf;
}

void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
			     unsigned long *frame_cnt,
			     unsigned long *byte_cnt)
{
	struct txq_info *txqi = to_txq_info(txq);
	u32 frag_cnt = 0, frag_bytes = 0;
	struct sk_buff *skb;

	skb_queue_walk(&txqi->frags, skb) {
		frag_cnt++;
		frag_bytes += skb->len;
	}

	if (frame_cnt)
		*frame_cnt = txqi->tin.backlog_packets + frag_cnt;

	if (byte_cnt)
		*byte_cnt = txqi->tin.backlog_bytes + frag_bytes;
}
EXPORT_SYMBOL(ieee80211_txq_get_depth);

const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS] = {
	IEEE80211_WMM_IE_STA_QOSINFO_AC_VO,
	IEEE80211_WMM_IE_STA_QOSINFO_AC_VI,
	IEEE80211_WMM_IE_STA_QOSINFO_AC_BE,
	IEEE80211_WMM_IE_STA_QOSINFO_AC_BK
};

u16 ieee80211_encode_usf(int listen_interval)
{
	static const int listen_int_usf[] = { 1, 10, 1000, 10000 };
	u16 ui, usf = 0;

	/* find greatest USF */
	while (usf < IEEE80211_MAX_USF) {
		if (listen_interval % listen_int_usf[usf + 1])
			break;
		usf += 1;
	}
	ui = listen_interval / listen_int_usf[usf];

	/* error if there is a remainder. Should've been checked by user */
	WARN_ON_ONCE(ui > IEEE80211_MAX_UI);
	listen_interval = FIELD_PREP(LISTEN_INT_USF, usf) |
			  FIELD_PREP(LISTEN_INT_UI, ui);

	return (u16) listen_interval;
}

u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata, u8 iftype)
{
	const struct ieee80211_sta_he_cap *he_cap;
	const struct ieee80211_sta_eht_cap *eht_cap;
	struct ieee80211_supported_band *sband;
	bool is_ap;
	u8 n;

	sband = ieee80211_get_sband(sdata);
	if (!sband)
		return 0;

	he_cap = ieee80211_get_he_iftype_cap(sband, iftype);
	eht_cap = ieee80211_get_eht_iftype_cap(sband, iftype);
	if (!he_cap || !eht_cap)
		return 0;

	is_ap = iftype == NL80211_IFTYPE_AP ||
		iftype == NL80211_IFTYPE_P2P_GO;

	n = ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem,
				       &eht_cap->eht_cap_elem,
				       is_ap);
	return 2 + 1 +
	       sizeof(eht_cap->eht_cap_elem) + n +
	       ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0],
				      eht_cap->eht_cap_elem.phy_cap_info);
	return 0;
}

u8 *ieee80211_ie_build_eht_cap(u8 *pos,
			       const struct ieee80211_sta_he_cap *he_cap,
			       const struct ieee80211_sta_eht_cap *eht_cap,
			       u8 *end,
			       bool for_ap)
{
	u8 mcs_nss_len, ppet_len;
	u8 ie_len;
	u8 *orig_pos = pos;

	/* Make sure we have place for the IE */
	if (!he_cap || !eht_cap)
		return orig_pos;

	mcs_nss_len = ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem,
						 &eht_cap->eht_cap_elem,
						 for_ap);
	ppet_len = ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0],
					  eht_cap->eht_cap_elem.phy_cap_info);

	ie_len = 2 + 1 + sizeof(eht_cap->eht_cap_elem) + mcs_nss_len + ppet_len;
	if ((end - pos) < ie_len)
		return orig_pos;

	*pos++ = WLAN_EID_EXTENSION;
	*pos++ = ie_len - 2;
	*pos++ = WLAN_EID_EXT_EHT_CAPABILITY;

	/* Fixed data */
	memcpy(pos, &eht_cap->eht_cap_elem, sizeof(eht_cap->eht_cap_elem));
	pos += sizeof(eht_cap->eht_cap_elem);

	memcpy(pos, &eht_cap->eht_mcs_nss_supp, mcs_nss_len);
	pos += mcs_nss_len;

	if (ppet_len) {
		memcpy(pos, &eht_cap->eht_ppe_thres, ppet_len);
		pos += ppet_len;
	}

	return pos;
}
