Fixes generated by 'codespell' and manually reviewed. Signed-off-by: Lucas De Marchi <lucas.demarchi@profusion.mobi>
		
			
				
	
	
		
			278 lines
		
	
	
	
		
			7.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
	
		
			7.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
 | 
						|
 * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
 | 
						|
 *
 | 
						|
 * 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 RC80211_PID_H
 | 
						|
#define RC80211_PID_H
 | 
						|
 | 
						|
/* Sampling period for measuring percentage of failed frames in ms. */
 | 
						|
#define RC_PID_INTERVAL			125
 | 
						|
 | 
						|
/* Exponential averaging smoothness (used for I part of PID controller) */
 | 
						|
#define RC_PID_SMOOTHING_SHIFT		3
 | 
						|
#define RC_PID_SMOOTHING		(1 << RC_PID_SMOOTHING_SHIFT)
 | 
						|
 | 
						|
/* Sharpening factor (used for D part of PID controller) */
 | 
						|
#define RC_PID_SHARPENING_FACTOR	0
 | 
						|
#define RC_PID_SHARPENING_DURATION	0
 | 
						|
 | 
						|
/* Fixed point arithmetic shifting amount. */
 | 
						|
#define RC_PID_ARITH_SHIFT		8
 | 
						|
 | 
						|
/* Proportional PID component coefficient. */
 | 
						|
#define RC_PID_COEFF_P			15
 | 
						|
/* Integral PID component coefficient. */
 | 
						|
#define RC_PID_COEFF_I			9
 | 
						|
/* Derivative PID component coefficient. */
 | 
						|
#define RC_PID_COEFF_D			15
 | 
						|
 | 
						|
/* Target failed frames rate for the PID controller. NB: This effectively gives
 | 
						|
 * maximum failed frames percentage we're willing to accept. If the wireless
 | 
						|
 * link quality is good, the controller will fail to adjust failed frames
 | 
						|
 * percentage to the target. This is intentional.
 | 
						|
 */
 | 
						|
#define RC_PID_TARGET_PF		14
 | 
						|
 | 
						|
/* Rate behaviour normalization quantity over time. */
 | 
						|
#define RC_PID_NORM_OFFSET		3
 | 
						|
 | 
						|
/* Push high rates right after loading. */
 | 
						|
#define RC_PID_FAST_START		0
 | 
						|
 | 
						|
/* Arithmetic right shift for positive and negative values for ISO C. */
 | 
						|
#define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
 | 
						|
	((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
 | 
						|
 | 
						|
enum rc_pid_event_type {
 | 
						|
	RC_PID_EVENT_TYPE_TX_STATUS,
 | 
						|
	RC_PID_EVENT_TYPE_RATE_CHANGE,
 | 
						|
	RC_PID_EVENT_TYPE_TX_RATE,
 | 
						|
	RC_PID_EVENT_TYPE_PF_SAMPLE,
 | 
						|
};
 | 
						|
 | 
						|
union rc_pid_event_data {
 | 
						|
	/* RC_PID_EVENT_TX_STATUS */
 | 
						|
	struct {
 | 
						|
		u32 flags;
 | 
						|
		struct ieee80211_tx_info tx_status;
 | 
						|
	};
 | 
						|
	/* RC_PID_EVENT_TYPE_RATE_CHANGE */
 | 
						|
	/* RC_PID_EVENT_TYPE_TX_RATE */
 | 
						|
	struct {
 | 
						|
		int index;
 | 
						|
		int rate;
 | 
						|
	};
 | 
						|
	/* RC_PID_EVENT_TYPE_PF_SAMPLE */
 | 
						|
	struct {
 | 
						|
		s32 pf_sample;
 | 
						|
		s32 prop_err;
 | 
						|
		s32 int_err;
 | 
						|
		s32 der_err;
 | 
						|
	};
 | 
						|
};
 | 
						|
 | 
						|
struct rc_pid_event {
 | 
						|
	/* The time when the event occurred */
 | 
						|
	unsigned long timestamp;
 | 
						|
 | 
						|
	/* Event ID number */
 | 
						|
	unsigned int id;
 | 
						|
 | 
						|
	/* Type of event */
 | 
						|
	enum rc_pid_event_type type;
 | 
						|
 | 
						|
	/* type specific data */
 | 
						|
	union rc_pid_event_data data;
 | 
						|
};
 | 
						|
 | 
						|
/* Size of the event ring buffer. */
 | 
						|
#define RC_PID_EVENT_RING_SIZE 32
 | 
						|
 | 
						|
struct rc_pid_event_buffer {
 | 
						|
	/* Counter that generates event IDs */
 | 
						|
	unsigned int ev_count;
 | 
						|
 | 
						|
	/* Ring buffer of events */
 | 
						|
	struct rc_pid_event ring[RC_PID_EVENT_RING_SIZE];
 | 
						|
 | 
						|
	/* Index to the entry in events_buf to be reused */
 | 
						|
	unsigned int next_entry;
 | 
						|
 | 
						|
	/* Lock that guards against concurrent access to this buffer struct */
 | 
						|
	spinlock_t lock;
 | 
						|
 | 
						|
	/* Wait queue for poll/select and blocking I/O */
 | 
						|
	wait_queue_head_t waitqueue;
 | 
						|
};
 | 
						|
 | 
						|
struct rc_pid_events_file_info {
 | 
						|
	/* The event buffer we read */
 | 
						|
	struct rc_pid_event_buffer *events;
 | 
						|
 | 
						|
	/* The entry we have should read next */
 | 
						|
	unsigned int next_entry;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * struct rc_pid_debugfs_entries - tunable parameters
 | 
						|
 *
 | 
						|
 * Algorithm parameters, tunable via debugfs.
 | 
						|
 * @target: target percentage for failed frames
 | 
						|
 * @sampling_period: error sampling interval in milliseconds
 | 
						|
 * @coeff_p: absolute value of the proportional coefficient
 | 
						|
 * @coeff_i: absolute value of the integral coefficient
 | 
						|
 * @coeff_d: absolute value of the derivative coefficient
 | 
						|
 * @smoothing_shift: absolute value of the integral smoothing factor (i.e.
 | 
						|
 *	amount of smoothing introduced by the exponential moving average)
 | 
						|
 * @sharpen_factor: absolute value of the derivative sharpening factor (i.e.
 | 
						|
 *	amount of emphasis given to the derivative term after low activity
 | 
						|
 *	events)
 | 
						|
 * @sharpen_duration: duration of the sharpening effect after the detected low
 | 
						|
 *	activity event, relative to sampling_period
 | 
						|
 * @norm_offset: amount of normalization periodically performed on the learnt
 | 
						|
 *	rate behaviour values (lower means we should trust more what we learnt
 | 
						|
 *	about behaviour of rates, higher means we should trust more the natural
 | 
						|
 *	ordering of rates)
 | 
						|
 */
 | 
						|
struct rc_pid_debugfs_entries {
 | 
						|
	struct dentry *target;
 | 
						|
	struct dentry *sampling_period;
 | 
						|
	struct dentry *coeff_p;
 | 
						|
	struct dentry *coeff_i;
 | 
						|
	struct dentry *coeff_d;
 | 
						|
	struct dentry *smoothing_shift;
 | 
						|
	struct dentry *sharpen_factor;
 | 
						|
	struct dentry *sharpen_duration;
 | 
						|
	struct dentry *norm_offset;
 | 
						|
};
 | 
						|
 | 
						|
void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
 | 
						|
				      struct ieee80211_tx_info *stat);
 | 
						|
 | 
						|
void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
 | 
						|
					       int index, int rate);
 | 
						|
 | 
						|
void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
 | 
						|
					   int index, int rate);
 | 
						|
 | 
						|
void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
 | 
						|
					     s32 pf_sample, s32 prop_err,
 | 
						|
					     s32 int_err, s32 der_err);
 | 
						|
 | 
						|
void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
 | 
						|
					     struct dentry *dir);
 | 
						|
 | 
						|
void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
 | 
						|
 | 
						|
struct rc_pid_sta_info {
 | 
						|
	unsigned long last_change;
 | 
						|
	unsigned long last_sample;
 | 
						|
 | 
						|
	u32 tx_num_failed;
 | 
						|
	u32 tx_num_xmit;
 | 
						|
 | 
						|
	int txrate_idx;
 | 
						|
 | 
						|
	/* Average failed frames percentage error (i.e. actual vs. target
 | 
						|
	 * percentage), scaled by RC_PID_SMOOTHING. This value is computed
 | 
						|
	 * using using an exponential weighted average technique:
 | 
						|
	 *
 | 
						|
	 *           (RC_PID_SMOOTHING - 1) * err_avg_old + err
 | 
						|
	 * err_avg = ------------------------------------------
 | 
						|
	 *                       RC_PID_SMOOTHING
 | 
						|
	 *
 | 
						|
	 * where err_avg is the new approximation, err_avg_old the previous one
 | 
						|
	 * and err is the error w.r.t. to the current failed frames percentage
 | 
						|
	 * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
 | 
						|
	 * given to the previous estimate, resulting in smoother behavior (i.e.
 | 
						|
	 * corresponding to a longer integration window).
 | 
						|
	 *
 | 
						|
	 * For computation, we actually don't use the above formula, but this
 | 
						|
	 * one:
 | 
						|
	 *
 | 
						|
	 * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
 | 
						|
	 *
 | 
						|
	 * where:
 | 
						|
	 * 	err_avg_scaled = err * RC_PID_SMOOTHING
 | 
						|
	 * 	err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
 | 
						|
	 *
 | 
						|
	 * This avoids floating point numbers and the per_failed_old value can
 | 
						|
	 * easily be obtained by shifting per_failed_old_scaled right by
 | 
						|
	 * RC_PID_SMOOTHING_SHIFT.
 | 
						|
	 */
 | 
						|
	s32 err_avg_sc;
 | 
						|
 | 
						|
	/* Last framed failes percentage sample. */
 | 
						|
	u32 last_pf;
 | 
						|
 | 
						|
	/* Sharpening needed. */
 | 
						|
	u8 sharp_cnt;
 | 
						|
 | 
						|
#ifdef CONFIG_MAC80211_DEBUGFS
 | 
						|
	/* Event buffer */
 | 
						|
	struct rc_pid_event_buffer events;
 | 
						|
 | 
						|
	/* Events debugfs file entry */
 | 
						|
	struct dentry *events_entry;
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
/* Algorithm parameters. We keep them on a per-algorithm approach, so they can
 | 
						|
 * be tuned individually for each interface.
 | 
						|
 */
 | 
						|
struct rc_pid_rateinfo {
 | 
						|
 | 
						|
	/* Map sorted rates to rates in ieee80211_hw_mode. */
 | 
						|
	int index;
 | 
						|
 | 
						|
	/* Map rates in ieee80211_hw_mode to sorted rates. */
 | 
						|
	int rev_index;
 | 
						|
 | 
						|
	/* Did we do any measurement on this rate? */
 | 
						|
	bool valid;
 | 
						|
 | 
						|
	/* Comparison with the lowest rate. */
 | 
						|
	int diff;
 | 
						|
};
 | 
						|
 | 
						|
struct rc_pid_info {
 | 
						|
 | 
						|
	/* The failed frames percentage target. */
 | 
						|
	unsigned int target;
 | 
						|
 | 
						|
	/* Rate at which failed frames percentage is sampled in 0.001s. */
 | 
						|
	unsigned int sampling_period;
 | 
						|
 | 
						|
	/* P, I and D coefficients. */
 | 
						|
	int coeff_p;
 | 
						|
	int coeff_i;
 | 
						|
	int coeff_d;
 | 
						|
 | 
						|
	/* Exponential averaging shift. */
 | 
						|
	unsigned int smoothing_shift;
 | 
						|
 | 
						|
	/* Sharpening factor and duration. */
 | 
						|
	unsigned int sharpen_factor;
 | 
						|
	unsigned int sharpen_duration;
 | 
						|
 | 
						|
	/* Normalization offset. */
 | 
						|
	unsigned int norm_offset;
 | 
						|
 | 
						|
	/* Rates information. */
 | 
						|
	struct rc_pid_rateinfo *rinfo;
 | 
						|
 | 
						|
	/* Index of the last used rate. */
 | 
						|
	int oldrate;
 | 
						|
 | 
						|
#ifdef CONFIG_MAC80211_DEBUGFS
 | 
						|
	/* Debugfs entries created for the parameters above. */
 | 
						|
	struct rc_pid_debugfs_entries dentries;
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
#endif /* RC80211_PID_H */
 |