2008-10-05 20:07:45 +04:00
/*
* Copyright ( C ) 2008 Felix Fietkau < nbd @ openwrt . org >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# ifndef __RC_MINSTREL_H
# define __RC_MINSTREL_H
2013-04-17 15:43:22 +04:00
# define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */
# define EWMA_DIV 128
2013-03-05 02:30:05 +04:00
# define SAMPLE_COLUMNS 10 /* number of columns in sample table */
2013-03-05 02:30:02 +04:00
/* scaled fraction values */
2016-12-14 22:46:59 +03:00
# define MINSTREL_SCALE 12
2013-03-05 02:30:02 +04:00
# define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
# define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
2013-03-05 02:30:07 +04:00
/* number of highest throughput rates to consider*/
# define MAX_THR_RATES 4
2013-03-05 02:30:01 +04:00
/*
* Perform EWMA ( Exponentially Weighted Moving Average ) calculation
2015-03-24 23:09:36 +03:00
*/
2013-03-05 02:30:01 +04:00
static inline int
minstrel_ewma ( int old , int new , int weight )
{
2015-03-24 23:09:42 +03:00
int diff , incr ;
diff = new - old ;
incr = ( EWMA_DIV - weight ) * diff / EWMA_DIV ;
return old + incr ;
2013-03-05 02:30:01 +04:00
}
2015-03-24 23:09:43 +03:00
/*
2016-12-14 22:47:00 +03:00
* Perform EWMV ( Exponentially Weighted Moving Variance ) calculation
2015-03-24 23:09:43 +03:00
*/
static inline int
2016-12-14 22:47:00 +03:00
minstrel_ewmv ( int old_ewmv , int cur_prob , int prob_ewma , int weight )
2015-03-24 23:09:43 +03:00
{
2016-12-14 22:47:00 +03:00
int diff , incr ;
2015-03-24 23:09:43 +03:00
2016-12-14 22:47:00 +03:00
diff = cur_prob - prob_ewma ;
2015-03-24 23:09:43 +03:00
incr = ( EWMA_DIV - weight ) * diff / EWMA_DIV ;
2016-12-14 22:47:00 +03:00
return weight * ( old_ewmv + MINSTREL_TRUNC ( diff * incr ) ) / EWMA_DIV ;
2015-03-24 23:09:43 +03:00
}
2014-09-10 01:22:13 +04:00
struct minstrel_rate_stats {
/* current / last sampling period attempts/success counters */
2014-12-17 15:38:34 +03:00
u16 attempts , last_attempts ;
u16 success , last_success ;
2014-09-10 01:22:13 +04:00
/* total attempts/success counters */
2016-12-14 22:46:56 +03:00
u32 att_hist , succ_hist ;
2014-09-10 01:22:13 +04:00
2015-03-24 23:09:39 +03:00
/* statistis of packet delivery probability
2015-03-24 23:09:43 +03:00
* prob_ewma - exponential weighted moving average of prob
* prob_ewmsd - exp . weighted moving standard deviation of prob */
2016-12-14 22:47:01 +03:00
u16 prob_ewma ;
2016-12-14 22:47:00 +03:00
u16 prob_ewmv ;
2014-09-10 01:22:13 +04:00
/* maximum retry counts */
2014-12-17 15:38:34 +03:00
u8 retry_count ;
u8 retry_count_rtscts ;
2014-09-10 01:22:13 +04:00
u8 sample_skipped ;
bool retry_updated ;
} ;
2013-03-05 02:30:01 +04:00
2008-10-05 20:07:45 +04:00
struct minstrel_rate {
int bitrate ;
2014-12-17 15:38:34 +03:00
s8 rix ;
u8 retry_count_cts ;
u8 adjusted_retry_count ;
2008-10-05 20:07:45 +04:00
unsigned int perfect_tx_time ;
unsigned int ack_time ;
2008-10-15 21:13:59 +04:00
int sample_limit ;
2008-10-05 20:07:45 +04:00
2014-09-10 01:22:13 +04:00
struct minstrel_rate_stats stats ;
2008-10-05 20:07:45 +04:00
} ;
struct minstrel_sta_info {
2013-04-22 18:14:43 +04:00
struct ieee80211_sta * sta ;
2015-03-24 23:09:39 +03:00
unsigned long last_stats_update ;
2008-10-05 20:07:45 +04:00
unsigned int sp_ack_dur ;
unsigned int rate_avg ;
unsigned int lowest_rix ;
2013-03-05 02:30:07 +04:00
u8 max_tp_rate [ MAX_THR_RATES ] ;
u8 max_prob_rate ;
2014-09-10 01:22:13 +04:00
unsigned int total_packets ;
unsigned int sample_packets ;
2008-10-05 20:07:45 +04:00
int sample_deferred ;
2013-03-05 02:30:03 +04:00
unsigned int sample_row ;
2008-10-05 20:07:45 +04:00
unsigned int sample_column ;
int n_rates ;
struct minstrel_rate * r ;
2008-10-15 21:13:59 +04:00
bool prev_sample ;
2008-10-05 20:07:45 +04:00
/* sampling table */
u8 * sample_table ;
# ifdef CONFIG_MAC80211_DEBUGFS
struct dentry * dbg_stats ;
2015-03-24 23:09:36 +03:00
struct dentry * dbg_stats_csv ;
2008-10-05 20:07:45 +04:00
# endif
} ;
struct minstrel_priv {
struct ieee80211_hw * hw ;
bool has_mrr ;
unsigned int cw_min ;
unsigned int cw_max ;
unsigned int max_retry ;
unsigned int segment_size ;
unsigned int update_interval ;
unsigned int lookaround_rate ;
unsigned int lookaround_rate_mrr ;
2011-05-20 22:29:17 +04:00
2013-02-13 13:51:08 +04:00
u8 cck_rates [ 4 ] ;
2011-05-20 22:29:17 +04:00
# ifdef CONFIG_MAC80211_DEBUGFS
/*
* enable fixed rate processing per RC
* - write static index to debugfs : ieee80211 / phyX / rc / fixed_rate_idx
* - write - 1 to enable RC processing again
* - setting will be applied on next update
*/
u32 fixed_rate_idx ;
struct dentry * dbg_fixed_rate ;
# endif
2008-10-05 20:07:45 +04:00
} ;
2010-03-02 00:17:38 +03:00
struct minstrel_debugfs_info {
size_t len ;
char buf [ ] ;
} ;
2016-12-14 22:47:00 +03:00
/* Get EWMSD (Exponentially Weighted Moving Standard Deviation) * 10 */
static inline int
minstrel_get_ewmsd10 ( struct minstrel_rate_stats * mrs )
{
unsigned int ewmv = mrs - > prob_ewmv ;
return int_sqrt ( MINSTREL_TRUNC ( ewmv * 1000 * 1000 ) ) ;
}
2014-01-21 02:29:34 +04:00
extern const struct rate_control_ops mac80211_minstrel ;
2008-10-05 20:07:45 +04:00
void minstrel_add_sta_debugfs ( void * priv , void * priv_sta , struct dentry * dir ) ;
void minstrel_remove_sta_debugfs ( void * priv , void * priv_sta ) ;
2015-03-24 23:09:38 +03:00
/* Recalculate success probabilities and counters for a given rate using EWMA */
2015-03-24 23:09:39 +03:00
void minstrel_calc_rate_stats ( struct minstrel_rate_stats * mrs ) ;
2015-03-24 23:09:41 +03:00
int minstrel_get_tp_avg ( struct minstrel_rate * mr , int prob_ewma ) ;
2015-03-24 23:09:38 +03:00
2010-03-02 00:21:40 +03:00
/* debugfs */
int minstrel_stats_open ( struct inode * inode , struct file * file ) ;
2015-03-24 23:09:36 +03:00
int minstrel_stats_csv_open ( struct inode * inode , struct file * file ) ;
2010-03-02 00:21:40 +03:00
ssize_t minstrel_stats_read ( struct file * file , char __user * buf , size_t len , loff_t * ppos ) ;
int minstrel_stats_release ( struct inode * inode , struct file * file ) ;
2008-10-05 20:07:45 +04:00
# endif