aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo.bianconi83@gmail.com>2015-08-06 17:47:31 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-08-14 11:49:50 -0400
commit90c66bd2232ae6d3c88c1f3378e3028fded642b3 (patch)
tree9271c2f858f7a083fab130de3309a3bfd80762ad /net/mac80211
parent35225eb7a5589407299033bfa7e1ac723b17e2b5 (diff)
mac80211: remove ieee80211_tx_rate dependency in rate mask code
Remove ieee80211_tx_rate dependency in rate_idx_match_legacy_mask(), rate_idx_match_mcs_mask() and rate_idx_match_mask() in order to use the previous logic to define a ratemask in rate_control_set_rates() for station rate table. Moreover move rate mask definition logic in rate_control_cap_mask() Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/rate.c139
1 files changed, 71 insertions, 68 deletions
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 4f02e07ecc7b..4f61ca026ecc 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -353,39 +353,37 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta,
353} 353}
354EXPORT_SYMBOL(rate_control_send_low); 354EXPORT_SYMBOL(rate_control_send_low);
355 355
356static bool rate_idx_match_legacy_mask(struct ieee80211_tx_rate *rate, 356static bool rate_idx_match_legacy_mask(s8 *rate_idx, int n_bitrates, u32 mask)
357 int n_bitrates, u32 mask)
358{ 357{
359 int j; 358 int j;
360 359
361 /* See whether the selected rate or anything below it is allowed. */ 360 /* See whether the selected rate or anything below it is allowed. */
362 for (j = rate->idx; j >= 0; j--) { 361 for (j = *rate_idx; j >= 0; j--) {
363 if (mask & (1 << j)) { 362 if (mask & (1 << j)) {
364 /* Okay, found a suitable rate. Use it. */ 363 /* Okay, found a suitable rate. Use it. */
365 rate->idx = j; 364 *rate_idx = j;
366 return true; 365 return true;
367 } 366 }
368 } 367 }
369 368
370 /* Try to find a higher rate that would be allowed */ 369 /* Try to find a higher rate that would be allowed */
371 for (j = rate->idx + 1; j < n_bitrates; j++) { 370 for (j = *rate_idx + 1; j < n_bitrates; j++) {
372 if (mask & (1 << j)) { 371 if (mask & (1 << j)) {
373 /* Okay, found a suitable rate. Use it. */ 372 /* Okay, found a suitable rate. Use it. */
374 rate->idx = j; 373 *rate_idx = j;
375 return true; 374 return true;
376 } 375 }
377 } 376 }
378 return false; 377 return false;
379} 378}
380 379
381static bool rate_idx_match_mcs_mask(struct ieee80211_tx_rate *rate, 380static bool rate_idx_match_mcs_mask(s8 *rate_idx, u8 *mcs_mask)
382 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
383{ 381{
384 int i, j; 382 int i, j;
385 int ridx, rbit; 383 int ridx, rbit;
386 384
387 ridx = rate->idx / 8; 385 ridx = *rate_idx / 8;
388 rbit = rate->idx % 8; 386 rbit = *rate_idx % 8;
389 387
390 /* sanity check */ 388 /* sanity check */
391 if (ridx < 0 || ridx >= IEEE80211_HT_MCS_MASK_LEN) 389 if (ridx < 0 || ridx >= IEEE80211_HT_MCS_MASK_LEN)
@@ -395,20 +393,20 @@ static bool rate_idx_match_mcs_mask(struct ieee80211_tx_rate *rate,
395 for (i = ridx; i >= 0; i--) { 393 for (i = ridx; i >= 0; i--) {
396 for (j = rbit; j >= 0; j--) 394 for (j = rbit; j >= 0; j--)
397 if (mcs_mask[i] & BIT(j)) { 395 if (mcs_mask[i] & BIT(j)) {
398 rate->idx = i * 8 + j; 396 *rate_idx = i * 8 + j;
399 return true; 397 return true;
400 } 398 }
401 rbit = 7; 399 rbit = 7;
402 } 400 }
403 401
404 /* Try to find a higher rate that would be allowed */ 402 /* Try to find a higher rate that would be allowed */
405 ridx = (rate->idx + 1) / 8; 403 ridx = (*rate_idx + 1) / 8;
406 rbit = (rate->idx + 1) % 8; 404 rbit = (*rate_idx + 1) % 8;
407 405
408 for (i = ridx; i < IEEE80211_HT_MCS_MASK_LEN; i++) { 406 for (i = ridx; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
409 for (j = rbit; j < 8; j++) 407 for (j = rbit; j < 8; j++)
410 if (mcs_mask[i] & BIT(j)) { 408 if (mcs_mask[i] & BIT(j)) {
411 rate->idx = i * 8 + j; 409 *rate_idx = i * 8 + j;
412 return true; 410 return true;
413 } 411 }
414 rbit = 0; 412 rbit = 0;
@@ -418,35 +416,30 @@ static bool rate_idx_match_mcs_mask(struct ieee80211_tx_rate *rate,
418 416
419 417
420 418
421static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, 419static void rate_idx_match_mask(s8 *rate_idx, u16 *rate_flags,
422 struct ieee80211_supported_band *sband, 420 struct ieee80211_supported_band *sband,
423 enum nl80211_chan_width chan_width, 421 enum nl80211_chan_width chan_width,
424 u32 mask, 422 u32 mask,
425 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) 423 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
426{ 424{
427 struct ieee80211_tx_rate alt_rate;
428
429 /* handle HT rates */ 425 /* handle HT rates */
430 if (rate->flags & IEEE80211_TX_RC_MCS) { 426 if (*rate_flags & IEEE80211_TX_RC_MCS) {
431 if (rate_idx_match_mcs_mask(rate, mcs_mask)) 427 if (rate_idx_match_mcs_mask(rate_idx, mcs_mask))
432 return; 428 return;
433 429
434 /* also try the legacy rates. */ 430 /* also try the legacy rates. */
435 alt_rate.idx = 0; 431 *rate_idx = 0;
436 /* keep protection flags */ 432 /* keep protection flags */
437 alt_rate.flags = rate->flags & 433 *rate_flags &= (IEEE80211_TX_RC_USE_RTS_CTS |
438 (IEEE80211_TX_RC_USE_RTS_CTS | 434 IEEE80211_TX_RC_USE_CTS_PROTECT |
439 IEEE80211_TX_RC_USE_CTS_PROTECT | 435 IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
440 IEEE80211_TX_RC_USE_SHORT_PREAMBLE); 436 if (rate_idx_match_legacy_mask(rate_idx, sband->n_bitrates,
441 alt_rate.count = rate->count; 437 mask))
442 if (rate_idx_match_legacy_mask(&alt_rate,
443 sband->n_bitrates, mask)) {
444 *rate = alt_rate;
445 return; 438 return;
446 } 439 } else if (!(*rate_flags & IEEE80211_TX_RC_VHT_MCS)) {
447 } else if (!(rate->flags & IEEE80211_TX_RC_VHT_MCS)) {
448 /* handle legacy rates */ 440 /* handle legacy rates */
449 if (rate_idx_match_legacy_mask(rate, sband->n_bitrates, mask)) 441 if (rate_idx_match_legacy_mask(rate_idx, sband->n_bitrates,
442 mask))
450 return; 443 return;
451 444
452 /* if HT BSS, and we handle a data frame, also try HT rates */ 445 /* if HT BSS, and we handle a data frame, also try HT rates */
@@ -459,23 +452,19 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
459 break; 452 break;
460 } 453 }
461 454
462 alt_rate.idx = 0; 455 *rate_idx = 0;
463 /* keep protection flags */ 456 /* keep protection flags */
464 alt_rate.flags = rate->flags & 457 *rate_flags &= (IEEE80211_TX_RC_USE_RTS_CTS |
465 (IEEE80211_TX_RC_USE_RTS_CTS | 458 IEEE80211_TX_RC_USE_CTS_PROTECT |
466 IEEE80211_TX_RC_USE_CTS_PROTECT | 459 IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
467 IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
468 alt_rate.count = rate->count;
469 460
470 alt_rate.flags |= IEEE80211_TX_RC_MCS; 461 *rate_flags |= IEEE80211_TX_RC_MCS;
471 462
472 if (chan_width == NL80211_CHAN_WIDTH_40) 463 if (chan_width == NL80211_CHAN_WIDTH_40)
473 alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 464 *rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
474 465
475 if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) { 466 if (rate_idx_match_mcs_mask(rate_idx, mcs_mask))
476 *rate = alt_rate;
477 return; 467 return;
478 }
479 } 468 }
480 469
481 /* 470 /*
@@ -628,6 +617,40 @@ static void rate_control_fill_sta_table(struct ieee80211_sta *sta,
628 } 617 }
629} 618}
630 619
620static bool rate_control_cap_mask(struct ieee80211_sub_if_data *sdata,
621 struct ieee80211_supported_band *sband,
622 struct ieee80211_sta *sta, u32 *mask,
623 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
624{
625 u32 i, flags;
626
627 *mask = sdata->rc_rateidx_mask[sband->band];
628 flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
629 for (i = 0; i < sband->n_bitrates; i++) {
630 if ((flags & sband->bitrates[i].flags) != flags)
631 *mask &= ~BIT(i);
632 }
633
634 if (*mask == (1 << sband->n_bitrates) - 1 &&
635 !sdata->rc_has_mcs_mask[sband->band])
636 return false;
637
638 if (sdata->rc_has_mcs_mask[sband->band])
639 memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[sband->band],
640 IEEE80211_HT_MCS_MASK_LEN);
641 else
642 memset(mcs_mask, 0xff, IEEE80211_HT_MCS_MASK_LEN);
643
644 if (sta) {
645 /* Filter out rates that the STA does not support */
646 *mask &= sta->supp_rates[sband->band];
647 for (i = 0; i < sizeof(mcs_mask); i++)
648 mcs_mask[i] &= sta->ht_cap.mcs.rx_mask[i];
649 }
650
651 return true;
652}
653
631static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata, 654static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
632 struct ieee80211_sta *sta, 655 struct ieee80211_sta *sta,
633 struct ieee80211_supported_band *sband, 656 struct ieee80211_supported_band *sband,
@@ -636,9 +659,8 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
636{ 659{
637 enum nl80211_chan_width chan_width; 660 enum nl80211_chan_width chan_width;
638 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]; 661 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
639 bool has_mcs_mask;
640 u32 mask; 662 u32 mask;
641 u32 rate_flags; 663 u16 rate_flags;
642 int i; 664 int i;
643 665
644 /* 666 /*
@@ -646,30 +668,9 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
646 * default mask (allow all rates) is used to save some processing for 668 * default mask (allow all rates) is used to save some processing for
647 * the common case. 669 * the common case.
648 */ 670 */
649 mask = sdata->rc_rateidx_mask[sband->band]; 671 if (!rate_control_cap_mask(sdata, sband, sta, &mask, mcs_mask))
650 has_mcs_mask = sdata->rc_has_mcs_mask[sband->band];
651 rate_flags =
652 ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
653 for (i = 0; i < sband->n_bitrates; i++)
654 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
655 mask &= ~BIT(i);
656
657 if (mask == (1 << sband->n_bitrates) - 1 && !has_mcs_mask)
658 return; 672 return;
659 673
660 if (has_mcs_mask)
661 memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[sband->band],
662 sizeof(mcs_mask));
663 else
664 memset(mcs_mask, 0xff, sizeof(mcs_mask));
665
666 if (sta) {
667 /* Filter out rates that the STA does not support */
668 mask &= sta->supp_rates[sband->band];
669 for (i = 0; i < sizeof(mcs_mask); i++)
670 mcs_mask[i] &= sta->ht_cap.mcs.rx_mask[i];
671 }
672
673 /* 674 /*
674 * Make sure the rate index selected for each TX rate is 675 * Make sure the rate index selected for each TX rate is
675 * included in the configured mask and change the rate indexes 676 * included in the configured mask and change the rate indexes
@@ -681,8 +682,10 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
681 if (rates[i].idx < 0) 682 if (rates[i].idx < 0)
682 break; 683 break;
683 684
684 rate_idx_match_mask(&rates[i], sband, chan_width, mask, 685 rate_flags = rates[i].flags;
685 mcs_mask); 686 rate_idx_match_mask(&rates[i].idx, &rate_flags, sband,
687 chan_width, mask, mcs_mask);
688 rates[i].flags = rate_flags;
686 } 689 }
687} 690}
688 691