aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_pid_algo.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-18 12:14:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-24 16:18:03 -0400
commit4b7679a561e552eeda1e3567119bef2bca99b66e (patch)
treeb5f2b45c9186eb954f9329322d07e277e669b422 /net/mac80211/rc80211_pid_algo.c
parent2ff6a6d4e92270283432690adf53a7e5ab186d19 (diff)
mac80211: clean up rate control API
Long awaited, hard work. This patch totally cleans up the rate control API to remove the requirement to include internal headers outside of net/mac80211/. There's one internal use in the PID algorithm left for mesh networking, we'll have to figure out a way to clean that one up and decide how to do the peer link evaluation, possibly independent of the rate control algorithm or via new API. Additionally, ath9k is left using the cross-inclusion hack for now, we will add new API where necessary to make this work properly, but right now I'm not expert enough to do it. It's still off better than before. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
-rw-r--r--net/mac80211/rc80211_pid_algo.c158
1 files changed, 59 insertions, 99 deletions
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index bc1c4569caa1..86eb374e3b87 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -68,18 +68,14 @@
68 * exhibited a worse failed frames behaviour and we'll choose the highest rate 68 * exhibited a worse failed frames behaviour and we'll choose the highest rate
69 * whose failed frames behaviour is not worse than the one of the original rate 69 * whose failed frames behaviour is not worse than the one of the original rate
70 * target. While at it, check that the new rate is valid. */ 70 * target. While at it, check that the new rate is valid. */
71static void rate_control_pid_adjust_rate(struct ieee80211_local *local, 71static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband,
72 struct sta_info *sta, int adj, 72 struct ieee80211_sta *sta,
73 struct rc_pid_sta_info *spinfo, int adj,
73 struct rc_pid_rateinfo *rinfo) 74 struct rc_pid_rateinfo *rinfo)
74{ 75{
75 struct ieee80211_sub_if_data *sdata;
76 struct ieee80211_supported_band *sband;
77 int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; 76 int cur_sorted, new_sorted, probe, tmp, n_bitrates, band;
78 struct rc_pid_sta_info *spinfo = (void *)sta->rate_ctrl_priv;
79 int cur = spinfo->txrate_idx; 77 int cur = spinfo->txrate_idx;
80 78
81 sdata = sta->sdata;
82 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
83 band = sband->band; 79 band = sband->band;
84 n_bitrates = sband->n_bitrates; 80 n_bitrates = sband->n_bitrates;
85 81
@@ -146,13 +142,11 @@ static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
146} 142}
147 143
148static void rate_control_pid_sample(struct rc_pid_info *pinfo, 144static void rate_control_pid_sample(struct rc_pid_info *pinfo,
149 struct ieee80211_local *local, 145 struct ieee80211_supported_band *sband,
150 struct sta_info *sta) 146 struct ieee80211_sta *sta,
147 struct rc_pid_sta_info *spinfo)
151{ 148{
152 struct ieee80211_sub_if_data *sdata = sta->sdata;
153 struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv;
154 struct rc_pid_rateinfo *rinfo = pinfo->rinfo; 149 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
155 struct ieee80211_supported_band *sband;
156 u32 pf; 150 u32 pf;
157 s32 err_avg; 151 s32 err_avg;
158 u32 err_prop; 152 u32 err_prop;
@@ -161,9 +155,6 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
161 int adj, i, j, tmp; 155 int adj, i, j, tmp;
162 unsigned long period; 156 unsigned long period;
163 157
164 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
165 spinfo = sta->rate_ctrl_priv;
166
167 /* In case nothing happened during the previous control interval, turn 158 /* In case nothing happened during the previous control interval, turn
168 * the sharpening factor on. */ 159 * the sharpening factor on. */
169 period = (HZ * pinfo->sampling_period + 500) / 1000; 160 period = (HZ * pinfo->sampling_period + 500) / 1000;
@@ -179,11 +170,15 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
179 if (unlikely(spinfo->tx_num_xmit == 0)) 170 if (unlikely(spinfo->tx_num_xmit == 0))
180 pf = spinfo->last_pf; 171 pf = spinfo->last_pf;
181 else { 172 else {
173 /* XXX: BAD HACK!!! */
174 struct sta_info *si = container_of(sta, struct sta_info, sta);
175
182 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; 176 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
183 if (ieee80211_vif_is_mesh(&sdata->vif) && pf == 100) 177
184 mesh_plink_broken(sta); 178 if (ieee80211_vif_is_mesh(&si->sdata->vif) && pf == 100)
179 mesh_plink_broken(si);
185 pf <<= RC_PID_ARITH_SHIFT; 180 pf <<= RC_PID_ARITH_SHIFT;
186 sta->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9) 181 si->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
187 >> RC_PID_ARITH_SHIFT; 182 >> RC_PID_ARITH_SHIFT;
188 } 183 }
189 184
@@ -229,43 +224,25 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
229 224
230 /* Change rate. */ 225 /* Change rate. */
231 if (adj) 226 if (adj)
232 rate_control_pid_adjust_rate(local, sta, adj, rinfo); 227 rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo);
233} 228}
234 229
235static void rate_control_pid_tx_status(void *priv, struct net_device *dev, 230static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband,
231 struct ieee80211_sta *sta, void *priv_sta,
236 struct sk_buff *skb) 232 struct sk_buff *skb)
237{ 233{
238 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
239 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
240 struct ieee80211_sub_if_data *sdata;
241 struct rc_pid_info *pinfo = priv; 234 struct rc_pid_info *pinfo = priv;
242 struct sta_info *sta; 235 struct rc_pid_sta_info *spinfo = priv_sta;
243 struct rc_pid_sta_info *spinfo;
244 unsigned long period; 236 unsigned long period;
245 struct ieee80211_supported_band *sband;
246 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 237 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
247 238
248 rcu_read_lock(); 239 if (!spinfo)
249 240 return;
250 sta = sta_info_get(local, hdr->addr1);
251 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
252
253 if (!sta)
254 goto unlock;
255
256 spinfo = sta->rate_ctrl_priv;
257
258 /* Don't update the state if we're not controlling the rate. */
259 sdata = sta->sdata;
260 if (sdata->force_unicast_rateidx > -1) {
261 spinfo->txrate_idx = sdata->max_ratectrl_rateidx;
262 goto unlock;
263 }
264 241
265 /* Ignore all frames that were sent with a different rate than the rate 242 /* Ignore all frames that were sent with a different rate than the rate
266 * we currently advise mac80211 to use. */ 243 * we currently advise mac80211 to use. */
267 if (info->tx_rate_idx != spinfo->txrate_idx) 244 if (info->tx_rate_idx != spinfo->txrate_idx)
268 goto unlock; 245 return;
269 246
270 spinfo->tx_num_xmit++; 247 spinfo->tx_num_xmit++;
271 248
@@ -289,78 +266,63 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
289 if (!period) 266 if (!period)
290 period = 1; 267 period = 1;
291 if (time_after(jiffies, spinfo->last_sample + period)) 268 if (time_after(jiffies, spinfo->last_sample + period))
292 rate_control_pid_sample(pinfo, local, sta); 269 rate_control_pid_sample(pinfo, sband, sta, spinfo);
293
294 unlock:
295 rcu_read_unlock();
296} 270}
297 271
298static void rate_control_pid_get_rate(void *priv, struct net_device *dev, 272static void
299 struct ieee80211_supported_band *sband, 273rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband,
300 struct sk_buff *skb, 274 struct ieee80211_sta *sta, void *priv_sta,
301 struct rate_selection *sel) 275 struct sk_buff *skb,
276 struct rate_selection *sel)
302{ 277{
303 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
304 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 278 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
305 struct ieee80211_sub_if_data *sdata; 279 struct rc_pid_sta_info *spinfo = priv_sta;
306 struct rc_pid_sta_info *spinfo;
307 struct sta_info *sta;
308 int rateidx; 280 int rateidx;
309 u16 fc; 281 u16 fc;
310 282
311 rcu_read_lock();
312
313 sta = sta_info_get(local, hdr->addr1);
314
315 /* Send management frames and broadcast/multicast data using lowest 283 /* Send management frames and broadcast/multicast data using lowest
316 * rate. */ 284 * rate. */
317 fc = le16_to_cpu(hdr->frame_control); 285 fc = le16_to_cpu(hdr->frame_control);
318 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || 286 if (!sta || !spinfo ||
319 is_multicast_ether_addr(hdr->addr1) || !sta) { 287 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
320 sel->rate_idx = rate_lowest_index(local, sband, sta); 288 is_multicast_ether_addr(hdr->addr1)) {
321 rcu_read_unlock(); 289 sel->rate_idx = rate_lowest_index(sband, sta);
322 return; 290 return;
323 } 291 }
324 292
325 /* If a forced rate is in effect, select it. */
326 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
327 spinfo = (struct rc_pid_sta_info *)sta->rate_ctrl_priv;
328 if (sdata->force_unicast_rateidx > -1)
329 spinfo->txrate_idx = sdata->force_unicast_rateidx;
330
331 rateidx = spinfo->txrate_idx; 293 rateidx = spinfo->txrate_idx;
332 294
333 if (rateidx >= sband->n_bitrates) 295 if (rateidx >= sband->n_bitrates)
334 rateidx = sband->n_bitrates - 1; 296 rateidx = sband->n_bitrates - 1;
335 297
336 rcu_read_unlock();
337
338 sel->rate_idx = rateidx; 298 sel->rate_idx = rateidx;
339 299
340#ifdef CONFIG_MAC80211_DEBUGFS 300#ifdef CONFIG_MAC80211_DEBUGFS
341 rate_control_pid_event_tx_rate( 301 rate_control_pid_event_tx_rate(&spinfo->events,
342 &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events,
343 rateidx, sband->bitrates[rateidx].bitrate); 302 rateidx, sband->bitrates[rateidx].bitrate);
344#endif 303#endif
345} 304}
346 305
347static void rate_control_pid_rate_init(void *priv, void *priv_sta, 306static void
348 struct ieee80211_local *local, 307rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
349 struct sta_info *sta) 308 struct ieee80211_sta *sta, void *priv_sta)
350{ 309{
310 struct rc_pid_sta_info *spinfo = priv_sta;
311 struct sta_info *si;
312
351 /* TODO: This routine should consider using RSSI from previous packets 313 /* TODO: This routine should consider using RSSI from previous packets
352 * as we need to have IEEE 802.1X auth succeed immediately after assoc.. 314 * as we need to have IEEE 802.1X auth succeed immediately after assoc..
353 * Until that method is implemented, we will use the lowest supported 315 * Until that method is implemented, we will use the lowest supported
354 * rate as a workaround. */ 316 * rate as a workaround. */
355 struct ieee80211_supported_band *sband;
356 struct rc_pid_sta_info *spinfo = (void *)sta->rate_ctrl_priv;
357 317
358 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 318 spinfo->txrate_idx = rate_lowest_index(sband, sta);
359 spinfo->txrate_idx = rate_lowest_index(local, sband, sta); 319 /* HACK */
360 sta->fail_avg = 0; 320 si = container_of(sta, struct sta_info, sta);
321 si->fail_avg = 0;
361} 322}
362 323
363static void *rate_control_pid_alloc(struct ieee80211_local *local) 324static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
325 struct dentry *debugfsdir)
364{ 326{
365 struct rc_pid_info *pinfo; 327 struct rc_pid_info *pinfo;
366 struct rc_pid_rateinfo *rinfo; 328 struct rc_pid_rateinfo *rinfo;
@@ -371,7 +333,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
371 struct rc_pid_debugfs_entries *de; 333 struct rc_pid_debugfs_entries *de;
372#endif 334#endif
373 335
374 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 336 sband = hw->wiphy->bands[hw->conf.channel->band];
375 337
376 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); 338 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
377 if (!pinfo) 339 if (!pinfo)
@@ -426,30 +388,28 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
426 388
427#ifdef CONFIG_MAC80211_DEBUGFS 389#ifdef CONFIG_MAC80211_DEBUGFS
428 de = &pinfo->dentries; 390 de = &pinfo->dentries;
429 de->dir = debugfs_create_dir("rc80211_pid",
430 local->hw.wiphy->debugfsdir);
431 de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, 391 de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
432 de->dir, &pinfo->target); 392 debugfsdir, &pinfo->target);
433 de->sampling_period = debugfs_create_u32("sampling_period", 393 de->sampling_period = debugfs_create_u32("sampling_period",
434 S_IRUSR | S_IWUSR, de->dir, 394 S_IRUSR | S_IWUSR, debugfsdir,
435 &pinfo->sampling_period); 395 &pinfo->sampling_period);
436 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, 396 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
437 de->dir, &pinfo->coeff_p); 397 debugfsdir, &pinfo->coeff_p);
438 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, 398 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
439 de->dir, &pinfo->coeff_i); 399 debugfsdir, &pinfo->coeff_i);
440 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, 400 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
441 de->dir, &pinfo->coeff_d); 401 debugfsdir, &pinfo->coeff_d);
442 de->smoothing_shift = debugfs_create_u32("smoothing_shift", 402 de->smoothing_shift = debugfs_create_u32("smoothing_shift",
443 S_IRUSR | S_IWUSR, de->dir, 403 S_IRUSR | S_IWUSR, debugfsdir,
444 &pinfo->smoothing_shift); 404 &pinfo->smoothing_shift);
445 de->sharpen_factor = debugfs_create_u32("sharpen_factor", 405 de->sharpen_factor = debugfs_create_u32("sharpen_factor",
446 S_IRUSR | S_IWUSR, de->dir, 406 S_IRUSR | S_IWUSR, debugfsdir,
447 &pinfo->sharpen_factor); 407 &pinfo->sharpen_factor);
448 de->sharpen_duration = debugfs_create_u32("sharpen_duration", 408 de->sharpen_duration = debugfs_create_u32("sharpen_duration",
449 S_IRUSR | S_IWUSR, de->dir, 409 S_IRUSR | S_IWUSR, debugfsdir,
450 &pinfo->sharpen_duration); 410 &pinfo->sharpen_duration);
451 de->norm_offset = debugfs_create_u32("norm_offset", 411 de->norm_offset = debugfs_create_u32("norm_offset",
452 S_IRUSR | S_IWUSR, de->dir, 412 S_IRUSR | S_IWUSR, debugfsdir,
453 &pinfo->norm_offset); 413 &pinfo->norm_offset);
454#endif 414#endif
455 415
@@ -471,7 +431,6 @@ static void rate_control_pid_free(void *priv)
471 debugfs_remove(de->coeff_p); 431 debugfs_remove(de->coeff_p);
472 debugfs_remove(de->sampling_period); 432 debugfs_remove(de->sampling_period);
473 debugfs_remove(de->target); 433 debugfs_remove(de->target);
474 debugfs_remove(de->dir);
475#endif 434#endif
476 435
477 kfree(pinfo->rinfo); 436 kfree(pinfo->rinfo);
@@ -482,7 +441,8 @@ static void rate_control_pid_clear(void *priv)
482{ 441{
483} 442}
484 443
485static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp) 444static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta,
445 gfp_t gfp)
486{ 446{
487 struct rc_pid_sta_info *spinfo; 447 struct rc_pid_sta_info *spinfo;
488 448
@@ -500,10 +460,10 @@ static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
500 return spinfo; 460 return spinfo;
501} 461}
502 462
503static void rate_control_pid_free_sta(void *priv, void *priv_sta) 463static void rate_control_pid_free_sta(void *priv, struct ieee80211_sta *sta,
464 void *priv_sta)
504{ 465{
505 struct rc_pid_sta_info *spinfo = priv_sta; 466 kfree(priv_sta);
506 kfree(spinfo);
507} 467}
508 468
509static struct rate_control_ops mac80211_rcpid = { 469static struct rate_control_ops mac80211_rcpid = {