linux/net/mac80211/util.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005-2006, Devicescape Software, Inc.
 * Copyright 2006-2007	Jiri Benc <[email protected]>
 * Copyright 2007	Johannes Berg <[email protected]>
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 * Copyright (C) 2015-2017	Intel Deutschland GmbH
 * Copyright (C) 2018-2024 Intel Corporation
 *
 * utilities for mac80211
 */

#include <net/mac80211.h>
#include <linux/netdevice.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/bitmap.h>
#include <linux/crc32.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
#include <net/rtnetlink.h>
#include <kunit/visibility.h>

#include "ieee80211_i.h"
#include "driver-ops.h"
#include "rate.h"
#include "mesh.h"
#include "wme.h"
#include "led.h"
#include "wep.h"

/* privid for wiphys to determine whether they belong to us or not */
const void *const mac80211_wiphy_privid =;

struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy)
{}
EXPORT_SYMBOL();

const struct ieee80211_conn_settings ieee80211_conn_settings_unlimited =;

u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
			enum nl80211_iftype type)
{}
EXPORT_SYMBOL();

void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
{}

int ieee80211_frame_duration(enum nl80211_band band, size_t len,
			     int rate, int erp, int short_preamble)
{}

/* Exported duration function for driver use */
__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
					struct ieee80211_vif *vif,
					enum nl80211_band band,
					size_t frame_len,
					struct ieee80211_rate *rate)
{}
EXPORT_SYMBOL();

__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
			      struct ieee80211_vif *vif, size_t frame_len,
			      const struct ieee80211_tx_info *frame_txctl)
{}
EXPORT_SYMBOL();

__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
				    struct ieee80211_vif *vif,
				    size_t frame_len,
				    const struct ieee80211_tx_info *frame_txctl)
{}
EXPORT_SYMBOL();

static void wake_tx_push_queue(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata,
			       struct ieee80211_txq *queue)
{}

/* wake_tx_queue handler for driver not implementing a custom one*/
void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
				    struct ieee80211_txq *txq)
{}
EXPORT_SYMBOL();

static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
{}

static void
__releases(&local->queue_stop_reason_lock)
__acquires(&local->queue_stop_reason_lock)
_ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags)
{}

void ieee80211_wake_txqs(struct tasklet_struct *t)
{}

static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
				   enum queue_stop_reason reason,
				   bool refcounted,
				   unsigned long *flags)
{}

void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
				    enum queue_stop_reason reason,
				    bool refcounted)
{}

void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
{}
EXPORT_SYMBOL();

static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
				   enum queue_stop_reason reason,
				   bool refcounted)
{}

void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
				    enum queue_stop_reason reason,
				    bool refcounted)
{}

void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
{}
EXPORT_SYMBOL();

void ieee80211_add_pending_skb(struct ieee80211_local *local,
			       struct sk_buff *skb)
{}

void ieee80211_add_pending_skbs(struct ieee80211_local *local,
				struct sk_buff_head *skbs)
{}

void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
				     unsigned long queues,
				     enum queue_stop_reason reason,
				     bool refcounted)
{}

void ieee80211_stop_queues(struct ieee80211_hw *hw)
{}
EXPORT_SYMBOL();

int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
{}
EXPORT_SYMBOL();

void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
				     unsigned long queues,
				     enum queue_stop_reason reason,
				     bool refcounted)
{}

void ieee80211_wake_queues(struct ieee80211_hw *hw)
{}
EXPORT_SYMBOL();

static unsigned int
ieee80211_get_vif_queues(struct ieee80211_local *local,
			 struct ieee80211_sub_if_data *sdata)
{}

void __ieee80211_flush_queues(struct ieee80211_local *local,
			      struct ieee80211_sub_if_data *sdata,
			      unsigned int queues, bool drop)
{}

void ieee80211_flush_queues(struct ieee80211_local *local,
			    struct ieee80211_sub_if_data *sdata, bool drop)
{}

void ieee80211_stop_vif_queues(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata,
			       enum queue_stop_reason reason)
{}

void ieee80211_wake_vif_queues(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata,
			       enum queue_stop_reason reason)
{}

static void __iterate_interfaces(struct ieee80211_local *local,
				 u32 iter_flags,
				 void (*iterator)(void *data, u8 *mac,
						  struct ieee80211_vif *vif),
				 void *data)
{}

void ieee80211_iterate_interfaces(
	struct ieee80211_hw *hw, u32 iter_flags,
	void (*iterator)(void *data, u8 *mac,
			 struct ieee80211_vif *vif),
	void *data)
{}
EXPORT_SYMBOL_GPL();

void ieee80211_iterate_active_interfaces_atomic(
	struct ieee80211_hw *hw, u32 iter_flags,
	void (*iterator)(void *data, u8 *mac,
			 struct ieee80211_vif *vif),
	void *data)
{}
EXPORT_SYMBOL_GPL();

void ieee80211_iterate_active_interfaces_mtx(
	struct ieee80211_hw *hw, u32 iter_flags,
	void (*iterator)(void *data, u8 *mac,
			 struct ieee80211_vif *vif),
	void *data)
{}
EXPORT_SYMBOL_GPL();

static void __iterate_stations(struct ieee80211_local *local,
			       void (*iterator)(void *data,
						struct ieee80211_sta *sta),
			       void *data)
{}

void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
			void (*iterator)(void *data,
					 struct ieee80211_sta *sta),
			void *data)
{}
EXPORT_SYMBOL_GPL();

struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev)
{}
EXPORT_SYMBOL_GPL();

struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
{}
EXPORT_SYMBOL_GPL();

/*
 * Nothing should have been stuffed into the workqueue during
 * the suspend->resume cycle. Since we can't check each caller
 * of this function if we are already quiescing / suspended,
 * check here and don't WARN since this can actually happen when
 * the rx path (for example) is racing against __ieee80211_suspend
 * and suspending / quiescing was set after the rx path checked
 * them.
 */
static bool ieee80211_can_queue_work(struct ieee80211_local *local)
{}

void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
{}
EXPORT_SYMBOL();

void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
				  struct delayed_work *dwork,
				  unsigned long delay)
{}
EXPORT_SYMBOL();

void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
					   struct ieee80211_tx_queue_params
					   *qparam, int ac)
{}

void ieee80211_set_wmm_default(struct ieee80211_link_data *link,
			       bool bss_notify, bool enable_qos)
{}

void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
			 u16 transaction, u16 auth_alg, u16 status,
			 const u8 *extra, size_t extra_len, const u8 *da,
			 const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx,
			 u32 tx_flags)
{}

void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
				    const u8 *da, const u8 *bssid,
				    u16 stype, u16 reason,
				    bool send_frame, u8 *frame_buf)
{}

static int ieee80211_put_s1g_cap(struct sk_buff *skb,
				 struct ieee80211_sta_s1g_cap *s1g_cap)
{}

static int ieee80211_put_preq_ies_band(struct sk_buff *skb,
				       struct ieee80211_sub_if_data *sdata,
				       const u8 *ie, size_t ie_len,
				       size_t *offset,
				       enum nl80211_band band,
				       u32 rate_mask,
				       struct cfg80211_chan_def *chandef,
				       u32 flags)
{}

static int ieee80211_put_preq_ies(struct sk_buff *skb,
				  struct ieee80211_sub_if_data *sdata,
				  struct ieee80211_scan_ies *ie_desc,
				  const u8 *ie, size_t ie_len,
				  u8 bands_used, u32 *rate_masks,
				  struct cfg80211_chan_def *chandef,
				  u32 flags)
{
	size_t custom_ie_offset = 0;
	int i, err;

	memset(ie_desc, 0, sizeof(*ie_desc));

	for (i = 0; i < NUM_NL80211_BANDS; i++) {
		if (bands_used & BIT(i)) {
			ie_desc->ies[i] = skb_tail_pointer(skb);
			err = ieee80211_put_preq_ies_band(skb, sdata,
							  ie, ie_len,
							  &custom_ie_offset,
							  i, rate_masks[i],
							  chandef, flags);
			if (err)
				return err;
			ie_desc->len[i] = skb_tail_pointer(skb) -
					  ie_desc->ies[i];
		}
	}

	/* add any remaining custom IEs */
	if (ie && ie_len) {
		if (WARN_ONCE(skb_tailroom(skb) < ie_len - custom_ie_offset,
			      "not enough space for preq custom IEs\n"))
			return -ENOBUFS;
		ie_desc->common_ies = skb_tail_pointer(skb);
		skb_put_data(skb, ie + custom_ie_offset,
			     ie_len - custom_ie_offset);
		ie_desc->common_ie_len = skb_tail_pointer(skb) -
					 ie_desc->common_ies;
	}

	return 0;
};

int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer,
			     size_t buffer_len,
			     struct ieee80211_scan_ies *ie_desc,
			     const u8 *ie, size_t ie_len,
			     u8 bands_used, u32 *rate_masks,
			     struct cfg80211_chan_def *chandef,
			     u32 flags)
{}

struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
					  const u8 *src, const u8 *dst,
					  u32 ratemask,
					  struct ieee80211_channel *chan,
					  const u8 *ssid, size_t ssid_len,
					  const u8 *ie, size_t ie_len,
					  u32 flags)
{}

u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
			    struct ieee802_11_elems *elems,
			    enum nl80211_band band, u32 *basic_rates)
{}

void ieee80211_stop_device(struct ieee80211_local *local, bool suspend)
{}

static void ieee80211_flush_completed_scan(struct ieee80211_local *local,
					   bool aborted)
{}

static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
{}

static void ieee80211_assign_chanctx(struct ieee80211_local *local,
				     struct ieee80211_sub_if_data *sdata,
				     struct ieee80211_link_data *link)
{}

static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata)
{}

static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata)
{}

static void ieee80211_reconfig_ap_links(struct ieee80211_local *local,
					struct ieee80211_sub_if_data *sdata,
					u64 changed)
{}

int ieee80211_reconfig(struct ieee80211_local *local)
{}

static void ieee80211_reconfig_disconnect(struct ieee80211_vif *vif, u8 flag)
{}

void ieee80211_hw_restart_disconnect(struct ieee80211_vif *vif)
{}
EXPORT_SYMBOL_GPL();

void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
{}
EXPORT_SYMBOL_GPL();

void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata,
			   struct ieee80211_link_data *link)
{}

void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata,
				  int link_id)
{}

size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
{}

u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
			      u16 cap)
{}

u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
			       u32 cap)
{}

/* this may return more than ieee80211_put_he_6ghz_cap() will need */
u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata)
{}

static void
ieee80211_get_adjusted_he_cap(const struct ieee80211_conn_settings *conn,
			      const struct ieee80211_sta_he_cap *he_cap,
			      struct ieee80211_he_cap_elem *elem)
{}

int ieee80211_put_he_cap(struct sk_buff *skb,
			 struct ieee80211_sub_if_data *sdata,
			 const struct ieee80211_supported_band *sband,
			 const struct ieee80211_conn_settings *conn)
{}

int ieee80211_put_he_6ghz_cap(struct sk_buff *skb,
			      struct ieee80211_sub_if_data *sdata,
			      enum ieee80211_smps_mode smps_mode)
{}

u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
			       const struct cfg80211_chan_def *chandef,
			       u16 prot_mode, bool rifs_mode)
{}

void ieee80211_ie_build_wide_bw_cs(u8 *pos,
				   const struct cfg80211_chan_def *chandef)
{}

u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
				const struct cfg80211_chan_def *chandef)
{}

u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef)
{}

u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef,
				const struct ieee80211_sta_eht_cap *eht_cap)

{}

bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
			       struct cfg80211_chan_def *chandef)
{}

bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info,
				const struct ieee80211_vht_operation *oper,
				const struct ieee80211_ht_operation *htop,
				struct cfg80211_chan_def *chandef)
{}

void ieee80211_chandef_eht_oper(const struct ieee80211_eht_operation_info *info,
				struct cfg80211_chan_def *chandef)
{}

bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_local *local,
				    const struct ieee80211_he_operation *he_oper,
				    const struct ieee80211_eht_operation *eht_oper,
				    struct cfg80211_chan_def *chandef)
{}

bool ieee80211_chandef_s1g_oper(const struct ieee80211_s1g_oper_ie *oper,
				struct cfg80211_chan_def *chandef)
{}

int ieee80211_put_srates_elem(struct sk_buff *skb,
			      const struct ieee80211_supported_band *sband,
			      u32 basic_rates, u32 rate_flags, u32 masked_rates,
			      u8 element_id)
{}

int ieee80211_ave_rssi(struct ieee80211_vif *vif)
{}
EXPORT_SYMBOL_GPL();

u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs)
{}

/**
 * ieee80211_calculate_rx_timestamp - calculate timestamp in frame
 * @local: mac80211 hw info struct
 * @status: RX status
 * @mpdu_len: total MPDU length (including FCS)
 * @mpdu_offset: offset into MPDU to calculate timestamp at
 *
 * This function calculates the RX timestamp at the given MPDU offset, taking
 * into account what the RX timestamp was. An offset of 0 will just normalize
 * the timestamp to TSF at beginning of MPDU reception.
 *
 * Returns: the calculated timestamp
 */
u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
				     struct ieee80211_rx_status *status,
				     unsigned int mpdu_len,
				     unsigned int mpdu_offset)
{}

void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
{}

void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
				       struct wiphy_work *work)
{}

void ieee80211_radar_detected(struct ieee80211_hw *hw)
{}
EXPORT_SYMBOL();

void ieee80211_chandef_downgrade(struct cfg80211_chan_def *c,
				 struct ieee80211_conn_settings *conn)
{}

/*
 * Returns true if smps_mode_new is strictly more restrictive than
 * smps_mode_old.
 */
bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old,
				   enum ieee80211_smps_mode smps_mode_new)
{}

int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
			      struct cfg80211_csa_settings *csa_settings)
{}

static bool
ieee80211_extend_noa_desc(struct ieee80211_noa_data *data, u32 tsf, int i)
{}

static bool
ieee80211_extend_absent_time(struct ieee80211_noa_data *data, u32 tsf,
			     s32 *offset)
{}

static u32
ieee80211_get_noa_absent_time(struct ieee80211_noa_data *data, u32 tsf)
{}

void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf)
{}
EXPORT_SYMBOL();

int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr,
			    struct ieee80211_noa_data *data, u32 tsf)
{}
EXPORT_SYMBOL();

void ieee80211_recalc_dtim(struct ieee80211_local *local,
			   struct ieee80211_sub_if_data *sdata)
{}

static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local,
					 struct ieee80211_chanctx *ctx)
{}

static u32
__ieee80211_get_radio_mask(struct ieee80211_sub_if_data *sdata)
{}

u32 ieee80211_get_radio_mask(struct wiphy *wiphy, struct net_device *dev)
{}

static bool
ieee80211_sdata_uses_radio(struct ieee80211_sub_if_data *sdata, int radio_idx)
{}

static int
ieee80211_fill_ifcomb_params(struct ieee80211_local *local,
			     struct iface_combination_params *params,
			     const struct cfg80211_chan_def *chandef,
			     struct ieee80211_sub_if_data *sdata)
{}

int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
				 const struct cfg80211_chan_def *chandef,
				 enum ieee80211_chanctx_mode chanmode,
				 u8 radar_detect, int radio_idx)
{}

static void
ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c,
			 void *data)
{}

int ieee80211_max_num_channels(struct ieee80211_local *local, int radio_idx)
{}

void ieee80211_add_s1g_capab_ie(struct ieee80211_sub_if_data *sdata,
				struct ieee80211_sta_s1g_cap *caps,
				struct sk_buff *skb)
{}

void ieee80211_add_aid_request_ie(struct ieee80211_sub_if_data *sdata,
				  struct sk_buff *skb)
{}

u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo)
{}

void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
			     unsigned long *frame_cnt,
			     unsigned long *byte_cnt)
{}
EXPORT_SYMBOL();

const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS] =;

u16 ieee80211_encode_usf(int listen_interval)
{}

/* this may return more than ieee80211_put_eht_cap() will need */
u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata)
{}

int ieee80211_put_eht_cap(struct sk_buff *skb,
			  struct ieee80211_sub_if_data *sdata,
			  const struct ieee80211_supported_band *sband,
			  const struct ieee80211_conn_settings *conn)
{}

const char *ieee80211_conn_mode_str(enum ieee80211_conn_mode mode)
{}

enum ieee80211_conn_bw_limit
ieee80211_min_bw_limit_from_chandef(struct cfg80211_chan_def *chandef)
{}

void ieee80211_clear_tpe(struct ieee80211_parsed_tpe *tpe)
{}