blob: 7f8cf27ad2f94b6a57c94399031a0fd75de9eb98 [file] [log] [blame]
Mattias Nisslerad018372007-12-19 01:25:57 +01001/*
2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005, Devicescape Software, Inc.
4 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
Stefano Brivio90d501d2007-12-19 01:26:34 +01005 * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
Mattias Nisslerad018372007-12-19 01:25:57 +01006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/netdevice.h>
13#include <linux/types.h>
14#include <linux/skbuff.h>
15
16#include <net/mac80211.h>
17#include "ieee80211_rate.h"
18
19
20/* This is an implementation of a TX rate control algorithm that uses a PID
21 * controller. Given a target failed frames rate, the controller decides about
22 * TX rate changes to meet the target failed frames rate.
23 *
24 * The controller basically computes the following:
25 *
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +010026 * adj = CP * err + CI * err_avg + CD * (err - last_err) * (1 + sharpening)
Mattias Nisslerad018372007-12-19 01:25:57 +010027 *
28 * where
29 * adj adjustment value that is used to switch TX rate (see below)
30 * err current error: target vs. current failed frames percentage
31 * last_err last error
32 * err_avg average (i.e. poor man's integral) of recent errors
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +010033 * sharpening non-zero when fast response is needed (i.e. right after
34 * association or no frames sent for a long time), heading
35 * to zero over time
Mattias Nisslerad018372007-12-19 01:25:57 +010036 * CP Proportional coefficient
37 * CI Integral coefficient
38 * CD Derivative coefficient
39 *
40 * CP, CI, CD are subject to careful tuning.
41 *
42 * The integral component uses a exponential moving average approach instead of
43 * an actual sliding window. The advantage is that we don't need to keep an
44 * array of the last N error values and computation is easier.
45 *
Stefano Brivio90d501d2007-12-19 01:26:34 +010046 * Once we have the adj value, we map it to a rate by means of a learning
47 * algorithm. This algorithm keeps the state of the percentual failed frames
48 * difference between rates. The behaviour of the lowest available rate is kept
49 * as a reference value, and every time we switch between two rates, we compute
50 * the difference between the failed frames each rate exhibited. By doing so,
51 * we compare behaviours which different rates exhibited in adjacent timeslices,
52 * thus the comparison is minimally affected by external conditions. This
53 * difference gets propagated to the whole set of measurements, so that the
54 * reference is always the same. Periodically, we normalize this set so that
55 * recent events weigh the most. By comparing the adj value with this set, we
56 * avoid pejorative switches to lower rates and allow for switches to higher
57 * rates if they behaved well.
Mattias Nisslerad018372007-12-19 01:25:57 +010058 *
59 * Note that for the computations we use a fixed-point representation to avoid
60 * floating point arithmetic. Hence, all values are shifted left by
61 * RC_PID_ARITH_SHIFT.
62 */
63
64/* Sampling period for measuring percentage of failed frames. */
65#define RC_PID_INTERVAL (HZ / 8)
66
67/* Exponential averaging smoothness (used for I part of PID controller) */
68#define RC_PID_SMOOTHING_SHIFT 3
69#define RC_PID_SMOOTHING (1 << RC_PID_SMOOTHING_SHIFT)
70
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +010071/* Sharpening factor (used for D part of PID controller) */
72#define RC_PID_SHARPENING_FACTOR 0
73#define RC_PID_SHARPENING_DURATION 0
74
Mattias Nisslerad018372007-12-19 01:25:57 +010075/* Fixed point arithmetic shifting amount. */
76#define RC_PID_ARITH_SHIFT 8
77
78/* Fixed point arithmetic factor. */
79#define RC_PID_ARITH_FACTOR (1 << RC_PID_ARITH_SHIFT)
80
81/* Proportional PID component coefficient. */
82#define RC_PID_COEFF_P 15
83/* Integral PID component coefficient. */
84#define RC_PID_COEFF_I 9
85/* Derivative PID component coefficient. */
86#define RC_PID_COEFF_D 15
87
88/* Target failed frames rate for the PID controller. NB: This effectively gives
89 * maximum failed frames percentage we're willing to accept. If the wireless
90 * link quality is good, the controller will fail to adjust failed frames
91 * percentage to the target. This is intentional.
92 */
93#define RC_PID_TARGET_PF (11 << RC_PID_ARITH_SHIFT)
94
Stefano Brivio90d501d2007-12-19 01:26:34 +010095/* Rate behaviour normalization quantity over time. */
96#define RC_PID_NORM_OFFSET 3
97
98/* Push high rates right after loading. */
99#define RC_PID_FAST_START 0
100
101/* Arithmetic right shift for positive and negative values for ISO C. */
102#define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
103 (x) < 0 ? -((-(x)) >> (y)) : (x) >> (y)
104
Mattias Nisslerad018372007-12-19 01:25:57 +0100105struct rc_pid_sta_info {
106 unsigned long last_change;
107 unsigned long last_sample;
108
109 u32 tx_num_failed;
110 u32 tx_num_xmit;
111
112 /* Average failed frames percentage error (i.e. actual vs. target
113 * percentage), scaled by RC_PID_SMOOTHING. This value is computed
114 * using using an exponential weighted average technique:
115 *
116 * (RC_PID_SMOOTHING - 1) * err_avg_old + err
117 * err_avg = ------------------------------------------
118 * RC_PID_SMOOTHING
119 *
120 * where err_avg is the new approximation, err_avg_old the previous one
121 * and err is the error w.r.t. to the current failed frames percentage
122 * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
123 * given to the previous estimate, resulting in smoother behavior (i.e.
124 * corresponding to a longer integration window).
125 *
126 * For computation, we actually don't use the above formula, but this
127 * one:
128 *
129 * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
130 *
131 * where:
132 * err_avg_scaled = err * RC_PID_SMOOTHING
133 * err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
134 *
135 * This avoids floating point numbers and the per_failed_old value can
136 * easily be obtained by shifting per_failed_old_scaled right by
137 * RC_PID_SMOOTHING_SHIFT.
138 */
139 s32 err_avg_sc;
140
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +0100141 /* Last framed failes percentage sample. */
Mattias Nisslerad018372007-12-19 01:25:57 +0100142 u32 last_pf;
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +0100143
144 /* Sharpening needed. */
145 u8 sharp_cnt;
Mattias Nisslerad018372007-12-19 01:25:57 +0100146};
147
148/* Algorithm parameters. We keep them on a per-algorithm approach, so they can
149 * be tuned individually for each interface.
150 */
Stefano Brivio90d501d2007-12-19 01:26:34 +0100151struct rc_pid_rateinfo {
152
153 /* Map sorted rates to rates in ieee80211_hw_mode. */
154 int index;
155
156 /* Map rates in ieee80211_hw_mode to sorted rates. */
157 int rev_index;
158
159 /* Comparison with the lowest rate. */
160 int diff;
161};
162
Mattias Nisslerad018372007-12-19 01:25:57 +0100163struct rc_pid_info {
164
165 /* The failed frames percentage target. */
166 u32 target;
167
168 /* P, I and D coefficients. */
169 s32 coeff_p;
170 s32 coeff_i;
171 s32 coeff_d;
Stefano Brivio90d501d2007-12-19 01:26:34 +0100172
173 /* Rates information. */
174 struct rc_pid_rateinfo *rinfo;
175
176 /* Index of the last used rate. */
177 int oldrate;
Mattias Nisslerad018372007-12-19 01:25:57 +0100178};
179
Stefano Brivio90d501d2007-12-19 01:26:34 +0100180/* Shift the adjustment so that we won't switch to a lower rate if it exhibited
181 * a worse failed frames behaviour and we'll choose the highest rate whose
182 * failed frames behaviour is not worse than the one of the original rate
183 * target. While at it, check that the adjustment is within the ranges. Then,
184 * provide the new rate index. */
185static int rate_control_pid_shift_adjust(struct rc_pid_rateinfo *r,
186 int adj, int cur, int l)
187{
188 int i, j, k, tmp;
189
190 if (cur + adj < 0)
191 return 0;
192 if (cur + adj >= l)
193 return l - 1;
194
195 i = r[cur + adj].rev_index;
196
197 j = r[cur].rev_index;
198
199 if (adj < 0) {
200 tmp = i;
201 for (k = j; k >= i; k--)
202 if (r[k].diff <= r[j].diff)
203 tmp = k;
204 return r[tmp].index;
205 } else if (adj > 0) {
206 tmp = i;
207 for (k = i + 1; k + i < l; k++)
208 if (r[k].diff <= r[i].diff)
209 tmp = k;
210 return r[tmp].index;
211 }
212 return cur + adj;
213}
Mattias Nisslerad018372007-12-19 01:25:57 +0100214
215static void rate_control_pid_adjust_rate(struct ieee80211_local *local,
Stefano Brivio90d501d2007-12-19 01:26:34 +0100216 struct sta_info *sta, int adj,
217 struct rc_pid_rateinfo *rinfo)
Mattias Nisslerad018372007-12-19 01:25:57 +0100218{
219 struct ieee80211_sub_if_data *sdata;
220 struct ieee80211_hw_mode *mode;
Stefano Brivio90d501d2007-12-19 01:26:34 +0100221 int newidx;
Mattias Nisslerad018372007-12-19 01:25:57 +0100222 int maxrate;
223 int back = (adj > 0) ? 1 : -1;
224
225 sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
226 if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
227 /* forced unicast rate - do not change STA rate */
228 return;
229 }
230
231 mode = local->oper_hw_mode;
232 maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1;
233
Stefano Brivio90d501d2007-12-19 01:26:34 +0100234 newidx = rate_control_pid_shift_adjust(rinfo, adj, sta->txrate,
235 mode->num_rates);
Mattias Nisslerad018372007-12-19 01:25:57 +0100236
237 while (newidx != sta->txrate) {
238 if (rate_supported(sta, mode, newidx) &&
239 (maxrate < 0 || newidx <= maxrate)) {
240 sta->txrate = newidx;
241 break;
242 }
243
244 newidx += back;
245 }
246}
247
Stefano Brivio90d501d2007-12-19 01:26:34 +0100248/* Normalize the failed frames per-rate differences. */
249static void rate_control_pid_normalize(struct rc_pid_rateinfo *r, int l)
250{
251 int i;
252
253 if (r[0].diff > RC_PID_NORM_OFFSET)
254 r[0].diff -= RC_PID_NORM_OFFSET;
255 else if (r[0].diff < -RC_PID_NORM_OFFSET)
256 r[0].diff += RC_PID_NORM_OFFSET;
257 for (i = 0; i < l - 1; i++)
258 if (r[i + 1].diff > r[i].diff + RC_PID_NORM_OFFSET)
259 r[i + 1].diff -= RC_PID_NORM_OFFSET;
260 else if (r[i + 1].diff <= r[i].diff)
261 r[i + 1].diff += RC_PID_NORM_OFFSET;
262}
263
Mattias Nisslerad018372007-12-19 01:25:57 +0100264static void rate_control_pid_sample(struct rc_pid_info *pinfo,
265 struct ieee80211_local *local,
266 struct sta_info *sta)
267{
268 struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv;
Stefano Brivio90d501d2007-12-19 01:26:34 +0100269 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
270 struct ieee80211_hw_mode *mode;
Mattias Nisslerad018372007-12-19 01:25:57 +0100271 u32 pf;
272 s32 err_avg;
273 s32 err_prop;
274 s32 err_int;
275 s32 err_der;
Stefano Brivio90d501d2007-12-19 01:26:34 +0100276 int adj, i, j, tmp;
Mattias Nisslerad018372007-12-19 01:25:57 +0100277
Stefano Brivio90d501d2007-12-19 01:26:34 +0100278 mode = local->oper_hw_mode;
Mattias Nisslerad018372007-12-19 01:25:57 +0100279 spinfo = sta->rate_ctrl_priv;
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +0100280
281 /* In case nothing happened during the previous control interval, turn
282 * the sharpening factor on. */
283 if (jiffies - spinfo->last_sample > 2 * RC_PID_INTERVAL)
284 spinfo->sharp_cnt = RC_PID_SHARPENING_DURATION;
285
Mattias Nisslerad018372007-12-19 01:25:57 +0100286 spinfo->last_sample = jiffies;
287
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +0100288 /* This should never happen, but in case, we assume the old sample is
Mattias Nisslerad018372007-12-19 01:25:57 +0100289 * still a good measurement and copy it. */
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +0100290 if (unlikely(spinfo->tx_num_xmit == 0))
Mattias Nisslerad018372007-12-19 01:25:57 +0100291 pf = spinfo->last_pf;
292 else {
293 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
294 pf <<= RC_PID_ARITH_SHIFT;
Mattias Nisslerad018372007-12-19 01:25:57 +0100295 }
296
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +0100297 spinfo->tx_num_xmit = 0;
298 spinfo->tx_num_failed = 0;
299
Stefano Brivio90d501d2007-12-19 01:26:34 +0100300 /* If we just switched rate, update the rate behaviour info. */
301 if (pinfo->oldrate != sta->txrate) {
302
303 i = rinfo[pinfo->oldrate].rev_index;
304 j = rinfo[sta->txrate].rev_index;
305
306 tmp = (pf - spinfo->last_pf);
307 tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT);
308
309 rinfo[j].diff = rinfo[i].diff + tmp;
310 pinfo->oldrate = sta->txrate;
311 }
312 rate_control_pid_normalize(rinfo, mode->num_rates);
313
Mattias Nisslerad018372007-12-19 01:25:57 +0100314 /* Compute the proportional, integral and derivative errors. */
315 err_prop = RC_PID_TARGET_PF - pf;
316
317 err_avg = spinfo->err_avg_sc >> RC_PID_SMOOTHING_SHIFT;
318 spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop;
319 err_int = spinfo->err_avg_sc >> RC_PID_SMOOTHING_SHIFT;
320
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +0100321 err_der = pf - spinfo->last_pf
322 * (1 + RC_PID_SHARPENING_FACTOR * spinfo->sharp_cnt);
Mattias Nisslerad018372007-12-19 01:25:57 +0100323 spinfo->last_pf = pf;
Stefano Brivio1dc4d1e2007-12-19 01:26:52 +0100324 if (spinfo->sharp_cnt)
325 spinfo->sharp_cnt--;
Mattias Nisslerad018372007-12-19 01:25:57 +0100326
327 /* Compute the controller output. */
328 adj = (err_prop * pinfo->coeff_p + err_int * pinfo->coeff_i
329 + err_der * pinfo->coeff_d);
Stefano Brivio90d501d2007-12-19 01:26:34 +0100330 adj = RC_PID_DO_ARITH_RIGHT_SHIFT(adj, 2 * RC_PID_ARITH_SHIFT);
Mattias Nisslerad018372007-12-19 01:25:57 +0100331
332 /* Change rate. */
333 if (adj)
Stefano Brivio90d501d2007-12-19 01:26:34 +0100334 rate_control_pid_adjust_rate(local, sta, adj, rinfo);
Mattias Nisslerad018372007-12-19 01:25:57 +0100335}
336
337static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
338 struct sk_buff *skb,
339 struct ieee80211_tx_status *status)
340{
341 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
342 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
343 struct rc_pid_info *pinfo = priv;
344 struct sta_info *sta;
345 struct rc_pid_sta_info *spinfo;
346
347 sta = sta_info_get(local, hdr->addr1);
348
349 if (!sta)
350 return;
351
352 /* Ignore all frames that were sent with a different rate than the rate
353 * we currently advise mac80211 to use. */
354 if (status->control.rate != &local->oper_hw_mode->rates[sta->txrate])
355 return;
356
357 spinfo = sta->rate_ctrl_priv;
358 spinfo->tx_num_xmit++;
359
360 /* We count frames that totally failed to be transmitted as two bad
361 * frames, those that made it out but had some retries as one good and
362 * one bad frame. */
363 if (status->excessive_retries) {
364 spinfo->tx_num_failed += 2;
365 spinfo->tx_num_xmit++;
366 } else if (status->retry_count) {
367 spinfo->tx_num_failed++;
368 spinfo->tx_num_xmit++;
369 }
370
371 if (status->excessive_retries) {
372 sta->tx_retry_failed++;
373 sta->tx_num_consecutive_failures++;
374 sta->tx_num_mpdu_fail++;
375 } else {
376 sta->last_ack_rssi[0] = sta->last_ack_rssi[1];
377 sta->last_ack_rssi[1] = sta->last_ack_rssi[2];
378 sta->last_ack_rssi[2] = status->ack_signal;
379 sta->tx_num_consecutive_failures = 0;
380 sta->tx_num_mpdu_ok++;
381 }
382 sta->tx_retry_count += status->retry_count;
383 sta->tx_num_mpdu_fail += status->retry_count;
384
385 /* Update PID controller state. */
386 if (time_after(jiffies, spinfo->last_sample + RC_PID_INTERVAL))
387 rate_control_pid_sample(pinfo, local, sta);
388
389 sta_info_put(sta);
390}
391
392static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
393 struct ieee80211_hw_mode *mode,
394 struct sk_buff *skb,
395 struct rate_selection *sel)
396{
397 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
398 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
399 struct sta_info *sta;
400 int rateidx;
401
402 sta = sta_info_get(local, hdr->addr1);
403
404 if (!sta) {
405 sel->rate = rate_lowest(local, mode, NULL);
406 sta_info_put(sta);
407 return;
408 }
409
410 rateidx = sta->txrate;
411
412 if (rateidx >= mode->num_rates)
413 rateidx = mode->num_rates - 1;
414
415 sta_info_put(sta);
416
417 sel->rate = &mode->rates[rateidx];
418}
419
420static void rate_control_pid_rate_init(void *priv, void *priv_sta,
421 struct ieee80211_local *local,
422 struct sta_info *sta)
423{
424 /* TODO: This routine should consider using RSSI from previous packets
425 * as we need to have IEEE 802.1X auth succeed immediately after assoc..
426 * Until that method is implemented, we will use the lowest supported
427 * rate as a workaround. */
428 sta->txrate = rate_lowest_index(local, local->oper_hw_mode, sta);
429}
430
431static void *rate_control_pid_alloc(struct ieee80211_local *local)
432{
433 struct rc_pid_info *pinfo;
Stefano Brivio90d501d2007-12-19 01:26:34 +0100434 struct rc_pid_rateinfo *rinfo;
435 struct ieee80211_hw_mode *mode;
436 int i, j, tmp;
437 bool s;
Mattias Nisslerad018372007-12-19 01:25:57 +0100438
439 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
Stefano Brivio90d501d2007-12-19 01:26:34 +0100440 if (!pinfo)
441 return NULL;
442
443 /* We can safely assume that oper_hw_mode won't change unless we get
444 * reinitialized. */
445 mode = local->oper_hw_mode;
446 rinfo = kmalloc(sizeof(*rinfo) * mode->num_rates, GFP_ATOMIC);
447 if (!rinfo) {
448 kfree(pinfo);
449 return NULL;
450 }
451
452 /* Sort the rates. This is optimized for the most common case (i.e.
453 * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
454 * mapping too. */
455 for (i = 0; i < mode->num_rates; i++) {
456 rinfo[i].index = i;
457 rinfo[i].rev_index = i;
458 if (RC_PID_FAST_START)
459 rinfo[i].diff = 0;
460 else
461 rinfo[i].diff = i * RC_PID_NORM_OFFSET;
462 }
463 for (i = 1; i < mode->num_rates; i++) {
464 s = 0;
465 for (j = 0; j < mode->num_rates - i; j++)
466 if (unlikely(mode->rates[rinfo[j].index].rate >
467 mode->rates[rinfo[j + 1].index].rate)) {
468 tmp = rinfo[j].index;
469 rinfo[j].index = rinfo[j + 1].index;
470 rinfo[j + 1].index = tmp;
471 rinfo[rinfo[j].index].rev_index = j;
472 rinfo[rinfo[j + 1].index].rev_index = j + 1;
473 s = 1;
474 }
475 if (!s)
476 break;
477 }
Mattias Nisslerad018372007-12-19 01:25:57 +0100478
479 pinfo->target = RC_PID_TARGET_PF;
480 pinfo->coeff_p = RC_PID_COEFF_P;
481 pinfo->coeff_i = RC_PID_COEFF_I;
482 pinfo->coeff_d = RC_PID_COEFF_D;
Stefano Brivio90d501d2007-12-19 01:26:34 +0100483 pinfo->rinfo = rinfo;
484 pinfo->oldrate = 0;
Mattias Nisslerad018372007-12-19 01:25:57 +0100485
486 return pinfo;
487}
488
489static void rate_control_pid_free(void *priv)
490{
491 struct rc_pid_info *pinfo = priv;
Stefano Brivio90d501d2007-12-19 01:26:34 +0100492 kfree(pinfo->rinfo);
Mattias Nisslerad018372007-12-19 01:25:57 +0100493 kfree(pinfo);
494}
495
496static void rate_control_pid_clear(void *priv)
497{
498}
499
500static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
501{
502 struct rc_pid_sta_info *spinfo;
503
504 spinfo = kzalloc(sizeof(*spinfo), gfp);
505
506 return spinfo;
507}
508
509static void rate_control_pid_free_sta(void *priv, void *priv_sta)
510{
511 struct rc_pid_sta_info *spinfo = priv_sta;
512 kfree(spinfo);
513}
514
515struct rate_control_ops mac80211_rcpid = {
516 .name = "pid",
517 .tx_status = rate_control_pid_tx_status,
518 .get_rate = rate_control_pid_get_rate,
519 .rate_init = rate_control_pid_rate_init,
520 .clear = rate_control_pid_clear,
521 .alloc = rate_control_pid_alloc,
522 .free = rate_control_pid_free,
523 .alloc_sta = rate_control_pid_alloc_sta,
524 .free_sta = rate_control_pid_free_sta,
525};