Lines Matching full:rate

72  *   rate, ht rate, prev rate, next rate
74 * If there isn't a valid next or previous rate then INV is used which
116 struct rs_rate *rate,
128 struct rs_rate *rate, in rs_ant_allow() argument
135 struct rs_rate *rate, in rs_mimo_allow() argument
157 struct rs_rate *rate, in rs_siso_allow() argument
167 struct rs_rate *rate, in rs_sgi_allow() argument
173 if (is_ht20(rate) && (ht_cap->cap & in rs_sgi_allow()
176 if (is_ht40(rate) && (ht_cap->cap & in rs_sgi_allow()
179 if (is_ht80(rate) && (vht_cap->cap & in rs_sgi_allow()
182 if (is_ht160(rate) && (vht_cap->cap & in rs_sgi_allow()
363 /* legacy rate format, search for match in table */ in iwl_hwrate_to_plcp_idx()
477 static char *rs_pretty_rate(const struct rs_rate *rate) in rs_pretty_rate() argument
508 if (is_type_legacy(rate->type) && (rate->index <= IWL_RATE_54M_INDEX)) in rs_pretty_rate()
509 rate_str = legacy_rates[rate->index]; in rs_pretty_rate()
510 else if ((is_type_ht(rate->type) || is_type_vht(rate->type)) && in rs_pretty_rate()
511 (rate->index >= IWL_RATE_MCS_0_INDEX) && in rs_pretty_rate()
512 (rate->index <= IWL_RATE_MCS_9_INDEX)) in rs_pretty_rate()
513 rate_str = ht_vht_rates[rate->index]; in rs_pretty_rate()
517 sprintf(buf, "(%s|%s|%s)", rs_pretty_lq_type(rate->type), in rs_pretty_rate()
518 iwl_rs_pretty_ant(rate->ant), rate_str ?: "BAD_RATE"); in rs_pretty_rate()
522 static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, in rs_dump_rate() argument
527 prefix, rs_pretty_rate(rate), rate->bw, in rs_dump_rate()
528 rate->sgi, rate->ldpc, rate->stbc); in rs_dump_rate()
632 * at this rate. window->data contains the bitmask of successful
647 * Keep track of only the latest 62 tx frame attempts in this rate's in _rs_collect_tx_data()
765 /* Select window for current tx bit rate */ in rs_collect_tlc_data()
771 /* Convert rs_rate object into ucode rate bitmask */
773 struct rs_rate *rate) in ucode_rate_from_rs_rate() argument
776 int index = rate->index; in ucode_rate_from_rs_rate()
778 ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) & in ucode_rate_from_rs_rate()
781 if (is_legacy(rate)) { in ucode_rate_from_rs_rate()
794 if (is_ht(rate)) { in ucode_rate_from_rs_rate()
796 IWL_ERR(mvm, "Invalid HT rate index %d\n", index); in ucode_rate_from_rs_rate()
801 if (is_ht_siso(rate)) in ucode_rate_from_rs_rate()
803 else if (is_ht_mimo2(rate)) in ucode_rate_from_rs_rate()
807 } else if (is_vht(rate)) { in ucode_rate_from_rs_rate()
809 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); in ucode_rate_from_rs_rate()
813 if (is_vht_siso(rate)) in ucode_rate_from_rs_rate()
815 else if (is_vht_mimo2(rate)) in ucode_rate_from_rs_rate()
821 IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type); in ucode_rate_from_rs_rate()
824 if (is_siso(rate) && rate->stbc) { in ucode_rate_from_rs_rate()
830 ucode_rate |= rate->bw; in ucode_rate_from_rs_rate()
831 if (rate->sgi) in ucode_rate_from_rs_rate()
833 if (rate->ldpc) in ucode_rate_from_rs_rate()
839 /* Convert a ucode rate into an rs_rate object */
842 struct rs_rate *rate) in rs_rate_from_ucode_rate() argument
848 memset(rate, 0, sizeof(*rate)); in rs_rate_from_ucode_rate()
849 rate->index = iwl_hwrate_to_plcp_idx(ucode_rate); in rs_rate_from_ucode_rate()
851 if (rate->index == IWL_RATE_INVALID) in rs_rate_from_ucode_rate()
854 rate->ant = (ant_msk >> RATE_MCS_ANT_POS); in rs_rate_from_ucode_rate()
862 rate->type = LQ_LEGACY_A; in rs_rate_from_ucode_rate()
864 rate->type = LQ_LEGACY_G; in rs_rate_from_ucode_rate()
872 rate->sgi = true; in rs_rate_from_ucode_rate()
874 rate->ldpc = true; in rs_rate_from_ucode_rate()
876 rate->stbc = true; in rs_rate_from_ucode_rate()
878 rate->bfer = true; in rs_rate_from_ucode_rate()
880 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK_V1; in rs_rate_from_ucode_rate()
887 rate->type = LQ_HT_SISO; in rs_rate_from_ucode_rate()
888 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1, in rs_rate_from_ucode_rate()
890 rate->stbc, rate->bfer); in rs_rate_from_ucode_rate()
892 rate->type = LQ_HT_MIMO2; in rs_rate_from_ucode_rate()
901 rate->type = LQ_VHT_SISO; in rs_rate_from_ucode_rate()
902 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1, in rs_rate_from_ucode_rate()
904 rate->stbc, rate->bfer); in rs_rate_from_ucode_rate()
906 rate->type = LQ_VHT_MIMO2; in rs_rate_from_ucode_rate()
915 rate->type = LQ_HE_SISO; in rs_rate_from_ucode_rate()
916 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1, in rs_rate_from_ucode_rate()
917 "stbc %d bfer %d", rate->stbc, rate->bfer); in rs_rate_from_ucode_rate()
919 rate->type = LQ_HE_MIMO2; in rs_rate_from_ucode_rate()
926 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 && in rs_rate_from_ucode_rate()
927 !is_he(rate) && !is_vht(rate)); in rs_rate_from_ucode_rate()
934 static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate) in rs_toggle_antenna() argument
938 if (!rs_is_valid_ant(valid_ant, rate->ant)) in rs_toggle_antenna()
941 new_ant_type = ant_toggle_lookup[rate->ant]; in rs_toggle_antenna()
943 while ((new_ant_type != rate->ant) && in rs_toggle_antenna()
947 if (new_ant_type == rate->ant) in rs_toggle_antenna()
950 rate->ant = new_ant_type; in rs_toggle_antenna()
956 struct rs_rate *rate) in rs_get_supported_rates() argument
958 if (is_legacy(rate)) in rs_get_supported_rates()
960 else if (is_siso(rate)) in rs_get_supported_rates()
962 else if (is_mimo2(rate)) in rs_get_supported_rates()
975 /* 802.11A or ht walks to the next literal adjacent rate in in rs_get_adjacent_rate()
976 * the rate table */ in rs_get_adjacent_rate()
981 /* Find the previous rate that is in the rate mask */ in rs_get_adjacent_rate()
992 /* Find the next rate that is in the rate mask */ in rs_get_adjacent_rate()
1026 struct rs_rate *rate) in rs_rate_supported() argument
1028 return BIT(rate->index) & rs_get_supported_rates(lq_sta, rate); in rs_rate_supported()
1031 /* Get the next supported lower rate in the current column.
1032 * Return true if bottom rate in the current column was reached
1035 struct rs_rate *rate) in rs_get_lower_rate_in_column() argument
1042 rate_mask = rs_get_supported_rates(lq_sta, rate); in rs_get_lower_rate_in_column()
1043 high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask, in rs_get_lower_rate_in_column()
1044 rate->type); in rs_get_lower_rate_in_column()
1047 /* Bottom rate of column reached */ in rs_get_lower_rate_in_column()
1051 rate->index = low; in rs_get_lower_rate_in_column()
1055 /* Get the next rate to use following a column downgrade */
1057 struct rs_rate *rate) in rs_get_lower_rate_down_column() argument
1061 if (is_legacy(rate)) { in rs_get_lower_rate_down_column()
1064 } else if (is_siso(rate)) { in rs_get_lower_rate_down_column()
1067 rate->type = LQ_LEGACY_A; in rs_get_lower_rate_down_column()
1069 rate->type = LQ_LEGACY_G; in rs_get_lower_rate_down_column()
1071 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_get_lower_rate_down_column()
1073 if (WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX)) in rs_get_lower_rate_down_column()
1074 rate->index = rs_ht_to_legacy[IWL_RATE_MCS_0_INDEX]; in rs_get_lower_rate_down_column()
1075 else if (WARN_ON_ONCE(rate->index > IWL_RATE_MCS_9_INDEX)) in rs_get_lower_rate_down_column()
1076 rate->index = rs_ht_to_legacy[IWL_RATE_MCS_9_INDEX]; in rs_get_lower_rate_down_column()
1078 rate->index = rs_ht_to_legacy[rate->index]; in rs_get_lower_rate_down_column()
1080 rate->ldpc = false; in rs_get_lower_rate_down_column()
1083 rate->type = is_vht_mimo2(rate) ? in rs_get_lower_rate_down_column()
1087 if (num_of_ant(rate->ant) > 1) in rs_get_lower_rate_down_column()
1088 rate->ant = first_antenna(iwl_mvm_get_valid_tx_ant(mvm)); in rs_get_lower_rate_down_column()
1091 rate->sgi = false; in rs_get_lower_rate_down_column()
1093 if (!rs_rate_supported(lq_sta, rate)) in rs_get_lower_rate_down_column()
1094 rs_get_lower_rate_in_column(lq_sta, rate); in rs_get_lower_rate_down_column()
1112 static inline enum rs_column rs_get_column_from_rate(struct rs_rate *rate) in rs_get_column_from_rate() argument
1114 if (is_legacy(rate)) { in rs_get_column_from_rate()
1115 if (rate->ant == ANT_A) in rs_get_column_from_rate()
1118 if (rate->ant == ANT_B) in rs_get_column_from_rate()
1124 if (is_siso(rate)) { in rs_get_column_from_rate()
1125 if (rate->ant == ANT_A || rate->stbc || rate->bfer) in rs_get_column_from_rate()
1126 return rate->sgi ? RS_COLUMN_SISO_ANT_A_SGI : in rs_get_column_from_rate()
1129 if (rate->ant == ANT_B) in rs_get_column_from_rate()
1130 return rate->sgi ? RS_COLUMN_SISO_ANT_B_SGI : in rs_get_column_from_rate()
1136 if (is_mimo(rate)) in rs_get_column_from_rate()
1137 return rate->sgi ? RS_COLUMN_MIMO2_SGI : RS_COLUMN_MIMO2; in rs_get_column_from_rate()
1307 struct rs_rate *rate = &tbl->rate; in rs_set_expected_tpt_table() local
1310 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw); in rs_set_expected_tpt_table()
1342 "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n", in rs_get_best_rate()
1347 "SR %d not that good. Find rate exceeding ACTUAL_TPT %d\n", in rs_get_best_rate()
1358 tbl->rate.type); in rs_get_best_rate()
1363 IWL_DEBUG_RATE(mvm, "Best rate found %d target_tp %d expected_new %d\n", in rs_get_best_rate()
1464 * history bitmaps and rate-specific stats for all rates in in rs_stay_in_table()
1503 if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || in rs_set_amsdu_len()
1504 tbl->rate.index < IWL_RATE_MCS_5_INDEX || in rs_set_amsdu_len()
1533 * setup rate table in uCode
1540 rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate); in rs_update_rate_tbl()
1553 if (!is_vht_siso(&tbl->rate)) in rs_tweak_rate_tbl()
1556 if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_80) && in rs_tweak_rate_tbl()
1557 (tbl->rate.index == IWL_RATE_MCS_0_INDEX) && in rs_tweak_rate_tbl()
1559 tbl->rate.bw = RATE_MCS_CHAN_WIDTH_20; in rs_tweak_rate_tbl()
1560 tbl->rate.index = IWL_RATE_MCS_4_INDEX; in rs_tweak_rate_tbl()
1568 * to 20Mhz MCS4 because the rate stats are cleared. in rs_tweak_rate_tbl()
1570 if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_20) && in rs_tweak_rate_tbl()
1571 (((tbl->rate.index == IWL_RATE_MCS_5_INDEX) && in rs_tweak_rate_tbl()
1573 ((tbl->rate.index > IWL_RATE_MCS_5_INDEX) && in rs_tweak_rate_tbl()
1575 tbl->rate.bw = RATE_MCS_CHAN_WIDTH_80; in rs_tweak_rate_tbl()
1576 tbl->rate.index = IWL_RATE_MCS_1_INDEX; in rs_tweak_rate_tbl()
1626 if (allow_func && !allow_func(mvm, sta, &tbl->rate, in rs_get_next_column()
1648 "Skip column %d: no rate is allowed in this column\n", in rs_get_next_column()
1681 struct rs_rate *rate = &search_tbl->rate; in rs_switch_to_column() local
1689 rate->sgi = column->sgi; in rs_switch_to_column()
1690 rate->ant = column->ant; in rs_switch_to_column()
1694 rate->type = LQ_LEGACY_A; in rs_switch_to_column()
1696 rate->type = LQ_LEGACY_G; in rs_switch_to_column()
1698 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_switch_to_column()
1699 rate->ldpc = false; in rs_switch_to_column()
1702 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; in rs_switch_to_column()
1705 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; in rs_switch_to_column()
1712 rate->bw = rs_bw_from_sta_bw(sta); in rs_switch_to_column()
1713 rate->ldpc = lq_sta->ldpc; in rs_switch_to_column()
1721 /* Get the best matching rate if we're changing modes. e.g. in rs_switch_to_column()
1726 rate_mask, rate->index); in rs_switch_to_column()
1732 " rate mask %lx\n", in rs_switch_to_column()
1738 rate->index = rate_idx; in rs_switch_to_column()
1742 col_id, rate->index); in rs_switch_to_column()
1747 rate->type = LQ_NONE; in rs_switch_to_column()
1762 "Decrease rate because of low SR\n"); in rs_get_rate_action()
1770 "No data about high/low rates. Increase rate\n"); in rs_get_rate_action()
1779 "No data about high rate and low rate is worse. Increase rate\n"); in rs_get_rate_action()
1786 "Higher rate is better. Increate rate\n"); in rs_get_rate_action()
1795 "Both high and low are worse. Maintain rate\n"); in rs_get_rate_action()
1802 "Lower rate is better\n"); in rs_get_rate_action()
1810 "No data about lower rate\n"); in rs_get_rate_action()
1815 IWL_DEBUG_RATE(mvm, "Maintain rate\n"); in rs_get_rate_action()
1825 "Current TPT is higher than max expected in low rate. Avoid downscale\n"); in rs_get_rate_action()
1828 IWL_DEBUG_RATE(mvm, "Decrease rate\n"); in rs_get_rate_action()
1863 struct rs_rate *rate, enum nl80211_band band) in rs_tpc_allowed() argument
1865 int index = rate->index; in rs_tpc_allowed()
1880 IWL_DEBUG_RATE(mvm, "check rate, table type: %d\n", rate->type); in rs_tpc_allowed()
1881 if (is_legacy(rate)) in rs_tpc_allowed()
1883 if (is_ht(rate)) in rs_tpc_allowed()
1885 if (is_vht(rate)) in rs_tpc_allowed()
1969 struct rs_rate *rate = &tbl->rate; in rs_tpc_perform() local
1994 if (!rs_tpc_allowed(mvm, vif, rate, band)) { in rs_tpc_perform()
2049 * Do rate scaling and search for new modulation mode.
2074 struct rs_rate *rate; in rs_rate_scale_perform() local
2079 * Select rate-scale / modulation-mode table to work with in in rs_rate_scale_perform()
2081 * modulation mode, or "active" if doing rate scaling within a mode. in rs_rate_scale_perform()
2089 rate = &tbl->rate; in rs_rate_scale_perform()
2099 /* current tx rate */ in rs_rate_scale_perform()
2100 index = rate->index; in rs_rate_scale_perform()
2103 rate_mask = rs_get_supported_rates(lq_sta, rate); in rs_rate_scale_perform()
2106 IWL_ERR(mvm, "Current Rate is not valid\n"); in rs_rate_scale_perform()
2109 rate->type = LQ_NONE; in rs_rate_scale_perform()
2117 /* Get expected throughput table and history window for current rate */ in rs_rate_scale_perform()
2129 * changing rate or mode (bypass most of the rest of this function). in rs_rate_scale_perform()
2130 * Set up new rate table in uCode only if old rate is not supported in rs_rate_scale_perform()
2131 * in current association (use new rate found above). in rs_rate_scale_perform()
2138 rs_pretty_rate(rate), in rs_rate_scale_perform()
2177 rate->type = LQ_NONE; in rs_rate_scale_perform()
2183 /* Revert to "active" rate and throughput info */ in rs_rate_scale_perform()
2184 index = tbl->rate.index; in rs_rate_scale_perform()
2187 /* Need to set up a new rate table in uCode */ in rs_rate_scale_perform()
2192 * search is done, allow rate adjustment next time. */ in rs_rate_scale_perform()
2199 * starting rate, while staying in this mode. */ in rs_rate_scale_perform()
2200 high_low = rs_get_adjacent_rate(mvm, index, rate_mask, rate->type); in rs_rate_scale_perform()
2217 rs_pretty_rate(rate), current_tpt, sr, in rs_rate_scale_perform()
2224 if (is_mimo(rate) && in rs_rate_scale_perform()
2234 /* Decrease starting rate, update uCode's rate table */ in rs_rate_scale_perform()
2240 "At the bottom rate. Can't decrease\n"); in rs_rate_scale_perform()
2245 /* Increase starting rate, update uCode's rate table */ in rs_rate_scale_perform()
2251 "At the top rate. Can't increase\n"); in rs_rate_scale_perform()
2265 /* Replace uCode's rate table for the destination station. */ in rs_rate_scale_perform()
2267 tbl->rate.index = index; in rs_rate_scale_perform()
2313 /* Use new "search" start rate */ in rs_rate_scale_perform()
2314 index = tbl->rate.index; in rs_rate_scale_perform()
2316 rs_dump_rate(mvm, &tbl->rate, in rs_rate_scale_perform()
2329 rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_sta); in rs_rate_scale_perform()
2403 /* Init the optimal rate based on STA caps
2404 * This combined with rssi is used to report the last tx rate
2411 struct rs_rate *rate = &lq_sta->optimal_rate; in rs_init_optimal_rate() local
2414 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; in rs_init_optimal_rate()
2416 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; in rs_init_optimal_rate()
2418 rate->type = LQ_LEGACY_A; in rs_init_optimal_rate()
2420 rate->type = LQ_LEGACY_G; in rs_init_optimal_rate()
2422 rate->bw = rs_bw_from_sta_bw(sta); in rs_init_optimal_rate()
2423 rate->sgi = rs_sgi_allow(mvm, sta, rate, NULL); in rs_init_optimal_rate()
2425 /* ANT/LDPC/STBC aren't relevant for the rate reported to userspace */ in rs_init_optimal_rate()
2427 if (is_mimo(rate)) { in rs_init_optimal_rate()
2429 } else if (is_siso(rate)) { in rs_init_optimal_rate()
2445 if (is_vht(rate)) { in rs_init_optimal_rate()
2446 if (rate->bw == RATE_MCS_CHAN_WIDTH_20) { in rs_init_optimal_rate()
2455 } else if (is_ht(rate)) { in rs_init_optimal_rate()
2461 /* Compute the optimal rate index based on RSSI */
2465 struct rs_rate *rate = &lq_sta->optimal_rate; in rs_get_optimal_rate() local
2468 rate->index = find_first_bit(&lq_sta->optimal_rate_mask, in rs_get_optimal_rate()
2476 rate->index = rate_idx; in rs_get_optimal_rate()
2481 return rate; in rs_get_optimal_rate()
2484 /* Choose an initial legacy rate and antenna to use based on the RSSI
2491 struct rs_rate *rate) in rs_get_initial_rate() argument
2515 rate->ant = first_antenna(valid_tx_ant); in rs_get_initial_rate()
2517 rate->ant = best_ant; in rs_get_initial_rate()
2519 rate->sgi = false; in rs_get_initial_rate()
2520 rate->ldpc = false; in rs_get_initial_rate()
2521 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_get_initial_rate()
2523 rate->index = find_first_bit(&lq_sta->active_legacy_rate, in rs_get_initial_rate()
2527 rate->type = LQ_LEGACY_A; in rs_get_initial_rate()
2531 rate->type = LQ_LEGACY_G; in rs_get_initial_rate()
2539 /* Start from a higher rate if the corresponding debug capability in rs_get_initial_rate()
2540 * is enabled. The rate is chosen according to AP capabilities. in rs_get_initial_rate()
2552 * bandwidth rate, and after authorization, when the phy context in rs_get_initial_rate()
2576 rate->type = LQ_VHT_SISO; in rs_get_initial_rate()
2577 rate->bw = bw; in rs_get_initial_rate()
2583 rate->type = LQ_HT_SISO; in rs_get_initial_rate()
2593 rate->index = rate_idx; in rs_get_initial_rate()
2599 rs_dump_rate(mvm, rate, "INITIAL"); in rs_get_initial_rate()
2625 * rs_initialize_lq - Initialize a station's hardware rate table
2631 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
2644 struct rs_rate *rate; in rs_initialize_lq() local
2656 rate = &tbl->rate; in rs_initialize_lq()
2658 rs_get_initial_rate(mvm, sta, lq_sta, band, rate); in rs_initialize_lq()
2661 WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B, in rs_initialize_lq()
2663 rate->ant, lq_sta->pers.chains, mvm->fw->valid_tx_ant, in rs_initialize_lq()
2666 tbl->column = rs_get_column_from_rate(rate); in rs_initialize_lq()
2669 rs_fill_lq_cmd(mvm, sta, lq_sta, rate); in rs_initialize_lq()
2703 /* Report the optimal rate based on rssi and STA caps if we haven't in rs_drv_get_rate()
2724 IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); in rs_drv_alloc_sta()
2860 void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) in iwl_mvm_update_frame_stats() argument
2871 switch (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) { in iwl_mvm_update_frame_stats()
2885 WARN_ONCE(1, "bad BW. rate 0x%x", rate); in iwl_mvm_update_frame_stats()
2888 if (rate & RATE_MCS_HT_MSK_V1) { in iwl_mvm_update_frame_stats()
2890 nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) >> RATE_HT_MCS_NSS_POS_V1) + 1; in iwl_mvm_update_frame_stats()
2891 } else if (rate & RATE_MCS_VHT_MSK_V1) { in iwl_mvm_update_frame_stats()
2893 nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; in iwl_mvm_update_frame_stats()
2903 if (rate & RATE_MCS_SGI_MSK_V1) in iwl_mvm_update_frame_stats()
2908 mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate; in iwl_mvm_update_frame_stats()
2918 * Called after adding a new station to initialize rate scaling
2950 "LQ: *** rate scale station global init for station %d ***\n", in rs_drv_rate_init()
2952 /* TODO: what is a good starting rate for STA? About middle? Maybe not in rs_drv_rate_init()
2953 * the lowest or the highest rate.. Could consider using RSSI from in rs_drv_rate_init()
2987 IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", in rs_drv_rate_init()
3049 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n"); in __iwl_mvm_rs_tx_status()
3065 /* Disable last tx check if we are debugging with fixed rate but in __iwl_mvm_rs_tx_status()
3075 "Can't map rate 0x%x to column", in __iwl_mvm_rs_tx_status()
3090 IWL_DEBUG_RATE(mvm, "Fixed rate 0x%x success %d attempts %d\n", in __iwl_mvm_rs_tx_status()
3108 /* Ignore this Tx frame response if its initial rate doesn't match in __iwl_mvm_rs_tx_status()
3122 /* Here we actually compare this rate to the latest LQ command */ in __iwl_mvm_rs_tx_status()
3140 /* Regardless, ignore this status info for outdated rate */ in __iwl_mvm_rs_tx_status()
3144 /* Rate did match, so reset the missed_rate_counter */ in __iwl_mvm_rs_tx_status()
3155 if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) { in __iwl_mvm_rs_tx_status()
3157 "Neither active nor search matches tx rate\n"); in __iwl_mvm_rs_tx_status()
3159 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE"); in __iwl_mvm_rs_tx_status()
3161 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH"); in __iwl_mvm_rs_tx_status()
3165 * and continue to perform rate scale to find the rate table in __iwl_mvm_rs_tx_status()
3174 * For aggregation, all packets were transmitted at the same rate, the in __iwl_mvm_rs_tx_status()
3175 * first index into rate scale table. in __iwl_mvm_rs_tx_status()
3190 * zero power reduction. When FW transmits agg with a rate in __iwl_mvm_rs_tx_status()
3191 * different from the initial rate, it will not use reduced txp in __iwl_mvm_rs_tx_status()
3218 /* Collect data for each rate used during failed TX attempts */ in __iwl_mvm_rs_tx_status()
3227 /* Only collect stats if retried rate is in the same RS in __iwl_mvm_rs_tx_status()
3230 if (rs_rate_column_match(&lq_rate, &curr_tbl->rate)) in __iwl_mvm_rs_tx_status()
3233 &other_tbl->rate)) in __iwl_mvm_rs_tx_status()
3253 /* The last TX rate is cached in lq_sta; it's set in if/else above */ in __iwl_mvm_rs_tx_status()
3257 /* See if there's a better rate or modulation mode to try. */ in __iwl_mvm_rs_tx_status()
3283 struct rs_rate rate; in rs_build_rates_table_from_fixed() local
3292 if (rs_rate_from_ucode_rate(ucode_rate, band, &rate)) { in rs_build_rates_table_from_fixed()
3297 if (is_mimo(&rate)) in rs_build_rates_table_from_fixed()
3317 struct rs_rate *rate, in rs_fill_rates_for_column() argument
3325 int prev_rate_idx = rate->index; in rs_fill_rates_for_column()
3332 rate)); in rs_fill_rates_for_column()
3335 rs_toggle_antenna(valid_tx_ant, rate); in rs_fill_rates_for_column()
3338 prev_rate_idx = rate->index; in rs_fill_rates_for_column()
3339 bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate); in rs_fill_rates_for_column()
3340 if (bottom_reached && !is_legacy(rate)) in rs_fill_rates_for_column()
3344 if (!bottom_reached && !is_legacy(rate)) in rs_fill_rates_for_column()
3345 rate->index = prev_rate_idx; in rs_fill_rates_for_column()
3350 /* Building the rate table is non trivial. When we're in MIMO2/VHT/80Mhz/SGI
3351 * column the rate table should look like this:
3353 * rate[0] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
3354 * rate[1] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
3355 * rate[2] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
3356 * rate[3] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
3357 * rate[4] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
3358 * rate[5] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
3359 * rate[6] 0x4005007 VHT | ANT: A BW: 80Mhz MCS: 7 NSS: 1 NGI
3360 * rate[7] 0x4009006 VHT | ANT: B BW: 80Mhz MCS: 6 NSS: 1 NGI
3361 * rate[8] 0x4005005 VHT | ANT: A BW: 80Mhz MCS: 5 NSS: 1 NGI
3362 * rate[9] 0x800B Legacy | ANT: B Rate: 36 Mbps
3363 * rate[10] 0x4009 Legacy | ANT: A Rate: 24 Mbps
3364 * rate[11] 0x8007 Legacy | ANT: B Rate: 18 Mbps
3365 * rate[12] 0x4005 Legacy | ANT: A Rate: 12 Mbps
3366 * rate[13] 0x800F Legacy | ANT: B Rate: 9 Mbps
3367 * rate[14] 0x400D Legacy | ANT: A Rate: 6 Mbps
3368 * rate[15] 0x800D Legacy | ANT: B Rate: 6 Mbps
3375 struct rs_rate rate; in rs_build_rates_table() local
3382 memcpy(&rate, initial_rate, sizeof(rate)); in rs_build_rates_table()
3389 rate.stbc = true; in rs_build_rates_table()
3391 if (is_siso(&rate)) { in rs_build_rates_table()
3394 } else if (is_mimo(&rate)) { in rs_build_rates_table()
3403 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3407 rs_get_lower_rate_down_column(lq_sta, &rate); in rs_build_rates_table()
3409 if (is_siso(&rate)) { in rs_build_rates_table()
3413 } else if (is_legacy(&rate)) { in rs_build_rates_table()
3422 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3426 rs_get_lower_rate_down_column(lq_sta, &rate); in rs_build_rates_table()
3431 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3638 /* rate scale requires free function to be implemented */
3653 int rs_pretty_print_rate_v1(char *buf, int bufsz, const u32 rate) in rs_pretty_print_rate_v1() argument
3658 u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; in rs_pretty_print_rate_v1()
3659 u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) >> in rs_pretty_print_rate_v1()
3662 if (!(rate & RATE_MCS_HT_MSK_V1) && in rs_pretty_print_rate_v1()
3663 !(rate & RATE_MCS_VHT_MSK_V1) && in rs_pretty_print_rate_v1()
3664 !(rate & RATE_MCS_HE_MSK_V1)) { in rs_pretty_print_rate_v1()
3665 int index = iwl_hwrate_to_plcp_idx(rate); in rs_pretty_print_rate_v1()
3667 return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps", in rs_pretty_print_rate_v1()
3673 if (rate & RATE_MCS_VHT_MSK_V1) { in rs_pretty_print_rate_v1()
3675 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; in rs_pretty_print_rate_v1()
3676 nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; in rs_pretty_print_rate_v1()
3677 } else if (rate & RATE_MCS_HT_MSK_V1) { in rs_pretty_print_rate_v1()
3679 mcs = rate & RATE_HT_MCS_INDEX_MSK_V1; in rs_pretty_print_rate_v1()
3680 nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) in rs_pretty_print_rate_v1()
3682 } else if (rate & RATE_MCS_HE_MSK_V1) { in rs_pretty_print_rate_v1()
3684 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; in rs_pretty_print_rate_v1()
3685 nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; in rs_pretty_print_rate_v1()
3692 rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss, in rs_pretty_print_rate_v1()
3693 (rate & RATE_MCS_SGI_MSK_V1) ? "SGI " : "NGI ", in rs_pretty_print_rate_v1()
3694 (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", in rs_pretty_print_rate_v1()
3695 (rate & RATE_MCS_LDPC_MSK_V1) ? "LDPC " : "", in rs_pretty_print_rate_v1()
3696 (rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "", in rs_pretty_print_rate_v1()
3697 (rate & RATE_MCS_BF_MSK) ? "BF " : ""); in rs_pretty_print_rate_v1()
3702 * Program the device to use fixed rate for frame transmit
3704 * once the device start use fixed rate, we need to reload the module
3714 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n", in rs_program_fix_rate()
3762 struct rs_rate *rate = &tbl->rate; in rs_sta_dbgfs_scale_table_read() local
3773 "failed=%d success=%d rate=0%lX\n", in rs_sta_dbgfs_scale_table_read()
3776 desc += scnprintf(buff + desc, bufsz - desc, "fixed rate 0x%X\n", in rs_sta_dbgfs_scale_table_read()
3782 (is_legacy(rate)) ? "legacy" : in rs_sta_dbgfs_scale_table_read()
3783 is_vht(rate) ? "VHT" : "HT"); in rs_sta_dbgfs_scale_table_read()
3784 if (!is_legacy(rate)) { in rs_sta_dbgfs_scale_table_read()
3786 (is_siso(rate)) ? "SISO" : "MIMO2"); in rs_sta_dbgfs_scale_table_read()
3788 (is_ht20(rate)) ? "20MHz" : in rs_sta_dbgfs_scale_table_read()
3789 (is_ht40(rate)) ? "40MHz" : in rs_sta_dbgfs_scale_table_read()
3790 (is_ht80(rate)) ? "80MHz" : in rs_sta_dbgfs_scale_table_read()
3791 (is_ht160(rate)) ? "160MHz" : "BAD BW"); in rs_sta_dbgfs_scale_table_read()
3793 (rate->sgi) ? "SGI" : "NGI", in rs_sta_dbgfs_scale_table_read()
3794 (rate->ldpc) ? "LDPC" : "BCC", in rs_sta_dbgfs_scale_table_read()
3798 desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X\n", in rs_sta_dbgfs_scale_table_read()
3837 " rate[%d] 0x%X ", i, r); in rs_sta_dbgfs_scale_table_read()
3862 struct rs_rate *rate; in rs_sta_dbgfs_stats_table_read() local
3871 rate = &tbl->rate; in rs_sta_dbgfs_stats_table_read()
3876 rate->type, in rs_sta_dbgfs_stats_table_read()
3877 rate->sgi, in rs_sta_dbgfs_stats_table_read()
3878 is_ht20(rate) ? "20MHz" : in rs_sta_dbgfs_stats_table_read()
3879 is_ht40(rate) ? "40MHz" : in rs_sta_dbgfs_stats_table_read()
3880 is_ht80(rate) ? "80MHz" : in rs_sta_dbgfs_stats_table_read()
3881 is_ht160(rate) ? "160MHz" : "ERR", in rs_sta_dbgfs_stats_table_read()
3882 rate->index); in rs_sta_dbgfs_stats_table_read()
3938 int col, rate; in rs_sta_dbgfs_drv_tx_stats_read() local
3952 for (rate = 0; rate < IWL_RATE_COUNT; rate++) in rs_sta_dbgfs_drv_tx_stats_read()
3953 pos += scnprintf(pos, endpos - pos, "%s,", rate_name[rate]); in rs_sta_dbgfs_drv_tx_stats_read()
3960 for (rate = 0; rate < IWL_RATE_COUNT; rate++) { in rs_sta_dbgfs_drv_tx_stats_read()
3961 stats = &(lq_sta->pers.tx_stats[col][rate]); in rs_sta_dbgfs_drv_tx_stats_read()
4082 * Initialization of rate scaling information is done by driver after
4093 /* ops for rate scaling implemented in the driver */