diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/rc80211_pid.h | 23 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 112 |
2 files changed, 110 insertions, 25 deletions
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index 5d0056c1513b..425eb708182a 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h | |||
@@ -119,6 +119,20 @@ struct rc_pid_events_file_info { | |||
119 | unsigned int next_entry; | 119 | unsigned int next_entry; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | struct rc_pid_debugfs_entries { | ||
123 | struct dentry *dir; | ||
124 | struct dentry *target; | ||
125 | struct dentry *sampling_period; | ||
126 | struct dentry *coeff_p; | ||
127 | struct dentry *coeff_i; | ||
128 | struct dentry *coeff_d; | ||
129 | struct dentry *smoothing_shift; | ||
130 | struct dentry *sharpen_factor; | ||
131 | struct dentry *sharpen_duration; | ||
132 | struct dentry *norm_offset; | ||
133 | struct dentry *fast_start; | ||
134 | }; | ||
135 | |||
122 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | 136 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, |
123 | struct ieee80211_tx_status *stat); | 137 | struct ieee80211_tx_status *stat); |
124 | 138 | ||
@@ -222,8 +236,8 @@ struct rc_pid_info { | |||
222 | /* Exponential averaging shift. */ | 236 | /* Exponential averaging shift. */ |
223 | unsigned int smoothing_shift; | 237 | unsigned int smoothing_shift; |
224 | 238 | ||
225 | /* Sharpening shift and duration. */ | 239 | /* Sharpening factor and duration. */ |
226 | unsigned int sharpen_shift; | 240 | unsigned int sharpen_factor; |
227 | unsigned int sharpen_duration; | 241 | unsigned int sharpen_duration; |
228 | 242 | ||
229 | /* Normalization offset. */ | 243 | /* Normalization offset. */ |
@@ -237,6 +251,11 @@ struct rc_pid_info { | |||
237 | 251 | ||
238 | /* Index of the last used rate. */ | 252 | /* Index of the last used rate. */ |
239 | int oldrate; | 253 | int oldrate; |
254 | |||
255 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
256 | /* Debugfs entries created for the parameters above. */ | ||
257 | struct rc_pid_debugfs_entries dentries; | ||
258 | #endif | ||
240 | }; | 259 | }; |
241 | 260 | ||
242 | #endif /* RC80211_PID_H */ | 261 | #endif /* RC80211_PID_H */ |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index 3fac3a5d7e00..631e46888267 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -139,19 +139,20 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | |||
139 | } | 139 | } |
140 | 140 | ||
141 | /* Normalize the failed frames per-rate differences. */ | 141 | /* Normalize the failed frames per-rate differences. */ |
142 | static void rate_control_pid_normalize(struct rc_pid_rateinfo *r, int l) | 142 | static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l) |
143 | { | 143 | { |
144 | int i; | 144 | int i, norm_offset = pinfo->norm_offset; |
145 | struct rc_pid_rateinfo *r = pinfo->rinfo; | ||
145 | 146 | ||
146 | if (r[0].diff > RC_PID_NORM_OFFSET) | 147 | if (r[0].diff > norm_offset) |
147 | r[0].diff -= RC_PID_NORM_OFFSET; | 148 | r[0].diff -= norm_offset; |
148 | else if (r[0].diff < -RC_PID_NORM_OFFSET) | 149 | else if (r[0].diff < -norm_offset) |
149 | r[0].diff += RC_PID_NORM_OFFSET; | 150 | r[0].diff += norm_offset; |
150 | for (i = 0; i < l - 1; i++) | 151 | for (i = 0; i < l - 1; i++) |
151 | if (r[i + 1].diff > r[i].diff + RC_PID_NORM_OFFSET) | 152 | if (r[i + 1].diff > r[i].diff + norm_offset) |
152 | r[i + 1].diff -= RC_PID_NORM_OFFSET; | 153 | r[i + 1].diff -= norm_offset; |
153 | else if (r[i + 1].diff <= r[i].diff) | 154 | else if (r[i + 1].diff <= r[i].diff) |
154 | r[i + 1].diff += RC_PID_NORM_OFFSET; | 155 | r[i + 1].diff += norm_offset; |
155 | } | 156 | } |
156 | 157 | ||
157 | static void rate_control_pid_sample(struct rc_pid_info *pinfo, | 158 | static void rate_control_pid_sample(struct rc_pid_info *pinfo, |
@@ -163,18 +164,22 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
163 | struct ieee80211_hw_mode *mode; | 164 | struct ieee80211_hw_mode *mode; |
164 | u32 pf; | 165 | u32 pf; |
165 | s32 err_avg; | 166 | s32 err_avg; |
166 | s32 err_prop; | 167 | u32 err_prop; |
167 | s32 err_int; | 168 | u32 err_int; |
168 | s32 err_der; | 169 | u32 err_der; |
169 | int adj, i, j, tmp; | 170 | int adj, i, j, tmp; |
171 | unsigned long period; | ||
170 | 172 | ||
171 | mode = local->oper_hw_mode; | 173 | mode = local->oper_hw_mode; |
172 | spinfo = sta->rate_ctrl_priv; | 174 | spinfo = sta->rate_ctrl_priv; |
173 | 175 | ||
174 | /* In case nothing happened during the previous control interval, turn | 176 | /* In case nothing happened during the previous control interval, turn |
175 | * the sharpening factor on. */ | 177 | * the sharpening factor on. */ |
176 | if (jiffies - spinfo->last_sample > 2 * RC_PID_INTERVAL) | 178 | period = (HZ * pinfo->sampling_period + 500) / 1000; |
177 | spinfo->sharp_cnt = RC_PID_SHARPENING_DURATION; | 179 | if (!period) |
180 | period = 1; | ||
181 | if (jiffies - spinfo->last_sample > 2 * period) | ||
182 | spinfo->sharp_cnt = pinfo->sharpen_duration; | ||
178 | 183 | ||
179 | spinfo->last_sample = jiffies; | 184 | spinfo->last_sample = jiffies; |
180 | 185 | ||
@@ -202,17 +207,17 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
202 | rinfo[j].diff = rinfo[i].diff + tmp; | 207 | rinfo[j].diff = rinfo[i].diff + tmp; |
203 | pinfo->oldrate = sta->txrate; | 208 | pinfo->oldrate = sta->txrate; |
204 | } | 209 | } |
205 | rate_control_pid_normalize(rinfo, mode->num_rates); | 210 | rate_control_pid_normalize(pinfo, mode->num_rates); |
206 | 211 | ||
207 | /* Compute the proportional, integral and derivative errors. */ | 212 | /* Compute the proportional, integral and derivative errors. */ |
208 | err_prop = RC_PID_TARGET_PF - pf; | 213 | err_prop = pinfo->target - pf; |
209 | 214 | ||
210 | err_avg = spinfo->err_avg_sc >> RC_PID_SMOOTHING_SHIFT; | 215 | err_avg = spinfo->err_avg_sc >> pinfo->smoothing_shift; |
211 | spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop; | 216 | spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop; |
212 | err_int = spinfo->err_avg_sc >> RC_PID_SMOOTHING_SHIFT; | 217 | err_int = spinfo->err_avg_sc >> pinfo->smoothing_shift; |
213 | 218 | ||
214 | err_der = pf - spinfo->last_pf | 219 | err_der = (pf - spinfo->last_pf) * |
215 | * (1 + RC_PID_SHARPENING_FACTOR * spinfo->sharp_cnt); | 220 | (1 + pinfo->sharpen_factor * spinfo->sharp_cnt); |
216 | spinfo->last_pf = pf; | 221 | spinfo->last_pf = pf; |
217 | if (spinfo->sharp_cnt) | 222 | if (spinfo->sharp_cnt) |
218 | spinfo->sharp_cnt--; | 223 | spinfo->sharp_cnt--; |
@@ -241,6 +246,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
241 | struct rc_pid_info *pinfo = priv; | 246 | struct rc_pid_info *pinfo = priv; |
242 | struct sta_info *sta; | 247 | struct sta_info *sta; |
243 | struct rc_pid_sta_info *spinfo; | 248 | struct rc_pid_sta_info *spinfo; |
249 | unsigned long period; | ||
244 | 250 | ||
245 | sta = sta_info_get(local, hdr->addr1); | 251 | sta = sta_info_get(local, hdr->addr1); |
246 | 252 | ||
@@ -285,7 +291,10 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
285 | sta->tx_num_mpdu_fail += status->retry_count; | 291 | sta->tx_num_mpdu_fail += status->retry_count; |
286 | 292 | ||
287 | /* Update PID controller state. */ | 293 | /* Update PID controller state. */ |
288 | if (time_after(jiffies, spinfo->last_sample + RC_PID_INTERVAL)) | 294 | period = (HZ * pinfo->sampling_period + 500) / 1000; |
295 | if (!period) | ||
296 | period = 1; | ||
297 | if (time_after(jiffies, spinfo->last_sample + period)) | ||
289 | rate_control_pid_sample(pinfo, local, sta); | 298 | rate_control_pid_sample(pinfo, local, sta); |
290 | 299 | ||
291 | sta_info_put(sta); | 300 | sta_info_put(sta); |
@@ -343,6 +352,9 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
343 | struct ieee80211_hw_mode *mode; | 352 | struct ieee80211_hw_mode *mode; |
344 | int i, j, tmp; | 353 | int i, j, tmp; |
345 | bool s; | 354 | bool s; |
355 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
356 | struct rc_pid_debugfs_entries *de; | ||
357 | #endif | ||
346 | 358 | ||
347 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); | 359 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); |
348 | if (!pinfo) | 360 | if (!pinfo) |
@@ -363,10 +375,10 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
363 | for (i = 0; i < mode->num_rates; i++) { | 375 | for (i = 0; i < mode->num_rates; i++) { |
364 | rinfo[i].index = i; | 376 | rinfo[i].index = i; |
365 | rinfo[i].rev_index = i; | 377 | rinfo[i].rev_index = i; |
366 | if (RC_PID_FAST_START) | 378 | if (pinfo->fast_start) |
367 | rinfo[i].diff = 0; | 379 | rinfo[i].diff = 0; |
368 | else | 380 | else |
369 | rinfo[i].diff = i * RC_PID_NORM_OFFSET; | 381 | rinfo[i].diff = i * pinfo->norm_offset; |
370 | } | 382 | } |
371 | for (i = 1; i < mode->num_rates; i++) { | 383 | for (i = 1; i < mode->num_rates; i++) { |
372 | s = 0; | 384 | s = 0; |
@@ -385,18 +397,72 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
385 | } | 397 | } |
386 | 398 | ||
387 | pinfo->target = RC_PID_TARGET_PF; | 399 | pinfo->target = RC_PID_TARGET_PF; |
400 | pinfo->sampling_period = RC_PID_INTERVAL; | ||
388 | pinfo->coeff_p = RC_PID_COEFF_P; | 401 | pinfo->coeff_p = RC_PID_COEFF_P; |
389 | pinfo->coeff_i = RC_PID_COEFF_I; | 402 | pinfo->coeff_i = RC_PID_COEFF_I; |
390 | pinfo->coeff_d = RC_PID_COEFF_D; | 403 | pinfo->coeff_d = RC_PID_COEFF_D; |
404 | pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT; | ||
405 | pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR; | ||
406 | pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION; | ||
407 | pinfo->norm_offset = RC_PID_NORM_OFFSET; | ||
408 | pinfo->fast_start = RC_PID_FAST_START; | ||
391 | pinfo->rinfo = rinfo; | 409 | pinfo->rinfo = rinfo; |
392 | pinfo->oldrate = 0; | 410 | pinfo->oldrate = 0; |
393 | 411 | ||
412 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
413 | de = &pinfo->dentries; | ||
414 | de->dir = debugfs_create_dir("rc80211_pid", | ||
415 | local->hw.wiphy->debugfsdir); | ||
416 | de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, | ||
417 | de->dir, &pinfo->target); | ||
418 | de->sampling_period = debugfs_create_u32("sampling_period", | ||
419 | S_IRUSR | S_IWUSR, de->dir, | ||
420 | &pinfo->sampling_period); | ||
421 | de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, | ||
422 | de->dir, &pinfo->coeff_p); | ||
423 | de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, | ||
424 | de->dir, &pinfo->coeff_i); | ||
425 | de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, | ||
426 | de->dir, &pinfo->coeff_d); | ||
427 | de->smoothing_shift = debugfs_create_u32("smoothing_shift", | ||
428 | S_IRUSR | S_IWUSR, de->dir, | ||
429 | &pinfo->smoothing_shift); | ||
430 | de->sharpen_factor = debugfs_create_u32("sharpen_factor", | ||
431 | S_IRUSR | S_IWUSR, de->dir, | ||
432 | &pinfo->sharpen_factor); | ||
433 | de->sharpen_duration = debugfs_create_u32("sharpen_duration", | ||
434 | S_IRUSR | S_IWUSR, de->dir, | ||
435 | &pinfo->sharpen_duration); | ||
436 | de->norm_offset = debugfs_create_u32("norm_offset", | ||
437 | S_IRUSR | S_IWUSR, de->dir, | ||
438 | &pinfo->norm_offset); | ||
439 | de->fast_start = debugfs_create_bool("fast_start", | ||
440 | S_IRUSR | S_IWUSR, de->dir, | ||
441 | &pinfo->fast_start); | ||
442 | #endif | ||
443 | |||
394 | return pinfo; | 444 | return pinfo; |
395 | } | 445 | } |
396 | 446 | ||
397 | static void rate_control_pid_free(void *priv) | 447 | static void rate_control_pid_free(void *priv) |
398 | { | 448 | { |
399 | struct rc_pid_info *pinfo = priv; | 449 | struct rc_pid_info *pinfo = priv; |
450 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
451 | struct rc_pid_debugfs_entries *de = &pinfo->dentries; | ||
452 | |||
453 | debugfs_remove(de->fast_start); | ||
454 | debugfs_remove(de->norm_offset); | ||
455 | debugfs_remove(de->sharpen_duration); | ||
456 | debugfs_remove(de->sharpen_factor); | ||
457 | debugfs_remove(de->smoothing_shift); | ||
458 | debugfs_remove(de->coeff_d); | ||
459 | debugfs_remove(de->coeff_i); | ||
460 | debugfs_remove(de->coeff_p); | ||
461 | debugfs_remove(de->sampling_period); | ||
462 | debugfs_remove(de->target); | ||
463 | debugfs_remove(de->dir); | ||
464 | #endif | ||
465 | |||
400 | kfree(pinfo->rinfo); | 466 | kfree(pinfo->rinfo); |
401 | kfree(pinfo); | 467 | kfree(pinfo); |
402 | } | 468 | } |