1 /*
2  * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
3  * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9 
10 #ifndef RC80211_PID_H
11 #define RC80211_PID_H
12 
13 /* Sampling period for measuring percentage of failed frames in ms. */
14 #define RC_PID_INTERVAL			125
15 
16 /* Exponential averaging smoothness (used for I part of PID controller) */
17 #define RC_PID_SMOOTHING_SHIFT		3
18 #define RC_PID_SMOOTHING		(1 << RC_PID_SMOOTHING_SHIFT)
19 
20 /* Sharpening factor (used for D part of PID controller) */
21 #define RC_PID_SHARPENING_FACTOR	0
22 #define RC_PID_SHARPENING_DURATION	0
23 
24 /* Fixed point arithmetic shifting amount. */
25 #define RC_PID_ARITH_SHIFT		8
26 
27 /* Proportional PID component coefficient. */
28 #define RC_PID_COEFF_P			15
29 /* Integral PID component coefficient. */
30 #define RC_PID_COEFF_I			9
31 /* Derivative PID component coefficient. */
32 #define RC_PID_COEFF_D			15
33 
34 /* Target failed frames rate for the PID controller. NB: This effectively gives
35  * maximum failed frames percentage we're willing to accept. If the wireless
36  * link quality is good, the controller will fail to adjust failed frames
37  * percentage to the target. This is intentional.
38  */
39 #define RC_PID_TARGET_PF		14
40 
41 /* Rate behaviour normalization quantity over time. */
42 #define RC_PID_NORM_OFFSET		3
43 
44 /* Push high rates right after loading. */
45 #define RC_PID_FAST_START		0
46 
47 /* Arithmetic right shift for positive and negative values for ISO C. */
48 #define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
49 	((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
50 
51 enum rc_pid_event_type {
52 	RC_PID_EVENT_TYPE_TX_STATUS,
53 	RC_PID_EVENT_TYPE_RATE_CHANGE,
54 	RC_PID_EVENT_TYPE_TX_RATE,
55 	RC_PID_EVENT_TYPE_PF_SAMPLE,
56 };
57 
58 union rc_pid_event_data {
59 	/* RC_PID_EVENT_TX_STATUS */
60 	struct {
61 		u32 flags;
62 		struct ieee80211_tx_info tx_status;
63 	};
64 	/* RC_PID_EVENT_TYPE_RATE_CHANGE */
65 	/* RC_PID_EVENT_TYPE_TX_RATE */
66 	struct {
67 		int index;
68 		int rate;
69 	};
70 	/* RC_PID_EVENT_TYPE_PF_SAMPLE */
71 	struct {
72 		s32 pf_sample;
73 		s32 prop_err;
74 		s32 int_err;
75 		s32 der_err;
76 	};
77 };
78 
79 struct rc_pid_event {
80 	/* The time when the event occurred */
81 	unsigned long timestamp;
82 
83 	/* Event ID number */
84 	unsigned int id;
85 
86 	/* Type of event */
87 	enum rc_pid_event_type type;
88 
89 	/* type specific data */
90 	union rc_pid_event_data data;
91 };
92 
93 /* Size of the event ring buffer. */
94 #define RC_PID_EVENT_RING_SIZE 32
95 
96 struct rc_pid_event_buffer {
97 	/* Counter that generates event IDs */
98 	unsigned int ev_count;
99 
100 	/* Ring buffer of events */
101 	struct rc_pid_event ring[RC_PID_EVENT_RING_SIZE];
102 
103 	/* Index to the entry in events_buf to be reused */
104 	unsigned int next_entry;
105 
106 	/* Lock that guards against concurrent access to this buffer struct */
107 	spinlock_t lock;
108 
109 	/* Wait queue for poll/select and blocking I/O */
110 	wait_queue_head_t waitqueue;
111 };
112 
113 struct rc_pid_events_file_info {
114 	/* The event buffer we read */
115 	struct rc_pid_event_buffer *events;
116 
117 	/* The entry we have should read next */
118 	unsigned int next_entry;
119 };
120 
121 /**
122  * struct rc_pid_debugfs_entries - tunable parameters
123  *
124  * Algorithm parameters, tunable via debugfs.
125  * @target: target percentage for failed frames
126  * @sampling_period: error sampling interval in milliseconds
127  * @coeff_p: absolute value of the proportional coefficient
128  * @coeff_i: absolute value of the integral coefficient
129  * @coeff_d: absolute value of the derivative coefficient
130  * @smoothing_shift: absolute value of the integral smoothing factor (i.e.
131  *	amount of smoothing introduced by the exponential moving average)
132  * @sharpen_factor: absolute value of the derivative sharpening factor (i.e.
133  *	amount of emphasis given to the derivative term after low activity
134  *	events)
135  * @sharpen_duration: duration of the sharpening effect after the detected low
136  *	activity event, relative to sampling_period
137  * @norm_offset: amount of normalization periodically performed on the learnt
138  *	rate behaviour values (lower means we should trust more what we learnt
139  *	about behaviour of rates, higher means we should trust more the natural
140  *	ordering of rates)
141  */
142 struct rc_pid_debugfs_entries {
143 	struct dentry *target;
144 	struct dentry *sampling_period;
145 	struct dentry *coeff_p;
146 	struct dentry *coeff_i;
147 	struct dentry *coeff_d;
148 	struct dentry *smoothing_shift;
149 	struct dentry *sharpen_factor;
150 	struct dentry *sharpen_duration;
151 	struct dentry *norm_offset;
152 };
153 
154 void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
155 				      struct ieee80211_tx_info *stat);
156 
157 void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
158 					       int index, int rate);
159 
160 void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
161 					   int index, int rate);
162 
163 void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
164 					     s32 pf_sample, s32 prop_err,
165 					     s32 int_err, s32 der_err);
166 
167 void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
168 					     struct dentry *dir);
169 
170 void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
171 
172 struct rc_pid_sta_info {
173 	unsigned long last_change;
174 	unsigned long last_sample;
175 
176 	u32 tx_num_failed;
177 	u32 tx_num_xmit;
178 
179 	int txrate_idx;
180 
181 	/* Average failed frames percentage error (i.e. actual vs. target
182 	 * percentage), scaled by RC_PID_SMOOTHING. This value is computed
183 	 * using using an exponential weighted average technique:
184 	 *
185 	 *           (RC_PID_SMOOTHING - 1) * err_avg_old + err
186 	 * err_avg = ------------------------------------------
187 	 *                       RC_PID_SMOOTHING
188 	 *
189 	 * where err_avg is the new approximation, err_avg_old the previous one
190 	 * and err is the error w.r.t. to the current failed frames percentage
191 	 * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
192 	 * given to the previous estimate, resulting in smoother behavior (i.e.
193 	 * corresponding to a longer integration window).
194 	 *
195 	 * For computation, we actually don't use the above formula, but this
196 	 * one:
197 	 *
198 	 * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
199 	 *
200 	 * where:
201 	 * 	err_avg_scaled = err * RC_PID_SMOOTHING
202 	 * 	err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
203 	 *
204 	 * This avoids floating point numbers and the per_failed_old value can
205 	 * easily be obtained by shifting per_failed_old_scaled right by
206 	 * RC_PID_SMOOTHING_SHIFT.
207 	 */
208 	s32 err_avg_sc;
209 
210 	/* Last framed failes percentage sample. */
211 	u32 last_pf;
212 
213 	/* Sharpening needed. */
214 	u8 sharp_cnt;
215 
216 #ifdef CONFIG_MAC80211_DEBUGFS
217 	/* Event buffer */
218 	struct rc_pid_event_buffer events;
219 
220 	/* Events debugfs file entry */
221 	struct dentry *events_entry;
222 #endif
223 };
224 
225 /* Algorithm parameters. We keep them on a per-algorithm approach, so they can
226  * be tuned individually for each interface.
227  */
228 struct rc_pid_rateinfo {
229 
230 	/* Map sorted rates to rates in ieee80211_hw_mode. */
231 	int index;
232 
233 	/* Map rates in ieee80211_hw_mode to sorted rates. */
234 	int rev_index;
235 
236 	/* Did we do any measurement on this rate? */
237 	bool valid;
238 
239 	/* Comparison with the lowest rate. */
240 	int diff;
241 };
242 
243 struct rc_pid_info {
244 
245 	/* The failed frames percentage target. */
246 	unsigned int target;
247 
248 	/* Rate at which failed frames percentage is sampled in 0.001s. */
249 	unsigned int sampling_period;
250 
251 	/* P, I and D coefficients. */
252 	int coeff_p;
253 	int coeff_i;
254 	int coeff_d;
255 
256 	/* Exponential averaging shift. */
257 	unsigned int smoothing_shift;
258 
259 	/* Sharpening factor and duration. */
260 	unsigned int sharpen_factor;
261 	unsigned int sharpen_duration;
262 
263 	/* Normalization offset. */
264 	unsigned int norm_offset;
265 
266 	/* Rates information. */
267 	struct rc_pid_rateinfo *rinfo;
268 
269 	/* Index of the last used rate. */
270 	int oldrate;
271 
272 #ifdef CONFIG_MAC80211_DEBUGFS
273 	/* Debugfs entries created for the parameters above. */
274 	struct rc_pid_debugfs_entries dentries;
275 #endif
276 };
277 
278 #endif /* RC80211_PID_H */
279