18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Wireless configuration interface internals.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2006-2010	Johannes Berg <johannes@sipsolutions.net>
68c2ecf20Sopenharmony_ci * Copyright (C) 2018-2020 Intel Corporation
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci#ifndef __NET_WIRELESS_CORE_H
98c2ecf20Sopenharmony_ci#define __NET_WIRELESS_CORE_H
108c2ecf20Sopenharmony_ci#include <linux/list.h>
118c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
128c2ecf20Sopenharmony_ci#include <linux/rbtree.h>
138c2ecf20Sopenharmony_ci#include <linux/debugfs.h>
148c2ecf20Sopenharmony_ci#include <linux/rfkill.h>
158c2ecf20Sopenharmony_ci#include <linux/workqueue.h>
168c2ecf20Sopenharmony_ci#include <linux/rtnetlink.h>
178c2ecf20Sopenharmony_ci#include <net/genetlink.h>
188c2ecf20Sopenharmony_ci#include <net/cfg80211.h>
198c2ecf20Sopenharmony_ci#include "reg.h"
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#define WIPHY_IDX_INVALID	-1
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cistruct cfg80211_registered_device {
258c2ecf20Sopenharmony_ci	const struct cfg80211_ops *ops;
268c2ecf20Sopenharmony_ci	struct list_head list;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	/* rfkill support */
298c2ecf20Sopenharmony_ci	struct rfkill_ops rfkill_ops;
308c2ecf20Sopenharmony_ci	struct rfkill *rfkill;
318c2ecf20Sopenharmony_ci	struct work_struct rfkill_block;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	/* ISO / IEC 3166 alpha2 for which this device is receiving
348c2ecf20Sopenharmony_ci	 * country IEs on, this can help disregard country IEs from APs
358c2ecf20Sopenharmony_ci	 * on the same alpha2 quickly. The alpha2 may differ from
368c2ecf20Sopenharmony_ci	 * cfg80211_regdomain's alpha2 when an intersection has occurred.
378c2ecf20Sopenharmony_ci	 * If the AP is reconfigured this can also be used to tell us if
388c2ecf20Sopenharmony_ci	 * the country on the country IE changed. */
398c2ecf20Sopenharmony_ci	char country_ie_alpha2[2];
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	/*
428c2ecf20Sopenharmony_ci	 * the driver requests the regulatory core to set this regulatory
438c2ecf20Sopenharmony_ci	 * domain as the wiphy's. Only used for %REGULATORY_WIPHY_SELF_MANAGED
448c2ecf20Sopenharmony_ci	 * devices using the regulatory_set_wiphy_regd() API
458c2ecf20Sopenharmony_ci	 */
468c2ecf20Sopenharmony_ci	const struct ieee80211_regdomain *requested_regd;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	/* If a Country IE has been received this tells us the environment
498c2ecf20Sopenharmony_ci	 * which its telling us its in. This defaults to ENVIRON_ANY */
508c2ecf20Sopenharmony_ci	enum environment_cap env;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	/* wiphy index, internal only */
538c2ecf20Sopenharmony_ci	int wiphy_idx;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	/* protected by RTNL */
568c2ecf20Sopenharmony_ci	int devlist_generation, wdev_id;
578c2ecf20Sopenharmony_ci	int opencount;
588c2ecf20Sopenharmony_ci	wait_queue_head_t dev_wait;
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	struct list_head beacon_registrations;
618c2ecf20Sopenharmony_ci	spinlock_t beacon_registrations_lock;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	/* protected by RTNL only */
648c2ecf20Sopenharmony_ci	int num_running_ifaces;
658c2ecf20Sopenharmony_ci	int num_running_monitor_ifaces;
668c2ecf20Sopenharmony_ci	u64 cookie_counter;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	/* BSSes/scanning */
698c2ecf20Sopenharmony_ci	spinlock_t bss_lock;
708c2ecf20Sopenharmony_ci	struct list_head bss_list;
718c2ecf20Sopenharmony_ci	struct rb_root bss_tree;
728c2ecf20Sopenharmony_ci	u32 bss_generation;
738c2ecf20Sopenharmony_ci	u32 bss_entries;
748c2ecf20Sopenharmony_ci	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
758c2ecf20Sopenharmony_ci	struct cfg80211_scan_request *int_scan_req;
768c2ecf20Sopenharmony_ci	struct sk_buff *scan_msg;
778c2ecf20Sopenharmony_ci	struct list_head sched_scan_req_list;
788c2ecf20Sopenharmony_ci	time64_t suspend_at;
798c2ecf20Sopenharmony_ci	struct work_struct scan_done_wk;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	struct genl_info *cur_cmd_info;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	struct work_struct conn_work;
848c2ecf20Sopenharmony_ci	struct work_struct event_work;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	struct delayed_work dfs_update_channels_wk;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	/* netlink port which started critical protocol (0 means not started) */
898c2ecf20Sopenharmony_ci	u32 crit_proto_nlportid;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	struct cfg80211_coalesce *coalesce;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	struct work_struct destroy_work;
948c2ecf20Sopenharmony_ci	struct work_struct sched_scan_stop_wk;
958c2ecf20Sopenharmony_ci	struct work_struct sched_scan_res_wk;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	struct cfg80211_chan_def radar_chandef;
988c2ecf20Sopenharmony_ci	struct work_struct propagate_radar_detect_wk;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	struct cfg80211_chan_def cac_done_chandef;
1018c2ecf20Sopenharmony_ci	struct work_struct propagate_cac_done_wk;
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	struct work_struct mgmt_registrations_update_wk;
1048c2ecf20Sopenharmony_ci	/* lock for all wdev lists */
1058c2ecf20Sopenharmony_ci	spinlock_t mgmt_registrations_lock;
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	/* must be last because of the way we do wiphy_priv(),
1088c2ecf20Sopenharmony_ci	 * and it should at least be aligned to NETDEV_ALIGN */
1098c2ecf20Sopenharmony_ci	struct wiphy wiphy __aligned(NETDEV_ALIGN);
1108c2ecf20Sopenharmony_ci};
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_cistatic inline
1138c2ecf20Sopenharmony_cistruct cfg80211_registered_device *wiphy_to_rdev(struct wiphy *wiphy)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	BUG_ON(!wiphy);
1168c2ecf20Sopenharmony_ci	return container_of(wiphy, struct cfg80211_registered_device, wiphy);
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_cistatic inline void
1208c2ecf20Sopenharmony_cicfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
1218c2ecf20Sopenharmony_ci{
1228c2ecf20Sopenharmony_ci#ifdef CONFIG_PM
1238c2ecf20Sopenharmony_ci	int i;
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	if (!rdev->wiphy.wowlan_config)
1268c2ecf20Sopenharmony_ci		return;
1278c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->wiphy.wowlan_config->n_patterns; i++)
1288c2ecf20Sopenharmony_ci		kfree(rdev->wiphy.wowlan_config->patterns[i].mask);
1298c2ecf20Sopenharmony_ci	kfree(rdev->wiphy.wowlan_config->patterns);
1308c2ecf20Sopenharmony_ci	if (rdev->wiphy.wowlan_config->tcp &&
1318c2ecf20Sopenharmony_ci	    rdev->wiphy.wowlan_config->tcp->sock)
1328c2ecf20Sopenharmony_ci		sock_release(rdev->wiphy.wowlan_config->tcp->sock);
1338c2ecf20Sopenharmony_ci	kfree(rdev->wiphy.wowlan_config->tcp);
1348c2ecf20Sopenharmony_ci	kfree(rdev->wiphy.wowlan_config->nd_config);
1358c2ecf20Sopenharmony_ci	kfree(rdev->wiphy.wowlan_config);
1368c2ecf20Sopenharmony_ci#endif
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistatic inline u64 cfg80211_assign_cookie(struct cfg80211_registered_device *rdev)
1408c2ecf20Sopenharmony_ci{
1418c2ecf20Sopenharmony_ci	u64 r = ++rdev->cookie_counter;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	if (WARN_ON(r == 0))
1448c2ecf20Sopenharmony_ci		r = ++rdev->cookie_counter;
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	return r;
1478c2ecf20Sopenharmony_ci}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ciextern struct workqueue_struct *cfg80211_wq;
1508c2ecf20Sopenharmony_ciextern struct list_head cfg80211_rdev_list;
1518c2ecf20Sopenharmony_ciextern int cfg80211_rdev_list_generation;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_cistruct cfg80211_internal_bss {
1548c2ecf20Sopenharmony_ci	struct list_head list;
1558c2ecf20Sopenharmony_ci	struct list_head hidden_list;
1568c2ecf20Sopenharmony_ci	struct rb_node rbn;
1578c2ecf20Sopenharmony_ci	u64 ts_boottime;
1588c2ecf20Sopenharmony_ci	unsigned long ts;
1598c2ecf20Sopenharmony_ci	unsigned long refcount;
1608c2ecf20Sopenharmony_ci	atomic_t hold;
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	/* time at the start of the reception of the first octet of the
1638c2ecf20Sopenharmony_ci	 * timestamp field of the last beacon/probe received for this BSS.
1648c2ecf20Sopenharmony_ci	 * The time is the TSF of the BSS specified by %parent_bssid.
1658c2ecf20Sopenharmony_ci	 */
1668c2ecf20Sopenharmony_ci	u64 parent_tsf;
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	/* the BSS according to which %parent_tsf is set. This is set to
1698c2ecf20Sopenharmony_ci	 * the BSS that the interface that requested the scan was connected to
1708c2ecf20Sopenharmony_ci	 * when the beacon/probe was received.
1718c2ecf20Sopenharmony_ci	 */
1728c2ecf20Sopenharmony_ci	u8 parent_bssid[ETH_ALEN] __aligned(2);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	/* must be last because of priv member */
1758c2ecf20Sopenharmony_ci	struct cfg80211_bss pub;
1768c2ecf20Sopenharmony_ci};
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_cistatic inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pub)
1798c2ecf20Sopenharmony_ci{
1808c2ecf20Sopenharmony_ci	return container_of(pub, struct cfg80211_internal_bss, pub);
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_cistatic inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	atomic_inc(&bss->hold);
1868c2ecf20Sopenharmony_ci	if (bss->pub.transmitted_bss) {
1878c2ecf20Sopenharmony_ci		bss = container_of(bss->pub.transmitted_bss,
1888c2ecf20Sopenharmony_ci				   struct cfg80211_internal_bss, pub);
1898c2ecf20Sopenharmony_ci		atomic_inc(&bss->hold);
1908c2ecf20Sopenharmony_ci	}
1918c2ecf20Sopenharmony_ci}
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_cistatic inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
1948c2ecf20Sopenharmony_ci{
1958c2ecf20Sopenharmony_ci	int r = atomic_dec_return(&bss->hold);
1968c2ecf20Sopenharmony_ci	WARN_ON(r < 0);
1978c2ecf20Sopenharmony_ci	if (bss->pub.transmitted_bss) {
1988c2ecf20Sopenharmony_ci		bss = container_of(bss->pub.transmitted_bss,
1998c2ecf20Sopenharmony_ci				   struct cfg80211_internal_bss, pub);
2008c2ecf20Sopenharmony_ci		r = atomic_dec_return(&bss->hold);
2018c2ecf20Sopenharmony_ci		WARN_ON(r < 0);
2028c2ecf20Sopenharmony_ci	}
2038c2ecf20Sopenharmony_ci}
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_cistruct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
2078c2ecf20Sopenharmony_ciint get_wiphy_idx(struct wiphy *wiphy);
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_cistruct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ciint cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
2128c2ecf20Sopenharmony_ci			  struct net *net);
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_civoid cfg80211_init_wdev(struct wireless_dev *wdev);
2158c2ecf20Sopenharmony_civoid cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
2168c2ecf20Sopenharmony_ci			    struct wireless_dev *wdev);
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_cistatic inline void wdev_lock(struct wireless_dev *wdev)
2198c2ecf20Sopenharmony_ci	__acquires(wdev)
2208c2ecf20Sopenharmony_ci{
2218c2ecf20Sopenharmony_ci	mutex_lock(&wdev->mtx);
2228c2ecf20Sopenharmony_ci	__acquire(wdev->mtx);
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cistatic inline void wdev_unlock(struct wireless_dev *wdev)
2268c2ecf20Sopenharmony_ci	__releases(wdev)
2278c2ecf20Sopenharmony_ci{
2288c2ecf20Sopenharmony_ci	__release(wdev->mtx);
2298c2ecf20Sopenharmony_ci	mutex_unlock(&wdev->mtx);
2308c2ecf20Sopenharmony_ci}
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_cistatic inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)
2358c2ecf20Sopenharmony_ci{
2368c2ecf20Sopenharmony_ci	ASSERT_RTNL();
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	return rdev->num_running_ifaces == rdev->num_running_monitor_ifaces &&
2398c2ecf20Sopenharmony_ci	       rdev->num_running_ifaces > 0;
2408c2ecf20Sopenharmony_ci}
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_cienum cfg80211_event_type {
2438c2ecf20Sopenharmony_ci	EVENT_CONNECT_RESULT,
2448c2ecf20Sopenharmony_ci	EVENT_ROAMED,
2458c2ecf20Sopenharmony_ci	EVENT_DISCONNECTED,
2468c2ecf20Sopenharmony_ci	EVENT_IBSS_JOINED,
2478c2ecf20Sopenharmony_ci	EVENT_STOPPED,
2488c2ecf20Sopenharmony_ci	EVENT_PORT_AUTHORIZED,
2498c2ecf20Sopenharmony_ci};
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_cistruct cfg80211_event {
2528c2ecf20Sopenharmony_ci	struct list_head list;
2538c2ecf20Sopenharmony_ci	enum cfg80211_event_type type;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	union {
2568c2ecf20Sopenharmony_ci		struct cfg80211_connect_resp_params cr;
2578c2ecf20Sopenharmony_ci		struct cfg80211_roam_info rm;
2588c2ecf20Sopenharmony_ci		struct {
2598c2ecf20Sopenharmony_ci			const u8 *ie;
2608c2ecf20Sopenharmony_ci			size_t ie_len;
2618c2ecf20Sopenharmony_ci			u16 reason;
2628c2ecf20Sopenharmony_ci			bool locally_generated;
2638c2ecf20Sopenharmony_ci		} dc;
2648c2ecf20Sopenharmony_ci		struct {
2658c2ecf20Sopenharmony_ci			u8 bssid[ETH_ALEN];
2668c2ecf20Sopenharmony_ci			struct ieee80211_channel *channel;
2678c2ecf20Sopenharmony_ci		} ij;
2688c2ecf20Sopenharmony_ci		struct {
2698c2ecf20Sopenharmony_ci			u8 bssid[ETH_ALEN];
2708c2ecf20Sopenharmony_ci		} pa;
2718c2ecf20Sopenharmony_ci	};
2728c2ecf20Sopenharmony_ci};
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_cistruct cfg80211_cached_keys {
2758c2ecf20Sopenharmony_ci	struct key_params params[CFG80211_MAX_WEP_KEYS];
2768c2ecf20Sopenharmony_ci	u8 data[CFG80211_MAX_WEP_KEYS][WLAN_KEY_LEN_WEP104];
2778c2ecf20Sopenharmony_ci	int def;
2788c2ecf20Sopenharmony_ci};
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_cienum cfg80211_chan_mode {
2818c2ecf20Sopenharmony_ci	CHAN_MODE_UNDEFINED,
2828c2ecf20Sopenharmony_ci	CHAN_MODE_SHARED,
2838c2ecf20Sopenharmony_ci	CHAN_MODE_EXCLUSIVE,
2848c2ecf20Sopenharmony_ci};
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_cistruct cfg80211_beacon_registration {
2878c2ecf20Sopenharmony_ci	struct list_head list;
2888c2ecf20Sopenharmony_ci	u32 nlportid;
2898c2ecf20Sopenharmony_ci};
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_cistruct cfg80211_cqm_config {
2928c2ecf20Sopenharmony_ci	u32 rssi_hyst;
2938c2ecf20Sopenharmony_ci	s32 last_rssi_event_value;
2948c2ecf20Sopenharmony_ci	int n_rssi_thresholds;
2958c2ecf20Sopenharmony_ci	s32 rssi_thresholds[];
2968c2ecf20Sopenharmony_ci};
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_civoid cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev);
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci/* free object */
3018c2ecf20Sopenharmony_civoid cfg80211_dev_free(struct cfg80211_registered_device *rdev);
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ciint cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
3048c2ecf20Sopenharmony_ci			char *newname);
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_civoid ieee80211_set_bitrate_flags(struct wiphy *wiphy);
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_civoid cfg80211_bss_expire(struct cfg80211_registered_device *rdev);
3098c2ecf20Sopenharmony_civoid cfg80211_bss_age(struct cfg80211_registered_device *rdev,
3108c2ecf20Sopenharmony_ci                      unsigned long age_secs);
3118c2ecf20Sopenharmony_civoid cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
3128c2ecf20Sopenharmony_ci				     struct ieee80211_channel *channel);
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci/* IBSS */
3158c2ecf20Sopenharmony_ciint __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
3168c2ecf20Sopenharmony_ci			 struct net_device *dev,
3178c2ecf20Sopenharmony_ci			 struct cfg80211_ibss_params *params,
3188c2ecf20Sopenharmony_ci			 struct cfg80211_cached_keys *connkeys);
3198c2ecf20Sopenharmony_civoid cfg80211_clear_ibss(struct net_device *dev, bool nowext);
3208c2ecf20Sopenharmony_ciint __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
3218c2ecf20Sopenharmony_ci			  struct net_device *dev, bool nowext);
3228c2ecf20Sopenharmony_ciint cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
3238c2ecf20Sopenharmony_ci			struct net_device *dev, bool nowext);
3248c2ecf20Sopenharmony_civoid __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
3258c2ecf20Sopenharmony_ci			    struct ieee80211_channel *channel);
3268c2ecf20Sopenharmony_ciint cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
3278c2ecf20Sopenharmony_ci			    struct wireless_dev *wdev);
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci/* mesh */
3308c2ecf20Sopenharmony_ciextern const struct mesh_config default_mesh_config;
3318c2ecf20Sopenharmony_ciextern const struct mesh_setup default_mesh_setup;
3328c2ecf20Sopenharmony_ciint __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
3338c2ecf20Sopenharmony_ci			 struct net_device *dev,
3348c2ecf20Sopenharmony_ci			 struct mesh_setup *setup,
3358c2ecf20Sopenharmony_ci			 const struct mesh_config *conf);
3368c2ecf20Sopenharmony_ciint __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
3378c2ecf20Sopenharmony_ci			  struct net_device *dev);
3388c2ecf20Sopenharmony_ciint cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
3398c2ecf20Sopenharmony_ci			struct net_device *dev);
3408c2ecf20Sopenharmony_ciint cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
3418c2ecf20Sopenharmony_ci			      struct wireless_dev *wdev,
3428c2ecf20Sopenharmony_ci			      struct cfg80211_chan_def *chandef);
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci/* OCB */
3458c2ecf20Sopenharmony_ciint __cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
3468c2ecf20Sopenharmony_ci			struct net_device *dev,
3478c2ecf20Sopenharmony_ci			struct ocb_setup *setup);
3488c2ecf20Sopenharmony_ciint cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
3498c2ecf20Sopenharmony_ci		      struct net_device *dev,
3508c2ecf20Sopenharmony_ci		      struct ocb_setup *setup);
3518c2ecf20Sopenharmony_ciint __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
3528c2ecf20Sopenharmony_ci			 struct net_device *dev);
3538c2ecf20Sopenharmony_ciint cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
3548c2ecf20Sopenharmony_ci		       struct net_device *dev);
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci/* AP */
3578c2ecf20Sopenharmony_ciint __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
3588c2ecf20Sopenharmony_ci		       struct net_device *dev, bool notify);
3598c2ecf20Sopenharmony_ciint cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
3608c2ecf20Sopenharmony_ci		     struct net_device *dev, bool notify);
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci/* MLME */
3638c2ecf20Sopenharmony_ciint cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
3648c2ecf20Sopenharmony_ci		       struct net_device *dev,
3658c2ecf20Sopenharmony_ci		       struct ieee80211_channel *chan,
3668c2ecf20Sopenharmony_ci		       enum nl80211_auth_type auth_type,
3678c2ecf20Sopenharmony_ci		       const u8 *bssid,
3688c2ecf20Sopenharmony_ci		       const u8 *ssid, int ssid_len,
3698c2ecf20Sopenharmony_ci		       const u8 *ie, int ie_len,
3708c2ecf20Sopenharmony_ci		       const u8 *key, int key_len, int key_idx,
3718c2ecf20Sopenharmony_ci		       const u8 *auth_data, int auth_data_len);
3728c2ecf20Sopenharmony_ciint cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
3738c2ecf20Sopenharmony_ci			struct net_device *dev,
3748c2ecf20Sopenharmony_ci			struct ieee80211_channel *chan,
3758c2ecf20Sopenharmony_ci			const u8 *bssid,
3768c2ecf20Sopenharmony_ci			const u8 *ssid, int ssid_len,
3778c2ecf20Sopenharmony_ci			struct cfg80211_assoc_request *req);
3788c2ecf20Sopenharmony_ciint cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
3798c2ecf20Sopenharmony_ci			 struct net_device *dev, const u8 *bssid,
3808c2ecf20Sopenharmony_ci			 const u8 *ie, int ie_len, u16 reason,
3818c2ecf20Sopenharmony_ci			 bool local_state_change);
3828c2ecf20Sopenharmony_ciint cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
3838c2ecf20Sopenharmony_ci			   struct net_device *dev, const u8 *bssid,
3848c2ecf20Sopenharmony_ci			   const u8 *ie, int ie_len, u16 reason,
3858c2ecf20Sopenharmony_ci			   bool local_state_change);
3868c2ecf20Sopenharmony_civoid cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
3878c2ecf20Sopenharmony_ci			struct net_device *dev);
3888c2ecf20Sopenharmony_ciint cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
3898c2ecf20Sopenharmony_ci				u16 frame_type, const u8 *match_data,
3908c2ecf20Sopenharmony_ci				int match_len, bool multicast_rx,
3918c2ecf20Sopenharmony_ci				struct netlink_ext_ack *extack);
3928c2ecf20Sopenharmony_civoid cfg80211_mgmt_registrations_update_wk(struct work_struct *wk);
3938c2ecf20Sopenharmony_civoid cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
3948c2ecf20Sopenharmony_civoid cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
3958c2ecf20Sopenharmony_ciint cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
3968c2ecf20Sopenharmony_ci			  struct wireless_dev *wdev,
3978c2ecf20Sopenharmony_ci			  struct cfg80211_mgmt_tx_params *params,
3988c2ecf20Sopenharmony_ci			  u64 *cookie);
3998c2ecf20Sopenharmony_civoid cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
4008c2ecf20Sopenharmony_ci			       const struct ieee80211_ht_cap *ht_capa_mask);
4018c2ecf20Sopenharmony_civoid cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
4028c2ecf20Sopenharmony_ci				const struct ieee80211_vht_cap *vht_capa_mask);
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci/* SME events */
4058c2ecf20Sopenharmony_ciint cfg80211_connect(struct cfg80211_registered_device *rdev,
4068c2ecf20Sopenharmony_ci		     struct net_device *dev,
4078c2ecf20Sopenharmony_ci		     struct cfg80211_connect_params *connect,
4088c2ecf20Sopenharmony_ci		     struct cfg80211_cached_keys *connkeys,
4098c2ecf20Sopenharmony_ci		     const u8 *prev_bssid);
4108c2ecf20Sopenharmony_civoid __cfg80211_connect_result(struct net_device *dev,
4118c2ecf20Sopenharmony_ci			       struct cfg80211_connect_resp_params *params,
4128c2ecf20Sopenharmony_ci			       bool wextev);
4138c2ecf20Sopenharmony_civoid __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
4148c2ecf20Sopenharmony_ci			     size_t ie_len, u16 reason, bool from_ap);
4158c2ecf20Sopenharmony_ciint cfg80211_disconnect(struct cfg80211_registered_device *rdev,
4168c2ecf20Sopenharmony_ci			struct net_device *dev, u16 reason,
4178c2ecf20Sopenharmony_ci			bool wextev);
4188c2ecf20Sopenharmony_civoid __cfg80211_roamed(struct wireless_dev *wdev,
4198c2ecf20Sopenharmony_ci		       struct cfg80211_roam_info *info);
4208c2ecf20Sopenharmony_civoid __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid);
4218c2ecf20Sopenharmony_ciint cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
4228c2ecf20Sopenharmony_ci			      struct wireless_dev *wdev);
4238c2ecf20Sopenharmony_civoid cfg80211_autodisconnect_wk(struct work_struct *work);
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci/* SME implementation */
4268c2ecf20Sopenharmony_civoid cfg80211_conn_work(struct work_struct *work);
4278c2ecf20Sopenharmony_civoid cfg80211_sme_scan_done(struct net_device *dev);
4288c2ecf20Sopenharmony_cibool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status);
4298c2ecf20Sopenharmony_civoid cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len);
4308c2ecf20Sopenharmony_civoid cfg80211_sme_disassoc(struct wireless_dev *wdev);
4318c2ecf20Sopenharmony_civoid cfg80211_sme_deauth(struct wireless_dev *wdev);
4328c2ecf20Sopenharmony_civoid cfg80211_sme_auth_timeout(struct wireless_dev *wdev);
4338c2ecf20Sopenharmony_civoid cfg80211_sme_assoc_timeout(struct wireless_dev *wdev);
4348c2ecf20Sopenharmony_civoid cfg80211_sme_abandon_assoc(struct wireless_dev *wdev);
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci/* internal helpers */
4378c2ecf20Sopenharmony_cibool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
4388c2ecf20Sopenharmony_cibool cfg80211_valid_key_idx(struct cfg80211_registered_device *rdev,
4398c2ecf20Sopenharmony_ci			    int key_idx, bool pairwise);
4408c2ecf20Sopenharmony_ciint cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
4418c2ecf20Sopenharmony_ci				   struct key_params *params, int key_idx,
4428c2ecf20Sopenharmony_ci				   bool pairwise, const u8 *mac_addr);
4438c2ecf20Sopenharmony_civoid __cfg80211_scan_done(struct work_struct *wk);
4448c2ecf20Sopenharmony_civoid ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
4458c2ecf20Sopenharmony_ci			   bool send_message);
4468c2ecf20Sopenharmony_civoid cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
4478c2ecf20Sopenharmony_ci				 struct cfg80211_sched_scan_request *req);
4488c2ecf20Sopenharmony_ciint cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
4498c2ecf20Sopenharmony_ci				     bool want_multi);
4508c2ecf20Sopenharmony_civoid cfg80211_sched_scan_results_wk(struct work_struct *work);
4518c2ecf20Sopenharmony_ciint cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
4528c2ecf20Sopenharmony_ci				 struct cfg80211_sched_scan_request *req,
4538c2ecf20Sopenharmony_ci				 bool driver_initiated);
4548c2ecf20Sopenharmony_ciint __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
4558c2ecf20Sopenharmony_ci			       u64 reqid, bool driver_initiated);
4568c2ecf20Sopenharmony_civoid cfg80211_upload_connect_keys(struct wireless_dev *wdev);
4578c2ecf20Sopenharmony_ciint cfg80211_change_iface(struct cfg80211_registered_device *rdev,
4588c2ecf20Sopenharmony_ci			  struct net_device *dev, enum nl80211_iftype ntype,
4598c2ecf20Sopenharmony_ci			  struct vif_params *params);
4608c2ecf20Sopenharmony_civoid cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
4618c2ecf20Sopenharmony_civoid cfg80211_process_wdev_events(struct wireless_dev *wdev);
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_cibool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range,
4648c2ecf20Sopenharmony_ci				u32 center_freq_khz, u32 bw_khz);
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ciint cfg80211_scan(struct cfg80211_registered_device *rdev);
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ciextern struct work_struct cfg80211_disconnect_work;
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci/**
4718c2ecf20Sopenharmony_ci * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable
4728c2ecf20Sopenharmony_ci * @wiphy: the wiphy to validate against
4738c2ecf20Sopenharmony_ci * @chandef: the channel definition to check
4748c2ecf20Sopenharmony_ci *
4758c2ecf20Sopenharmony_ci * Checks if chandef is usable and we can/need start CAC on such channel.
4768c2ecf20Sopenharmony_ci *
4778c2ecf20Sopenharmony_ci * Return: true if all channels available and at least
4788c2ecf20Sopenharmony_ci *	   one channel requires CAC (NL80211_DFS_USABLE)
4798c2ecf20Sopenharmony_ci */
4808c2ecf20Sopenharmony_cibool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
4818c2ecf20Sopenharmony_ci				 const struct cfg80211_chan_def *chandef);
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_civoid cfg80211_set_dfs_state(struct wiphy *wiphy,
4848c2ecf20Sopenharmony_ci			    const struct cfg80211_chan_def *chandef,
4858c2ecf20Sopenharmony_ci			    enum nl80211_dfs_state dfs_state);
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_civoid cfg80211_dfs_channels_update_work(struct work_struct *work);
4888c2ecf20Sopenharmony_ci
4898c2ecf20Sopenharmony_ciunsigned int
4908c2ecf20Sopenharmony_cicfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
4918c2ecf20Sopenharmony_ci			      const struct cfg80211_chan_def *chandef);
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_civoid cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_cibool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
4968c2ecf20Sopenharmony_ci				  struct ieee80211_channel *chan);
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_cibool cfg80211_beaconing_iface_active(struct wireless_dev *wdev);
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_cibool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
5018c2ecf20Sopenharmony_ci			  struct ieee80211_channel *chan);
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_cistatic inline unsigned int elapsed_jiffies_msecs(unsigned long start)
5048c2ecf20Sopenharmony_ci{
5058c2ecf20Sopenharmony_ci	unsigned long end = jiffies;
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_ci	if (end >= start)
5088c2ecf20Sopenharmony_ci		return jiffies_to_msecs(end - start);
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci	return jiffies_to_msecs(end + (ULONG_MAX - start) + 1);
5118c2ecf20Sopenharmony_ci}
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_civoid
5148c2ecf20Sopenharmony_cicfg80211_get_chan_state(struct wireless_dev *wdev,
5158c2ecf20Sopenharmony_ci		        struct ieee80211_channel **chan,
5168c2ecf20Sopenharmony_ci		        enum cfg80211_chan_mode *chanmode,
5178c2ecf20Sopenharmony_ci		        u8 *radar_detect);
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ciint cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
5208c2ecf20Sopenharmony_ci				 struct cfg80211_chan_def *chandef);
5218c2ecf20Sopenharmony_ci
5228c2ecf20Sopenharmony_ciint ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
5238c2ecf20Sopenharmony_ci			   const u8 *rates, unsigned int n_rates,
5248c2ecf20Sopenharmony_ci			   u32 *mask);
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ciint cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
5278c2ecf20Sopenharmony_ci				 enum nl80211_iftype iftype, u32 beacon_int);
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_civoid cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
5308c2ecf20Sopenharmony_ci			       enum nl80211_iftype iftype, int num);
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_civoid __cfg80211_leave(struct cfg80211_registered_device *rdev,
5338c2ecf20Sopenharmony_ci		      struct wireless_dev *wdev);
5348c2ecf20Sopenharmony_civoid cfg80211_leave(struct cfg80211_registered_device *rdev,
5358c2ecf20Sopenharmony_ci		    struct wireless_dev *wdev);
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_civoid cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
5388c2ecf20Sopenharmony_ci			      struct wireless_dev *wdev);
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_civoid cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
5418c2ecf20Sopenharmony_ci		       struct wireless_dev *wdev);
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_cistruct cfg80211_internal_bss *
5448c2ecf20Sopenharmony_cicfg80211_bss_update(struct cfg80211_registered_device *rdev,
5458c2ecf20Sopenharmony_ci		    struct cfg80211_internal_bss *tmp,
5468c2ecf20Sopenharmony_ci		    bool signal_valid, unsigned long ts);
5478c2ecf20Sopenharmony_ci#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
5488c2ecf20Sopenharmony_ci#define CFG80211_DEV_WARN_ON(cond)	WARN_ON(cond)
5498c2ecf20Sopenharmony_ci#else
5508c2ecf20Sopenharmony_ci/*
5518c2ecf20Sopenharmony_ci * Trick to enable using it as a condition,
5528c2ecf20Sopenharmony_ci * and also not give a warning when it's
5538c2ecf20Sopenharmony_ci * not used that way.
5548c2ecf20Sopenharmony_ci */
5558c2ecf20Sopenharmony_ci#define CFG80211_DEV_WARN_ON(cond)	({bool __r = (cond); __r; })
5568c2ecf20Sopenharmony_ci#endif
5578c2ecf20Sopenharmony_ci
5588c2ecf20Sopenharmony_civoid cfg80211_cqm_config_free(struct wireless_dev *wdev);
5598c2ecf20Sopenharmony_ci
5608c2ecf20Sopenharmony_civoid cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
5618c2ecf20Sopenharmony_civoid cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
5628c2ecf20Sopenharmony_civoid cfg80211_pmsr_free_wk(struct work_struct *work);
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci#endif /* __NET_WIRELESS_CORE_H */
565