blob: 19111c7bf454bc022eff5dfca098af465b25b8a8 [file] [log] [blame]
Mattias Nissler12446c62007-12-19 01:27:18 +01001/*
2 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
Stefano Brivioca5fbca2007-12-23 04:40:32 +01003 * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
Mattias Nissler12446c62007-12-19 01:27:18 +01004 *
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
Stefano Brivio1b507e72007-12-23 17:49:00 +010013/* Sampling period for measuring percentage of failed frames in ms. */
14#define RC_PID_INTERVAL 125
Mattias Nissler12446c62007-12-19 01:27:18 +010015
16/* Exponential averaging smoothness (used for I part of PID controller) */
Stefano Briviod4398102007-12-23 04:44:56 +010017#define RC_PID_SMOOTHING_SHIFT 3
18#define RC_PID_SMOOTHING (1 << RC_PID_SMOOTHING_SHIFT)
Mattias Nissler12446c62007-12-19 01:27:18 +010019
20/* Sharpening factor (used for D part of PID controller) */
Stefano Briviod4398102007-12-23 04:44:56 +010021#define RC_PID_SHARPENING_FACTOR 0
22#define RC_PID_SHARPENING_DURATION 0
Mattias Nissler12446c62007-12-19 01:27:18 +010023
24/* Fixed point arithmetic shifting amount. */
Stefano Briviod4398102007-12-23 04:44:56 +010025#define RC_PID_ARITH_SHIFT 8
Mattias Nissler12446c62007-12-19 01:27:18 +010026
Mattias Nissler12446c62007-12-19 01:27:18 +010027/* Proportional PID component coefficient. */
Stefano Briviod4398102007-12-23 04:44:56 +010028#define RC_PID_COEFF_P 15
Mattias Nissler12446c62007-12-19 01:27:18 +010029/* Integral PID component coefficient. */
Stefano Briviod4398102007-12-23 04:44:56 +010030#define RC_PID_COEFF_I 9
Mattias Nissler12446c62007-12-19 01:27:18 +010031/* Derivative PID component coefficient. */
Stefano Briviod4398102007-12-23 04:44:56 +010032#define RC_PID_COEFF_D 15
Mattias Nissler12446c62007-12-19 01:27:18 +010033
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 */
Stefano Briviod4398102007-12-23 04:44:56 +010039#define RC_PID_TARGET_PF 14
Mattias Nissler12446c62007-12-19 01:27:18 +010040
41/* Rate behaviour normalization quantity over time. */
Stefano Briviod4398102007-12-23 04:44:56 +010042#define RC_PID_NORM_OFFSET 3
Mattias Nissler12446c62007-12-19 01:27:18 +010043
44/* Push high rates right after loading. */
Stefano Briviod4398102007-12-23 04:44:56 +010045#define RC_PID_FAST_START 0
Mattias Nissler12446c62007-12-19 01:27:18 +010046
47/* Arithmetic right shift for positive and negative values for ISO C. */
48#define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
Johannes Bergc6a1fa12008-10-07 12:04:32 +020049 ((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
Mattias Nissler12446c62007-12-19 01:27:18 +010050
51enum 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
58union rc_pid_event_data {
59 /* RC_PID_EVENT_TX_STATUS */
60 struct {
Johannes Berge6a98542008-10-21 12:40:02 +020061 u32 flags;
Johannes Berge039fa42008-05-15 12:55:29 +020062 struct ieee80211_tx_info tx_status;
Mattias Nissler12446c62007-12-19 01:27:18 +010063 };
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
79struct rc_pid_event {
Lucas De Marchi25985ed2011-03-30 22:57:33 -030080 /* The time when the event occurred */
Mattias Nissler12446c62007-12-19 01:27:18 +010081 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
96struct 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
113struct 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
Stefano Brivioca5fbca2007-12-23 04:40:32 +0100121/**
122 * struct rc_pid_debugfs_entries - tunable parameters
123 *
124 * Algorithm parameters, tunable via debugfs.
Stefano Brivioca5fbca2007-12-23 04:40:32 +0100125 * @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)
Stefano Brivioca5fbca2007-12-23 04:40:32 +0100141 */
Mattias Nissler1946b742007-12-20 13:27:26 +0100142struct rc_pid_debugfs_entries {
Mattias Nissler1946b742007-12-20 13:27:26 +0100143 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;
Mattias Nissler1946b742007-12-20 13:27:26 +0100152};
153
Mattias Nissler12446c62007-12-19 01:27:18 +0100154void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
Johannes Berge039fa42008-05-15 12:55:29 +0200155 struct ieee80211_tx_info *stat);
Mattias Nissler12446c62007-12-19 01:27:18 +0100156
157void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
158 int index, int rate);
159
160void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
161 int index, int rate);
162
163void 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
167void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
168 struct dentry *dir);
169
170void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
171
172struct 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
Johannes Bergae17e982008-09-11 03:04:36 +0200179 int txrate_idx;
180
Mattias Nissler12446c62007-12-19 01:27:18 +0100181 /* 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 */
228struct 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
243struct 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
Mattias Nissler1946b742007-12-20 13:27:26 +0100259 /* Sharpening factor and duration. */
260 unsigned int sharpen_factor;
Mattias Nissler12446c62007-12-19 01:27:18 +0100261 unsigned int sharpen_duration;
262
263 /* Normalization offset. */
264 unsigned int norm_offset;
265
Mattias Nissler12446c62007-12-19 01:27:18 +0100266 /* Rates information. */
267 struct rc_pid_rateinfo *rinfo;
268
269 /* Index of the last used rate. */
270 int oldrate;
Mattias Nissler1946b742007-12-20 13:27:26 +0100271
272#ifdef CONFIG_MAC80211_DEBUGFS
273 /* Debugfs entries created for the parameters above. */
274 struct rc_pid_debugfs_entries dentries;
275#endif
Mattias Nissler12446c62007-12-19 01:27:18 +0100276};
277
278#endif /* RC80211_PID_H */