diff options
author | Eyal Shapira <eyal@wizery.com> | 2013-11-22 18:06:36 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2013-12-09 15:29:47 -0500 |
commit | 5aa335537aa27e0d169e98d90d23342434a1cef0 (patch) | |
tree | 694836a7fd512c1d9f5af21a4d767c95564f5356 | |
parent | 0c308e97d40f0e8f43336b6076f4b26e71ba59c6 (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.c | 568 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.h | 60 |
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); |
176 | static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); | 176 | static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); |
177 | static const char *rs_pretty_lq_type(enum iwl_table_type type); | 177 | static const char *rs_pretty_lq_type(enum iwl_table_type type); |
178 | static const char *rs_pretty_ant(u8 ant); | ||
178 | 179 | ||
179 | #ifdef CONFIG_MAC80211_DEBUGFS | 180 | #ifdef CONFIG_MAC80211_DEBUGFS |
180 | static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, | 181 | static 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 | ||
268 | static 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 | |||
267 | static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) | 277 | static 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. | 444 | static 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 */ | ||
437 | static 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, | 498 | static 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) |
493 | static 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 */ |
571 | static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, | 572 | static 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 | */ |
604 | static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta, | 607 | static 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 | ||
675 | static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, | 678 | static 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 | ||
730 | out: | 732 | out: |
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 | 738 | static inline bool rs_rate_match(struct rs_rate *a, |
736 | */ | 739 | struct rs_rate *b) |
737 | static 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 | ||
744 | static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags) | 744 | static 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; |
948 | done: | 941 | done: |
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 | ||
1166 | static void rs_set_bw_from_sta(struct iwl_scale_tbl_info *tbl, | 1160 | static 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 | ||
1177 | static bool rs_sgi_allowed(struct iwl_scale_tbl_info *tbl, | 1170 | static 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 | ||
1371 | out: | 1370 | out: |
@@ -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) | |||
1657 | static void rs_update_rate_tbl(struct iwl_mvm *mvm, | 1659 | static 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 | ||
2042 | lq_update: | 2045 | lq_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 | ||
2132 | out: | 2137 | out: |
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 | ||
2630 | static const char *rs_pretty_lq_type(enum iwl_table_type type) | 2633 | static 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 | ||
2648 | static int rs_pretty_print_rate(char *buf, const u32 rate) | 2651 | static 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 | |||
2670 | static 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)) | 227 | struct 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 | */ |
268 | struct iwl_scale_tbl_info { | 291 | struct 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. */ |