// SPDX-License-Identifier: GPL-2.0-only
/*
 * This is the linux wireless configuration interface.
 *
 * Copyright 2006-2010		Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 * Copyright 2015-2017	Intel Deutschland GmbH
 * Copyright (C) 2018-2026 Intel Corporation
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/if.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/nl80211.h>
#include <linux/debugfs.h>
#include <linux/notifier.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <linux/sched.h>
#include <net/genetlink.h>
#include <net/cfg80211.h>
#include "nl80211.h"
#include "core.h"
#include "sysfs.h"
#include "debugfs.h"
#include "wext-compat.h"
#include "rdev-ops.h"

/* name for sysfs, %d is appended */
#define PHY_NAME "phy"

/* maximum length of radio debugfs directory name */
#define RADIO_DEBUGFSDIR_MAX_LEN	8

MODULE_AUTHOR("Johannes Berg");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("wireless configuration support");
MODULE_ALIAS_GENL_FAMILY(NL80211_GENL_NAME);

/* RCU-protected (and RTNL for writers) */
LIST_HEAD(cfg80211_rdev_list);
int cfg80211_rdev_list_generation;

/* for debugfs */
static struct dentry *ieee80211_debugfs_dir;

/* for the cleanup, scan and event works */
struct workqueue_struct *cfg80211_wq;

static bool cfg80211_disable_40mhz_24ghz;
module_param(cfg80211_disable_40mhz_24ghz, bool, 0644);
MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz,
		 "Disable 40MHz support in the 2.4GHz band");

struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
{
	struct cfg80211_registered_device *result = NULL, *rdev;

	ASSERT_RTNL();

	for_each_rdev(rdev) {
		if (rdev->wiphy_idx == wiphy_idx) {
			result = rdev;
			break;
		}
	}

	return result;
}

int get_wiphy_idx(struct wiphy *wiphy)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);

	return rdev->wiphy_idx;
}

struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
{
	struct cfg80211_registered_device *rdev;

	ASSERT_RTNL();

	rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx);
	if (!rdev)
		return NULL;
	return &rdev->wiphy;
}

static int cfg80211_dev_check_name(struct cfg80211_registered_device *rdev,
				   const char *newname)
{
	struct cfg80211_registered_device *rdev2;
	int wiphy_idx, taken = -1, digits;

	ASSERT_RTNL();

	if (strlen(newname) > NL80211_WIPHY_NAME_MAXLEN)
		return -EINVAL;

	/* prohibit calling the thing phy%d when %d is not its number */
	sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
	if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
		/* count number of places needed to print wiphy_idx */
		digits = 1;
		while (wiphy_idx /= 10)
			digits++;
		/*
		 * deny the name if it is phy<idx> where <idx> is printed
		 * without leading zeroes. taken == strlen(newname) here
		 */
		if (taken == strlen(PHY_NAME) + digits)
			return -EINVAL;
	}

	/* Ensure another device does not already have this name. */
	for_each_rdev(rdev2)
		if (strcmp(newname, wiphy_name(&rdev2->wiphy)) == 0)
			return -EINVAL;

	return 0;
}

int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
			char *newname)
{
	int result;

	ASSERT_RTNL();
	lockdep_assert_wiphy(&rdev->wiphy);

	/* Ignore nop renames */
	if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0)
		return 0;

	result = cfg80211_dev_check_name(rdev, newname);
	if (result < 0)
		return result;

	result = device_rename(&rdev->wiphy.dev, newname);
	if (result)
		return result;

	debugfs_change_name(rdev->wiphy.debugfsdir, "%s", newname);

	nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);

	return 0;
}

static int cfg80211_switch_wdev_netns(struct wireless_dev *wdev,
				      struct net *net)
{
	int err;

	if (!wdev->netdev)
		return 0;

	wdev->netdev->netns_immutable = false;
	err = dev_change_net_namespace(wdev->netdev, net, "wlan%d");
	wdev->netdev->netns_immutable = true;

	return err;
}

static int __cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
				   struct net *net, bool force)
{
	struct net *old_net = wiphy_net(&rdev->wiphy);
	struct wireless_dev *wdev, *tmp;
	int err = 0;

	list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
		err = cfg80211_switch_wdev_netns(wdev, net);
		if (!err)
			continue;
		if (!force)
			goto undo;
		/* remove interfaces that fail to allow wiphy switching */
		dev_close(wdev->netdev);
		scoped_guard(wiphy, &rdev->wiphy)
			cfg80211_unregister_wdev(wdev);
		err = 0;
	}

	scoped_guard(wiphy, &rdev->wiphy) {
		list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
			if (!wdev->netdev)
				continue;
			nl80211_notify_iface(rdev, wdev,
					     NL80211_CMD_DEL_INTERFACE);
		}

		nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);

		wiphy_net_set(&rdev->wiphy, net);

		/* this only fails on allocation failure */
		err = device_rename(&rdev->wiphy.dev,
				    dev_name(&rdev->wiphy.dev));
		if (err && !force)
			wiphy_net_set(&rdev->wiphy, old_net);

		nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);

		list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
			if (!wdev->netdev)
				continue;
			nl80211_notify_iface(rdev, wdev,
					     NL80211_CMD_NEW_INTERFACE);
		}
	}

	if (!err || force)
		return err;

	/* set to the last one to undo all of them */
	wdev = list_entry(&rdev->wiphy.wdev_list, typeof(*wdev), list);
undo:
	/*
	 * Move back everything, if this fails again (allocation failures)
	 * then things get stuck in different network namespaces.
	 */
	list_for_each_entry_continue_reverse(wdev, &rdev->wiphy.wdev_list,
					     list)
		WARN_ON(cfg80211_switch_wdev_netns(wdev, old_net));

	return err;
}

int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
			  struct net *net)
{
	if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
		return -EOPNOTSUPP;

	return __cfg80211_switch_netns(rdev, net, false);
}

static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
{
	struct cfg80211_registered_device *rdev = data;

	guard(wiphy)(&rdev->wiphy);

	rdev_rfkill_poll(rdev);
}

void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
			      struct wireless_dev *wdev)
{
	lockdep_assert_held(&rdev->wiphy.mtx);

	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE))
		return;

	if (!wdev_running(wdev))
		return;

	cfg80211_pmsr_wdev_down(wdev);
	rdev_stop_p2p_device(rdev, wdev);
	wdev->is_running = false;

	rdev->opencount--;

	if (rdev->scan_req && rdev->scan_req->req.wdev == wdev) {
		if (!rdev->scan_req->notified &&
		    (!rdev->int_scan_req || !rdev->int_scan_req->notified))
			rdev->scan_req->info.aborted = true;
		___cfg80211_scan_done(rdev, false);
	}
}

void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
		       struct wireless_dev *wdev)
{
	struct cfg80211_nan_local_sched empty_sched = {};

	lockdep_assert_held(&rdev->wiphy.mtx);

	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_NAN))
		return;

	if (!wdev_running(wdev))
		return;

	cfg80211_pmsr_wdev_down(wdev);

	/*
	 * If there is a scheduled update pending, mark it as canceled, so the
	 * empty schedule will be accepted
	 */
	wdev->u.nan.sched_update_pending = false;

	/* Unschedule all */
	cfg80211_nan_set_local_schedule(rdev, wdev, &empty_sched);

	rdev_stop_nan(rdev, wdev);
	wdev->is_running = false;

	eth_zero_addr(wdev->u.nan.cluster_id);

	rdev->opencount--;
}

int cfg80211_nan_set_local_schedule(struct cfg80211_registered_device *rdev,
				    struct wireless_dev *wdev,
				    struct cfg80211_nan_local_sched *sched)
{
	int ret;

	lockdep_assert_held(&rdev->wiphy.mtx);

	if (wdev->iftype != NL80211_IFTYPE_NAN || !wdev_running(wdev))
		return -EINVAL;

	if (wdev->u.nan.sched_update_pending)
		return -EBUSY;

	ret = rdev_nan_set_local_sched(rdev, wdev, sched);
	if (ret)
		return ret;

	wdev->u.nan.sched_update_pending = sched->deferred;

	kfree(wdev->u.nan.chandefs);
	wdev->u.nan.chandefs = NULL;
	wdev->u.nan.n_channels = 0;

	if (!sched->n_channels)
		return 0;

	wdev->u.nan.chandefs = kzalloc_objs(*wdev->u.nan.chandefs,
					    sched->n_channels);
	if (!wdev->u.nan.chandefs)
		return -ENOMEM;

	for (int i = 0; i < sched->n_channels; i++)
		wdev->u.nan.chandefs[i] = sched->nan_channels[i].chandef;

	wdev->u.nan.n_channels = sched->n_channels;

	return 0;
}

void cfg80211_stop_pd(struct cfg80211_registered_device *rdev,
		      struct wireless_dev *wdev)
{
	lockdep_assert_held(&rdev->wiphy.mtx);

	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_PD))
		return;

	if (!rdev->ops->stop_pd)
		return;

	if (!wdev_running(wdev))
		return;

	cfg80211_pmsr_wdev_down(wdev);

	rdev_stop_pd(rdev, wdev);
	wdev->is_running = false;

	rdev->opencount--;
}

void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct wireless_dev *wdev;

	ASSERT_RTNL();

	/*
	 * Some netdev interfaces need to be closed before some non-netdev
	 * ones, i.e. NAN_DATA interfaces need to be closed before the NAN
	 * interface
	 */
	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
		if (wdev->netdev) {
			dev_close(wdev->netdev);
			continue;
		}
	}

	guard(wiphy)(wiphy);

	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
		switch (wdev->iftype) {
		case NL80211_IFTYPE_P2P_DEVICE:
			cfg80211_stop_p2p_device(rdev, wdev);
			break;
		case NL80211_IFTYPE_NAN:
			cfg80211_stop_nan(rdev, wdev);
			break;
		case NL80211_IFTYPE_PD:
			cfg80211_stop_pd(rdev, wdev);
			break;
		default:
			break;
		}
	}
}
EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces);

static int cfg80211_rfkill_set_block(void *data, bool blocked)
{
	struct cfg80211_registered_device *rdev = data;

	if (!blocked)
		return 0;

	rtnl_lock();
	cfg80211_shutdown_all_interfaces(&rdev->wiphy);
	rtnl_unlock();

	return 0;
}

static void cfg80211_rfkill_block_work(struct work_struct *work)
{
	struct cfg80211_registered_device *rdev;

	rdev = container_of(work, struct cfg80211_registered_device,
			    rfkill_block);
	cfg80211_rfkill_set_block(rdev, true);
}

static void cfg80211_event_work(struct work_struct *work)
{
	struct cfg80211_registered_device *rdev;

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

	guard(wiphy)(&rdev->wiphy);

	cfg80211_process_rdev_events(rdev);
}

void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
{
	struct wireless_dev *wdev, *tmp;

	ASSERT_RTNL();

	list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
		if (wdev->nl_owner_dead) {
			cfg80211_close_dependents(rdev, wdev);

			if (wdev->netdev)
				dev_close(wdev->netdev);

			guard(wiphy)(&rdev->wiphy);

			cfg80211_remove_virtual_intf(rdev, wdev);
		}
	}
}

void cfg80211_close_dependents(struct cfg80211_registered_device *rdev,
			       struct wireless_dev *wdev)
{
	ASSERT_RTNL();

	if (wdev->iftype != NL80211_IFTYPE_NAN)
		return;

	/* Close all NAN DATA interfaces */
	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
		if (wdev->iftype == NL80211_IFTYPE_NAN_DATA)
			dev_close(wdev->netdev);
	}
}

static void cfg80211_destroy_iface_wk(struct work_struct *work)
{
	struct cfg80211_registered_device *rdev;

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

	rtnl_lock();
	cfg80211_destroy_ifaces(rdev);
	rtnl_unlock();
}

static void cfg80211_sched_scan_stop_wk(struct wiphy *wiphy,
					struct wiphy_work *work)
{
	struct cfg80211_registered_device *rdev;
	struct cfg80211_sched_scan_request *req, *tmp;

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

	list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
		if (req->nl_owner_dead)
			cfg80211_stop_sched_scan_req(rdev, req, false);
	}
}

static void cfg80211_propagate_radar_detect_wk(struct work_struct *work)
{
	struct cfg80211_registered_device *rdev;

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

	rtnl_lock();

	regulatory_propagate_dfs_state(&rdev->wiphy, &rdev->radar_chandef,
				       NL80211_DFS_UNAVAILABLE,
				       NL80211_RADAR_DETECTED);

	rtnl_unlock();
}

static void cfg80211_propagate_cac_done_wk(struct work_struct *work)
{
	struct cfg80211_registered_device *rdev;

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

	rtnl_lock();

	regulatory_propagate_dfs_state(&rdev->wiphy, &rdev->cac_done_chandef,
				       NL80211_DFS_AVAILABLE,
				       NL80211_RADAR_CAC_FINISHED);

	rtnl_unlock();
}

static void cfg80211_wiphy_work(struct work_struct *work)
{
	struct cfg80211_registered_device *rdev;
	struct wiphy_work *wk;

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

	trace_wiphy_work_worker_start(&rdev->wiphy);

	guard(wiphy)(&rdev->wiphy);
	if (rdev->suspended)
		return;

	spin_lock_irq(&rdev->wiphy_work_lock);
	wk = list_first_entry_or_null(&rdev->wiphy_work_list,
				      struct wiphy_work, entry);
	if (wk) {
		list_del_init(&wk->entry);
		if (!list_empty(&rdev->wiphy_work_list))
			queue_work(system_dfl_wq, work);
		spin_unlock_irq(&rdev->wiphy_work_lock);

		trace_wiphy_work_run(&rdev->wiphy, wk);
		wk->func(&rdev->wiphy, wk);
	} else {
		spin_unlock_irq(&rdev->wiphy_work_lock);
	}
}

/* exported functions */

struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
			   const char *requested_name)
{
	static atomic_t wiphy_counter = ATOMIC_INIT(0);

	struct cfg80211_registered_device *rdev;
	int alloc_size;

	WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
	WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
	WARN_ON(ops->connect && !ops->disconnect);
	WARN_ON(ops->join_ibss && !ops->leave_ibss);
	WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf);
	WARN_ON(ops->add_station && !ops->del_station);
	WARN_ON(ops->add_mpath && !ops->del_mpath);
	WARN_ON(ops->join_mesh && !ops->leave_mesh);
	WARN_ON(ops->start_p2p_device && !ops->stop_p2p_device);
	WARN_ON(ops->start_ap && !ops->stop_ap);
	WARN_ON(ops->join_ocb && !ops->leave_ocb);
	WARN_ON(ops->suspend && !ops->resume);
	WARN_ON(ops->sched_scan_start && !ops->sched_scan_stop);
	WARN_ON(ops->remain_on_channel && !ops->cancel_remain_on_channel);
	WARN_ON(ops->tdls_channel_switch && !ops->tdls_cancel_channel_switch);
	WARN_ON(ops->add_tx_ts && !ops->del_tx_ts);

	alloc_size = sizeof(*rdev) + sizeof_priv;

	rdev = kzalloc(alloc_size, GFP_KERNEL);
	if (!rdev)
		return NULL;

	rdev->ops = ops;

	rdev->wiphy_idx = atomic_inc_return(&wiphy_counter);

	if (unlikely(rdev->wiphy_idx < 0)) {
		/* ugh, wrapped! */
		atomic_dec(&wiphy_counter);
		kfree(rdev);
		return NULL;
	}

	/* atomic_inc_return makes it start at 1, make it start at 0 */
	rdev->wiphy_idx--;

	/* give it a proper name */
	if (requested_name && requested_name[0]) {
		int rv;

		rtnl_lock();
		rv = cfg80211_dev_check_name(rdev, requested_name);

		if (rv < 0) {
			rtnl_unlock();
			goto use_default_name;
		}

		rv = dev_set_name(&rdev->wiphy.dev, "%s", requested_name);
		rtnl_unlock();
		if (rv)
			goto use_default_name;
	} else {
		int rv;

use_default_name:
		/* NOTE:  This is *probably* safe w/out holding rtnl because of
		 * the restrictions on phy names.  Probably this call could
		 * fail if some other part of the kernel (re)named a device
		 * phyX.  But, might should add some locking and check return
		 * value, and use a different name if this one exists?
		 */
		rv = dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
		if (rv < 0) {
			kfree(rdev);
			return NULL;
		}
	}

	mutex_init(&rdev->wiphy.mtx);
	INIT_LIST_HEAD(&rdev->wiphy.wdev_list);
	INIT_LIST_HEAD(&rdev->beacon_registrations);
	spin_lock_init(&rdev->beacon_registrations_lock);
	spin_lock_init(&rdev->bss_lock);
	INIT_LIST_HEAD(&rdev->bss_list);
	INIT_LIST_HEAD(&rdev->sched_scan_req_list);
	wiphy_work_init(&rdev->scan_done_wk, __cfg80211_scan_done);
	INIT_DELAYED_WORK(&rdev->dfs_update_channels_wk,
			  cfg80211_dfs_channels_update_work);
#ifdef CONFIG_CFG80211_WEXT
	rdev->wiphy.wext = &cfg80211_wext_handler;
#endif

	device_initialize(&rdev->wiphy.dev);
	rdev->wiphy.dev.class = &ieee80211_class;
	rdev->wiphy.dev.platform_data = rdev;
	device_enable_async_suspend(&rdev->wiphy.dev);

	INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
	wiphy_work_init(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
	INIT_WORK(&rdev->sched_scan_res_wk, cfg80211_sched_scan_results_wk);
	wiphy_work_init(&rdev->reg_check_chans_wk, reg_leave_invalid_chans_wk);
	INIT_WORK(&rdev->reg_leave_nan_wk, reg_leave_invalid_nan_wk);
	INIT_WORK(&rdev->propagate_radar_detect_wk,
		  cfg80211_propagate_radar_detect_wk);
	INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
	INIT_WORK(&rdev->mgmt_registrations_update_wk,
		  cfg80211_mgmt_registrations_update_wk);
	spin_lock_init(&rdev->mgmt_registrations_lock);
	INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work);
	INIT_LIST_HEAD(&rdev->wiphy_work_list);
	spin_lock_init(&rdev->wiphy_work_lock);

#ifdef CONFIG_CFG80211_DEFAULT_PS
	rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
#endif

	wiphy_net_set(&rdev->wiphy, &init_net);

	rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block;
	rdev->wiphy.rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev),
					  &rdev->wiphy.dev, RFKILL_TYPE_WLAN,
					  &rdev->rfkill_ops, rdev);

	if (!rdev->wiphy.rfkill) {
		wiphy_free(&rdev->wiphy);
		return NULL;
	}

	INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work);
	INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
	INIT_WORK(&rdev->event_work, cfg80211_event_work);
	INIT_WORK(&rdev->background_cac_abort_wk,
		  cfg80211_background_cac_abort_wk);
	INIT_DELAYED_WORK(&rdev->background_cac_done_wk,
			  cfg80211_background_cac_done_wk);

	init_waitqueue_head(&rdev->dev_wait);

	/*
	 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
	 * Fragmentation and RTS threshold are disabled by default with the
	 * special -1 value.
	 */
	rdev->wiphy.retry_short = 7;
	rdev->wiphy.retry_long = 4;
	rdev->wiphy.frag_threshold = (u32) -1;
	rdev->wiphy.rts_threshold = (u32) -1;
	rdev->wiphy.coverage_class = 0;

	rdev->wiphy.max_num_csa_counters = 1;

	rdev->wiphy.max_sched_scan_plans = 1;
	rdev->wiphy.max_sched_scan_plan_interval = U32_MAX;

	return &rdev->wiphy;
}
EXPORT_SYMBOL(wiphy_new_nm);

static
int wiphy_verify_iface_combinations(struct wiphy *wiphy,
				    const struct ieee80211_iface_combination *iface_comb,
				    int n_iface_comb,
				    bool combined_radio)
{
	const struct ieee80211_iface_combination *c;
	int i, j;

	for (i = 0; i < n_iface_comb; i++) {
		u32 cnt = 0;
		u16 all_iftypes = 0;

		c = &iface_comb[i];

		/*
		 * Combinations with just one interface aren't real,
		 * however we make an exception for DFS.
		 */
		if (WARN_ON((c->max_interfaces < 2) && !c->radar_detect_widths))
			return -EINVAL;

		/* Need at least one channel */
		if (WARN_ON(!c->num_different_channels))
			return -EINVAL;

		/* DFS only works on one channel. Avoid this check
		 * for multi-radio global combination, since it hold
		 * the capabilities of all radio combinations.
		 */
		if (!combined_radio &&
		    WARN_ON(c->radar_detect_widths &&
			    c->num_different_channels > 1))
			return -EINVAL;

		if (WARN_ON(!c->n_limits))
			return -EINVAL;

		for (j = 0; j < c->n_limits; j++) {
			u16 types = c->limits[j].types;

			/* interface types shouldn't overlap */
			if (WARN_ON(types & all_iftypes))
				return -EINVAL;
			all_iftypes |= types;

			if (WARN_ON(!c->limits[j].max))
				return -EINVAL;

			/* Shouldn't list software iftypes in combinations! */
			if (WARN_ON(wiphy->software_iftypes & types))
				return -EINVAL;

			/* Only a single P2P_DEVICE can be allowed, avoid this
			 * check for multi-radio global combination, since it
			 * hold the capabilities of all radio combinations.
			 */
			if (!combined_radio &&
			    WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
				    c->limits[j].max > 1))
				return -EINVAL;

			/* Only a single NAN can be allowed */
			if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
				    c->limits[j].max > 1))
				return -EINVAL;

			/*
			 * This isn't well-defined right now. If you have an
			 * IBSS interface, then its beacon interval may change
			 * by joining other networks, and nothing prevents it
			 * from doing that.
			 * So technically we probably shouldn't even allow AP
			 * and IBSS in the same interface, but it seems that
			 * some drivers support that, possibly only with fixed
			 * beacon intervals for IBSS.
			 */
			if (WARN_ON(types & BIT(NL80211_IFTYPE_ADHOC) &&
				    c->beacon_int_min_gcd)) {
				return -EINVAL;
			}

			cnt += c->limits[j].max;
			/*
			 * Don't advertise an unsupported type
			 * in a combination.
			 */
			if (WARN_ON((wiphy->interface_modes & types) != types))
				return -EINVAL;
		}

		if (WARN_ON(all_iftypes & BIT(NL80211_IFTYPE_WDS)))
			return -EINVAL;

		/* You can't even choose that many! */
		if (WARN_ON(cnt < c->max_interfaces))
			return -EINVAL;
	}

	return 0;
}

static int wiphy_verify_combinations(struct wiphy *wiphy)
{
	int i, ret;
	bool combined_radio = false;

	if (wiphy->n_radio) {
		for (i = 0; i < wiphy->n_radio; i++) {
			const struct wiphy_radio *radio = &wiphy->radio[i];

			ret = wiphy_verify_iface_combinations(wiphy,
							      radio->iface_combinations,
							      radio->n_iface_combinations,
							      false);
			if (ret)
				return ret;
		}

		combined_radio = true;
	}

	ret = wiphy_verify_iface_combinations(wiphy,
					      wiphy->iface_combinations,
					      wiphy->n_iface_combinations,
					      combined_radio);

	return ret;
}

static bool wiphy_cipher_suites_valid(const struct wiphy *wiphy)
{
	int i, j;

	if (wiphy->n_cipher_suites && !wiphy->cipher_suites)
		return false;

	for (i = 0; i < wiphy->n_cipher_suites; i++) {
		for (j = 0; j < i; j++) {
			if (wiphy->cipher_suites[i] ==
			    wiphy->cipher_suites[j])
				return false;
		}
	}

	return true;
}

int wiphy_register(struct wiphy *wiphy)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	int res;
	enum nl80211_band band;
	struct ieee80211_supported_band *sband;
	bool have_band = false;
	int i;
	u16 ifmodes = wiphy->interface_modes;

#ifdef CONFIG_PM
	if (WARN_ON(wiphy->wowlan &&
		    (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
		    !(wiphy->wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
		return -EINVAL;
	if (WARN_ON(wiphy->wowlan &&
		    !wiphy->wowlan->flags && !wiphy->wowlan->n_patterns &&
		    !wiphy->wowlan->tcp))
		return -EINVAL;
#endif
	if (WARN_ON((wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) &&
		    (!rdev->ops->tdls_channel_switch ||
		     !rdev->ops->tdls_cancel_channel_switch)))
		return -EINVAL;
	if (WARN_ON((wiphy->interface_modes & BIT(NL80211_IFTYPE_PD)) &&
		    (!rdev->ops->start_pd || !rdev->ops->stop_pd)))
		return -EINVAL;

	if (WARN_ON((wiphy->interface_modes & BIT(NL80211_IFTYPE_NAN)) &&
		    (!rdev->ops->start_nan || !rdev->ops->stop_nan ||
		     !rdev->ops->add_nan_func || !rdev->ops->del_nan_func ||
		     !(wiphy->nan_supported_bands & BIT(NL80211_BAND_2GHZ)))))
		return -EINVAL;

	if (WARN_ON((wiphy->interface_modes & BIT(NL80211_IFTYPE_NAN_DATA)) &&
		    (!wiphy->nan_capa.phy.ht.ht_supported || wiphy->n_radio > 1)))
		return -EINVAL;

	if (WARN_ON(wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)))
		return -EINVAL;

	if (WARN_ON(wiphy->pmsr_capa && !wiphy->pmsr_capa->ftm.supported))
		return -EINVAL;

	if (wiphy->pmsr_capa && wiphy->pmsr_capa->ftm.supported) {
		if (WARN_ON(!wiphy->pmsr_capa->ftm.asap &&
			    !wiphy->pmsr_capa->ftm.non_asap))
			return -EINVAL;
		if (WARN_ON(!wiphy->pmsr_capa->ftm.preambles ||
			    !wiphy->pmsr_capa->ftm.bandwidths))
			return -EINVAL;
		if (WARN_ON(wiphy->pmsr_capa->ftm.preambles &
				~(BIT(NL80211_PREAMBLE_LEGACY) |
				  BIT(NL80211_PREAMBLE_HT) |
				  BIT(NL80211_PREAMBLE_VHT) |
				  BIT(NL80211_PREAMBLE_HE) |
				  BIT(NL80211_PREAMBLE_DMG))))
			return -EINVAL;
		if (WARN_ON((wiphy->pmsr_capa->ftm.trigger_based ||
			     wiphy->pmsr_capa->ftm.non_trigger_based) &&
			    !(wiphy->pmsr_capa->ftm.preambles &
			      BIT(NL80211_PREAMBLE_HE))))
			return -EINVAL;
		if (WARN_ON(wiphy->pmsr_capa->ftm.bandwidths &
				~(BIT(NL80211_CHAN_WIDTH_20_NOHT) |
				  BIT(NL80211_CHAN_WIDTH_20) |
				  BIT(NL80211_CHAN_WIDTH_40) |
				  BIT(NL80211_CHAN_WIDTH_80) |
				  BIT(NL80211_CHAN_WIDTH_80P80) |
				  BIT(NL80211_CHAN_WIDTH_160) |
				  BIT(NL80211_CHAN_WIDTH_320))))
			return -EINVAL;
	}

	if (WARN_ON((wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) &&
		    (wiphy->regulatory_flags &
					(REGULATORY_CUSTOM_REG |
					 REGULATORY_STRICT_REG |
					 REGULATORY_COUNTRY_IE_FOLLOW_POWER |
					 REGULATORY_COUNTRY_IE_IGNORE))))
		return -EINVAL;

	if (WARN_ON(wiphy->coalesce &&
		    (!wiphy->coalesce->n_rules ||
		     !wiphy->coalesce->n_patterns) &&
		    (!wiphy->coalesce->pattern_min_len ||
		     wiphy->coalesce->pattern_min_len >
			wiphy->coalesce->pattern_max_len)))
		return -EINVAL;

	if (WARN_ON(wiphy->ap_sme_capa &&
		    !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME)))
		return -EINVAL;

	if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
		return -EINVAL;

	if (WARN_ON(wiphy->addresses &&
		    !is_zero_ether_addr(wiphy->perm_addr) &&
		    memcmp(wiphy->perm_addr, wiphy->addresses[0].addr,
			   ETH_ALEN)))
		return -EINVAL;

	if (WARN_ON(wiphy->max_acl_mac_addrs &&
		    (!(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME) ||
		     !rdev->ops->set_mac_acl)))
		return -EINVAL;

	/* assure only valid behaviours are flagged by driver
	 * hence subtract 2 as bit 0 is invalid.
	 */
	if (WARN_ON(wiphy->bss_select_support &&
		    (wiphy->bss_select_support & ~(BIT(__NL80211_BSS_SELECT_ATTR_AFTER_LAST) - 2))))
		return -EINVAL;

	if (WARN_ON(wiphy_ext_feature_isset(&rdev->wiphy,
					    NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X) &&
		    (!rdev->ops->set_pmk || !rdev->ops->del_pmk)))
		return -EINVAL;

	if (WARN_ON(!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
		    rdev->ops->update_connect_params))
		return -EINVAL;

	if (wiphy->addresses)
		memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);

	/* sanity check ifmodes */
	WARN_ON(!ifmodes);
	ifmodes &= ((1 << NUM_NL80211_IFTYPES) - 1) & ~1;
	if (WARN_ON(ifmodes != wiphy->interface_modes))
		wiphy->interface_modes = ifmodes;

	res = wiphy_verify_combinations(wiphy);
	if (res)
		return res;

	if (!wiphy_cipher_suites_valid(wiphy))
		return -EINVAL;

	/* sanity check supported bands/channels */
	for (band = 0; band < NUM_NL80211_BANDS; band++) {
		const struct ieee80211_sband_iftype_data *iftd;
		u16 types = 0;
		bool have_he = false;

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

		sband->band = band;
		if (WARN_ON(!sband->n_channels))
			return -EINVAL;
		/*
		 * on 60GHz or sub-1Ghz band, there are no legacy rates, so
		 * n_bitrates is 0
		 */
		if (WARN_ON((band != NL80211_BAND_60GHZ &&
			     band != NL80211_BAND_S1GHZ) &&
			    !sband->n_bitrates))
			return -EINVAL;

		if (WARN_ON(band == NL80211_BAND_6GHZ &&
			    (sband->ht_cap.ht_supported ||
			     sband->vht_cap.vht_supported)))
			return -EINVAL;

		/*
		 * Since cfg80211_disable_40mhz_24ghz is global, we can
		 * modify the sband's ht data even if the driver uses a
		 * global structure for that.
		 */
		if (cfg80211_disable_40mhz_24ghz &&
		    band == NL80211_BAND_2GHZ &&
		    sband->ht_cap.ht_supported) {
			sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
			sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
		}

		/*
		 * Since we use a u32 for rate bitmaps in
		 * ieee80211_get_response_rate, we cannot
		 * have more than 32 legacy rates.
		 */
		if (WARN_ON(sband->n_bitrates > 32))
			return -EINVAL;

		for (i = 0; i < sband->n_channels; i++) {
			sband->channels[i].orig_flags =
				sband->channels[i].flags;
			sband->channels[i].orig_mag = INT_MAX;
			sband->channels[i].orig_mpwr =
				sband->channels[i].max_power;
			sband->channels[i].band = band;

			if (WARN_ON(sband->channels[i].freq_offset >= 1000))
				return -EINVAL;
		}

		for_each_sband_iftype_data(sband, i, iftd) {
			bool has_ap, has_non_ap;
			u32 ap_bits = BIT(NL80211_IFTYPE_AP) |
				      BIT(NL80211_IFTYPE_P2P_GO);

			if (WARN_ON(!iftd->types_mask))
				return -EINVAL;
			if (WARN_ON(types & iftd->types_mask))
				return -EINVAL;

			/* at least one piece of information must be present */
			if (WARN_ON(!iftd->he_cap.has_he))
				return -EINVAL;

			types |= iftd->types_mask;

			if (i == 0)
				have_he = iftd->he_cap.has_he;
			else
				have_he = have_he &&
					  iftd->he_cap.has_he;

			has_ap = iftd->types_mask & ap_bits;
			has_non_ap = iftd->types_mask & ~ap_bits;

			/*
			 * For EHT 20 MHz STA, the capabilities format differs
			 * but to simplify, don't check 20 MHz but rather check
			 * only if AP and non-AP were mentioned at the same time,
			 * reject if so.
			 */
			if (WARN_ON(iftd->eht_cap.has_eht &&
				    has_ap && has_non_ap))
				return -EINVAL;
		}

		if (WARN_ON(!have_he && band == NL80211_BAND_6GHZ))
			return -EINVAL;

		have_band = true;
	}

	if (!have_band) {
		WARN_ON(1);
		return -EINVAL;
	}

	for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
		/*
		 * Validate we have a policy (can be explicitly set to
		 * VENDOR_CMD_RAW_DATA which is non-NULL) and also that
		 * we have at least one of doit/dumpit.
		 */
		if (WARN_ON(!rdev->wiphy.vendor_commands[i].policy))
			return -EINVAL;
		if (WARN_ON(!rdev->wiphy.vendor_commands[i].doit &&
			    !rdev->wiphy.vendor_commands[i].dumpit))
			return -EINVAL;
	}

#ifdef CONFIG_PM
	if (WARN_ON(rdev->wiphy.wowlan && rdev->wiphy.wowlan->n_patterns &&
		    (!rdev->wiphy.wowlan->pattern_min_len ||
		     rdev->wiphy.wowlan->pattern_min_len >
				rdev->wiphy.wowlan->pattern_max_len)))
		return -EINVAL;
#endif

	if (!wiphy->max_num_akm_suites)
		wiphy->max_num_akm_suites = NL80211_MAX_NR_AKM_SUITES;
	else if (wiphy->max_num_akm_suites < NL80211_MAX_NR_AKM_SUITES ||
		 wiphy->max_num_akm_suites > CFG80211_MAX_NUM_AKM_SUITES)
		return -EINVAL;

	/* Allocate radio configuration space for multi-radio wiphy */
	if (wiphy->n_radio > 0) {
		int idx;

		wiphy->radio_cfg = kzalloc_objs(*wiphy->radio_cfg,
						wiphy->n_radio);
		if (!wiphy->radio_cfg)
			return -ENOMEM;
		/*
		 * Initialize wiphy radio parameters to IEEE 802.11
		 * MIB default values. RTS threshold is disabled by
		 * default with the special -1 value.
		 */
		for (idx = 0; idx < wiphy->n_radio; idx++)
			wiphy->radio_cfg[idx].rts_threshold = (u32)-1;
	}

	/* check and set up bitrates */
	ieee80211_set_bitrate_flags(wiphy);

	rdev->wiphy.features |= NL80211_FEATURE_SCAN_FLUSH;

	if (rdev->wiphy.bss_param_support & WIPHY_BSS_PARAM_P2P_CTWINDOW)
		rdev->wiphy.features |= NL80211_FEATURE_P2P_GO_CTWIN;
	else if (rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)
		rdev->wiphy.bss_param_support |= WIPHY_BSS_PARAM_P2P_CTWINDOW;
	if (rdev->wiphy.bss_param_support & WIPHY_BSS_PARAM_P2P_OPPPS)
		rdev->wiphy.features |= NL80211_FEATURE_P2P_GO_OPPPS;
	else if (rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)
		rdev->wiphy.bss_param_support |= WIPHY_BSS_PARAM_P2P_OPPPS;

	rtnl_lock();
	wiphy_lock(&rdev->wiphy);
	res = device_add(&rdev->wiphy.dev);
	if (res) {
		wiphy_unlock(&rdev->wiphy);
		rtnl_unlock();
		return res;
	}

	list_add_rcu(&rdev->list, &cfg80211_rdev_list);
	cfg80211_rdev_list_generation++;

	/* add to debugfs */
	rdev->wiphy.debugfsdir = debugfs_create_dir(wiphy_name(&rdev->wiphy),
						    ieee80211_debugfs_dir);
	if (wiphy->n_radio > 0) {
		int idx;
		char radio_name[RADIO_DEBUGFSDIR_MAX_LEN];

		for (idx = 0; idx < wiphy->n_radio; idx++) {
			scnprintf(radio_name, sizeof(radio_name), "radio%d",
				  idx);
			wiphy->radio_cfg[idx].radio_debugfsdir =
				debugfs_create_dir(radio_name,
						   rdev->wiphy.debugfsdir);
		}
	}

	cfg80211_debugfs_rdev_add(rdev);
	nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
	wiphy_unlock(&rdev->wiphy);

	/* set up regulatory info */
	wiphy_regulatory_register(wiphy);

	if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
		struct regulatory_request request = {
			.wiphy_idx = get_wiphy_idx(wiphy),
			.initiator = NL80211_REGDOM_SET_BY_DRIVER,
			.alpha2[0] = '9',
			.alpha2[1] = '9',
		};

		nl80211_send_reg_change_event(&request);
	}

	/* Check that nobody globally advertises any capabilities they do not
	 * advertise on all possible interface types.
	 */
	if (wiphy->extended_capabilities_len &&
	    wiphy->num_iftype_ext_capab &&
	    wiphy->iftype_ext_capab) {
		u8 supported_on_all, j;
		const struct wiphy_iftype_ext_capab *capab;

		capab = wiphy->iftype_ext_capab;
		for (j = 0; j < wiphy->extended_capabilities_len; j++) {
			if (capab[0].extended_capabilities_len > j)
				supported_on_all =
					capab[0].extended_capabilities[j];
			else
				supported_on_all = 0x00;
			for (i = 1; i < wiphy->num_iftype_ext_capab; i++) {
				if (j >= capab[i].extended_capabilities_len) {
					supported_on_all = 0x00;
					break;
				}
				supported_on_all &=
					capab[i].extended_capabilities[j];
			}
			if (WARN_ON(wiphy->extended_capabilities[j] &
				    ~supported_on_all))
				break;
		}
	}

	rdev->wiphy.registered = true;
	rtnl_unlock();

	res = rfkill_register(rdev->wiphy.rfkill);
	if (res) {
		rfkill_destroy(rdev->wiphy.rfkill);
		rdev->wiphy.rfkill = NULL;
		wiphy_unregister(&rdev->wiphy);
		return res;
	}

	return 0;
}
EXPORT_SYMBOL(wiphy_register);

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

	if (!rdev->ops->rfkill_poll)
		return;
	rdev->rfkill_ops.poll = cfg80211_rfkill_poll;
	rfkill_resume_polling(wiphy->rfkill);
}
EXPORT_SYMBOL(wiphy_rfkill_start_polling);

void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev,
				  struct wiphy_work *end)
{
	unsigned int runaway_limit = 100;
	unsigned long flags;

	lockdep_assert_held(&rdev->wiphy.mtx);

	spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
	while (!list_empty(&rdev->wiphy_work_list)) {
		struct wiphy_work *wk;

		wk = list_first_entry(&rdev->wiphy_work_list,
				      struct wiphy_work, entry);
		list_del_init(&wk->entry);
		spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);

		trace_wiphy_work_run(&rdev->wiphy, wk);
		wk->func(&rdev->wiphy, wk);

		spin_lock_irqsave(&rdev->wiphy_work_lock, flags);

		if (wk == end)
			break;

		if (WARN_ON(--runaway_limit == 0))
			INIT_LIST_HEAD(&rdev->wiphy_work_list);
	}
	spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
}

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

	wait_event(rdev->dev_wait, ({
		int __count;
		wiphy_lock(&rdev->wiphy);
		__count = rdev->opencount;
		wiphy_unlock(&rdev->wiphy);
		__count == 0; }));

	if (rdev->wiphy.rfkill)
		rfkill_unregister(rdev->wiphy.rfkill);

	rtnl_lock();
	wiphy_lock(&rdev->wiphy);
	nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
	rdev->wiphy.registered = false;

	WARN_ON(!list_empty(&rdev->wiphy.wdev_list));

	/*
	 * First remove the hardware from everywhere, this makes
	 * it impossible to find from userspace.
	 */
	debugfs_remove_recursive(rdev->wiphy.debugfsdir);
	list_del_rcu(&rdev->list);
	synchronize_rcu();

	/*
	 * If this device got a regulatory hint tell core its
	 * free to listen now to a new shiny device regulatory hint
	 */
	wiphy_regulatory_deregister(wiphy);

	cfg80211_rdev_list_generation++;
	device_del(&rdev->wiphy.dev);

#ifdef CONFIG_PM
	if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
		rdev_set_wakeup(rdev, false);
#endif

	/* surely nothing is reachable now, clean up work */
	cfg80211_process_wiphy_works(rdev, NULL);
	wiphy_unlock(&rdev->wiphy);
	rtnl_unlock();

	/* this has nothing to do now but make sure it's gone */
	cancel_work_sync(&rdev->wiphy_work);

	cancel_work_sync(&rdev->sched_scan_res_wk);
	cancel_work_sync(&rdev->rfkill_block);
	cancel_work_sync(&rdev->conn_work);
	flush_work(&rdev->event_work);
	cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
	cancel_delayed_work_sync(&rdev->background_cac_done_wk);
	flush_work(&rdev->destroy_work);
	flush_work(&rdev->reg_leave_nan_wk);
	flush_work(&rdev->propagate_radar_detect_wk);
	flush_work(&rdev->propagate_cac_done_wk);
	flush_work(&rdev->mgmt_registrations_update_wk);
	flush_work(&rdev->background_cac_abort_wk);

	cfg80211_rdev_free_wowlan(rdev);
	cfg80211_free_coalesce(rdev->coalesce);
	rdev->coalesce = NULL;
}
EXPORT_SYMBOL(wiphy_unregister);

void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
{
	struct cfg80211_internal_bss *scan, *tmp;
	struct cfg80211_beacon_registration *reg, *treg;
	unsigned long flags;

	spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
	WARN_ON(!list_empty(&rdev->wiphy_work_list));
	spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
	cancel_work_sync(&rdev->wiphy_work);

	rfkill_destroy(rdev->wiphy.rfkill);
	list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) {
		list_del(&reg->list);
		kfree(reg);
	}
	list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
		cfg80211_put_bss(&rdev->wiphy, &scan->pub);
	mutex_destroy(&rdev->wiphy.mtx);

	/*
	 * The 'regd' can only be non-NULL if we never finished
	 * initializing the wiphy and thus never went through the
	 * unregister path - e.g. in failure scenarios. Thus, it
	 * cannot have been visible to anyone if non-NULL, so we
	 * can just free it here.
	 */
	kfree(rcu_dereference_raw(rdev->wiphy.regd));

	kfree(rdev);
}

void wiphy_free(struct wiphy *wiphy)
{
	kfree(wiphy->radio_cfg);
	put_device(&wiphy->dev);
}
EXPORT_SYMBOL(wiphy_free);

void wiphy_rfkill_set_hw_state_reason(struct wiphy *wiphy, bool blocked,
				      enum rfkill_hard_block_reasons reason)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);

	if (rfkill_set_hw_state_reason(wiphy->rfkill, blocked, reason))
		schedule_work(&rdev->rfkill_block);
}
EXPORT_SYMBOL(wiphy_rfkill_set_hw_state_reason);

static void _cfg80211_unregister_wdev(struct wireless_dev *wdev,
				      bool unregister_netdev)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_cqm_config *cqm_config;
	unsigned int link_id;

	ASSERT_RTNL();
	lockdep_assert_held(&rdev->wiphy.mtx);

	nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE);

	wdev->registered = false;

	if (wdev->netdev) {
		sysfs_remove_link(&wdev->netdev->dev.kobj, "phy80211");
		if (unregister_netdev)
			unregister_netdevice(wdev->netdev);
	}

	list_del_rcu(&wdev->list);
	synchronize_net();
	rdev->devlist_generation++;
	wiphy_work_cancel(wdev->wiphy, &wdev->disconnect_wk);

	cfg80211_mlme_purge_registrations(wdev);

	switch (wdev->iftype) {
	case NL80211_IFTYPE_P2P_DEVICE:
		cfg80211_stop_p2p_device(rdev, wdev);
		break;
	case NL80211_IFTYPE_NAN:
		cfg80211_stop_nan(rdev, wdev);
		break;
	case NL80211_IFTYPE_PD:
		cfg80211_stop_pd(rdev, wdev);
		break;
	default:
		break;
	}

#ifdef CONFIG_CFG80211_WEXT
	kfree_sensitive(wdev->wext.keys);
	wdev->wext.keys = NULL;
#endif
	wiphy_work_cancel(wdev->wiphy, &wdev->cqm_rssi_work);
	/* deleted from the list, so can't be found from nl80211 any more */
	cqm_config = rcu_access_pointer(wdev->cqm_config);
	kfree_rcu(cqm_config, rcu_head);
	RCU_INIT_POINTER(wdev->cqm_config, NULL);

	/*
	 * Ensure that all events have been processed and
	 * freed.
	 */
	cfg80211_process_wdev_events(wdev);

	if (wdev->iftype == NL80211_IFTYPE_STATION ||
	    wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) {
		for (link_id = 0; link_id < ARRAY_SIZE(wdev->links); link_id++) {
			struct cfg80211_internal_bss *curbss;

			curbss = wdev->links[link_id].client.current_bss;

			if (WARN_ON(curbss)) {
				cfg80211_unhold_bss(curbss);
				cfg80211_put_bss(wdev->wiphy, &curbss->pub);
				wdev->links[link_id].client.current_bss = NULL;
			}
		}
	}

	wdev->connected = false;
}

void cfg80211_unregister_wdev(struct wireless_dev *wdev)
{
	_cfg80211_unregister_wdev(wdev, true);
}
EXPORT_SYMBOL(cfg80211_unregister_wdev);

static const struct device_type wiphy_type = {
	.name	= "wlan",
};

void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
			       enum nl80211_iftype iftype, int num)
{
	lockdep_assert_held(&rdev->wiphy.mtx);

	rdev->num_running_ifaces += num;
	if (iftype == NL80211_IFTYPE_MONITOR)
		rdev->num_running_monitor_ifaces += num;
}

void cfg80211_leave_locked(struct cfg80211_registered_device *rdev,
			   struct wireless_dev *wdev, int link_id)
{
	struct net_device *dev = wdev->netdev;
	struct cfg80211_sched_scan_request *pos, *tmp;

	lockdep_assert_held(&rdev->wiphy.mtx);

	cfg80211_pmsr_wdev_down(wdev);

	cfg80211_stop_radar_detection(wdev);
	cfg80211_stop_background_radar_detection(wdev);

	switch (wdev->iftype) {
	case NL80211_IFTYPE_ADHOC:
		cfg80211_leave_ibss(rdev, dev, true);
		break;
	case NL80211_IFTYPE_P2P_CLIENT:
	case NL80211_IFTYPE_STATION:
		list_for_each_entry_safe(pos, tmp, &rdev->sched_scan_req_list,
					 list) {
			if (dev == pos->dev)
				cfg80211_stop_sched_scan_req(rdev, pos, false);
		}

#ifdef CONFIG_CFG80211_WEXT
		kfree(wdev->wext.ie);
		wdev->wext.ie = NULL;
		wdev->wext.ie_len = 0;
		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
#endif
		cfg80211_disconnect(rdev, dev,
				    WLAN_REASON_DEAUTH_LEAVING, true);
		break;
	case NL80211_IFTYPE_MESH_POINT:
		cfg80211_leave_mesh(rdev, dev);
		break;
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_P2P_GO:
		cfg80211_stop_ap(rdev, dev, link_id, true);
		break;
	case NL80211_IFTYPE_OCB:
		cfg80211_leave_ocb(rdev, dev);
		break;
	case NL80211_IFTYPE_P2P_DEVICE:
		cfg80211_stop_p2p_device(rdev, wdev);
		break;
	case NL80211_IFTYPE_NAN:
		cfg80211_stop_nan(rdev, wdev);
		break;
	case NL80211_IFTYPE_PD:
		cfg80211_stop_pd(rdev, wdev);
		break;
	case NL80211_IFTYPE_AP_VLAN:
	case NL80211_IFTYPE_MONITOR:
	case NL80211_IFTYPE_NAN_DATA:
		/* nothing to do */
		break;
	case NL80211_IFTYPE_UNSPECIFIED:
	case NL80211_IFTYPE_WDS:
	case NUM_NL80211_IFTYPES:
		/* invalid */
		break;
	}
}

void cfg80211_leave(struct cfg80211_registered_device *rdev,
		    struct wireless_dev *wdev, int link_id)
{
	ASSERT_RTNL();

	/* NAN_DATA interfaces must be closed before stopping NAN */
	cfg80211_close_dependents(rdev, wdev);

	guard(wiphy)(&rdev->wiphy);

	cfg80211_leave_locked(rdev, wdev, link_id);
}

void cfg80211_stop_link(struct wiphy *wiphy, struct wireless_dev *wdev,
			int link_id, gfp_t gfp)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct cfg80211_event *ev;
	unsigned long flags;

	/* Only AP/GO interfaces may have a specific link_id */
	if (WARN_ON_ONCE(link_id != -1 &&
			 wdev->iftype != NL80211_IFTYPE_AP &&
			 wdev->iftype != NL80211_IFTYPE_P2P_GO))
		link_id = -1;

	trace_cfg80211_stop_link(wiphy, wdev, link_id);

	if (wdev->iftype == NL80211_IFTYPE_NAN)
		return;

	ev = kzalloc_obj(*ev, gfp);
	if (!ev)
		return;

	ev->type = EVENT_STOPPED;
	ev->link_id = link_id;

	spin_lock_irqsave(&wdev->event_lock, flags);
	list_add_tail(&ev->list, &wdev->event_list);
	spin_unlock_irqrestore(&wdev->event_lock, flags);
	queue_work(cfg80211_wq, &rdev->event_work);
}
EXPORT_SYMBOL(cfg80211_stop_link);

void cfg80211_init_wdev(struct wireless_dev *wdev)
{
	INIT_LIST_HEAD(&wdev->event_list);
	spin_lock_init(&wdev->event_lock);
	INIT_LIST_HEAD(&wdev->mgmt_registrations);
	INIT_LIST_HEAD(&wdev->pmsr_list);
	spin_lock_init(&wdev->pmsr_lock);
	wiphy_work_init(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);

#ifdef CONFIG_CFG80211_WEXT
	wdev->wext.default_key = -1;
	wdev->wext.default_mgmt_key = -1;
	wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
#endif

	wiphy_work_init(&wdev->cqm_rssi_work, cfg80211_cqm_rssi_notify_work);

	if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
		wdev->ps = true;
	else
		wdev->ps = false;
	/* allow mac80211 to determine the timeout */
	wdev->ps_timeout = -1;

	wdev->radio_mask = BIT(wdev->wiphy->n_radio) - 1;

	if ((wdev->iftype == NL80211_IFTYPE_STATION ||
	     wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
	     wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
		wdev->netdev->priv_flags |= IFF_DONT_BRIDGE;

	wiphy_work_init(&wdev->disconnect_wk, cfg80211_autodisconnect_wk);
}

void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
			    struct wireless_dev *wdev)
{
	ASSERT_RTNL();
	lockdep_assert_held(&rdev->wiphy.mtx);

	/*
	 * We get here also when the interface changes network namespaces,
	 * as it's registered into the new one, but we don't want it to
	 * change ID in that case. Checking if the ID is already assigned
	 * works, because 0 isn't considered a valid ID and the memory is
	 * 0-initialized.
	 */
	if (!wdev->identifier)
		wdev->identifier = ++rdev->wdev_id;
	list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
	rdev->devlist_generation++;
	wdev->registered = true;

	if (wdev->netdev &&
	    sysfs_create_link(&wdev->netdev->dev.kobj, &rdev->wiphy.dev.kobj,
			      "phy80211"))
		pr_err("failed to add phy80211 symlink to netdev!\n");

	nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
}

int cfg80211_register_netdevice(struct net_device *dev)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev;
	int ret;

	ASSERT_RTNL();

	if (WARN_ON(!wdev))
		return -EINVAL;

	rdev = wiphy_to_rdev(wdev->wiphy);

	lockdep_assert_held(&rdev->wiphy.mtx);

	/* we'll take care of this */
	wdev->registered = true;
	wdev->registering = true;
	ret = register_netdevice(dev);
	if (ret)
		goto out;

	cfg80211_register_wdev(rdev, wdev);
	ret = 0;
out:
	wdev->registering = false;
	if (ret)
		wdev->registered = false;
	return ret;
}
EXPORT_SYMBOL(cfg80211_register_netdevice);

static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
					 unsigned long state, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev;
	struct cfg80211_sched_scan_request *pos, *tmp;

	if (!wdev)
		return NOTIFY_DONE;

	rdev = wiphy_to_rdev(wdev->wiphy);

	WARN_ON(wdev->iftype == NL80211_IFTYPE_UNSPECIFIED);

	switch (state) {
	case NETDEV_POST_INIT:
		SET_NETDEV_DEVTYPE(dev, &wiphy_type);
		wdev->netdev = dev;
		/* can only change netns with wiphy */
		dev->netns_immutable = true;

		cfg80211_init_wdev(wdev);
		break;
	case NETDEV_REGISTER:
		if (!wdev->registered) {
			guard(wiphy)(&rdev->wiphy);

			cfg80211_register_wdev(rdev, wdev);
		}
		break;
	case NETDEV_UNREGISTER:
		/*
		 * It is possible to get NETDEV_UNREGISTER multiple times,
		 * so check wdev->registered.
		 */
		if (wdev->registered && !wdev->registering) {
			guard(wiphy)(&rdev->wiphy);

			_cfg80211_unregister_wdev(wdev, false);
		}
		break;
	case NETDEV_GOING_DOWN:
		cfg80211_leave(rdev, wdev, -1);
		scoped_guard(wiphy, &rdev->wiphy) {
			cfg80211_remove_links(wdev);
			/* since we just did cfg80211_leave() nothing to do there */
			wiphy_work_cancel(wdev->wiphy, &wdev->disconnect_wk);
		}
		break;
	case NETDEV_DOWN:
		wiphy_lock(&rdev->wiphy);
		cfg80211_update_iface_num(rdev, wdev->iftype, -1);
		if (rdev->scan_req && rdev->scan_req->req.wdev == wdev) {
			if (!rdev->scan_req->notified &&
			    (!rdev->int_scan_req ||
			     !rdev->int_scan_req->notified))
				rdev->scan_req->info.aborted = true;
			___cfg80211_scan_done(rdev, false);
		}

		list_for_each_entry_safe(pos, tmp,
					 &rdev->sched_scan_req_list, list) {
			if (WARN_ON(pos->dev == wdev->netdev))
				cfg80211_stop_sched_scan_req(rdev, pos, false);
		}

		rdev->opencount--;
		wiphy_unlock(&rdev->wiphy);
		wake_up(&rdev->dev_wait);
		break;
	case NETDEV_UP:
		wiphy_lock(&rdev->wiphy);
		cfg80211_update_iface_num(rdev, wdev->iftype, 1);
		switch (wdev->iftype) {
#ifdef CONFIG_CFG80211_WEXT
		case NL80211_IFTYPE_ADHOC:
			cfg80211_ibss_wext_join(rdev, wdev);
			break;
		case NL80211_IFTYPE_STATION:
			cfg80211_mgd_wext_connect(rdev, wdev);
			break;
#endif
#ifdef CONFIG_MAC80211_MESH
		case NL80211_IFTYPE_MESH_POINT:
			{
				/* backward compat code... */
				struct mesh_setup setup;
				memcpy(&setup, &default_mesh_setup,
						sizeof(setup));
				 /* back compat only needed for mesh_id */
				setup.mesh_id = wdev->u.mesh.id;
				setup.mesh_id_len = wdev->u.mesh.id_up_len;
				if (wdev->u.mesh.id_up_len)
					__cfg80211_join_mesh(rdev, dev,
							&setup,
							&default_mesh_config);
				break;
			}
#endif
		default:
			break;
		}
		rdev->opencount++;

		/*
		 * Configure power management to the driver here so that its
		 * correctly set also after interface type changes etc.
		 */
		if ((wdev->iftype == NL80211_IFTYPE_STATION ||
		     wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
		    rdev->ops->set_power_mgmt &&
		    rdev_set_power_mgmt(rdev, dev, wdev->ps,
					wdev->ps_timeout)) {
			/* assume this means it's off */
			wdev->ps = false;
		}
		wiphy_unlock(&rdev->wiphy);
		break;
	case NETDEV_PRE_UP:
		if (!cfg80211_iftype_allowed(wdev->wiphy, wdev->iftype,
					     wdev->use_4addr, 0))
			return notifier_from_errno(-EOPNOTSUPP);

		if (rfkill_blocked(rdev->wiphy.rfkill))
			return notifier_from_errno(-ERFKILL);

		/* NAN_DATA interfaces require a running NAN interface */
		if (wdev->iftype == NL80211_IFTYPE_NAN_DATA) {
			struct wireless_dev *iter;
			bool nan_started = false;

			list_for_each_entry(iter, &rdev->wiphy.wdev_list, list) {
				if (iter->iftype == NL80211_IFTYPE_NAN &&
				    wdev_running(iter)) {
					nan_started = true;
					break;
				}
			}

			if (!nan_started)
				return notifier_from_errno(-ENOLINK);
		}
		break;
	default:
		return NOTIFY_DONE;
	}

	wireless_nlevent_flush();

	return NOTIFY_OK;
}

static struct notifier_block cfg80211_netdev_notifier = {
	.notifier_call = cfg80211_netdev_notifier_call,
};

static void __net_exit cfg80211_pernet_exit(struct net *net)
{
	struct cfg80211_registered_device *rdev;

	rtnl_lock();
	for_each_rdev(rdev) {
		if (net_eq(wiphy_net(&rdev->wiphy), net))
			WARN_ON(__cfg80211_switch_netns(rdev, &init_net, true));
	}
	rtnl_unlock();
}

static struct pernet_operations cfg80211_pernet_ops = {
	.exit = cfg80211_pernet_exit,
};

void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	unsigned long flags;

	trace_wiphy_work_queue(wiphy, work);

	spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
	if (list_empty(&work->entry))
		list_add_tail(&work->entry, &rdev->wiphy_work_list);
	spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);

	queue_work(system_dfl_wq, &rdev->wiphy_work);
}
EXPORT_SYMBOL_GPL(wiphy_work_queue);

void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	unsigned long flags;

	lockdep_assert_held(&wiphy->mtx);

	trace_wiphy_work_cancel(wiphy, work);

	spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
	if (!list_empty(&work->entry))
		list_del_init(&work->entry);
	spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
}
EXPORT_SYMBOL_GPL(wiphy_work_cancel);

void wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *work)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	unsigned long flags;
	bool run;

	trace_wiphy_work_flush(wiphy, work);

	spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
	run = !work || !list_empty(&work->entry);
	spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);

	if (run)
		cfg80211_process_wiphy_works(rdev, work);
}
EXPORT_SYMBOL_GPL(wiphy_work_flush);

void wiphy_delayed_work_timer(struct timer_list *t)
{
	struct wiphy_delayed_work *dwork = timer_container_of(dwork, t, timer);

	wiphy_work_queue(dwork->wiphy, &dwork->work);
}
EXPORT_SYMBOL(wiphy_delayed_work_timer);

void wiphy_delayed_work_queue(struct wiphy *wiphy,
			      struct wiphy_delayed_work *dwork,
			      unsigned long delay)
{
	trace_wiphy_delayed_work_queue(wiphy, &dwork->work, delay);

	if (!delay) {
		timer_delete(&dwork->timer);
		wiphy_work_queue(wiphy, &dwork->work);
		return;
	}

	dwork->wiphy = wiphy;
	mod_timer(&dwork->timer, jiffies + delay);
}
EXPORT_SYMBOL_GPL(wiphy_delayed_work_queue);

void wiphy_delayed_work_cancel(struct wiphy *wiphy,
			       struct wiphy_delayed_work *dwork)
{
	lockdep_assert_held(&wiphy->mtx);

	timer_delete_sync(&dwork->timer);
	wiphy_work_cancel(wiphy, &dwork->work);
}
EXPORT_SYMBOL_GPL(wiphy_delayed_work_cancel);

void wiphy_delayed_work_flush(struct wiphy *wiphy,
			      struct wiphy_delayed_work *dwork)
{
	lockdep_assert_held(&wiphy->mtx);

	timer_delete_sync(&dwork->timer);
	wiphy_work_flush(wiphy, &dwork->work);
}
EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush);

bool wiphy_delayed_work_pending(struct wiphy *wiphy,
				struct wiphy_delayed_work *dwork)
{
	return timer_pending(&dwork->timer);
}
EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending);

enum hrtimer_restart wiphy_hrtimer_work_timer(struct hrtimer *t)
{
	struct wiphy_hrtimer_work *hrwork =
		container_of(t, struct wiphy_hrtimer_work, timer);

	wiphy_work_queue(hrwork->wiphy, &hrwork->work);

	return HRTIMER_NORESTART;
}
EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_timer);

void wiphy_hrtimer_work_queue(struct wiphy *wiphy,
			      struct wiphy_hrtimer_work *hrwork,
			      ktime_t delay)
{
	trace_wiphy_hrtimer_work_queue(wiphy, &hrwork->work, delay);

	if (!delay) {
		hrtimer_cancel(&hrwork->timer);
		wiphy_work_queue(wiphy, &hrwork->work);
		return;
	}

	hrwork->wiphy = wiphy;
	hrtimer_start_range_ns(&hrwork->timer, delay,
			       1000 * NSEC_PER_USEC, HRTIMER_MODE_REL);
}
EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_queue);

void wiphy_hrtimer_work_cancel(struct wiphy *wiphy,
			       struct wiphy_hrtimer_work *hrwork)
{
	lockdep_assert_held(&wiphy->mtx);

	hrtimer_cancel(&hrwork->timer);
	wiphy_work_cancel(wiphy, &hrwork->work);
}
EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_cancel);

void wiphy_hrtimer_work_flush(struct wiphy *wiphy,
			      struct wiphy_hrtimer_work *hrwork)
{
	lockdep_assert_held(&wiphy->mtx);

	hrtimer_cancel(&hrwork->timer);
	wiphy_work_flush(wiphy, &hrwork->work);
}
EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_flush);

bool wiphy_hrtimer_work_pending(struct wiphy *wiphy,
				struct wiphy_hrtimer_work *hrwork)
{
	return hrtimer_is_queued(&hrwork->timer);
}
EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_pending);

static int __init cfg80211_init(void)
{
	int err;

	err = register_pernet_device(&cfg80211_pernet_ops);
	if (err)
		goto out_fail_pernet;

	err = wiphy_sysfs_init();
	if (err)
		goto out_fail_sysfs;

	err = register_netdevice_notifier(&cfg80211_netdev_notifier);
	if (err)
		goto out_fail_notifier;

	err = nl80211_init();
	if (err)
		goto out_fail_nl80211;

	ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL);

	err = regulatory_init();
	if (err)
		goto out_fail_reg;

	cfg80211_wq = alloc_ordered_workqueue("cfg80211", WQ_MEM_RECLAIM);
	if (!cfg80211_wq) {
		err = -ENOMEM;
		goto out_fail_wq;
	}

	return 0;

out_fail_wq:
	regulatory_exit();
out_fail_reg:
	debugfs_remove(ieee80211_debugfs_dir);
	nl80211_exit();
out_fail_nl80211:
	unregister_netdevice_notifier(&cfg80211_netdev_notifier);
out_fail_notifier:
	wiphy_sysfs_exit();
out_fail_sysfs:
	unregister_pernet_device(&cfg80211_pernet_ops);
out_fail_pernet:
	return err;
}
fs_initcall(cfg80211_init);

static void __exit cfg80211_exit(void)
{
	debugfs_remove(ieee80211_debugfs_dir);
	nl80211_exit();
	unregister_netdevice_notifier(&cfg80211_netdev_notifier);
	wiphy_sysfs_exit();
	regulatory_exit();
	unregister_pernet_device(&cfg80211_pernet_ops);
	destroy_workqueue(cfg80211_wq);
}
module_exit(cfg80211_exit);
