linux/net/mac80211/rc80211_pid.h
<<
>>
Prefs
   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/* Fixed point arithmetic factor. */
  28#define RC_PID_ARITH_FACTOR             (1 << RC_PID_ARITH_SHIFT)
  29
  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
  36
  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.
  41 */
  42#define RC_PID_TARGET_PF                14
  43
  44/* Rate behaviour normalization quantity over time. */
  45#define RC_PID_NORM_OFFSET              3
  46
  47/* Push high rates right after loading. */
  48#define RC_PID_FAST_START               0
  49
  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))
  53
  54enum 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,
  59};
  60
  61union rc_pid_event_data {
  62        /* RC_PID_EVENT_TX_STATUS */
  63        struct {
  64                u32 flags;
  65                struct ieee80211_tx_info tx_status;
  66        };
  67        /* RC_PID_EVENT_TYPE_RATE_CHANGE */
  68        /* RC_PID_EVENT_TYPE_TX_RATE */
  69        struct {
  70                int index;
  71                int rate;
  72        };
  73        /* RC_PID_EVENT_TYPE_PF_SAMPLE */
  74        struct {
  75                s32 pf_sample;
  76                s32 prop_err;
  77                s32 int_err;
  78                s32 der_err;
  79        };
  80};
  81
  82struct rc_pid_event {
  83        /* The time when the event occured */
  84        unsigned long timestamp;
  85
  86        /* Event ID number */
  87        unsigned int id;
  88
  89        /* Type of event */
  90        enum rc_pid_event_type type;
  91
  92        /* type specific data */
  93        union rc_pid_event_data data;
  94};
  95
  96/* Size of the event ring buffer. */
  97#define RC_PID_EVENT_RING_SIZE 32
  98
  99struct rc_pid_event_buffer {
 100        /* Counter that generates event IDs */
 101        unsigned int ev_count;
 102
 103        /* Ring buffer of events */
 104        struct rc_pid_event ring[RC_PID_EVENT_RING_SIZE];
 105
 106        /* Index to the entry in events_buf to be reused */
 107        unsigned int next_entry;
 108
 109        /* Lock that guards against concurrent access to this buffer struct */
 110        spinlock_t lock;
 111
 112        /* Wait queue for poll/select and blocking I/O */
 113        wait_queue_head_t waitqueue;
 114};
 115
 116struct rc_pid_events_file_info {
 117        /* The event buffer we read */
 118        struct rc_pid_event_buffer *events;
 119
 120        /* The entry we have should read next */
 121        unsigned int next_entry;
 122};
 123
 124/**
 125 * struct rc_pid_debugfs_entries - tunable parameters
 126 *
 127 * Algorithm parameters, tunable via debugfs.
 128 * @target: target percentage for failed frames
 129 * @sampling_period: error sampling interval in milliseconds
 130 * @coeff_p: absolute value of the proportional coefficient
 131 * @coeff_i: absolute value of the integral coefficient
 132 * @coeff_d: absolute value of the derivative coefficient
 133 * @smoothing_shift: absolute value of the integral smoothing factor (i.e.
 134 *      amount of smoothing introduced by the exponential moving average)
 135 * @sharpen_factor: absolute value of the derivative sharpening factor (i.e.
 136 *      amount of emphasis given to the derivative term after low activity
 137 *      events)
 138 * @sharpen_duration: duration of the sharpening effect after the detected low
 139 *      activity event, relative to sampling_period
 140 * @norm_offset: amount of normalization periodically performed on the learnt
 141 *      rate behaviour values (lower means we should trust more what we learnt
 142 *      about behaviour of rates, higher means we should trust more the natural
 143 *      ordering of rates)
 144 */
 145struct rc_pid_debugfs_entries {
 146        struct dentry *target;
 147        struct dentry *sampling_period;
 148        struct dentry *coeff_p;
 149        struct dentry *coeff_i;
 150        struct dentry *coeff_d;
 151        struct dentry *smoothing_shift;
 152        struct dentry *sharpen_factor;
 153        struct dentry *sharpen_duration;
 154        struct dentry *norm_offset;
 155};
 156
 157void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
 158                                      struct ieee80211_tx_info *stat);
 159
 160void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
 161                                               int index, int rate);
 162
 163void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
 164                                           int index, int rate);
 165
 166void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
 167                                             s32 pf_sample, s32 prop_err,
 168                                             s32 int_err, s32 der_err);
 169
 170void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
 171                                             struct dentry *dir);
 172
 173void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
 174
 175struct rc_pid_sta_info {
 176        unsigned long last_change;
 177        unsigned long last_sample;
 178
 179        u32 tx_num_failed;
 180        u32 tx_num_xmit;
 181
 182        int txrate_idx;
 183
 184        /* Average failed frames percentage error (i.e. actual vs. target
 185         * percentage), scaled by RC_PID_SMOOTHING. This value is computed
 186         * using using an exponential weighted average technique:
 187         *
 188         *           (RC_PID_SMOOTHING - 1) * err_avg_old + err
 189         * err_avg = ------------------------------------------
 190         *                       RC_PID_SMOOTHING
 191         *
 192         * where err_avg is the new approximation, err_avg_old the previous one
 193         * and err is the error w.r.t. to the current failed frames percentage
 194         * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
 195         * given to the previous estimate, resulting in smoother behavior (i.e.
 196         * corresponding to a longer integration window).
 197         *
 198         * For computation, we actually don't use the above formula, but this
 199         * one:
 200         *
 201         * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
 202         *
 203         * where:
 204         *      err_avg_scaled = err * RC_PID_SMOOTHING
 205         *      err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
 206         *
 207         * This avoids floating point numbers and the per_failed_old value can
 208         * easily be obtained by shifting per_failed_old_scaled right by
 209         * RC_PID_SMOOTHING_SHIFT.
 210         */
 211        s32 err_avg_sc;
 212
 213        /* Last framed failes percentage sample. */
 214        u32 last_pf;
 215
 216        /* Sharpening needed. */
 217        u8 sharp_cnt;
 218
 219#ifdef CONFIG_MAC80211_DEBUGFS
 220        /* Event buffer */
 221        struct rc_pid_event_buffer events;
 222
 223        /* Events debugfs file entry */
 224        struct dentry *events_entry;
 225#endif
 226};
 227
 228/* Algorithm parameters. We keep them on a per-algorithm approach, so they can
 229 * be tuned individually for each interface.
 230 */
 231struct rc_pid_rateinfo {
 232
 233        /* Map sorted rates to rates in ieee80211_hw_mode. */
 234        int index;
 235
 236        /* Map rates in ieee80211_hw_mode to sorted rates. */
 237        int rev_index;
 238
 239        /* Did we do any measurement on this rate? */
 240        bool valid;
 241
 242        /* Comparison with the lowest rate. */
 243        int diff;
 244};
 245
 246struct rc_pid_info {
 247
 248        /* The failed frames percentage target. */
 249        unsigned int target;
 250
 251        /* Rate at which failed frames percentage is sampled in 0.001s. */
 252        unsigned int sampling_period;
 253
 254        /* P, I and D coefficients. */
 255        int coeff_p;
 256        int coeff_i;
 257        int coeff_d;
 258
 259        /* Exponential averaging shift. */
 260        unsigned int smoothing_shift;
 261
 262        /* Sharpening factor and duration. */
 263        unsigned int sharpen_factor;
 264        unsigned int sharpen_duration;
 265
 266        /* Normalization offset. */
 267        unsigned int norm_offset;
 268
 269        /* Rates information. */
 270        struct rc_pid_rateinfo *rinfo;
 271
 272        /* Index of the last used rate. */
 273        int oldrate;
 274
 275#ifdef CONFIG_MAC80211_DEBUGFS
 276        /* Debugfs entries created for the parameters above. */
 277        struct rc_pid_debugfs_entries dentries;
 278#endif
 279};
 280
 281#endif /* RC80211_PID_H */
 282
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.