Blame view
net/mac80211/rc80211_pid_algo.c
14.6 KB
ad0183759 mac80211: add PID... |
1 2 3 4 |
/* * Copyright 2002-2005, Instant802 Networks, Inc. * Copyright 2005, Devicescape Software, Inc. * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de> |
b7c50de92 rc80211-pid: fix ... |
5 |
* Copyright 2007-2008, Stefano Brivio <stefano.brivio@polimi.it> |
ad0183759 mac80211: add PID... |
6 7 8 9 10 11 12 13 14 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/netdevice.h> #include <linux/types.h> #include <linux/skbuff.h> |
4b475898e mac80211: better ... |
15 |
#include <linux/debugfs.h> |
5a0e3ad6a include cleanup: ... |
16 |
#include <linux/slab.h> |
ad0183759 mac80211: add PID... |
17 |
#include <net/mac80211.h> |
2c8dccc77 mac80211: rename ... |
18 |
#include "rate.h" |
ee3858551 mac80211: mesh da... |
19 |
#include "mesh.h" |
12446c67f rc80211-pid: add ... |
20 |
#include "rc80211_pid.h" |
ad0183759 mac80211: add PID... |
21 22 23 24 25 26 27 |
/* This is an implementation of a TX rate control algorithm that uses a PID * controller. Given a target failed frames rate, the controller decides about * TX rate changes to meet the target failed frames rate. * * The controller basically computes the following: * |
1dc4d1e6a rc80211-pid: add ... |
28 |
* adj = CP * err + CI * err_avg + CD * (err - last_err) * (1 + sharpening) |
ad0183759 mac80211: add PID... |
29 30 31 32 33 34 |
* * where * adj adjustment value that is used to switch TX rate (see below) * err current error: target vs. current failed frames percentage * last_err last error * err_avg average (i.e. poor man's integral) of recent errors |
1dc4d1e6a rc80211-pid: add ... |
35 36 37 |
* sharpening non-zero when fast response is needed (i.e. right after * association or no frames sent for a long time), heading * to zero over time |
ad0183759 mac80211: add PID... |
38 39 40 41 42 43 44 45 46 47 |
* CP Proportional coefficient * CI Integral coefficient * CD Derivative coefficient * * CP, CI, CD are subject to careful tuning. * * The integral component uses a exponential moving average approach instead of * an actual sliding window. The advantage is that we don't need to keep an * array of the last N error values and computation is easier. * |
90d501d61 rc80211-pid: add ... |
48 49 50 51 52 53 54 55 56 57 58 59 |
* Once we have the adj value, we map it to a rate by means of a learning * algorithm. This algorithm keeps the state of the percentual failed frames * difference between rates. The behaviour of the lowest available rate is kept * as a reference value, and every time we switch between two rates, we compute * the difference between the failed frames each rate exhibited. By doing so, * we compare behaviours which different rates exhibited in adjacent timeslices, * thus the comparison is minimally affected by external conditions. This * difference gets propagated to the whole set of measurements, so that the * reference is always the same. Periodically, we normalize this set so that * recent events weigh the most. By comparing the adj value with this set, we * avoid pejorative switches to lower rates and allow for switches to higher * rates if they behaved well. |
ad0183759 mac80211: add PID... |
60 61 62 63 64 |
* * Note that for the computations we use a fixed-point representation to avoid * floating point arithmetic. Hence, all values are shifted left by * RC_PID_ARITH_SHIFT. */ |
ad0183759 mac80211: add PID... |
65 |
|
b7c50de92 rc80211-pid: fix ... |
66 67 68 69 |
/* Adjust the rate while ensuring that we won't switch to a lower rate if it * exhibited a worse failed frames behaviour and we'll choose the highest rate * whose failed frames behaviour is not worse than the one of the original rate * target. While at it, check that the new rate is valid. */ |
4b7679a56 mac80211: clean u... |
70 71 72 |
static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, struct rc_pid_sta_info *spinfo, int adj, |
90d501d61 rc80211-pid: add ... |
73 |
struct rc_pid_rateinfo *rinfo) |
ad0183759 mac80211: add PID... |
74 |
{ |
b7c50de92 rc80211-pid: fix ... |
75 |
int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; |
ae17e9860 mac80211: move tx... |
76 |
int cur = spinfo->txrate_idx; |
ad0183759 mac80211: add PID... |
77 |
|
b7c50de92 rc80211-pid: fix ... |
78 79 |
band = sband->band; n_bitrates = sband->n_bitrates; |
ad0183759 mac80211: add PID... |
80 |
|
b7c50de92 rc80211-pid: fix ... |
81 82 83 |
/* Map passed arguments to sorted values. */ cur_sorted = rinfo[cur].rev_index; new_sorted = cur_sorted + adj; |
ad0183759 mac80211: add PID... |
84 |
|
b7c50de92 rc80211-pid: fix ... |
85 86 87 88 89 90 91 |
/* Check limits. */ if (new_sorted < 0) new_sorted = rinfo[0].rev_index; else if (new_sorted >= n_bitrates) new_sorted = rinfo[n_bitrates - 1].rev_index; tmp = new_sorted; |
ad0183759 mac80211: add PID... |
92 |
|
b7c50de92 rc80211-pid: fix ... |
93 94 95 96 97 98 99 100 101 102 103 104 |
if (adj < 0) { /* Ensure that the rate decrease isn't disadvantageous. */ for (probe = cur_sorted; probe >= new_sorted; probe--) if (rinfo[probe].diff <= rinfo[cur_sorted].diff && rate_supported(sta, band, rinfo[probe].index)) tmp = probe; } else { /* Look for rate increase with zero (or below) cost. */ for (probe = new_sorted + 1; probe < n_bitrates; probe++) if (rinfo[probe].diff <= rinfo[new_sorted].diff && rate_supported(sta, band, rinfo[probe].index)) tmp = probe; |
ad0183759 mac80211: add PID... |
105 |
} |
12446c67f rc80211-pid: add ... |
106 |
|
b7c50de92 rc80211-pid: fix ... |
107 108 109 |
/* Fit the rate found to the nearest supported rate. */ do { if (rate_supported(sta, band, rinfo[tmp].index)) { |
ae17e9860 mac80211: move tx... |
110 |
spinfo->txrate_idx = rinfo[tmp].index; |
b7c50de92 rc80211-pid: fix ... |
111 112 113 114 115 116 117 |
break; } if (adj < 0) tmp--; else tmp++; } while (tmp < n_bitrates && tmp >= 0); |
12446c67f rc80211-pid: add ... |
118 |
#ifdef CONFIG_MAC80211_DEBUGFS |
ae17e9860 mac80211: move tx... |
119 120 121 |
rate_control_pid_event_rate_change(&spinfo->events, spinfo->txrate_idx, sband->bitrates[spinfo->txrate_idx].bitrate); |
12446c67f rc80211-pid: add ... |
122 |
#endif |
ad0183759 mac80211: add PID... |
123 |
} |
90d501d61 rc80211-pid: add ... |
124 |
/* Normalize the failed frames per-rate differences. */ |
1946b74ce rc80211-pid: expo... |
125 |
static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l) |
90d501d61 rc80211-pid: add ... |
126 |
{ |
1946b74ce rc80211-pid: expo... |
127 128 |
int i, norm_offset = pinfo->norm_offset; struct rc_pid_rateinfo *r = pinfo->rinfo; |
90d501d61 rc80211-pid: add ... |
129 |
|
1946b74ce rc80211-pid: expo... |
130 131 132 133 |
if (r[0].diff > norm_offset) r[0].diff -= norm_offset; else if (r[0].diff < -norm_offset) r[0].diff += norm_offset; |
90d501d61 rc80211-pid: add ... |
134 |
for (i = 0; i < l - 1; i++) |
1946b74ce rc80211-pid: expo... |
135 136 |
if (r[i + 1].diff > r[i].diff + norm_offset) r[i + 1].diff -= norm_offset; |
90d501d61 rc80211-pid: add ... |
137 |
else if (r[i + 1].diff <= r[i].diff) |
1946b74ce rc80211-pid: expo... |
138 |
r[i + 1].diff += norm_offset; |
90d501d61 rc80211-pid: add ... |
139 |
} |
ad0183759 mac80211: add PID... |
140 |
static void rate_control_pid_sample(struct rc_pid_info *pinfo, |
4b7679a56 mac80211: clean u... |
141 142 143 |
struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, struct rc_pid_sta_info *spinfo) |
ad0183759 mac80211: add PID... |
144 |
{ |
90d501d61 rc80211-pid: add ... |
145 |
struct rc_pid_rateinfo *rinfo = pinfo->rinfo; |
ad0183759 mac80211: add PID... |
146 147 |
u32 pf; s32 err_avg; |
1946b74ce rc80211-pid: expo... |
148 149 150 |
u32 err_prop; u32 err_int; u32 err_der; |
90d501d61 rc80211-pid: add ... |
151 |
int adj, i, j, tmp; |
1946b74ce rc80211-pid: expo... |
152 |
unsigned long period; |
ad0183759 mac80211: add PID... |
153 |
|
1dc4d1e6a rc80211-pid: add ... |
154 155 |
/* In case nothing happened during the previous control interval, turn * the sharpening factor on. */ |
8e9310c17 mac80211: pid: re... |
156 |
period = msecs_to_jiffies(pinfo->sampling_period); |
1946b74ce rc80211-pid: expo... |
157 158 |
if (jiffies - spinfo->last_sample > 2 * period) spinfo->sharp_cnt = pinfo->sharpen_duration; |
1dc4d1e6a rc80211-pid: add ... |
159 |
|
ad0183759 mac80211: add PID... |
160 |
spinfo->last_sample = jiffies; |
1dc4d1e6a rc80211-pid: add ... |
161 |
/* This should never happen, but in case, we assume the old sample is |
ad0183759 mac80211: add PID... |
162 |
* still a good measurement and copy it. */ |
1dc4d1e6a rc80211-pid: add ... |
163 |
if (unlikely(spinfo->tx_num_xmit == 0)) |
ad0183759 mac80211: add PID... |
164 |
pf = spinfo->last_pf; |
bfc32e6a9 mac80211: Decoupl... |
165 |
else |
ad0183759 mac80211: add PID... |
166 |
pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; |
4b7679a56 mac80211: clean u... |
167 |
|
1dc4d1e6a rc80211-pid: add ... |
168 169 |
spinfo->tx_num_xmit = 0; spinfo->tx_num_failed = 0; |
90d501d61 rc80211-pid: add ... |
170 |
/* If we just switched rate, update the rate behaviour info. */ |
ae17e9860 mac80211: move tx... |
171 |
if (pinfo->oldrate != spinfo->txrate_idx) { |
90d501d61 rc80211-pid: add ... |
172 173 |
i = rinfo[pinfo->oldrate].rev_index; |
ae17e9860 mac80211: move tx... |
174 |
j = rinfo[spinfo->txrate_idx].rev_index; |
90d501d61 rc80211-pid: add ... |
175 176 177 178 179 |
tmp = (pf - spinfo->last_pf); tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); rinfo[j].diff = rinfo[i].diff + tmp; |
ae17e9860 mac80211: move tx... |
180 |
pinfo->oldrate = spinfo->txrate_idx; |
90d501d61 rc80211-pid: add ... |
181 |
} |
8318d78a4 cfg80211 API for ... |
182 |
rate_control_pid_normalize(pinfo, sband->n_bitrates); |
90d501d61 rc80211-pid: add ... |
183 |
|
ad0183759 mac80211: add PID... |
184 |
/* Compute the proportional, integral and derivative errors. */ |
e850f68b8 mac80211: fix sig... |
185 |
err_prop = (pinfo->target - pf) << RC_PID_ARITH_SHIFT; |
ad0183759 mac80211: add PID... |
186 |
|
1946b74ce rc80211-pid: expo... |
187 |
err_avg = spinfo->err_avg_sc >> pinfo->smoothing_shift; |
ad0183759 mac80211: add PID... |
188 |
spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop; |
1946b74ce rc80211-pid: expo... |
189 |
err_int = spinfo->err_avg_sc >> pinfo->smoothing_shift; |
ad0183759 mac80211: add PID... |
190 |
|
1946b74ce rc80211-pid: expo... |
191 192 |
err_der = (pf - spinfo->last_pf) * (1 + pinfo->sharpen_factor * spinfo->sharp_cnt); |
ad0183759 mac80211: add PID... |
193 |
spinfo->last_pf = pf; |
1dc4d1e6a rc80211-pid: add ... |
194 195 |
if (spinfo->sharp_cnt) spinfo->sharp_cnt--; |
ad0183759 mac80211: add PID... |
196 |
|
12446c67f rc80211-pid: add ... |
197 198 199 200 |
#ifdef CONFIG_MAC80211_DEBUGFS rate_control_pid_event_pf_sample(&spinfo->events, pf, err_prop, err_int, err_der); #endif |
ad0183759 mac80211: add PID... |
201 202 203 |
/* Compute the controller output. */ adj = (err_prop * pinfo->coeff_p + err_int * pinfo->coeff_i + err_der * pinfo->coeff_d); |
90d501d61 rc80211-pid: add ... |
204 |
adj = RC_PID_DO_ARITH_RIGHT_SHIFT(adj, 2 * RC_PID_ARITH_SHIFT); |
ad0183759 mac80211: add PID... |
205 206 207 |
/* Change rate. */ if (adj) |
4b7679a56 mac80211: clean u... |
208 |
rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo); |
ad0183759 mac80211: add PID... |
209 |
} |
4b7679a56 mac80211: clean u... |
210 211 |
static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, void *priv_sta, |
e039fa4a4 mac80211: move TX... |
212 |
struct sk_buff *skb) |
ad0183759 mac80211: add PID... |
213 |
{ |
ad0183759 mac80211: add PID... |
214 |
struct rc_pid_info *pinfo = priv; |
4b7679a56 mac80211: clean u... |
215 |
struct rc_pid_sta_info *spinfo = priv_sta; |
1946b74ce rc80211-pid: expo... |
216 |
unsigned long period; |
e039fa4a4 mac80211: move TX... |
217 |
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
ad0183759 mac80211: add PID... |
218 |
|
4b7679a56 mac80211: clean u... |
219 220 |
if (!spinfo) return; |
df26e7ea0 rc80211_pid shoul... |
221 |
|
ad0183759 mac80211: add PID... |
222 223 |
/* Ignore all frames that were sent with a different rate than the rate * we currently advise mac80211 to use. */ |
e6a9854b0 mac80211/drivers:... |
224 |
if (info->status.rates[0].idx != spinfo->txrate_idx) |
4b7679a56 mac80211: clean u... |
225 |
return; |
ad0183759 mac80211: add PID... |
226 |
|
ad0183759 mac80211: add PID... |
227 |
spinfo->tx_num_xmit++; |
12446c67f rc80211-pid: add ... |
228 |
#ifdef CONFIG_MAC80211_DEBUGFS |
e039fa4a4 mac80211: move TX... |
229 |
rate_control_pid_event_tx_status(&spinfo->events, info); |
12446c67f rc80211-pid: add ... |
230 |
#endif |
ad0183759 mac80211: add PID... |
231 232 233 |
/* We count frames that totally failed to be transmitted as two bad * frames, those that made it out but had some retries as one good and * one bad frame. */ |
e6a9854b0 mac80211/drivers:... |
234 |
if (!(info->flags & IEEE80211_TX_STAT_ACK)) { |
ad0183759 mac80211: add PID... |
235 236 |
spinfo->tx_num_failed += 2; spinfo->tx_num_xmit++; |
1dc5a8416 mac80211: Fix pid... |
237 |
} else if (info->status.rates[0].count > 1) { |
ad0183759 mac80211: add PID... |
238 239 240 |
spinfo->tx_num_failed++; spinfo->tx_num_xmit++; } |
ad0183759 mac80211: add PID... |
241 |
/* Update PID controller state. */ |
8e9310c17 mac80211: pid: re... |
242 |
period = msecs_to_jiffies(pinfo->sampling_period); |
1946b74ce rc80211-pid: expo... |
243 |
if (time_after(jiffies, spinfo->last_sample + period)) |
4b7679a56 mac80211: clean u... |
244 |
rate_control_pid_sample(pinfo, sband, sta, spinfo); |
ad0183759 mac80211: add PID... |
245 |
} |
4b7679a56 mac80211: clean u... |
246 |
static void |
e6a9854b0 mac80211/drivers:... |
247 248 249 |
rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_tx_rate_control *txrc) |
ad0183759 mac80211: add PID... |
250 |
{ |
e6a9854b0 mac80211/drivers:... |
251 252 |
struct sk_buff *skb = txrc->skb; struct ieee80211_supported_band *sband = txrc->sband; |
e6a9854b0 mac80211/drivers:... |
253 |
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
4b7679a56 mac80211: clean u... |
254 |
struct rc_pid_sta_info *spinfo = priv_sta; |
ad0183759 mac80211: add PID... |
255 |
int rateidx; |
e6a9854b0 mac80211/drivers:... |
256 257 258 259 260 261 |
if (txrc->rts) info->control.rates[0].count = txrc->hw->conf.long_frame_max_tx_count; else info->control.rates[0].count = txrc->hw->conf.short_frame_max_tx_count; |
922368414 mac80211: Fix han... |
262 |
/* Send management frames and NO_ACK data using lowest rate. */ |
4c6d4f5c3 mac80211: add hel... |
263 |
if (rate_control_send_low(sta, priv_sta, txrc)) |
ad0183759 mac80211: add PID... |
264 |
return; |
ad0183759 mac80211: add PID... |
265 |
|
ae17e9860 mac80211: move tx... |
266 |
rateidx = spinfo->txrate_idx; |
ad0183759 mac80211: add PID... |
267 |
|
8318d78a4 cfg80211 API for ... |
268 269 |
if (rateidx >= sband->n_bitrates) rateidx = sband->n_bitrates - 1; |
ad0183759 mac80211: add PID... |
270 |
|
e6a9854b0 mac80211/drivers:... |
271 |
info->control.rates[0].idx = rateidx; |
12446c67f rc80211-pid: add ... |
272 273 |
#ifdef CONFIG_MAC80211_DEBUGFS |
4b7679a56 mac80211: clean u... |
274 |
rate_control_pid_event_tx_rate(&spinfo->events, |
8318d78a4 cfg80211 API for ... |
275 |
rateidx, sband->bitrates[rateidx].bitrate); |
12446c67f rc80211-pid: add ... |
276 |
#endif |
ad0183759 mac80211: add PID... |
277 |
} |
4b7679a56 mac80211: clean u... |
278 279 280 |
static void rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, void *priv_sta) |
ad0183759 mac80211: add PID... |
281 |
{ |
4b7679a56 mac80211: clean u... |
282 |
struct rc_pid_sta_info *spinfo = priv_sta; |
6909268dc mac80211: pid, fi... |
283 284 |
struct rc_pid_info *pinfo = priv; struct rc_pid_rateinfo *rinfo = pinfo->rinfo; |
6909268dc mac80211: pid, fi... |
285 286 |
int i, j, tmp; bool s; |
4b7679a56 mac80211: clean u... |
287 |
|
ad0183759 mac80211: add PID... |
288 289 290 291 |
/* TODO: This routine should consider using RSSI from previous packets * as we need to have IEEE 802.1X auth succeed immediately after assoc.. * Until that method is implemented, we will use the lowest supported * rate as a workaround. */ |
8318d78a4 cfg80211 API for ... |
292 |
|
6909268dc mac80211: pid, fi... |
293 294 295 296 297 298 299 300 301 302 303 304 |
/* Sort the rates. This is optimized for the most common case (i.e. * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed * mapping too. */ for (i = 0; i < sband->n_bitrates; i++) { rinfo[i].index = i; rinfo[i].rev_index = i; if (RC_PID_FAST_START) rinfo[i].diff = 0; else rinfo[i].diff = i * pinfo->norm_offset; } for (i = 1; i < sband->n_bitrates; i++) { |
3db1cd5c0 net: fix assignme... |
305 |
s = false; |
6909268dc mac80211: pid, fi... |
306 307 308 309 310 311 312 313 |
for (j = 0; j < sband->n_bitrates - i; j++) if (unlikely(sband->bitrates[rinfo[j].index].bitrate > sband->bitrates[rinfo[j + 1].index].bitrate)) { tmp = rinfo[j].index; rinfo[j].index = rinfo[j + 1].index; rinfo[j + 1].index = tmp; rinfo[rinfo[j].index].rev_index = j; rinfo[rinfo[j + 1].index].rev_index = j + 1; |
3db1cd5c0 net: fix assignme... |
314 |
s = true; |
6909268dc mac80211: pid, fi... |
315 316 317 318 |
} if (!s) break; } |
4b7679a56 mac80211: clean u... |
319 |
spinfo->txrate_idx = rate_lowest_index(sband, sta); |
ad0183759 mac80211: add PID... |
320 |
} |
4b7679a56 mac80211: clean u... |
321 322 |
static void *rate_control_pid_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) |
ad0183759 mac80211: add PID... |
323 324 |
{ struct rc_pid_info *pinfo; |
90d501d61 rc80211-pid: add ... |
325 |
struct rc_pid_rateinfo *rinfo; |
8318d78a4 cfg80211 API for ... |
326 |
struct ieee80211_supported_band *sband; |
6909268dc mac80211: pid, fi... |
327 |
int i, max_rates = 0; |
1946b74ce rc80211-pid: expo... |
328 329 330 |
#ifdef CONFIG_MAC80211_DEBUGFS struct rc_pid_debugfs_entries *de; #endif |
ad0183759 mac80211: add PID... |
331 332 |
pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); |
90d501d61 rc80211-pid: add ... |
333 334 |
if (!pinfo) return NULL; |
6909268dc mac80211: pid, fi... |
335 336 |
for (i = 0; i < IEEE80211_NUM_BANDS; i++) { sband = hw->wiphy->bands[i]; |
621ad7c96 mac80211: avoid N... |
337 |
if (sband && sband->n_bitrates > max_rates) |
6909268dc mac80211: pid, fi... |
338 339 340 341 |
max_rates = sband->n_bitrates; } rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC); |
90d501d61 rc80211-pid: add ... |
342 343 344 345 |
if (!rinfo) { kfree(pinfo); return NULL; } |
adeed4809 rc80211_pid: Fix ... |
346 347 348 349 350 351 352 353 354 355 356 |
pinfo->target = RC_PID_TARGET_PF; pinfo->sampling_period = RC_PID_INTERVAL; pinfo->coeff_p = RC_PID_COEFF_P; pinfo->coeff_i = RC_PID_COEFF_I; pinfo->coeff_d = RC_PID_COEFF_D; pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT; pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR; pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION; pinfo->norm_offset = RC_PID_NORM_OFFSET; pinfo->rinfo = rinfo; pinfo->oldrate = 0; |
1946b74ce rc80211-pid: expo... |
357 358 |
#ifdef CONFIG_MAC80211_DEBUGFS de = &pinfo->dentries; |
1946b74ce rc80211-pid: expo... |
359 |
de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, |
4b7679a56 mac80211: clean u... |
360 |
debugfsdir, &pinfo->target); |
1946b74ce rc80211-pid: expo... |
361 |
de->sampling_period = debugfs_create_u32("sampling_period", |
4b7679a56 mac80211: clean u... |
362 |
S_IRUSR | S_IWUSR, debugfsdir, |
1946b74ce rc80211-pid: expo... |
363 364 |
&pinfo->sampling_period); de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, |
9902b1843 mac80211: rc80211... |
365 |
debugfsdir, (u32 *)&pinfo->coeff_p); |
1946b74ce rc80211-pid: expo... |
366 |
de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, |
9902b1843 mac80211: rc80211... |
367 |
debugfsdir, (u32 *)&pinfo->coeff_i); |
1946b74ce rc80211-pid: expo... |
368 |
de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, |
9902b1843 mac80211: rc80211... |
369 |
debugfsdir, (u32 *)&pinfo->coeff_d); |
1946b74ce rc80211-pid: expo... |
370 |
de->smoothing_shift = debugfs_create_u32("smoothing_shift", |
4b7679a56 mac80211: clean u... |
371 |
S_IRUSR | S_IWUSR, debugfsdir, |
1946b74ce rc80211-pid: expo... |
372 373 |
&pinfo->smoothing_shift); de->sharpen_factor = debugfs_create_u32("sharpen_factor", |
4b7679a56 mac80211: clean u... |
374 |
S_IRUSR | S_IWUSR, debugfsdir, |
1946b74ce rc80211-pid: expo... |
375 376 |
&pinfo->sharpen_factor); de->sharpen_duration = debugfs_create_u32("sharpen_duration", |
4b7679a56 mac80211: clean u... |
377 |
S_IRUSR | S_IWUSR, debugfsdir, |
1946b74ce rc80211-pid: expo... |
378 379 |
&pinfo->sharpen_duration); de->norm_offset = debugfs_create_u32("norm_offset", |
4b7679a56 mac80211: clean u... |
380 |
S_IRUSR | S_IWUSR, debugfsdir, |
1946b74ce rc80211-pid: expo... |
381 |
&pinfo->norm_offset); |
1946b74ce rc80211-pid: expo... |
382 |
#endif |
ad0183759 mac80211: add PID... |
383 384 385 386 387 388 |
return pinfo; } static void rate_control_pid_free(void *priv) { struct rc_pid_info *pinfo = priv; |
1946b74ce rc80211-pid: expo... |
389 390 |
#ifdef CONFIG_MAC80211_DEBUGFS struct rc_pid_debugfs_entries *de = &pinfo->dentries; |
1946b74ce rc80211-pid: expo... |
391 392 393 394 395 396 397 398 399 |
debugfs_remove(de->norm_offset); debugfs_remove(de->sharpen_duration); debugfs_remove(de->sharpen_factor); debugfs_remove(de->smoothing_shift); debugfs_remove(de->coeff_d); debugfs_remove(de->coeff_i); debugfs_remove(de->coeff_p); debugfs_remove(de->sampling_period); debugfs_remove(de->target); |
1946b74ce rc80211-pid: expo... |
400 |
#endif |
90d501d61 rc80211-pid: add ... |
401 |
kfree(pinfo->rinfo); |
ad0183759 mac80211: add PID... |
402 403 |
kfree(pinfo); } |
4b7679a56 mac80211: clean u... |
404 405 |
static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) |
ad0183759 mac80211: add PID... |
406 407 408 409 |
{ struct rc_pid_sta_info *spinfo; spinfo = kzalloc(sizeof(*spinfo), gfp); |
12446c67f rc80211-pid: add ... |
410 411 |
if (spinfo == NULL) return NULL; |
c09c7237e rc80211-pid: fix ... |
412 |
spinfo->last_sample = jiffies; |
12446c67f rc80211-pid: add ... |
413 414 415 416 |
#ifdef CONFIG_MAC80211_DEBUGFS spin_lock_init(&spinfo->events.lock); init_waitqueue_head(&spinfo->events.waitqueue); #endif |
ad0183759 mac80211: add PID... |
417 418 419 |
return spinfo; } |
4b7679a56 mac80211: clean u... |
420 421 |
static void rate_control_pid_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) |
ad0183759 mac80211: add PID... |
422 |
{ |
4b7679a56 mac80211: clean u... |
423 |
kfree(priv_sta); |
ad0183759 mac80211: add PID... |
424 |
} |
4b475898e mac80211: better ... |
425 |
static struct rate_control_ops mac80211_rcpid = { |
ad0183759 mac80211: add PID... |
426 427 428 429 |
.name = "pid", .tx_status = rate_control_pid_tx_status, .get_rate = rate_control_pid_get_rate, .rate_init = rate_control_pid_rate_init, |
ad0183759 mac80211: add PID... |
430 431 432 433 |
.alloc = rate_control_pid_alloc, .free = rate_control_pid_free, .alloc_sta = rate_control_pid_alloc_sta, .free_sta = rate_control_pid_free_sta, |
12446c67f rc80211-pid: add ... |
434 435 436 437 |
#ifdef CONFIG_MAC80211_DEBUGFS .add_sta_debugfs = rate_control_pid_add_sta_debugfs, .remove_sta_debugfs = rate_control_pid_remove_sta_debugfs, #endif |
ad0183759 mac80211: add PID... |
438 |
}; |
4b475898e mac80211: better ... |
439 |
|
4b475898e mac80211: better ... |
440 441 442 443 |
int __init rc80211_pid_init(void) { return ieee80211_rate_control_register(&mac80211_rcpid); } |
f0b9205cf mac80211 rate con... |
444 |
void rc80211_pid_exit(void) |
4b475898e mac80211: better ... |
445 446 447 |
{ ieee80211_rate_control_unregister(&mac80211_rcpid); } |