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