^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef __RC_MINSTREL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define __RC_MINSTREL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define EWMA_DIV 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define SAMPLE_COLUMNS 10 /* number of columns in sample table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /* scaled fraction values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define MINSTREL_SCALE 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* number of highest throughput rates to consider*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define MAX_THR_RATES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Coefficients for moving average with noise filter (period=16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * scaled by 10 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * a1 = exp(-pi * sqrt(2) / period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * coeff3 = -sqr(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * coeff1 = 1 - coeff2 - coeff3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MINSTREL_AVG_COEFF2 - \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) MINSTREL_AVG_COEFF3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MINSTREL_AVG_COEFF2 0x00001499
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MINSTREL_AVG_COEFF3 -0x0000092e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Perform EWMA (Exponentially Weighted Moving Average) calculation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) minstrel_ewma(int old, int new, int weight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int diff, incr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) diff = new - old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return old + incr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) s32 out_1 = *prev_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) s32 out_2 = *prev_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) s32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (!in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) in += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (!out_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) val = out_1 = in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) val = MINSTREL_AVG_COEFF1 * in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) val += MINSTREL_AVG_COEFF2 * out_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) val += MINSTREL_AVG_COEFF3 * out_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) val >>= MINSTREL_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (val > 1 << MINSTREL_SCALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) val = 1 << MINSTREL_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *prev_2 = out_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *prev_1 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct minstrel_rate_stats {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* current / last sampling period attempts/success counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) u16 attempts, last_attempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u16 success, last_success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* total attempts/success counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u32 att_hist, succ_hist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* prob_avg - moving average of prob */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) u16 prob_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u16 prob_avg_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* maximum retry counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u8 retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u8 retry_count_rtscts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u8 sample_skipped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) bool retry_updated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct minstrel_rate {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) s8 rix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u8 retry_count_cts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u8 adjusted_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned int perfect_tx_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int ack_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int sample_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct minstrel_rate_stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct minstrel_sta_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct ieee80211_sta *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned long last_stats_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int sp_ack_dur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned int rate_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned int lowest_rix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u8 max_tp_rate[MAX_THR_RATES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u8 max_prob_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned int total_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int sample_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned int sample_row;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned int sample_column;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int n_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct minstrel_rate *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) bool prev_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* sampling table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u8 *sample_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct minstrel_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct ieee80211_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) bool has_mrr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) bool new_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u32 sample_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned int cw_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned int cw_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned int max_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned int segment_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) unsigned int update_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned int lookaround_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned int lookaround_rate_mrr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u8 cck_rates[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #ifdef CONFIG_MAC80211_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * enable fixed rate processing per RC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * - write static index to debugfs:ieee80211/phyX/rc/fixed_rate_idx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * - write -1 to enable RC processing again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * - setting will be applied on next update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u32 fixed_rate_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct minstrel_debugfs_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) char buf[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) extern const struct rate_control_ops mac80211_minstrel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Recalculate success probabilities and counters for a given rate using EWMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) void minstrel_calc_rate_stats(struct minstrel_priv *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct minstrel_rate_stats *mrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* debugfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int minstrel_stats_open(struct inode *inode, struct file *file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int minstrel_stats_csv_open(struct inode *inode, struct file *file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #endif