// SPDX-License-Identifier: GPL-2.0-only
/*
 * Interface handling
 *
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005-2006, Devicescape Software, Inc.
 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 * Copyright (c) 2016        Intel Deutschland GmbH
 * Copyright (C) 2018-2023 Intel Corporation
 */
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/kcov.h>
#include <net/mac80211.h>
#include <net/ieee80211_radiotap.h>
#include "ieee80211_i.h"
#include "sta_info.h"
#include "debugfs_netdev.h"
#include "mesh.h"
#include "led.h"
#include "driver-ops.h"
#include "wme.h"
#include "rate.h"

/**
 * DOC: Interface list locking
 *
 * The interface list in each struct ieee80211_local is protected
 * three-fold:
 *
 * (1) modifications may only be done under the RTNL *and* wiphy mutex
 *     *and* iflist_mtx
 * (2) modifications are done in an RCU manner so atomic readers
 *     can traverse the list in RCU-safe blocks.
 *
 * As a consequence, reads (traversals) of the list can be protected
 * by either the RTNL, the wiphy mutex, the iflist_mtx or RCU.
 */

static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work);

bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_chanctx_conf *chanctx_conf;
	int power;

	rcu_read_lock();
	chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
	if (!chanctx_conf) {
		rcu_read_unlock();
		return false;
	}

	power = ieee80211_chandef_max_power(&chanctx_conf->def);
	rcu_read_unlock();

	if (sdata->deflink.user_power_level != IEEE80211_UNSET_POWER_LEVEL)
		power = min(power, sdata->deflink.user_power_level);

	if (sdata->deflink.ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
		power = min(power, sdata->deflink.ap_power_level);

	if (power != sdata->vif.bss_conf.txpower) {
		sdata->vif.bss_conf.txpower = power;
		ieee80211_hw_config(sdata->local, 0);
		return true;
	}

	return false;
}

void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
			      bool update_bss)
{
	if (__ieee80211_recalc_txpower(sdata) ||
	    (update_bss && ieee80211_sdata_running(sdata)))
		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
						  BSS_CHANGED_TXPOWER);
}

static u32 __ieee80211_idle_off(struct ieee80211_local *local)
{
	if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
		return 0;

	local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
	return IEEE80211_CONF_CHANGE_IDLE;
}

static u32 __ieee80211_idle_on(struct ieee80211_local *local)
{
	if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
		return 0;

	ieee80211_flush_queues(local, NULL, false);

	local->hw.conf.flags |= IEEE80211_CONF_IDLE;
	return IEEE80211_CONF_CHANGE_IDLE;
}

static u32 __ieee80211_recalc_idle(struct ieee80211_local *local,
				   bool force_active)
{
	bool working, scanning, active;
	unsigned int led_trig_start = 0, led_trig_stop = 0;

	lockdep_assert_wiphy(local->hw.wiphy);

	active = force_active ||
		 !list_empty(&local->chanctx_list) ||
		 local->monitors;

	working = !local->ops->remain_on_channel &&
		  !list_empty(&local->roc_list);

	scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
		   test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);

	if (working || scanning)
		led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
	else
		led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;

	if (active)
		led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
	else
		led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;

	ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);

	if (working || scanning || active)
		return __ieee80211_idle_off(local);
	return __ieee80211_idle_on(local);
}

u32 ieee80211_idle_off(struct ieee80211_local *local)
{
	return __ieee80211_recalc_idle(local, true);
}

void ieee80211_recalc_idle(struct ieee80211_local *local)
{
	u32 change = __ieee80211_recalc_idle(local, false);
	if (change)
		ieee80211_hw_config(local, change);
}

static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
				bool check_dup)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sub_if_data *iter;
	u64 new, mask, tmp;
	u8 *m;
	int ret = 0;

	lockdep_assert_wiphy(local->hw.wiphy);

	if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
		return 0;

	m = addr;
	new =	((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
		((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
		((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);

	m = local->hw.wiphy->addr_mask;
	mask =	((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
		((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
		((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);

	if (!check_dup)
		return ret;

	list_for_each_entry(iter, &local->interfaces, list) {
		if (iter == sdata)
			continue;

		if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
		    !(iter->u.mntr.flags & MONITOR_FLAG_ACTIVE))
			continue;

		m = iter->vif.addr;
		tmp =	((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
			((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
			((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);

		if ((new & ~mask) != (tmp & ~mask)) {
			ret = -EINVAL;
			break;
		}
	}

	return ret;
}

static int ieee80211_can_powered_addr_change(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_roc_work *roc;
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sub_if_data *scan_sdata;
	int ret = 0;

	lockdep_assert_wiphy(local->hw.wiphy);

	/* To be the most flexible here we want to only limit changing the
	 * address if the specific interface is doing offchannel work or
	 * scanning.
	 */
	if (netif_carrier_ok(sdata->dev))
		return -EBUSY;

	/* First check no ROC work is happening on this iface */
	list_for_each_entry(roc, &local->roc_list, list) {
		if (roc->sdata != sdata)
			continue;

		if (roc->started) {
			ret = -EBUSY;
			goto unlock;
		}
	}

	/* And if this iface is scanning */
	if (local->scanning) {
		scan_sdata = rcu_dereference_protected(local->scan_sdata,
						       lockdep_is_held(&local->hw.wiphy->mtx));
		if (sdata == scan_sdata)
			ret = -EBUSY;
	}

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_P2P_CLIENT:
		/* More interface types could be added here but changing the
		 * address while powered makes the most sense in client modes.
		 */
		break;
	default:
		ret = -EOPNOTSUPP;
	}

unlock:
	return ret;
}

static int _ieee80211_change_mac(struct ieee80211_sub_if_data *sdata,
				 void *addr)
{
	struct ieee80211_local *local = sdata->local;
	struct sockaddr *sa = addr;
	bool check_dup = true;
	bool live = false;
	int ret;

	if (ieee80211_sdata_running(sdata)) {
		ret = ieee80211_can_powered_addr_change(sdata);
		if (ret)
			return ret;

		live = true;
	}

	if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
	    !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
		check_dup = false;

	ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
	if (ret)
		return ret;

	if (live)
		drv_remove_interface(local, sdata);
	ret = eth_mac_addr(sdata->dev, sa);

	if (ret == 0) {
		memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
		ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
	}

	/* Regardless of eth_mac_addr() return we still want to add the
	 * interface back. This should not fail...
	 */
	if (live)
		WARN_ON(drv_add_interface(local, sdata));

	return ret;
}

static int ieee80211_change_mac(struct net_device *dev, void *addr)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_local *local = sdata->local;
	int ret;

	/*
	 * This happens during unregistration if there's a bond device
	 * active (maybe other cases?) and we must get removed from it.
	 * But we really don't care anymore if it's not registered now.
	 */
	if (!dev->ieee80211_ptr->registered)
		return 0;

	wiphy_lock(local->hw.wiphy);
	ret = _ieee80211_change_mac(sdata, addr);
	wiphy_unlock(local->hw.wiphy);

	return ret;
}

static inline int identical_mac_addr_allowed(int type1, int type2)
{
	return type1 == NL80211_IFTYPE_MONITOR ||
		type2 == NL80211_IFTYPE_MONITOR ||
		type1 == NL80211_IFTYPE_P2P_DEVICE ||
		type2 == NL80211_IFTYPE_P2P_DEVICE ||
		(type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_AP_VLAN) ||
		(type1 == NL80211_IFTYPE_AP_VLAN &&
			(type2 == NL80211_IFTYPE_AP ||
			 type2 == NL80211_IFTYPE_AP_VLAN));
}

static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
					    enum nl80211_iftype iftype)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sub_if_data *nsdata;

	ASSERT_RTNL();
	lockdep_assert_wiphy(local->hw.wiphy);

	/* we hold the RTNL here so can safely walk the list */
	list_for_each_entry(nsdata, &local->interfaces, list) {
		if (nsdata != sdata && ieee80211_sdata_running(nsdata)) {
			/*
			 * Only OCB and monitor mode may coexist
			 */
			if ((sdata->vif.type == NL80211_IFTYPE_OCB &&
			     nsdata->vif.type != NL80211_IFTYPE_MONITOR) ||
			    (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
			     nsdata->vif.type == NL80211_IFTYPE_OCB))
				return -EBUSY;

			/*
			 * Allow only a single IBSS interface to be up at any
			 * time. This is restricted because beacon distribution
			 * cannot work properly if both are in the same IBSS.
			 *
			 * To remove this restriction we'd have to disallow them
			 * from setting the same SSID on different IBSS interfaces
			 * belonging to the same hardware. Then, however, we're
			 * faced with having to adopt two different TSF timers...
			 */
			if (iftype == NL80211_IFTYPE_ADHOC &&
			    nsdata->vif.type == NL80211_IFTYPE_ADHOC)
				return -EBUSY;
			/*
			 * will not add another interface while any channel
			 * switch is active.
			 */
			if (nsdata->vif.bss_conf.csa_active)
				return -EBUSY;

			/*
			 * The remaining checks are only performed for interfaces
			 * with the same MAC address.
			 */
			if (!ether_addr_equal(sdata->vif.addr,
					      nsdata->vif.addr))
				continue;

			/*
			 * check whether it may have the same address
			 */
			if (!identical_mac_addr_allowed(iftype,
							nsdata->vif.type))
				return -ENOTUNIQ;

			/* No support for VLAN with MLO yet */
			if (iftype == NL80211_IFTYPE_AP_VLAN &&
			    sdata->wdev.use_4addr &&
			    nsdata->vif.type == NL80211_IFTYPE_AP &&
			    nsdata->vif.valid_links)
				return -EOPNOTSUPP;

			/*
			 * can only add VLANs to enabled APs
			 */
			if (iftype == NL80211_IFTYPE_AP_VLAN &&
			    nsdata->vif.type == NL80211_IFTYPE_AP)
				sdata->bss = &nsdata->u.ap;
		}
	}

	return ieee80211_check_combinations(sdata, NULL, 0, 0);
}

static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata,
				  enum nl80211_iftype iftype)
{
	int n_queues = sdata->local->hw.queues;
	int i;

	if (iftype == NL80211_IFTYPE_NAN)
		return 0;

	if (iftype != NL80211_IFTYPE_P2P_DEVICE) {
		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
			if (WARN_ON_ONCE(sdata->vif.hw_queue[i] ==
					 IEEE80211_INVAL_HW_QUEUE))
				return -EINVAL;
			if (WARN_ON_ONCE(sdata->vif.hw_queue[i] >=
					 n_queues))
				return -EINVAL;
		}
	}

	if ((iftype != NL80211_IFTYPE_AP &&
	     iftype != NL80211_IFTYPE_P2P_GO &&
	     iftype != NL80211_IFTYPE_MESH_POINT) ||
	    !ieee80211_hw_check(&sdata->local->hw, QUEUE_CONTROL)) {
		sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
		return 0;
	}

	if (WARN_ON_ONCE(sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE))
		return -EINVAL;

	if (WARN_ON_ONCE(sdata->vif.cab_queue >= n_queues))
		return -EINVAL;

	return 0;
}

static int ieee80211_open(struct net_device *dev)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	int err;

	/* fail early if user set an invalid address */
	if (!is_valid_ether_addr(dev->dev_addr))
		return -EADDRNOTAVAIL;

	wiphy_lock(sdata->local->hw.wiphy);
	err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type);
	if (err)
		goto out;

	err = ieee80211_do_open(&sdata->wdev, true);
out:
	wiphy_unlock(sdata->local->hw.wiphy);

	return err;
}

static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_down)
{
	struct ieee80211_local *local = sdata->local;
	unsigned long flags;
	struct sk_buff *skb, *tmp;
	u32 hw_reconf_flags = 0;
	int i, flushed;
	struct ps_data *ps;
	struct cfg80211_chan_def chandef;
	bool cancel_scan;
	struct cfg80211_nan_func *func;

	lockdep_assert_wiphy(local->hw.wiphy);

	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
	synchronize_rcu(); /* flush _ieee80211_wake_txqs() */

	cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata;
	if (cancel_scan)
		ieee80211_scan_cancel(local);

	ieee80211_roc_purge(local, sdata);

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_STATION:
		ieee80211_mgd_stop(sdata);
		break;
	case NL80211_IFTYPE_ADHOC:
		ieee80211_ibss_stop(sdata);
		break;
	case NL80211_IFTYPE_MONITOR:
		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
			break;
		list_del_rcu(&sdata->u.mntr.list);
		break;
	default:
		break;
	}

	/*
	 * Remove all stations associated with this interface.
	 *
	 * This must be done before calling ops->remove_interface()
	 * because otherwise we can later invoke ops->sta_notify()
	 * whenever the STAs are removed, and that invalidates driver
	 * assumptions about always getting a vif pointer that is valid
	 * (because if we remove a STA after ops->remove_interface()
	 * the driver will have removed the vif info already!)
	 *
	 * For AP_VLANs stations may exist since there's nothing else that
	 * would have removed them, but in other modes there shouldn't
	 * be any stations.
	 */
	flushed = sta_info_flush(sdata);
	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN && flushed > 0);

	/* don't count this interface for allmulti while it is down */
	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
		atomic_dec(&local->iff_allmultis);

	if (sdata->vif.type == NL80211_IFTYPE_AP) {
		local->fif_pspoll--;
		local->fif_probe_req--;
	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
		local->fif_probe_req--;
	}

	if (sdata->dev) {
		netif_addr_lock_bh(sdata->dev);
		spin_lock_bh(&local->filter_lock);
		__hw_addr_unsync(&local->mc_list, &sdata->dev->mc,
				 sdata->dev->addr_len);
		spin_unlock_bh(&local->filter_lock);
		netif_addr_unlock_bh(sdata->dev);
	}

	del_timer_sync(&local->dynamic_ps_timer);
	wiphy_work_cancel(local->hw.wiphy, &local->dynamic_ps_enable_work);

	WARN(ieee80211_vif_is_mld(&sdata->vif),
	     "destroying interface with valid links 0x%04x\n",
	     sdata->vif.valid_links);

	sdata->vif.bss_conf.csa_active = false;
	if (sdata->vif.type == NL80211_IFTYPE_STATION)
		sdata->deflink.u.mgd.csa_waiting_bcn = false;
	if (sdata->deflink.csa_block_tx) {
		ieee80211_wake_vif_queues(local, sdata,
					  IEEE80211_QUEUE_STOP_REASON_CSA);
		sdata->deflink.csa_block_tx = false;
	}

	wiphy_work_cancel(local->hw.wiphy, &sdata->deflink.csa_finalize_work);
	wiphy_work_cancel(local->hw.wiphy,
			  &sdata->deflink.color_change_finalize_work);
	wiphy_delayed_work_cancel(local->hw.wiphy,
				  &sdata->deflink.dfs_cac_timer_work);

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

	if (sdata->vif.type == NL80211_IFTYPE_AP) {
		WARN_ON(!list_empty(&sdata->u.ap.vlans));
	} else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
		/* remove all packets in parent bc_buf pointing to this dev */
		ps = &sdata->bss->ps;

		spin_lock_irqsave(&ps->bc_buf.lock, flags);
		skb_queue_walk_safe(&ps->bc_buf, skb, tmp) {
			if (skb->dev == sdata->dev) {
				__skb_unlink(skb, &ps->bc_buf);
				local->total_ps_buffered--;
				ieee80211_free_txskb(&local->hw, skb);
			}
		}
		spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
	}

	if (going_down)
		local->open_count--;

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP_VLAN:
		list_del(&sdata->u.vlan.list);
		RCU_INIT_POINTER(sdata->vif.bss_conf.chanctx_conf, NULL);
		/* see comment in the default case below */
		ieee80211_free_keys(sdata, true);
		/* no need to tell driver */
		break;
	case NL80211_IFTYPE_MONITOR:
		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
			local->cooked_mntrs--;
			break;
		}

		local->monitors--;
		if (local->monitors == 0) {
			local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
			hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
		}

		ieee80211_adjust_monitor_flags(sdata, -1);
		break;
	case NL80211_IFTYPE_NAN:
		/* clean all the functions */
		spin_lock_bh(&sdata->u.nan.func_lock);

		idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) {
			idr_remove(&sdata->u.nan.function_inst_ids, i);
			cfg80211_free_nan_func(func);
		}
		idr_destroy(&sdata->u.nan.function_inst_ids);

		spin_unlock_bh(&sdata->u.nan.func_lock);
		break;
	case NL80211_IFTYPE_P2P_DEVICE:
		/* relies on synchronize_rcu() below */
		RCU_INIT_POINTER(local->p2p_sdata, NULL);
		fallthrough;
	default:
		wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->work);
		/*
		 * When we get here, the interface is marked down.
		 * Free the remaining keys, if there are any
		 * (which can happen in AP mode if userspace sets
		 * keys before the interface is operating)
		 *
		 * Force the key freeing to always synchronize_net()
		 * to wait for the RX path in case it is using this
		 * interface enqueuing frames at this very time on
		 * another CPU.
		 */
		ieee80211_free_keys(sdata, true);
		skb_queue_purge(&sdata->skb_queue);
		skb_queue_purge(&sdata->status_queue);
	}

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
		skb_queue_walk_safe(&local->pending[i], skb, tmp) {
			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
			if (info->control.vif == &sdata->vif) {
				__skb_unlink(skb, &local->pending[i]);
				ieee80211_free_txskb(&local->hw, skb);
			}
		}
	}
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);

	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
		ieee80211_txq_remove_vlan(local, sdata);

	sdata->bss = NULL;

	if (local->open_count == 0)
		ieee80211_clear_tx_pending(local);

	sdata->vif.bss_conf.beacon_int = 0;

	/*
	 * If the interface goes down while suspended, presumably because
	 * the device was unplugged and that happens before our resume,
	 * then the driver is already unconfigured and the remainder of
	 * this function isn't needed.
	 * XXX: what about WoWLAN? If the device has software state, e.g.
	 *	memory allocated, it might expect teardown commands from
	 *	mac80211 here?
	 */
	if (local->suspended) {
		WARN_ON(local->wowlan);
		WARN_ON(rcu_access_pointer(local->monitor_sdata));
		return;
	}

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP_VLAN:
		break;
	case NL80211_IFTYPE_MONITOR:
		if (local->monitors == 0)
			ieee80211_del_virtual_monitor(local);

		ieee80211_recalc_idle(local);

		if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
			break;

		fallthrough;
	default:
		if (going_down)
			drv_remove_interface(local, sdata);
	}

	ieee80211_recalc_ps(local);

	if (cancel_scan)
		wiphy_delayed_work_flush(local->hw.wiphy, &local->scan_work);

	if (local->open_count == 0) {
		ieee80211_stop_device(local);

		/* no reconfiguring after stop! */
		return;
	}

	/* do after stop to avoid reconfiguring when we stop anyway */
	ieee80211_configure_filter(local);
	ieee80211_hw_config(local, hw_reconf_flags);

	if (local->monitors == local->open_count)
		ieee80211_add_virtual_monitor(local);
}

static void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_sub_if_data *tx_sdata, *non_tx_sdata, *tmp_sdata;
	struct ieee80211_vif *tx_vif = sdata->vif.mbssid_tx_vif;

	if (!tx_vif)
		return;

	tx_sdata = vif_to_sdata(tx_vif);
	sdata->vif.mbssid_tx_vif = NULL;

	list_for_each_entry_safe(non_tx_sdata, tmp_sdata,
				 &tx_sdata->local->interfaces, list) {
		if (non_tx_sdata != sdata && non_tx_sdata != tx_sdata &&
		    non_tx_sdata->vif.mbssid_tx_vif == tx_vif &&
		    ieee80211_sdata_running(non_tx_sdata)) {
			non_tx_sdata->vif.mbssid_tx_vif = NULL;
			dev_close(non_tx_sdata->wdev.netdev);
		}
	}

	if (sdata != tx_sdata && ieee80211_sdata_running(tx_sdata)) {
		tx_sdata->vif.mbssid_tx_vif = NULL;
		dev_close(tx_sdata->wdev.netdev);
	}
}

static int ieee80211_stop(struct net_device *dev)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

	/* close dependent VLAN and MBSSID interfaces before locking wiphy */
	if (sdata->vif.type == NL80211_IFTYPE_AP) {
		struct ieee80211_sub_if_data *vlan, *tmpsdata;

		list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
					 u.vlan.list)
			dev_close(vlan->dev);

		ieee80211_stop_mbssid(sdata);
	}

	wiphy_lock(sdata->local->hw.wiphy);
	wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->activate_links_work);

	ieee80211_do_stop(sdata, true);
	wiphy_unlock(sdata->local->hw.wiphy);

	return 0;
}

static void ieee80211_set_multicast_list(struct net_device *dev)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_local *local = sdata->local;
	int allmulti, sdata_allmulti;

	allmulti = !!(dev->flags & IFF_ALLMULTI);
	sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI);

	if (allmulti != sdata_allmulti) {
		if (dev->flags & IFF_ALLMULTI)
			atomic_inc(&local->iff_allmultis);
		else
			atomic_dec(&local->iff_allmultis);
		sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
	}

	spin_lock_bh(&local->filter_lock);
	__hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
	spin_unlock_bh(&local->filter_lock);
	wiphy_work_queue(local->hw.wiphy, &local->reconfig_filter);
}

/*
 * Called when the netdev is removed or, by the code below, before
 * the interface type changes.
 */
static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
{
	/* free extra data */
	ieee80211_free_keys(sdata, false);

	ieee80211_debugfs_remove_netdev(sdata);

	ieee80211_destroy_frag_cache(&sdata->frags);

	if (ieee80211_vif_is_mesh(&sdata->vif))
		ieee80211_mesh_teardown_sdata(sdata);

	ieee80211_vif_clear_links(sdata);
	ieee80211_link_stop(&sdata->deflink);
}

static void ieee80211_uninit(struct net_device *dev)
{
	ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
}

static void
ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
	dev_fetch_sw_netstats(stats, dev->tstats);
}

static int ieee80211_netdev_setup_tc(struct net_device *dev,
				     enum tc_setup_type type, void *type_data)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_local *local = sdata->local;

	return drv_net_setup_tc(local, sdata, dev, type, type_data);
}

static const struct net_device_ops ieee80211_dataif_ops = {
	.ndo_open		= ieee80211_open,
	.ndo_stop		= ieee80211_stop,
	.ndo_uninit		= ieee80211_uninit,
	.ndo_start_xmit		= ieee80211_subif_start_xmit,
	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
	.ndo_set_mac_address 	= ieee80211_change_mac,
	.ndo_get_stats64	= ieee80211_get_stats64,
	.ndo_setup_tc		= ieee80211_netdev_setup_tc,
};

static u16 ieee80211_monitor_select_queue(struct net_device *dev,
					  struct sk_buff *skb,
					  struct net_device *sb_dev)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ieee80211_hdr *hdr;
	int len_rthdr;

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

	/* reset flags and info before parsing radiotap header */
	memset(info, 0, sizeof(*info));

	if (!ieee80211_parse_tx_radiotap(skb, dev))
		return 0; /* doesn't matter, frame will be dropped */

	len_rthdr = ieee80211_get_radiotap_len(skb->data);
	hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
	if (skb->len < len_rthdr + 2 ||
	    skb->len < len_rthdr + ieee80211_hdrlen(hdr->frame_control))
		return 0; /* doesn't matter, frame will be dropped */

	return ieee80211_select_queue_80211(sdata, skb, hdr);
}

static const struct net_device_ops ieee80211_monitorif_ops = {
	.ndo_open		= ieee80211_open,
	.ndo_stop		= ieee80211_stop,
	.ndo_uninit		= ieee80211_uninit,
	.ndo_start_xmit		= ieee80211_monitor_start_xmit,
	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
	.ndo_set_mac_address 	= ieee80211_change_mac,
	.ndo_select_queue	= ieee80211_monitor_select_queue,
	.ndo_get_stats64	= ieee80211_get_stats64,
};

static int ieee80211_netdev_fill_forward_path(struct net_device_path_ctx *ctx,
					      struct net_device_path *path)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_local *local;
	struct sta_info *sta;
	int ret = -ENOENT;

	sdata = IEEE80211_DEV_TO_SUB_IF(ctx->dev);
	local = sdata->local;

	if (!local->ops->net_fill_forward_path)
		return -EOPNOTSUPP;

	rcu_read_lock();
	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP_VLAN:
		sta = rcu_dereference(sdata->u.vlan.sta);
		if (sta)
			break;
		if (sdata->wdev.use_4addr)
			goto out;
		if (is_multicast_ether_addr(ctx->daddr))
			goto out;
		sta = sta_info_get_bss(sdata, ctx->daddr);
		break;
	case NL80211_IFTYPE_AP:
		if (is_multicast_ether_addr(ctx->daddr))
			goto out;
		sta = sta_info_get(sdata, ctx->daddr);
		break;
	case NL80211_IFTYPE_STATION:
		if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
			sta = sta_info_get(sdata, ctx->daddr);
			if (sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
				if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
					goto out;

				break;
			}
		}

		sta = sta_info_get(sdata, sdata->deflink.u.mgd.bssid);
		break;
	default:
		goto out;
	}

	if (!sta)
		goto out;

	ret = drv_net_fill_forward_path(local, sdata, &sta->sta, ctx, path);
out:
	rcu_read_unlock();

	return ret;
}

static const struct net_device_ops ieee80211_dataif_8023_ops = {
	.ndo_open		= ieee80211_open,
	.ndo_stop		= ieee80211_stop,
	.ndo_uninit		= ieee80211_uninit,
	.ndo_start_xmit		= ieee80211_subif_start_xmit_8023,
	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
	.ndo_set_mac_address	= ieee80211_change_mac,
	.ndo_get_stats64	= ieee80211_get_stats64,
	.ndo_fill_forward_path	= ieee80211_netdev_fill_forward_path,
	.ndo_setup_tc		= ieee80211_netdev_setup_tc,
};

static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype)
{
	switch (iftype) {
	/* P2P GO and client are mapped to AP/STATION types */
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_STATION:
		return true;
	default:
		return false;
	}
}

static bool ieee80211_set_sdata_offload_flags(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	u32 flags;

	flags = sdata->vif.offload_flags;

	if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) &&
	    ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
		flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED;

		if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
		    local->hw.wiphy->frag_threshold != (u32)-1)
			flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;

		if (local->monitors)
			flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
	} else {
		flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
	}

	if (ieee80211_hw_check(&local->hw, SUPPORTS_RX_DECAP_OFFLOAD) &&
	    ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
		flags |= IEEE80211_OFFLOAD_DECAP_ENABLED;

		if (local->monitors &&
		    !ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP))
			flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
	} else {
		flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
	}

	if (sdata->vif.offload_flags == flags)
		return false;

	sdata->vif.offload_flags = flags;
	ieee80211_check_fast_rx_iface(sdata);
	return true;
}

static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sub_if_data *bss = sdata;
	bool enabled;

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

		bss = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
	}

	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
	    !ieee80211_iftype_supports_hdr_offload(bss->vif.type))
		return;

	enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
	if (sdata->wdev.use_4addr &&
	    !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR))
		enabled = false;

	sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops :
					   &ieee80211_dataif_ops;
}

static void ieee80211_recalc_sdata_offload(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sub_if_data *vsdata;

	if (ieee80211_set_sdata_offload_flags(sdata)) {
		drv_update_vif_offload(local, sdata);
		ieee80211_set_vif_encap_ops(sdata);
	}

	list_for_each_entry(vsdata, &local->interfaces, list) {
		if (vsdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
		    vsdata->bss != &sdata->u.ap)
			continue;

		ieee80211_set_vif_encap_ops(vsdata);
	}
}

void ieee80211_recalc_offload(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata;

	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD))
		return;

	lockdep_assert_wiphy(local->hw.wiphy);

	list_for_each_entry(sdata, &local->interfaces, list) {
		if (!ieee80211_sdata_running(sdata))
			continue;

		ieee80211_recalc_sdata_offload(sdata);
	}
}

void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
				    const int offset)
{
	struct ieee80211_local *local = sdata->local;
	u32 flags = sdata->u.mntr.flags;

#define ADJUST(_f, _s)	do {					\
	if (flags & MONITOR_FLAG_##_f)				\
		local->fif_##_s += offset;			\
	} while (0)

	ADJUST(FCSFAIL, fcsfail);
	ADJUST(PLCPFAIL, plcpfail);
	ADJUST(CONTROL, control);
	ADJUST(CONTROL, pspoll);
	ADJUST(OTHER_BSS, other_bss);

#undef ADJUST
}

static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	int i;

	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
		if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
			sdata->vif.hw_queue[i] = IEEE80211_INVAL_HW_QUEUE;
		else if (local->hw.queues >= IEEE80211_NUM_ACS)
			sdata->vif.hw_queue[i] = i;
		else
			sdata->vif.hw_queue[i] = 0;
	}
	sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
}

static void ieee80211_sdata_init(struct ieee80211_local *local,
				 struct ieee80211_sub_if_data *sdata)
{
	sdata->local = local;

	/*
	 * Initialize the default link, so we can use link_id 0 for non-MLD,
	 * and that continues to work for non-MLD-aware drivers that use just
	 * vif.bss_conf instead of vif.link_conf.
	 *
	 * Note that we never change this, so if link ID 0 isn't used in an
	 * MLD connection, we get a separate allocation for it.
	 */
	ieee80211_link_init(sdata, -1, &sdata->deflink, &sdata->vif.bss_conf);
}

int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata;
	int ret;

	if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
		return 0;

	ASSERT_RTNL();
	lockdep_assert_wiphy(local->hw.wiphy);

	if (local->monitor_sdata)
		return 0;

	sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL);
	if (!sdata)
		return -ENOMEM;

	/* set up data */
	sdata->vif.type = NL80211_IFTYPE_MONITOR;
	snprintf(sdata->name, IFNAMSIZ, "%s-monitor",
		 wiphy_name(local->hw.wiphy));
	sdata->wdev.iftype = NL80211_IFTYPE_MONITOR;
	sdata->wdev.wiphy = local->hw.wiphy;

	ieee80211_sdata_init(local, sdata);

	ieee80211_set_default_queues(sdata);

	ret = drv_add_interface(local, sdata);
	if (WARN_ON(ret)) {
		/* ok .. stupid driver, it asked for this! */
		kfree(sdata);
		return ret;
	}

	set_bit(SDATA_STATE_RUNNING, &sdata->state);

	ret = ieee80211_check_queues(sdata, NL80211_IFTYPE_MONITOR);
	if (ret) {
		kfree(sdata);
		return ret;
	}

	mutex_lock(&local->iflist_mtx);
	rcu_assign_pointer(local->monitor_sdata, sdata);
	mutex_unlock(&local->iflist_mtx);

	ret = ieee80211_link_use_channel(&sdata->deflink, &local->monitor_chandef,
					 IEEE80211_CHANCTX_EXCLUSIVE);
	if (ret) {
		mutex_lock(&local->iflist_mtx);
		RCU_INIT_POINTER(local->monitor_sdata, NULL);
		mutex_unlock(&local->iflist_mtx);
		synchronize_net();
		drv_remove_interface(local, sdata);
		kfree(sdata);
		return ret;
	}

	skb_queue_head_init(&sdata->skb_queue);
	skb_queue_head_init(&sdata->status_queue);
	wiphy_work_init(&sdata->work, ieee80211_iface_work);

	return 0;
}

void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata;

	if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
		return;

	ASSERT_RTNL();
	lockdep_assert_wiphy(local->hw.wiphy);

	mutex_lock(&local->iflist_mtx);

	sdata = rcu_dereference_protected(local->monitor_sdata,
					  lockdep_is_held(&local->iflist_mtx));
	if (!sdata) {
		mutex_unlock(&local->iflist_mtx);
		return;
	}

	RCU_INIT_POINTER(local->monitor_sdata, NULL);
	mutex_unlock(&local->iflist_mtx);

	synchronize_net();

	ieee80211_link_release_channel(&sdata->deflink);

	drv_remove_interface(local, sdata);

	kfree(sdata);
}

/*
 * NOTE: Be very careful when changing this function, it must NOT return
 * an error on interface type changes that have been pre-checked, so most
 * checks should be in ieee80211_check_concurrent_iface.
 */
int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
	struct net_device *dev = wdev->netdev;
	struct ieee80211_local *local = sdata->local;
	u64 changed = 0;
	int res;
	u32 hw_reconf_flags = 0;

	lockdep_assert_wiphy(local->hw.wiphy);

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP_VLAN: {
		struct ieee80211_sub_if_data *master;

		if (!sdata->bss)
			return -ENOLINK;

		list_add(&sdata->u.vlan.list, &sdata->bss->vlans);

		master = container_of(sdata->bss,
				      struct ieee80211_sub_if_data, u.ap);
		sdata->control_port_protocol =
			master->control_port_protocol;
		sdata->control_port_no_encrypt =
			master->control_port_no_encrypt;
		sdata->control_port_over_nl80211 =
			master->control_port_over_nl80211;
		sdata->control_port_no_preauth =
			master->control_port_no_preauth;
		sdata->vif.cab_queue = master->vif.cab_queue;
		memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
		       sizeof(sdata->vif.hw_queue));
		sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef;

		sdata->crypto_tx_tailroom_needed_cnt +=
			master->crypto_tx_tailroom_needed_cnt;

		break;
		}
	case NL80211_IFTYPE_AP:
		sdata->bss = &sdata->u.ap;
		break;
	case NL80211_IFTYPE_MESH_POINT:
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_MONITOR:
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_P2P_DEVICE:
	case NL80211_IFTYPE_OCB:
	case NL80211_IFTYPE_NAN:
		/* no special treatment */
		break;
	case NL80211_IFTYPE_UNSPECIFIED:
	case NUM_NL80211_IFTYPES:
	case NL80211_IFTYPE_P2P_CLIENT:
	case NL80211_IFTYPE_P2P_GO:
	case NL80211_IFTYPE_WDS:
		/* cannot happen */
		WARN_ON(1);
		break;
	}

	if (local->open_count == 0) {
		/* here we can consider everything in good order (again) */
		local->reconfig_failure = false;

		res = drv_start(local);
		if (res)
			goto err_del_bss;
		/* we're brought up, everything changes */
		hw_reconf_flags = ~0;
		ieee80211_led_radio(local, true);
		ieee80211_mod_tpt_led_trig(local,
					   IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
	}

	/*
	 * Copy the hopefully now-present MAC address to
	 * this interface, if it has the special null one.
	 */
	if (dev && is_zero_ether_addr(dev->dev_addr)) {
		eth_hw_addr_set(dev, local->hw.wiphy->perm_addr);
		memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);

		if (!is_valid_ether_addr(dev->dev_addr)) {
			res = -EADDRNOTAVAIL;
			goto err_stop;
		}
	}

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP_VLAN:
		/* no need to tell driver, but set carrier and chanctx */
		if (sdata->bss->active) {
			ieee80211_link_vlan_copy_chanctx(&sdata->deflink);
			netif_carrier_on(dev);
			ieee80211_set_vif_encap_ops(sdata);
		} else {
			netif_carrier_off(dev);
		}
		break;
	case NL80211_IFTYPE_MONITOR:
		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
			local->cooked_mntrs++;
			break;
		}

		if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
			res = drv_add_interface(local, sdata);
			if (res)
				goto err_stop;
		} else if (local->monitors == 0 && local->open_count == 0) {
			res = ieee80211_add_virtual_monitor(local);
			if (res)
				goto err_stop;
		}

		/* must be before the call to ieee80211_configure_filter */
		local->monitors++;
		if (local->monitors == 1) {
			local->hw.conf.flags |= IEEE80211_CONF_MONITOR;
			hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
		}

		ieee80211_adjust_monitor_flags(sdata, 1);
		ieee80211_configure_filter(local);
		ieee80211_recalc_offload(local);
		ieee80211_recalc_idle(local);

		netif_carrier_on(dev);
		break;
	default:
		if (coming_up) {
			ieee80211_del_virtual_monitor(local);
			ieee80211_set_sdata_offload_flags(sdata);

			res = drv_add_interface(local, sdata);
			if (res)
				goto err_stop;

			ieee80211_set_vif_encap_ops(sdata);
			res = ieee80211_check_queues(sdata,
				ieee80211_vif_type_p2p(&sdata->vif));
			if (res)
				goto err_del_interface;
		}

		if (sdata->vif.type == NL80211_IFTYPE_AP) {
			local->fif_pspoll++;
			local->fif_probe_req++;

			ieee80211_configure_filter(local);
		} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
			local->fif_probe_req++;
		}

		if (sdata->vif.probe_req_reg)
			drv_config_iface_filter(local, sdata,
						FIF_PROBE_REQ,
						FIF_PROBE_REQ);

		if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
		    sdata->vif.type != NL80211_IFTYPE_NAN)
			changed |= ieee80211_reset_erp_info(sdata);
		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
						  changed);

		switch (sdata->vif.type) {
		case NL80211_IFTYPE_STATION:
		case NL80211_IFTYPE_ADHOC:
		case NL80211_IFTYPE_AP:
		case NL80211_IFTYPE_MESH_POINT:
		case NL80211_IFTYPE_OCB:
			netif_carrier_off(dev);
			break;
		case NL80211_IFTYPE_P2P_DEVICE:
		case NL80211_IFTYPE_NAN:
			break;
		default:
			/* not reached */
			WARN_ON(1);
		}

		/*
		 * Set default queue parameters so drivers don't
		 * need to initialise the hardware if the hardware
		 * doesn't start up with sane defaults.
		 * Enable QoS for anything but station interfaces.
		 */
		ieee80211_set_wmm_default(&sdata->deflink, true,
			sdata->vif.type != NL80211_IFTYPE_STATION);
	}

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_P2P_DEVICE:
		rcu_assign_pointer(local->p2p_sdata, sdata);
		break;
	case NL80211_IFTYPE_MONITOR:
		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
			break;
		list_add_tail_rcu(&sdata->u.mntr.list, &local->mon_list);
		break;
	default:
		break;
	}

	/*
	 * set_multicast_list will be invoked by the networking core
	 * which will check whether any increments here were done in
	 * error and sync them down to the hardware as filter flags.
	 */
	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
		atomic_inc(&local->iff_allmultis);

	if (coming_up)
		local->open_count++;

	if (hw_reconf_flags)
		ieee80211_hw_config(local, hw_reconf_flags);

	ieee80211_recalc_ps(local);

	set_bit(SDATA_STATE_RUNNING, &sdata->state);

	return 0;
 err_del_interface:
	drv_remove_interface(local, sdata);
 err_stop:
	if (!local->open_count)
		drv_stop(local);
 err_del_bss:
	sdata->bss = NULL;
	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
		list_del(&sdata->u.vlan.list);
	/* might already be clear but that doesn't matter */
	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
	return res;
}

static void ieee80211_if_free(struct net_device *dev)
{
	free_percpu(dev->tstats);
}

static void ieee80211_if_setup(struct net_device *dev)
{
	ether_setup(dev);
	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
	dev->priv_flags |= IFF_NO_QUEUE;
	dev->netdev_ops = &ieee80211_dataif_ops;
	dev->needs_free_netdev = true;
	dev->priv_destructor = ieee80211_if_free;
}

static void ieee80211_iface_process_skb(struct ieee80211_local *local,
					struct ieee80211_sub_if_data *sdata,
					struct sk_buff *skb)
{
	struct ieee80211_mgmt *mgmt = (void *)skb->data;

	lockdep_assert_wiphy(local->hw.wiphy);

	if (ieee80211_is_action(mgmt->frame_control) &&
	    mgmt->u.action.category == WLAN_CATEGORY_BACK) {
		struct sta_info *sta;
		int len = skb->len;

		sta = sta_info_get_bss(sdata, mgmt->sa);
		if (sta) {
			switch (mgmt->u.action.u.addba_req.action_code) {
			case WLAN_ACTION_ADDBA_REQ:
				ieee80211_process_addba_request(local, sta,
								mgmt, len);
				break;
			case WLAN_ACTION_ADDBA_RESP:
				ieee80211_process_addba_resp(local, sta,
							     mgmt, len);
				break;
			case WLAN_ACTION_DELBA:
				ieee80211_process_delba(sdata, sta,
							mgmt, len);
				break;
			default:
				WARN_ON(1);
				break;
			}
		}
	} else if (ieee80211_is_action(mgmt->frame_control) &&
		   mgmt->u.action.category == WLAN_CATEGORY_VHT) {
		switch (mgmt->u.action.u.vht_group_notif.action_code) {
		case WLAN_VHT_ACTION_OPMODE_NOTIF: {
			struct ieee80211_rx_status *status;
			enum nl80211_band band;
			struct sta_info *sta;
			u8 opmode;

			status = IEEE80211_SKB_RXCB(skb);
			band = status->band;
			opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;

			sta = sta_info_get_bss(sdata, mgmt->sa);

			if (sta)
				ieee80211_vht_handle_opmode(sdata,
							    &sta->deflink,
							    opmode, band);

			break;
		}
		case WLAN_VHT_ACTION_GROUPID_MGMT:
			ieee80211_process_mu_groups(sdata, &sdata->deflink,
						    mgmt);
			break;
		default:
			WARN_ON(1);
			break;
		}
	} else if (ieee80211_is_action(mgmt->frame_control) &&
		   mgmt->u.action.category == WLAN_CATEGORY_S1G) {
		switch (mgmt->u.action.u.s1g.action_code) {
		case WLAN_S1G_TWT_TEARDOWN:
		case WLAN_S1G_TWT_SETUP:
			ieee80211_s1g_rx_twt_action(sdata, skb);
			break;
		default:
			break;
		}
	} else if (ieee80211_is_ext(mgmt->frame_control)) {
		if (sdata->vif.type == NL80211_IFTYPE_STATION)
			ieee80211_sta_rx_queued_ext(sdata, skb);
		else
			WARN_ON(1);
	} else if (ieee80211_is_data_qos(mgmt->frame_control)) {
		struct ieee80211_hdr *hdr = (void *)mgmt;
		struct sta_info *sta;

		/*
		 * So the frame isn't mgmt, but frame_control
		 * is at the right place anyway, of course, so
		 * the if statement is correct.
		 *
		 * Warn if we have other data frame types here,
		 * they must not get here.
		 */
		WARN_ON(hdr->frame_control &
				cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
		WARN_ON(!(hdr->seq_ctrl &
				cpu_to_le16(IEEE80211_SCTL_FRAG)));
		/*
		 * This was a fragment of a frame, received while
		 * a block-ack session was active. That cannot be
		 * right, so terminate the session.
		 */
		sta = sta_info_get_bss(sdata, mgmt->sa);
		if (sta) {
			u16 tid = ieee80211_get_tid(hdr);

			__ieee80211_stop_rx_ba_session(
				sta, tid, WLAN_BACK_RECIPIENT,
				WLAN_REASON_QSTA_REQUIRE_SETUP,
				true);
		}
	} else switch (sdata->vif.type) {
	case NL80211_IFTYPE_STATION:
		ieee80211_sta_rx_queued_mgmt(sdata, skb);
		break;
	case NL80211_IFTYPE_ADHOC:
		ieee80211_ibss_rx_queued_mgmt(sdata, skb);
		break;
	case NL80211_IFTYPE_MESH_POINT:
		if (!ieee80211_vif_is_mesh(&sdata->vif))
			break;
		ieee80211_mesh_rx_queued_mgmt(sdata, skb);
		break;
	default:
		WARN(1, "frame for unexpected interface type");
		break;
	}
}

static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
					   struct sk_buff *skb)
{
	struct ieee80211_mgmt *mgmt = (void *)skb->data;

	if (ieee80211_is_action(mgmt->frame_control) &&
	    mgmt->u.action.category == WLAN_CATEGORY_S1G) {
		switch (mgmt->u.action.u.s1g.action_code) {
		case WLAN_S1G_TWT_TEARDOWN:
		case WLAN_S1G_TWT_SETUP:
			ieee80211_s1g_status_twt_action(sdata, skb);
			break;
		default:
			break;
		}
	}
}

static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data, work);
	struct ieee80211_local *local = sdata->local;
	struct sk_buff *skb;

	if (!ieee80211_sdata_running(sdata))
		return;

	if (test_bit(SCAN_SW_SCANNING, &local->scanning))
		return;

	if (!ieee80211_can_run_worker(local))
		return;

	/* first process frames */
	while ((skb = skb_dequeue(&sdata->skb_queue))) {
		kcov_remote_start_common(skb_get_kcov_handle(skb));

		if (skb->protocol == cpu_to_be16(ETH_P_TDLS))
			ieee80211_process_tdls_channel_switch(sdata, skb);
		else
			ieee80211_iface_process_skb(local, sdata, skb);

		kfree_skb(skb);
		kcov_remote_stop();
	}

	/* process status queue */
	while ((skb = skb_dequeue(&sdata->status_queue))) {
		kcov_remote_start_common(skb_get_kcov_handle(skb));

		ieee80211_iface_process_status(sdata, skb);
		kfree_skb(skb);

		kcov_remote_stop();
	}

	/* then other type-dependent work */
	switch (sdata->vif.type) {
	case NL80211_IFTYPE_STATION:
		ieee80211_sta_work(sdata);
		break;
	case NL80211_IFTYPE_ADHOC:
		ieee80211_ibss_work(sdata);
		break;
	case NL80211_IFTYPE_MESH_POINT:
		if (!ieee80211_vif_is_mesh(&sdata->vif))
			break;
		ieee80211_mesh_work(sdata);
		break;
	case NL80211_IFTYPE_OCB:
		ieee80211_ocb_work(sdata);
		break;
	default:
		break;
	}
}

static void ieee80211_activate_links_work(struct wiphy *wiphy,
					  struct wiphy_work *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data,
			     activate_links_work);

	ieee80211_set_active_links(&sdata->vif, sdata->desired_active_links);
}

/*
 * Helper function to initialise an interface to a specific type.
 */
static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
				  enum nl80211_iftype type)
{
	static const u8 bssid_wildcard[ETH_ALEN] = {0xff, 0xff, 0xff,
						    0xff, 0xff, 0xff};

	/* clear type-dependent unions */
	memset(&sdata->u, 0, sizeof(sdata->u));
	memset(&sdata->deflink.u, 0, sizeof(sdata->deflink.u));

	/* and set some type-dependent values */
	sdata->vif.type = type;
	sdata->vif.p2p = false;
	sdata->wdev.iftype = type;

	sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
	sdata->control_port_no_encrypt = false;
	sdata->control_port_over_nl80211 = false;
	sdata->control_port_no_preauth = false;
	sdata->vif.cfg.idle = true;
	sdata->vif.bss_conf.txpower = INT_MIN; /* unset */

	sdata->noack_map = 0;

	/* only monitor/p2p-device differ */
	if (sdata->dev) {
		sdata->dev->netdev_ops = &ieee80211_dataif_ops;
		sdata->dev->type = ARPHRD_ETHER;
	}

	skb_queue_head_init(&sdata->skb_queue);
	skb_queue_head_init(&sdata->status_queue);
	wiphy_work_init(&sdata->work, ieee80211_iface_work);
	wiphy_work_init(&sdata->activate_links_work,
			ieee80211_activate_links_work);

	switch (type) {
	case NL80211_IFTYPE_P2P_GO:
		type = NL80211_IFTYPE_AP;
		sdata->vif.type = type;
		sdata->vif.p2p = true;
		fallthrough;
	case NL80211_IFTYPE_AP:
		skb_queue_head_init(&sdata->u.ap.ps.bc_buf);
		INIT_LIST_HEAD(&sdata->u.ap.vlans);
		sdata->vif.bss_conf.bssid = sdata->vif.addr;
		break;
	case NL80211_IFTYPE_P2P_CLIENT:
		type = NL80211_IFTYPE_STATION;
		sdata->vif.type = type;
		sdata->vif.p2p = true;
		fallthrough;
	case NL80211_IFTYPE_STATION:
		sdata->vif.bss_conf.bssid = sdata->deflink.u.mgd.bssid;
		ieee80211_sta_setup_sdata(sdata);
		break;
	case NL80211_IFTYPE_OCB:
		sdata->vif.bss_conf.bssid = bssid_wildcard;
		ieee80211_ocb_setup_sdata(sdata);
		break;
	case NL80211_IFTYPE_ADHOC:
		sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
		ieee80211_ibss_setup_sdata(sdata);
		break;
	case NL80211_IFTYPE_MESH_POINT:
		if (ieee80211_vif_is_mesh(&sdata->vif))
			ieee80211_mesh_init_sdata(sdata);
		break;
	case NL80211_IFTYPE_MONITOR:
		sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP;
		sdata->dev->netdev_ops = &ieee80211_monitorif_ops;
		sdata->u.mntr.flags = MONITOR_FLAG_CONTROL |
				      MONITOR_FLAG_OTHER_BSS;
		break;
	case NL80211_IFTYPE_NAN:
		idr_init(&sdata->u.nan.function_inst_ids);
		spin_lock_init(&sdata->u.nan.func_lock);
		sdata->vif.bss_conf.bssid = sdata->vif.addr;
		break;
	case NL80211_IFTYPE_AP_VLAN:
	case NL80211_IFTYPE_P2P_DEVICE:
		sdata->vif.bss_conf.bssid = sdata->vif.addr;
		break;
	case NL80211_IFTYPE_UNSPECIFIED:
	case NL80211_IFTYPE_WDS:
	case NUM_NL80211_IFTYPES:
		WARN_ON(1);
		break;
	}

	/* need to do this after the switch so vif.type is correct */
	ieee80211_link_setup(&sdata->deflink);

	ieee80211_debugfs_recreate_netdev(sdata, false);
}

static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
					   enum nl80211_iftype type)
{
	struct ieee80211_local *local = sdata->local;
	int ret, err;
	enum nl80211_iftype internal_type = type;
	bool p2p = false;

	ASSERT_RTNL();

	if (!local->ops->change_interface)
		return -EBUSY;

	/* for now, don't support changing while links exist */
	if (ieee80211_vif_is_mld(&sdata->vif))
		return -EBUSY;

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP:
		if (!list_empty(&sdata->u.ap.vlans))
			return -EBUSY;
		break;
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_OCB:
		/*
		 * Could maybe also all others here?
		 * Just not sure how that interacts
		 * with the RX/config path e.g. for
		 * mesh.
		 */
		break;
	default:
		return -EBUSY;
	}

	switch (type) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_OCB:
		/*
		 * Could probably support everything
		 * but here.
		 */
		break;
	case NL80211_IFTYPE_P2P_CLIENT:
		p2p = true;
		internal_type = NL80211_IFTYPE_STATION;
		break;
	case NL80211_IFTYPE_P2P_GO:
		p2p = true;
		internal_type = NL80211_IFTYPE_AP;
		break;
	default:
		return -EBUSY;
	}

	ret = ieee80211_check_concurrent_iface(sdata, internal_type);
	if (ret)
		return ret;

	ieee80211_stop_vif_queues(local, sdata,
				  IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE);
	/* do_stop will synchronize_rcu() first thing */
	ieee80211_do_stop(sdata, false);

	ieee80211_teardown_sdata(sdata);

	ieee80211_set_sdata_offload_flags(sdata);
	ret = drv_change_interface(local, sdata, internal_type, p2p);
	if (ret)
		type = ieee80211_vif_type_p2p(&sdata->vif);

	/*
	 * Ignore return value here, there's not much we can do since
	 * the driver changed the interface type internally already.
	 * The warnings will hopefully make driver authors fix it :-)
	 */
	ieee80211_check_queues(sdata, type);

	ieee80211_setup_sdata(sdata, type);
	ieee80211_set_vif_encap_ops(sdata);

	err = ieee80211_do_open(&sdata->wdev, false);
	WARN(err, "type change: do_open returned %d", err);

	ieee80211_wake_vif_queues(local, sdata,
				  IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE);
	return ret;
}

int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
			     enum nl80211_iftype type)
{
	int ret;

	ASSERT_RTNL();

	if (type == ieee80211_vif_type_p2p(&sdata->vif))
		return 0;

	if (ieee80211_sdata_running(sdata)) {
		ret = ieee80211_runtime_change_iftype(sdata, type);
		if (ret)
			return ret;
	} else {
		/* Purge and reset type-dependent state. */
		ieee80211_teardown_sdata(sdata);
		ieee80211_setup_sdata(sdata, type);
	}

	/* reset some values that shouldn't be kept across type changes */
	if (type == NL80211_IFTYPE_STATION)
		sdata->u.mgd.use_4addr = false;

	return 0;
}

static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
				       u8 *perm_addr, enum nl80211_iftype type)
{
	struct ieee80211_sub_if_data *sdata;
	u64 mask, start, addr, val, inc;
	u8 *m;
	u8 tmp_addr[ETH_ALEN];
	int i;

	lockdep_assert_wiphy(local->hw.wiphy);

	/* default ... something at least */
	memcpy(perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN);

	if (is_zero_ether_addr(local->hw.wiphy->addr_mask) &&
	    local->hw.wiphy->n_addresses <= 1)
		return;

	switch (type) {
	case NL80211_IFTYPE_MONITOR:
		/* doesn't matter */
		break;
	case NL80211_IFTYPE_AP_VLAN:
		/* match up with an AP interface */
		list_for_each_entry(sdata, &local->interfaces, list) {
			if (sdata->vif.type != NL80211_IFTYPE_AP)
				continue;
			memcpy(perm_addr, sdata->vif.addr, ETH_ALEN);
			break;
		}
		/* keep default if no AP interface present */
		break;
	case NL80211_IFTYPE_P2P_CLIENT:
	case NL80211_IFTYPE_P2P_GO:
		if (ieee80211_hw_check(&local->hw, P2P_DEV_ADDR_FOR_INTF)) {
			list_for_each_entry(sdata, &local->interfaces, list) {
				if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE)
					continue;
				if (!ieee80211_sdata_running(sdata))
					continue;
				memcpy(perm_addr, sdata->vif.addr, ETH_ALEN);
				return;
			}
		}
		fallthrough;
	default:
		/* assign a new address if possible -- try n_addresses first */
		for (i = 0; i < local->hw.wiphy->n_addresses; i++) {
			bool used = false;

			list_for_each_entry(sdata, &local->interfaces, list) {
				if (ether_addr_equal(local->hw.wiphy->addresses[i].addr,
						     sdata->vif.addr)) {
					used = true;
					break;
				}
			}

			if (!used) {
				memcpy(perm_addr,
				       local->hw.wiphy->addresses[i].addr,
				       ETH_ALEN);
				break;
			}
		}

		/* try mask if available */
		if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
			break;

		m = local->hw.wiphy->addr_mask;
		mask =	((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
			((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
			((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);

		if (__ffs64(mask) + hweight64(mask) != fls64(mask)) {
			/* not a contiguous mask ... not handled now! */
			pr_info("not contiguous\n");
			break;
		}

		/*
		 * Pick address of existing interface in case user changed
		 * MAC address manually, default to perm_addr.
		 */
		m = local->hw.wiphy->perm_addr;
		list_for_each_entry(sdata, &local->interfaces, list) {
			if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
				continue;
			m = sdata->vif.addr;
			break;
		}
		start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
			((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
			((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);

		inc = 1ULL<<__ffs64(mask);
		val = (start & mask);
		addr = (start & ~mask) | (val & mask);
		do {
			bool used = false;

			tmp_addr[5] = addr >> 0*8;
			tmp_addr[4] = addr >> 1*8;
			tmp_addr[3] = addr >> 2*8;
			tmp_addr[2] = addr >> 3*8;
			tmp_addr[1] = addr >> 4*8;
			tmp_addr[0] = addr >> 5*8;

			val += inc;

			list_for_each_entry(sdata, &local->interfaces, list) {
				if (ether_addr_equal(tmp_addr, sdata->vif.addr)) {
					used = true;
					break;
				}
			}

			if (!used) {
				memcpy(perm_addr, tmp_addr, ETH_ALEN);
				break;
			}
			addr = (start & ~mask) | (val & mask);
		} while (addr != start);

		break;
	}
}

int ieee80211_if_add(struct ieee80211_local *local, const char *name,
		     unsigned char name_assign_type,
		     struct wireless_dev **new_wdev, enum nl80211_iftype type,
		     struct vif_params *params)
{
	struct net_device *ndev = NULL;
	struct ieee80211_sub_if_data *sdata = NULL;
	struct txq_info *txqi;
	int ret, i;

	ASSERT_RTNL();
	lockdep_assert_wiphy(local->hw.wiphy);

	if (type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN) {
		struct wireless_dev *wdev;

		sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size,
				GFP_KERNEL);
		if (!sdata)
			return -ENOMEM;
		wdev = &sdata->wdev;

		sdata->dev = NULL;
		strscpy(sdata->name, name, IFNAMSIZ);
		ieee80211_assign_perm_addr(local, wdev->address, type);
		memcpy(sdata->vif.addr, wdev->address, ETH_ALEN);
		ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
	} else {
		int size = ALIGN(sizeof(*sdata) + local->hw.vif_data_size,
				 sizeof(void *));
		int txq_size = 0;

		if (type != NL80211_IFTYPE_AP_VLAN &&
		    (type != NL80211_IFTYPE_MONITOR ||
		     (params->flags & MONITOR_FLAG_ACTIVE)))
			txq_size += sizeof(struct txq_info) +
				    local->hw.txq_data_size;

		ndev = alloc_netdev_mqs(size + txq_size,
					name, name_assign_type,
					ieee80211_if_setup, 1, 1);
		if (!ndev)
			return -ENOMEM;

		dev_net_set(ndev, wiphy_net(local->hw.wiphy));

		ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
		if (!ndev->tstats) {
			free_netdev(ndev);
			return -ENOMEM;
		}

		ndev->needed_headroom = local->tx_headroom +
					4*6 /* four MAC addresses */
					+ 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */
					+ 6 /* mesh */
					+ 8 /* rfc1042/bridge tunnel */
					- ETH_HLEN /* ethernet hard_header_len */
					+ IEEE80211_ENCRYPT_HEADROOM;
		ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;

		ret = dev_alloc_name(ndev, ndev->name);
		if (ret < 0) {
			ieee80211_if_free(ndev);
			free_netdev(ndev);
			return ret;
		}

		ieee80211_assign_perm_addr(local, ndev->perm_addr, type);
		if (is_valid_ether_addr(params->macaddr))
			eth_hw_addr_set(ndev, params->macaddr);
		else
			eth_hw_addr_set(ndev, ndev->perm_addr);
		SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));

		/* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */
		sdata = netdev_priv(ndev);
		ndev->ieee80211_ptr = &sdata->wdev;
		memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN);
		ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
		memcpy(sdata->name, ndev->name, IFNAMSIZ);

		if (txq_size) {
			txqi = netdev_priv(ndev) + size;
			ieee80211_txq_init(sdata, NULL, txqi, 0);
		}

		sdata->dev = ndev;
	}

	/* initialise type-independent data */
	sdata->wdev.wiphy = local->hw.wiphy;

	ieee80211_sdata_init(local, sdata);

	ieee80211_init_frag_cache(&sdata->frags);

	INIT_LIST_HEAD(&sdata->key_list);

	wiphy_delayed_work_init(&sdata->dec_tailroom_needed_wk,
				ieee80211_delayed_tailroom_dec);

	for (i = 0; i < NUM_NL80211_BANDS; i++) {
		struct ieee80211_supported_band *sband;
		sband = local->hw.wiphy->bands[i];
		sdata->rc_rateidx_mask[i] =
			sband ? (1 << sband->n_bitrates) - 1 : 0;
		if (sband) {
			__le16 cap;
			u16 *vht_rate_mask;

			memcpy(sdata->rc_rateidx_mcs_mask[i],
			       sband->ht_cap.mcs.rx_mask,
			       sizeof(sdata->rc_rateidx_mcs_mask[i]));

			cap = sband->vht_cap.vht_mcs.rx_mcs_map;
			vht_rate_mask = sdata->rc_rateidx_vht_mcs_mask[i];
			ieee80211_get_vht_mask_from_cap(cap, vht_rate_mask);
		} else {
			memset(sdata->rc_rateidx_mcs_mask[i], 0,
			       sizeof(sdata->rc_rateidx_mcs_mask[i]));
			memset(sdata->rc_rateidx_vht_mcs_mask[i], 0,
			       sizeof(sdata->rc_rateidx_vht_mcs_mask[i]));
		}
	}

	ieee80211_set_default_queues(sdata);

	sdata->deflink.ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
	sdata->deflink.user_power_level = local->user_power_level;

	/* setup type-dependent data */
	ieee80211_setup_sdata(sdata, type);

	if (ndev) {
		ndev->ieee80211_ptr->use_4addr = params->use_4addr;
		if (type == NL80211_IFTYPE_STATION)
			sdata->u.mgd.use_4addr = params->use_4addr;

		ndev->features |= local->hw.netdev_features;
		ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
		ndev->hw_features |= ndev->features &
					MAC80211_SUPPORTED_FEATURES_TX;
		sdata->vif.netdev_features = local->hw.netdev_features;

		netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);

		/* MTU range is normally 256 - 2304, where the upper limit is
		 * the maximum MSDU size. Monitor interfaces send and receive
		 * MPDU and A-MSDU frames which may be much larger so we do
		 * not impose an upper limit in that case.
		 */
		ndev->min_mtu = 256;
		if (type == NL80211_IFTYPE_MONITOR)
			ndev->max_mtu = 0;
		else
			ndev->max_mtu = local->hw.max_mtu;

		ret = cfg80211_register_netdevice(ndev);
		if (ret) {
			free_netdev(ndev);
			return ret;
		}
	}

	mutex_lock(&local->iflist_mtx);
	list_add_tail_rcu(&sdata->list, &local->interfaces);
	mutex_unlock(&local->iflist_mtx);

	if (new_wdev)
		*new_wdev = &sdata->wdev;

	return 0;
}

void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
{
	ASSERT_RTNL();
	lockdep_assert_wiphy(sdata->local->hw.wiphy);

	mutex_lock(&sdata->local->iflist_mtx);
	list_del_rcu(&sdata->list);
	mutex_unlock(&sdata->local->iflist_mtx);

	if (sdata->vif.txq)
		ieee80211_txq_purge(sdata->local, to_txq_info(sdata->vif.txq));

	synchronize_rcu();

	cfg80211_unregister_wdev(&sdata->wdev);

	if (!sdata->dev) {
		ieee80211_teardown_sdata(sdata);
		kfree(sdata);
	}
}

void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata)
{
	if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state)))
		return;
	ieee80211_do_stop(sdata, true);
}

void ieee80211_remove_interfaces(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata, *tmp;
	LIST_HEAD(unreg_list);

	ASSERT_RTNL();

	/* Before destroying the interfaces, make sure they're all stopped so
	 * that the hardware is stopped. Otherwise, the driver might still be
	 * iterating the interfaces during the shutdown, e.g. from a worker
	 * or from RX processing or similar, and if it does so (using atomic
	 * iteration) while we're manipulating the list, the iteration will
	 * crash.
	 *
	 * After this, the hardware should be stopped and the driver should
	 * have stopped all of its activities, so that we can do RCU-unaware
	 * manipulations of the interface list below.
	 */
	cfg80211_shutdown_all_interfaces(local->hw.wiphy);

	wiphy_lock(local->hw.wiphy);

	WARN(local->open_count, "%s: open count remains %d\n",
	     wiphy_name(local->hw.wiphy), local->open_count);

	mutex_lock(&local->iflist_mtx);
	list_splice_init(&local->interfaces, &unreg_list);
	mutex_unlock(&local->iflist_mtx);

	list_for_each_entry_safe(sdata, tmp, &unreg_list, list) {
		bool netdev = sdata->dev;

		/*
		 * Remove IP addresses explicitly, since the notifier will
		 * skip the callbacks if wdev->registered is false, since
		 * we can't acquire the wiphy_lock() again there if already
		 * inside this locked section.
		 */
		sdata->vif.cfg.arp_addr_cnt = 0;
		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
		    sdata->u.mgd.associated)
			ieee80211_vif_cfg_change_notify(sdata,
							BSS_CHANGED_ARP_FILTER);

		list_del(&sdata->list);
		cfg80211_unregister_wdev(&sdata->wdev);

		if (!netdev)
			kfree(sdata);
	}
	wiphy_unlock(local->hw.wiphy);
}

static int netdev_notify(struct notifier_block *nb,
			 unsigned long state, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct ieee80211_sub_if_data *sdata;

	if (state != NETDEV_CHANGENAME)
		return NOTIFY_DONE;

	if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
		return NOTIFY_DONE;

	if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
		return NOTIFY_DONE;

	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	memcpy(sdata->name, dev->name, IFNAMSIZ);
	ieee80211_debugfs_rename_netdev(sdata);

	return NOTIFY_OK;
}

static struct notifier_block mac80211_netdev_notifier = {
	.notifier_call = netdev_notify,
};

int ieee80211_iface_init(void)
{
	return register_netdevice_notifier(&mac80211_netdev_notifier);
}

void ieee80211_iface_exit(void)
{
	unregister_netdevice_notifier(&mac80211_netdev_notifier);
}

void ieee80211_vif_inc_num_mcast(struct ieee80211_sub_if_data *sdata)
{
	if (sdata->vif.type == NL80211_IFTYPE_AP)
		atomic_inc(&sdata->u.ap.num_mcast_sta);
	else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
		atomic_inc(&sdata->u.vlan.num_mcast_sta);
}

void ieee80211_vif_dec_num_mcast(struct ieee80211_sub_if_data *sdata)
{
	if (sdata->vif.type == NL80211_IFTYPE_AP)
		atomic_dec(&sdata->u.ap.num_mcast_sta);
	else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
		atomic_dec(&sdata->u.vlan.num_mcast_sta);
}
