1/* 2 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9#ifndef __RC_MINSTREL_H 10#define __RC_MINSTREL_H 11 12#define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ 13#define EWMA_DIV 128 14#define SAMPLE_COLUMNS 10 /* number of columns in sample table */ 15 16/* scaled fraction values */ 17#define MINSTREL_SCALE 16 18#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) 19#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) 20 21/* number of highest throughput rates to consider*/ 22#define MAX_THR_RATES 4 23 24/* 25 * Perform EWMA (Exponentially Weighted Moving Average) calculation 26 */ 27static inline int 28minstrel_ewma(int old, int new, int weight) 29{ 30 int diff, incr; 31 32 diff = new - old; 33 incr = (EWMA_DIV - weight) * diff / EWMA_DIV; 34 35 return old + incr; 36} 37 38/* 39 * Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation 40 */ 41static inline int 42minstrel_ewmsd(int old_ewmsd, int cur_prob, int prob_ewma, int weight) 43{ 44 int diff, incr, tmp_var; 45 46 /* calculate exponential weighted moving variance */ 47 diff = MINSTREL_TRUNC((cur_prob - prob_ewma) * 1000000); 48 incr = (EWMA_DIV - weight) * diff / EWMA_DIV; 49 tmp_var = old_ewmsd * old_ewmsd; 50 tmp_var = weight * (tmp_var + diff * incr / 1000000) / EWMA_DIV; 51 52 /* return standard deviation */ 53 return (u16) int_sqrt(tmp_var); 54} 55 56struct minstrel_rate_stats { 57 /* current / last sampling period attempts/success counters */ 58 u16 attempts, last_attempts; 59 u16 success, last_success; 60 61 /* total attempts/success counters */ 62 u64 att_hist, succ_hist; 63 64 /* statistis of packet delivery probability 65 * cur_prob - current prob within last update intervall 66 * prob_ewma - exponential weighted moving average of prob 67 * prob_ewmsd - exp. weighted moving standard deviation of prob */ 68 unsigned int cur_prob; 69 unsigned int prob_ewma; 70 u16 prob_ewmsd; 71 72 /* maximum retry counts */ 73 u8 retry_count; 74 u8 retry_count_rtscts; 75 76 u8 sample_skipped; 77 bool retry_updated; 78}; 79 80struct minstrel_rate { 81 int bitrate; 82 83 s8 rix; 84 u8 retry_count_cts; 85 u8 adjusted_retry_count; 86 87 unsigned int perfect_tx_time; 88 unsigned int ack_time; 89 90 int sample_limit; 91 92 struct minstrel_rate_stats stats; 93}; 94 95struct minstrel_sta_info { 96 struct ieee80211_sta *sta; 97 98 unsigned long last_stats_update; 99 unsigned int sp_ack_dur; 100 unsigned int rate_avg; 101 102 unsigned int lowest_rix; 103 104 u8 max_tp_rate[MAX_THR_RATES]; 105 u8 max_prob_rate; 106 unsigned int total_packets; 107 unsigned int sample_packets; 108 int sample_deferred; 109 110 unsigned int sample_row; 111 unsigned int sample_column; 112 113 int n_rates; 114 struct minstrel_rate *r; 115 bool prev_sample; 116 117 /* sampling table */ 118 u8 *sample_table; 119 120#ifdef CONFIG_MAC80211_DEBUGFS 121 struct dentry *dbg_stats; 122 struct dentry *dbg_stats_csv; 123#endif 124}; 125 126struct minstrel_priv { 127 struct ieee80211_hw *hw; 128 bool has_mrr; 129 unsigned int cw_min; 130 unsigned int cw_max; 131 unsigned int max_retry; 132 unsigned int segment_size; 133 unsigned int update_interval; 134 unsigned int lookaround_rate; 135 unsigned int lookaround_rate_mrr; 136 137 u8 cck_rates[4]; 138 139#ifdef CONFIG_MAC80211_DEBUGFS 140 /* 141 * enable fixed rate processing per RC 142 * - write static index to debugfs:ieee80211/phyX/rc/fixed_rate_idx 143 * - write -1 to enable RC processing again 144 * - setting will be applied on next update 145 */ 146 u32 fixed_rate_idx; 147 struct dentry *dbg_fixed_rate; 148#endif 149}; 150 151struct minstrel_debugfs_info { 152 size_t len; 153 char buf[]; 154}; 155 156extern const struct rate_control_ops mac80211_minstrel; 157void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); 158void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); 159 160/* Recalculate success probabilities and counters for a given rate using EWMA */ 161void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs); 162int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma); 163 164/* debugfs */ 165int minstrel_stats_open(struct inode *inode, struct file *file); 166int minstrel_stats_csv_open(struct inode *inode, struct file *file); 167ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos); 168int minstrel_stats_release(struct inode *inode, struct file *file); 169 170#endif 171