Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / net / mac80211 / rc80211_pid.h
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 */