Linux Audio

Check our new training course

Loading...
v5.9
  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 */
 39static inline int
 40minstrel_ewma(int old, int new, int weight)
 41{
 42	int diff, incr;
 43
 44	diff = new - old;
 45	incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
 46
 47	return old + incr;
 48}
 49
 50static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in)
 
 
 
 
 51{
 52	s32 out_1 = *prev_1;
 53	s32 out_2 = *prev_2;
 54	s32 val;
 55
 56	if (!in)
 57		in += 1;
 58
 59	if (!out_1) {
 60		val = out_1 = in;
 61		goto out;
 62	}
 63
 64	val = MINSTREL_AVG_COEFF1 * in;
 65	val += MINSTREL_AVG_COEFF2 * out_1;
 66	val += MINSTREL_AVG_COEFF3 * out_2;
 67	val >>= MINSTREL_SCALE;
 68
 69	if (val > 1 << MINSTREL_SCALE)
 70		val = 1 << MINSTREL_SCALE;
 71	if (val < 0)
 72		val = 1;
 73
 74out:
 75	*prev_2 = out_1;
 76	*prev_1 = val;
 77
 78	return val;
 
 79}
 80
 81struct 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
101struct 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
116struct 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
142struct 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
168struct minstrel_debugfs_info {
169	size_t len;
170	char buf[];
171};
172
173extern const struct rate_control_ops mac80211_minstrel;
174void 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 */
177void minstrel_calc_rate_stats(struct minstrel_priv *mp,
178			      struct minstrel_rate_stats *mrs);
179int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg);
180
181/* debugfs */
182int minstrel_stats_open(struct inode *inode, struct file *file);
183int minstrel_stats_csv_open(struct inode *inode, struct file *file);
 
 
184
185#endif
v4.6
 
  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