162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Wireless configuration interface internals. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 662306a36Sopenharmony_ci * Copyright (C) 2018-2022 Intel Corporation 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci#ifndef __NET_WIRELESS_CORE_H 962306a36Sopenharmony_ci#define __NET_WIRELESS_CORE_H 1062306a36Sopenharmony_ci#include <linux/list.h> 1162306a36Sopenharmony_ci#include <linux/netdevice.h> 1262306a36Sopenharmony_ci#include <linux/rbtree.h> 1362306a36Sopenharmony_ci#include <linux/debugfs.h> 1462306a36Sopenharmony_ci#include <linux/rfkill.h> 1562306a36Sopenharmony_ci#include <linux/workqueue.h> 1662306a36Sopenharmony_ci#include <linux/rtnetlink.h> 1762306a36Sopenharmony_ci#include <net/genetlink.h> 1862306a36Sopenharmony_ci#include <net/cfg80211.h> 1962306a36Sopenharmony_ci#include "reg.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define WIPHY_IDX_INVALID -1 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct cfg80211_registered_device { 2562306a36Sopenharmony_ci const struct cfg80211_ops *ops; 2662306a36Sopenharmony_ci struct list_head list; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci /* rfkill support */ 2962306a36Sopenharmony_ci struct rfkill_ops rfkill_ops; 3062306a36Sopenharmony_ci struct work_struct rfkill_block; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci /* ISO / IEC 3166 alpha2 for which this device is receiving 3362306a36Sopenharmony_ci * country IEs on, this can help disregard country IEs from APs 3462306a36Sopenharmony_ci * on the same alpha2 quickly. The alpha2 may differ from 3562306a36Sopenharmony_ci * cfg80211_regdomain's alpha2 when an intersection has occurred. 3662306a36Sopenharmony_ci * If the AP is reconfigured this can also be used to tell us if 3762306a36Sopenharmony_ci * the country on the country IE changed. */ 3862306a36Sopenharmony_ci char country_ie_alpha2[2]; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci /* 4162306a36Sopenharmony_ci * the driver requests the regulatory core to set this regulatory 4262306a36Sopenharmony_ci * domain as the wiphy's. Only used for %REGULATORY_WIPHY_SELF_MANAGED 4362306a36Sopenharmony_ci * devices using the regulatory_set_wiphy_regd() API 4462306a36Sopenharmony_ci */ 4562306a36Sopenharmony_ci const struct ieee80211_regdomain *requested_regd; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci /* If a Country IE has been received this tells us the environment 4862306a36Sopenharmony_ci * which its telling us its in. This defaults to ENVIRON_ANY */ 4962306a36Sopenharmony_ci enum environment_cap env; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci /* wiphy index, internal only */ 5262306a36Sopenharmony_ci int wiphy_idx; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci /* protected by RTNL */ 5562306a36Sopenharmony_ci int devlist_generation, wdev_id; 5662306a36Sopenharmony_ci int opencount; 5762306a36Sopenharmony_ci wait_queue_head_t dev_wait; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci struct list_head beacon_registrations; 6062306a36Sopenharmony_ci spinlock_t beacon_registrations_lock; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* protected by RTNL only */ 6362306a36Sopenharmony_ci int num_running_ifaces; 6462306a36Sopenharmony_ci int num_running_monitor_ifaces; 6562306a36Sopenharmony_ci u64 cookie_counter; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci /* BSSes/scanning */ 6862306a36Sopenharmony_ci spinlock_t bss_lock; 6962306a36Sopenharmony_ci struct list_head bss_list; 7062306a36Sopenharmony_ci struct rb_root bss_tree; 7162306a36Sopenharmony_ci u32 bss_generation; 7262306a36Sopenharmony_ci u32 bss_entries; 7362306a36Sopenharmony_ci struct cfg80211_scan_request *scan_req; /* protected by RTNL */ 7462306a36Sopenharmony_ci struct cfg80211_scan_request *int_scan_req; 7562306a36Sopenharmony_ci struct sk_buff *scan_msg; 7662306a36Sopenharmony_ci struct list_head sched_scan_req_list; 7762306a36Sopenharmony_ci time64_t suspend_at; 7862306a36Sopenharmony_ci struct wiphy_work scan_done_wk; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci struct genl_info *cur_cmd_info; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci struct work_struct conn_work; 8362306a36Sopenharmony_ci struct work_struct event_work; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci struct delayed_work dfs_update_channels_wk; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci struct wireless_dev *background_radar_wdev; 8862306a36Sopenharmony_ci struct cfg80211_chan_def background_radar_chandef; 8962306a36Sopenharmony_ci struct delayed_work background_cac_done_wk; 9062306a36Sopenharmony_ci struct work_struct background_cac_abort_wk; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci /* netlink port which started critical protocol (0 means not started) */ 9362306a36Sopenharmony_ci u32 crit_proto_nlportid; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci struct cfg80211_coalesce *coalesce; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci struct work_struct destroy_work; 9862306a36Sopenharmony_ci struct wiphy_work sched_scan_stop_wk; 9962306a36Sopenharmony_ci struct work_struct sched_scan_res_wk; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci struct cfg80211_chan_def radar_chandef; 10262306a36Sopenharmony_ci struct work_struct propagate_radar_detect_wk; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci struct cfg80211_chan_def cac_done_chandef; 10562306a36Sopenharmony_ci struct work_struct propagate_cac_done_wk; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci struct work_struct mgmt_registrations_update_wk; 10862306a36Sopenharmony_ci /* lock for all wdev lists */ 10962306a36Sopenharmony_ci spinlock_t mgmt_registrations_lock; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci struct work_struct wiphy_work; 11262306a36Sopenharmony_ci struct list_head wiphy_work_list; 11362306a36Sopenharmony_ci /* protects the list above */ 11462306a36Sopenharmony_ci spinlock_t wiphy_work_lock; 11562306a36Sopenharmony_ci bool suspended; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci /* must be last because of the way we do wiphy_priv(), 11862306a36Sopenharmony_ci * and it should at least be aligned to NETDEV_ALIGN */ 11962306a36Sopenharmony_ci struct wiphy wiphy __aligned(NETDEV_ALIGN); 12062306a36Sopenharmony_ci}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic inline 12362306a36Sopenharmony_cistruct cfg80211_registered_device *wiphy_to_rdev(struct wiphy *wiphy) 12462306a36Sopenharmony_ci{ 12562306a36Sopenharmony_ci BUG_ON(!wiphy); 12662306a36Sopenharmony_ci return container_of(wiphy, struct cfg80211_registered_device, wiphy); 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic inline void 13062306a36Sopenharmony_cicfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev) 13162306a36Sopenharmony_ci{ 13262306a36Sopenharmony_ci#ifdef CONFIG_PM 13362306a36Sopenharmony_ci int i; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci if (!rdev->wiphy.wowlan_config) 13662306a36Sopenharmony_ci return; 13762306a36Sopenharmony_ci for (i = 0; i < rdev->wiphy.wowlan_config->n_patterns; i++) 13862306a36Sopenharmony_ci kfree(rdev->wiphy.wowlan_config->patterns[i].mask); 13962306a36Sopenharmony_ci kfree(rdev->wiphy.wowlan_config->patterns); 14062306a36Sopenharmony_ci if (rdev->wiphy.wowlan_config->tcp && 14162306a36Sopenharmony_ci rdev->wiphy.wowlan_config->tcp->sock) 14262306a36Sopenharmony_ci sock_release(rdev->wiphy.wowlan_config->tcp->sock); 14362306a36Sopenharmony_ci kfree(rdev->wiphy.wowlan_config->tcp); 14462306a36Sopenharmony_ci kfree(rdev->wiphy.wowlan_config->nd_config); 14562306a36Sopenharmony_ci kfree(rdev->wiphy.wowlan_config); 14662306a36Sopenharmony_ci#endif 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic inline u64 cfg80211_assign_cookie(struct cfg80211_registered_device *rdev) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci u64 r = ++rdev->cookie_counter; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci if (WARN_ON(r == 0)) 15462306a36Sopenharmony_ci r = ++rdev->cookie_counter; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci return r; 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ciextern struct workqueue_struct *cfg80211_wq; 16062306a36Sopenharmony_ciextern struct list_head cfg80211_rdev_list; 16162306a36Sopenharmony_ciextern int cfg80211_rdev_list_generation; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistruct cfg80211_internal_bss { 16462306a36Sopenharmony_ci struct list_head list; 16562306a36Sopenharmony_ci struct list_head hidden_list; 16662306a36Sopenharmony_ci struct rb_node rbn; 16762306a36Sopenharmony_ci u64 ts_boottime; 16862306a36Sopenharmony_ci unsigned long ts; 16962306a36Sopenharmony_ci unsigned long refcount; 17062306a36Sopenharmony_ci atomic_t hold; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci /* time at the start of the reception of the first octet of the 17362306a36Sopenharmony_ci * timestamp field of the last beacon/probe received for this BSS. 17462306a36Sopenharmony_ci * The time is the TSF of the BSS specified by %parent_bssid. 17562306a36Sopenharmony_ci */ 17662306a36Sopenharmony_ci u64 parent_tsf; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci /* the BSS according to which %parent_tsf is set. This is set to 17962306a36Sopenharmony_ci * the BSS that the interface that requested the scan was connected to 18062306a36Sopenharmony_ci * when the beacon/probe was received. 18162306a36Sopenharmony_ci */ 18262306a36Sopenharmony_ci u8 parent_bssid[ETH_ALEN] __aligned(2); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci /* must be last because of priv member */ 18562306a36Sopenharmony_ci struct cfg80211_bss pub; 18662306a36Sopenharmony_ci}; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cistatic inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pub) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci return container_of(pub, struct cfg80211_internal_bss, pub); 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci atomic_inc(&bss->hold); 19662306a36Sopenharmony_ci if (bss->pub.transmitted_bss) { 19762306a36Sopenharmony_ci bss = container_of(bss->pub.transmitted_bss, 19862306a36Sopenharmony_ci struct cfg80211_internal_bss, pub); 19962306a36Sopenharmony_ci atomic_inc(&bss->hold); 20062306a36Sopenharmony_ci } 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss) 20462306a36Sopenharmony_ci{ 20562306a36Sopenharmony_ci int r = atomic_dec_return(&bss->hold); 20662306a36Sopenharmony_ci WARN_ON(r < 0); 20762306a36Sopenharmony_ci if (bss->pub.transmitted_bss) { 20862306a36Sopenharmony_ci bss = container_of(bss->pub.transmitted_bss, 20962306a36Sopenharmony_ci struct cfg80211_internal_bss, pub); 21062306a36Sopenharmony_ci r = atomic_dec_return(&bss->hold); 21162306a36Sopenharmony_ci WARN_ON(r < 0); 21262306a36Sopenharmony_ci } 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistruct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); 21762306a36Sopenharmony_ciint get_wiphy_idx(struct wiphy *wiphy); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistruct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ciint cfg80211_switch_netns(struct cfg80211_registered_device *rdev, 22262306a36Sopenharmony_ci struct net *net); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_civoid cfg80211_init_wdev(struct wireless_dev *wdev); 22562306a36Sopenharmony_civoid cfg80211_register_wdev(struct cfg80211_registered_device *rdev, 22662306a36Sopenharmony_ci struct wireless_dev *wdev); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistatic inline void wdev_lock(struct wireless_dev *wdev) 22962306a36Sopenharmony_ci __acquires(wdev) 23062306a36Sopenharmony_ci{ 23162306a36Sopenharmony_ci mutex_lock(&wdev->mtx); 23262306a36Sopenharmony_ci __acquire(wdev->mtx); 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic inline void wdev_unlock(struct wireless_dev *wdev) 23662306a36Sopenharmony_ci __releases(wdev) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci __release(wdev->mtx); 23962306a36Sopenharmony_ci mutex_unlock(&wdev->mtx); 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_cistatic inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) 24562306a36Sopenharmony_ci{ 24662306a36Sopenharmony_ci lockdep_assert_held(&rdev->wiphy.mtx); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci return rdev->num_running_ifaces == rdev->num_running_monitor_ifaces && 24962306a36Sopenharmony_ci rdev->num_running_ifaces > 0; 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cienum cfg80211_event_type { 25362306a36Sopenharmony_ci EVENT_CONNECT_RESULT, 25462306a36Sopenharmony_ci EVENT_ROAMED, 25562306a36Sopenharmony_ci EVENT_DISCONNECTED, 25662306a36Sopenharmony_ci EVENT_IBSS_JOINED, 25762306a36Sopenharmony_ci EVENT_STOPPED, 25862306a36Sopenharmony_ci EVENT_PORT_AUTHORIZED, 25962306a36Sopenharmony_ci}; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistruct cfg80211_event { 26262306a36Sopenharmony_ci struct list_head list; 26362306a36Sopenharmony_ci enum cfg80211_event_type type; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci union { 26662306a36Sopenharmony_ci struct cfg80211_connect_resp_params cr; 26762306a36Sopenharmony_ci struct cfg80211_roam_info rm; 26862306a36Sopenharmony_ci struct { 26962306a36Sopenharmony_ci const u8 *ie; 27062306a36Sopenharmony_ci size_t ie_len; 27162306a36Sopenharmony_ci u16 reason; 27262306a36Sopenharmony_ci bool locally_generated; 27362306a36Sopenharmony_ci } dc; 27462306a36Sopenharmony_ci struct { 27562306a36Sopenharmony_ci u8 bssid[ETH_ALEN]; 27662306a36Sopenharmony_ci struct ieee80211_channel *channel; 27762306a36Sopenharmony_ci } ij; 27862306a36Sopenharmony_ci struct { 27962306a36Sopenharmony_ci u8 bssid[ETH_ALEN]; 28062306a36Sopenharmony_ci const u8 *td_bitmap; 28162306a36Sopenharmony_ci u8 td_bitmap_len; 28262306a36Sopenharmony_ci } pa; 28362306a36Sopenharmony_ci }; 28462306a36Sopenharmony_ci}; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_cistruct cfg80211_cached_keys { 28762306a36Sopenharmony_ci struct key_params params[4]; 28862306a36Sopenharmony_ci u8 data[4][WLAN_KEY_LEN_WEP104]; 28962306a36Sopenharmony_ci int def; 29062306a36Sopenharmony_ci}; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_cistruct cfg80211_beacon_registration { 29362306a36Sopenharmony_ci struct list_head list; 29462306a36Sopenharmony_ci u32 nlportid; 29562306a36Sopenharmony_ci}; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistruct cfg80211_cqm_config { 29862306a36Sopenharmony_ci struct rcu_head rcu_head; 29962306a36Sopenharmony_ci u32 rssi_hyst; 30062306a36Sopenharmony_ci s32 last_rssi_event_value; 30162306a36Sopenharmony_ci enum nl80211_cqm_rssi_threshold_event last_rssi_event_type; 30262306a36Sopenharmony_ci bool use_range_api; 30362306a36Sopenharmony_ci int n_rssi_thresholds; 30462306a36Sopenharmony_ci s32 rssi_thresholds[] __counted_by(n_rssi_thresholds); 30562306a36Sopenharmony_ci}; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_civoid cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, 30862306a36Sopenharmony_ci struct wiphy_work *work); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_civoid cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev); 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci/* free object */ 31362306a36Sopenharmony_civoid cfg80211_dev_free(struct cfg80211_registered_device *rdev); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ciint cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 31662306a36Sopenharmony_ci char *newname); 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_civoid ieee80211_set_bitrate_flags(struct wiphy *wiphy); 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_civoid cfg80211_bss_expire(struct cfg80211_registered_device *rdev); 32162306a36Sopenharmony_civoid cfg80211_bss_age(struct cfg80211_registered_device *rdev, 32262306a36Sopenharmony_ci unsigned long age_secs); 32362306a36Sopenharmony_civoid cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev, 32462306a36Sopenharmony_ci unsigned int link, 32562306a36Sopenharmony_ci struct ieee80211_channel *channel); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci/* IBSS */ 32862306a36Sopenharmony_ciint __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 32962306a36Sopenharmony_ci struct net_device *dev, 33062306a36Sopenharmony_ci struct cfg80211_ibss_params *params, 33162306a36Sopenharmony_ci struct cfg80211_cached_keys *connkeys); 33262306a36Sopenharmony_civoid cfg80211_clear_ibss(struct net_device *dev, bool nowext); 33362306a36Sopenharmony_ciint __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 33462306a36Sopenharmony_ci struct net_device *dev, bool nowext); 33562306a36Sopenharmony_ciint cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 33662306a36Sopenharmony_ci struct net_device *dev, bool nowext); 33762306a36Sopenharmony_civoid __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, 33862306a36Sopenharmony_ci struct ieee80211_channel *channel); 33962306a36Sopenharmony_ciint cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, 34062306a36Sopenharmony_ci struct wireless_dev *wdev); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci/* mesh */ 34362306a36Sopenharmony_ciextern const struct mesh_config default_mesh_config; 34462306a36Sopenharmony_ciextern const struct mesh_setup default_mesh_setup; 34562306a36Sopenharmony_ciint __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 34662306a36Sopenharmony_ci struct net_device *dev, 34762306a36Sopenharmony_ci struct mesh_setup *setup, 34862306a36Sopenharmony_ci const struct mesh_config *conf); 34962306a36Sopenharmony_ciint __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 35062306a36Sopenharmony_ci struct net_device *dev); 35162306a36Sopenharmony_ciint cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 35262306a36Sopenharmony_ci struct net_device *dev); 35362306a36Sopenharmony_ciint cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, 35462306a36Sopenharmony_ci struct wireless_dev *wdev, 35562306a36Sopenharmony_ci struct cfg80211_chan_def *chandef); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci/* OCB */ 35862306a36Sopenharmony_ciint __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, 35962306a36Sopenharmony_ci struct net_device *dev, 36062306a36Sopenharmony_ci struct ocb_setup *setup); 36162306a36Sopenharmony_ciint cfg80211_join_ocb(struct cfg80211_registered_device *rdev, 36262306a36Sopenharmony_ci struct net_device *dev, 36362306a36Sopenharmony_ci struct ocb_setup *setup); 36462306a36Sopenharmony_ciint __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, 36562306a36Sopenharmony_ci struct net_device *dev); 36662306a36Sopenharmony_ciint cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, 36762306a36Sopenharmony_ci struct net_device *dev); 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci/* AP */ 37062306a36Sopenharmony_ciint __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 37162306a36Sopenharmony_ci struct net_device *dev, int link, 37262306a36Sopenharmony_ci bool notify); 37362306a36Sopenharmony_ciint cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 37462306a36Sopenharmony_ci struct net_device *dev, int link, 37562306a36Sopenharmony_ci bool notify); 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci/* MLME */ 37862306a36Sopenharmony_ciint cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 37962306a36Sopenharmony_ci struct net_device *dev, 38062306a36Sopenharmony_ci struct cfg80211_auth_request *req); 38162306a36Sopenharmony_ciint cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 38262306a36Sopenharmony_ci struct net_device *dev, 38362306a36Sopenharmony_ci struct cfg80211_assoc_request *req); 38462306a36Sopenharmony_ciint cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 38562306a36Sopenharmony_ci struct net_device *dev, const u8 *bssid, 38662306a36Sopenharmony_ci const u8 *ie, int ie_len, u16 reason, 38762306a36Sopenharmony_ci bool local_state_change); 38862306a36Sopenharmony_ciint cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, 38962306a36Sopenharmony_ci struct net_device *dev, const u8 *ap_addr, 39062306a36Sopenharmony_ci const u8 *ie, int ie_len, u16 reason, 39162306a36Sopenharmony_ci bool local_state_change); 39262306a36Sopenharmony_civoid cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 39362306a36Sopenharmony_ci struct net_device *dev); 39462306a36Sopenharmony_ciint cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, 39562306a36Sopenharmony_ci u16 frame_type, const u8 *match_data, 39662306a36Sopenharmony_ci int match_len, bool multicast_rx, 39762306a36Sopenharmony_ci struct netlink_ext_ack *extack); 39862306a36Sopenharmony_civoid cfg80211_mgmt_registrations_update_wk(struct work_struct *wk); 39962306a36Sopenharmony_civoid cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); 40062306a36Sopenharmony_civoid cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); 40162306a36Sopenharmony_ciint cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 40262306a36Sopenharmony_ci struct wireless_dev *wdev, 40362306a36Sopenharmony_ci struct cfg80211_mgmt_tx_params *params, 40462306a36Sopenharmony_ci u64 *cookie); 40562306a36Sopenharmony_civoid cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 40662306a36Sopenharmony_ci const struct ieee80211_ht_cap *ht_capa_mask); 40762306a36Sopenharmony_civoid cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa, 40862306a36Sopenharmony_ci const struct ieee80211_vht_cap *vht_capa_mask); 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci/* SME events */ 41162306a36Sopenharmony_ciint cfg80211_connect(struct cfg80211_registered_device *rdev, 41262306a36Sopenharmony_ci struct net_device *dev, 41362306a36Sopenharmony_ci struct cfg80211_connect_params *connect, 41462306a36Sopenharmony_ci struct cfg80211_cached_keys *connkeys, 41562306a36Sopenharmony_ci const u8 *prev_bssid); 41662306a36Sopenharmony_civoid __cfg80211_connect_result(struct net_device *dev, 41762306a36Sopenharmony_ci struct cfg80211_connect_resp_params *params, 41862306a36Sopenharmony_ci bool wextev); 41962306a36Sopenharmony_civoid __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 42062306a36Sopenharmony_ci size_t ie_len, u16 reason, bool from_ap); 42162306a36Sopenharmony_ciint cfg80211_disconnect(struct cfg80211_registered_device *rdev, 42262306a36Sopenharmony_ci struct net_device *dev, u16 reason, 42362306a36Sopenharmony_ci bool wextev); 42462306a36Sopenharmony_civoid __cfg80211_roamed(struct wireless_dev *wdev, 42562306a36Sopenharmony_ci struct cfg80211_roam_info *info); 42662306a36Sopenharmony_civoid __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid, 42762306a36Sopenharmony_ci const u8 *td_bitmap, u8 td_bitmap_len); 42862306a36Sopenharmony_ciint cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 42962306a36Sopenharmony_ci struct wireless_dev *wdev); 43062306a36Sopenharmony_civoid cfg80211_autodisconnect_wk(struct work_struct *work); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci/* SME implementation */ 43362306a36Sopenharmony_civoid cfg80211_conn_work(struct work_struct *work); 43462306a36Sopenharmony_civoid cfg80211_sme_scan_done(struct net_device *dev); 43562306a36Sopenharmony_cibool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status); 43662306a36Sopenharmony_civoid cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len); 43762306a36Sopenharmony_civoid cfg80211_sme_disassoc(struct wireless_dev *wdev); 43862306a36Sopenharmony_civoid cfg80211_sme_deauth(struct wireless_dev *wdev); 43962306a36Sopenharmony_civoid cfg80211_sme_auth_timeout(struct wireless_dev *wdev); 44062306a36Sopenharmony_civoid cfg80211_sme_assoc_timeout(struct wireless_dev *wdev); 44162306a36Sopenharmony_civoid cfg80211_sme_abandon_assoc(struct wireless_dev *wdev); 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci/* internal helpers */ 44462306a36Sopenharmony_cibool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); 44562306a36Sopenharmony_cibool cfg80211_valid_key_idx(struct cfg80211_registered_device *rdev, 44662306a36Sopenharmony_ci int key_idx, bool pairwise); 44762306a36Sopenharmony_ciint cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 44862306a36Sopenharmony_ci struct key_params *params, int key_idx, 44962306a36Sopenharmony_ci bool pairwise, const u8 *mac_addr); 45062306a36Sopenharmony_civoid __cfg80211_scan_done(struct wiphy *wiphy, struct wiphy_work *wk); 45162306a36Sopenharmony_civoid ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, 45262306a36Sopenharmony_ci bool send_message); 45362306a36Sopenharmony_civoid cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev, 45462306a36Sopenharmony_ci struct cfg80211_sched_scan_request *req); 45562306a36Sopenharmony_ciint cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev, 45662306a36Sopenharmony_ci bool want_multi); 45762306a36Sopenharmony_civoid cfg80211_sched_scan_results_wk(struct work_struct *work); 45862306a36Sopenharmony_ciint cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev, 45962306a36Sopenharmony_ci struct cfg80211_sched_scan_request *req, 46062306a36Sopenharmony_ci bool driver_initiated); 46162306a36Sopenharmony_ciint __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, 46262306a36Sopenharmony_ci u64 reqid, bool driver_initiated); 46362306a36Sopenharmony_civoid cfg80211_upload_connect_keys(struct wireless_dev *wdev); 46462306a36Sopenharmony_ciint cfg80211_change_iface(struct cfg80211_registered_device *rdev, 46562306a36Sopenharmony_ci struct net_device *dev, enum nl80211_iftype ntype, 46662306a36Sopenharmony_ci struct vif_params *params); 46762306a36Sopenharmony_civoid cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); 46862306a36Sopenharmony_civoid cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev, 46962306a36Sopenharmony_ci struct wiphy_work *end); 47062306a36Sopenharmony_civoid cfg80211_process_wdev_events(struct wireless_dev *wdev); 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_cibool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, 47362306a36Sopenharmony_ci u32 center_freq_khz, u32 bw_khz); 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ciint cfg80211_scan(struct cfg80211_registered_device *rdev); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ciextern struct work_struct cfg80211_disconnect_work; 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci/** 48062306a36Sopenharmony_ci * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable 48162306a36Sopenharmony_ci * @wiphy: the wiphy to validate against 48262306a36Sopenharmony_ci * @chandef: the channel definition to check 48362306a36Sopenharmony_ci * 48462306a36Sopenharmony_ci * Checks if chandef is usable and we can/need start CAC on such channel. 48562306a36Sopenharmony_ci * 48662306a36Sopenharmony_ci * Return: true if all channels available and at least 48762306a36Sopenharmony_ci * one channel requires CAC (NL80211_DFS_USABLE) 48862306a36Sopenharmony_ci */ 48962306a36Sopenharmony_cibool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, 49062306a36Sopenharmony_ci const struct cfg80211_chan_def *chandef); 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_civoid cfg80211_set_dfs_state(struct wiphy *wiphy, 49362306a36Sopenharmony_ci const struct cfg80211_chan_def *chandef, 49462306a36Sopenharmony_ci enum nl80211_dfs_state dfs_state); 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_civoid cfg80211_dfs_channels_update_work(struct work_struct *work); 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ciunsigned int 49962306a36Sopenharmony_cicfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, 50062306a36Sopenharmony_ci const struct cfg80211_chan_def *chandef); 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_civoid cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ciint 50562306a36Sopenharmony_cicfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, 50662306a36Sopenharmony_ci struct wireless_dev *wdev, 50762306a36Sopenharmony_ci struct cfg80211_chan_def *chandef); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_civoid cfg80211_stop_background_radar_detection(struct wireless_dev *wdev); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_civoid cfg80211_background_cac_done_wk(struct work_struct *work); 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_civoid cfg80211_background_cac_abort_wk(struct work_struct *work); 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_cibool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, 51662306a36Sopenharmony_ci struct ieee80211_channel *chan); 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_cibool cfg80211_beaconing_iface_active(struct wireless_dev *wdev); 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_cibool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef, 52162306a36Sopenharmony_ci struct ieee80211_channel *chan, 52262306a36Sopenharmony_ci bool primary_only); 52362306a36Sopenharmony_cibool cfg80211_wdev_on_sub_chan(struct wireless_dev *wdev, 52462306a36Sopenharmony_ci struct ieee80211_channel *chan, 52562306a36Sopenharmony_ci bool primary_only); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_cistatic inline unsigned int elapsed_jiffies_msecs(unsigned long start) 52862306a36Sopenharmony_ci{ 52962306a36Sopenharmony_ci unsigned long end = jiffies; 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci if (end >= start) 53262306a36Sopenharmony_ci return jiffies_to_msecs(end - start); 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci return jiffies_to_msecs(end + (ULONG_MAX - start) + 1); 53562306a36Sopenharmony_ci} 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ciint cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, 53862306a36Sopenharmony_ci struct cfg80211_chan_def *chandef); 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ciint ieee80211_get_ratemask(struct ieee80211_supported_band *sband, 54162306a36Sopenharmony_ci const u8 *rates, unsigned int n_rates, 54262306a36Sopenharmony_ci u32 *mask); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ciint cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, 54562306a36Sopenharmony_ci enum nl80211_iftype iftype, u32 beacon_int); 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_civoid cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, 54862306a36Sopenharmony_ci enum nl80211_iftype iftype, int num); 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_civoid __cfg80211_leave(struct cfg80211_registered_device *rdev, 55162306a36Sopenharmony_ci struct wireless_dev *wdev); 55262306a36Sopenharmony_civoid cfg80211_leave(struct cfg80211_registered_device *rdev, 55362306a36Sopenharmony_ci struct wireless_dev *wdev); 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_civoid cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, 55662306a36Sopenharmony_ci struct wireless_dev *wdev); 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_civoid cfg80211_stop_nan(struct cfg80211_registered_device *rdev, 55962306a36Sopenharmony_ci struct wireless_dev *wdev); 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_cistruct cfg80211_internal_bss * 56262306a36Sopenharmony_cicfg80211_bss_update(struct cfg80211_registered_device *rdev, 56362306a36Sopenharmony_ci struct cfg80211_internal_bss *tmp, 56462306a36Sopenharmony_ci bool signal_valid, unsigned long ts); 56562306a36Sopenharmony_ci#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 56662306a36Sopenharmony_ci#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) 56762306a36Sopenharmony_ci#else 56862306a36Sopenharmony_ci/* 56962306a36Sopenharmony_ci * Trick to enable using it as a condition, 57062306a36Sopenharmony_ci * and also not give a warning when it's 57162306a36Sopenharmony_ci * not used that way. 57262306a36Sopenharmony_ci */ 57362306a36Sopenharmony_ci#define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; }) 57462306a36Sopenharmony_ci#endif 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_civoid cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid); 57762306a36Sopenharmony_civoid cfg80211_pmsr_wdev_down(struct wireless_dev *wdev); 57862306a36Sopenharmony_civoid cfg80211_pmsr_free_wk(struct work_struct *work); 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_civoid cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id); 58162306a36Sopenharmony_civoid cfg80211_remove_links(struct wireless_dev *wdev); 58262306a36Sopenharmony_ciint cfg80211_remove_virtual_intf(struct cfg80211_registered_device *rdev, 58362306a36Sopenharmony_ci struct wireless_dev *wdev); 58462306a36Sopenharmony_civoid cfg80211_wdev_release_link_bsses(struct wireless_dev *wdev, u16 link_mask); 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci#endif /* __NET_WIRELESS_CORE_H */ 587