linux/net/mac80211/rc80211_minstrel_ht.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2010-2013 Felix Fietkau <[email protected]>
 * Copyright (C) 2019-2022 Intel Corporation
 */
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/debugfs.h>
#include <linux/random.h>
#include <linux/moduleparam.h>
#include <linux/ieee80211.h>
#include <linux/minmax.h>
#include <net/mac80211.h>
#include "rate.h"
#include "sta_info.h"
#include "rc80211_minstrel_ht.h"

#define AVG_AMPDU_SIZE
#define AVG_PKT_SIZE

/* Number of bits for an average sized packet */
#define MCS_NBITS

/* Number of symbols for a packet with (bps) bits per symbol */
#define MCS_NSYMS(bps)

/* Transmission time (nanoseconds) for a packet containing (syms) symbols */
#define MCS_SYMBOL_TIME(sgi, syms)

/* Transmit duration for the raw data part of an average sized packet */
#define MCS_DURATION(streams, sgi, bps)

#define BW_20
#define BW_40
#define BW_80

/*
 * Define group sort order: HT40 -> SGI -> #streams
 */
#define GROUP_IDX(_streams, _sgi, _ht40)

#define _MAX(a, b)

#define GROUP_SHIFT(duration)

/* MCS rate information for an MCS group */
#define __MCS_GROUP(_streams, _sgi, _ht40, _s)

#define MCS_GROUP_SHIFT(_streams, _sgi, _ht40)

#define MCS_GROUP(_streams, _sgi, _ht40)

#define VHT_GROUP_IDX(_streams, _sgi, _bw)

#define BW2VBPS(_bw, r3, r2, r1)

#define __VHT_GROUP(_streams, _sgi, _bw, _s)

#define VHT_GROUP_SHIFT(_streams, _sgi, _bw)

#define VHT_GROUP(_streams, _sgi, _bw)

#define CCK_DURATION(_bitrate, _short)

#define CCK_DURATION_LIST(_short, _s)

#define __CCK_GROUP(_s)

#define CCK_GROUP_SHIFT

#define CCK_GROUP

#define OFDM_DURATION(_bitrate)

#define OFDM_DURATION_LIST(_s)

#define __OFDM_GROUP(_s)

#define OFDM_GROUP_SHIFT

#define OFDM_GROUP


static bool minstrel_vht_only =;
module_param(minstrel_vht_only, bool, 0644);
MODULE_PARM_DESC();

/*
 * To enable sufficiently targeted rate sampling, MCS rates are divided into
 * groups, based on the number of streams and flags (HT40, SGI) that they
 * use.
 *
 * Sortorder has to be fixed for GROUP_IDX macro to be applicable:
 * BW -> SGI -> #streams
 */
const struct mcs_group minstrel_mcs_groups[] =;

const s16 minstrel_cck_bitrates[4] =;
const s16 minstrel_ofdm_bitrates[8] =;
static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
static const u8 minstrel_sample_seq[] =;

static void
minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);

/*
 * Some VHT MCSes are invalid (when Ndbps / Nes is not an integer)
 * e.g for MCS9@20MHzx1Nss: Ndbps=8x52*(5/6) Nes=1
 *
 * Returns the valid mcs map for struct minstrel_mcs_group_data.supported
 */
static u16
minstrel_get_valid_vht_rates(int bw, int nss, __le16 mcs_map)
{}

static bool
minstrel_ht_is_legacy_group(int group)
{}

/*
 * Look up an MCS group index based on mac80211 rate information
 */
static int
minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate)
{}

/*
 * Look up an MCS group index based on new cfg80211 rate_info.
 */
static int
minstrel_ht_ri_get_group_idx(struct rate_info *rate)
{}

static int
minstrel_vht_get_group_idx(struct ieee80211_tx_rate *rate)
{}

/*
 * Look up an MCS group index based on new cfg80211 rate_info.
 */
static int
minstrel_vht_ri_get_group_idx(struct rate_info *rate)
{}

static struct minstrel_rate_stats *
minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
		      struct ieee80211_tx_rate *rate)
{}

/*
 * Get the minstrel rate statistics for specified STA and rate info.
 */
static struct minstrel_rate_stats *
minstrel_ht_ri_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
			  struct ieee80211_rate_status *rate_status)
{}

static inline struct minstrel_rate_stats *
minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index)
{}

static inline int minstrel_get_duration(int index)
{}

static unsigned int
minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi)
{}

/*
 * Return current throughput based on the average A-MPDU length, taking into
 * account the expected number of retransmissions and their expected length
 */
int
minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
		       int prob_avg)
{}

/*
 * Find & sort topmost throughput rates
 *
 * If multiple rates provide equal throughput the sorting is based on their
 * current success probability. Higher success probability is preferred among
 * MCS groups, CCK rates do not provide aggregation and are therefore at last.
 */
static void
minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index,
			       u16 *tp_list)
{}

/*
 * Find and set the topmost probability rate per sta and per group
 */
static void
minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
{}


/*
 * Assign new rate set per sta and use CCK rates only if the fastest
 * rate (max_tp_rate[0]) is from CCK group. This prohibits such sorted
 * rate sets where MCS and CCK rates are mixed, because CCK rates can
 * not use aggregation.
 */
static void
minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
				 u16 tmp_mcs_tp_rate[MAX_THR_RATES],
				 u16 tmp_legacy_tp_rate[MAX_THR_RATES])
{}

/*
 * Try to increase robustness of max_prob rate by decrease number of
 * streams if possible.
 */
static inline void
minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi)
{}

static u16
__minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi,
			      enum minstrel_sample_type type)
{}

static inline int
minstrel_ewma(int old, int new, int weight)
{}

static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in)
{}

/*
* Recalculate statistics and counters of a given rate
*/
static void
minstrel_ht_calc_rate_stats(struct minstrel_priv *mp,
			    struct minstrel_rate_stats *mrs)
{}

static bool
minstrel_ht_find_sample_rate(struct minstrel_ht_sta *mi, int type, int idx)
{}

static int
minstrel_ht_move_sample_rates(struct minstrel_ht_sta *mi, int type,
			      u32 fast_rate_dur, u32 slow_rate_dur)
{}

static int
minstrel_ht_group_min_rate_offset(struct minstrel_ht_sta *mi, int group,
				  u32 max_duration)
{}

/*
 * Incremental update rates:
 * Flip through groups and pick the first group rate that is faster than the
 * highest currently selected rate
 */
static u16
minstrel_ht_next_inc_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur)
{}

static int
minstrel_ht_next_group_sample_rate(struct minstrel_ht_sta *mi, int group,
				   u16 supported, int offset)
{}

/*
 * Jump rates:
 * Sample random rates, use those that are faster than the highest
 * currently selected rate. Rates between the fastest and the slowest
 * get sorted into the slow sample bucket, but only if it has room
 */
static u16
minstrel_ht_next_jump_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur,
			   u32 slow_rate_dur, int *slow_rate_ofs)
{}

static void
minstrel_ht_refill_sample_rates(struct minstrel_ht_sta *mi)
{}


/*
 * Update rate statistics and select new primary rates
 *
 * Rules for rate selection:
 *  - max_prob_rate must use only one stream, as a tradeoff between delivery
 *    probability and throughput during strong fluctuations
 *  - as long as the max prob rate has a probability of more than 75%, pick
 *    higher throughput rates, even if the probablity is a bit lower
 */
static void
minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
{}

static bool
minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
			 struct ieee80211_tx_rate *rate)
{}

/*
 * Check whether rate_status contains valid information.
 */
static bool
minstrel_ht_ri_txstat_valid(struct minstrel_priv *mp,
			    struct minstrel_ht_sta *mi,
			    struct ieee80211_rate_status *rate_status)
{}

static void
minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
{}

static void
minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
                      void *priv_sta, struct ieee80211_tx_status *st)
{}

static void
minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
                         int index)
{}


static void
minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
                     struct ieee80211_sta_rates *ratetbl, int offset, int index)
{}

static inline int
minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate)
{}

static int
minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi)
{}

static void
minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
{}

static u16
minstrel_ht_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
{}

static void
minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
                     struct ieee80211_tx_rate_control *txrc)
{}

static void
minstrel_ht_update_cck(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
		       struct ieee80211_supported_band *sband,
		       struct ieee80211_sta *sta)
{}

static void
minstrel_ht_update_ofdm(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
			struct ieee80211_supported_band *sband,
			struct ieee80211_sta *sta)
{}

static void
minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
			struct cfg80211_chan_def *chandef,
			struct ieee80211_sta *sta, void *priv_sta)
{}

static void
minstrel_ht_rate_init(void *priv, struct ieee80211_supported_band *sband,
		      struct cfg80211_chan_def *chandef,
                      struct ieee80211_sta *sta, void *priv_sta)
{}

static void
minstrel_ht_rate_update(void *priv, struct ieee80211_supported_band *sband,
			struct cfg80211_chan_def *chandef,
                        struct ieee80211_sta *sta, void *priv_sta,
                        u32 changed)
{}

static void *
minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
{}

static void
minstrel_ht_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta)
{}

static void
minstrel_ht_fill_rate_array(u8 *dest, struct ieee80211_supported_band *sband,
			    const s16 *bitrates, int n_rates, u32 rate_flags)
{}

static void
minstrel_ht_init_cck_rates(struct minstrel_priv *mp)
{}

static void
minstrel_ht_init_ofdm_rates(struct minstrel_priv *mp, enum nl80211_band band)
{}

static void *
minstrel_ht_alloc(struct ieee80211_hw *hw)
{}

#ifdef CONFIG_MAC80211_DEBUGFS
static void minstrel_ht_add_debugfs(struct ieee80211_hw *hw, void *priv,
				    struct dentry *debugfsdir)
{}
#endif

static void
minstrel_ht_free(void *priv)
{}

static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
{}

static const struct rate_control_ops mac80211_minstrel_ht =;


static void __init init_sample_table(void)
{}

int __init
rc80211_minstrel_init(void)
{}

void
rc80211_minstrel_exit(void)
{}