1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2704232c2SJohannes Berg /*
3704232c2SJohannes Berg * Wireless configuration interface internals.
4704232c2SJohannes Berg *
55f2aa25eSJohannes Berg * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
634c9a0e7SJohannes Berg * Copyright (C) 2018-2022 Intel Corporation
7704232c2SJohannes Berg */
8704232c2SJohannes Berg #ifndef __NET_WIRELESS_CORE_H
9704232c2SJohannes Berg #define __NET_WIRELESS_CORE_H
10704232c2SJohannes Berg #include <linux/list.h>
11704232c2SJohannes Berg #include <linux/netdevice.h>
122a519311SJohannes Berg #include <linux/rbtree.h>
131ac61302SLuis R. Rodriguez #include <linux/debugfs.h>
141f87f7d3SJohannes Berg #include <linux/rfkill.h>
151f87f7d3SJohannes Berg #include <linux/workqueue.h>
16c5a7e582SJohannes Berg #include <linux/rtnetlink.h>
17704232c2SJohannes Berg #include <net/genetlink.h>
18704232c2SJohannes Berg #include <net/cfg80211.h>
193f2355cbSLuis R. Rodriguez #include "reg.h"
20704232c2SJohannes Berg
21f4173766SJohannes Berg
22f4173766SJohannes Berg #define WIPHY_IDX_INVALID -1
23f4173766SJohannes Berg
24704232c2SJohannes Berg struct cfg80211_registered_device {
253dcf670bSDavid Kilroy const struct cfg80211_ops *ops;
26704232c2SJohannes Berg struct list_head list;
27704232c2SJohannes Berg
281f87f7d3SJohannes Berg /* rfkill support */
291f87f7d3SJohannes Berg struct rfkill_ops rfkill_ops;
303cfe91c4SJohannes Berg struct work_struct rfkill_block;
311f87f7d3SJohannes Berg
323f2355cbSLuis R. Rodriguez /* ISO / IEC 3166 alpha2 for which this device is receiving
333f2355cbSLuis R. Rodriguez * country IEs on, this can help disregard country IEs from APs
343f2355cbSLuis R. Rodriguez * on the same alpha2 quickly. The alpha2 may differ from
353f2355cbSLuis R. Rodriguez * cfg80211_regdomain's alpha2 when an intersection has occurred.
363f2355cbSLuis R. Rodriguez * If the AP is reconfigured this can also be used to tell us if
373f2355cbSLuis R. Rodriguez * the country on the country IE changed. */
383f2355cbSLuis R. Rodriguez char country_ie_alpha2[2];
393f2355cbSLuis R. Rodriguez
40b0d7aa59SJonathan Doron /*
41b0d7aa59SJonathan Doron * the driver requests the regulatory core to set this regulatory
42b0d7aa59SJonathan Doron * domain as the wiphy's. Only used for %REGULATORY_WIPHY_SELF_MANAGED
43b0d7aa59SJonathan Doron * devices using the regulatory_set_wiphy_regd() API
44b0d7aa59SJonathan Doron */
45b0d7aa59SJonathan Doron const struct ieee80211_regdomain *requested_regd;
46b0d7aa59SJonathan Doron
473f2355cbSLuis R. Rodriguez /* If a Country IE has been received this tells us the environment
483f2355cbSLuis R. Rodriguez * which its telling us its in. This defaults to ENVIRON_ANY */
493f2355cbSLuis R. Rodriguez enum environment_cap env;
503f2355cbSLuis R. Rodriguez
51704232c2SJohannes Berg /* wiphy index, internal only */
52b5850a7aSLuis R. Rodriguez int wiphy_idx;
53704232c2SJohannes Berg
5453873f13SJohannes Berg /* protected by RTNL */
5589a54e48SJohannes Berg int devlist_generation, wdev_id;
568b9b2f06SJohannes Berg int opencount;
57ad002395SJohannes Berg wait_queue_head_t dev_wait;
58704232c2SJohannes Berg
5937c73b5fSBen Greear struct list_head beacon_registrations;
6037c73b5fSBen Greear spinlock_t beacon_registrations_lock;
615e760230SJohannes Berg
62c5a7e582SJohannes Berg /* protected by RTNL only */
63dbbae26aSMichal Kazior int num_running_ifaces;
64dbbae26aSMichal Kazior int num_running_monitor_ifaces;
65b60ad348SJohannes Berg u64 cookie_counter;
66dbbae26aSMichal Kazior
672a519311SJohannes Berg /* BSSes/scanning */
682a519311SJohannes Berg spinlock_t bss_lock;
692a519311SJohannes Berg struct list_head bss_list;
702a519311SJohannes Berg struct rb_root bss_tree;
712a519311SJohannes Berg u32 bss_generation;
729853a55eSJohannes Berg u32 bss_entries;
732a519311SJohannes Berg struct cfg80211_scan_request *scan_req; /* protected by RTNL */
74c8cb5b85STova Mussai struct cfg80211_scan_request *int_scan_req;
75f9d15d16SJohannes Berg struct sk_buff *scan_msg;
76ca986ad9SArend Van Spriel struct list_head sched_scan_req_list;
77fe0984d3SArnd Bergmann time64_t suspend_at;
78fe0af9feSJohannes Berg struct wiphy_work scan_done_wk;
792a519311SJohannes Berg
80ad7e718cSJohannes Berg struct genl_info *cur_cmd_info;
81aff89a9bSJohannes Berg
826829c878SJohannes Berg struct work_struct conn_work;
83667503ddSJohannes Berg struct work_struct event_work;
846829c878SJohannes Berg
8504f39047SSimon Wunderlich struct delayed_work dfs_update_channels_wk;
8604f39047SSimon Wunderlich
87a95bfb87SLorenzo Bianconi struct wireless_dev *background_radar_wdev;
88a95bfb87SLorenzo Bianconi struct cfg80211_chan_def background_radar_chandef;
89a95bfb87SLorenzo Bianconi struct delayed_work background_cac_done_wk;
90a95bfb87SLorenzo Bianconi struct work_struct background_cac_abort_wk;
91bc2dfc02SLorenzo Bianconi
925de17984SArend van Spriel /* netlink port which started critical protocol (0 means not started) */
935de17984SArend van Spriel u32 crit_proto_nlportid;
945de17984SArend van Spriel
95be29b99aSAmitkumar Karwar struct cfg80211_coalesce *coalesce;
96be29b99aSAmitkumar Karwar
9778f22b6aSJohannes Berg struct work_struct destroy_work;
98c88d7178SJohannes Berg struct wiphy_work sched_scan_stop_wk;
99b34939b9SArend Van Spriel struct work_struct sched_scan_res_wk;
10093a1e86cSJukka Rissanen
10189766727SVasanthakumar Thiagarajan struct cfg80211_chan_def radar_chandef;
10289766727SVasanthakumar Thiagarajan struct work_struct propagate_radar_detect_wk;
10389766727SVasanthakumar Thiagarajan
10489766727SVasanthakumar Thiagarajan struct cfg80211_chan_def cac_done_chandef;
10589766727SVasanthakumar Thiagarajan struct work_struct propagate_cac_done_wk;
10689766727SVasanthakumar Thiagarajan
10779ea1e12SJohannes Berg struct work_struct mgmt_registrations_update_wk;
10809b1d5dcSJohannes Berg /* lock for all wdev lists */
10909b1d5dcSJohannes Berg spinlock_t mgmt_registrations_lock;
11079ea1e12SJohannes Berg
111a3ee4dc8SJohannes Berg struct work_struct wiphy_work;
112a3ee4dc8SJohannes Berg struct list_head wiphy_work_list;
113a3ee4dc8SJohannes Berg /* protects the list above */
114a3ee4dc8SJohannes Berg spinlock_t wiphy_work_lock;
115a3ee4dc8SJohannes Berg bool suspended;
116a3ee4dc8SJohannes Berg
117704232c2SJohannes Berg /* must be last because of the way we do wiphy_priv(),
118704232c2SJohannes Berg * and it should at least be aligned to NETDEV_ALIGN */
1191c06ef98SJohannes Berg struct wiphy wiphy __aligned(NETDEV_ALIGN);
120704232c2SJohannes Berg };
121704232c2SJohannes Berg
122704232c2SJohannes Berg static inline
wiphy_to_rdev(struct wiphy * wiphy)123f26cbf40SZhao, Gang struct cfg80211_registered_device *wiphy_to_rdev(struct wiphy *wiphy)
124704232c2SJohannes Berg {
125704232c2SJohannes Berg BUG_ON(!wiphy);
126704232c2SJohannes Berg return container_of(wiphy, struct cfg80211_registered_device, wiphy);
127704232c2SJohannes Berg }
128704232c2SJohannes Berg
129ff1b6e69SJohannes Berg static inline void
cfg80211_rdev_free_wowlan(struct cfg80211_registered_device * rdev)130ff1b6e69SJohannes Berg cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
131ff1b6e69SJohannes Berg {
1326abb9cb9SJohannes Berg #ifdef CONFIG_PM
133ff1b6e69SJohannes Berg int i;
134ff1b6e69SJohannes Berg
1356abb9cb9SJohannes Berg if (!rdev->wiphy.wowlan_config)
136ff1b6e69SJohannes Berg return;
1376abb9cb9SJohannes Berg for (i = 0; i < rdev->wiphy.wowlan_config->n_patterns; i++)
1386abb9cb9SJohannes Berg kfree(rdev->wiphy.wowlan_config->patterns[i].mask);
1396abb9cb9SJohannes Berg kfree(rdev->wiphy.wowlan_config->patterns);
1406abb9cb9SJohannes Berg if (rdev->wiphy.wowlan_config->tcp &&
1416abb9cb9SJohannes Berg rdev->wiphy.wowlan_config->tcp->sock)
1426abb9cb9SJohannes Berg sock_release(rdev->wiphy.wowlan_config->tcp->sock);
1436abb9cb9SJohannes Berg kfree(rdev->wiphy.wowlan_config->tcp);
1448cd4d456SLuciano Coelho kfree(rdev->wiphy.wowlan_config->nd_config);
1456abb9cb9SJohannes Berg kfree(rdev->wiphy.wowlan_config);
1466abb9cb9SJohannes Berg #endif
147ff1b6e69SJohannes Berg }
148e60d7443SAlban Browaeys
cfg80211_assign_cookie(struct cfg80211_registered_device * rdev)149b60ad348SJohannes Berg static inline u64 cfg80211_assign_cookie(struct cfg80211_registered_device *rdev)
150b60ad348SJohannes Berg {
151b60ad348SJohannes Berg u64 r = ++rdev->cookie_counter;
152b60ad348SJohannes Berg
153b60ad348SJohannes Berg if (WARN_ON(r == 0))
154b60ad348SJohannes Berg r = ++rdev->cookie_counter;
155b60ad348SJohannes Berg
156b60ad348SJohannes Berg return r;
157b60ad348SJohannes Berg }
158b60ad348SJohannes Berg
159e60d7443SAlban Browaeys extern struct workqueue_struct *cfg80211_wq;
16079c97e97SJohannes Berg extern struct list_head cfg80211_rdev_list;
161f5ea9120SJohannes Berg extern int cfg80211_rdev_list_generation;
162704232c2SJohannes Berg
1632a519311SJohannes Berg struct cfg80211_internal_bss {
1642a519311SJohannes Berg struct list_head list;
165776b3580SJohannes Berg struct list_head hidden_list;
1662a519311SJohannes Berg struct rb_node rbn;
1676e19bc4bSDmitry Shmidt u64 ts_boottime;
1682a519311SJohannes Berg unsigned long ts;
169776b3580SJohannes Berg unsigned long refcount;
17019957bb3SJohannes Berg atomic_t hold;
171a08c1c1aSKalle Valo
1721d76250bSAvraham Stern /* time at the start of the reception of the first octet of the
1731d76250bSAvraham Stern * timestamp field of the last beacon/probe received for this BSS.
1741d76250bSAvraham Stern * The time is the TSF of the BSS specified by %parent_bssid.
1751d76250bSAvraham Stern */
1761d76250bSAvraham Stern u64 parent_tsf;
1771d76250bSAvraham Stern
1781d76250bSAvraham Stern /* the BSS according to which %parent_tsf is set. This is set to
1791d76250bSAvraham Stern * the BSS that the interface that requested the scan was connected to
1801d76250bSAvraham Stern * when the beacon/probe was received.
1811d76250bSAvraham Stern */
1821d76250bSAvraham Stern u8 parent_bssid[ETH_ALEN] __aligned(2);
1831d76250bSAvraham Stern
1842a519311SJohannes Berg /* must be last because of priv member */
1852a519311SJohannes Berg struct cfg80211_bss pub;
1862a519311SJohannes Berg };
1872a519311SJohannes Berg
bss_from_pub(struct cfg80211_bss * pub)18819957bb3SJohannes Berg static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pub)
18919957bb3SJohannes Berg {
19019957bb3SJohannes Berg return container_of(pub, struct cfg80211_internal_bss, pub);
19119957bb3SJohannes Berg }
19219957bb3SJohannes Berg
cfg80211_hold_bss(struct cfg80211_internal_bss * bss)19319957bb3SJohannes Berg static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
19419957bb3SJohannes Berg {
19519957bb3SJohannes Berg atomic_inc(&bss->hold);
1967011ba58SSara Sharon if (bss->pub.transmitted_bss) {
1977011ba58SSara Sharon bss = container_of(bss->pub.transmitted_bss,
198a3584f56SSara Sharon struct cfg80211_internal_bss, pub);
199a3584f56SSara Sharon atomic_inc(&bss->hold);
200a3584f56SSara Sharon }
20119957bb3SJohannes Berg }
20219957bb3SJohannes Berg
cfg80211_unhold_bss(struct cfg80211_internal_bss * bss)20319957bb3SJohannes Berg static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
20419957bb3SJohannes Berg {
20519957bb3SJohannes Berg int r = atomic_dec_return(&bss->hold);
20619957bb3SJohannes Berg WARN_ON(r < 0);
2077011ba58SSara Sharon if (bss->pub.transmitted_bss) {
2087011ba58SSara Sharon bss = container_of(bss->pub.transmitted_bss,
209a3584f56SSara Sharon struct cfg80211_internal_bss, pub);
210a3584f56SSara Sharon r = atomic_dec_return(&bss->hold);
211a3584f56SSara Sharon WARN_ON(r < 0);
212a3584f56SSara Sharon }
21319957bb3SJohannes Berg }
21419957bb3SJohannes Berg
21519957bb3SJohannes Berg
21679c97e97SJohannes Berg struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
217806a9e39SLuis R. Rodriguez int get_wiphy_idx(struct wiphy *wiphy);
218806a9e39SLuis R. Rodriguez
219806a9e39SLuis R. Rodriguez struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
220806a9e39SLuis R. Rodriguez
221463d0183SJohannes Berg int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
222463d0183SJohannes Berg struct net *net);
22355682965SJohannes Berg
2249bdaf3b9SJohannes Berg void cfg80211_init_wdev(struct wireless_dev *wdev);
2259bdaf3b9SJohannes Berg void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
226e4d4216eSJohannes Berg struct wireless_dev *wdev);
227e4d4216eSJohannes Berg
wdev_lock(struct wireless_dev * wdev)228667503ddSJohannes Berg static inline void wdev_lock(struct wireless_dev *wdev)
229667503ddSJohannes Berg __acquires(wdev)
230667503ddSJohannes Berg {
231667503ddSJohannes Berg mutex_lock(&wdev->mtx);
232667503ddSJohannes Berg __acquire(wdev->mtx);
233667503ddSJohannes Berg }
234667503ddSJohannes Berg
wdev_unlock(struct wireless_dev * wdev)235667503ddSJohannes Berg static inline void wdev_unlock(struct wireless_dev *wdev)
236667503ddSJohannes Berg __releases(wdev)
237667503ddSJohannes Berg {
238667503ddSJohannes Berg __release(wdev->mtx);
239667503ddSJohannes Berg mutex_unlock(&wdev->mtx);
240667503ddSJohannes Berg }
241667503ddSJohannes Berg
242*53dc61aeSPing-Ke Shih #define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
243667503ddSJohannes Berg
cfg80211_has_monitors_only(struct cfg80211_registered_device * rdev)244dbbae26aSMichal Kazior static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)
245dbbae26aSMichal Kazior {
246a05829a7SJohannes Berg lockdep_assert_held(&rdev->wiphy.mtx);
247dbbae26aSMichal Kazior
248dbbae26aSMichal Kazior return rdev->num_running_ifaces == rdev->num_running_monitor_ifaces &&
249dbbae26aSMichal Kazior rdev->num_running_ifaces > 0;
250dbbae26aSMichal Kazior }
251dbbae26aSMichal Kazior
252667503ddSJohannes Berg enum cfg80211_event_type {
253667503ddSJohannes Berg EVENT_CONNECT_RESULT,
254667503ddSJohannes Berg EVENT_ROAMED,
255667503ddSJohannes Berg EVENT_DISCONNECTED,
256667503ddSJohannes Berg EVENT_IBSS_JOINED,
257f04c2203SMichal Kazior EVENT_STOPPED,
258503c1fb9SAvraham Stern EVENT_PORT_AUTHORIZED,
259667503ddSJohannes Berg };
260667503ddSJohannes Berg
261667503ddSJohannes Berg struct cfg80211_event {
262667503ddSJohannes Berg struct list_head list;
263667503ddSJohannes Berg enum cfg80211_event_type type;
264667503ddSJohannes Berg
265667503ddSJohannes Berg union {
2665349a0f7SVidyullatha Kanchanapally struct cfg80211_connect_resp_params cr;
26729ce6ecbSAvraham Stern struct cfg80211_roam_info rm;
268667503ddSJohannes Berg struct {
269667503ddSJohannes Berg const u8 *ie;
270667503ddSJohannes Berg size_t ie_len;
271667503ddSJohannes Berg u16 reason;
27280279fb7SJohannes Berg bool locally_generated;
273667503ddSJohannes Berg } dc;
274667503ddSJohannes Berg struct {
275667503ddSJohannes Berg u8 bssid[ETH_ALEN];
276fe94f3a4SAntonio Quartulli struct ieee80211_channel *channel;
277667503ddSJohannes Berg } ij;
278503c1fb9SAvraham Stern struct {
279503c1fb9SAvraham Stern u8 bssid[ETH_ALEN];
2800ff57171SVinayak Yadawad const u8 *td_bitmap;
2810ff57171SVinayak Yadawad u8 td_bitmap_len;
282503c1fb9SAvraham Stern } pa;
283667503ddSJohannes Berg };
284667503ddSJohannes Berg };
285667503ddSJohannes Berg
286fffd0934SJohannes Berg struct cfg80211_cached_keys {
287585b6e13SJohannes Berg struct key_params params[4];
288585b6e13SJohannes Berg u8 data[4][WLAN_KEY_LEN_WEP104];
28989b706fbSJohannes Berg int def;
290fffd0934SJohannes Berg };
291fffd0934SJohannes Berg
29237c73b5fSBen Greear struct cfg80211_beacon_registration {
29337c73b5fSBen Greear struct list_head list;
29437c73b5fSBen Greear u32 nlportid;
29537c73b5fSBen Greear };
296667503ddSJohannes Berg
2974a4b8169SAndrew Zaborowski struct cfg80211_cqm_config {
29837c20b2eSJohannes Berg struct rcu_head rcu_head;
2994a4b8169SAndrew Zaborowski u32 rssi_hyst;
3004a4b8169SAndrew Zaborowski s32 last_rssi_event_value;
30137c20b2eSJohannes Berg enum nl80211_cqm_rssi_threshold_event last_rssi_event_type;
302d6730990SJohannes Berg bool use_range_api;
3034a4b8169SAndrew Zaborowski int n_rssi_thresholds;
304d4d3aaf2SKees Cook s32 rssi_thresholds[] __counted_by(n_rssi_thresholds);
3054a4b8169SAndrew Zaborowski };
3064a4b8169SAndrew Zaborowski
30737c20b2eSJohannes Berg void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy,
30837c20b2eSJohannes Berg struct wiphy_work *work);
30937c20b2eSJohannes Berg
31078f22b6aSJohannes Berg void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev);
31178f22b6aSJohannes Berg
312704232c2SJohannes Berg /* free object */
313c1b1203dSJoe Perches void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
314704232c2SJohannes Berg
315c1b1203dSJoe Perches int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
31655682965SJohannes Berg char *newname);
31755682965SJohannes Berg
3188318d78aSJohannes Berg void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
3198318d78aSJohannes Berg
3201b8ec87aSZhao, Gang void cfg80211_bss_expire(struct cfg80211_registered_device *rdev);
3211b8ec87aSZhao, Gang void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
322cb3a8eecSDan Williams unsigned long age_secs);
3230afd425bSSergey Matyukevich void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
3247b0a0e3cSJohannes Berg unsigned int link,
3250afd425bSSergey Matyukevich struct ieee80211_channel *channel);
3262a519311SJohannes Berg
32704a773adSJohannes Berg /* IBSS */
328f8d16d3eSDenis Kenzior int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
32904a773adSJohannes Berg struct net_device *dev,
330fffd0934SJohannes Berg struct cfg80211_ibss_params *params,
331fffd0934SJohannes Berg struct cfg80211_cached_keys *connkeys);
3329d308429SJohannes Berg void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
33398d3a7caSJohannes Berg int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
33498d3a7caSJohannes Berg struct net_device *dev, bool nowext);
33504a773adSJohannes Berg int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
3369d308429SJohannes Berg struct net_device *dev, bool nowext);
337fe94f3a4SAntonio Quartulli void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
338fe94f3a4SAntonio Quartulli struct ieee80211_channel *channel);
339fffd0934SJohannes Berg int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
340fffd0934SJohannes Berg struct wireless_dev *wdev);
34104a773adSJohannes Berg
34229cbe68cSJohannes Berg /* mesh */
34329cbe68cSJohannes Berg extern const struct mesh_config default_mesh_config;
344c80d545dSJavier Cardona extern const struct mesh_setup default_mesh_setup;
34529cbe68cSJohannes Berg int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
34629cbe68cSJohannes Berg struct net_device *dev,
347cc1d2806SJohannes Berg struct mesh_setup *setup,
34829cbe68cSJohannes Berg const struct mesh_config *conf);
349f04c2203SMichal Kazior int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
350f04c2203SMichal Kazior struct net_device *dev);
35129cbe68cSJohannes Berg int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
35229cbe68cSJohannes Berg struct net_device *dev);
353683b6d3bSJohannes Berg int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
354683b6d3bSJohannes Berg struct wireless_dev *wdev,
355683b6d3bSJohannes Berg struct cfg80211_chan_def *chandef);
35629cbe68cSJohannes Berg
3576e0bd6c3SRostislav Lisovy /* OCB */
3586e0bd6c3SRostislav Lisovy int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
3596e0bd6c3SRostislav Lisovy struct net_device *dev,
3606e0bd6c3SRostislav Lisovy struct ocb_setup *setup);
3616e0bd6c3SRostislav Lisovy int cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
3626e0bd6c3SRostislav Lisovy struct net_device *dev,
3636e0bd6c3SRostislav Lisovy struct ocb_setup *setup);
3646e0bd6c3SRostislav Lisovy int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
3656e0bd6c3SRostislav Lisovy struct net_device *dev);
3666e0bd6c3SRostislav Lisovy int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
3676e0bd6c3SRostislav Lisovy struct net_device *dev);
3686e0bd6c3SRostislav Lisovy
36960771780SMichal Kazior /* AP */
370f04c2203SMichal Kazior int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
3717b0a0e3cSJohannes Berg struct net_device *dev, int link,
3727b0a0e3cSJohannes Berg bool notify);
37360771780SMichal Kazior int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
3747b0a0e3cSJohannes Berg struct net_device *dev, int link,
3757b0a0e3cSJohannes Berg bool notify);
37660771780SMichal Kazior
37719957bb3SJohannes Berg /* MLME */
37891bf9b26SJohannes Berg int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
379667503ddSJohannes Berg struct net_device *dev,
380325839daSJohannes Berg struct cfg80211_auth_request *req);
38119957bb3SJohannes Berg int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
382f62fab73SJohannes Berg struct net_device *dev,
383f62fab73SJohannes Berg struct cfg80211_assoc_request *req);
38419957bb3SJohannes Berg int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
38519957bb3SJohannes Berg struct net_device *dev, const u8 *bssid,
386d5cdfacbSJouni Malinen const u8 *ie, int ie_len, u16 reason,
387d5cdfacbSJouni Malinen bool local_state_change);
38819957bb3SJohannes Berg int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
3898f6e0dfcSJohannes Berg struct net_device *dev, const u8 *ap_addr,
390d5cdfacbSJouni Malinen const u8 *ie, int ie_len, u16 reason,
391d5cdfacbSJouni Malinen bool local_state_change);
39219957bb3SJohannes Berg void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
39319957bb3SJohannes Berg struct net_device *dev);
3942e161f78SJohannes Berg int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
3952e161f78SJohannes Berg u16 frame_type, const u8 *match_data,
3969dba48a6SJohannes Berg int match_len, bool multicast_rx,
3979dba48a6SJohannes Berg struct netlink_ext_ack *extack);
3986cd536feSJohannes Berg void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk);
3992e161f78SJohannes Berg void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
4002e161f78SJohannes Berg void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
4012e161f78SJohannes Berg int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
40271bbc994SJohannes Berg struct wireless_dev *wdev,
403b176e629SAndrei Otcheretianski struct cfg80211_mgmt_tx_params *params,
404b176e629SAndrei Otcheretianski u64 *cookie);
4057e7c8926SBen Greear void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
4067e7c8926SBen Greear const struct ieee80211_ht_cap *ht_capa_mask);
407ee2aca34SJohannes Berg void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
408ee2aca34SJohannes Berg const struct ieee80211_vht_cap *vht_capa_mask);
40919957bb3SJohannes Berg
410ceca7b71SJohannes Berg /* SME events */
41183739b03SJohannes Berg int cfg80211_connect(struct cfg80211_registered_device *rdev,
412667503ddSJohannes Berg struct net_device *dev,
413fffd0934SJohannes Berg struct cfg80211_connect_params *connect,
414f401a6f7SJohannes Berg struct cfg80211_cached_keys *connkeys,
415f401a6f7SJohannes Berg const u8 *prev_bssid);
4165349a0f7SVidyullatha Kanchanapally void __cfg80211_connect_result(struct net_device *dev,
4175349a0f7SVidyullatha Kanchanapally struct cfg80211_connect_resp_params *params,
4185349a0f7SVidyullatha Kanchanapally bool wextev);
419ceca7b71SJohannes Berg void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
420ceca7b71SJohannes Berg size_t ie_len, u16 reason, bool from_ap);
421b23aa676SSamuel Ortiz int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
422f2129354SJohannes Berg struct net_device *dev, u16 reason,
423f2129354SJohannes Berg bool wextev);
424ed9d0102SJouni Malinen void __cfg80211_roamed(struct wireless_dev *wdev,
42529ce6ecbSAvraham Stern struct cfg80211_roam_info *info);
4260ff57171SVinayak Yadawad void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
4270ff57171SVinayak Yadawad const u8 *td_bitmap, u8 td_bitmap_len);
428fffd0934SJohannes Berg int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
429fffd0934SJohannes Berg struct wireless_dev *wdev);
430bd2522b1SAndrzej Zaborowski void cfg80211_autodisconnect_wk(struct work_struct *work);
431b23aa676SSamuel Ortiz
432ceca7b71SJohannes Berg /* SME implementation */
4336829c878SJohannes Berg void cfg80211_conn_work(struct work_struct *work);
434ceca7b71SJohannes Berg void cfg80211_sme_scan_done(struct net_device *dev);
435ceca7b71SJohannes Berg bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status);
436ceca7b71SJohannes Berg void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len);
437ceca7b71SJohannes Berg void cfg80211_sme_disassoc(struct wireless_dev *wdev);
438ceca7b71SJohannes Berg void cfg80211_sme_deauth(struct wireless_dev *wdev);
439ceca7b71SJohannes Berg void cfg80211_sme_auth_timeout(struct wireless_dev *wdev);
440ceca7b71SJohannes Berg void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev);
441e6f462dfSJohannes Berg void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev);
4426829c878SJohannes Berg
44308645126SJohannes Berg /* internal helpers */
44438ba3c57SJouni Malinen bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
4452d946308SAnant Thazhemadam bool cfg80211_valid_key_idx(struct cfg80211_registered_device *rdev,
4462d946308SAnant Thazhemadam int key_idx, bool pairwise);
447fffd0934SJohannes Berg int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
448fffd0934SJohannes Berg struct key_params *params, int key_idx,
449e31b8213SJohannes Berg bool pairwise, const u8 *mac_addr);
450fe0af9feSJohannes Berg void __cfg80211_scan_done(struct wiphy *wiphy, struct wiphy_work *wk);
451f9d15d16SJohannes Berg void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
452f9d15d16SJohannes Berg bool send_message);
453ca986ad9SArend Van Spriel void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
454ca986ad9SArend Van Spriel struct cfg80211_sched_scan_request *req);
455ca986ad9SArend Van Spriel int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
456ca986ad9SArend Van Spriel bool want_multi);
457b34939b9SArend Van Spriel void cfg80211_sched_scan_results_wk(struct work_struct *work);
458ca986ad9SArend Van Spriel int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
459ca986ad9SArend Van Spriel struct cfg80211_sched_scan_request *req,
460807f8a8cSLuciano Coelho bool driver_initiated);
461ca986ad9SArend Van Spriel int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
462ca986ad9SArend Van Spriel u64 reqid, bool driver_initiated);
463fffd0934SJohannes Berg void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
4643d54d255SJohannes Berg int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
4653d54d255SJohannes Berg struct net_device *dev, enum nl80211_iftype ntype,
466818a986eSJohannes Berg struct vif_params *params);
4673d54d255SJohannes Berg void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
4685d9eefa2SJohannes Berg void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev,
4695d9eefa2SJohannes Berg struct wiphy_work *end);
4701f6fc43eSDaniel Drake void cfg80211_process_wdev_events(struct wireless_dev *wdev);
47108645126SJohannes Berg
4724787cfa0SRafał Miłecki bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range,
4734787cfa0SRafał Miłecki u32 center_freq_khz, u32 bw_khz);
4744787cfa0SRafał Miłecki
475c8cb5b85STova Mussai int cfg80211_scan(struct cfg80211_registered_device *rdev);
476c8cb5b85STova Mussai
477e005bd7dSJohannes Berg extern struct work_struct cfg80211_disconnect_work;
478e005bd7dSJohannes Berg
479fe7c3a1fSJanusz Dziedzic /**
480fe7c3a1fSJanusz Dziedzic * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable
481fe7c3a1fSJanusz Dziedzic * @wiphy: the wiphy to validate against
482fe7c3a1fSJanusz Dziedzic * @chandef: the channel definition to check
483fe7c3a1fSJanusz Dziedzic *
484fe7c3a1fSJanusz Dziedzic * Checks if chandef is usable and we can/need start CAC on such channel.
485fe7c3a1fSJanusz Dziedzic *
486b42c8edfSRandy Dunlap * Return: true if all channels available and at least
487b42c8edfSRandy Dunlap * one channel requires CAC (NL80211_DFS_USABLE)
488fe7c3a1fSJanusz Dziedzic */
489fe7c3a1fSJanusz Dziedzic bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
490fe7c3a1fSJanusz Dziedzic const struct cfg80211_chan_def *chandef);
491fe7c3a1fSJanusz Dziedzic
49204f39047SSimon Wunderlich void cfg80211_set_dfs_state(struct wiphy *wiphy,
49304f39047SSimon Wunderlich const struct cfg80211_chan_def *chandef,
49404f39047SSimon Wunderlich enum nl80211_dfs_state dfs_state);
49504f39047SSimon Wunderlich
49604f39047SSimon Wunderlich void cfg80211_dfs_channels_update_work(struct work_struct *work);
49704f39047SSimon Wunderlich
49831559f35SJanusz Dziedzic unsigned int
49931559f35SJanusz Dziedzic cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
50031559f35SJanusz Dziedzic const struct cfg80211_chan_def *chandef);
50104f39047SSimon Wunderlich
502b35a51c7SVasanthakumar Thiagarajan void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
503b35a51c7SVasanthakumar Thiagarajan
504bc2dfc02SLorenzo Bianconi int
505a95bfb87SLorenzo Bianconi cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev,
506bc2dfc02SLorenzo Bianconi struct wireless_dev *wdev,
507bc2dfc02SLorenzo Bianconi struct cfg80211_chan_def *chandef);
508bc2dfc02SLorenzo Bianconi
509a95bfb87SLorenzo Bianconi void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev);
510bc2dfc02SLorenzo Bianconi
511a95bfb87SLorenzo Bianconi void cfg80211_background_cac_done_wk(struct work_struct *work);
5121507b153SLorenzo Bianconi
513a95bfb87SLorenzo Bianconi void cfg80211_background_cac_abort_wk(struct work_struct *work);
514bc2dfc02SLorenzo Bianconi
515b35a51c7SVasanthakumar Thiagarajan bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
516b35a51c7SVasanthakumar Thiagarajan struct ieee80211_channel *chan);
517b35a51c7SVasanthakumar Thiagarajan
518b35a51c7SVasanthakumar Thiagarajan bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev);
519b35a51c7SVasanthakumar Thiagarajan
520b35a51c7SVasanthakumar Thiagarajan bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
5217b0a0e3cSJohannes Berg struct ieee80211_channel *chan,
5227b0a0e3cSJohannes Berg bool primary_only);
5237b0a0e3cSJohannes Berg bool cfg80211_wdev_on_sub_chan(struct wireless_dev *wdev,
5247b0a0e3cSJohannes Berg struct ieee80211_channel *chan,
5257b0a0e3cSJohannes Berg bool primary_only);
526b35a51c7SVasanthakumar Thiagarajan
elapsed_jiffies_msecs(unsigned long start)52704f39047SSimon Wunderlich static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
52804f39047SSimon Wunderlich {
52904f39047SSimon Wunderlich unsigned long end = jiffies;
53004f39047SSimon Wunderlich
53104f39047SSimon Wunderlich if (end >= start)
53204f39047SSimon Wunderlich return jiffies_to_msecs(end - start);
53304f39047SSimon Wunderlich
5340ce12026SEliad Peller return jiffies_to_msecs(end + (ULONG_MAX - start) + 1);
53504f39047SSimon Wunderlich }
53604f39047SSimon Wunderlich
537e8c9bd5bSJohannes Berg int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
538683b6d3bSJohannes Berg struct cfg80211_chan_def *chandef);
53959bbb6f7SJohannes Berg
54034850ab2SJohannes Berg int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
54134850ab2SJohannes Berg const u8 *rates, unsigned int n_rates,
54234850ab2SJohannes Berg u32 *mask);
54334850ab2SJohannes Berg
54456d1893dSJohannes Berg int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
5450c317a02SPurushottam Kushwaha enum nl80211_iftype iftype, u32 beacon_int);
54656d1893dSJohannes Berg
547dbbae26aSMichal Kazior void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
548dbbae26aSMichal Kazior enum nl80211_iftype iftype, int num);
549dbbae26aSMichal Kazior
550f04c2203SMichal Kazior void __cfg80211_leave(struct cfg80211_registered_device *rdev,
551f04c2203SMichal Kazior struct wireless_dev *wdev);
55281256969SStanislaw Gruszka void cfg80211_leave(struct cfg80211_registered_device *rdev,
55381256969SStanislaw Gruszka struct wireless_dev *wdev);
55481256969SStanislaw Gruszka
555f9f47529SJohannes Berg void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
556f9f47529SJohannes Berg struct wireless_dev *wdev);
557f9f47529SJohannes Berg
558cb3b7d87SAyala Beker void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
559cb3b7d87SAyala Beker struct wireless_dev *wdev);
560cb3b7d87SAyala Beker
561a3ce17d1SChaitanya Tata struct cfg80211_internal_bss *
562a3ce17d1SChaitanya Tata cfg80211_bss_update(struct cfg80211_registered_device *rdev,
563a3ce17d1SChaitanya Tata struct cfg80211_internal_bss *tmp,
564a3ce17d1SChaitanya Tata bool signal_valid, unsigned long ts);
565f7969969SJohannes Berg #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
566f7969969SJohannes Berg #define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
567f7969969SJohannes Berg #else
568f7969969SJohannes Berg /*
569f7969969SJohannes Berg * Trick to enable using it as a condition,
570f7969969SJohannes Berg * and also not give a warning when it's
571f7969969SJohannes Berg * not used that way.
572f7969969SJohannes Berg */
573f7969969SJohannes Berg #define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; })
574f7969969SJohannes Berg #endif
575f7969969SJohannes Berg
5769bb7e0f2SJohannes Berg void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
5779bb7e0f2SJohannes Berg void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
5789bb7e0f2SJohannes Berg void cfg80211_pmsr_free_wk(struct work_struct *work);
5799bb7e0f2SJohannes Berg
580cdf0a0a8SJohannes Berg void cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id);
581cdf0a0a8SJohannes Berg void cfg80211_remove_links(struct wireless_dev *wdev);
582cdf0a0a8SJohannes Berg int cfg80211_remove_virtual_intf(struct cfg80211_registered_device *rdev,
583cdf0a0a8SJohannes Berg struct wireless_dev *wdev);
584065563b2SVeerendranath Jakkam void cfg80211_wdev_release_link_bsses(struct wireless_dev *wdev, u16 link_mask);
585cdf0a0a8SJohannes Berg
586704232c2SJohannes Berg #endif /* __NET_WIRELESS_CORE_H */
587