diff options
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 158 |
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. */ |
71 | static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | 71 | static 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 | ||
148 | static void rate_control_pid_sample(struct rc_pid_info *pinfo, | 144 | static 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 | ||
235 | static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | 230 | static 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 | ||
298 | static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | 272 | static void |
299 | struct ieee80211_supported_band *sband, | 273 | rate_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 | ||
347 | static void rate_control_pid_rate_init(void *priv, void *priv_sta, | 306 | static void |
348 | struct ieee80211_local *local, | 307 | rate_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 | ||
363 | static void *rate_control_pid_alloc(struct ieee80211_local *local) | 324 | static 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 | ||
485 | static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp) | 444 | static 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 | ||
503 | static void rate_control_pid_free_sta(void *priv, void *priv_sta) | 463 | static 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 | ||
509 | static struct rate_control_ops mac80211_rcpid = { | 469 | static struct rate_control_ops mac80211_rcpid = { |