Lines Matching +full:rates +full:- +full:mcs
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright(c) 2005 - 2014, 2018 - 2021 Intel Corporation. All rights reserved.
5 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
6 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
19 #include "fw-api.h"
21 #include "iwl-op-mode.h"
83 IWL_DECLARE_RATE_INFO(6, 0, 5, 11), /* 6mbps ; MCS 0 */
85 IWL_DECLARE_RATE_INFO(12, 1, 11, 18), /* 12mbps ; MCS 1 */
86 IWL_DECLARE_RATE_INFO(18, 2, 12, 24), /* 18mbps ; MCS 2 */
87 IWL_DECLARE_RATE_INFO(24, 3, 18, 36), /* 24mbps ; MCS 3 */
88 IWL_DECLARE_RATE_INFO(36, 4, 24, 48), /* 36mbps ; MCS 4 */
89 IWL_DECLARE_RATE_INFO(48, 5, 36, 54), /* 48mbps ; MCS 5 */
90 IWL_DECLARE_RATE_INFO(54, 6, 48, INV), /* 54mbps ; MCS 6 */
91 IWL_DECLARE_MCS_RATE(7), /* MCS 7 */
92 IWL_DECLARE_MCS_RATE(8), /* MCS 8 */
93 IWL_DECLARE_MCS_RATE(9), /* MCS 9 */
98 RS_ACTION_DOWNSCALE = -1,
131 return iwl_mvm_bt_coex_is_ant_avail(mvm, next_col->ant); in rs_ant_allow()
138 if (!sta->deflink.ht_cap.ht_supported) in rs_mimo_allow()
141 if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC) in rs_mimo_allow()
150 if (mvm->nvm_data->sku_cap_mimo_disabled) in rs_mimo_allow()
160 if (!sta->deflink.ht_cap.ht_supported) in rs_siso_allow()
170 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; in rs_sgi_allow()
171 struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; in rs_sgi_allow()
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()
385 * The following tables contain the expected throughput metrics for all rates
391 * CCK rates are only valid in legacy table and will only be used in G
399 * 0 - NGI, 1 - SGI, 2 - AGG+NGI, 3 - AGG+SGI
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); in rs_pretty_rate()
527 prefix, rs_pretty_rate(rate), rate->bw, in rs_dump_rate()
528 rate->sgi, rate->ldpc, rate->stbc); in rs_dump_rate()
533 window->data = 0; in rs_rate_scale_clear_window()
534 window->success_counter = 0; in rs_rate_scale_clear_window()
535 window->success_ratio = IWL_INVALID_VALUE; in rs_rate_scale_clear_window()
536 window->counter = 0; in rs_rate_scale_clear_window()
537 window->average_tpt = IWL_INVALID_VALUE; in rs_rate_scale_clear_window()
547 rs_rate_scale_clear_window(&tbl->win[i]); in rs_rate_scale_clear_tbl_windows()
549 for (i = 0; i < ARRAY_SIZE(tbl->tpc_win); i++) in rs_rate_scale_clear_tbl_windows()
550 rs_rate_scale_clear_window(&tbl->tpc_win[i]); in rs_rate_scale_clear_tbl_windows()
565 sta->addr, tid); in rs_tl_turn_on_agg_for_tid()
569 if (ret == -EAGAIN) { in rs_tl_turn_on_agg_for_tid()
600 tid_data = &mvmsta->tid_data[tid]; in rs_tl_turn_on_agg()
601 if (mvmsta->sta_state >= IEEE80211_STA_AUTHORIZED && in rs_tl_turn_on_agg()
602 tid_data->state == IWL_AGG_OFF && in rs_tl_turn_on_agg()
603 (lq_sta->tx_agg_tid_en & BIT(tid)) && in rs_tl_turn_on_agg()
604 tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) { in rs_tl_turn_on_agg()
607 tid_data->state = IWL_AGG_QUEUED; in rs_tl_turn_on_agg()
623 if (tbl->expected_tpt) in get_expected_tpt()
624 return tbl->expected_tpt[rs_index]; in get_expected_tpt()
629 * rs_collect_tx_data - Update the success/failure sliding window
632 * at this rate. window->data contains the bitmask of successful
640 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); in _rs_collect_tx_data()
655 if (window->counter >= IWL_RATE_MAX_WINDOW) { in _rs_collect_tx_data()
657 window->counter = IWL_RATE_MAX_WINDOW - 1; in _rs_collect_tx_data()
659 if (window->data & mask) { in _rs_collect_tx_data()
660 window->data &= ~mask; in _rs_collect_tx_data()
661 window->success_counter--; in _rs_collect_tx_data()
665 /* Increment frames-attempted counter */ in _rs_collect_tx_data()
666 window->counter++; in _rs_collect_tx_data()
669 window->data <<= 1; in _rs_collect_tx_data()
673 window->success_counter++; in _rs_collect_tx_data()
674 window->data |= 0x1; in _rs_collect_tx_data()
675 successes--; in _rs_collect_tx_data()
678 attempts--; in _rs_collect_tx_data()
681 /* Calculate current success ratio, avoid divide-by-0! */ in _rs_collect_tx_data()
682 if (window->counter > 0) in _rs_collect_tx_data()
683 window->success_ratio = 128 * (100 * window->success_counter) in _rs_collect_tx_data()
684 / window->counter; in _rs_collect_tx_data()
686 window->success_ratio = IWL_INVALID_VALUE; in _rs_collect_tx_data()
688 fail_count = window->counter - window->success_counter; in _rs_collect_tx_data()
692 (window->success_counter >= IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) in _rs_collect_tx_data()
693 window->average_tpt = (window->success_ratio * tpt + 64) / 128; in _rs_collect_tx_data()
695 window->average_tpt = IWL_INVALID_VALUE; in _rs_collect_tx_data()
709 return -EINVAL; in rs_collect_tpc_data()
711 window = &tbl->tpc_win[reduced_txp]; in rs_collect_tpc_data()
725 tid_data = &mvmsta->tid_data[tid]; in rs_update_tid_tpt_stats()
730 * BA session, so it should be updated only when A-MPDU is in rs_update_tid_tpt_stats()
733 if (tid_data->state != IWL_AGG_OFF) in rs_update_tid_tpt_stats()
736 if (time_is_before_jiffies(tid_data->tpt_meas_start + HZ) || in rs_update_tid_tpt_stats()
737 (tid_data->tx_count >= IWL_MVM_RS_AGG_START_THRESHOLD)) { in rs_update_tid_tpt_stats()
738 tid_data->tx_count_last = tid_data->tx_count; in rs_update_tid_tpt_stats()
739 tid_data->tx_count = 0; in rs_update_tid_tpt_stats()
740 tid_data->tpt_meas_start = jiffies; in rs_update_tid_tpt_stats()
742 tid_data->tx_count += successes; in rs_update_tid_tpt_stats()
754 return -EINVAL; in rs_collect_tlc_data()
756 if (tbl->column != RS_COLUMN_INVALID) { in rs_collect_tlc_data()
757 struct lq_sta_pers *pers = &mvmsta->lq_sta.rs_drv.pers; in rs_collect_tlc_data()
759 pers->tx_stats[tbl->column][scale_index].total += attempts; in rs_collect_tlc_data()
760 pers->tx_stats[tbl->column][scale_index].success += successes; in rs_collect_tlc_data()
766 window = &(tbl->win[scale_index]); in rs_collect_tlc_data()
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()
788 /* set RTS protection for all non legacy rates 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()
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()
852 return -EINVAL; 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()
902 rate->type = LQ_VHT_SISO; in rs_rate_from_ucode_rate()
903 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1, in rs_rate_from_ucode_rate()
905 rate->stbc, rate->bfer); in rs_rate_from_ucode_rate()
907 rate->type = LQ_VHT_MIMO2; in rs_rate_from_ucode_rate()
917 rate->type = LQ_HE_SISO; in rs_rate_from_ucode_rate()
918 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1, in rs_rate_from_ucode_rate()
919 "stbc %d bfer %d", rate->stbc, rate->bfer); in rs_rate_from_ucode_rate()
921 rate->type = LQ_HE_MIMO2; in rs_rate_from_ucode_rate()
928 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 && in rs_rate_from_ucode_rate()
940 if (!rs_is_valid_ant(valid_ant, rate->ant)) in rs_toggle_antenna()
943 new_ant_type = ant_toggle_lookup[rate->ant]; in rs_toggle_antenna()
945 while ((new_ant_type != rate->ant) && in rs_toggle_antenna()
949 if (new_ant_type == rate->ant) in rs_toggle_antenna()
952 rate->ant = new_ant_type; in rs_toggle_antenna()
961 return lq_sta->active_legacy_rate; in rs_get_supported_rates()
963 return lq_sta->active_siso_rate; in rs_get_supported_rates()
965 return lq_sta->active_mimo2_rate; in rs_get_supported_rates()
984 i = index - 1; in rs_get_adjacent_rate()
987 for (; i >= 0; i--, mask >>= 1) { in rs_get_adjacent_rate()
1030 return BIT(rate->index) & rs_get_supported_rates(lq_sta, rate); in rs_rate_supported()
1042 struct iwl_mvm *mvm = lq_sta->pers.drv; in rs_get_lower_rate_in_column()
1045 high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask, in rs_get_lower_rate_in_column()
1046 rate->type); in rs_get_lower_rate_in_column()
1053 rate->index = low; in rs_get_lower_rate_in_column()
1061 struct iwl_mvm *mvm = lq_sta->pers.drv; in rs_get_lower_rate_down_column()
1068 if (lq_sta->band == NL80211_BAND_5GHZ) in rs_get_lower_rate_down_column()
1069 rate->type = LQ_LEGACY_A; in rs_get_lower_rate_down_column()
1071 rate->type = LQ_LEGACY_G; in rs_get_lower_rate_down_column()
1073 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_get_lower_rate_down_column()
1075 WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX || in rs_get_lower_rate_down_column()
1076 rate->index > 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()
1079 rate->ldpc = false; in rs_get_lower_rate_down_column()
1081 /* Downgrade to SISO with same MCS if in MIMO */ in rs_get_lower_rate_down_column()
1082 rate->type = is_vht_mimo2(rate) ? in rs_get_lower_rate_down_column()
1086 if (num_of_ant(rate->ant) > 1) in rs_get_lower_rate_down_column()
1087 rate->ant = first_antenna(iwl_mvm_get_valid_tx_ant(mvm)); in rs_get_lower_rate_down_column()
1090 rate->sgi = false; in rs_get_lower_rate_down_column()
1096 /* Check if both rates share the same column */
1102 if (a->stbc || a->bfer) in rs_rate_column_match()
1103 ant_match = (b->ant == ANT_A || b->ant == ANT_B); in rs_rate_column_match()
1105 ant_match = (a->ant == b->ant); in rs_rate_column_match()
1107 return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) in rs_rate_column_match()
1114 if (rate->ant == ANT_A) in rs_get_column_from_rate()
1117 if (rate->ant == ANT_B) in rs_get_column_from_rate()
1124 if (rate->ant == ANT_A || rate->stbc || rate->bfer) in rs_get_column_from_rate()
1125 return rate->sgi ? RS_COLUMN_SISO_ANT_A_SGI : in rs_get_column_from_rate()
1128 if (rate->ant == ANT_B) in rs_get_column_from_rate()
1129 return rate->sgi ? RS_COLUMN_SISO_ANT_B_SGI : in rs_get_column_from_rate()
1136 return rate->sgi ? RS_COLUMN_MIMO2_SGI : RS_COLUMN_MIMO2; in rs_get_column_from_rate()
1146 if (ieee80211_is_data_qos(hdr->frame_control)) { in rs_get_tid()
1165 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; in rs_drv_mac80211_tx_status()
1171 if (!mvmsta->vif) in rs_drv_mac80211_tx_status()
1174 if (!ieee80211_is_data(hdr->frame_control) || in rs_drv_mac80211_tx_status()
1175 info->flags & IEEE80211_TX_CTL_NO_ACK) in rs_drv_mac80211_tx_status()
1179 ieee80211_is_qos_nullfunc(hdr->frame_control)); in rs_drv_mac80211_tx_status()
1185 * Set frame tx success limits according to legacy vs. high-throughput,
1186 * and reset overall (spanning all rates) tx success history statistics.
1194 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN; in rs_set_stay_in_table()
1196 lq_sta->table_count_limit = IWL_MVM_RS_LEGACY_TABLE_COUNT; in rs_set_stay_in_table()
1197 lq_sta->max_failure_limit = IWL_MVM_RS_LEGACY_FAILURE_LIMIT; in rs_set_stay_in_table()
1198 lq_sta->max_success_limit = IWL_MVM_RS_LEGACY_SUCCESS_LIMIT; in rs_set_stay_in_table()
1200 lq_sta->table_count_limit = IWL_MVM_RS_NON_LEGACY_TABLE_COUNT; in rs_set_stay_in_table()
1201 lq_sta->max_failure_limit = IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT; in rs_set_stay_in_table()
1202 lq_sta->max_success_limit = IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT; in rs_set_stay_in_table()
1204 lq_sta->table_count = 0; in rs_set_stay_in_table()
1205 lq_sta->total_failed = 0; in rs_set_stay_in_table()
1206 lq_sta->total_success = 0; in rs_set_stay_in_table()
1207 lq_sta->flush_timer = jiffies; in rs_set_stay_in_table()
1208 lq_sta->visited_columns = 0; in rs_set_stay_in_table()
1221 switch (column->mode) { in rs_get_max_allowed_rate()
1223 return lq_sta->max_legacy_rate_idx; in rs_get_max_allowed_rate()
1225 return lq_sta->max_siso_rate_idx; in rs_get_max_allowed_rate()
1227 return lq_sta->max_mimo2_rate_idx; in rs_get_max_allowed_rate()
1232 return lq_sta->max_legacy_rate_idx; in rs_get_max_allowed_rate()
1242 if (WARN_ON_ONCE(column->mode != RS_LEGACY && in rs_get_expected_tpt_table()
1243 column->mode != RS_SISO && in rs_get_expected_tpt_table()
1244 column->mode != RS_MIMO2)) in rs_get_expected_tpt_table()
1247 /* Legacy rates have only one table */ in rs_get_expected_tpt_table()
1248 if (column->mode == RS_LEGACY) in rs_get_expected_tpt_table()
1255 if (column->mode == RS_SISO) { in rs_get_expected_tpt_table()
1272 } else if (column->mode == RS_MIMO2) { in rs_get_expected_tpt_table()
1293 if (!column->sgi && !lq_sta->is_agg) /* Normal */ in rs_get_expected_tpt_table()
1295 else if (column->sgi && !lq_sta->is_agg) /* SGI */ in rs_get_expected_tpt_table()
1297 else if (!column->sgi && lq_sta->is_agg) /* AGG */ in rs_get_expected_tpt_table()
1306 struct rs_rate *rate = &tbl->rate; in rs_set_expected_tpt_table()
1307 const struct rs_tx_column *column = &rs_tx_columns[tbl->column]; in rs_set_expected_tpt_table()
1309 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw); in rs_set_expected_tpt_table()
1330 &(lq_sta->lq_info[lq_sta->active_tbl]); in rs_get_best_rate()
1331 s32 success_ratio = active_tbl->win[index].success_ratio; in rs_get_best_rate()
1332 u16 expected_current_tpt = active_tbl->expected_tpt[index]; in rs_get_best_rate()
1333 const u16 *tpt_tbl = tbl->expected_tpt; in rs_get_best_rate()
1344 target_tpt = lq_sta->last_tpt; in rs_get_best_rate()
1357 tbl->rate.type); in rs_get_best_rate()
1372 struct ieee80211_sta_vht_cap *sta_vht_cap = &sta->deflink.vht_cap; in rs_bw_from_sta_bw()
1374 .vht_cap_info = cpu_to_le32(sta_vht_cap->cap), in rs_bw_from_sta_bw()
1375 .supp_mcs = sta_vht_cap->vht_mcs, in rs_bw_from_sta_bw()
1378 switch (sta->deflink.bandwidth) { in rs_bw_from_sta_bw()
1384 * We only check MCS 0 - they will support that if in rs_bw_from_sta_bw()
1385 * we got here at all and we don't care which MCS, in rs_bw_from_sta_bw()
1391 sta->deflink.rx_nss) < sta->deflink.rx_nss) in rs_bw_from_sta_bw()
1418 mvm = lq_sta->pers.drv; in rs_stay_in_table()
1419 active_tbl = lq_sta->active_tbl; in rs_stay_in_table()
1421 tbl = &(lq_sta->lq_info[active_tbl]); in rs_stay_in_table()
1424 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { in rs_stay_in_table()
1426 if (lq_sta->flush_timer) in rs_stay_in_table()
1429 (unsigned long)(lq_sta->flush_timer + in rs_stay_in_table()
1441 (lq_sta->total_failed > lq_sta->max_failure_limit) || in rs_stay_in_table()
1442 (lq_sta->total_success > lq_sta->max_success_limit) || in rs_stay_in_table()
1443 ((!lq_sta->search_better_tbl) && in rs_stay_in_table()
1444 (lq_sta->flush_timer) && (flush_interval_passed))) { in rs_stay_in_table()
1447 lq_sta->total_failed, in rs_stay_in_table()
1448 lq_sta->total_success, in rs_stay_in_table()
1452 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_STARTED; in rs_stay_in_table()
1455 lq_sta->total_failed = 0; in rs_stay_in_table()
1456 lq_sta->total_success = 0; in rs_stay_in_table()
1457 lq_sta->flush_timer = 0; in rs_stay_in_table()
1459 lq_sta->visited_columns = BIT(tbl->column); in rs_stay_in_table()
1463 * history bitmaps and rate-specific stats for all rates in in rs_stay_in_table()
1467 lq_sta->table_count++; in rs_stay_in_table()
1468 if (lq_sta->table_count >= in rs_stay_in_table()
1469 lq_sta->table_count_limit) { in rs_stay_in_table()
1470 lq_sta->table_count = 0; in rs_stay_in_table()
1481 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) { in rs_stay_in_table()
1494 sta->deflink.agg.max_amsdu_len = rs_fw_get_max_amsdu_len(sta); in rs_set_amsdu_len()
1498 * or 0, since there is no per-TID alg. in rs_set_amsdu_len()
1500 if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || in rs_set_amsdu_len()
1501 tbl->rate.index < IWL_RATE_MCS_5_INDEX || in rs_set_amsdu_len()
1503 mvmsta->amsdu_enabled = 0; in rs_set_amsdu_len()
1505 mvmsta->amsdu_enabled = 0xFFFF; in rs_set_amsdu_len()
1507 if (mvmsta->vif->bss_conf.he_support && in rs_set_amsdu_len()
1509 mvmsta->max_amsdu_len = sta->deflink.agg.max_amsdu_len; in rs_set_amsdu_len()
1511 mvmsta->max_amsdu_len = in rs_set_amsdu_len()
1512 min_t(int, sta->deflink.agg.max_amsdu_len, 8500); in rs_set_amsdu_len()
1514 sta->deflink.agg.max_rc_amsdu_len = mvmsta->max_amsdu_len; in rs_set_amsdu_len()
1517 if (mvmsta->amsdu_enabled) in rs_set_amsdu_len()
1518 sta->deflink.agg.max_tid_amsdu_len[i] = in rs_set_amsdu_len()
1525 sta->deflink.agg.max_tid_amsdu_len[i] = 1; in rs_set_amsdu_len()
1537 rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate); in rs_update_rate_tbl()
1538 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); in rs_update_rate_tbl()
1550 if (!is_vht_siso(&tbl->rate)) in rs_tweak_rate_tbl()
1553 if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_80) && in rs_tweak_rate_tbl()
1554 (tbl->rate.index == IWL_RATE_MCS_0_INDEX) && in rs_tweak_rate_tbl()
1556 tbl->rate.bw = RATE_MCS_CHAN_WIDTH_20; in rs_tweak_rate_tbl()
1557 tbl->rate.index = IWL_RATE_MCS_4_INDEX; in rs_tweak_rate_tbl()
1558 IWL_DEBUG_RATE(mvm, "Switch 80Mhz SISO MCS0 -> 20Mhz MCS4\n"); in rs_tweak_rate_tbl()
1567 if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_20) && in rs_tweak_rate_tbl()
1568 (((tbl->rate.index == IWL_RATE_MCS_5_INDEX) && in rs_tweak_rate_tbl()
1570 ((tbl->rate.index > IWL_RATE_MCS_5_INDEX) && in rs_tweak_rate_tbl()
1572 tbl->rate.bw = RATE_MCS_CHAN_WIDTH_80; in rs_tweak_rate_tbl()
1573 tbl->rate.index = IWL_RATE_MCS_1_INDEX; in rs_tweak_rate_tbl()
1574 IWL_DEBUG_RATE(mvm, "Switch 20Mhz SISO MCS5 -> 80Mhz MCS1\n"); in rs_tweak_rate_tbl()
1593 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column]; in rs_get_next_column()
1601 next_col_id = curr_col->next_columns[i]; in rs_get_next_column()
1606 if (lq_sta->visited_columns & BIT(next_col_id)) { in rs_get_next_column()
1614 if (!rs_is_valid_ant(valid_ants, next_col->ant)) { in rs_get_next_column()
1617 next_col_id, valid_ants, next_col->ant); in rs_get_next_column()
1622 allow_func = next_col->checks[j]; in rs_get_next_column()
1623 if (allow_func && !allow_func(mvm, sta, &tbl->rate, in rs_get_next_column()
1636 tpt = lq_sta->last_tpt / 100; in rs_get_next_column()
1675 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in rs_switch_to_column()
1677 &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in rs_switch_to_column()
1678 struct rs_rate *rate = &search_tbl->rate; in rs_switch_to_column()
1680 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column]; in rs_switch_to_column()
1686 rate->sgi = column->sgi; in rs_switch_to_column()
1687 rate->ant = column->ant; in rs_switch_to_column()
1689 if (column->mode == RS_LEGACY) { in rs_switch_to_column()
1690 if (lq_sta->band == NL80211_BAND_5GHZ) in rs_switch_to_column()
1691 rate->type = LQ_LEGACY_A; in rs_switch_to_column()
1693 rate->type = LQ_LEGACY_G; in rs_switch_to_column()
1695 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_switch_to_column()
1696 rate->ldpc = false; in rs_switch_to_column()
1697 rate_mask = lq_sta->active_legacy_rate; in rs_switch_to_column()
1698 } else if (column->mode == RS_SISO) { in rs_switch_to_column()
1699 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; in rs_switch_to_column()
1700 rate_mask = lq_sta->active_siso_rate; in rs_switch_to_column()
1701 } else if (column->mode == RS_MIMO2) { in rs_switch_to_column()
1702 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; in rs_switch_to_column()
1703 rate_mask = lq_sta->active_mimo2_rate; in rs_switch_to_column()
1708 if (column->mode != RS_LEGACY) { in rs_switch_to_column()
1709 rate->bw = rs_bw_from_sta_bw(sta); in rs_switch_to_column()
1710 rate->ldpc = lq_sta->ldpc; in rs_switch_to_column()
1713 search_tbl->column = col_id; in rs_switch_to_column()
1716 lq_sta->visited_columns |= BIT(col_id); in rs_switch_to_column()
1719 * SISO->MIMO, LEGACY->SISO, MIMO->SISO in rs_switch_to_column()
1721 if (curr_column->mode != column->mode) { in rs_switch_to_column()
1723 rate_mask, rate->index); in rs_switch_to_column()
1735 rate->index = rate_idx; in rs_switch_to_column()
1739 col_id, rate->index); in rs_switch_to_column()
1744 rate->type = LQ_NONE; in rs_switch_to_column()
1745 return -1; in rs_switch_to_column()
1767 "No data about high/low rates. Increase rate\n"); in rs_get_rate_action()
1820 } else if (current_tpt > (100 * tbl->expected_tpt[low])) { in rs_get_rate_action()
1838 if (!lq_sta->stbc_capable) in rs_stbc_allow()
1854 *stronger = index - IWL_MVM_RS_TPC_TX_POWER_STEP; in rs_get_adjacent_txp()
1862 int index = rate->index; in rs_tpc_allowed()
1864 bool sta_ps_disabled = (vif->type == NL80211_IFTYPE_STATION && in rs_tpc_allowed()
1865 !vif->cfg.ps); in rs_tpc_allowed()
1877 IWL_DEBUG_RATE(mvm, "check rate, table type: %d\n", rate->type); in rs_tpc_allowed()
1952 IWL_DEBUG_RATE(mvm, "no need to increase or decrease txp - stay\n"); in rs_get_tpc_action()
1962 struct ieee80211_vif *vif = mvm_sta->vif; in rs_tpc_perform()
1966 struct rs_rate *rate = &tbl->rate; in rs_tpc_perform()
1969 u8 cur = lq_sta->lq.reduced_tpc; in rs_tpc_perform()
1975 if (lq_sta->pers.dbg_fixed_txp_reduction <= TPC_MAX_REDUCTION) { in rs_tpc_perform()
1977 lq_sta->pers.dbg_fixed_txp_reduction); in rs_tpc_perform()
1978 lq_sta->lq.reduced_tpc = lq_sta->pers.dbg_fixed_txp_reduction; in rs_tpc_perform()
1979 return cur != lq_sta->pers.dbg_fixed_txp_reduction; in rs_tpc_perform()
1984 chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf); in rs_tpc_perform()
1988 band = chanctx_conf->def.chan->band; in rs_tpc_perform()
1994 lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; in rs_tpc_perform()
2000 /* Collect measured throughputs for current and adjacent rates */ in rs_tpc_perform()
2001 window = tbl->tpc_win; in rs_tpc_perform()
2030 lq_sta->lq.reduced_tpc = weak; in rs_tpc_perform()
2033 lq_sta->lq.reduced_tpc = strong; in rs_tpc_perform()
2036 lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; in rs_tpc_perform()
2069 u8 prev_agg = lq_sta->is_agg; in rs_rate_scale_perform()
2073 lq_sta->is_agg = !!mvmsta->agg_tids; in rs_rate_scale_perform()
2076 * Select rate-scale / modulation-mode table to work with in in rs_rate_scale_perform()
2080 if (!lq_sta->search_better_tbl) in rs_rate_scale_perform()
2081 active_tbl = lq_sta->active_tbl; in rs_rate_scale_perform()
2083 active_tbl = rs_search_tbl(lq_sta->active_tbl); in rs_rate_scale_perform()
2085 tbl = &(lq_sta->lq_info[active_tbl]); in rs_rate_scale_perform()
2086 rate = &tbl->rate; in rs_rate_scale_perform()
2088 if (prev_agg != lq_sta->is_agg) { in rs_rate_scale_perform()
2091 prev_agg, lq_sta->is_agg); in rs_rate_scale_perform()
2097 index = rate->index; in rs_rate_scale_perform()
2099 /* rates available for this association, and for modulation mode */ in rs_rate_scale_perform()
2104 if (lq_sta->search_better_tbl) { in rs_rate_scale_perform()
2106 rate->type = LQ_NONE; in rs_rate_scale_perform()
2107 lq_sta->search_better_tbl = 0; in rs_rate_scale_perform()
2108 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in rs_rate_scale_perform()
2115 if (!tbl->expected_tpt) { in rs_rate_scale_perform()
2116 IWL_ERR(mvm, "tbl->expected_tpt is NULL\n"); in rs_rate_scale_perform()
2121 window = &(tbl->win[index]); in rs_rate_scale_perform()
2130 fail_count = window->counter - window->success_counter; in rs_rate_scale_perform()
2132 (window->success_counter < IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) { in rs_rate_scale_perform()
2136 window->success_counter, window->counter); in rs_rate_scale_perform()
2139 window->average_tpt = IWL_INVALID_VALUE; in rs_rate_scale_perform()
2149 if (lq_sta->search_better_tbl) { in rs_rate_scale_perform()
2153 if (window->average_tpt > lq_sta->last_tpt) { in rs_rate_scale_perform()
2156 "cur-tpt %d old-tpt %d\n", in rs_rate_scale_perform()
2157 window->success_ratio, in rs_rate_scale_perform()
2158 window->average_tpt, in rs_rate_scale_perform()
2159 lq_sta->last_tpt); in rs_rate_scale_perform()
2162 lq_sta->active_tbl = active_tbl; in rs_rate_scale_perform()
2163 current_tpt = window->average_tpt; in rs_rate_scale_perform()
2168 "cur-tpt %d old-tpt %d\n", in rs_rate_scale_perform()
2169 window->success_ratio, in rs_rate_scale_perform()
2170 window->average_tpt, in rs_rate_scale_perform()
2171 lq_sta->last_tpt); in rs_rate_scale_perform()
2174 rate->type = LQ_NONE; in rs_rate_scale_perform()
2177 active_tbl = lq_sta->active_tbl; in rs_rate_scale_perform()
2178 tbl = &(lq_sta->lq_info[active_tbl]); in rs_rate_scale_perform()
2181 index = tbl->rate.index; in rs_rate_scale_perform()
2182 current_tpt = lq_sta->last_tpt; in rs_rate_scale_perform()
2190 lq_sta->search_better_tbl = 0; in rs_rate_scale_perform()
2197 high_low = rs_get_adjacent_rate(mvm, index, rate_mask, rate->type); in rs_rate_scale_perform()
2203 sr = window->success_ratio; in rs_rate_scale_perform()
2205 /* Collect measured throughputs for current and adjacent rates */ in rs_rate_scale_perform()
2206 current_tpt = window->average_tpt; in rs_rate_scale_perform()
2208 low_tpt = tbl->win[low].average_tpt; in rs_rate_scale_perform()
2210 high_tpt = tbl->win[high].average_tpt; in rs_rate_scale_perform()
2254 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) in rs_rate_scale_perform()
2264 tbl->rate.index = index; in rs_rate_scale_perform()
2275 * 1) Not changing rates right now in rs_rate_scale_perform()
2280 lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED in rs_rate_scale_perform()
2281 && window->counter) { in rs_rate_scale_perform()
2285 lq_sta->last_tpt = current_tpt; in rs_rate_scale_perform()
2288 "Start Search: update_lq %d done_search %d rs_state %d win->counter %d\n", in rs_rate_scale_perform()
2289 update_lq, done_search, lq_sta->rs_state, in rs_rate_scale_perform()
2290 window->counter); in rs_rate_scale_perform()
2297 lq_sta->search_better_tbl = 1; in rs_rate_scale_perform()
2301 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_ENDED; in rs_rate_scale_perform()
2305 if (lq_sta->search_better_tbl) { in rs_rate_scale_perform()
2307 tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in rs_rate_scale_perform()
2311 index = tbl->rate.index; in rs_rate_scale_perform()
2313 rs_dump_rate(mvm, &tbl->rate, in rs_rate_scale_perform()
2324 if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) { in rs_rate_scale_perform()
2325 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); in rs_rate_scale_perform()
2326 rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_sta); in rs_rate_scale_perform()
2336 { -60, IWL_RATE_54M_INDEX },
2337 { -64, IWL_RATE_48M_INDEX },
2338 { -68, IWL_RATE_36M_INDEX },
2339 { -80, IWL_RATE_24M_INDEX },
2340 { -84, IWL_RATE_18M_INDEX },
2341 { -85, IWL_RATE_12M_INDEX },
2342 { -86, IWL_RATE_11M_INDEX },
2343 { -88, IWL_RATE_5M_INDEX },
2344 { -90, IWL_RATE_2M_INDEX },
2349 { -60, IWL_RATE_54M_INDEX },
2350 { -64, IWL_RATE_48M_INDEX },
2351 { -72, IWL_RATE_36M_INDEX },
2352 { -80, IWL_RATE_24M_INDEX },
2353 { -84, IWL_RATE_18M_INDEX },
2354 { -85, IWL_RATE_12M_INDEX },
2355 { -87, IWL_RATE_9M_INDEX },
2360 { -60, IWL_RATE_MCS_7_INDEX },
2361 { -64, IWL_RATE_MCS_6_INDEX },
2362 { -68, IWL_RATE_MCS_5_INDEX },
2363 { -72, IWL_RATE_MCS_4_INDEX },
2364 { -80, IWL_RATE_MCS_3_INDEX },
2365 { -84, IWL_RATE_MCS_2_INDEX },
2366 { -85, IWL_RATE_MCS_1_INDEX },
2370 /* MCS index 9 is not valid for 20MHz VHT channel width,
2374 { -60, IWL_RATE_MCS_8_INDEX },
2375 { -64, IWL_RATE_MCS_7_INDEX },
2376 { -68, IWL_RATE_MCS_6_INDEX },
2377 { -72, IWL_RATE_MCS_5_INDEX },
2378 { -80, IWL_RATE_MCS_4_INDEX },
2379 { -84, IWL_RATE_MCS_3_INDEX },
2380 { -85, IWL_RATE_MCS_2_INDEX },
2381 { -87, IWL_RATE_MCS_1_INDEX },
2386 { -60, IWL_RATE_MCS_9_INDEX },
2387 { -64, IWL_RATE_MCS_8_INDEX },
2388 { -68, IWL_RATE_MCS_7_INDEX },
2389 { -72, IWL_RATE_MCS_6_INDEX },
2390 { -80, IWL_RATE_MCS_5_INDEX },
2391 { -84, IWL_RATE_MCS_4_INDEX },
2392 { -85, IWL_RATE_MCS_3_INDEX },
2393 { -87, IWL_RATE_MCS_2_INDEX },
2394 { -88, IWL_RATE_MCS_1_INDEX },
2398 #define IWL_RS_LOW_RSSI_THRESHOLD (-76) /* dBm */
2408 struct rs_rate *rate = &lq_sta->optimal_rate; in rs_init_optimal_rate()
2410 if (lq_sta->max_mimo2_rate_idx != IWL_RATE_INVALID) in rs_init_optimal_rate()
2411 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; in rs_init_optimal_rate()
2412 else if (lq_sta->max_siso_rate_idx != IWL_RATE_INVALID) in rs_init_optimal_rate()
2413 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; in rs_init_optimal_rate()
2414 else if (lq_sta->band == NL80211_BAND_5GHZ) in rs_init_optimal_rate()
2415 rate->type = LQ_LEGACY_A; in rs_init_optimal_rate()
2417 rate->type = LQ_LEGACY_G; in rs_init_optimal_rate()
2419 rate->bw = rs_bw_from_sta_bw(sta); in rs_init_optimal_rate()
2420 rate->sgi = rs_sgi_allow(mvm, sta, rate, NULL); in rs_init_optimal_rate()
2425 lq_sta->optimal_rate_mask = lq_sta->active_mimo2_rate; in rs_init_optimal_rate()
2427 lq_sta->optimal_rate_mask = lq_sta->active_siso_rate; in rs_init_optimal_rate()
2429 lq_sta->optimal_rate_mask = lq_sta->active_legacy_rate; in rs_init_optimal_rate()
2431 if (lq_sta->band == NL80211_BAND_5GHZ) { in rs_init_optimal_rate()
2432 lq_sta->optimal_rates = rs_optimal_rates_5ghz_legacy; in rs_init_optimal_rate()
2433 lq_sta->optimal_nentries = in rs_init_optimal_rate()
2436 lq_sta->optimal_rates = rs_optimal_rates_24ghz_legacy; in rs_init_optimal_rate()
2437 lq_sta->optimal_nentries = in rs_init_optimal_rate()
2443 if (rate->bw == RATE_MCS_CHAN_WIDTH_20) { in rs_init_optimal_rate()
2444 lq_sta->optimal_rates = rs_optimal_rates_vht_20mhz; in rs_init_optimal_rate()
2445 lq_sta->optimal_nentries = in rs_init_optimal_rate()
2448 lq_sta->optimal_rates = rs_optimal_rates_vht; in rs_init_optimal_rate()
2449 lq_sta->optimal_nentries = in rs_init_optimal_rate()
2453 lq_sta->optimal_rates = rs_optimal_rates_ht; in rs_init_optimal_rate()
2454 lq_sta->optimal_nentries = ARRAY_SIZE(rs_optimal_rates_ht); in rs_init_optimal_rate()
2462 struct rs_rate *rate = &lq_sta->optimal_rate; in rs_get_optimal_rate()
2465 rate->index = find_first_bit(&lq_sta->optimal_rate_mask, in rs_get_optimal_rate()
2468 for (i = 0; i < lq_sta->optimal_nentries; i++) { in rs_get_optimal_rate()
2469 int rate_idx = lq_sta->optimal_rates[i].rate_idx; in rs_get_optimal_rate()
2471 if ((lq_sta->pers.last_rssi >= lq_sta->optimal_rates[i].rssi) && in rs_get_optimal_rate()
2472 (BIT(rate_idx) & lq_sta->optimal_rate_mask)) { in rs_get_optimal_rate()
2473 rate->index = rate_idx; in rs_get_optimal_rate()
2498 for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { in rs_get_initial_rate()
2499 if (!(lq_sta->pers.chains & BIT(i))) in rs_get_initial_rate()
2502 if (lq_sta->pers.chain_signal[i] > best_rssi) { in rs_get_initial_rate()
2503 best_rssi = lq_sta->pers.chain_signal[i]; in rs_get_initial_rate()
2512 rate->ant = first_antenna(valid_tx_ant); in rs_get_initial_rate()
2514 rate->ant = best_ant; in rs_get_initial_rate()
2516 rate->sgi = false; in rs_get_initial_rate()
2517 rate->ldpc = false; in rs_get_initial_rate()
2518 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_get_initial_rate()
2520 rate->index = find_first_bit(&lq_sta->active_legacy_rate, in rs_get_initial_rate()
2524 rate->type = LQ_LEGACY_A; in rs_get_initial_rate()
2528 rate->type = LQ_LEGACY_G; in rs_get_initial_rate()
2539 * legacy rates. in rs_get_initial_rate()
2541 if (sta->deflink.vht_cap.vht_supported && in rs_get_initial_rate()
2550 * is already up-to-date, re-init rs with the correct bw. in rs_get_initial_rate()
2552 u32 bw = mvmsta->sta_state < IEEE80211_STA_AUTHORIZED ? in rs_get_initial_rate()
2568 sta->deflink.bandwidth); in rs_get_initial_rate()
2572 active_rate = lq_sta->active_siso_rate; in rs_get_initial_rate()
2573 rate->type = LQ_VHT_SISO; in rs_get_initial_rate()
2574 rate->bw = bw; in rs_get_initial_rate()
2575 } else if (sta->deflink.ht_cap.ht_supported && in rs_get_initial_rate()
2579 active_rate = lq_sta->active_siso_rate; in rs_get_initial_rate()
2580 rate->type = LQ_HT_SISO; in rs_get_initial_rate()
2582 active_rate = lq_sta->active_legacy_rate; in rs_get_initial_rate()
2590 rate->index = rate_idx; in rs_get_initial_rate()
2604 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; in rs_update_last_rssi()
2607 lq_sta->pers.chains = rx_status->chains; in rs_update_last_rssi()
2608 lq_sta->pers.chain_signal[0] = rx_status->chain_signal[0]; in rs_update_last_rssi()
2609 lq_sta->pers.chain_signal[1] = rx_status->chain_signal[1]; in rs_update_last_rssi()
2610 lq_sta->pers.last_rssi = S8_MIN; in rs_update_last_rssi()
2612 for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { in rs_update_last_rssi()
2613 if (!(lq_sta->pers.chains & BIT(i))) in rs_update_last_rssi()
2616 if (lq_sta->pers.chain_signal[i] > lq_sta->pers.last_rssi) in rs_update_last_rssi()
2617 lq_sta->pers.last_rssi = lq_sta->pers.chain_signal[i]; in rs_update_last_rssi()
2622 * rs_initialize_lq - Initialize a station's hardware rate table
2624 * The uCode's station table contains a table of fallback rates
2628 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
2647 if (!lq_sta->search_better_tbl) in rs_initialize_lq()
2648 active_tbl = lq_sta->active_tbl; in rs_initialize_lq()
2650 active_tbl = rs_search_tbl(lq_sta->active_tbl); in rs_initialize_lq()
2652 tbl = &(lq_sta->lq_info[active_tbl]); in rs_initialize_lq()
2653 rate = &tbl->rate; in rs_initialize_lq()
2658 WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B, in rs_initialize_lq()
2660 rate->ant, lq_sta->pers.chains, mvm->fw->valid_tx_ant, in rs_initialize_lq()
2661 mvm->nvm_data ? mvm->nvm_data->valid_tx_ant : ANT_INVALID); in rs_initialize_lq()
2663 tbl->column = rs_get_column_from_rate(rate); in rs_initialize_lq()
2668 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); in rs_initialize_lq()
2677 struct sk_buff *skb = txrc->skb; in rs_drv_get_rate()
2683 if (sta && !iwl_mvm_sta_from_mac80211(sta)->vif) { in rs_drv_get_rate()
2695 iwl_mvm_hwrate_to_tx_rate_v1(lq_sta->last_rate_n_flags, in rs_drv_get_rate()
2696 info->band, &info->control.rates[0]); in rs_drv_get_rate()
2697 info->control.rates[0].count = 1; in rs_drv_get_rate()
2702 if (lq_sta->rs_state != RS_STATE_STAY_IN_COLUMN) { in rs_drv_get_rate()
2706 iwl_mvm_hwrate_to_tx_rate_v1(last_ucode_rate, info->band, in rs_drv_get_rate()
2707 &txrc->reported_rate); in rs_drv_get_rate()
2717 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; in rs_drv_alloc_sta()
2721 lq_sta->pers.drv = mvm; in rs_drv_alloc_sta()
2723 lq_sta->pers.dbg_fixed_rate = 0; in rs_drv_alloc_sta()
2724 lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID; in rs_drv_alloc_sta()
2725 lq_sta->pers.ss_force = RS_SS_FORCE_NONE; in rs_drv_alloc_sta()
2727 lq_sta->pers.chains = 0; in rs_drv_alloc_sta()
2728 memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); in rs_drv_alloc_sta()
2729 lq_sta->pers.last_rssi = S8_MIN; in rs_drv_alloc_sta()
2737 u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) & in rs_vht_highest_rx_mcs_index()
2738 (0x3 << (2 * (nss - 1))); in rs_vht_highest_rx_mcs_index()
2739 rx_mcs >>= (2 * (nss - 1)); in rs_vht_highest_rx_mcs_index()
2749 return -1; in rs_vht_highest_rx_mcs_index()
2766 sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) in rs_vht_set_enabled_rates()
2769 lq_sta->active_siso_rate |= BIT(i); in rs_vht_set_enabled_rates()
2773 if (sta->deflink.rx_nss < 2) in rs_vht_set_enabled_rates()
2784 sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) in rs_vht_set_enabled_rates()
2787 lq_sta->active_mimo2_rate |= BIT(i); in rs_vht_set_enabled_rates()
2798 * and CCK (bits 0-3), supp_rates[] does not; in rs_ht_init()
2801 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; in rs_ht_init()
2802 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; in rs_ht_init()
2803 lq_sta->active_siso_rate &= ~((u16)0x2); in rs_ht_init()
2804 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; in rs_ht_init()
2806 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; in rs_ht_init()
2807 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; in rs_ht_init()
2808 lq_sta->active_mimo2_rate &= ~((u16)0x2); in rs_ht_init()
2809 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; in rs_ht_init()
2811 if (mvm->cfg->ht_params->ldpc && in rs_ht_init()
2812 (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) in rs_ht_init()
2813 lq_sta->ldpc = true; in rs_ht_init()
2815 if (mvm->cfg->ht_params->stbc && in rs_ht_init()
2817 (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) in rs_ht_init()
2818 lq_sta->stbc_capable = true; in rs_ht_init()
2820 lq_sta->is_vht = false; in rs_ht_init()
2830 if (mvm->cfg->ht_params->ldpc && in rs_vht_init()
2831 (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)) in rs_vht_init()
2832 lq_sta->ldpc = true; in rs_vht_init()
2834 if (mvm->cfg->ht_params->stbc && in rs_vht_init()
2836 (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)) in rs_vht_init()
2837 lq_sta->stbc_capable = true; in rs_vht_init()
2839 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_BEAMFORMER) && in rs_vht_init()
2841 (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) in rs_vht_init()
2842 lq_sta->bfer_capable = true; in rs_vht_init()
2844 lq_sta->is_vht = true; in rs_vht_init()
2850 spin_lock_bh(&mvm->drv_stats_lock); in iwl_mvm_reset_frame_stats()
2851 memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats)); in iwl_mvm_reset_frame_stats()
2852 spin_unlock_bh(&mvm->drv_stats_lock); in iwl_mvm_reset_frame_stats()
2859 spin_lock(&mvm->drv_stats_lock); in iwl_mvm_update_frame_stats()
2862 mvm->drv_rx_stats.agg_frames++; in iwl_mvm_update_frame_stats()
2864 mvm->drv_rx_stats.success_frames++; in iwl_mvm_update_frame_stats()
2868 mvm->drv_rx_stats.bw_20_frames++; in iwl_mvm_update_frame_stats()
2871 mvm->drv_rx_stats.bw_40_frames++; in iwl_mvm_update_frame_stats()
2874 mvm->drv_rx_stats.bw_80_frames++; in iwl_mvm_update_frame_stats()
2877 mvm->drv_rx_stats.bw_160_frames++; in iwl_mvm_update_frame_stats()
2884 mvm->drv_rx_stats.ht_frames++; in iwl_mvm_update_frame_stats()
2887 mvm->drv_rx_stats.vht_frames++; in iwl_mvm_update_frame_stats()
2891 mvm->drv_rx_stats.legacy_frames++; in iwl_mvm_update_frame_stats()
2895 mvm->drv_rx_stats.siso_frames++; in iwl_mvm_update_frame_stats()
2897 mvm->drv_rx_stats.mimo2_frames++; in iwl_mvm_update_frame_stats()
2900 mvm->drv_rx_stats.sgi_frames++; in iwl_mvm_update_frame_stats()
2902 mvm->drv_rx_stats.ngi_frames++; in iwl_mvm_update_frame_stats()
2904 mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate; in iwl_mvm_update_frame_stats()
2905 mvm->drv_rx_stats.last_frame_idx = in iwl_mvm_update_frame_stats()
2906 (mvm->drv_rx_stats.last_frame_idx + 1) % in iwl_mvm_update_frame_stats()
2907 ARRAY_SIZE(mvm->drv_rx_stats.last_rates); in iwl_mvm_update_frame_stats()
2909 spin_unlock(&mvm->drv_stats_lock); in iwl_mvm_update_frame_stats()
2920 struct ieee80211_hw *hw = mvm->hw; in rs_drv_rate_init()
2921 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; in rs_drv_rate_init()
2922 struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; in rs_drv_rate_init()
2924 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; in rs_drv_rate_init()
2928 lockdep_assert_held(&mvmsta->lq_sta.rs_drv.pers.lock); in rs_drv_rate_init()
2930 /* clear all non-persistent lq data */ in rs_drv_rate_init()
2933 sband = hw->wiphy->bands[band]; in rs_drv_rate_init()
2935 lq_sta->lq.sta_id = mvmsta->sta_id; in rs_drv_rate_init()
2936 mvmsta->amsdu_enabled = 0; in rs_drv_rate_init()
2937 mvmsta->max_amsdu_len = sta->cur->max_amsdu_len; in rs_drv_rate_init()
2940 rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]); in rs_drv_rate_init()
2942 lq_sta->flush_timer = 0; in rs_drv_rate_init()
2943 lq_sta->last_tx = jiffies; in rs_drv_rate_init()
2947 mvmsta->sta_id); in rs_drv_rate_init()
2953 lq_sta->missed_rate_counter = IWL_MVM_RS_MISSED_RATE_MAX; in rs_drv_rate_init()
2954 lq_sta->band = sband->band; in rs_drv_rate_init()
2956 * active legacy rates as per supported rates bitmap in rs_drv_rate_init()
2958 supp = sta->deflink.supp_rates[sband->band]; in rs_drv_rate_init()
2959 lq_sta->active_legacy_rate = 0; in rs_drv_rate_init()
2961 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); in rs_drv_rate_init()
2964 if (!vht_cap || !vht_cap->vht_supported) in rs_drv_rate_init()
2969 lq_sta->max_legacy_rate_idx = in rs_drv_rate_init()
2970 rs_get_max_rate_from_mask(lq_sta->active_legacy_rate); in rs_drv_rate_init()
2971 lq_sta->max_siso_rate_idx = in rs_drv_rate_init()
2972 rs_get_max_rate_from_mask(lq_sta->active_siso_rate); in rs_drv_rate_init()
2973 lq_sta->max_mimo2_rate_idx = in rs_drv_rate_init()
2974 rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate); in rs_drv_rate_init()
2978 lq_sta->active_legacy_rate, in rs_drv_rate_init()
2979 lq_sta->active_siso_rate, in rs_drv_rate_init()
2980 lq_sta->active_mimo2_rate, in rs_drv_rate_init()
2981 lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable, in rs_drv_rate_init()
2982 lq_sta->bfer_capable); in rs_drv_rate_init()
2984 lq_sta->max_legacy_rate_idx, in rs_drv_rate_init()
2985 lq_sta->max_siso_rate_idx, in rs_drv_rate_init()
2986 lq_sta->max_mimo2_rate_idx); in rs_drv_rate_init()
2989 lq_sta->lq.single_stream_ant_msk = in rs_drv_rate_init()
2991 lq_sta->lq.dual_stream_ant_msk = ANT_AB; in rs_drv_rate_init()
2994 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; in rs_drv_rate_init()
2995 lq_sta->is_agg = 0; in rs_drv_rate_init()
3012 if (!iwl_mvm_sta_from_mac80211(sta)->vif) in rs_drv_rate_update()
3019 iwl_mvm_rs_rate_init(mvm, sta, sband->band, true); in rs_drv_rate_update()
3034 u32 tlc_info = (uintptr_t)info->status.status_driver_data[0]; in __iwl_mvm_rs_tx_status()
3037 u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1]; in __iwl_mvm_rs_tx_status()
3039 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; in __iwl_mvm_rs_tx_status()
3041 if (!lq_sta->pers.drv) { in __iwl_mvm_rs_tx_status()
3047 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && in __iwl_mvm_rs_tx_status()
3048 !(info->flags & IEEE80211_TX_STAT_AMPDU)) in __iwl_mvm_rs_tx_status()
3051 if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, in __iwl_mvm_rs_tx_status()
3061 if (lq_sta->pers.dbg_fixed_rate) { in __iwl_mvm_rs_tx_status()
3072 if (info->flags & IEEE80211_TX_STAT_AMPDU) { in __iwl_mvm_rs_tx_status()
3073 attempts = info->status.ampdu_len; in __iwl_mvm_rs_tx_status()
3074 success = info->status.ampdu_ack_len; in __iwl_mvm_rs_tx_status()
3076 attempts = info->status.rates[0].count; in __iwl_mvm_rs_tx_status()
3077 success = !!(info->flags & IEEE80211_TX_STAT_ACK); in __iwl_mvm_rs_tx_status()
3080 lq_sta->pers.tx_stats[column][index].total += attempts; in __iwl_mvm_rs_tx_status()
3081 lq_sta->pers.tx_stats[column][index].success += success; in __iwl_mvm_rs_tx_status()
3090 (unsigned long)(lq_sta->last_tx + in __iwl_mvm_rs_tx_status()
3096 rs_drv_rate_init(mvm, sta, info->band); in __iwl_mvm_rs_tx_status()
3099 lq_sta->last_tx = jiffies; in __iwl_mvm_rs_tx_status()
3108 table = &lq_sta->lq; in __iwl_mvm_rs_tx_status()
3109 lq_hwrate = le32_to_cpu(table->rs_table[0]); in __iwl_mvm_rs_tx_status()
3110 if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) { in __iwl_mvm_rs_tx_status()
3116 if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) { in __iwl_mvm_rs_tx_status()
3119 lq_color, LQ_FLAG_COLOR_GET(table->flags)); in __iwl_mvm_rs_tx_status()
3121 /* Since rates mis-match, the last LQ command may have failed. in __iwl_mvm_rs_tx_status()
3122 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with in __iwl_mvm_rs_tx_status()
3125 lq_sta->missed_rate_counter++; in __iwl_mvm_rs_tx_status()
3126 if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) { in __iwl_mvm_rs_tx_status()
3127 lq_sta->missed_rate_counter = 0; in __iwl_mvm_rs_tx_status()
3129 "Too many rates mismatch. Send sync LQ. rs_state %d\n", in __iwl_mvm_rs_tx_status()
3130 lq_sta->rs_state); in __iwl_mvm_rs_tx_status()
3131 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); in __iwl_mvm_rs_tx_status()
3138 lq_sta->missed_rate_counter = 0; in __iwl_mvm_rs_tx_status()
3140 if (!lq_sta->search_better_tbl) { in __iwl_mvm_rs_tx_status()
3141 curr_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in __iwl_mvm_rs_tx_status()
3142 other_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in __iwl_mvm_rs_tx_status()
3144 curr_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in __iwl_mvm_rs_tx_status()
3145 other_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in __iwl_mvm_rs_tx_status()
3148 if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) { in __iwl_mvm_rs_tx_status()
3151 tmp_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in __iwl_mvm_rs_tx_status()
3152 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE"); in __iwl_mvm_rs_tx_status()
3153 tmp_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in __iwl_mvm_rs_tx_status()
3154 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH"); in __iwl_mvm_rs_tx_status()
3157 /* no matching table found, let's by-pass the data collection in __iwl_mvm_rs_tx_status()
3170 if (info->flags & IEEE80211_TX_STAT_AMPDU) { in __iwl_mvm_rs_tx_status()
3172 info->status.ampdu_len, in __iwl_mvm_rs_tx_status()
3173 info->status.ampdu_ack_len, in __iwl_mvm_rs_tx_status()
3189 if (info->status.ampdu_ack_len == 0) in __iwl_mvm_rs_tx_status()
3190 info->status.ampdu_len = 1; in __iwl_mvm_rs_tx_status()
3194 info->status.ampdu_len, in __iwl_mvm_rs_tx_status()
3195 info->status.ampdu_ack_len); in __iwl_mvm_rs_tx_status()
3198 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { in __iwl_mvm_rs_tx_status()
3199 lq_sta->total_success += info->status.ampdu_ack_len; in __iwl_mvm_rs_tx_status()
3200 lq_sta->total_failed += (info->status.ampdu_len - in __iwl_mvm_rs_tx_status()
3201 info->status.ampdu_ack_len); in __iwl_mvm_rs_tx_status()
3205 retries = info->status.rates[0].count - 1; in __iwl_mvm_rs_tx_status()
3210 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); in __iwl_mvm_rs_tx_status()
3213 lq_hwrate = le32_to_cpu(table->rs_table[i]); in __iwl_mvm_rs_tx_status()
3214 if (rs_rate_from_ucode_rate(lq_hwrate, info->band, in __iwl_mvm_rs_tx_status()
3223 if (rs_rate_column_match(&lq_rate, &curr_tbl->rate)) in __iwl_mvm_rs_tx_status()
3226 &other_tbl->rate)) in __iwl_mvm_rs_tx_status()
3241 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { in __iwl_mvm_rs_tx_status()
3242 lq_sta->total_success += legacy_success; in __iwl_mvm_rs_tx_status()
3243 lq_sta->total_failed += retries + (1 - legacy_success); in __iwl_mvm_rs_tx_status()
3247 lq_sta->last_rate_n_flags = lq_hwrate; in __iwl_mvm_rs_tx_status()
3251 if (sta->deflink.supp_rates[info->band]) in __iwl_mvm_rs_tx_status()
3263 if (!spin_trylock(&mvmsta->lq_sta.rs_drv.pers.lock)) in iwl_mvm_rs_tx_status()
3267 spin_unlock(&mvmsta->lq_sta.rs_drv.pers.lock); in iwl_mvm_rs_tx_status()
3278 int num_rates = ARRAY_SIZE(lq_cmd->rs_table); in rs_build_rates_table_from_fixed()
3283 lq_cmd->rs_table[i] = ucode_rate_le32; in rs_build_rates_table_from_fixed()
3291 lq_cmd->mimo_delim = num_rates - 1; in rs_build_rates_table_from_fixed()
3293 lq_cmd->mimo_delim = 0; in rs_build_rates_table_from_fixed()
3295 lq_cmd->reduced_tpc = 0; in rs_build_rates_table_from_fixed()
3298 lq_cmd->single_stream_ant_msk = ant; in rs_build_rates_table_from_fixed()
3300 if (!mvm->trans->trans_cfg->gen2) in rs_build_rates_table_from_fixed()
3301 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; in rs_build_rates_table_from_fixed()
3303 lq_cmd->agg_frame_cnt_limit = in rs_build_rates_table_from_fixed()
3318 int prev_rate_idx = rate->index; in rs_fill_rates_for_column()
3331 prev_rate_idx = rate->index; in rs_fill_rates_for_column()
3338 rate->index = prev_rate_idx; in rs_fill_rates_for_column()
3346 * rate[0] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
3347 * rate[1] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
3348 * rate[2] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
3349 * rate[3] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
3350 * rate[4] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
3351 * rate[5] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
3352 * rate[6] 0x4005007 VHT | ANT: A BW: 80Mhz MCS: 7 NSS: 1 NGI
3353 * rate[7] 0x4009006 VHT | ANT: B BW: 80Mhz MCS: 6 NSS: 1 NGI
3354 * rate[8] 0x4005005 VHT | ANT: A BW: 80Mhz MCS: 5 NSS: 1 NGI
3371 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; in rs_build_rates_table()
3380 if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_LQ_SS_PARAMS) && in rs_build_rates_table()
3396 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3405 lq_cmd->mimo_delim = index; in rs_build_rates_table()
3415 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3424 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3428 /* update the color of the LQ command (as a counter at bits 1-3) */ in rs_build_rates_table()
3429 color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags)); in rs_build_rates_table()
3430 lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color); in rs_build_rates_table()
3443 struct iwl_lq_cmd *lq_cmd = &mvmsta->lq_sta.rs_drv.lq; in rs_bfer_active_iter()
3444 u32 ss_params = le32_to_cpu(lq_cmd->ss_params); in rs_bfer_active_iter()
3446 if (sta == data->exclude_sta) in rs_bfer_active_iter()
3451 WARN_ON_ONCE(data->bfer_mvmsta != NULL); in rs_bfer_active_iter()
3453 data->bfer_mvmsta = mvmsta; in rs_bfer_active_iter()
3459 int prio = -1; in rs_bfer_priority()
3460 enum nl80211_iftype viftype = ieee80211_vif_type_p2p(sta->vif); in rs_bfer_priority()
3474 WARN_ONCE(true, "viftype %d sta_id %d", viftype, sta->sta_id); in rs_bfer_priority()
3475 prio = -1; in rs_bfer_priority()
3491 return -1; in rs_bfer_priority_cmp()
3500 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; in rs_set_lq_ss_params()
3516 if (lq_sta->pers.ss_force == RS_SS_FORCE_STBC) in rs_set_lq_ss_params()
3518 else if (lq_sta->pers.ss_force == RS_SS_FORCE_BFER) in rs_set_lq_ss_params()
3521 if (lq_sta->pers.ss_force != RS_SS_FORCE_NONE) { in rs_set_lq_ss_params()
3523 lq_sta->pers.ss_force); in rs_set_lq_ss_params()
3528 if (lq_sta->stbc_capable) in rs_set_lq_ss_params()
3531 if (!lq_sta->bfer_capable) in rs_set_lq_ss_params()
3534 ieee80211_iterate_stations_atomic(mvm->hw, in rs_set_lq_ss_params()
3551 bfer_mvmsta->sta_id); in rs_set_lq_ss_params()
3556 &bfer_mvmsta->lq_sta.rs_drv.lq; in rs_set_lq_ss_params()
3557 u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); in rs_set_lq_ss_params()
3560 bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); in rs_set_lq_ss_params()
3566 bfer_mvmsta->sta_id); in rs_set_lq_ss_params()
3569 lq_cmd->ss_params = cpu_to_le32(ss_params); in rs_set_lq_ss_params()
3577 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; in rs_fill_lq_cmd()
3581 lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START; in rs_fill_lq_cmd()
3582 lq_cmd->agg_time_limit = in rs_fill_lq_cmd()
3586 if (lq_sta->pers.dbg_fixed_rate) { in rs_fill_lq_cmd()
3588 lq_sta->band, in rs_fill_lq_cmd()
3589 lq_sta->pers.dbg_fixed_rate); in rs_fill_lq_cmd()
3598 if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_LQ_SS_PARAMS)) in rs_fill_lq_cmd()
3602 mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); in rs_fill_lq_cmd()
3604 if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2) && in rs_fill_lq_cmd()
3605 num_of_ant(initial_rate->ant) == 1) in rs_fill_lq_cmd()
3606 lq_cmd->single_stream_ant_msk = initial_rate->ant; in rs_fill_lq_cmd()
3608 lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize; in rs_fill_lq_cmd()
3616 lq_cmd->agg_frame_cnt_limit--; in rs_fill_lq_cmd()
3618 if (mvmsta->vif->p2p) in rs_fill_lq_cmd()
3619 lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK; in rs_fill_lq_cmd()
3621 lq_cmd->agg_time_limit = in rs_fill_lq_cmd()
3627 return hw->priv; in rs_alloc()
3649 u8 mcs = 0, nss = 0; in rs_pretty_print_rate_v1() local
3662 iwl_rate_mcs(index)->mbps); in rs_pretty_print_rate_v1()
3667 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; in rs_pretty_print_rate_v1()
3672 mcs = rate & RATE_HT_MCS_INDEX_MSK_V1; in rs_pretty_print_rate_v1()
3677 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; in rs_pretty_print_rate_v1()
3685 "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s", in rs_pretty_print_rate_v1()
3686 rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss, in rs_pretty_print_rate_v1()
3704 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ in rs_program_fix_rate()
3705 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ in rs_program_fix_rate()
3706 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ in rs_program_fix_rate()
3709 lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate); in rs_program_fix_rate()
3711 if (lq_sta->pers.dbg_fixed_rate) { in rs_program_fix_rate()
3713 iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq); in rs_program_fix_rate()
3720 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_scale_table_write()
3726 mvm = lq_sta->pers.drv; in rs_sta_dbgfs_scale_table_write()
3728 buf_size = min(count, sizeof(buf) - 1); in rs_sta_dbgfs_scale_table_write()
3730 return -EFAULT; in rs_sta_dbgfs_scale_table_write()
3733 lq_sta->pers.dbg_fixed_rate = parsed_rate; in rs_sta_dbgfs_scale_table_write()
3735 lq_sta->pers.dbg_fixed_rate = 0; in rs_sta_dbgfs_scale_table_write()
3751 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_scale_table_read()
3755 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in rs_sta_dbgfs_scale_table_read()
3756 struct rs_rate *rate = &tbl->rate; in rs_sta_dbgfs_scale_table_read()
3759 mvm = lq_sta->pers.drv; in rs_sta_dbgfs_scale_table_read()
3762 return -ENOMEM; in rs_sta_dbgfs_scale_table_read()
3764 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3765 "sta_id %d\n", lq_sta->lq.sta_id); in rs_sta_dbgfs_scale_table_read()
3766 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3768 lq_sta->total_failed, lq_sta->total_success, in rs_sta_dbgfs_scale_table_read()
3769 lq_sta->active_legacy_rate); in rs_sta_dbgfs_scale_table_read()
3770 desc += scnprintf(buff + desc, bufsz - desc, "fixed rate 0x%X\n", in rs_sta_dbgfs_scale_table_read()
3771 lq_sta->pers.dbg_fixed_rate); in rs_sta_dbgfs_scale_table_read()
3772 desc += scnprintf(buff + desc, bufsz - desc, "valid_tx_ant %s%s\n", in rs_sta_dbgfs_scale_table_read()
3775 desc += scnprintf(buff + desc, bufsz - desc, "lq type %s\n", in rs_sta_dbgfs_scale_table_read()
3779 desc += scnprintf(buff + desc, bufsz - desc, " %s", in rs_sta_dbgfs_scale_table_read()
3781 desc += scnprintf(buff + desc, bufsz - desc, " %s", in rs_sta_dbgfs_scale_table_read()
3786 desc += scnprintf(buff + desc, bufsz - desc, " %s %s %s %s\n", in rs_sta_dbgfs_scale_table_read()
3787 (rate->sgi) ? "SGI" : "NGI", in rs_sta_dbgfs_scale_table_read()
3788 (rate->ldpc) ? "LDPC" : "BCC", in rs_sta_dbgfs_scale_table_read()
3789 (lq_sta->is_agg) ? "AGG on" : "", in rs_sta_dbgfs_scale_table_read()
3790 (mvmsta->amsdu_enabled) ? "AMSDU on" : ""); in rs_sta_dbgfs_scale_table_read()
3792 desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X\n", in rs_sta_dbgfs_scale_table_read()
3793 lq_sta->last_rate_n_flags); in rs_sta_dbgfs_scale_table_read()
3794 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3795 "general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n", in rs_sta_dbgfs_scale_table_read()
3796 lq_sta->lq.flags, in rs_sta_dbgfs_scale_table_read()
3797 lq_sta->lq.mimo_delim, in rs_sta_dbgfs_scale_table_read()
3798 lq_sta->lq.single_stream_ant_msk, in rs_sta_dbgfs_scale_table_read()
3799 lq_sta->lq.dual_stream_ant_msk); in rs_sta_dbgfs_scale_table_read()
3801 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3803 le16_to_cpu(lq_sta->lq.agg_time_limit), in rs_sta_dbgfs_scale_table_read()
3804 lq_sta->lq.agg_disable_start_th, in rs_sta_dbgfs_scale_table_read()
3805 lq_sta->lq.agg_frame_cnt_limit); in rs_sta_dbgfs_scale_table_read()
3807 desc += scnprintf(buff + desc, bufsz - desc, "reduced tpc=%d\n", in rs_sta_dbgfs_scale_table_read()
3808 lq_sta->lq.reduced_tpc); in rs_sta_dbgfs_scale_table_read()
3809 ss_params = le32_to_cpu(lq_sta->lq.ss_params); in rs_sta_dbgfs_scale_table_read()
3810 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3820 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3822 lq_sta->lq.initial_rate_index[0], in rs_sta_dbgfs_scale_table_read()
3823 lq_sta->lq.initial_rate_index[1], in rs_sta_dbgfs_scale_table_read()
3824 lq_sta->lq.initial_rate_index[2], in rs_sta_dbgfs_scale_table_read()
3825 lq_sta->lq.initial_rate_index[3]); in rs_sta_dbgfs_scale_table_read()
3828 u32 r = le32_to_cpu(lq_sta->lq.rs_table[i]); in rs_sta_dbgfs_scale_table_read()
3830 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3832 desc += rs_pretty_print_rate_v1(buff + desc, bufsz - desc, r); in rs_sta_dbgfs_scale_table_read()
3833 if (desc < bufsz - 1) in rs_sta_dbgfs_scale_table_read()
3857 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_stats_table_read()
3861 return -ENOMEM; in rs_sta_dbgfs_stats_table_read()
3864 tbl = &(lq_sta->lq_info[i]); in rs_sta_dbgfs_stats_table_read()
3865 rate = &tbl->rate; in rs_sta_dbgfs_stats_table_read()
3869 lq_sta->active_tbl == i ? "*" : "x", in rs_sta_dbgfs_stats_table_read()
3870 rate->type, in rs_sta_dbgfs_stats_table_read()
3871 rate->sgi, in rs_sta_dbgfs_stats_table_read()
3876 rate->index); in rs_sta_dbgfs_stats_table_read()
3880 tbl->win[j].counter, in rs_sta_dbgfs_stats_table_read()
3881 tbl->win[j].success_counter, in rs_sta_dbgfs_stats_table_read()
3882 tbl->win[j].success_ratio); in rs_sta_dbgfs_stats_table_read()
3934 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_drv_tx_stats_read()
3940 return -ENOMEM; in rs_sta_dbgfs_drv_tx_stats_read()
3945 pos += scnprintf(pos, endpos - pos, "COLUMN,"); in rs_sta_dbgfs_drv_tx_stats_read()
3947 pos += scnprintf(pos, endpos - pos, "%s,", rate_name[rate]); in rs_sta_dbgfs_drv_tx_stats_read()
3948 pos += scnprintf(pos, endpos - pos, "\n"); in rs_sta_dbgfs_drv_tx_stats_read()
3951 pos += scnprintf(pos, endpos - pos, in rs_sta_dbgfs_drv_tx_stats_read()
3955 stats = &(lq_sta->pers.tx_stats[col][rate]); in rs_sta_dbgfs_drv_tx_stats_read()
3956 pos += scnprintf(pos, endpos - pos, in rs_sta_dbgfs_drv_tx_stats_read()
3958 stats->success, in rs_sta_dbgfs_drv_tx_stats_read()
3959 stats->total); in rs_sta_dbgfs_drv_tx_stats_read()
3961 pos += scnprintf(pos, endpos - pos, "\n"); in rs_sta_dbgfs_drv_tx_stats_read()
3964 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff); in rs_sta_dbgfs_drv_tx_stats_read()
3973 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_drv_tx_stats_write()
3974 memset(lq_sta->pers.tx_stats, 0, sizeof(lq_sta->pers.tx_stats)); in rs_sta_dbgfs_drv_tx_stats_write()
3990 struct iwl_lq_sta *lq_sta = file->private_data; in iwl_dbgfs_ss_force_read()
4001 pos += scnprintf(buf+pos, bufsz-pos, "%s\n", in iwl_dbgfs_ss_force_read()
4002 ss_force_name[lq_sta->pers.ss_force]); in iwl_dbgfs_ss_force_read()
4009 struct iwl_mvm *mvm = lq_sta->pers.drv; in iwl_dbgfs_ss_force_write()
4013 lq_sta->pers.ss_force = RS_SS_FORCE_NONE; in iwl_dbgfs_ss_force_write()
4015 lq_sta->pers.ss_force = RS_SS_FORCE_SISO; in iwl_dbgfs_ss_force_write()
4017 if (lq_sta->stbc_capable) { in iwl_dbgfs_ss_force_write()
4018 lq_sta->pers.ss_force = RS_SS_FORCE_STBC; in iwl_dbgfs_ss_force_write()
4022 ret = -EINVAL; in iwl_dbgfs_ss_force_write()
4025 if (lq_sta->bfer_capable) { in iwl_dbgfs_ss_force_write()
4026 lq_sta->pers.ss_force = RS_SS_FORCE_BFER; in iwl_dbgfs_ss_force_write()
4030 ret = -EINVAL; in iwl_dbgfs_ss_force_write()
4034 ret = -EINVAL; in iwl_dbgfs_ss_force_write()
4056 if (!mvmsta->vif) in rs_drv_add_sta_debugfs()
4066 &lq_sta->tx_agg_tid_en); in rs_drv_add_sta_debugfs()
4068 &lq_sta->pers.dbg_fixed_txp_reduction); in rs_drv_add_sta_debugfs()
4111 spin_lock(&mvmsta->lq_sta.rs_drv.pers.lock); in iwl_mvm_rs_rate_init()
4113 spin_unlock(&mvmsta->lq_sta.rs_drv.pers.lock); in iwl_mvm_rs_rate_init()
4130 struct iwl_lq_cmd *lq = &mvmsta->lq_sta.rs_drv.lq; in rs_drv_tx_protection()
4132 lockdep_assert_held(&mvm->mutex); in rs_drv_tx_protection()
4135 if (mvmsta->tx_protection == 0) in rs_drv_tx_protection()
4136 lq->flags |= LQ_FLAG_USE_RTS_MSK; in rs_drv_tx_protection()
4137 mvmsta->tx_protection++; in rs_drv_tx_protection()
4139 mvmsta->tx_protection--; in rs_drv_tx_protection()
4140 if (mvmsta->tx_protection == 0) in rs_drv_tx_protection()
4141 lq->flags &= ~LQ_FLAG_USE_RTS_MSK; in rs_drv_tx_protection()
4148 * iwl_mvm_tx_protection - ask FW to enable RTS/CTS protection