| 1 |
|
| 2 | |
| 3 | * Wireless configuration interface internals.
|
| 4 | *
|
| 5 | * Copyright 2006-2010 Johannes Berg <[email protected]>
|
| 6 | * Copyright (C) 2018-2026 Intel Corporation
|
| 7 |
|
| 8 | #ifndef __NET_WIRELESS_CORE_H
|
| 9 | #define __NET_WIRELESS_CORE_H
|
| 10 | #include <linux/list.h>
|
| 11 | #include <linux/netdevice.h>
|
| 12 | #include <linux/rbtree.h>
|
| 13 | #include <linux/debugfs.h>
|
| 14 | #include <linux/rfkill.h>
|
| 15 | #include <linux/workqueue.h>
|
| 16 | #include <linux/rtnetlink.h>
|
| 17 | #include <net/genetlink.h>
|
| 18 | #include <net/cfg80211.h>
|
| 19 | #include "reg.h"
|
| 20 |
|
| 21 |
|
| 22 | #define WIPHY_IDX_INVALID -1
|
| 23 |
|
| 24 | struct cfg80211_scan_request_int {
|
| 25 | struct cfg80211_scan_info info;
|
| 26 | bool notified;
|
| 27 | |
| 28 | * set while the request is handed to the driver, i.e. between
|
| 29 | * rdev_scan() and cfg80211_scan_done()
|
| 30 |
|
| 31 | bool driver_owns;
|
| 32 | |
| 33 | * set when cfg80211 is done with the request but the driver still
|
| 34 | * owns it, so that cfg80211_scan_done() knows to just free it
|
| 35 |
|
| 36 | bool stale;
|
| 37 |
|
| 38 | struct cfg80211_scan_request req;
|
| 39 | };
|
| 40 |
|
| 41 | struct cfg80211_registered_device {
|
| 42 | const struct cfg80211_ops *ops;
|
| 43 | struct list_head list;
|
| 44 |
|
| 45 |
|
| 46 | struct rfkill_ops rfkill_ops;
|
| 47 | struct work_struct rfkill_block;
|
| 48 |
|
| 49 | |
| 50 | * country IEs on, this can help disregard country IEs from APs
|
| 51 | * on the same alpha2 quickly. The alpha2 may differ from
|
| 52 | * cfg80211_regdomain's alpha2 when an intersection has occurred.
|
| 53 | * If the AP is reconfigured this can also be used to tell us if
|
| 54 | * the country on the country IE changed.
|
| 55 | char country_ie_alpha2[2];
|
| 56 |
|
| 57 | |
| 58 | * the driver requests the regulatory core to set this regulatory
|
| 59 | * domain as the wiphy's. Only used for %REGULATORY_WIPHY_SELF_MANAGED
|
| 60 | * devices using the regulatory_set_wiphy_regd() API
|
| 61 |
|
| 62 | const struct ieee80211_regdomain *requested_regd;
|
| 63 |
|
| 64 | |
| 65 | * which its telling us its in. This defaults to ENVIRON_ANY
|
| 66 | enum environment_cap env;
|
| 67 |
|
| 68 |
|
| 69 | int wiphy_idx;
|
| 70 |
|
| 71 |
|
| 72 | int devlist_generation, wdev_id;
|
| 73 | int opencount;
|
| 74 | wait_queue_head_t dev_wait;
|
| 75 |
|
| 76 | struct list_head beacon_registrations;
|
| 77 | spinlock_t beacon_registrations_lock;
|
| 78 |
|
| 79 |
|
| 80 | int num_running_ifaces;
|
| 81 | int num_running_monitor_ifaces;
|
| 82 | u64 cookie_counter;
|
| 83 |
|
| 84 |
|
| 85 | spinlock_t bss_lock;
|
| 86 | struct list_head bss_list;
|
| 87 | struct rb_root bss_tree;
|
| 88 | u32 bss_generation;
|
| 89 | u32 bss_entries;
|
| 90 | struct cfg80211_scan_request_int *scan_req;
|
| 91 | struct cfg80211_scan_request_int *int_scan_req;
|
| 92 | struct sk_buff *scan_msg;
|
| 93 | struct list_head sched_scan_req_list;
|
| 94 | time64_t suspend_at;
|
| 95 | struct wiphy_work scan_done_wk;
|
| 96 |
|
| 97 | struct genl_info *cur_cmd_info;
|
| 98 |
|
| 99 | struct work_struct conn_work;
|
| 100 | struct work_struct event_work;
|
| 101 |
|
| 102 | struct delayed_work dfs_update_channels_wk;
|
| 103 |
|
| 104 | struct wireless_dev *background_radar_wdev;
|
| 105 | struct cfg80211_chan_def background_radar_chandef;
|
| 106 | struct delayed_work background_cac_done_wk;
|
| 107 | struct work_struct background_cac_abort_wk;
|
| 108 |
|
| 109 |
|
| 110 | u32 crit_proto_nlportid;
|
| 111 |
|
| 112 | struct cfg80211_coalesce *coalesce;
|
| 113 |
|
| 114 | struct work_struct destroy_work;
|
| 115 | struct wiphy_work sched_scan_stop_wk;
|
| 116 | struct work_struct sched_scan_res_wk;
|
| 117 | struct wiphy_work reg_check_chans_wk;
|
| 118 | struct work_struct reg_leave_nan_wk;
|
| 119 |
|
| 120 | struct cfg80211_chan_def radar_chandef;
|
| 121 | struct work_struct propagate_radar_detect_wk;
|
| 122 |
|
| 123 | struct cfg80211_chan_def cac_done_chandef;
|
| 124 | struct work_struct propagate_cac_done_wk;
|
| 125 |
|
| 126 | struct work_struct mgmt_registrations_update_wk;
|
| 127 |
|
| 128 | spinlock_t mgmt_registrations_lock;
|
| 129 |
|
| 130 | struct work_struct wiphy_work;
|
| 131 | struct list_head wiphy_work_list;
|
| 132 |
|
| 133 | spinlock_t wiphy_work_lock;
|
| 134 | bool suspended;
|
| 135 |
|
| 136 | |
| 137 | * and it should at least be aligned to NETDEV_ALIGN
|
| 138 | struct wiphy wiphy __aligned(NETDEV_ALIGN);
|
| 139 | };
|
| 140 |
|
| 141 | static inline
|
| 142 | struct cfg80211_registered_device *wiphy_to_rdev(struct wiphy *wiphy)
|
| 143 | {
|
| 144 | BUG_ON(!wiphy);
|
| 145 | return container_of(wiphy, struct cfg80211_registered_device, wiphy);
|
| 146 | }
|
| 147 |
|
| 148 | static inline void
|
| 149 | cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
|
| 150 | {
|
| 151 | #ifdef CONFIG_PM
|
| 152 | int i;
|
| 153 |
|
| 154 | if (!rdev->wiphy.wowlan_config)
|
| 155 | return;
|
| 156 | for (i = 0; i < rdev->wiphy.wowlan_config->n_patterns; i++)
|
| 157 | kfree(rdev->wiphy.wowlan_config->patterns[i].mask);
|
| 158 | kfree(rdev->wiphy.wowlan_config->patterns);
|
| 159 | if (rdev->wiphy.wowlan_config->tcp &&
|
| 160 | rdev->wiphy.wowlan_config->tcp->sock)
|
| 161 | sock_release(rdev->wiphy.wowlan_config->tcp->sock);
|
| 162 | kfree(rdev->wiphy.wowlan_config->tcp);
|
| 163 | kfree(rdev->wiphy.wowlan_config->nd_config);
|
| 164 | kfree(rdev->wiphy.wowlan_config);
|
| 165 | #endif
|
| 166 | }
|
| 167 |
|
| 168 | static inline u64 cfg80211_assign_cookie(struct cfg80211_registered_device *rdev)
|
| 169 | {
|
| 170 | u64 r = ++rdev->cookie_counter;
|
| 171 |
|
| 172 | if (WARN_ON(r == 0))
|
| 173 | r = ++rdev->cookie_counter;
|
| 174 |
|
| 175 | return r;
|
| 176 | }
|
| 177 |
|
| 178 | extern struct workqueue_struct *cfg80211_wq;
|
| 179 | extern struct list_head cfg80211_rdev_list;
|
| 180 | extern int cfg80211_rdev_list_generation;
|
| 181 |
|
| 182 |
|
| 183 | static inline int for_each_rdev_check_rtnl(void)
|
| 184 | {
|
| 185 | ASSERT_RTNL();
|
| 186 | return 0;
|
| 187 | }
|
| 188 | #define for_each_rdev(rdev) \
|
| 189 | if (for_each_rdev_check_rtnl()) {} else \
|
| 190 | list_for_each_entry(rdev, &cfg80211_rdev_list, list)
|
| 191 |
|
| 192 | enum bss_source_type {
|
| 193 | BSS_SOURCE_DIRECT = 0,
|
| 194 | BSS_SOURCE_MBSSID,
|
| 195 | BSS_SOURCE_STA_PROFILE,
|
| 196 | };
|
| 197 |
|
| 198 | struct cfg80211_internal_bss {
|
| 199 | struct list_head list;
|
| 200 | struct list_head hidden_list;
|
| 201 | struct rb_node rbn;
|
| 202 | unsigned long ts;
|
| 203 | unsigned long refcount;
|
| 204 | atomic_t hold;
|
| 205 |
|
| 206 | |
| 207 | * timestamp field of the last beacon/probe received for this BSS.
|
| 208 | * The time is the TSF of the BSS specified by %parent_bssid.
|
| 209 |
|
| 210 | u64 parent_tsf;
|
| 211 |
|
| 212 | |
| 213 | * the BSS that the interface that requested the scan was connected to
|
| 214 | * when the beacon/probe was received.
|
| 215 |
|
| 216 | u8 parent_bssid[ETH_ALEN] __aligned(2);
|
| 217 |
|
| 218 | enum bss_source_type bss_source;
|
| 219 |
|
| 220 |
|
| 221 | struct cfg80211_bss pub;
|
| 222 | };
|
| 223 |
|
| 224 | static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pub)
|
| 225 | {
|
| 226 | return container_of(pub, struct cfg80211_internal_bss, pub);
|
| 227 | }
|
| 228 |
|
| 229 | static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
|
| 230 | {
|
| 231 | atomic_inc(&bss->hold);
|
| 232 | if (bss->pub.transmitted_bss) {
|
| 233 | bss = container_of(bss->pub.transmitted_bss,
|
| 234 | struct cfg80211_internal_bss, pub);
|
| 235 | atomic_inc(&bss->hold);
|
| 236 | }
|
| 237 | }
|
| 238 |
|
| 239 | static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
|
| 240 | {
|
| 241 | int r = atomic_dec_return(&bss->hold);
|
| 242 | WARN_ON(r < 0);
|
| 243 | if (bss->pub.transmitted_bss) {
|
| 244 | bss = container_of(bss->pub.transmitted_bss,
|
| 245 | struct cfg80211_internal_bss, pub);
|
| 246 | r = atomic_dec_return(&bss->hold);
|
| 247 | WARN_ON(r < 0);
|
| 248 | }
|
| 249 | }
|
| 250 |
|
| 251 |
|
| 252 | struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
|
| 253 | int get_wiphy_idx(struct wiphy *wiphy);
|
| 254 |
|
| 255 | struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
|
| 256 |
|
| 257 | int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
|
| 258 | struct net *net);
|
| 259 |
|
| 260 | void cfg80211_init_wdev(struct wireless_dev *wdev);
|
| 261 | void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
|
| 262 | struct wireless_dev *wdev);
|
| 263 |
|
| 264 | static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)
|
| 265 | {
|
| 266 | lockdep_assert_held(&rdev->wiphy.mtx);
|
| 267 |
|
| 268 | return rdev->num_running_ifaces == rdev->num_running_monitor_ifaces &&
|
| 269 | rdev->num_running_ifaces > 0;
|
| 270 | }
|
| 271 |
|
| 272 | enum cfg80211_event_type {
|
| 273 | EVENT_CONNECT_RESULT,
|
| 274 | EVENT_ROAMED,
|
| 275 | EVENT_DISCONNECTED,
|
| 276 | EVENT_IBSS_JOINED,
|
| 277 | EVENT_STOPPED,
|
| 278 | EVENT_PORT_AUTHORIZED,
|
| 279 | };
|
| 280 |
|
| 281 | struct cfg80211_event {
|
| 282 | struct list_head list;
|
| 283 | enum cfg80211_event_type type;
|
| 284 |
|
| 285 | union {
|
| 286 | struct cfg80211_connect_resp_params cr;
|
| 287 | struct cfg80211_roam_info rm;
|
| 288 | struct {
|
| 289 | const u8 *ie;
|
| 290 | size_t ie_len;
|
| 291 | u16 reason;
|
| 292 | bool locally_generated;
|
| 293 | } dc;
|
| 294 | struct {
|
| 295 | struct cfg80211_bss *bss;
|
| 296 | } ij;
|
| 297 | struct {
|
| 298 | u8 peer_addr[ETH_ALEN];
|
| 299 | const u8 *td_bitmap;
|
| 300 | u8 td_bitmap_len;
|
| 301 | } pa;
|
| 302 | };
|
| 303 | int link_id;
|
| 304 | };
|
| 305 |
|
| 306 | struct cfg80211_cached_keys {
|
| 307 | struct key_params params[4];
|
| 308 | u8 data[4][WLAN_KEY_LEN_WEP104];
|
| 309 | int def;
|
| 310 | };
|
| 311 |
|
| 312 | struct cfg80211_beacon_registration {
|
| 313 | struct list_head list;
|
| 314 | u32 nlportid;
|
| 315 | };
|
| 316 |
|
| 317 | struct cfg80211_cqm_config {
|
| 318 | struct rcu_head rcu_head;
|
| 319 | u32 rssi_hyst;
|
| 320 | s32 last_rssi_event_value;
|
| 321 | enum nl80211_cqm_rssi_threshold_event last_rssi_event_type;
|
| 322 | bool use_range_api;
|
| 323 | int n_rssi_thresholds;
|
| 324 | s32 rssi_thresholds[] __counted_by(n_rssi_thresholds);
|
| 325 | };
|
| 326 |
|
| 327 | void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy,
|
| 328 | struct wiphy_work *work);
|
| 329 |
|
| 330 | void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev);
|
| 331 |
|
| 332 | void cfg80211_close_dependents(struct cfg80211_registered_device *rdev,
|
| 333 | struct wireless_dev *wdev);
|
| 334 |
|
| 335 |
|
| 336 | void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
|
| 337 |
|
| 338 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
|
| 339 | char *newname);
|
| 340 |
|
| 341 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
|
| 342 |
|
| 343 | void cfg80211_bss_expire(struct cfg80211_registered_device *rdev);
|
| 344 | void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
|
| 345 | unsigned long age_secs);
|
| 346 | void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
|
| 347 | unsigned int link,
|
| 348 | struct ieee80211_channel *channel);
|
| 349 |
|
| 350 |
|
| 351 | int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
| 352 | struct net_device *dev,
|
| 353 | struct cfg80211_ibss_params *params,
|
| 354 | struct cfg80211_cached_keys *connkeys);
|
| 355 | void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
|
| 356 | int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
|
| 357 | struct net_device *dev, bool nowext);
|
| 358 | void __cfg80211_ibss_joined(struct net_device *dev, struct cfg80211_bss *bss);
|
| 359 | int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
|
| 360 | struct wireless_dev *wdev);
|
| 361 |
|
| 362 |
|
| 363 | extern const struct mesh_config default_mesh_config;
|
| 364 | extern const struct mesh_setup default_mesh_setup;
|
| 365 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
|
| 366 | struct net_device *dev,
|
| 367 | struct mesh_setup *setup,
|
| 368 | const struct mesh_config *conf);
|
| 369 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
|
| 370 | struct net_device *dev);
|
| 371 | int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
| 372 | struct wireless_dev *wdev,
|
| 373 | struct cfg80211_chan_def *chandef);
|
| 374 |
|
| 375 |
|
| 376 | int cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
|
| 377 | struct net_device *dev,
|
| 378 | struct ocb_setup *setup);
|
| 379 | int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
|
| 380 | struct net_device *dev);
|
| 381 |
|
| 382 |
|
| 383 | int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
| 384 | struct net_device *dev, int link,
|
| 385 | bool notify);
|
| 386 |
|
| 387 |
|
| 388 | int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
|
| 389 | struct net_device *dev,
|
| 390 | struct cfg80211_auth_request *req);
|
| 391 | int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
|
| 392 | struct net_device *dev,
|
| 393 | struct cfg80211_assoc_request *req,
|
| 394 | struct netlink_ext_ack *extack);
|
| 395 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
|
| 396 | struct net_device *dev, const u8 *bssid,
|
| 397 | const u8 *ie, int ie_len, u16 reason,
|
| 398 | bool local_state_change);
|
| 399 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
|
| 400 | struct net_device *dev, const u8 *ap_addr,
|
| 401 | const u8 *ie, int ie_len, u16 reason,
|
| 402 | bool local_state_change);
|
| 403 | void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
|
| 404 | struct net_device *dev);
|
| 405 | int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
|
| 406 | u16 frame_type, const u8 *match_data,
|
| 407 | int match_len, bool multicast_rx,
|
| 408 | struct netlink_ext_ack *extack);
|
| 409 | void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk);
|
| 410 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
|
| 411 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
|
| 412 | int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
| 413 | struct wireless_dev *wdev,
|
| 414 | struct cfg80211_mgmt_tx_params *params,
|
| 415 | u64 cookie);
|
| 416 | void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
|
| 417 | const struct ieee80211_ht_cap *ht_capa_mask);
|
| 418 | void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
|
| 419 | const struct ieee80211_vht_cap *vht_capa_mask);
|
| 420 |
|
| 421 |
|
| 422 | int cfg80211_connect(struct cfg80211_registered_device *rdev,
|
| 423 | struct net_device *dev,
|
| 424 | struct cfg80211_connect_params *connect,
|
| 425 | struct cfg80211_cached_keys *connkeys,
|
| 426 | const u8 *prev_bssid);
|
| 427 | void __cfg80211_connect_result(struct net_device *dev,
|
| 428 | struct cfg80211_connect_resp_params *params,
|
| 429 | bool wextev);
|
| 430 | void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
|
| 431 | size_t ie_len, u16 reason, bool from_ap);
|
| 432 | int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
|
| 433 | struct net_device *dev, u16 reason,
|
| 434 | bool wextev);
|
| 435 | void __cfg80211_roamed(struct wireless_dev *wdev,
|
| 436 | struct cfg80211_roam_info *info);
|
| 437 | void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *peer_addr,
|
| 438 | const u8 *td_bitmap, u8 td_bitmap_len);
|
| 439 | int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
|
| 440 | struct wireless_dev *wdev);
|
| 441 | void cfg80211_autodisconnect_wk(struct wiphy *wiphy, struct wiphy_work *work);
|
| 442 |
|
| 443 |
|
| 444 | void cfg80211_conn_work(struct work_struct *work);
|
| 445 | void cfg80211_sme_scan_done(struct net_device *dev);
|
| 446 | bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status);
|
| 447 | void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len);
|
| 448 | void cfg80211_sme_disassoc(struct wireless_dev *wdev);
|
| 449 | void cfg80211_sme_deauth(struct wireless_dev *wdev);
|
| 450 | void cfg80211_sme_auth_timeout(struct wireless_dev *wdev);
|
| 451 | void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev);
|
| 452 | void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev);
|
| 453 |
|
| 454 |
|
| 455 | bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
|
| 456 | bool cfg80211_valid_key_idx(struct wireless_dev *wdev,
|
| 457 | int key_idx, bool pairwise,
|
| 458 | const u8 *mac_addr);
|
| 459 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
|
| 460 | struct wireless_dev *wdev,
|
| 461 | struct key_params *params, int key_idx,
|
| 462 | bool pairwise, const u8 *mac_addr);
|
| 463 | void __cfg80211_scan_done(struct wiphy *wiphy, struct wiphy_work *wk);
|
| 464 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
|
| 465 | bool send_message);
|
| 466 | void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
|
| 467 | struct cfg80211_sched_scan_request *req);
|
| 468 | int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
|
| 469 | bool want_multi);
|
| 470 | void cfg80211_sched_scan_results_wk(struct work_struct *work);
|
| 471 | int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
|
| 472 | struct cfg80211_sched_scan_request *req,
|
| 473 | bool driver_initiated);
|
| 474 | int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
| 475 | u64 reqid, bool driver_initiated);
|
| 476 | void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
|
| 477 | int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
| 478 | struct net_device *dev, enum nl80211_iftype ntype,
|
| 479 | struct vif_params *params);
|
| 480 | void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
|
| 481 | void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev,
|
| 482 | struct wiphy_work *end);
|
| 483 | void cfg80211_process_wdev_events(struct wireless_dev *wdev);
|
| 484 |
|
| 485 | bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range,
|
| 486 | u32 center_freq_khz, u32 bw_khz);
|
| 487 |
|
| 488 | int cfg80211_scan(struct cfg80211_registered_device *rdev);
|
| 489 |
|
| 490 | extern struct work_struct cfg80211_disconnect_work;
|
| 491 |
|
| 492 | #define NL80211_BSS_USE_FOR_ALL (NL80211_BSS_USE_FOR_NORMAL | \
|
| 493 | NL80211_BSS_USE_FOR_MLD_LINK)
|
| 494 |
|
| 495 | void cfg80211_set_dfs_state(struct wiphy *wiphy,
|
| 496 | const struct cfg80211_chan_def *chandef,
|
| 497 | enum nl80211_dfs_state dfs_state);
|
| 498 |
|
| 499 | void cfg80211_set_cac_state(struct wiphy *wiphy,
|
| 500 | const struct cfg80211_chan_def *chandef,
|
| 501 | bool cac_ongoing);
|
| 502 |
|
| 503 | void cfg80211_dfs_channels_update_work(struct work_struct *work);
|
| 504 |
|
| 505 | void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
|
| 506 |
|
| 507 | int
|
| 508 | cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev,
|
| 509 | struct wireless_dev *wdev,
|
| 510 | struct cfg80211_chan_def *chandef);
|
| 511 |
|
| 512 | void cfg80211_stop_radar_detection(struct wireless_dev *wdev);
|
| 513 | void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev);
|
| 514 |
|
| 515 | void cfg80211_background_cac_done_wk(struct work_struct *work);
|
| 516 |
|
| 517 | void cfg80211_background_cac_abort_wk(struct work_struct *work);
|
| 518 |
|
| 519 | bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
|
| 520 | struct ieee80211_channel *chan);
|
| 521 |
|
| 522 | bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev);
|
| 523 |
|
| 524 | bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
|
| 525 | struct ieee80211_channel *chan,
|
| 526 | bool primary_only);
|
| 527 | bool cfg80211_wdev_on_sub_chan(struct wireless_dev *wdev,
|
| 528 | struct ieee80211_channel *chan,
|
| 529 | bool primary_only);
|
| 530 | bool _cfg80211_chandef_usable(struct wiphy *wiphy,
|
| 531 | const struct cfg80211_chan_def *chandef,
|
| 532 | u32 prohibited_flags,
|
| 533 | u32 permitting_flags);
|
| 534 |
|
| 535 | static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
|
| 536 | {
|
| 537 | unsigned long end = jiffies;
|
| 538 |
|
| 539 | if (end >= start)
|
| 540 | return jiffies_to_msecs(end - start);
|
| 541 |
|
| 542 | return jiffies_to_msecs(end + (ULONG_MAX - start) + 1);
|
| 543 | }
|
| 544 |
|
| 545 | int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
| 546 | struct net_device *dev,
|
| 547 | struct cfg80211_chan_def *chandef);
|
| 548 |
|
| 549 | int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
|
| 550 | const u8 *rates, unsigned int n_rates,
|
| 551 | u32 *mask);
|
| 552 |
|
| 553 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
|
| 554 | enum nl80211_iftype iftype, u32 beacon_int);
|
| 555 |
|
| 556 | void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
|
| 557 | enum nl80211_iftype iftype, int num);
|
| 558 |
|
| 559 | void cfg80211_leave_locked(struct cfg80211_registered_device *rdev,
|
| 560 | struct wireless_dev *wdev, int link_id);
|
| 561 |
|
| 562 | void cfg80211_leave(struct cfg80211_registered_device *rdev,
|
| 563 | struct wireless_dev *wdev,
|
| 564 | int link_id);
|
| 565 |
|
| 566 | void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
|
| 567 | struct wireless_dev *wdev);
|
| 568 |
|
| 569 | void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
|
| 570 | struct wireless_dev *wdev);
|
| 571 | void cfg80211_stop_pd(struct cfg80211_registered_device *rdev,
|
| 572 | struct wireless_dev *wdev);
|
| 573 |
|
| 574 | int cfg80211_nan_set_local_schedule(struct cfg80211_registered_device *rdev,
|
| 575 | struct wireless_dev *wdev,
|
| 576 | struct cfg80211_nan_local_sched *sched);
|
| 577 |
|
| 578 | struct cfg80211_internal_bss *
|
| 579 | cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
| 580 | struct cfg80211_internal_bss *tmp,
|
| 581 | bool signal_valid, unsigned long ts);
|
| 582 |
|
| 583 | enum ieee80211_ap_reg_power
|
| 584 | cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len,
|
| 585 | u32 client_flags);
|
| 586 |
|
| 587 | #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
|
| 588 | #define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
|
| 589 | #else
|
| 590 | |
| 591 | * Trick to enable using it as a condition,
|
| 592 | * and also not give a warning when it's
|
| 593 | * not used that way.
|
| 594 |
|
| 595 | #define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; })
|
| 596 | #endif
|
| 597 |
|
| 598 | void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
|
| 599 | void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
|
| 600 | void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work);
|
| 601 |
|
| 602 | void cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id);
|
| 603 | void cfg80211_remove_links(struct wireless_dev *wdev);
|
| 604 | int cfg80211_remove_virtual_intf(struct cfg80211_registered_device *rdev,
|
| 605 | struct wireless_dev *wdev);
|
| 606 | void cfg80211_wdev_release_link_bsses(struct wireless_dev *wdev, u16 link_mask);
|
| 607 |
|
| 608 | int cfg80211_assoc_ml_reconf(struct cfg80211_registered_device *rdev,
|
| 609 | struct net_device *dev,
|
| 610 | struct cfg80211_ml_reconf_req *req);
|
| 611 |
|
| 612 | |
| 613 | * struct cfg80211_colocated_ap - colocated AP information
|
| 614 | *
|
| 615 | * @list: linked list to all colocated APs
|
| 616 | * @bssid: BSSID of the reported AP
|
| 617 | * @ssid: SSID of the reported AP
|
| 618 | * @ssid_len: length of the ssid
|
| 619 | * @center_freq: frequency the reported AP is on
|
| 620 | * @unsolicited_probe: the reported AP is part of an ESS, where all the APs
|
| 621 | * that operate in the same channel as the reported AP and that might be
|
| 622 | * detected by a STA receiving this frame, are transmitting unsolicited
|
| 623 | * Probe Response frames every 20 TUs
|
| 624 | * @oct_recommended: OCT is recommended to exchange MMPDUs with the reported AP
|
| 625 | * @same_ssid: the reported AP has the same SSID as the reporting AP
|
| 626 | * @multi_bss: the reported AP is part of a multiple BSSID set
|
| 627 | * @transmitted_bssid: the reported AP is the transmitting BSSID
|
| 628 | * @colocated_ess: all the APs that share the same ESS as the reported AP are
|
| 629 | * colocated and can be discovered via legacy bands.
|
| 630 | * @short_ssid_valid: short_ssid is valid and can be used
|
| 631 | * @short_ssid: the short SSID for this SSID
|
| 632 | * @psd_20: The 20MHz PSD EIRP of the primary 20MHz channel for the reported AP
|
| 633 |
|
| 634 | struct cfg80211_colocated_ap {
|
| 635 | struct list_head list;
|
| 636 | u8 bssid[ETH_ALEN];
|
| 637 | u8 ssid[IEEE80211_MAX_SSID_LEN];
|
| 638 | size_t ssid_len;
|
| 639 | u32 short_ssid;
|
| 640 | u32 center_freq;
|
| 641 | u8 unsolicited_probe:1,
|
| 642 | oct_recommended:1,
|
| 643 | same_ssid:1,
|
| 644 | multi_bss:1,
|
| 645 | transmitted_bssid:1,
|
| 646 | colocated_ess:1,
|
| 647 | short_ssid_valid:1;
|
| 648 | s8 psd_20;
|
| 649 | };
|
| 650 |
|
| 651 | #if IS_ENABLED(CONFIG_CFG80211_KUNIT_TEST)
|
| 652 | #define EXPORT_SYMBOL_IF_CFG80211_KUNIT(sym) EXPORT_SYMBOL_IF_KUNIT(sym)
|
| 653 | #define VISIBLE_IF_CFG80211_KUNIT
|
| 654 | void cfg80211_free_coloc_ap_list(struct list_head *coloc_ap_list);
|
| 655 |
|
| 656 | int cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies,
|
| 657 | struct list_head *list);
|
| 658 |
|
| 659 | size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
|
| 660 | const u8 *subie, size_t subie_len,
|
| 661 | u8 *new_ie, size_t new_ie_len);
|
| 662 | #else
|
| 663 | #define EXPORT_SYMBOL_IF_CFG80211_KUNIT(sym)
|
| 664 | #define VISIBLE_IF_CFG80211_KUNIT static
|
| 665 | #endif
|
| 666 |
|
| 667 | #endif
|