2 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
3 * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
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.
13 /* Sampling period for measuring percentage of failed frames in ms. */
14 #define RC_PID_INTERVAL 125
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)
20 /* Sharpening factor (used for D part of PID controller) */
21 #define RC_PID_SHARPENING_FACTOR 0
22 #define RC_PID_SHARPENING_DURATION 0
24 /* Fixed point arithmetic shifting amount. */
25 #define RC_PID_ARITH_SHIFT 8
27 /* Fixed point arithmetic factor. */
28 #define RC_PID_ARITH_FACTOR (1 << RC_PID_ARITH_SHIFT)
30 /* Proportional PID component coefficient. */
31 #define RC_PID_COEFF_P 15
32 /* Integral PID component coefficient. */
33 #define RC_PID_COEFF_I 9
34 /* Derivative PID component coefficient. */
35 #define RC_PID_COEFF_D 15
37 /* Target failed frames rate for the PID controller. NB: This effectively gives
38 * maximum failed frames percentage we're willing to accept. If the wireless
39 * link quality is good, the controller will fail to adjust failed frames
40 * percentage to the target. This is intentional.
42 #define RC_PID_TARGET_PF 14
44 /* Rate behaviour normalization quantity over time. */
45 #define RC_PID_NORM_OFFSET 3
47 /* Push high rates right after loading. */
48 #define RC_PID_FAST_START 0
50 /* Arithmetic right shift for positive and negative values for ISO C. */
51 #define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
52 (x) < 0 ? -((-(x)) >> (y)) : (x) >> (y)
54 enum rc_pid_event_type
{
55 RC_PID_EVENT_TYPE_TX_STATUS
,
56 RC_PID_EVENT_TYPE_RATE_CHANGE
,
57 RC_PID_EVENT_TYPE_TX_RATE
,
58 RC_PID_EVENT_TYPE_PF_SAMPLE
,
61 union rc_pid_event_data
{
62 /* RC_PID_EVENT_TX_STATUS */
64 struct ieee80211_tx_info tx_status
;
66 /* RC_PID_EVENT_TYPE_RATE_CHANGE */
67 /* RC_PID_EVENT_TYPE_TX_RATE */
72 /* RC_PID_EVENT_TYPE_PF_SAMPLE */
82 /* The time when the event occured */
83 unsigned long timestamp
;
89 enum rc_pid_event_type type
;
91 /* type specific data */
92 union rc_pid_event_data data
;
95 /* Size of the event ring buffer. */
96 #define RC_PID_EVENT_RING_SIZE 32
98 struct rc_pid_event_buffer
{
99 /* Counter that generates event IDs */
100 unsigned int ev_count
;
102 /* Ring buffer of events */
103 struct rc_pid_event ring
[RC_PID_EVENT_RING_SIZE
];
105 /* Index to the entry in events_buf to be reused */
106 unsigned int next_entry
;
108 /* Lock that guards against concurrent access to this buffer struct */
111 /* Wait queue for poll/select and blocking I/O */
112 wait_queue_head_t waitqueue
;
115 struct rc_pid_events_file_info
{
116 /* The event buffer we read */
117 struct rc_pid_event_buffer
*events
;
119 /* The entry we have should read next */
120 unsigned int next_entry
;
124 * struct rc_pid_debugfs_entries - tunable parameters
126 * Algorithm parameters, tunable via debugfs.
127 * @target: target percentage for failed frames
128 * @sampling_period: error sampling interval in milliseconds
129 * @coeff_p: absolute value of the proportional coefficient
130 * @coeff_i: absolute value of the integral coefficient
131 * @coeff_d: absolute value of the derivative coefficient
132 * @smoothing_shift: absolute value of the integral smoothing factor (i.e.
133 * amount of smoothing introduced by the exponential moving average)
134 * @sharpen_factor: absolute value of the derivative sharpening factor (i.e.
135 * amount of emphasis given to the derivative term after low activity
137 * @sharpen_duration: duration of the sharpening effect after the detected low
138 * activity event, relative to sampling_period
139 * @norm_offset: amount of normalization periodically performed on the learnt
140 * rate behaviour values (lower means we should trust more what we learnt
141 * about behaviour of rates, higher means we should trust more the natural
144 struct rc_pid_debugfs_entries
{
145 struct dentry
*target
;
146 struct dentry
*sampling_period
;
147 struct dentry
*coeff_p
;
148 struct dentry
*coeff_i
;
149 struct dentry
*coeff_d
;
150 struct dentry
*smoothing_shift
;
151 struct dentry
*sharpen_factor
;
152 struct dentry
*sharpen_duration
;
153 struct dentry
*norm_offset
;
156 void rate_control_pid_event_tx_status(struct rc_pid_event_buffer
*buf
,
157 struct ieee80211_tx_info
*stat
);
159 void rate_control_pid_event_rate_change(struct rc_pid_event_buffer
*buf
,
160 int index
, int rate
);
162 void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer
*buf
,
163 int index
, int rate
);
165 void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer
*buf
,
166 s32 pf_sample
, s32 prop_err
,
167 s32 int_err
, s32 der_err
);
169 void rate_control_pid_add_sta_debugfs(void *priv
, void *priv_sta
,
172 void rate_control_pid_remove_sta_debugfs(void *priv
, void *priv_sta
);
174 struct rc_pid_sta_info
{
175 unsigned long last_change
;
176 unsigned long last_sample
;
183 /* Average failed frames percentage error (i.e. actual vs. target
184 * percentage), scaled by RC_PID_SMOOTHING. This value is computed
185 * using using an exponential weighted average technique:
187 * (RC_PID_SMOOTHING - 1) * err_avg_old + err
188 * err_avg = ------------------------------------------
191 * where err_avg is the new approximation, err_avg_old the previous one
192 * and err is the error w.r.t. to the current failed frames percentage
193 * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
194 * given to the previous estimate, resulting in smoother behavior (i.e.
195 * corresponding to a longer integration window).
197 * For computation, we actually don't use the above formula, but this
200 * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
203 * err_avg_scaled = err * RC_PID_SMOOTHING
204 * err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
206 * This avoids floating point numbers and the per_failed_old value can
207 * easily be obtained by shifting per_failed_old_scaled right by
208 * RC_PID_SMOOTHING_SHIFT.
212 /* Last framed failes percentage sample. */
215 /* Sharpening needed. */
218 #ifdef CONFIG_MAC80211_DEBUGFS
220 struct rc_pid_event_buffer events
;
222 /* Events debugfs file entry */
223 struct dentry
*events_entry
;
227 /* Algorithm parameters. We keep them on a per-algorithm approach, so they can
228 * be tuned individually for each interface.
230 struct rc_pid_rateinfo
{
232 /* Map sorted rates to rates in ieee80211_hw_mode. */
235 /* Map rates in ieee80211_hw_mode to sorted rates. */
238 /* Did we do any measurement on this rate? */
241 /* Comparison with the lowest rate. */
247 /* The failed frames percentage target. */
250 /* Rate at which failed frames percentage is sampled in 0.001s. */
251 unsigned int sampling_period
;
253 /* P, I and D coefficients. */
258 /* Exponential averaging shift. */
259 unsigned int smoothing_shift
;
261 /* Sharpening factor and duration. */
262 unsigned int sharpen_factor
;
263 unsigned int sharpen_duration
;
265 /* Normalization offset. */
266 unsigned int norm_offset
;
268 /* Rates information. */
269 struct rc_pid_rateinfo
*rinfo
;
271 /* Index of the last used rate. */
274 #ifdef CONFIG_MAC80211_DEBUGFS
275 /* Debugfs entries created for the parameters above. */
276 struct rc_pid_debugfs_entries dentries
;
280 #endif /* RC80211_PID_H */