aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_pid_algo.c
diff options
context:
space:
mode:
authorMattias Nissler <mattias.nissler@gmx.de>2007-12-20 07:27:26 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:44 -0500
commit1946b74ce03c4edecabde80d027da00a7eab56ca (patch)
tree1adfba8e2a582c278acbf4c5440ac67d714c0954 /net/mac80211/rc80211_pid_algo.c
parent12446c67fea1e5bc74c58e43ef53eea308cdda61 (diff)
rc80211-pid: export tuning parameters through debugfs
This adds all the tunable parameters used by rc80211_pid to debugfs for easy testing and tuning. Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de> Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
-rw-r--r--net/mac80211/rc80211_pid_algo.c112
1 files changed, 89 insertions, 23 deletions
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. */
142static void rate_control_pid_normalize(struct rc_pid_rateinfo *r, int l) 142static 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
157static void rate_control_pid_sample(struct rc_pid_info *pinfo, 158static 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
397static void rate_control_pid_free(void *priv) 447static 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}