rc80211_pid.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
00003  * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  */
00009 
00010 #ifndef RC80211_PID_H
00011 #define RC80211_PID_H
00012 
00013 /* Sampling period for measuring percentage of failed frames in ms. */
00014 #define RC_PID_INTERVAL                 125
00015 
00016 /* Exponential averaging smoothness (used for I part of PID controller) */
00017 #define RC_PID_SMOOTHING_SHIFT          3
00018 #define RC_PID_SMOOTHING                (1 << RC_PID_SMOOTHING_SHIFT)
00019 
00020 /* Sharpening factor (used for D part of PID controller) */
00021 #define RC_PID_SHARPENING_FACTOR        0
00022 #define RC_PID_SHARPENING_DURATION      0
00023 
00024 /* Fixed point arithmetic shifting amount. */
00025 #define RC_PID_ARITH_SHIFT              8
00026 
00027 /* Proportional PID component coefficient. */
00028 #define RC_PID_COEFF_P                  15
00029 /* Integral PID component coefficient. */
00030 #define RC_PID_COEFF_I                  9
00031 /* Derivative PID component coefficient. */
00032 #define RC_PID_COEFF_D                  15
00033 
00034 /* Target failed frames rate for the PID controller. NB: This effectively gives
00035  * maximum failed frames percentage we're willing to accept. If the wireless
00036  * link quality is good, the controller will fail to adjust failed frames
00037  * percentage to the target. This is intentional.
00038  */
00039 #define RC_PID_TARGET_PF                14
00040 
00041 /* Rate behaviour normalization quantity over time. */
00042 #define RC_PID_NORM_OFFSET              3
00043 
00044 /* Push high rates right after loading. */
00045 #define RC_PID_FAST_START               0
00046 
00047 /* Arithmetic right shift for positive and negative values for ISO C. */
00048 #define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
00049         ((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
00050 
00051 enum rc_pid_event_type {
00052         RC_PID_EVENT_TYPE_TX_STATUS,
00053         RC_PID_EVENT_TYPE_RATE_CHANGE,
00054         RC_PID_EVENT_TYPE_TX_RATE,
00055         RC_PID_EVENT_TYPE_PF_SAMPLE,
00056 };
00057 
00058 union rc_pid_event_data {
00059         /* RC_PID_EVENT_TX_STATUS */
00060         struct {
00061                 u32 flags;
00062                 struct ieee80211_tx_info tx_status;
00063         };
00064         /* RC_PID_EVENT_TYPE_RATE_CHANGE */
00065         /* RC_PID_EVENT_TYPE_TX_RATE */
00066         struct {
00067                 int index;
00068                 int rate;
00069         };
00070         /* RC_PID_EVENT_TYPE_PF_SAMPLE */
00071         struct {
00072                 s32 pf_sample;
00073                 s32 prop_err;
00074                 s32 int_err;
00075                 s32 der_err;
00076         };
00077 };
00078 
00079 struct rc_pid_event {
00080         /* The time when the event occurred */
00081         unsigned long timestamp;
00082 
00083         /* Event ID number */
00084         unsigned int id;
00085 
00086         /* Type of event */
00087         enum rc_pid_event_type type;
00088 
00089         /* type specific data */
00090         union rc_pid_event_data data;
00091 };
00092 
00093 /* Size of the event ring buffer. */
00094 #define RC_PID_EVENT_RING_SIZE 32
00095 
00096 struct rc_pid_event_buffer {
00097         /* Counter that generates event IDs */
00098         unsigned int ev_count;
00099 
00100         /* Ring buffer of events */
00101         struct rc_pid_event ring[RC_PID_EVENT_RING_SIZE];
00102 
00103         /* Index to the entry in events_buf to be reused */
00104         unsigned int next_entry;
00105 
00106         /* Lock that guards against concurrent access to this buffer struct */
00107         spinlock_t lock;
00108 
00109         /* Wait queue for poll/select and blocking I/O */
00110         wait_queue_head_t waitqueue;
00111 };
00112 
00113 struct rc_pid_events_file_info {
00114         /* The event buffer we read */
00115         struct rc_pid_event_buffer *events;
00116 
00117         /* The entry we have should read next */
00118         unsigned int next_entry;
00119 };
00120 
00142 struct rc_pid_debugfs_entries {
00143         struct dentry *target;
00144         struct dentry *sampling_period;
00145         struct dentry *coeff_p;
00146         struct dentry *coeff_i;
00147         struct dentry *coeff_d;
00148         struct dentry *smoothing_shift;
00149         struct dentry *sharpen_factor;
00150         struct dentry *sharpen_duration;
00151         struct dentry *norm_offset;
00152 };
00153 
00154 void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
00155                                       struct ieee80211_tx_info *stat);
00156 
00157 void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
00158                                                int index, int rate);
00159 
00160 void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
00161                                            int index, int rate);
00162 
00163 void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
00164                                              s32 pf_sample, s32 prop_err,
00165                                              s32 int_err, s32 der_err);
00166 
00167 void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
00168                                              struct dentry *dir);
00169 
00170 void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
00171 
00172 struct rc_pid_sta_info {
00173         unsigned long last_change;
00174         unsigned long last_sample;
00175 
00176         u32 tx_num_failed;
00177         u32 tx_num_xmit;
00178 
00179         int txrate_idx;
00180 
00181         /* Average failed frames percentage error (i.e. actual vs. target
00182          * percentage), scaled by RC_PID_SMOOTHING. This value is computed
00183          * using using an exponential weighted average technique:
00184          *
00185          *           (RC_PID_SMOOTHING - 1) * err_avg_old + err
00186          * err_avg = ------------------------------------------
00187          *                       RC_PID_SMOOTHING
00188          *
00189          * where err_avg is the new approximation, err_avg_old the previous one
00190          * and err is the error w.r.t. to the current failed frames percentage
00191          * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
00192          * given to the previous estimate, resulting in smoother behavior (i.e.
00193          * corresponding to a longer integration window).
00194          *
00195          * For computation, we actually don't use the above formula, but this
00196          * one:
00197          *
00198          * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
00199          *
00200          * where:
00201          *      err_avg_scaled = err * RC_PID_SMOOTHING
00202          *      err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
00203          *
00204          * This avoids floating point numbers and the per_failed_old value can
00205          * easily be obtained by shifting per_failed_old_scaled right by
00206          * RC_PID_SMOOTHING_SHIFT.
00207          */
00208         s32 err_avg_sc;
00209 
00210         /* Last framed failes percentage sample. */
00211         u32 last_pf;
00212 
00213         /* Sharpening needed. */
00214         u8 sharp_cnt;
00215 
00216 #ifdef CONFIG_MAC80211_DEBUGFS
00217         /* Event buffer */
00218         struct rc_pid_event_buffer events;
00219 
00220         /* Events debugfs file entry */
00221         struct dentry *events_entry;
00222 #endif
00223 };
00224 
00225 /* Algorithm parameters. We keep them on a per-algorithm approach, so they can
00226  * be tuned individually for each interface.
00227  */
00228 struct rc_pid_rateinfo {
00229 
00230         /* Map sorted rates to rates in ieee80211_hw_mode. */
00231         int index;
00232 
00233         /* Map rates in ieee80211_hw_mode to sorted rates. */
00234         int rev_index;
00235 
00236         /* Did we do any measurement on this rate? */
00237         bool valid;
00238 
00239         /* Comparison with the lowest rate. */
00240         int diff;
00241 };
00242 
00243 struct rc_pid_info {
00244 
00245         /* The failed frames percentage target. */
00246         unsigned int target;
00247 
00248         /* Rate at which failed frames percentage is sampled in 0.001s. */
00249         unsigned int sampling_period;
00250 
00251         /* P, I and D coefficients. */
00252         int coeff_p;
00253         int coeff_i;
00254         int coeff_d;
00255 
00256         /* Exponential averaging shift. */
00257         unsigned int smoothing_shift;
00258 
00259         /* Sharpening factor and duration. */
00260         unsigned int sharpen_factor;
00261         unsigned int sharpen_duration;
00262 
00263         /* Normalization offset. */
00264         unsigned int norm_offset;
00265 
00266         /* Rates information. */
00267         struct rc_pid_rateinfo *rinfo;
00268 
00269         /* Index of the last used rate. */
00270         int oldrate;
00271 
00272 #ifdef CONFIG_MAC80211_DEBUGFS
00273         /* Debugfs entries created for the parameters above. */
00274         struct rc_pid_debugfs_entries dentries;
00275 #endif
00276 };
00277 
00278 #endif /* RC80211_PID_H */


ros_rt_wmp
Author(s): Danilo Tardioli, dantard@unizar.es
autogenerated on Fri Jan 3 2014 12:07:55