linux/net/mac80211/sta_info.c

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

#include <linux/module.h>
#include <linux/init.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/timer.h>
#include <linux/rtnetlink.h>

#include <net/codel.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
#include "rate.h"
#include "sta_info.h"
#include "debugfs_sta.h"
#include "mesh.h"
#include "wme.h"

/**
 * DOC: STA information lifetime rules
 *
 * STA info structures (&struct sta_info) are managed in a hash table
 * for faster lookup and a list for iteration. They are managed using
 * RCU, i.e. access to the list and hash table is protected by RCU.
 *
 * Upon allocating a STA info structure with sta_info_alloc(), the caller
 * owns that structure. It must then insert it into the hash table using
 * either sta_info_insert() or sta_info_insert_rcu(); only in the latter
 * case (which acquires an rcu read section but must not be called from
 * within one) will the pointer still be valid after the call. Note that
 * the caller may not do much with the STA info before inserting it; in
 * particular, it may not start any mesh peer link management or add
 * encryption keys.
 *
 * When the insertion fails (sta_info_insert()) returns non-zero), the
 * structure will have been freed by sta_info_insert()!
 *
 * Station entries are added by mac80211 when you establish a link with a
 * peer. This means different things for the different type of interfaces
 * we support. For a regular station this mean we add the AP sta when we
 * receive an association response from the AP. For IBSS this occurs when
 * get to know about a peer on the same IBSS. For WDS we add the sta for
 * the peer immediately upon device open. When using AP mode we add stations
 * for each respective station upon request from userspace through nl80211.
 *
 * In order to remove a STA info structure, various sta_info_destroy_*()
 * calls are available.
 *
 * There is no concept of ownership on a STA entry; each structure is
 * owned by the global hash table/list until it is removed. All users of
 * the structure need to be RCU protected so that the structure won't be
 * freed before they are done using it.
 */

struct sta_link_alloc {};

static const struct rhashtable_params sta_rht_params =;

static const struct rhashtable_params link_sta_rht_params =;

static int sta_info_hash_del(struct ieee80211_local *local,
			     struct sta_info *sta)
{}

static int link_sta_info_hash_add(struct ieee80211_local *local,
				  struct link_sta_info *link_sta)
{}

static int link_sta_info_hash_del(struct ieee80211_local *local,
				  struct link_sta_info *link_sta)
{}

void ieee80211_purge_sta_txqs(struct sta_info *sta)
{}

static void __cleanup_single_sta(struct sta_info *sta)
{}

static void cleanup_single_sta(struct sta_info *sta)
{}

struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local,
					 const u8 *addr)
{}

/* protected by RCU */
struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
			      const u8 *addr)
{}

/*
 * Get sta info either from the specified interface
 * or from one of its vlans
 */
struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
				  const u8 *addr)
{}

struct rhlist_head *link_sta_info_hash_lookup(struct ieee80211_local *local,
					      const u8 *addr)
{}

struct link_sta_info *
link_sta_info_get_bss(struct ieee80211_sub_if_data *sdata, const u8 *addr)
{}

struct ieee80211_sta *
ieee80211_find_sta_by_link_addrs(struct ieee80211_hw *hw,
				 const u8 *addr,
				 const u8 *localaddr,
				 unsigned int *link_id)
{}
EXPORT_SYMBOL_GPL();

struct sta_info *sta_info_get_by_addrs(struct ieee80211_local *local,
				       const u8 *sta_addr, const u8 *vif_addr)
{}

struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
				     int idx)
{}

static void sta_info_free_link(struct link_sta_info *link_sta)
{}

static void sta_remove_link(struct sta_info *sta, unsigned int link_id,
			    bool unhash)
{}

/**
 * sta_info_free - free STA
 *
 * @local: pointer to the global information
 * @sta: STA info to free
 *
 * This function must undo everything done by sta_info_alloc()
 * that may happen before sta_info_insert(). It may only be
 * called when sta_info_insert() has not been attempted (and
 * if that fails, the station is freed anyway.)
 */
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
{}

static int sta_info_hash_add(struct ieee80211_local *local,
			     struct sta_info *sta)
{}

static void sta_deliver_ps_frames(struct work_struct *wk)
{}

static int sta_prepare_rate_control(struct ieee80211_local *local,
				    struct sta_info *sta, gfp_t gfp)
{}

static int sta_info_alloc_link(struct ieee80211_local *local,
			       struct link_sta_info *link_info,
			       gfp_t gfp)
{}

static void sta_info_add_link(struct sta_info *sta,
			      unsigned int link_id,
			      struct link_sta_info *link_info,
			      struct ieee80211_link_sta *link_sta)
{}

static struct sta_info *
__sta_info_alloc(struct ieee80211_sub_if_data *sdata,
		 const u8 *addr, int link_id, const u8 *link_addr,
		 gfp_t gfp)
{}

struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
				const u8 *addr, gfp_t gfp)
{}

struct sta_info *sta_info_alloc_with_link(struct ieee80211_sub_if_data *sdata,
					  const u8 *mld_addr,
					  unsigned int link_id,
					  const u8 *link_addr,
					  gfp_t gfp)
{}

static int sta_info_insert_check(struct sta_info *sta)
{}

static int sta_info_insert_drv_state(struct ieee80211_local *local,
				     struct ieee80211_sub_if_data *sdata,
				     struct sta_info *sta)
{}

static void
ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata)
{}

static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
{}

int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
{}

int sta_info_insert(struct sta_info *sta)
{}

static inline void __bss_tim_set(u8 *tim, u16 id)
{}

static inline void __bss_tim_clear(u8 *tim, u16 id)
{}

static inline bool __bss_tim_get(u8 *tim, u16 id)
{}

static unsigned long ieee80211_tids_for_ac(int ac)
{}

static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
{}

void sta_info_recalc_tim(struct sta_info *sta)
{}

static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb)
{}


static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local,
						struct sta_info *sta, int ac)
{}

static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
					     struct sta_info *sta)
{}

static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
{}

static int _sta_info_move_state(struct sta_info *sta,
				enum ieee80211_sta_state new_state,
				bool recalc)
{}

int sta_info_move_state(struct sta_info *sta,
			enum ieee80211_sta_state new_state)
{}

static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc)
{}

int __must_check __sta_info_destroy(struct sta_info *sta)
{}

int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr)
{}

int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
			      const u8 *addr)
{}

static void sta_info_cleanup(struct timer_list *t)
{}

int sta_info_init(struct ieee80211_local *local)
{}

void sta_info_stop(struct ieee80211_local *local)
{}


int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans,
		     int link_id)
{}

void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
			  unsigned long exp_time)
{}

struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
						   const u8 *addr,
						   const u8 *localaddr)
{}
EXPORT_SYMBOL_GPL();

struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
					 const u8 *addr)
{}
EXPORT_SYMBOL();

/* powersave support code */
void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
{}

static void ieee80211_send_null_response(struct sta_info *sta, int tid,
					 enum ieee80211_frame_release_type reason,
					 bool call_driver, bool more_data)
{}

static int find_highest_prio_tid(unsigned long tids)
{}

/* Indicates if the MORE_DATA bit should be set in the last
 * frame obtained by ieee80211_sta_ps_get_frames.
 * Note that driver_release_tids is relevant only if
 * reason = IEEE80211_FRAME_RELEASE_PSPOLL
 */
static bool
ieee80211_sta_ps_more_data(struct sta_info *sta, u8 ignored_acs,
			   enum ieee80211_frame_release_type reason,
			   unsigned long driver_release_tids)
{}

static void
ieee80211_sta_ps_get_frames(struct sta_info *sta, int n_frames, u8 ignored_acs,
			    enum ieee80211_frame_release_type reason,
			    struct sk_buff_head *frames,
			    unsigned long *driver_release_tids)
{}

static void
ieee80211_sta_ps_deliver_response(struct sta_info *sta,
				  int n_frames, u8 ignored_acs,
				  enum ieee80211_frame_release_type reason)
{}

void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
{}

void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)
{}

void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
			       struct ieee80211_sta *pubsta, bool block)
{}
EXPORT_SYMBOL();

void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)
{}
EXPORT_SYMBOL();

void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid)
{}
EXPORT_SYMBOL();

void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
				u8 tid, bool buffered)
{}
EXPORT_SYMBOL();

void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
				    u32 tx_airtime, u32 rx_airtime)
{}
EXPORT_SYMBOL();

void __ieee80211_sta_recalc_aggregates(struct sta_info *sta, u16 active_links)
{}

void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta)
{}
EXPORT_SYMBOL();

void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
					  struct sta_info *sta, u8 ac,
					  u16 tx_airtime, bool tx_completed)
{}

static struct ieee80211_sta_rx_stats *
sta_get_last_rx_stats(struct sta_info *sta)
{}

static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
				  struct rate_info *rinfo)
{}

static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
{}

static inline u64 sta_get_tidstats_msdu(struct ieee80211_sta_rx_stats *rxstats,
					int tid)
{}

static void sta_set_tidstats(struct sta_info *sta,
			     struct cfg80211_tid_stats *tidstats,
			     int tid)
{}

static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats)
{}

void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
		   bool tidstats)
{}

u32 sta_get_expected_throughput(struct sta_info *sta)
{}

unsigned long ieee80211_sta_last_active(struct sta_info *sta)
{}

static void sta_update_codel_params(struct sta_info *sta, u32 thr)
{}

void ieee80211_sta_set_expected_throughput(struct ieee80211_sta *pubsta,
					   u32 thr)
{}

int ieee80211_sta_allocate_link(struct sta_info *sta, unsigned int link_id)
{}

void ieee80211_sta_free_link(struct sta_info *sta, unsigned int link_id)
{}

int ieee80211_sta_activate_link(struct sta_info *sta, unsigned int link_id)
{}

void ieee80211_sta_remove_link(struct sta_info *sta, unsigned int link_id)
{}

void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,
					   const u8 *ext_capab,
					   unsigned int ext_capab_len)
{}

#ifdef CONFIG_LOCKDEP
bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta)
{}
EXPORT_SYMBOL();
#endif