aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEyal Shapira <eyal@wizery.com>2013-11-22 18:06:36 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-12-09 15:29:47 -0500
commit5aa335537aa27e0d169e98d90d23342434a1cef0 (patch)
tree694836a7fd512c1d9f5af21a4d767c95564f5356
parent0c308e97d40f0e8f43336b6076f4b26e71ba59c6 (diff)
iwlwifi: mvm: rs: refactor to use rs_rate
Introduce rs_rate which represents a rate. Use this structure instead of iwl_scale_tbl_info where we're dealing with a single rate. This avoids allocating the big iwl_scale_tbl_info structure on the stack in several cases like converting to ucode rate format or from ucode rate format. Signed-off-by: Eyal Shapira <eyal@wizery.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c568
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h60
2 files changed, 331 insertions, 297 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 0598f26b5da9..3af90620b3de 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -175,6 +175,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
175 struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 175 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
176static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); 176static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
177static const char *rs_pretty_lq_type(enum iwl_table_type type); 177static const char *rs_pretty_lq_type(enum iwl_table_type type);
178static const char *rs_pretty_ant(u8 ant);
178 179
179#ifdef CONFIG_MAC80211_DEBUGFS 180#ifdef CONFIG_MAC80211_DEBUGFS
180static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, 181static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
@@ -264,6 +265,15 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
264 265
265#define MCS_INDEX_PER_STREAM (8) 266#define MCS_INDEX_PER_STREAM (8)
266 267
268static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate,
269 const char *prefix)
270{
271 IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d\n",
272 prefix, rs_pretty_lq_type(rate->type),
273 rate->index, rs_pretty_ant(rate->ant),
274 rate->bw, rate->sgi);
275}
276
267static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) 277static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
268{ 278{
269 window->data = 0; 279 window->data = 0;
@@ -430,167 +440,160 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
430 return 0; 440 return 0;
431} 441}
432 442
433/* 443/* Convert rs_rate object into ucode rate bitmask */
434 * Fill uCode API rate_n_flags field, based on "search" or "active" table. 444static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
435 */ 445 struct rs_rate *rate)
436/* FIXME:RS:remove this function and put the flags statically in the table */
437static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm,
438 struct iwl_scale_tbl_info *tbl, int index)
439{ 446{
440 u32 rate_n_flags = 0; 447 u32 ucode_rate = 0;
448 int index = rate->index;
441 449
442 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & 450 ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) &
443 RATE_MCS_ANT_ABC_MSK); 451 RATE_MCS_ANT_ABC_MSK);
444 452
445 if (is_legacy(tbl->lq_type)) { 453 if (is_legacy(rate)) {
446 rate_n_flags |= iwl_rates[index].plcp; 454 ucode_rate |= iwl_rates[index].plcp;
447 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) 455 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
448 rate_n_flags |= RATE_MCS_CCK_MSK; 456 ucode_rate |= RATE_MCS_CCK_MSK;
449 return rate_n_flags; 457 return ucode_rate;
450 } 458 }
451 459
452 if (is_ht(tbl->lq_type)) { 460 if (is_ht(rate)) {
453 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) { 461 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) {
454 IWL_ERR(mvm, "Invalid HT rate index %d\n", index); 462 IWL_ERR(mvm, "Invalid HT rate index %d\n", index);
455 index = IWL_LAST_HT_RATE; 463 index = IWL_LAST_HT_RATE;
456 } 464 }
457 rate_n_flags |= RATE_MCS_HT_MSK; 465 ucode_rate |= RATE_MCS_HT_MSK;
458 466
459 if (is_ht_siso(tbl->lq_type)) 467 if (is_ht_siso(rate))
460 rate_n_flags |= iwl_rates[index].plcp_ht_siso; 468 ucode_rate |= iwl_rates[index].plcp_ht_siso;
461 else if (is_ht_mimo2(tbl->lq_type)) 469 else if (is_ht_mimo2(rate))
462 rate_n_flags |= iwl_rates[index].plcp_ht_mimo2; 470 ucode_rate |= iwl_rates[index].plcp_ht_mimo2;
463 else 471 else
464 WARN_ON_ONCE(1); 472 WARN_ON_ONCE(1);
465 } else if (is_vht(tbl->lq_type)) { 473 } else if (is_vht(rate)) {
466 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) { 474 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) {
467 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); 475 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index);
468 index = IWL_LAST_VHT_RATE; 476 index = IWL_LAST_VHT_RATE;
469 } 477 }
470 rate_n_flags |= RATE_MCS_VHT_MSK; 478 ucode_rate |= RATE_MCS_VHT_MSK;
471 if (is_vht_siso(tbl->lq_type)) 479 if (is_vht_siso(rate))
472 rate_n_flags |= iwl_rates[index].plcp_vht_siso; 480 ucode_rate |= iwl_rates[index].plcp_vht_siso;
473 else if (is_vht_mimo2(tbl->lq_type)) 481 else if (is_vht_mimo2(rate))
474 rate_n_flags |= iwl_rates[index].plcp_vht_mimo2; 482 ucode_rate |= iwl_rates[index].plcp_vht_mimo2;
475 else 483 else
476 WARN_ON_ONCE(1); 484 WARN_ON_ONCE(1);
477 485
478 } else { 486 } else {
479 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type); 487 IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type);
480 } 488 }
481 489
482 rate_n_flags |= tbl->bw; 490 ucode_rate |= rate->bw;
483 if (tbl->is_SGI) 491 if (rate->sgi)
484 rate_n_flags |= RATE_MCS_SGI_MSK; 492 ucode_rate |= RATE_MCS_SGI_MSK;
485 493
486 return rate_n_flags; 494 return ucode_rate;
487} 495}
488 496
489/* 497/* Convert a ucode rate into an rs_rate object */
490 * Interpret uCode API's rate_n_flags format, 498static int rs_rate_from_ucode_rate(const u32 ucode_rate,
491 * fill "search" or "active" tx mode table. 499 enum ieee80211_band band,
492 */ 500 struct rs_rate *rate)
493static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
494 enum ieee80211_band band,
495 struct iwl_scale_tbl_info *tbl,
496 int *rate_idx)
497{ 501{
498 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); 502 u32 ant_msk = ucode_rate & RATE_MCS_ANT_ABC_MSK;
499 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); 503 u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate);
500 u8 nss; 504 u8 nss;
501 505
502 memset(tbl, 0, offsetof(struct iwl_scale_tbl_info, win)); 506 memset(rate, 0, sizeof(struct rs_rate));
503 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); 507 rate->index = iwl_hwrate_to_plcp_idx(ucode_rate);
504 508
505 if (*rate_idx == IWL_RATE_INVALID) { 509 if (rate->index == IWL_RATE_INVALID) {
506 *rate_idx = -1; 510 rate->index = -1;
507 return -EINVAL; 511 return -EINVAL;
508 } 512 }
509 tbl->is_SGI = 0; /* default legacy setup */ 513
510 tbl->bw = 0; 514 rate->ant = (ant_msk >> RATE_MCS_ANT_POS);
511 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
512 tbl->lq_type = LQ_NONE;
513 tbl->max_search = IWL_MAX_SEARCH;
514 515
515 /* Legacy */ 516 /* Legacy */
516 if (!(rate_n_flags & RATE_MCS_HT_MSK) && 517 if (!(ucode_rate & RATE_MCS_HT_MSK) &&
517 !(rate_n_flags & RATE_MCS_VHT_MSK)) { 518 !(ucode_rate & RATE_MCS_VHT_MSK)) {
518 if (num_of_ant == 1) { 519 if (num_of_ant == 1) {
519 if (band == IEEE80211_BAND_5GHZ) 520 if (band == IEEE80211_BAND_5GHZ)
520 tbl->lq_type = LQ_LEGACY_A; 521 rate->type = LQ_LEGACY_A;
521 else 522 else
522 tbl->lq_type = LQ_LEGACY_G; 523 rate->type = LQ_LEGACY_G;
523 } 524 }
524 525
525 return 0; 526 return 0;
526 } 527 }
527 528
528 /* HT or VHT */ 529 /* HT or VHT */
529 if (rate_n_flags & RATE_MCS_SGI_MSK) 530 if (ucode_rate & RATE_MCS_SGI_MSK)
530 tbl->is_SGI = 1; 531 rate->sgi = true;
531 532
532 tbl->bw = rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; 533 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK;
533 534
534 if (rate_n_flags & RATE_MCS_HT_MSK) { 535 if (ucode_rate & RATE_MCS_HT_MSK) {
535 nss = ((rate_n_flags & RATE_HT_MCS_NSS_MSK) >> 536 nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK) >>
536 RATE_HT_MCS_NSS_POS) + 1; 537 RATE_HT_MCS_NSS_POS) + 1;
537 538
538 if (nss == 1) { 539 if (nss == 1) {
539 tbl->lq_type = LQ_HT_SISO; 540 rate->type = LQ_HT_SISO;
540 WARN_ON_ONCE(num_of_ant != 1); 541 WARN_ON_ONCE(num_of_ant != 1);
541 } else if (nss == 2) { 542 } else if (nss == 2) {
542 tbl->lq_type = LQ_HT_MIMO2; 543 rate->type = LQ_HT_MIMO2;
543 WARN_ON_ONCE(num_of_ant != 2); 544 WARN_ON_ONCE(num_of_ant != 2);
544 } else { 545 } else {
545 WARN_ON_ONCE(1); 546 WARN_ON_ONCE(1);
546 } 547 }
547 } else if (rate_n_flags & RATE_MCS_VHT_MSK) { 548 } else if (ucode_rate & RATE_MCS_VHT_MSK) {
548 nss = ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> 549 nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >>
549 RATE_VHT_MCS_NSS_POS) + 1; 550 RATE_VHT_MCS_NSS_POS) + 1;
550 551
551 if (nss == 1) { 552 if (nss == 1) {
552 tbl->lq_type = LQ_VHT_SISO; 553 rate->type = LQ_VHT_SISO;
553 WARN_ON_ONCE(num_of_ant != 1); 554 WARN_ON_ONCE(num_of_ant != 1);
554 } else if (nss == 2) { 555 } else if (nss == 2) {
555 tbl->lq_type = LQ_VHT_MIMO2; 556 rate->type = LQ_VHT_MIMO2;
556 WARN_ON_ONCE(num_of_ant != 2); 557 WARN_ON_ONCE(num_of_ant != 2);
557 } else { 558 } else {
558 WARN_ON_ONCE(1); 559 WARN_ON_ONCE(1);
559 } 560 }
560 } 561 }
561 562
562 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_160); 563 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_160);
563 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_80 && 564 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 &&
564 !is_vht(tbl->lq_type)); 565 !is_vht(rate));
565 566
566 return 0; 567 return 0;
567} 568}
568 569
569/* switch to another antenna/antennas and return 1 */ 570/* switch to another antenna/antennas and return 1 */
570/* if no other valid antenna found, return 0 */ 571/* if no other valid antenna found, return 0 */
571static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, 572static int rs_toggle_antenna(u32 valid_ant, u32 *ucode_rate,
572 struct iwl_scale_tbl_info *tbl) 573 struct rs_rate *rate)
573{ 574{
574 u8 new_ant_type; 575 u8 new_ant_type;
575 576
576 if (!tbl->ant_type || tbl->ant_type > ANT_ABC) 577 if (!rate->ant || rate->ant > ANT_ABC)
577 return 0; 578 return 0;
578 579
579 if (!rs_is_valid_ant(valid_ant, tbl->ant_type)) 580 if (!rs_is_valid_ant(valid_ant, rate->ant))
580 return 0; 581 return 0;
581 582
582 new_ant_type = ant_toggle_lookup[tbl->ant_type]; 583 new_ant_type = ant_toggle_lookup[rate->ant];
583 584
584 while ((new_ant_type != tbl->ant_type) && 585 while ((new_ant_type != rate->ant) &&
585 !rs_is_valid_ant(valid_ant, new_ant_type)) 586 !rs_is_valid_ant(valid_ant, new_ant_type))
586 new_ant_type = ant_toggle_lookup[new_ant_type]; 587 new_ant_type = ant_toggle_lookup[new_ant_type];
587 588
588 if (new_ant_type == tbl->ant_type) 589 if (new_ant_type == rate->ant)
589 return 0; 590 return 0;
590 591
591 tbl->ant_type = new_ant_type; 592 rate->ant = new_ant_type;
592 *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK; 593
593 *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS; 594 /* TODO: get rid of ucode_rate here. This should handle only rs_rate */
595 *ucode_rate &= ~RATE_MCS_ANT_ABC_MSK;
596 *ucode_rate |= new_ant_type << RATE_MCS_ANT_POS;
594 return 1; 597 return 1;
595} 598}
596 599
@@ -603,13 +606,13 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
603 */ 606 */
604static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta, 607static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
605 struct ieee80211_hdr *hdr, 608 struct ieee80211_hdr *hdr,
606 enum iwl_table_type rate_type) 609 struct rs_rate *rate)
607{ 610{
608 if (is_legacy(rate_type)) 611 if (is_legacy(rate))
609 return lq_sta->active_legacy_rate; 612 return lq_sta->active_legacy_rate;
610 else if (is_siso(rate_type)) 613 else if (is_siso(rate))
611 return lq_sta->active_siso_rate; 614 return lq_sta->active_siso_rate;
612 else if (is_mimo2(rate_type)) 615 else if (is_mimo2(rate))
613 return lq_sta->active_mimo2_rate; 616 return lq_sta->active_mimo2_rate;
614 617
615 WARN_ON_ONCE(1); 618 WARN_ON_ONCE(1);
@@ -624,7 +627,7 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
624 627
625 /* 802.11A or ht walks to the next literal adjacent rate in 628 /* 802.11A or ht walks to the next literal adjacent rate in
626 * the rate table */ 629 * the rate table */
627 if (is_a_band(rate_type) || !is_legacy(rate_type)) { 630 if (is_type_a_band(rate_type) || !is_type_legacy(rate_type)) {
628 int i; 631 int i;
629 u32 mask; 632 u32 mask;
630 633
@@ -673,7 +676,7 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
673} 676}
674 677
675static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, 678static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
676 struct iwl_scale_tbl_info *tbl, 679 struct rs_rate *rate,
677 u8 scale_index, u8 ht_possible) 680 u8 scale_index, u8 ht_possible)
678{ 681{
679 s32 low; 682 s32 low;
@@ -685,30 +688,29 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
685 /* check if we need to switch from HT to legacy rates. 688 /* check if we need to switch from HT to legacy rates.
686 * assumption is that mandatory rates (1Mbps or 6Mbps) 689 * assumption is that mandatory rates (1Mbps or 6Mbps)
687 * are always supported (spec demand) */ 690 * are always supported (spec demand) */
688 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { 691 if (!is_legacy(rate) && (!ht_possible || !scale_index)) {
689 switch_to_legacy = 1; 692 switch_to_legacy = 1;
690 scale_index = rs_ht_to_legacy[scale_index]; 693 scale_index = rs_ht_to_legacy[scale_index];
691 if (lq_sta->band == IEEE80211_BAND_5GHZ) 694 if (lq_sta->band == IEEE80211_BAND_5GHZ)
692 tbl->lq_type = LQ_LEGACY_A; 695 rate->type = LQ_LEGACY_A;
693 else 696 else
694 tbl->lq_type = LQ_LEGACY_G; 697 rate->type = LQ_LEGACY_G;
695 698
696 if (num_of_ant(tbl->ant_type) > 1) 699 if (num_of_ant(rate->ant) > 1)
697 tbl->ant_type = 700 rate->ant =
698 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 701 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
699 702
700 tbl->bw = 0; 703 rate->bw = 0;
701 tbl->is_SGI = 0; 704 rate->sgi = false;
702 tbl->max_search = IWL_MAX_SEARCH;
703 } 705 }
704 706
705 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); 707 rate_mask = rs_get_supported_rates(lq_sta, NULL, rate);
706 708
707 /* Mask with station rate restriction */ 709 /* Mask with station rate restriction */
708 if (is_legacy(tbl->lq_type)) { 710 if (is_legacy(rate)) {
709 /* supp_rates has no CCK bits in A mode */ 711 /* supp_rates has no CCK bits in A mode */
710 if (lq_sta->band == IEEE80211_BAND_5GHZ) 712 if (lq_sta->band == IEEE80211_BAND_5GHZ)
711 rate_mask = (u16)(rate_mask & 713 rate_mask = (u16)(rate_mask &
712 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); 714 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
713 else 715 else
714 rate_mask = (u16)(rate_mask & lq_sta->supp_rates); 716 rate_mask = (u16)(rate_mask & lq_sta->supp_rates);
@@ -721,24 +723,22 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
721 } 723 }
722 724
723 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask, 725 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
724 tbl->lq_type); 726 rate->type);
725 low = high_low & 0xff; 727 low = high_low & 0xff;
726 728
727 if (low == IWL_RATE_INVALID) 729 if (low == IWL_RATE_INVALID)
728 low = scale_index; 730 low = scale_index;
729 731
730out: 732out:
731 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low); 733 rate->index = low;
734 return ucode_rate_from_rs_rate(lq_sta->drv, rate);
732} 735}
733 736
734/* 737/* Simple function to compare two rate scale table types */
735 * Simple function to compare two rate scale table types 738static inline bool rs_rate_match(struct rs_rate *a,
736 */ 739 struct rs_rate *b)
737static bool table_type_matches(struct iwl_scale_tbl_info *a,
738 struct iwl_scale_tbl_info *b)
739{ 740{
740 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && 741 return (a->type == b->type) && (a->ant == b->ant) && (a->sgi == b->sgi);
741 (a->is_SGI == b->is_SGI);
742} 742}
743 743
744static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags) 744static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
@@ -762,7 +762,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
762{ 762{
763 int legacy_success; 763 int legacy_success;
764 int retries; 764 int retries;
765 int rs_index, mac_index, i; 765 int mac_index, i;
766 struct iwl_lq_sta *lq_sta = priv_sta; 766 struct iwl_lq_sta *lq_sta = priv_sta;
767 struct iwl_lq_cmd *table; 767 struct iwl_lq_cmd *table;
768 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 768 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -770,8 +770,8 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
770 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 770 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
771 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 771 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
772 enum mac80211_rate_control_flags mac_flags; 772 enum mac80211_rate_control_flags mac_flags;
773 u32 tx_rate; 773 u32 ucode_rate;
774 struct iwl_scale_tbl_info tbl_type; 774 struct rs_rate rate;
775 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 775 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
776 776
777 /* Treat uninitialized rate scaling data same as non-existing. */ 777 /* Treat uninitialized rate scaling data same as non-existing. */
@@ -801,10 +801,10 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
801 * to a new "search" mode (which might become the new "active" mode). 801 * to a new "search" mode (which might become the new "active" mode).
802 */ 802 */
803 table = &lq_sta->lq; 803 table = &lq_sta->lq;
804 tx_rate = le32_to_cpu(table->rs_table[0]); 804 ucode_rate = le32_to_cpu(table->rs_table[0]);
805 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, &rs_index); 805 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
806 if (info->band == IEEE80211_BAND_5GHZ) 806 if (info->band == IEEE80211_BAND_5GHZ)
807 rs_index -= IWL_FIRST_OFDM_RATE; 807 rate.index -= IWL_FIRST_OFDM_RATE;
808 mac_flags = info->status.rates[0].flags; 808 mac_flags = info->status.rates[0].flags;
809 mac_index = info->status.rates[0].idx; 809 mac_index = info->status.rates[0].idx;
810 /* For HT packets, map MCS to PLCP */ 810 /* For HT packets, map MCS to PLCP */
@@ -827,19 +827,19 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
827 827
828 /* Here we actually compare this rate to the latest LQ command */ 828 /* Here we actually compare this rate to the latest LQ command */
829 if ((mac_index < 0) || 829 if ((mac_index < 0) ||
830 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || 830 (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
831 (tbl_type.bw != rs_ch_width_from_mac_flags(mac_flags)) || 831 (rate.bw != rs_ch_width_from_mac_flags(mac_flags)) ||
832 (tbl_type.ant_type != info->status.antenna) || 832 (rate.ant != info->status.antenna) ||
833 (!!(tx_rate & RATE_MCS_HT_MSK) != 833 (!!(ucode_rate & RATE_MCS_HT_MSK) !=
834 !!(mac_flags & IEEE80211_TX_RC_MCS)) || 834 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
835 (!!(tx_rate & RATE_MCS_VHT_MSK) != 835 (!!(ucode_rate & RATE_MCS_VHT_MSK) !=
836 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) || 836 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) ||
837 (!!(tx_rate & RATE_HT_MCS_GF_MSK) != 837 (!!(ucode_rate & RATE_HT_MCS_GF_MSK) !=
838 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || 838 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
839 (rs_index != mac_index)) { 839 (rate.index != mac_index)) {
840 IWL_DEBUG_RATE(mvm, 840 IWL_DEBUG_RATE(mvm,
841 "initial rate %d does not match %d (0x%x)\n", 841 "initial rate %d does not match %d (0x%x)\n",
842 mac_index, rs_index, tx_rate); 842 mac_index, rate.index, ucode_rate);
843 /* 843 /*
844 * Since rates mis-match, the last LQ command may have failed. 844 * Since rates mis-match, the last LQ command may have failed.
845 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with 845 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
@@ -857,28 +857,23 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
857 lq_sta->missed_rate_counter = 0; 857 lq_sta->missed_rate_counter = 0;
858 858
859 /* Figure out if rate scale algorithm is in active or search table */ 859 /* Figure out if rate scale algorithm is in active or search table */
860 if (table_type_matches(&tbl_type, 860 if (rs_rate_match(&rate,
861 &(lq_sta->lq_info[lq_sta->active_tbl]))) { 861 &(lq_sta->lq_info[lq_sta->active_tbl].rate))) {
862 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 862 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
863 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 863 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
864 } else if (table_type_matches( 864 } else if (rs_rate_match(&rate,
865 &tbl_type, &lq_sta->lq_info[1 - lq_sta->active_tbl])) { 865 &lq_sta->lq_info[1 - lq_sta->active_tbl].rate)) {
866 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 866 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
867 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 867 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
868 } else { 868 } else {
869 IWL_DEBUG_RATE(mvm, 869 IWL_DEBUG_RATE(mvm,
870 "Neither active nor search matches tx rate\n"); 870 "Neither active nor search matches tx rate\n");
871 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 871 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
872 IWL_DEBUG_RATE(mvm, "active- lq:%x, ant:%x, SGI:%d\n", 872 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
873 tmp_tbl->lq_type, tmp_tbl->ant_type,
874 tmp_tbl->is_SGI);
875 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 873 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
876 IWL_DEBUG_RATE(mvm, "search- lq:%x, ant:%x, SGI:%d\n", 874 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
877 tmp_tbl->lq_type, tmp_tbl->ant_type, 875 rs_dump_rate(mvm, &rate, "ACTUAL");
878 tmp_tbl->is_SGI); 876
879 IWL_DEBUG_RATE(mvm, "actual- lq:%x, ant:%x, SGI:%d\n",
880 tbl_type.lq_type, tbl_type.ant_type,
881 tbl_type.is_SGI);
882 /* 877 /*
883 * no matching table found, let's by-pass the data collection 878 * no matching table found, let's by-pass the data collection
884 * and continue to perform rate scale to find the rate table 879 * and continue to perform rate scale to find the rate table
@@ -895,10 +890,9 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
895 * first index into rate scale table. 890 * first index into rate scale table.
896 */ 891 */
897 if (info->flags & IEEE80211_TX_STAT_AMPDU) { 892 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
898 tx_rate = le32_to_cpu(table->rs_table[0]); 893 ucode_rate = le32_to_cpu(table->rs_table[0]);
899 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, 894 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
900 &rs_index); 895 rs_collect_tx_data(curr_tbl, rate.index,
901 rs_collect_tx_data(curr_tbl, rs_index,
902 info->status.ampdu_len, 896 info->status.ampdu_len,
903 info->status.ampdu_ack_len); 897 info->status.ampdu_ack_len);
904 898
@@ -920,20 +914,19 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
920 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); 914 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
921 /* Collect data for each rate used during failed TX attempts */ 915 /* Collect data for each rate used during failed TX attempts */
922 for (i = 0; i <= retries; ++i) { 916 for (i = 0; i <= retries; ++i) {
923 tx_rate = le32_to_cpu(table->rs_table[i]); 917 ucode_rate = le32_to_cpu(table->rs_table[i]);
924 rs_get_tbl_info_from_mcs(tx_rate, info->band, 918 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
925 &tbl_type, &rs_index);
926 /* 919 /*
927 * Only collect stats if retried rate is in the same RS 920 * Only collect stats if retried rate is in the same RS
928 * table as active/search. 921 * table as active/search.
929 */ 922 */
930 if (table_type_matches(&tbl_type, curr_tbl)) 923 if (rs_rate_match(&rate, &curr_tbl->rate))
931 tmp_tbl = curr_tbl; 924 tmp_tbl = curr_tbl;
932 else if (table_type_matches(&tbl_type, other_tbl)) 925 else if (rs_rate_match(&rate, &other_tbl->rate))
933 tmp_tbl = other_tbl; 926 tmp_tbl = other_tbl;
934 else 927 else
935 continue; 928 continue;
936 rs_collect_tx_data(tmp_tbl, rs_index, 1, 929 rs_collect_tx_data(tmp_tbl, rate.index, 1,
937 i < retries ? 0 : legacy_success); 930 i < retries ? 0 : legacy_success);
938 } 931 }
939 932
@@ -944,7 +937,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
944 } 937 }
945 } 938 }
946 /* The last TX rate is cached in lq_sta; it's set in if/else above */ 939 /* The last TX rate is cached in lq_sta; it's set in if/else above */
947 lq_sta->last_rate_n_flags = tx_rate; 940 lq_sta->last_rate_n_flags = ucode_rate;
948done: 941done:
949 /* See if there's a better rate or modulation mode to try. */ 942 /* See if there's a better rate or modulation mode to try. */
950 if (sta && sta->supp_rates[sband->band]) 943 if (sta && sta->supp_rates[sband->band])
@@ -988,16 +981,17 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
988{ 981{
989 /* Used to choose among HT tables */ 982 /* Used to choose among HT tables */
990 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT]; 983 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
984 struct rs_rate *rate = &tbl->rate;
991 985
992 /* Check for invalid LQ type */ 986 /* Check for invalid LQ type */
993 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_ht(tbl->lq_type) && 987 if (WARN_ON_ONCE(!is_legacy(rate) && !is_ht(rate) &&
994 !(is_vht(tbl->lq_type)))) { 988 !(is_vht(rate)))) {
995 tbl->expected_tpt = expected_tpt_legacy; 989 tbl->expected_tpt = expected_tpt_legacy;
996 return; 990 return;
997 } 991 }
998 992
999 /* Legacy rates have only one table */ 993 /* Legacy rates have only one table */
1000 if (is_legacy(tbl->lq_type)) { 994 if (is_legacy(rate)) {
1001 tbl->expected_tpt = expected_tpt_legacy; 995 tbl->expected_tpt = expected_tpt_legacy;
1002 return; 996 return;
1003 } 997 }
@@ -1006,8 +1000,8 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1006 /* Choose among many HT tables depending on number of streams 1000 /* Choose among many HT tables depending on number of streams
1007 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation 1001 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation
1008 * status */ 1002 * status */
1009 if (is_siso(tbl->lq_type)) { 1003 if (is_siso(rate)) {
1010 switch (tbl->bw) { 1004 switch (rate->bw) {
1011 case RATE_MCS_CHAN_WIDTH_20: 1005 case RATE_MCS_CHAN_WIDTH_20:
1012 ht_tbl_pointer = expected_tpt_siso_20MHz; 1006 ht_tbl_pointer = expected_tpt_siso_20MHz;
1013 break; 1007 break;
@@ -1020,8 +1014,8 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1020 default: 1014 default:
1021 WARN_ON_ONCE(1); 1015 WARN_ON_ONCE(1);
1022 } 1016 }
1023 } else if (is_mimo2(tbl->lq_type)) { 1017 } else if (is_mimo2(rate)) {
1024 switch (tbl->bw) { 1018 switch (rate->bw) {
1025 case RATE_MCS_CHAN_WIDTH_20: 1019 case RATE_MCS_CHAN_WIDTH_20:
1026 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 1020 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1027 break; 1021 break;
@@ -1038,11 +1032,11 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1038 WARN_ON_ONCE(1); 1032 WARN_ON_ONCE(1);
1039 } 1033 }
1040 1034
1041 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ 1035 if (!rate->sgi && !lq_sta->is_agg) /* Normal */
1042 tbl->expected_tpt = ht_tbl_pointer[0]; 1036 tbl->expected_tpt = ht_tbl_pointer[0];
1043 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */ 1037 else if (rate->sgi && !lq_sta->is_agg) /* SGI */
1044 tbl->expected_tpt = ht_tbl_pointer[1]; 1038 tbl->expected_tpt = ht_tbl_pointer[1];
1045 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */ 1039 else if (!rate->sgi && lq_sta->is_agg) /* AGG */
1046 tbl->expected_tpt = ht_tbl_pointer[2]; 1040 tbl->expected_tpt = ht_tbl_pointer[2];
1047 else /* AGG+SGI */ 1041 else /* AGG+SGI */
1048 tbl->expected_tpt = ht_tbl_pointer[3]; 1042 tbl->expected_tpt = ht_tbl_pointer[3];
@@ -1082,7 +1076,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1082 1076
1083 while (1) { 1077 while (1) {
1084 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask, 1078 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask,
1085 tbl->lq_type); 1079 tbl->rate.type);
1086 1080
1087 low = high_low & 0xff; 1081 low = high_low & 0xff;
1088 high = (high_low >> 8) & 0xff; 1082 high = (high_low >> 8) & 0xff;
@@ -1163,30 +1157,29 @@ static inline void rs_move_next_action(struct iwl_scale_tbl_info *tbl,
1163 tbl->action = (tbl->action + 1) % (last_action + 1); 1157 tbl->action = (tbl->action + 1) % (last_action + 1);
1164} 1158}
1165 1159
1166static void rs_set_bw_from_sta(struct iwl_scale_tbl_info *tbl, 1160static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
1167 struct ieee80211_sta *sta)
1168{ 1161{
1169 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80) 1162 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80)
1170 tbl->bw = RATE_MCS_CHAN_WIDTH_80; 1163 return RATE_MCS_CHAN_WIDTH_80;
1171 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) 1164 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
1172 tbl->bw = RATE_MCS_CHAN_WIDTH_40; 1165 return RATE_MCS_CHAN_WIDTH_40;
1173 else 1166
1174 tbl->bw = RATE_MCS_CHAN_WIDTH_20; 1167 return RATE_MCS_CHAN_WIDTH_20;
1175} 1168}
1176 1169
1177static bool rs_sgi_allowed(struct iwl_scale_tbl_info *tbl, 1170static bool rs_sgi_allowed(struct rs_rate *rate,
1178 struct ieee80211_sta *sta) 1171 struct ieee80211_sta *sta)
1179{ 1172{
1180 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 1173 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1181 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 1174 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
1182 1175
1183 if (is_ht20(tbl) && (ht_cap->cap & 1176 if (is_ht20(rate) && (ht_cap->cap &
1184 IEEE80211_HT_CAP_SGI_20)) 1177 IEEE80211_HT_CAP_SGI_20))
1185 return true; 1178 return true;
1186 if (is_ht40(tbl) && (ht_cap->cap & 1179 if (is_ht40(rate) && (ht_cap->cap &
1187 IEEE80211_HT_CAP_SGI_40)) 1180 IEEE80211_HT_CAP_SGI_40))
1188 return true; 1181 return true;
1189 if (is_ht80(tbl) && (vht_cap->cap & 1182 if (is_ht80(rate) && (vht_cap->cap &
1190 IEEE80211_VHT_CAP_SHORT_GI_80)) 1183 IEEE80211_VHT_CAP_SHORT_GI_80))
1191 return true; 1184 return true;
1192 1185
@@ -1202,7 +1195,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1202 struct iwl_scale_tbl_info *tbl, int index) 1195 struct iwl_scale_tbl_info *tbl, int index)
1203{ 1196{
1204 u16 rate_mask; 1197 u16 rate_mask;
1205 s32 rate; 1198 s32 rate_idx;
1206 1199
1207 if (!sta->ht_cap.ht_supported) 1200 if (!sta->ht_cap.ht_supported)
1208 return -1; 1201 return -1;
@@ -1216,24 +1209,26 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1216 1209
1217 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); 1210 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n");
1218 1211
1219 tbl->lq_type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; 1212 tbl->rate.type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;
1220 tbl->action = 0; 1213 tbl->action = 0;
1221 tbl->max_search = IWL_MAX_SEARCH; 1214 tbl->max_search = IWL_MAX_SEARCH;
1222 rate_mask = lq_sta->active_mimo2_rate; 1215 rate_mask = lq_sta->active_mimo2_rate;
1223 1216
1224 rs_set_bw_from_sta(tbl, sta); 1217 tbl->rate.bw = rs_bw_from_sta_bw(sta);
1225 rs_set_expected_tpt_table(lq_sta, tbl); 1218 rs_set_expected_tpt_table(lq_sta, tbl);
1226 1219
1227 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index); 1220 rate_idx = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1228 1221
1229 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 best rate %d mask %X\n", 1222 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 best rate %d mask %X\n",
1230 rate, rate_mask); 1223 rate_idx, rate_mask);
1231 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { 1224 if ((rate_idx == IWL_RATE_INVALID) || !((1 << rate_idx) & rate_mask)) {
1232 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n", 1225 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n",
1233 rate, rate_mask); 1226 rate_idx, rate_mask);
1234 return -1; 1227 return -1;
1235 } 1228 }
1236 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate); 1229
1230 tbl->rate.index = rate_idx;
1231 tbl->current_rate = ucode_rate_from_rs_rate(mvm, &tbl->rate);
1237 1232
1238 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n", 1233 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n",
1239 tbl->current_rate); 1234 tbl->current_rate);
@@ -1249,30 +1244,34 @@ static int rs_switch_to_siso(struct iwl_mvm *mvm,
1249 struct iwl_scale_tbl_info *tbl, int index) 1244 struct iwl_scale_tbl_info *tbl, int index)
1250{ 1245{
1251 u16 rate_mask; 1246 u16 rate_mask;
1252 s32 rate; 1247 s32 rate_idx;
1253 1248
1254 if (!sta->ht_cap.ht_supported) 1249 if (!sta->ht_cap.ht_supported)
1255 return -1; 1250 return -1;
1256 1251
1257 IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n"); 1252 IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n");
1258 1253
1259 tbl->lq_type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; 1254 tbl->rate.type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;
1260 tbl->action = 0; 1255 tbl->action = 0;
1261 tbl->max_search = IWL_MAX_SEARCH; 1256 tbl->max_search = IWL_MAX_SEARCH;
1262 rate_mask = lq_sta->active_siso_rate; 1257 rate_mask = lq_sta->active_siso_rate;
1263 1258
1264 rs_set_bw_from_sta(tbl, sta); 1259 tbl->rate.bw = rs_bw_from_sta_bw(sta);
1265 rs_set_expected_tpt_table(lq_sta, tbl); 1260 rs_set_expected_tpt_table(lq_sta, tbl);
1266 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index); 1261 rate_idx = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1267 1262
1268 IWL_DEBUG_RATE(mvm, "LQ: get best rate %d mask %X\n", rate, rate_mask); 1263 IWL_DEBUG_RATE(mvm, "LQ: get best rate %d mask %X\n",
1269 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { 1264 rate_idx, rate_mask);
1265 if ((rate_idx == IWL_RATE_INVALID) || !((1 << rate_idx) & rate_mask)) {
1270 IWL_DEBUG_RATE(mvm, 1266 IWL_DEBUG_RATE(mvm,
1271 "can not switch with index %d rate mask %x\n", 1267 "can not switch with index %d rate mask %x\n",
1272 rate, rate_mask); 1268 rate_idx, rate_mask);
1273 return -1; 1269 return -1;
1274 } 1270 }
1275 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate); 1271
1272 tbl->rate.index = rate_idx;
1273 tbl->current_rate = ucode_rate_from_rs_rate(mvm, &tbl->rate);
1274
1276 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n", 1275 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n",
1277 tbl->current_rate); 1276 tbl->current_rate);
1278 return 0; 1277 return 0;
@@ -1289,6 +1288,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1289 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1288 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1290 struct iwl_scale_tbl_info *search_tbl = 1289 struct iwl_scale_tbl_info *search_tbl =
1291 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1290 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1291 struct rs_rate *rate = &search_tbl->rate;
1292 struct iwl_rate_scale_data *window = &(tbl->win[index]); 1292 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1293 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1293 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1294 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1294 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
@@ -1317,7 +1317,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1317 1317
1318 if (rs_toggle_antenna(valid_tx_ant, 1318 if (rs_toggle_antenna(valid_tx_ant,
1319 &search_tbl->current_rate, 1319 &search_tbl->current_rate,
1320 search_tbl)) { 1320 &search_tbl->rate)) {
1321 update_search_tbl_counter = 1; 1321 update_search_tbl_counter = 1;
1322 rs_set_expected_tpt_table(lq_sta, search_tbl); 1322 rs_set_expected_tpt_table(lq_sta, search_tbl);
1323 goto out; 1323 goto out;
@@ -1328,7 +1328,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1328 1328
1329 /* Set up search table to try SISO */ 1329 /* Set up search table to try SISO */
1330 memcpy(search_tbl, tbl, sz); 1330 memcpy(search_tbl, tbl, sz);
1331 search_tbl->is_SGI = 0; 1331 rate->sgi = false;
1332 ret = rs_switch_to_siso(mvm, lq_sta, sta, 1332 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1333 search_tbl, index); 1333 search_tbl, index);
1334 if (!ret) { 1334 if (!ret) {
@@ -1342,12 +1342,11 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1342 1342
1343 /* Set up search table to try MIMO */ 1343 /* Set up search table to try MIMO */
1344 memcpy(search_tbl, tbl, sz); 1344 memcpy(search_tbl, tbl, sz);
1345 search_tbl->is_SGI = 0; 1345 rate->sgi = false;
1346 1346 rate->ant = ANT_AB;
1347 search_tbl->ant_type = ANT_AB;
1348 1347
1349 if (!rs_is_valid_ant(valid_tx_ant, 1348 if (!rs_is_valid_ant(valid_tx_ant,
1350 search_tbl->ant_type)) 1349 rate->ant))
1351 break; 1350 break;
1352 1351
1353 ret = rs_switch_to_mimo2(mvm, lq_sta, sta, 1352 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
@@ -1365,7 +1364,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1365 if (tbl->action == start_action) 1364 if (tbl->action == start_action)
1366 break; 1365 break;
1367 } 1366 }
1368 search_tbl->lq_type = LQ_NONE; 1367 rate->type = LQ_NONE;
1369 return 0; 1368 return 0;
1370 1369
1371out: 1370out:
@@ -1386,6 +1385,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1386 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1385 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1387 struct iwl_scale_tbl_info *search_tbl = 1386 struct iwl_scale_tbl_info *search_tbl =
1388 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1387 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1388 struct rs_rate *rate = &search_tbl->rate;
1389 struct iwl_rate_scale_data *window = &(tbl->win[index]); 1389 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1390 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1390 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1391 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1391 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
@@ -1416,7 +1416,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1416 memcpy(search_tbl, tbl, sz); 1416 memcpy(search_tbl, tbl, sz);
1417 if (rs_toggle_antenna(valid_tx_ant, 1417 if (rs_toggle_antenna(valid_tx_ant,
1418 &search_tbl->current_rate, 1418 &search_tbl->current_rate,
1419 search_tbl)) { 1419 rate)) {
1420 update_search_tbl_counter = 1; 1420 update_search_tbl_counter = 1;
1421 goto out; 1421 goto out;
1422 } 1422 }
@@ -1424,12 +1424,11 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1424 case IWL_SISO_SWITCH_MIMO2: 1424 case IWL_SISO_SWITCH_MIMO2:
1425 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO2\n"); 1425 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO2\n");
1426 memcpy(search_tbl, tbl, sz); 1426 memcpy(search_tbl, tbl, sz);
1427 search_tbl->is_SGI = 0; 1427 rate->sgi = false;
1428 1428 rate->ant = ANT_AB;
1429 search_tbl->ant_type = ANT_AB;
1430 1429
1431 if (!rs_is_valid_ant(valid_tx_ant, 1430 if (!rs_is_valid_ant(valid_tx_ant,
1432 search_tbl->ant_type)) 1431 rate->ant))
1433 break; 1432 break;
1434 1433
1435 ret = rs_switch_to_mimo2(mvm, lq_sta, sta, 1434 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
@@ -1438,21 +1437,22 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1438 goto out; 1437 goto out;
1439 break; 1438 break;
1440 case IWL_SISO_SWITCH_GI: 1439 case IWL_SISO_SWITCH_GI:
1441 if (!rs_sgi_allowed(tbl, sta)) 1440 if (!rs_sgi_allowed(rate, sta))
1442 break; 1441 break;
1443 1442
1444 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n"); 1443 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n");
1445 1444
1446 memcpy(search_tbl, tbl, sz); 1445 memcpy(search_tbl, tbl, sz);
1447 search_tbl->is_SGI = !tbl->is_SGI; 1446 rate->sgi = !tbl->rate.sgi;
1448 rs_set_expected_tpt_table(lq_sta, search_tbl); 1447 rs_set_expected_tpt_table(lq_sta, search_tbl);
1449 if (tbl->is_SGI) { 1448 if (tbl->rate.sgi) {
1450 s32 tpt = lq_sta->last_tpt / 100; 1449 s32 tpt = lq_sta->last_tpt / 100;
1451 if (tpt >= search_tbl->expected_tpt[index]) 1450 if (tpt >= search_tbl->expected_tpt[index])
1452 break; 1451 break;
1453 } 1452 }
1453 rate->index = index;
1454 search_tbl->current_rate = 1454 search_tbl->current_rate =
1455 rate_n_flags_from_tbl(mvm, search_tbl, index); 1455 ucode_rate_from_rs_rate(mvm, rate);
1456 update_search_tbl_counter = 1; 1456 update_search_tbl_counter = 1;
1457 goto out; 1457 goto out;
1458 default: 1458 default:
@@ -1463,7 +1463,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1463 if (tbl->action == start_action) 1463 if (tbl->action == start_action)
1464 break; 1464 break;
1465 } 1465 }
1466 search_tbl->lq_type = LQ_NONE; 1466 rate->type = LQ_NONE;
1467 return 0; 1467 return 0;
1468 1468
1469 out: 1469 out:
@@ -1485,6 +1485,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1485 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1485 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1486 struct iwl_scale_tbl_info *search_tbl = 1486 struct iwl_scale_tbl_info *search_tbl =
1487 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1487 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1488 struct rs_rate *rate = &search_tbl->rate;
1488 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1489 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1489 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1490 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1490 u8 start_action; 1491 u8 start_action;
@@ -1509,12 +1510,12 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1509 memcpy(search_tbl, tbl, sz); 1510 memcpy(search_tbl, tbl, sz);
1510 1511
1511 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A) 1512 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
1512 search_tbl->ant_type = ANT_A; 1513 rate->ant = ANT_A;
1513 else /* tbl->action == IWL_MIMO2_SWITCH_SISO_B */ 1514 else /* tbl->action == IWL_MIMO2_SWITCH_SISO_B */
1514 search_tbl->ant_type = ANT_B; 1515 rate->ant = ANT_B;
1515 1516
1516 if (!rs_is_valid_ant(valid_tx_ant, 1517 if (!rs_is_valid_ant(valid_tx_ant,
1517 search_tbl->ant_type)) 1518 rate->ant))
1518 break; 1519 break;
1519 1520
1520 ret = rs_switch_to_siso(mvm, lq_sta, sta, 1521 ret = rs_switch_to_siso(mvm, lq_sta, sta,
@@ -1525,14 +1526,14 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1525 break; 1526 break;
1526 1527
1527 case IWL_MIMO2_SWITCH_GI: 1528 case IWL_MIMO2_SWITCH_GI:
1528 if (!rs_sgi_allowed(tbl, sta)) 1529 if (!rs_sgi_allowed(rate, sta))
1529 break; 1530 break;
1530 1531
1531 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n"); 1532 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n");
1532 1533
1533 /* Set up new search table for MIMO2 */ 1534 /* Set up new search table for MIMO2 */
1534 memcpy(search_tbl, tbl, sz); 1535 memcpy(search_tbl, tbl, sz);
1535 search_tbl->is_SGI = !tbl->is_SGI; 1536 rate->sgi = !tbl->rate.sgi;
1536 rs_set_expected_tpt_table(lq_sta, search_tbl); 1537 rs_set_expected_tpt_table(lq_sta, search_tbl);
1537 /* 1538 /*
1538 * If active table already uses the fastest possible 1539 * If active table already uses the fastest possible
@@ -1540,13 +1541,14 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1540 * and it's working well, there's no need to look 1541 * and it's working well, there's no need to look
1541 * for a better type of modulation! 1542 * for a better type of modulation!
1542 */ 1543 */
1543 if (tbl->is_SGI) { 1544 if (tbl->rate.sgi) {
1544 s32 tpt = lq_sta->last_tpt / 100; 1545 s32 tpt = lq_sta->last_tpt / 100;
1545 if (tpt >= search_tbl->expected_tpt[index]) 1546 if (tpt >= search_tbl->expected_tpt[index])
1546 break; 1547 break;
1547 } 1548 }
1549 rate->index = index;
1548 search_tbl->current_rate = 1550 search_tbl->current_rate =
1549 rate_n_flags_from_tbl(mvm, search_tbl, index); 1551 ucode_rate_from_rs_rate(mvm, rate);
1550 update_search_tbl_counter = 1; 1552 update_search_tbl_counter = 1;
1551 goto out; 1553 goto out;
1552 default: 1554 default:
@@ -1557,7 +1559,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1557 if (tbl->action == start_action) 1559 if (tbl->action == start_action)
1558 break; 1560 break;
1559 } 1561 }
1560 search_tbl->lq_type = LQ_NONE; 1562 rate->type = LQ_NONE;
1561 return 0; 1563 return 0;
1562 out: 1564 out:
1563 lq_sta->search_better_tbl = 1; 1565 lq_sta->search_better_tbl = 1;
@@ -1657,14 +1659,12 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1657static void rs_update_rate_tbl(struct iwl_mvm *mvm, 1659static void rs_update_rate_tbl(struct iwl_mvm *mvm,
1658 struct ieee80211_sta *sta, 1660 struct ieee80211_sta *sta,
1659 struct iwl_lq_sta *lq_sta, 1661 struct iwl_lq_sta *lq_sta,
1660 struct iwl_scale_tbl_info *tbl, 1662 struct rs_rate *rate)
1661 int index)
1662{ 1663{
1663 u32 rate; 1664 u32 ucode_rate;
1664 1665
1665 /* Update uCode's rate table. */ 1666 ucode_rate = ucode_rate_from_rs_rate(mvm, rate);
1666 rate = rate_n_flags_from_tbl(mvm, tbl, index); 1667 rs_fill_link_cmd(mvm, sta, lq_sta, ucode_rate);
1667 rs_fill_link_cmd(mvm, sta, lq_sta, rate);
1668 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); 1668 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
1669} 1669}
1670 1670
@@ -1716,6 +1716,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1716 u8 prev_agg = lq_sta->is_agg; 1716 u8 prev_agg = lq_sta->is_agg;
1717 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 1717 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
1718 struct iwl_mvm_tid_data *tid_data; 1718 struct iwl_mvm_tid_data *tid_data;
1719 struct rs_rate *rate;
1719 1720
1720 /* Send management frames and NO_ACK data using lowest rate. */ 1721 /* Send management frames and NO_ACK data using lowest rate. */
1721 /* TODO: this could probably be improved.. */ 1722 /* TODO: this could probably be improved.. */
@@ -1748,6 +1749,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1748 active_tbl = 1 - lq_sta->active_tbl; 1749 active_tbl = 1 - lq_sta->active_tbl;
1749 1750
1750 tbl = &(lq_sta->lq_info[active_tbl]); 1751 tbl = &(lq_sta->lq_info[active_tbl]);
1752 rate = &tbl->rate;
1751 1753
1752 if (prev_agg != lq_sta->is_agg) { 1754 if (prev_agg != lq_sta->is_agg) {
1753 IWL_DEBUG_RATE(mvm, 1755 IWL_DEBUG_RATE(mvm,
@@ -1760,10 +1762,10 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1760 index = lq_sta->last_txrate_idx; 1762 index = lq_sta->last_txrate_idx;
1761 1763
1762 /* rates available for this association, and for modulation mode */ 1764 /* rates available for this association, and for modulation mode */
1763 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); 1765 rate_mask = rs_get_supported_rates(lq_sta, hdr, rate);
1764 1766
1765 /* mask with station rate restriction */ 1767 /* mask with station rate restriction */
1766 if (is_legacy(tbl->lq_type)) { 1768 if (is_legacy(rate)) {
1767 if (lq_sta->band == IEEE80211_BAND_5GHZ) 1769 if (lq_sta->band == IEEE80211_BAND_5GHZ)
1768 /* supp_rates has no CCK bits in A mode */ 1770 /* supp_rates has no CCK bits in A mode */
1769 rate_scale_index_msk = (u16) (rate_mask & 1771 rate_scale_index_msk = (u16) (rate_mask &
@@ -1783,12 +1785,13 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1783 IWL_ERR(mvm, "Current Rate is not valid\n"); 1785 IWL_ERR(mvm, "Current Rate is not valid\n");
1784 if (lq_sta->search_better_tbl) { 1786 if (lq_sta->search_better_tbl) {
1785 /* revert to active table if search table is not valid*/ 1787 /* revert to active table if search table is not valid*/
1786 tbl->lq_type = LQ_NONE; 1788 rate->type = LQ_NONE;
1787 lq_sta->search_better_tbl = 0; 1789 lq_sta->search_better_tbl = 0;
1788 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1790 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1789 /* get "active" rate info */ 1791 /* get "active" rate info */
1790 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 1792 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
1791 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index); 1793 tbl->rate.index = index;
1794 rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
1792 } 1795 }
1793 return; 1796 return;
1794 } 1797 }
@@ -1825,7 +1828,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1825 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) { 1828 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
1826 IWL_DEBUG_RATE(mvm, 1829 IWL_DEBUG_RATE(mvm,
1827 "(%s: %d): Test Window: succ %d total %d\n", 1830 "(%s: %d): Test Window: succ %d total %d\n",
1828 rs_pretty_lq_type(tbl->lq_type), 1831 rs_pretty_lq_type(rate->type),
1829 index, window->success_counter, window->counter); 1832 index, window->success_counter, window->counter);
1830 1833
1831 /* Can't calculate this yet; not enough history */ 1834 /* Can't calculate this yet; not enough history */
@@ -1858,7 +1861,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1858 window->average_tpt, 1861 window->average_tpt,
1859 lq_sta->last_tpt); 1862 lq_sta->last_tpt);
1860 1863
1861 if (!is_legacy(tbl->lq_type)) 1864 if (!is_legacy(rate))
1862 lq_sta->enable_counter = 1; 1865 lq_sta->enable_counter = 1;
1863 1866
1864 /* Swap tables; "search" becomes "active" */ 1867 /* Swap tables; "search" becomes "active" */
@@ -1874,7 +1877,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1874 lq_sta->last_tpt); 1877 lq_sta->last_tpt);
1875 1878
1876 /* Nullify "search" table */ 1879 /* Nullify "search" table */
1877 tbl->lq_type = LQ_NONE; 1880 rate->type = LQ_NONE;
1878 1881
1879 /* Revert to "active" table */ 1882 /* Revert to "active" table */
1880 active_tbl = lq_sta->active_tbl; 1883 active_tbl = lq_sta->active_tbl;
@@ -1898,7 +1901,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1898 /* (Else) not in search of better modulation mode, try for better 1901 /* (Else) not in search of better modulation mode, try for better
1899 * starting rate, while staying in this mode. */ 1902 * starting rate, while staying in this mode. */
1900 high_low = rs_get_adjacent_rate(mvm, index, rate_scale_index_msk, 1903 high_low = rs_get_adjacent_rate(mvm, index, rate_scale_index_msk,
1901 tbl->lq_type); 1904 rate->type);
1902 low = high_low & 0xff; 1905 low = high_low & 0xff;
1903 high = (high_low >> 8) & 0xff; 1906 high = (high_low >> 8) & 0xff;
1904 1907
@@ -1918,8 +1921,8 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1918 1921
1919 IWL_DEBUG_RATE(mvm, 1922 IWL_DEBUG_RATE(mvm,
1920 "(%s: %d): cur_tpt %d SR %d low %d high %d low_tpt %d high_tpt %d\n", 1923 "(%s: %d): cur_tpt %d SR %d low %d high %d low_tpt %d high_tpt %d\n",
1921 rs_pretty_lq_type(tbl->lq_type), index, current_tpt, 1924 rs_pretty_lq_type(rate->type), index, current_tpt, sr,
1922 sr, low, high, low_tpt, high_tpt); 1925 low, high, low_tpt, high_tpt);
1923 1926
1924 scale_action = 0; 1927 scale_action = 0;
1925 1928
@@ -2002,7 +2005,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2002 } 2005 }
2003 2006
2004 /* Force a search in case BT doesn't like us being in MIMO */ 2007 /* Force a search in case BT doesn't like us being in MIMO */
2005 if (is_mimo(tbl->lq_type) && 2008 if (is_mimo(rate) &&
2006 !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) { 2009 !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) {
2007 IWL_DEBUG_RATE(mvm, 2010 IWL_DEBUG_RATE(mvm,
2008 "BT Coex forbids MIMO. Search for new config\n"); 2011 "BT Coex forbids MIMO. Search for new config\n");
@@ -2041,8 +2044,10 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2041 2044
2042lq_update: 2045lq_update:
2043 /* Replace uCode's rate table for the destination station. */ 2046 /* Replace uCode's rate table for the destination station. */
2044 if (update_lq) 2047 if (update_lq) {
2045 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index); 2048 tbl->rate.index = index;
2049 rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
2050 }
2046 2051
2047 rs_stay_in_table(lq_sta, false); 2052 rs_stay_in_table(lq_sta, false);
2048 2053
@@ -2063,11 +2068,11 @@ lq_update:
2063 window->counter); 2068 window->counter);
2064 /* Select a new "search" modulation mode to try. 2069 /* Select a new "search" modulation mode to try.
2065 * If one is found, set up the new "search" table. */ 2070 * If one is found, set up the new "search" table. */
2066 if (is_legacy(tbl->lq_type)) 2071 if (is_legacy(&tbl->rate))
2067 rs_move_legacy_other(mvm, lq_sta, sta, index); 2072 rs_move_legacy_other(mvm, lq_sta, sta, index);
2068 else if (is_siso(tbl->lq_type)) 2073 else if (is_siso(&tbl->rate))
2069 rs_move_siso_to_other(mvm, lq_sta, sta, index); 2074 rs_move_siso_to_other(mvm, lq_sta, sta, index);
2070 else if (is_mimo2(tbl->lq_type)) 2075 else if (is_mimo2(&tbl->rate))
2071 rs_move_mimo2_to_other(mvm, lq_sta, sta, index); 2076 rs_move_mimo2_to_other(mvm, lq_sta, sta, index);
2072 else 2077 else
2073 WARN_ON_ONCE(1); 2078 WARN_ON_ONCE(1);
@@ -2086,7 +2091,7 @@ lq_update:
2086 "Switch to SEARCH TABLE: " 2091 "Switch to SEARCH TABLE: "
2087 "mcs %X (%s: %d)\n", 2092 "mcs %X (%s: %d)\n",
2088 tbl->current_rate, 2093 tbl->current_rate,
2089 rs_pretty_lq_type(tbl->lq_type), 2094 rs_pretty_lq_type(tbl->rate.type),
2090 index); 2095 index);
2091 rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate); 2096 rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate);
2092 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); 2097 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
@@ -2102,7 +2107,7 @@ lq_update:
2102 * stay with best antenna legacy modulation for a while 2107 * stay with best antenna legacy modulation for a while
2103 * before next round of mode comparisons. */ 2108 * before next round of mode comparisons. */
2104 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); 2109 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
2105 if (is_legacy(tbl1->lq_type) && !sta->ht_cap.ht_supported && 2110 if (is_legacy(&tbl1->rate) && !sta->ht_cap.ht_supported &&
2106 lq_sta->action_counter > tbl1->max_search) { 2111 lq_sta->action_counter > tbl1->max_search) {
2107 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n"); 2112 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
2108 rs_set_stay_in_table(mvm, 1, lq_sta); 2113 rs_set_stay_in_table(mvm, 1, lq_sta);
@@ -2130,7 +2135,8 @@ lq_update:
2130 } 2135 }
2131 2136
2132out: 2137out:
2133 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index); 2138 tbl->rate.index = index;
2139 tbl->current_rate = ucode_rate_from_rs_rate(mvm, &tbl->rate);
2134 lq_sta->last_txrate_idx = index; 2140 lq_sta->last_txrate_idx = index;
2135} 2141}
2136 2142
@@ -2155,9 +2161,9 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2155 bool init) 2161 bool init)
2156{ 2162{
2157 struct iwl_scale_tbl_info *tbl; 2163 struct iwl_scale_tbl_info *tbl;
2158 int rate_idx; 2164 struct rs_rate *rate;
2159 int i; 2165 int i;
2160 u32 rate; 2166 u32 ucode_rate;
2161 u8 active_tbl = 0; 2167 u8 active_tbl = 0;
2162 u8 valid_tx_ant; 2168 u8 valid_tx_ant;
2163 2169
@@ -2174,25 +2180,26 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2174 active_tbl = 1 - lq_sta->active_tbl; 2180 active_tbl = 1 - lq_sta->active_tbl;
2175 2181
2176 tbl = &(lq_sta->lq_info[active_tbl]); 2182 tbl = &(lq_sta->lq_info[active_tbl]);
2183 rate = &tbl->rate;
2177 2184
2178 if ((i < 0) || (i >= IWL_RATE_COUNT)) 2185 if ((i < 0) || (i >= IWL_RATE_COUNT))
2179 i = 0; 2186 i = 0;
2180 2187
2181 rate = iwl_rates[i].plcp; 2188 ucode_rate = iwl_rates[i].plcp;
2182 tbl->ant_type = first_antenna(valid_tx_ant); 2189 rate->ant = first_antenna(valid_tx_ant);
2183 rate |= tbl->ant_type << RATE_MCS_ANT_POS; 2190 ucode_rate |= rate->ant << RATE_MCS_ANT_POS;
2184 2191
2185 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) 2192 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
2186 rate |= RATE_MCS_CCK_MSK; 2193 ucode_rate |= RATE_MCS_CCK_MSK;
2187 2194
2188 rs_get_tbl_info_from_mcs(rate, band, tbl, &rate_idx); 2195 rs_rate_from_ucode_rate(ucode_rate, band, rate);
2189 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) 2196 if (!rs_is_valid_ant(valid_tx_ant, rate->ant))
2190 rs_toggle_antenna(valid_tx_ant, &rate, tbl); 2197 rs_toggle_antenna(valid_tx_ant, &ucode_rate, rate);
2191 2198
2192 rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx); 2199 ucode_rate = ucode_rate_from_rs_rate(mvm, rate);
2193 tbl->current_rate = rate; 2200 tbl->current_rate = ucode_rate;
2194 rs_set_expected_tpt_table(lq_sta, tbl); 2201 rs_set_expected_tpt_table(lq_sta, tbl);
2195 rs_fill_link_cmd(NULL, NULL, lq_sta, rate); 2202 rs_fill_link_cmd(NULL, NULL, lq_sta, ucode_rate);
2196 /* TODO restore station should remember the lq cmd */ 2203 /* TODO restore station should remember the lq cmd */
2197 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init); 2204 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init);
2198} 2205}
@@ -2435,9 +2442,8 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2435 struct ieee80211_sta *sta, 2442 struct ieee80211_sta *sta,
2436 struct iwl_lq_sta *lq_sta, u32 new_rate) 2443 struct iwl_lq_sta *lq_sta, u32 new_rate)
2437{ 2444{
2438 struct iwl_scale_tbl_info tbl_type; 2445 struct rs_rate rate;
2439 int index = 0; 2446 int index = 0;
2440 int rate_idx;
2441 int repeat_rate = 0; 2447 int repeat_rate = 0;
2442 u8 ant_toggle_cnt = 0; 2448 u8 ant_toggle_cnt = 0;
2443 u8 use_ht_possible = 1; 2449 u8 use_ht_possible = 1;
@@ -2447,12 +2453,10 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2447 /* Override starting rate (index 0) if needed for debug purposes */ 2453 /* Override starting rate (index 0) if needed for debug purposes */
2448 rs_dbgfs_set_mcs(lq_sta, &new_rate); 2454 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2449 2455
2450 /* Interpret new_rate (rate_n_flags) */ 2456 rs_rate_from_ucode_rate(new_rate, lq_sta->band, &rate);
2451 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2452 &tbl_type, &rate_idx);
2453 2457
2454 /* How many times should we repeat the initial rate? */ 2458 /* How many times should we repeat the initial rate? */
2455 if (is_legacy(tbl_type.lq_type)) { 2459 if (is_legacy(&rate)) {
2456 ant_toggle_cnt = 1; 2460 ant_toggle_cnt = 1;
2457 repeat_rate = IWL_NUMBER_TRY; 2461 repeat_rate = IWL_NUMBER_TRY;
2458 } else { 2462 } else {
@@ -2460,15 +2464,15 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2460 LINK_QUAL_AGG_DISABLE_START_DEF - 1); 2464 LINK_QUAL_AGG_DISABLE_START_DEF - 1);
2461 } 2465 }
2462 2466
2463 lq_cmd->mimo_delim = is_mimo(tbl_type.lq_type) ? 1 : 0; 2467 lq_cmd->mimo_delim = is_mimo(&rate) ? 1 : 0;
2464 2468
2465 /* Fill 1st table entry (index 0) */ 2469 /* Fill 1st table entry (index 0) */
2466 lq_cmd->rs_table[index] = cpu_to_le32(new_rate); 2470 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
2467 2471
2468 if (num_of_ant(tbl_type.ant_type) == 1) 2472 if (num_of_ant(rate.ant) == 1)
2469 lq_cmd->single_stream_ant_msk = tbl_type.ant_type; 2473 lq_cmd->single_stream_ant_msk = rate.ant;
2470 else if (num_of_ant(tbl_type.ant_type) == 2) 2474 else if (num_of_ant(rate.ant) == 2)
2471 lq_cmd->dual_stream_ant_msk = tbl_type.ant_type; 2475 lq_cmd->dual_stream_ant_msk = rate.ant;
2472 /* otherwise we don't modify the existing value */ 2476 /* otherwise we don't modify the existing value */
2473 2477
2474 index++; 2478 index++;
@@ -2482,12 +2486,12 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2482 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute. 2486 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
2483 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ 2487 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
2484 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { 2488 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
2485 if (is_legacy(tbl_type.lq_type)) { 2489 if (is_legacy(&rate)) {
2486 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) 2490 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2487 ant_toggle_cnt++; 2491 ant_toggle_cnt++;
2488 else if (mvm && 2492 else if (mvm &&
2489 rs_toggle_antenna(valid_tx_ant, 2493 rs_toggle_antenna(valid_tx_ant,
2490 &new_rate, &tbl_type)) 2494 &new_rate, &rate))
2491 ant_toggle_cnt = 1; 2495 ant_toggle_cnt = 1;
2492 } 2496 }
2493 2497
@@ -2501,26 +2505,25 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2501 index++; 2505 index++;
2502 } 2506 }
2503 2507
2504 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, 2508 rs_rate_from_ucode_rate(new_rate, lq_sta->band, &rate);
2505 &rate_idx);
2506 2509
2507 /* Indicate to uCode which entries might be MIMO. 2510 /* Indicate to uCode which entries might be MIMO.
2508 * If initial rate was MIMO, this will finally end up 2511 * If initial rate was MIMO, this will finally end up
2509 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ 2512 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
2510 if (is_mimo(tbl_type.lq_type)) 2513 if (is_mimo(&rate))
2511 lq_cmd->mimo_delim = index; 2514 lq_cmd->mimo_delim = index;
2512 2515
2513 /* Get next rate */ 2516 /* Get next rate */
2514 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx, 2517 new_rate = rs_get_lower_rate(lq_sta, &rate, rate.index,
2515 use_ht_possible); 2518 use_ht_possible);
2516 2519
2517 /* How many times should we repeat the next rate? */ 2520 /* How many times should we repeat the next rate? */
2518 if (is_legacy(tbl_type.lq_type)) { 2521 if (is_legacy(&rate)) {
2519 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) 2522 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2520 ant_toggle_cnt++; 2523 ant_toggle_cnt++;
2521 else if (mvm && 2524 else if (mvm &&
2522 rs_toggle_antenna(valid_tx_ant, 2525 rs_toggle_antenna(valid_tx_ant,
2523 &new_rate, &tbl_type)) 2526 &new_rate, &rate))
2524 ant_toggle_cnt = 1; 2527 ant_toggle_cnt = 1;
2525 2528
2526 repeat_rate = IWL_NUMBER_TRY; 2529 repeat_rate = IWL_NUMBER_TRY;
@@ -2629,7 +2632,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2629 2632
2630static const char *rs_pretty_lq_type(enum iwl_table_type type) 2633static const char *rs_pretty_lq_type(enum iwl_table_type type)
2631{ 2634{
2632 static const char * const lq_type[] = { 2635 static const char * const lq_types[] = {
2633 [LQ_NONE] = "NONE", 2636 [LQ_NONE] = "NONE",
2634 [LQ_LEGACY_A] = "LEGACY_A", 2637 [LQ_LEGACY_A] = "LEGACY_A",
2635 [LQ_LEGACY_G] = "LEGACY_G", 2638 [LQ_LEGACY_G] = "LEGACY_G",
@@ -2642,10 +2645,10 @@ static const char *rs_pretty_lq_type(enum iwl_table_type type)
2642 if (type < LQ_NONE || type >= LQ_MAX) 2645 if (type < LQ_NONE || type >= LQ_MAX)
2643 return "UNKNOWN"; 2646 return "UNKNOWN";
2644 2647
2645 return lq_type[type]; 2648 return lq_types[type];
2646} 2649}
2647 2650
2648static int rs_pretty_print_rate(char *buf, const u32 rate) 2651static const char *rs_pretty_ant(u8 ant)
2649{ 2652{
2650 static const char * const ant_name[] = { 2653 static const char * const ant_name[] = {
2651 [ANT_NONE] = "None", 2654 [ANT_NONE] = "None",
@@ -2658,6 +2661,15 @@ static int rs_pretty_print_rate(char *buf, const u32 rate)
2658 [ANT_ABC] = "ABC", 2661 [ANT_ABC] = "ABC",
2659 }; 2662 };
2660 2663
2664 if (ant > ANT_ABC)
2665 return "UNKNOWN";
2666
2667 return ant_name[ant];
2668}
2669
2670static int rs_pretty_print_rate(char *buf, const u32 rate)
2671{
2672
2661 char *type, *bw; 2673 char *type, *bw;
2662 u8 mcs = 0, nss = 0; 2674 u8 mcs = 0, nss = 0;
2663 u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS; 2675 u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
@@ -2667,7 +2679,7 @@ static int rs_pretty_print_rate(char *buf, const u32 rate)
2667 int index = iwl_hwrate_to_plcp_idx(rate); 2679 int index = iwl_hwrate_to_plcp_idx(rate);
2668 2680
2669 return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n", 2681 return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n",
2670 ant_name[ant], iwl_rate_mcs[index].mbps); 2682 rs_pretty_ant(ant), iwl_rate_mcs[index].mbps);
2671 } 2683 }
2672 2684
2673 if (rate & RATE_MCS_VHT_MSK) { 2685 if (rate & RATE_MCS_VHT_MSK) {
@@ -2700,7 +2712,7 @@ static int rs_pretty_print_rate(char *buf, const u32 rate)
2700 } 2712 }
2701 2713
2702 return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n", 2714 return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n",
2703 type, ant_name[ant], bw, mcs, nss, 2715 type, rs_pretty_ant(ant), bw, mcs, nss,
2704 (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ", 2716 (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ",
2705 (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", 2717 (rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
2706 (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "", 2718 (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
@@ -2719,7 +2731,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2719 struct iwl_lq_sta *lq_sta = file->private_data; 2731 struct iwl_lq_sta *lq_sta = file->private_data;
2720 struct iwl_mvm *mvm; 2732 struct iwl_mvm *mvm;
2721 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 2733 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2722 2734 struct rs_rate *rate = &tbl->rate;
2723 mvm = lq_sta->drv; 2735 mvm = lq_sta->drv;
2724 buff = kmalloc(2048, GFP_KERNEL); 2736 buff = kmalloc(2048, GFP_KERNEL);
2725 if (!buff) 2737 if (!buff)
@@ -2736,17 +2748,17 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2736 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", 2748 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "",
2737 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); 2749 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : "");
2738 desc += sprintf(buff+desc, "lq type %s\n", 2750 desc += sprintf(buff+desc, "lq type %s\n",
2739 (is_legacy(tbl->lq_type)) ? "legacy" : 2751 (is_legacy(rate)) ? "legacy" :
2740 is_vht(tbl->lq_type) ? "VHT" : "HT"); 2752 is_vht(rate) ? "VHT" : "HT");
2741 if (!is_legacy(tbl->lq_type)) { 2753 if (!is_legacy(rate)) {
2742 desc += sprintf(buff+desc, " %s", 2754 desc += sprintf(buff+desc, " %s",
2743 (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2"); 2755 (is_siso(rate)) ? "SISO" : "MIMO2");
2744 desc += sprintf(buff+desc, " %s", 2756 desc += sprintf(buff+desc, " %s",
2745 (is_ht20(tbl)) ? "20MHz" : 2757 (is_ht20(rate)) ? "20MHz" :
2746 (is_ht40(tbl)) ? "40MHz" : 2758 (is_ht40(rate)) ? "40MHz" :
2747 (is_ht80(tbl)) ? "80Mhz" : "BAD BW"); 2759 (is_ht80(rate)) ? "80Mhz" : "BAD BW");
2748 desc += sprintf(buff+desc, " %s %s\n", 2760 desc += sprintf(buff+desc, " %s %s\n",
2749 (tbl->is_SGI) ? "SGI" : "NGI", 2761 (rate->sgi) ? "SGI" : "NGI",
2750 (lq_sta->is_agg) ? "AGG on" : ""); 2762 (lq_sta->is_agg) ? "AGG on" : "");
2751 } 2763 }
2752 desc += sprintf(buff+desc, "last tx rate=0x%X\n", 2764 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
@@ -2799,6 +2811,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2799 int i, j; 2811 int i, j;
2800 ssize_t ret; 2812 ssize_t ret;
2801 struct iwl_scale_tbl_info *tbl; 2813 struct iwl_scale_tbl_info *tbl;
2814 struct rs_rate *rate;
2802 struct iwl_lq_sta *lq_sta = file->private_data; 2815 struct iwl_lq_sta *lq_sta = file->private_data;
2803 2816
2804 buff = kmalloc(1024, GFP_KERNEL); 2817 buff = kmalloc(1024, GFP_KERNEL);
@@ -2807,15 +2820,16 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2807 2820
2808 for (i = 0; i < LQ_SIZE; i++) { 2821 for (i = 0; i < LQ_SIZE; i++) {
2809 tbl = &(lq_sta->lq_info[i]); 2822 tbl = &(lq_sta->lq_info[i]);
2823 rate = &tbl->rate;
2810 desc += sprintf(buff+desc, 2824 desc += sprintf(buff+desc,
2811 "%s type=%d SGI=%d BW=%s DUP=0\n" 2825 "%s type=%d SGI=%d BW=%s DUP=0\n"
2812 "rate=0x%X\n", 2826 "rate=0x%X\n",
2813 lq_sta->active_tbl == i ? "*" : "x", 2827 lq_sta->active_tbl == i ? "*" : "x",
2814 tbl->lq_type, 2828 rate->type,
2815 tbl->is_SGI, 2829 rate->sgi,
2816 is_ht20(tbl) ? "20Mhz" : 2830 is_ht20(rate) ? "20Mhz" :
2817 is_ht40(tbl) ? "40Mhz" : 2831 is_ht40(rate) ? "40Mhz" :
2818 is_ht80(tbl) ? "80Mhz" : "ERR", 2832 is_ht80(rate) ? "80Mhz" : "ERR",
2819 tbl->current_rate); 2833 tbl->current_rate);
2820 for (j = 0; j < IWL_RATE_COUNT; j++) { 2834 for (j = 0; j < IWL_RATE_COUNT; j++) {
2821 desc += sprintf(buff+desc, 2835 desc += sprintf(buff+desc,
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index ae983bce2172..8fa26aff1339 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -224,22 +224,45 @@ enum iwl_table_type {
224 LQ_MAX, 224 LQ_MAX,
225}; 225};
226 226
227#define is_legacy(tbl) (((tbl) == LQ_LEGACY_G) || ((tbl) == LQ_LEGACY_A)) 227struct rs_rate {
228#define is_ht_siso(tbl) ((tbl) == LQ_HT_SISO) 228 int index;
229#define is_ht_mimo2(tbl) ((tbl) == LQ_HT_MIMO2) 229 enum iwl_table_type type;
230#define is_vht_siso(tbl) ((tbl) == LQ_VHT_SISO) 230 u8 ant;
231#define is_vht_mimo2(tbl) ((tbl) == LQ_VHT_MIMO2) 231 u32 bw;
232#define is_siso(tbl) (is_ht_siso(tbl) || is_vht_siso(tbl)) 232 bool sgi;
233#define is_mimo2(tbl) (is_ht_mimo2(tbl) || is_vht_mimo2(tbl)) 233};
234#define is_mimo(tbl) (is_mimo2(tbl)) 234
235#define is_ht(tbl) (is_ht_siso(tbl) || is_ht_mimo2(tbl)) 235
236#define is_vht(tbl) (is_vht_siso(tbl) || is_vht_mimo2(tbl)) 236#define is_type_legacy(type) (((type) == LQ_LEGACY_G) || \
237#define is_a_band(tbl) ((tbl) == LQ_LEGACY_A) 237 ((type) == LQ_LEGACY_A))
238#define is_g_band(tbl) ((tbl) == LQ_LEGACY_G) 238#define is_type_ht_siso(type) ((type) == LQ_HT_SISO)
239 239#define is_type_ht_mimo2(type) ((type) == LQ_HT_MIMO2)
240#define is_ht20(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_20) 240#define is_type_vht_siso(type) ((type) == LQ_VHT_SISO)
241#define is_ht40(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_40) 241#define is_type_vht_mimo2(type) ((type) == LQ_VHT_MIMO2)
242#define is_ht80(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_80) 242#define is_type_siso(type) (is_type_ht_siso(type) || is_type_vht_siso(type))
243#define is_type_mimo2(type) (is_type_ht_mimo2(type) || is_type_vht_mimo2(type))
244#define is_type_mimo(type) (is_type_mimo2(type))
245#define is_type_ht(type) (is_type_ht_siso(type) || is_type_ht_mimo2(type))
246#define is_type_vht(type) (is_type_vht_siso(type) || is_type_vht_mimo2(type))
247#define is_type_a_band(type) ((type) == LQ_LEGACY_A)
248#define is_type_g_band(type) ((type) == LQ_LEGACY_G)
249
250#define is_legacy(rate) is_type_legacy((rate)->type)
251#define is_ht_siso(rate) is_type_ht_siso((rate)->type)
252#define is_ht_mimo2(rate) is_type_ht_mimo2((rate)->type)
253#define is_vht_siso(rate) is_type_vht_siso((rate)->type)
254#define is_vht_mimo2(rate) is_type_vht_mimo2((rate)->type)
255#define is_siso(rate) is_type_siso((rate)->type)
256#define is_mimo2(rate) is_type_mimo2((rate)->type)
257#define is_mimo(rate) is_type_mimo((rate)->type)
258#define is_ht(rate) is_type_ht((rate)->type)
259#define is_vht(rate) is_type_vht((rate)->type)
260#define is_a_band(rate) is_type_a_band((rate)->type)
261#define is_g_band(rate) is_type_g_band((rate)->type)
262
263#define is_ht20(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_20)
264#define is_ht40(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_40)
265#define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80)
243 266
244#define IWL_MAX_MCS_DISPLAY_SIZE 12 267#define IWL_MAX_MCS_DISPLAY_SIZE 12
245 268
@@ -266,10 +289,7 @@ struct iwl_rate_scale_data {
266 * one for "active", and one for "search". 289 * one for "active", and one for "search".
267 */ 290 */
268struct iwl_scale_tbl_info { 291struct iwl_scale_tbl_info {
269 enum iwl_table_type lq_type; 292 struct rs_rate rate;
270 u8 ant_type;
271 u8 is_SGI; /* 1 = short guard interval */
272 u32 bw; /* channel bandwidth; RATE_MCS_CHAN_WIDTH_XX */
273 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ 293 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
274 u8 max_search; /* maximun number of tables we can search */ 294 u8 max_search; /* maximun number of tables we can search */
275 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ 295 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */