00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <linux/netdevice.h>
00013 #include <linux/types.h>
00014 #include <linux/skbuff.h>
00015 #include <linux/debugfs.h>
00016 #include <linux/slab.h>
00017 #include <net/mac80211.h>
00018 #include "rate.h"
00019 #include "mesh.h"
00020 #include "rc80211_pid.h"
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband,
00073 struct ieee80211_sta *sta,
00074 struct rc_pid_sta_info *spinfo, int adj,
00075 struct rc_pid_rateinfo *rinfo)
00076 {
00077 int cur_sorted, new_sorted, probe, tmp, n_bitrates, band;
00078 int cur = spinfo->txrate_idx;
00079
00080 band = sband->band;
00081 n_bitrates = sband->n_bitrates;
00082
00083
00084 cur_sorted = rinfo[cur].rev_index;
00085 new_sorted = cur_sorted + adj;
00086
00087
00088 if (new_sorted < 0)
00089 new_sorted = rinfo[0].rev_index;
00090 else if (new_sorted >= n_bitrates)
00091 new_sorted = rinfo[n_bitrates - 1].rev_index;
00092
00093 tmp = new_sorted;
00094
00095 if (adj < 0) {
00096
00097 for (probe = cur_sorted; probe >= new_sorted; probe--)
00098 if (rinfo[probe].diff <= rinfo[cur_sorted].diff &&
00099 rate_supported(sta, band, rinfo[probe].index))
00100 tmp = probe;
00101 } else {
00102
00103 for (probe = new_sorted + 1; probe < n_bitrates; probe++)
00104 if (rinfo[probe].diff <= rinfo[new_sorted].diff &&
00105 rate_supported(sta, band, rinfo[probe].index))
00106 tmp = probe;
00107 }
00108
00109
00110 do {
00111 if (rate_supported(sta, band, rinfo[tmp].index)) {
00112 spinfo->txrate_idx = rinfo[tmp].index;
00113 break;
00114 }
00115 if (adj < 0)
00116 tmp--;
00117 else
00118 tmp++;
00119 } while (tmp < n_bitrates && tmp >= 0);
00120
00121 #ifdef CONFIG_MAC80211_DEBUGFS
00122 rate_control_pid_event_rate_change(&spinfo->events,
00123 spinfo->txrate_idx,
00124 sband->bitrates[spinfo->txrate_idx].bitrate);
00125 #endif
00126 }
00127
00128
00129 static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
00130 {
00131 int i, norm_offset = pinfo->norm_offset;
00132 struct rc_pid_rateinfo *r = pinfo->rinfo;
00133
00134 if (r[0].diff > norm_offset)
00135 r[0].diff -= norm_offset;
00136 else if (r[0].diff < -norm_offset)
00137 r[0].diff += norm_offset;
00138 for (i = 0; i < l - 1; i++)
00139 if (r[i + 1].diff > r[i].diff + norm_offset)
00140 r[i + 1].diff -= norm_offset;
00141 else if (r[i + 1].diff <= r[i].diff)
00142 r[i + 1].diff += norm_offset;
00143 }
00144
00145 static void rate_control_pid_sample(struct rc_pid_info *pinfo,
00146 struct ieee80211_supported_band *sband,
00147 struct ieee80211_sta *sta,
00148 struct rc_pid_sta_info *spinfo)
00149 {
00150 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
00151 u32 pf;
00152 s32 err_avg;
00153 u32 err_prop;
00154 u32 err_int;
00155 u32 err_der;
00156 int adj, i, j, tmp;
00157 unsigned long period;
00158
00159
00160
00161 period = msecs_to_jiffies(pinfo->sampling_period);
00162 if (jiffies - spinfo->last_sample > 2 * period)
00163 spinfo->sharp_cnt = pinfo->sharpen_duration;
00164
00165 spinfo->last_sample = jiffies;
00166
00167
00168
00169 if (unlikely(spinfo->tx_num_xmit == 0))
00170 pf = spinfo->last_pf;
00171 else
00172 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
00173
00174 spinfo->tx_num_xmit = 0;
00175 spinfo->tx_num_failed = 0;
00176
00177
00178 if (pinfo->oldrate != spinfo->txrate_idx) {
00179
00180 i = rinfo[pinfo->oldrate].rev_index;
00181 j = rinfo[spinfo->txrate_idx].rev_index;
00182
00183 tmp = (pf - spinfo->last_pf);
00184 tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT);
00185
00186 rinfo[j].diff = rinfo[i].diff + tmp;
00187 pinfo->oldrate = spinfo->txrate_idx;
00188 }
00189 rate_control_pid_normalize(pinfo, sband->n_bitrates);
00190
00191
00192 err_prop = (pinfo->target - pf) << RC_PID_ARITH_SHIFT;
00193
00194 err_avg = spinfo->err_avg_sc >> pinfo->smoothing_shift;
00195 spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop;
00196 err_int = spinfo->err_avg_sc >> pinfo->smoothing_shift;
00197
00198 err_der = (pf - spinfo->last_pf) *
00199 (1 + pinfo->sharpen_factor * spinfo->sharp_cnt);
00200 spinfo->last_pf = pf;
00201 if (spinfo->sharp_cnt)
00202 spinfo->sharp_cnt--;
00203
00204 #ifdef CONFIG_MAC80211_DEBUGFS
00205 rate_control_pid_event_pf_sample(&spinfo->events, pf, err_prop, err_int,
00206 err_der);
00207 #endif
00208
00209
00210 adj = (err_prop * pinfo->coeff_p + err_int * pinfo->coeff_i
00211 + err_der * pinfo->coeff_d);
00212 adj = RC_PID_DO_ARITH_RIGHT_SHIFT(adj, 2 * RC_PID_ARITH_SHIFT);
00213
00214
00215 if (adj)
00216 rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo);
00217 }
00218
00219 static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband,
00220 struct ieee80211_sta *sta, void *priv_sta,
00221 struct sk_buff *skb)
00222 {
00223 struct rc_pid_info *pinfo = priv;
00224 struct rc_pid_sta_info *spinfo = priv_sta;
00225 unsigned long period;
00226 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
00227
00228 if (!spinfo)
00229 return;
00230
00231
00232
00233 if (info->status.rates[0].idx != spinfo->txrate_idx)
00234 return;
00235
00236 spinfo->tx_num_xmit++;
00237
00238 #ifdef CONFIG_MAC80211_DEBUGFS
00239 rate_control_pid_event_tx_status(&spinfo->events, info);
00240 #endif
00241
00242
00243
00244
00245 if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
00246 spinfo->tx_num_failed += 2;
00247 spinfo->tx_num_xmit++;
00248 } else if (info->status.rates[0].count > 1) {
00249 spinfo->tx_num_failed++;
00250 spinfo->tx_num_xmit++;
00251 }
00252
00253
00254 period = msecs_to_jiffies(pinfo->sampling_period);
00255 if (time_after(jiffies, spinfo->last_sample + period))
00256 rate_control_pid_sample(pinfo, sband, sta, spinfo);
00257 }
00258
00259 static void
00260 rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
00261 void *priv_sta,
00262 struct ieee80211_tx_rate_control *txrc)
00263 {
00264 struct sk_buff *skb = txrc->skb;
00265 struct ieee80211_supported_band *sband = txrc->sband;
00266 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
00267 struct rc_pid_sta_info *spinfo = priv_sta;
00268 int rateidx;
00269
00270 if (txrc->rts)
00271 info->control.rates[0].count =
00272 txrc->hw->conf.long_frame_max_tx_count;
00273 else
00274 info->control.rates[0].count =
00275 txrc->hw->conf.short_frame_max_tx_count;
00276
00277
00278 if (rate_control_send_low(sta, priv_sta, txrc))
00279 return;
00280
00281 rateidx = spinfo->txrate_idx;
00282
00283 if (rateidx >= sband->n_bitrates)
00284 rateidx = sband->n_bitrates - 1;
00285
00286 info->control.rates[0].idx = rateidx;
00287
00288 #ifdef CONFIG_MAC80211_DEBUGFS
00289 rate_control_pid_event_tx_rate(&spinfo->events,
00290 rateidx, sband->bitrates[rateidx].bitrate);
00291 #endif
00292 }
00293
00294 static void
00295 rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
00296 struct ieee80211_sta *sta, void *priv_sta)
00297 {
00298 struct rc_pid_sta_info *spinfo = priv_sta;
00299 struct rc_pid_info *pinfo = priv;
00300 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
00301 int i, j, tmp;
00302 bool s;
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 for (i = 0; i < sband->n_bitrates; i++) {
00313 rinfo[i].index = i;
00314 rinfo[i].rev_index = i;
00315 if (RC_PID_FAST_START)
00316 rinfo[i].diff = 0;
00317 else
00318 rinfo[i].diff = i * pinfo->norm_offset;
00319 }
00320 for (i = 1; i < sband->n_bitrates; i++) {
00321 s = false;
00322 for (j = 0; j < sband->n_bitrates - i; j++)
00323 if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
00324 sband->bitrates[rinfo[j + 1].index].bitrate)) {
00325 tmp = rinfo[j].index;
00326 rinfo[j].index = rinfo[j + 1].index;
00327 rinfo[j + 1].index = tmp;
00328 rinfo[rinfo[j].index].rev_index = j;
00329 rinfo[rinfo[j + 1].index].rev_index = j + 1;
00330 s = true;
00331 }
00332 if (!s)
00333 break;
00334 }
00335
00336 spinfo->txrate_idx = rate_lowest_index(sband, sta);
00337 }
00338
00339 static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
00340 struct dentry *debugfsdir)
00341 {
00342 struct rc_pid_info *pinfo;
00343 struct rc_pid_rateinfo *rinfo;
00344 struct ieee80211_supported_band *sband;
00345 int i, max_rates = 0;
00346 #ifdef CONFIG_MAC80211_DEBUGFS
00347 struct rc_pid_debugfs_entries *de;
00348 #endif
00349
00350 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
00351 if (!pinfo)
00352 return NULL;
00353
00354 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
00355 sband = hw->wiphy->bands[i];
00356 if (sband && sband->n_bitrates > max_rates)
00357 max_rates = sband->n_bitrates;
00358 }
00359
00360 rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC);
00361 if (!rinfo) {
00362 kfree(pinfo);
00363 return NULL;
00364 }
00365
00366 pinfo->target = RC_PID_TARGET_PF;
00367 pinfo->sampling_period = RC_PID_INTERVAL;
00368 pinfo->coeff_p = RC_PID_COEFF_P;
00369 pinfo->coeff_i = RC_PID_COEFF_I;
00370 pinfo->coeff_d = RC_PID_COEFF_D;
00371 pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
00372 pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
00373 pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
00374 pinfo->norm_offset = RC_PID_NORM_OFFSET;
00375 pinfo->rinfo = rinfo;
00376 pinfo->oldrate = 0;
00377
00378 #ifdef CONFIG_MAC80211_DEBUGFS
00379 de = &pinfo->dentries;
00380 de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
00381 debugfsdir, &pinfo->target);
00382 de->sampling_period = debugfs_create_u32("sampling_period",
00383 S_IRUSR | S_IWUSR, debugfsdir,
00384 &pinfo->sampling_period);
00385 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
00386 debugfsdir, (u32 *)&pinfo->coeff_p);
00387 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
00388 debugfsdir, (u32 *)&pinfo->coeff_i);
00389 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
00390 debugfsdir, (u32 *)&pinfo->coeff_d);
00391 de->smoothing_shift = debugfs_create_u32("smoothing_shift",
00392 S_IRUSR | S_IWUSR, debugfsdir,
00393 &pinfo->smoothing_shift);
00394 de->sharpen_factor = debugfs_create_u32("sharpen_factor",
00395 S_IRUSR | S_IWUSR, debugfsdir,
00396 &pinfo->sharpen_factor);
00397 de->sharpen_duration = debugfs_create_u32("sharpen_duration",
00398 S_IRUSR | S_IWUSR, debugfsdir,
00399 &pinfo->sharpen_duration);
00400 de->norm_offset = debugfs_create_u32("norm_offset",
00401 S_IRUSR | S_IWUSR, debugfsdir,
00402 &pinfo->norm_offset);
00403 #endif
00404
00405 return pinfo;
00406 }
00407
00408 static void rate_control_pid_free(void *priv)
00409 {
00410 struct rc_pid_info *pinfo = priv;
00411 #ifdef CONFIG_MAC80211_DEBUGFS
00412 struct rc_pid_debugfs_entries *de = &pinfo->dentries;
00413
00414 debugfs_remove(de->norm_offset);
00415 debugfs_remove(de->sharpen_duration);
00416 debugfs_remove(de->sharpen_factor);
00417 debugfs_remove(de->smoothing_shift);
00418 debugfs_remove(de->coeff_d);
00419 debugfs_remove(de->coeff_i);
00420 debugfs_remove(de->coeff_p);
00421 debugfs_remove(de->sampling_period);
00422 debugfs_remove(de->target);
00423 #endif
00424
00425 kfree(pinfo->rinfo);
00426 kfree(pinfo);
00427 }
00428
00429 static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta,
00430 gfp_t gfp)
00431 {
00432 struct rc_pid_sta_info *spinfo;
00433
00434 spinfo = kzalloc(sizeof(*spinfo), gfp);
00435 if (spinfo == NULL)
00436 return NULL;
00437
00438 spinfo->last_sample = jiffies;
00439
00440 #ifdef CONFIG_MAC80211_DEBUGFS
00441 spin_lock_init(&spinfo->events.lock);
00442 init_waitqueue_head(&spinfo->events.waitqueue);
00443 #endif
00444
00445 return spinfo;
00446 }
00447
00448 static void rate_control_pid_free_sta(void *priv, struct ieee80211_sta *sta,
00449 void *priv_sta)
00450 {
00451 kfree(priv_sta);
00452 }
00453
00454 static struct rate_control_ops mac80211_rcpid = {
00455 .name = "pid",
00456 .tx_status = rate_control_pid_tx_status,
00457 .get_rate = rate_control_pid_get_rate,
00458 .rate_init = rate_control_pid_rate_init,
00459 .alloc = rate_control_pid_alloc,
00460 .free = rate_control_pid_free,
00461 .alloc_sta = rate_control_pid_alloc_sta,
00462 .free_sta = rate_control_pid_free_sta,
00463 #ifdef CONFIG_MAC80211_DEBUGFS
00464 .add_sta_debugfs = rate_control_pid_add_sta_debugfs,
00465 .remove_sta_debugfs = rate_control_pid_remove_sta_debugfs,
00466 #endif
00467 };
00468
00469 int __init rc80211_pid_init(void)
00470 {
00471 return ieee80211_rate_control_register(&mac80211_rcpid);
00472 }
00473
00474 void rc80211_pid_exit(void)
00475 {
00476 ieee80211_rate_control_unregister(&mac80211_rcpid);
00477 }