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 */ 279