Lines Matching +full:cts +full:- +full:rts +full:- +full:swap
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright(c) 2005 - 2014, 2018 - 2020 Intel Corporation. All rights reserved.
5 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
6 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
10 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 #include "fw-api.h"
26 #include "iwl-op-mode.h"
103 RS_ACTION_DOWNSCALE = -1,
136 return iwl_mvm_bt_coex_is_ant_avail(mvm, next_col->ant); in rs_ant_allow()
143 if (!sta->ht_cap.ht_supported) in rs_mimo_allow()
146 if (sta->smps_mode == IEEE80211_SMPS_STATIC) in rs_mimo_allow()
155 if (mvm->nvm_data->sku_cap_mimo_disabled) in rs_mimo_allow()
165 if (!sta->ht_cap.ht_supported) in rs_siso_allow()
175 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; in rs_sgi_allow()
176 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; in rs_sgi_allow()
178 if (is_ht20(rate) && (ht_cap->cap & in rs_sgi_allow()
181 if (is_ht40(rate) && (ht_cap->cap & in rs_sgi_allow()
184 if (is_ht80(rate) && (vht_cap->cap & in rs_sgi_allow()
187 if (is_ht160(rate) && (vht_cap->cap & in rs_sgi_allow()
405 * 0 - NGI, 1 - SGI, 2 - AGG+NGI, 3 - AGG+SGI
552 if (is_type_legacy(rate->type) && (rate->index <= IWL_RATE_54M_INDEX)) in rs_pretty_rate()
553 rate_str = legacy_rates[rate->index]; in rs_pretty_rate()
554 else if ((is_type_ht(rate->type) || is_type_vht(rate->type)) && in rs_pretty_rate()
555 (rate->index >= IWL_RATE_MCS_0_INDEX) && in rs_pretty_rate()
556 (rate->index <= IWL_RATE_MCS_9_INDEX)) in rs_pretty_rate()
557 rate_str = ht_vht_rates[rate->index]; in rs_pretty_rate()
561 sprintf(buf, "(%s|%s|%s)", rs_pretty_lq_type(rate->type), in rs_pretty_rate()
562 rs_pretty_ant(rate->ant), rate_str); in rs_pretty_rate()
571 prefix, rs_pretty_rate(rate), rate->bw, in rs_dump_rate()
572 rate->sgi, rate->ldpc, rate->stbc); in rs_dump_rate()
577 window->data = 0; in rs_rate_scale_clear_window()
578 window->success_counter = 0; in rs_rate_scale_clear_window()
579 window->success_ratio = IWL_INVALID_VALUE; in rs_rate_scale_clear_window()
580 window->counter = 0; in rs_rate_scale_clear_window()
581 window->average_tpt = IWL_INVALID_VALUE; in rs_rate_scale_clear_window()
591 rs_rate_scale_clear_window(&tbl->win[i]); in rs_rate_scale_clear_tbl_windows()
593 for (i = 0; i < ARRAY_SIZE(tbl->tpc_win); i++) in rs_rate_scale_clear_tbl_windows()
594 rs_rate_scale_clear_window(&tbl->tpc_win[i]); in rs_rate_scale_clear_tbl_windows()
609 sta->addr, tid); in rs_tl_turn_on_agg_for_tid()
613 if (ret == -EAGAIN) { in rs_tl_turn_on_agg_for_tid()
644 tid_data = &mvmsta->tid_data[tid]; in rs_tl_turn_on_agg()
645 if (mvmsta->sta_state >= IEEE80211_STA_AUTHORIZED && in rs_tl_turn_on_agg()
646 tid_data->state == IWL_AGG_OFF && in rs_tl_turn_on_agg()
647 (lq_sta->tx_agg_tid_en & BIT(tid)) && in rs_tl_turn_on_agg()
648 tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) { in rs_tl_turn_on_agg()
651 tid_data->state = IWL_AGG_QUEUED; in rs_tl_turn_on_agg()
668 if (tbl->expected_tpt) in get_expected_tpt()
669 return tbl->expected_tpt[rs_index]; in get_expected_tpt()
674 * rs_collect_tx_data - Update the success/failure sliding window
677 * at this rate. window->data contains the bitmask of successful
685 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); in _rs_collect_tx_data()
700 if (window->counter >= IWL_RATE_MAX_WINDOW) { in _rs_collect_tx_data()
702 window->counter = IWL_RATE_MAX_WINDOW - 1; in _rs_collect_tx_data()
704 if (window->data & mask) { in _rs_collect_tx_data()
705 window->data &= ~mask; in _rs_collect_tx_data()
706 window->success_counter--; in _rs_collect_tx_data()
710 /* Increment frames-attempted counter */ in _rs_collect_tx_data()
711 window->counter++; in _rs_collect_tx_data()
714 window->data <<= 1; in _rs_collect_tx_data()
718 window->success_counter++; in _rs_collect_tx_data()
719 window->data |= 0x1; in _rs_collect_tx_data()
720 successes--; in _rs_collect_tx_data()
723 attempts--; in _rs_collect_tx_data()
726 /* Calculate current success ratio, avoid divide-by-0! */ in _rs_collect_tx_data()
727 if (window->counter > 0) in _rs_collect_tx_data()
728 window->success_ratio = 128 * (100 * window->success_counter) in _rs_collect_tx_data()
729 / window->counter; in _rs_collect_tx_data()
731 window->success_ratio = IWL_INVALID_VALUE; in _rs_collect_tx_data()
733 fail_count = window->counter - window->success_counter; in _rs_collect_tx_data()
737 (window->success_counter >= IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) in _rs_collect_tx_data()
738 window->average_tpt = (window->success_ratio * tpt + 64) / 128; in _rs_collect_tx_data()
740 window->average_tpt = IWL_INVALID_VALUE; in _rs_collect_tx_data()
754 return -EINVAL; in rs_collect_tpc_data()
756 window = &tbl->tpc_win[reduced_txp]; in rs_collect_tpc_data()
770 tid_data = &mvmsta->tid_data[tid]; in rs_update_tid_tpt_stats()
775 * BA session, so it should be updated only when A-MPDU is in rs_update_tid_tpt_stats()
778 if (tid_data->state != IWL_AGG_OFF) in rs_update_tid_tpt_stats()
781 if (time_is_before_jiffies(tid_data->tpt_meas_start + HZ) || in rs_update_tid_tpt_stats()
782 (tid_data->tx_count >= IWL_MVM_RS_AGG_START_THRESHOLD)) { in rs_update_tid_tpt_stats()
783 tid_data->tx_count_last = tid_data->tx_count; in rs_update_tid_tpt_stats()
784 tid_data->tx_count = 0; in rs_update_tid_tpt_stats()
785 tid_data->tpt_meas_start = jiffies; in rs_update_tid_tpt_stats()
787 tid_data->tx_count += successes; in rs_update_tid_tpt_stats()
799 return -EINVAL; in rs_collect_tlc_data()
801 if (tbl->column != RS_COLUMN_INVALID) { in rs_collect_tlc_data()
802 struct lq_sta_pers *pers = &mvmsta->lq_sta.rs_drv.pers; in rs_collect_tlc_data()
804 pers->tx_stats[tbl->column][scale_index].total += attempts; in rs_collect_tlc_data()
805 pers->tx_stats[tbl->column][scale_index].success += successes; in rs_collect_tlc_data()
811 window = &(tbl->win[scale_index]); in rs_collect_tlc_data()
821 int index = rate->index; in ucode_rate_from_rs_rate()
823 ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) & in ucode_rate_from_rs_rate()
833 /* set RTS protection for all non legacy rates in ucode_rate_from_rs_rate()
835 * RTS retries only, instead of the entire BA packet. in ucode_rate_from_rs_rate()
866 IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type); in ucode_rate_from_rs_rate()
869 if (is_siso(rate) && rate->stbc) { in ucode_rate_from_rs_rate()
875 ucode_rate |= rate->bw; in ucode_rate_from_rs_rate()
876 if (rate->sgi) in ucode_rate_from_rs_rate()
878 if (rate->ldpc) in ucode_rate_from_rs_rate()
894 rate->index = iwl_hwrate_to_plcp_idx(ucode_rate); in rs_rate_from_ucode_rate()
896 if (rate->index == IWL_RATE_INVALID) in rs_rate_from_ucode_rate()
897 return -EINVAL; in rs_rate_from_ucode_rate()
899 rate->ant = (ant_msk >> RATE_MCS_ANT_POS); in rs_rate_from_ucode_rate()
907 rate->type = LQ_LEGACY_A; in rs_rate_from_ucode_rate()
909 rate->type = LQ_LEGACY_G; in rs_rate_from_ucode_rate()
917 rate->sgi = true; in rs_rate_from_ucode_rate()
919 rate->ldpc = true; in rs_rate_from_ucode_rate()
921 rate->stbc = true; in rs_rate_from_ucode_rate()
923 rate->bfer = true; in rs_rate_from_ucode_rate()
925 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; in rs_rate_from_ucode_rate()
932 rate->type = LQ_HT_SISO; in rs_rate_from_ucode_rate()
933 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1, in rs_rate_from_ucode_rate()
935 rate->stbc, rate->bfer); in rs_rate_from_ucode_rate()
937 rate->type = LQ_HT_MIMO2; in rs_rate_from_ucode_rate()
947 rate->type = LQ_VHT_SISO; in rs_rate_from_ucode_rate()
948 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1, in rs_rate_from_ucode_rate()
950 rate->stbc, rate->bfer); in rs_rate_from_ucode_rate()
952 rate->type = LQ_VHT_MIMO2; in rs_rate_from_ucode_rate()
962 rate->type = LQ_HE_SISO; in rs_rate_from_ucode_rate()
963 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1, in rs_rate_from_ucode_rate()
964 "stbc %d bfer %d", rate->stbc, rate->bfer); in rs_rate_from_ucode_rate()
966 rate->type = LQ_HE_MIMO2; in rs_rate_from_ucode_rate()
973 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 && in rs_rate_from_ucode_rate()
985 if (!rate->ant || WARN_ON_ONCE(rate->ant & ANT_C)) in rs_toggle_antenna()
988 if (!rs_is_valid_ant(valid_ant, rate->ant)) in rs_toggle_antenna()
991 new_ant_type = ant_toggle_lookup[rate->ant]; in rs_toggle_antenna()
993 while ((new_ant_type != rate->ant) && in rs_toggle_antenna()
997 if (new_ant_type == rate->ant) in rs_toggle_antenna()
1000 rate->ant = new_ant_type; in rs_toggle_antenna()
1009 return lq_sta->active_legacy_rate; in rs_get_supported_rates()
1011 return lq_sta->active_siso_rate; in rs_get_supported_rates()
1013 return lq_sta->active_mimo2_rate; in rs_get_supported_rates()
1032 i = index - 1; in rs_get_adjacent_rate()
1035 for (; i >= 0; i--, mask >>= 1) { in rs_get_adjacent_rate()
1078 return BIT(rate->index) & rs_get_supported_rates(lq_sta, rate); in rs_rate_supported()
1090 struct iwl_mvm *mvm = lq_sta->pers.drv; in rs_get_lower_rate_in_column()
1093 high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask, in rs_get_lower_rate_in_column()
1094 rate->type); in rs_get_lower_rate_in_column()
1101 rate->index = low; in rs_get_lower_rate_in_column()
1109 struct iwl_mvm *mvm = lq_sta->pers.drv; in rs_get_lower_rate_down_column()
1116 if (lq_sta->band == NL80211_BAND_5GHZ) in rs_get_lower_rate_down_column()
1117 rate->type = LQ_LEGACY_A; in rs_get_lower_rate_down_column()
1119 rate->type = LQ_LEGACY_G; in rs_get_lower_rate_down_column()
1121 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_get_lower_rate_down_column()
1123 WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX || in rs_get_lower_rate_down_column()
1124 rate->index > IWL_RATE_MCS_9_INDEX); in rs_get_lower_rate_down_column()
1126 rate->index = rs_ht_to_legacy[rate->index]; in rs_get_lower_rate_down_column()
1127 rate->ldpc = false; in rs_get_lower_rate_down_column()
1130 rate->type = is_vht_mimo2(rate) ? in rs_get_lower_rate_down_column()
1134 if (num_of_ant(rate->ant) > 1) in rs_get_lower_rate_down_column()
1135 rate->ant = first_antenna(iwl_mvm_get_valid_tx_ant(mvm)); in rs_get_lower_rate_down_column()
1138 rate->sgi = false; in rs_get_lower_rate_down_column()
1150 if (a->stbc || a->bfer) in rs_rate_column_match()
1151 ant_match = (b->ant == ANT_A || b->ant == ANT_B); in rs_rate_column_match()
1153 ant_match = (a->ant == b->ant); in rs_rate_column_match()
1155 return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) in rs_rate_column_match()
1162 if (rate->ant == ANT_A) in rs_get_column_from_rate()
1165 if (rate->ant == ANT_B) in rs_get_column_from_rate()
1172 if (rate->ant == ANT_A || rate->stbc || rate->bfer) in rs_get_column_from_rate()
1173 return rate->sgi ? RS_COLUMN_SISO_ANT_A_SGI : in rs_get_column_from_rate()
1176 if (rate->ant == ANT_B) in rs_get_column_from_rate()
1177 return rate->sgi ? RS_COLUMN_SISO_ANT_B_SGI : in rs_get_column_from_rate()
1184 return rate->sgi ? RS_COLUMN_MIMO2_SGI : RS_COLUMN_MIMO2; in rs_get_column_from_rate()
1194 if (ieee80211_is_data_qos(hdr->frame_control)) { in rs_get_tid()
1213 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; in rs_drv_mac80211_tx_status()
1219 if (!mvmsta->vif) in rs_drv_mac80211_tx_status()
1222 if (!ieee80211_is_data(hdr->frame_control) || in rs_drv_mac80211_tx_status()
1223 info->flags & IEEE80211_TX_CTL_NO_ACK) in rs_drv_mac80211_tx_status()
1227 ieee80211_is_qos_nullfunc(hdr->frame_control)); in rs_drv_mac80211_tx_status()
1233 * Set frame tx success limits according to legacy vs. high-throughput,
1242 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN; in rs_set_stay_in_table()
1244 lq_sta->table_count_limit = IWL_MVM_RS_LEGACY_TABLE_COUNT; in rs_set_stay_in_table()
1245 lq_sta->max_failure_limit = IWL_MVM_RS_LEGACY_FAILURE_LIMIT; in rs_set_stay_in_table()
1246 lq_sta->max_success_limit = IWL_MVM_RS_LEGACY_SUCCESS_LIMIT; in rs_set_stay_in_table()
1248 lq_sta->table_count_limit = IWL_MVM_RS_NON_LEGACY_TABLE_COUNT; in rs_set_stay_in_table()
1249 lq_sta->max_failure_limit = IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT; in rs_set_stay_in_table()
1250 lq_sta->max_success_limit = IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT; in rs_set_stay_in_table()
1252 lq_sta->table_count = 0; in rs_set_stay_in_table()
1253 lq_sta->total_failed = 0; in rs_set_stay_in_table()
1254 lq_sta->total_success = 0; in rs_set_stay_in_table()
1255 lq_sta->flush_timer = jiffies; in rs_set_stay_in_table()
1256 lq_sta->visited_columns = 0; in rs_set_stay_in_table()
1269 switch (column->mode) { in rs_get_max_allowed_rate()
1271 return lq_sta->max_legacy_rate_idx; in rs_get_max_allowed_rate()
1273 return lq_sta->max_siso_rate_idx; in rs_get_max_allowed_rate()
1275 return lq_sta->max_mimo2_rate_idx; in rs_get_max_allowed_rate()
1280 return lq_sta->max_legacy_rate_idx; in rs_get_max_allowed_rate()
1290 if (WARN_ON_ONCE(column->mode != RS_LEGACY && in rs_get_expected_tpt_table()
1291 column->mode != RS_SISO && in rs_get_expected_tpt_table()
1292 column->mode != RS_MIMO2)) in rs_get_expected_tpt_table()
1296 if (column->mode == RS_LEGACY) in rs_get_expected_tpt_table()
1303 if (column->mode == RS_SISO) { in rs_get_expected_tpt_table()
1320 } else if (column->mode == RS_MIMO2) { in rs_get_expected_tpt_table()
1341 if (!column->sgi && !lq_sta->is_agg) /* Normal */ in rs_get_expected_tpt_table()
1343 else if (column->sgi && !lq_sta->is_agg) /* SGI */ in rs_get_expected_tpt_table()
1345 else if (!column->sgi && lq_sta->is_agg) /* AGG */ in rs_get_expected_tpt_table()
1354 struct rs_rate *rate = &tbl->rate; in rs_set_expected_tpt_table()
1355 const struct rs_tx_column *column = &rs_tx_columns[tbl->column]; in rs_set_expected_tpt_table()
1357 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw); in rs_set_expected_tpt_table()
1378 &(lq_sta->lq_info[lq_sta->active_tbl]); in rs_get_best_rate()
1379 s32 success_ratio = active_tbl->win[index].success_ratio; in rs_get_best_rate()
1380 u16 expected_current_tpt = active_tbl->expected_tpt[index]; in rs_get_best_rate()
1381 const u16 *tpt_tbl = tbl->expected_tpt; in rs_get_best_rate()
1392 target_tpt = lq_sta->last_tpt; in rs_get_best_rate()
1405 tbl->rate.type); in rs_get_best_rate()
1420 struct ieee80211_sta_vht_cap *sta_vht_cap = &sta->vht_cap; in rs_bw_from_sta_bw()
1422 .vht_cap_info = cpu_to_le32(sta_vht_cap->cap), in rs_bw_from_sta_bw()
1423 .supp_mcs = sta_vht_cap->vht_mcs, in rs_bw_from_sta_bw()
1426 switch (sta->bandwidth) { in rs_bw_from_sta_bw()
1432 * We only check MCS 0 - they will support that if in rs_bw_from_sta_bw()
1439 sta->rx_nss) < sta->rx_nss) in rs_bw_from_sta_bw()
1466 mvm = lq_sta->pers.drv; in rs_stay_in_table()
1467 active_tbl = lq_sta->active_tbl; in rs_stay_in_table()
1469 tbl = &(lq_sta->lq_info[active_tbl]); in rs_stay_in_table()
1472 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { in rs_stay_in_table()
1474 if (lq_sta->flush_timer) in rs_stay_in_table()
1477 (unsigned long)(lq_sta->flush_timer + in rs_stay_in_table()
1489 (lq_sta->total_failed > lq_sta->max_failure_limit) || in rs_stay_in_table()
1490 (lq_sta->total_success > lq_sta->max_success_limit) || in rs_stay_in_table()
1491 ((!lq_sta->search_better_tbl) && in rs_stay_in_table()
1492 (lq_sta->flush_timer) && (flush_interval_passed))) { in rs_stay_in_table()
1495 lq_sta->total_failed, in rs_stay_in_table()
1496 lq_sta->total_success, in rs_stay_in_table()
1500 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_STARTED; in rs_stay_in_table()
1503 lq_sta->total_failed = 0; in rs_stay_in_table()
1504 lq_sta->total_success = 0; in rs_stay_in_table()
1505 lq_sta->flush_timer = 0; in rs_stay_in_table()
1507 lq_sta->visited_columns = BIT(tbl->column); in rs_stay_in_table()
1511 * history bitmaps and rate-specific stats for all rates in in rs_stay_in_table()
1515 lq_sta->table_count++; in rs_stay_in_table()
1516 if (lq_sta->table_count >= in rs_stay_in_table()
1517 lq_sta->table_count_limit) { in rs_stay_in_table()
1518 lq_sta->table_count = 0; in rs_stay_in_table()
1529 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) { in rs_stay_in_table()
1542 sta->max_amsdu_len = rs_fw_get_max_amsdu_len(sta); in rs_set_amsdu_len()
1546 * or 0, since there is no per-TID alg. in rs_set_amsdu_len()
1548 if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) || in rs_set_amsdu_len()
1549 tbl->rate.index < IWL_RATE_MCS_5_INDEX || in rs_set_amsdu_len()
1551 mvmsta->amsdu_enabled = 0; in rs_set_amsdu_len()
1553 mvmsta->amsdu_enabled = 0xFFFF; in rs_set_amsdu_len()
1555 if (mvmsta->vif->bss_conf.he_support && in rs_set_amsdu_len()
1557 mvmsta->max_amsdu_len = sta->max_amsdu_len; in rs_set_amsdu_len()
1559 mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500); in rs_set_amsdu_len()
1561 sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; in rs_set_amsdu_len()
1564 if (mvmsta->amsdu_enabled) in rs_set_amsdu_len()
1565 sta->max_tid_amsdu_len[i] = in rs_set_amsdu_len()
1572 sta->max_tid_amsdu_len[i] = 1; in rs_set_amsdu_len()
1584 rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate); in rs_update_rate_tbl()
1585 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); in rs_update_rate_tbl()
1597 if (!is_vht_siso(&tbl->rate)) in rs_tweak_rate_tbl()
1600 if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_80) && in rs_tweak_rate_tbl()
1601 (tbl->rate.index == IWL_RATE_MCS_0_INDEX) && in rs_tweak_rate_tbl()
1603 tbl->rate.bw = RATE_MCS_CHAN_WIDTH_20; in rs_tweak_rate_tbl()
1604 tbl->rate.index = IWL_RATE_MCS_4_INDEX; in rs_tweak_rate_tbl()
1605 IWL_DEBUG_RATE(mvm, "Switch 80Mhz SISO MCS0 -> 20Mhz MCS4\n"); in rs_tweak_rate_tbl()
1614 if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_20) && in rs_tweak_rate_tbl()
1615 (((tbl->rate.index == IWL_RATE_MCS_5_INDEX) && in rs_tweak_rate_tbl()
1617 ((tbl->rate.index > IWL_RATE_MCS_5_INDEX) && in rs_tweak_rate_tbl()
1619 tbl->rate.bw = RATE_MCS_CHAN_WIDTH_80; in rs_tweak_rate_tbl()
1620 tbl->rate.index = IWL_RATE_MCS_1_INDEX; in rs_tweak_rate_tbl()
1621 IWL_DEBUG_RATE(mvm, "Switch 20Mhz SISO MCS5 -> 80Mhz MCS1\n"); in rs_tweak_rate_tbl()
1640 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column]; in rs_get_next_column()
1648 next_col_id = curr_col->next_columns[i]; in rs_get_next_column()
1653 if (lq_sta->visited_columns & BIT(next_col_id)) { in rs_get_next_column()
1661 if (!rs_is_valid_ant(valid_ants, next_col->ant)) { in rs_get_next_column()
1664 next_col_id, valid_ants, next_col->ant); in rs_get_next_column()
1669 allow_func = next_col->checks[j]; in rs_get_next_column()
1670 if (allow_func && !allow_func(mvm, sta, &tbl->rate, in rs_get_next_column()
1683 tpt = lq_sta->last_tpt / 100; in rs_get_next_column()
1722 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in rs_switch_to_column()
1724 &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in rs_switch_to_column()
1725 struct rs_rate *rate = &search_tbl->rate; in rs_switch_to_column()
1727 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column]; in rs_switch_to_column()
1733 rate->sgi = column->sgi; in rs_switch_to_column()
1734 rate->ant = column->ant; in rs_switch_to_column()
1736 if (column->mode == RS_LEGACY) { in rs_switch_to_column()
1737 if (lq_sta->band == NL80211_BAND_5GHZ) in rs_switch_to_column()
1738 rate->type = LQ_LEGACY_A; in rs_switch_to_column()
1740 rate->type = LQ_LEGACY_G; in rs_switch_to_column()
1742 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_switch_to_column()
1743 rate->ldpc = false; in rs_switch_to_column()
1744 rate_mask = lq_sta->active_legacy_rate; in rs_switch_to_column()
1745 } else if (column->mode == RS_SISO) { in rs_switch_to_column()
1746 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; in rs_switch_to_column()
1747 rate_mask = lq_sta->active_siso_rate; in rs_switch_to_column()
1748 } else if (column->mode == RS_MIMO2) { in rs_switch_to_column()
1749 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; in rs_switch_to_column()
1750 rate_mask = lq_sta->active_mimo2_rate; in rs_switch_to_column()
1755 if (column->mode != RS_LEGACY) { in rs_switch_to_column()
1756 rate->bw = rs_bw_from_sta_bw(sta); in rs_switch_to_column()
1757 rate->ldpc = lq_sta->ldpc; in rs_switch_to_column()
1760 search_tbl->column = col_id; in rs_switch_to_column()
1763 lq_sta->visited_columns |= BIT(col_id); in rs_switch_to_column()
1766 * SISO->MIMO, LEGACY->SISO, MIMO->SISO in rs_switch_to_column()
1768 if (curr_column->mode != column->mode) { in rs_switch_to_column()
1770 rate_mask, rate->index); in rs_switch_to_column()
1782 rate->index = rate_idx; in rs_switch_to_column()
1786 col_id, rate->index); in rs_switch_to_column()
1791 rate->type = LQ_NONE; in rs_switch_to_column()
1792 return -1; in rs_switch_to_column()
1867 } else if (current_tpt > (100 * tbl->expected_tpt[low])) { in rs_get_rate_action()
1885 if (!lq_sta->stbc_capable) in rs_stbc_allow()
1901 *stronger = index - IWL_MVM_RS_TPC_TX_POWER_STEP; in rs_get_adjacent_txp()
1909 int index = rate->index; in rs_tpc_allowed()
1911 bool sta_ps_disabled = (vif->type == NL80211_IFTYPE_STATION && in rs_tpc_allowed()
1912 !vif->bss_conf.ps); in rs_tpc_allowed()
1924 IWL_DEBUG_RATE(mvm, "check rate, table type: %d\n", rate->type); in rs_tpc_allowed()
2001 IWL_DEBUG_RATE(mvm, "no need to increase or decrease txp - stay\n"); in rs_get_tpc_action()
2011 struct ieee80211_vif *vif = mvm_sta->vif; in rs_tpc_perform()
2015 struct rs_rate *rate = &tbl->rate; in rs_tpc_perform()
2018 u8 cur = lq_sta->lq.reduced_tpc; in rs_tpc_perform()
2024 if (lq_sta->pers.dbg_fixed_txp_reduction <= TPC_MAX_REDUCTION) { in rs_tpc_perform()
2026 lq_sta->pers.dbg_fixed_txp_reduction); in rs_tpc_perform()
2027 lq_sta->lq.reduced_tpc = lq_sta->pers.dbg_fixed_txp_reduction; in rs_tpc_perform()
2028 return cur != lq_sta->pers.dbg_fixed_txp_reduction; in rs_tpc_perform()
2033 chanctx_conf = rcu_dereference(vif->chanctx_conf); in rs_tpc_perform()
2037 band = chanctx_conf->def.chan->band; in rs_tpc_perform()
2043 lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; in rs_tpc_perform()
2050 window = tbl->tpc_win; in rs_tpc_perform()
2079 lq_sta->lq.reduced_tpc = weak; in rs_tpc_perform()
2082 lq_sta->lq.reduced_tpc = strong; in rs_tpc_perform()
2085 lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; in rs_tpc_perform()
2118 u8 prev_agg = lq_sta->is_agg; in rs_rate_scale_perform()
2122 lq_sta->is_agg = !!mvmsta->agg_tids; in rs_rate_scale_perform()
2125 * Select rate-scale / modulation-mode table to work with in in rs_rate_scale_perform()
2129 if (!lq_sta->search_better_tbl) in rs_rate_scale_perform()
2130 active_tbl = lq_sta->active_tbl; in rs_rate_scale_perform()
2132 active_tbl = rs_search_tbl(lq_sta->active_tbl); in rs_rate_scale_perform()
2134 tbl = &(lq_sta->lq_info[active_tbl]); in rs_rate_scale_perform()
2135 rate = &tbl->rate; in rs_rate_scale_perform()
2137 if (prev_agg != lq_sta->is_agg) { in rs_rate_scale_perform()
2140 prev_agg, lq_sta->is_agg); in rs_rate_scale_perform()
2146 index = rate->index; in rs_rate_scale_perform()
2153 if (lq_sta->search_better_tbl) { in rs_rate_scale_perform()
2155 rate->type = LQ_NONE; in rs_rate_scale_perform()
2156 lq_sta->search_better_tbl = 0; in rs_rate_scale_perform()
2157 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in rs_rate_scale_perform()
2164 if (!tbl->expected_tpt) { in rs_rate_scale_perform()
2165 IWL_ERR(mvm, "tbl->expected_tpt is NULL\n"); in rs_rate_scale_perform()
2170 window = &(tbl->win[index]); in rs_rate_scale_perform()
2179 fail_count = window->counter - window->success_counter; in rs_rate_scale_perform()
2181 (window->success_counter < IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) { in rs_rate_scale_perform()
2185 window->success_counter, window->counter); in rs_rate_scale_perform()
2188 window->average_tpt = IWL_INVALID_VALUE; in rs_rate_scale_perform()
2198 if (lq_sta->search_better_tbl) { in rs_rate_scale_perform()
2202 if (window->average_tpt > lq_sta->last_tpt) { in rs_rate_scale_perform()
2205 "cur-tpt %d old-tpt %d\n", in rs_rate_scale_perform()
2206 window->success_ratio, in rs_rate_scale_perform()
2207 window->average_tpt, in rs_rate_scale_perform()
2208 lq_sta->last_tpt); in rs_rate_scale_perform()
2210 /* Swap tables; "search" becomes "active" */ in rs_rate_scale_perform()
2211 lq_sta->active_tbl = active_tbl; in rs_rate_scale_perform()
2212 current_tpt = window->average_tpt; in rs_rate_scale_perform()
2217 "cur-tpt %d old-tpt %d\n", in rs_rate_scale_perform()
2218 window->success_ratio, in rs_rate_scale_perform()
2219 window->average_tpt, in rs_rate_scale_perform()
2220 lq_sta->last_tpt); in rs_rate_scale_perform()
2223 rate->type = LQ_NONE; in rs_rate_scale_perform()
2226 active_tbl = lq_sta->active_tbl; in rs_rate_scale_perform()
2227 tbl = &(lq_sta->lq_info[active_tbl]); in rs_rate_scale_perform()
2230 index = tbl->rate.index; in rs_rate_scale_perform()
2231 current_tpt = lq_sta->last_tpt; in rs_rate_scale_perform()
2239 lq_sta->search_better_tbl = 0; in rs_rate_scale_perform()
2246 high_low = rs_get_adjacent_rate(mvm, index, rate_mask, rate->type); in rs_rate_scale_perform()
2252 sr = window->success_ratio; in rs_rate_scale_perform()
2255 current_tpt = window->average_tpt; in rs_rate_scale_perform()
2257 low_tpt = tbl->win[low].average_tpt; in rs_rate_scale_perform()
2259 high_tpt = tbl->win[high].average_tpt; in rs_rate_scale_perform()
2303 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) in rs_rate_scale_perform()
2313 tbl->rate.index = index; in rs_rate_scale_perform()
2329 lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED in rs_rate_scale_perform()
2330 && window->counter) { in rs_rate_scale_perform()
2334 lq_sta->last_tpt = current_tpt; in rs_rate_scale_perform()
2337 "Start Search: update_lq %d done_search %d rs_state %d win->counter %d\n", in rs_rate_scale_perform()
2338 update_lq, done_search, lq_sta->rs_state, in rs_rate_scale_perform()
2339 window->counter); in rs_rate_scale_perform()
2346 lq_sta->search_better_tbl = 1; in rs_rate_scale_perform()
2350 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_ENDED; in rs_rate_scale_perform()
2354 if (lq_sta->search_better_tbl) { in rs_rate_scale_perform()
2356 tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in rs_rate_scale_perform()
2360 index = tbl->rate.index; in rs_rate_scale_perform()
2362 rs_dump_rate(mvm, &tbl->rate, in rs_rate_scale_perform()
2373 if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) { in rs_rate_scale_perform()
2374 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); in rs_rate_scale_perform()
2375 rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_sta); in rs_rate_scale_perform()
2385 { -60, IWL_RATE_54M_INDEX },
2386 { -64, IWL_RATE_48M_INDEX },
2387 { -68, IWL_RATE_36M_INDEX },
2388 { -80, IWL_RATE_24M_INDEX },
2389 { -84, IWL_RATE_18M_INDEX },
2390 { -85, IWL_RATE_12M_INDEX },
2391 { -86, IWL_RATE_11M_INDEX },
2392 { -88, IWL_RATE_5M_INDEX },
2393 { -90, IWL_RATE_2M_INDEX },
2398 { -60, IWL_RATE_54M_INDEX },
2399 { -64, IWL_RATE_48M_INDEX },
2400 { -72, IWL_RATE_36M_INDEX },
2401 { -80, IWL_RATE_24M_INDEX },
2402 { -84, IWL_RATE_18M_INDEX },
2403 { -85, IWL_RATE_12M_INDEX },
2404 { -87, IWL_RATE_9M_INDEX },
2409 { -60, IWL_RATE_MCS_7_INDEX },
2410 { -64, IWL_RATE_MCS_6_INDEX },
2411 { -68, IWL_RATE_MCS_5_INDEX },
2412 { -72, IWL_RATE_MCS_4_INDEX },
2413 { -80, IWL_RATE_MCS_3_INDEX },
2414 { -84, IWL_RATE_MCS_2_INDEX },
2415 { -85, IWL_RATE_MCS_1_INDEX },
2423 { -60, IWL_RATE_MCS_8_INDEX },
2424 { -64, IWL_RATE_MCS_7_INDEX },
2425 { -68, IWL_RATE_MCS_6_INDEX },
2426 { -72, IWL_RATE_MCS_5_INDEX },
2427 { -80, IWL_RATE_MCS_4_INDEX },
2428 { -84, IWL_RATE_MCS_3_INDEX },
2429 { -85, IWL_RATE_MCS_2_INDEX },
2430 { -87, IWL_RATE_MCS_1_INDEX },
2435 { -60, IWL_RATE_MCS_9_INDEX },
2436 { -64, IWL_RATE_MCS_8_INDEX },
2437 { -68, IWL_RATE_MCS_7_INDEX },
2438 { -72, IWL_RATE_MCS_6_INDEX },
2439 { -80, IWL_RATE_MCS_5_INDEX },
2440 { -84, IWL_RATE_MCS_4_INDEX },
2441 { -85, IWL_RATE_MCS_3_INDEX },
2442 { -87, IWL_RATE_MCS_2_INDEX },
2443 { -88, IWL_RATE_MCS_1_INDEX },
2447 #define IWL_RS_LOW_RSSI_THRESHOLD (-76) /* dBm */
2457 struct rs_rate *rate = &lq_sta->optimal_rate; in rs_init_optimal_rate()
2459 if (lq_sta->max_mimo2_rate_idx != IWL_RATE_INVALID) in rs_init_optimal_rate()
2460 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; in rs_init_optimal_rate()
2461 else if (lq_sta->max_siso_rate_idx != IWL_RATE_INVALID) in rs_init_optimal_rate()
2462 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; in rs_init_optimal_rate()
2463 else if (lq_sta->band == NL80211_BAND_5GHZ) in rs_init_optimal_rate()
2464 rate->type = LQ_LEGACY_A; in rs_init_optimal_rate()
2466 rate->type = LQ_LEGACY_G; in rs_init_optimal_rate()
2468 rate->bw = rs_bw_from_sta_bw(sta); in rs_init_optimal_rate()
2469 rate->sgi = rs_sgi_allow(mvm, sta, rate, NULL); in rs_init_optimal_rate()
2474 lq_sta->optimal_rate_mask = lq_sta->active_mimo2_rate; in rs_init_optimal_rate()
2476 lq_sta->optimal_rate_mask = lq_sta->active_siso_rate; in rs_init_optimal_rate()
2478 lq_sta->optimal_rate_mask = lq_sta->active_legacy_rate; in rs_init_optimal_rate()
2480 if (lq_sta->band == NL80211_BAND_5GHZ) { in rs_init_optimal_rate()
2481 lq_sta->optimal_rates = rs_optimal_rates_5ghz_legacy; in rs_init_optimal_rate()
2482 lq_sta->optimal_nentries = in rs_init_optimal_rate()
2485 lq_sta->optimal_rates = rs_optimal_rates_24ghz_legacy; in rs_init_optimal_rate()
2486 lq_sta->optimal_nentries = in rs_init_optimal_rate()
2492 if (rate->bw == RATE_MCS_CHAN_WIDTH_20) { in rs_init_optimal_rate()
2493 lq_sta->optimal_rates = rs_optimal_rates_vht_20mhz; in rs_init_optimal_rate()
2494 lq_sta->optimal_nentries = in rs_init_optimal_rate()
2497 lq_sta->optimal_rates = rs_optimal_rates_vht; in rs_init_optimal_rate()
2498 lq_sta->optimal_nentries = in rs_init_optimal_rate()
2502 lq_sta->optimal_rates = rs_optimal_rates_ht; in rs_init_optimal_rate()
2503 lq_sta->optimal_nentries = ARRAY_SIZE(rs_optimal_rates_ht); in rs_init_optimal_rate()
2511 struct rs_rate *rate = &lq_sta->optimal_rate; in rs_get_optimal_rate()
2514 rate->index = find_first_bit(&lq_sta->optimal_rate_mask, in rs_get_optimal_rate()
2517 for (i = 0; i < lq_sta->optimal_nentries; i++) { in rs_get_optimal_rate()
2518 int rate_idx = lq_sta->optimal_rates[i].rate_idx; in rs_get_optimal_rate()
2520 if ((lq_sta->pers.last_rssi >= lq_sta->optimal_rates[i].rssi) && in rs_get_optimal_rate()
2521 (BIT(rate_idx) & lq_sta->optimal_rate_mask)) { in rs_get_optimal_rate()
2522 rate->index = rate_idx; in rs_get_optimal_rate()
2547 for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { in rs_get_initial_rate()
2548 if (!(lq_sta->pers.chains & BIT(i))) in rs_get_initial_rate()
2551 if (lq_sta->pers.chain_signal[i] > best_rssi) { in rs_get_initial_rate()
2552 best_rssi = lq_sta->pers.chain_signal[i]; in rs_get_initial_rate()
2561 rate->ant = first_antenna(valid_tx_ant); in rs_get_initial_rate()
2563 rate->ant = best_ant; in rs_get_initial_rate()
2565 rate->sgi = false; in rs_get_initial_rate()
2566 rate->ldpc = false; in rs_get_initial_rate()
2567 rate->bw = RATE_MCS_CHAN_WIDTH_20; in rs_get_initial_rate()
2569 rate->index = find_first_bit(&lq_sta->active_legacy_rate, in rs_get_initial_rate()
2573 rate->type = LQ_LEGACY_A; in rs_get_initial_rate()
2577 rate->type = LQ_LEGACY_G; in rs_get_initial_rate()
2590 if (sta->vht_cap.vht_supported && in rs_get_initial_rate()
2599 * is already up-to-date, re-init rs with the correct bw. in rs_get_initial_rate()
2601 u32 bw = mvmsta->sta_state < IEEE80211_STA_AUTHORIZED ? in rs_get_initial_rate()
2616 IWL_ERR(mvm, "Invalid BW %d\n", sta->bandwidth); in rs_get_initial_rate()
2620 active_rate = lq_sta->active_siso_rate; in rs_get_initial_rate()
2621 rate->type = LQ_VHT_SISO; in rs_get_initial_rate()
2622 rate->bw = bw; in rs_get_initial_rate()
2623 } else if (sta->ht_cap.ht_supported && in rs_get_initial_rate()
2627 active_rate = lq_sta->active_siso_rate; in rs_get_initial_rate()
2628 rate->type = LQ_HT_SISO; in rs_get_initial_rate()
2630 active_rate = lq_sta->active_legacy_rate; in rs_get_initial_rate()
2638 rate->index = rate_idx; in rs_get_initial_rate()
2652 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; in rs_update_last_rssi()
2655 lq_sta->pers.chains = rx_status->chains; in rs_update_last_rssi()
2656 lq_sta->pers.chain_signal[0] = rx_status->chain_signal[0]; in rs_update_last_rssi()
2657 lq_sta->pers.chain_signal[1] = rx_status->chain_signal[1]; in rs_update_last_rssi()
2658 lq_sta->pers.chain_signal[2] = rx_status->chain_signal[2]; in rs_update_last_rssi()
2659 lq_sta->pers.last_rssi = S8_MIN; in rs_update_last_rssi()
2661 for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { in rs_update_last_rssi()
2662 if (!(lq_sta->pers.chains & BIT(i))) in rs_update_last_rssi()
2665 if (lq_sta->pers.chain_signal[i] > lq_sta->pers.last_rssi) in rs_update_last_rssi()
2666 lq_sta->pers.last_rssi = lq_sta->pers.chain_signal[i]; in rs_update_last_rssi()
2671 * rs_initialize_lq - Initialize a station's hardware rate table
2677 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
2696 if (!lq_sta->search_better_tbl) in rs_initialize_lq()
2697 active_tbl = lq_sta->active_tbl; in rs_initialize_lq()
2699 active_tbl = rs_search_tbl(lq_sta->active_tbl); in rs_initialize_lq()
2701 tbl = &(lq_sta->lq_info[active_tbl]); in rs_initialize_lq()
2702 rate = &tbl->rate; in rs_initialize_lq()
2707 WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B, in rs_initialize_lq()
2709 rate->ant, lq_sta->pers.chains, mvm->fw->valid_tx_ant, in rs_initialize_lq()
2710 mvm->nvm_data ? mvm->nvm_data->valid_tx_ant : ANT_INVALID); in rs_initialize_lq()
2712 tbl->column = rs_get_column_from_rate(rate); in rs_initialize_lq()
2717 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); in rs_initialize_lq()
2726 struct sk_buff *skb = txrc->skb; in rs_drv_get_rate()
2732 if (sta && !iwl_mvm_sta_from_mac80211(sta)->vif) { in rs_drv_get_rate()
2744 iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags, in rs_drv_get_rate()
2745 info->band, &info->control.rates[0]); in rs_drv_get_rate()
2746 info->control.rates[0].count = 1; in rs_drv_get_rate()
2751 if (lq_sta->rs_state != RS_STATE_STAY_IN_COLUMN) { in rs_drv_get_rate()
2755 iwl_mvm_hwrate_to_tx_rate(last_ucode_rate, info->band, in rs_drv_get_rate()
2756 &txrc->reported_rate); in rs_drv_get_rate()
2766 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; in rs_drv_alloc_sta()
2770 lq_sta->pers.drv = mvm; in rs_drv_alloc_sta()
2772 lq_sta->pers.dbg_fixed_rate = 0; in rs_drv_alloc_sta()
2773 lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID; in rs_drv_alloc_sta()
2774 lq_sta->pers.ss_force = RS_SS_FORCE_NONE; in rs_drv_alloc_sta()
2776 lq_sta->pers.chains = 0; in rs_drv_alloc_sta()
2777 memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); in rs_drv_alloc_sta()
2778 lq_sta->pers.last_rssi = S8_MIN; in rs_drv_alloc_sta()
2786 u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) & in rs_vht_highest_rx_mcs_index()
2787 (0x3 << (2 * (nss - 1))); in rs_vht_highest_rx_mcs_index()
2788 rx_mcs >>= (2 * (nss - 1)); in rs_vht_highest_rx_mcs_index()
2798 return -1; in rs_vht_highest_rx_mcs_index()
2815 sta->bandwidth == IEEE80211_STA_RX_BW_20) in rs_vht_set_enabled_rates()
2818 lq_sta->active_siso_rate |= BIT(i); in rs_vht_set_enabled_rates()
2822 if (sta->rx_nss < 2) in rs_vht_set_enabled_rates()
2833 sta->bandwidth == IEEE80211_STA_RX_BW_20) in rs_vht_set_enabled_rates()
2836 lq_sta->active_mimo2_rate |= BIT(i); in rs_vht_set_enabled_rates()
2847 * and CCK (bits 0-3), supp_rates[] does not; in rs_ht_init()
2850 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; in rs_ht_init()
2851 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; in rs_ht_init()
2852 lq_sta->active_siso_rate &= ~((u16)0x2); in rs_ht_init()
2853 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; in rs_ht_init()
2855 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; in rs_ht_init()
2856 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; in rs_ht_init()
2857 lq_sta->active_mimo2_rate &= ~((u16)0x2); in rs_ht_init()
2858 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; in rs_ht_init()
2860 if (mvm->cfg->ht_params->ldpc && in rs_ht_init()
2861 (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) in rs_ht_init()
2862 lq_sta->ldpc = true; in rs_ht_init()
2864 if (mvm->cfg->ht_params->stbc && in rs_ht_init()
2866 (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) in rs_ht_init()
2867 lq_sta->stbc_capable = true; in rs_ht_init()
2869 lq_sta->is_vht = false; in rs_ht_init()
2879 if (mvm->cfg->ht_params->ldpc && in rs_vht_init()
2880 (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)) in rs_vht_init()
2881 lq_sta->ldpc = true; in rs_vht_init()
2883 if (mvm->cfg->ht_params->stbc && in rs_vht_init()
2885 (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)) in rs_vht_init()
2886 lq_sta->stbc_capable = true; in rs_vht_init()
2888 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_BEAMFORMER) && in rs_vht_init()
2890 (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) in rs_vht_init()
2891 lq_sta->bfer_capable = true; in rs_vht_init()
2893 lq_sta->is_vht = true; in rs_vht_init()
2899 spin_lock_bh(&mvm->drv_stats_lock); in iwl_mvm_reset_frame_stats()
2900 memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats)); in iwl_mvm_reset_frame_stats()
2901 spin_unlock_bh(&mvm->drv_stats_lock); in iwl_mvm_reset_frame_stats()
2908 spin_lock(&mvm->drv_stats_lock); in iwl_mvm_update_frame_stats()
2911 mvm->drv_rx_stats.agg_frames++; in iwl_mvm_update_frame_stats()
2913 mvm->drv_rx_stats.success_frames++; in iwl_mvm_update_frame_stats()
2917 mvm->drv_rx_stats.bw_20_frames++; in iwl_mvm_update_frame_stats()
2920 mvm->drv_rx_stats.bw_40_frames++; in iwl_mvm_update_frame_stats()
2923 mvm->drv_rx_stats.bw_80_frames++; in iwl_mvm_update_frame_stats()
2926 mvm->drv_rx_stats.bw_160_frames++; in iwl_mvm_update_frame_stats()
2933 mvm->drv_rx_stats.ht_frames++; in iwl_mvm_update_frame_stats()
2936 mvm->drv_rx_stats.vht_frames++; in iwl_mvm_update_frame_stats()
2940 mvm->drv_rx_stats.legacy_frames++; in iwl_mvm_update_frame_stats()
2944 mvm->drv_rx_stats.siso_frames++; in iwl_mvm_update_frame_stats()
2946 mvm->drv_rx_stats.mimo2_frames++; in iwl_mvm_update_frame_stats()
2949 mvm->drv_rx_stats.sgi_frames++; in iwl_mvm_update_frame_stats()
2951 mvm->drv_rx_stats.ngi_frames++; in iwl_mvm_update_frame_stats()
2953 mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate; in iwl_mvm_update_frame_stats()
2954 mvm->drv_rx_stats.last_frame_idx = in iwl_mvm_update_frame_stats()
2955 (mvm->drv_rx_stats.last_frame_idx + 1) % in iwl_mvm_update_frame_stats()
2956 ARRAY_SIZE(mvm->drv_rx_stats.last_rates); in iwl_mvm_update_frame_stats()
2958 spin_unlock(&mvm->drv_stats_lock); in iwl_mvm_update_frame_stats()
2969 struct ieee80211_hw *hw = mvm->hw; in rs_drv_rate_init()
2970 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; in rs_drv_rate_init()
2971 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; in rs_drv_rate_init()
2973 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; in rs_drv_rate_init()
2977 lockdep_assert_held(&mvmsta->lq_sta.rs_drv.pers.lock); in rs_drv_rate_init()
2979 /* clear all non-persistent lq data */ in rs_drv_rate_init()
2982 sband = hw->wiphy->bands[band]; in rs_drv_rate_init()
2984 lq_sta->lq.sta_id = mvmsta->sta_id; in rs_drv_rate_init()
2985 mvmsta->amsdu_enabled = 0; in rs_drv_rate_init()
2986 mvmsta->max_amsdu_len = sta->max_amsdu_len; in rs_drv_rate_init()
2989 rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]); in rs_drv_rate_init()
2991 lq_sta->flush_timer = 0; in rs_drv_rate_init()
2992 lq_sta->last_tx = jiffies; in rs_drv_rate_init()
2996 mvmsta->sta_id); in rs_drv_rate_init()
3002 lq_sta->missed_rate_counter = IWL_MVM_RS_MISSED_RATE_MAX; in rs_drv_rate_init()
3003 lq_sta->band = sband->band; in rs_drv_rate_init()
3007 supp = sta->supp_rates[sband->band]; in rs_drv_rate_init()
3008 lq_sta->active_legacy_rate = 0; in rs_drv_rate_init()
3010 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); in rs_drv_rate_init()
3013 if (!vht_cap || !vht_cap->vht_supported) in rs_drv_rate_init()
3018 lq_sta->max_legacy_rate_idx = in rs_drv_rate_init()
3019 rs_get_max_rate_from_mask(lq_sta->active_legacy_rate); in rs_drv_rate_init()
3020 lq_sta->max_siso_rate_idx = in rs_drv_rate_init()
3021 rs_get_max_rate_from_mask(lq_sta->active_siso_rate); in rs_drv_rate_init()
3022 lq_sta->max_mimo2_rate_idx = in rs_drv_rate_init()
3023 rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate); in rs_drv_rate_init()
3027 lq_sta->active_legacy_rate, in rs_drv_rate_init()
3028 lq_sta->active_siso_rate, in rs_drv_rate_init()
3029 lq_sta->active_mimo2_rate, in rs_drv_rate_init()
3030 lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable, in rs_drv_rate_init()
3031 lq_sta->bfer_capable); in rs_drv_rate_init()
3033 lq_sta->max_legacy_rate_idx, in rs_drv_rate_init()
3034 lq_sta->max_siso_rate_idx, in rs_drv_rate_init()
3035 lq_sta->max_mimo2_rate_idx); in rs_drv_rate_init()
3038 lq_sta->lq.single_stream_ant_msk = in rs_drv_rate_init()
3040 lq_sta->lq.dual_stream_ant_msk = ANT_AB; in rs_drv_rate_init()
3043 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; in rs_drv_rate_init()
3044 lq_sta->is_agg = 0; in rs_drv_rate_init()
3061 if (!iwl_mvm_sta_from_mac80211(sta)->vif) in rs_drv_rate_update()
3068 iwl_mvm_rs_rate_init(mvm, sta, sband->band, true); in rs_drv_rate_update()
3083 u32 tlc_info = (uintptr_t)info->status.status_driver_data[0]; in __iwl_mvm_rs_tx_status()
3086 u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1]; in __iwl_mvm_rs_tx_status()
3088 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; in __iwl_mvm_rs_tx_status()
3090 if (!lq_sta->pers.drv) { in __iwl_mvm_rs_tx_status()
3096 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && in __iwl_mvm_rs_tx_status()
3097 !(info->flags & IEEE80211_TX_STAT_AMPDU)) in __iwl_mvm_rs_tx_status()
3100 if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, in __iwl_mvm_rs_tx_status()
3110 if (lq_sta->pers.dbg_fixed_rate) { in __iwl_mvm_rs_tx_status()
3121 if (info->flags & IEEE80211_TX_STAT_AMPDU) { in __iwl_mvm_rs_tx_status()
3122 attempts = info->status.ampdu_len; in __iwl_mvm_rs_tx_status()
3123 success = info->status.ampdu_ack_len; in __iwl_mvm_rs_tx_status()
3125 attempts = info->status.rates[0].count; in __iwl_mvm_rs_tx_status()
3126 success = !!(info->flags & IEEE80211_TX_STAT_ACK); in __iwl_mvm_rs_tx_status()
3129 lq_sta->pers.tx_stats[column][index].total += attempts; in __iwl_mvm_rs_tx_status()
3130 lq_sta->pers.tx_stats[column][index].success += success; in __iwl_mvm_rs_tx_status()
3139 (unsigned long)(lq_sta->last_tx + in __iwl_mvm_rs_tx_status()
3145 rs_drv_rate_init(mvm, sta, info->band); in __iwl_mvm_rs_tx_status()
3148 lq_sta->last_tx = jiffies; in __iwl_mvm_rs_tx_status()
3157 table = &lq_sta->lq; in __iwl_mvm_rs_tx_status()
3158 lq_hwrate = le32_to_cpu(table->rs_table[0]); in __iwl_mvm_rs_tx_status()
3159 if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) { in __iwl_mvm_rs_tx_status()
3165 if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) { in __iwl_mvm_rs_tx_status()
3168 lq_color, LQ_FLAG_COLOR_GET(table->flags)); in __iwl_mvm_rs_tx_status()
3170 /* Since rates mis-match, the last LQ command may have failed. in __iwl_mvm_rs_tx_status()
3171 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with in __iwl_mvm_rs_tx_status()
3174 lq_sta->missed_rate_counter++; in __iwl_mvm_rs_tx_status()
3175 if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) { in __iwl_mvm_rs_tx_status()
3176 lq_sta->missed_rate_counter = 0; in __iwl_mvm_rs_tx_status()
3179 lq_sta->rs_state); in __iwl_mvm_rs_tx_status()
3180 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq); in __iwl_mvm_rs_tx_status()
3187 lq_sta->missed_rate_counter = 0; in __iwl_mvm_rs_tx_status()
3189 if (!lq_sta->search_better_tbl) { in __iwl_mvm_rs_tx_status()
3190 curr_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in __iwl_mvm_rs_tx_status()
3191 other_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in __iwl_mvm_rs_tx_status()
3193 curr_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in __iwl_mvm_rs_tx_status()
3194 other_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in __iwl_mvm_rs_tx_status()
3197 if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) { in __iwl_mvm_rs_tx_status()
3200 tmp_tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in __iwl_mvm_rs_tx_status()
3201 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE"); in __iwl_mvm_rs_tx_status()
3202 tmp_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)]; in __iwl_mvm_rs_tx_status()
3203 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH"); in __iwl_mvm_rs_tx_status()
3206 /* no matching table found, let's by-pass the data collection in __iwl_mvm_rs_tx_status()
3219 if (info->flags & IEEE80211_TX_STAT_AMPDU) { in __iwl_mvm_rs_tx_status()
3221 info->status.ampdu_len, in __iwl_mvm_rs_tx_status()
3222 info->status.ampdu_ack_len, in __iwl_mvm_rs_tx_status()
3238 if (info->status.ampdu_ack_len == 0) in __iwl_mvm_rs_tx_status()
3239 info->status.ampdu_len = 1; in __iwl_mvm_rs_tx_status()
3243 info->status.ampdu_len, in __iwl_mvm_rs_tx_status()
3244 info->status.ampdu_ack_len); in __iwl_mvm_rs_tx_status()
3247 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { in __iwl_mvm_rs_tx_status()
3248 lq_sta->total_success += info->status.ampdu_ack_len; in __iwl_mvm_rs_tx_status()
3249 lq_sta->total_failed += (info->status.ampdu_len - in __iwl_mvm_rs_tx_status()
3250 info->status.ampdu_ack_len); in __iwl_mvm_rs_tx_status()
3254 retries = info->status.rates[0].count - 1; in __iwl_mvm_rs_tx_status()
3259 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); in __iwl_mvm_rs_tx_status()
3262 lq_hwrate = le32_to_cpu(table->rs_table[i]); in __iwl_mvm_rs_tx_status()
3263 if (rs_rate_from_ucode_rate(lq_hwrate, info->band, in __iwl_mvm_rs_tx_status()
3272 if (rs_rate_column_match(&lq_rate, &curr_tbl->rate)) in __iwl_mvm_rs_tx_status()
3275 &other_tbl->rate)) in __iwl_mvm_rs_tx_status()
3290 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) { in __iwl_mvm_rs_tx_status()
3291 lq_sta->total_success += legacy_success; in __iwl_mvm_rs_tx_status()
3292 lq_sta->total_failed += retries + (1 - legacy_success); in __iwl_mvm_rs_tx_status()
3296 lq_sta->last_rate_n_flags = lq_hwrate; in __iwl_mvm_rs_tx_status()
3300 if (sta->supp_rates[info->band]) in __iwl_mvm_rs_tx_status()
3312 if (!spin_trylock(&mvmsta->lq_sta.rs_drv.pers.lock)) in iwl_mvm_rs_tx_status()
3316 spin_unlock(&mvmsta->lq_sta.rs_drv.pers.lock); in iwl_mvm_rs_tx_status()
3327 int num_rates = ARRAY_SIZE(lq_cmd->rs_table); in rs_build_rates_table_from_fixed()
3332 lq_cmd->rs_table[i] = ucode_rate_le32; in rs_build_rates_table_from_fixed()
3340 lq_cmd->mimo_delim = num_rates - 1; in rs_build_rates_table_from_fixed()
3342 lq_cmd->mimo_delim = 0; in rs_build_rates_table_from_fixed()
3344 lq_cmd->reduced_tpc = 0; in rs_build_rates_table_from_fixed()
3347 lq_cmd->single_stream_ant_msk = ant; in rs_build_rates_table_from_fixed()
3349 if (!mvm->trans->trans_cfg->gen2) in rs_build_rates_table_from_fixed()
3350 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; in rs_build_rates_table_from_fixed()
3352 lq_cmd->agg_frame_cnt_limit = in rs_build_rates_table_from_fixed()
3367 int prev_rate_idx = rate->index; in rs_fill_rates_for_column()
3380 prev_rate_idx = rate->index; in rs_fill_rates_for_column()
3387 rate->index = prev_rate_idx; in rs_fill_rates_for_column()
3420 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; in rs_build_rates_table()
3429 if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_LQ_SS_PARAMS) && in rs_build_rates_table()
3445 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3454 lq_cmd->mimo_delim = index; in rs_build_rates_table()
3464 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3473 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, in rs_build_rates_table()
3477 /* update the color of the LQ command (as a counter at bits 1-3) */ in rs_build_rates_table()
3478 color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags)); in rs_build_rates_table()
3479 lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color); in rs_build_rates_table()
3492 struct iwl_lq_cmd *lq_cmd = &mvmsta->lq_sta.rs_drv.lq; in rs_bfer_active_iter()
3493 u32 ss_params = le32_to_cpu(lq_cmd->ss_params); in rs_bfer_active_iter()
3495 if (sta == data->exclude_sta) in rs_bfer_active_iter()
3500 WARN_ON_ONCE(data->bfer_mvmsta != NULL); in rs_bfer_active_iter()
3502 data->bfer_mvmsta = mvmsta; in rs_bfer_active_iter()
3508 int prio = -1; in rs_bfer_priority()
3509 enum nl80211_iftype viftype = ieee80211_vif_type_p2p(sta->vif); in rs_bfer_priority()
3523 WARN_ONCE(true, "viftype %d sta_id %d", viftype, sta->sta_id); in rs_bfer_priority()
3524 prio = -1; in rs_bfer_priority()
3540 return -1; in rs_bfer_priority_cmp()
3549 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; in rs_set_lq_ss_params()
3565 if (lq_sta->pers.ss_force == RS_SS_FORCE_STBC) in rs_set_lq_ss_params()
3567 else if (lq_sta->pers.ss_force == RS_SS_FORCE_BFER) in rs_set_lq_ss_params()
3570 if (lq_sta->pers.ss_force != RS_SS_FORCE_NONE) { in rs_set_lq_ss_params()
3572 lq_sta->pers.ss_force); in rs_set_lq_ss_params()
3577 if (lq_sta->stbc_capable) in rs_set_lq_ss_params()
3580 if (!lq_sta->bfer_capable) in rs_set_lq_ss_params()
3583 ieee80211_iterate_stations_atomic(mvm->hw, in rs_set_lq_ss_params()
3600 bfer_mvmsta->sta_id); in rs_set_lq_ss_params()
3605 &bfer_mvmsta->lq_sta.rs_drv.lq; in rs_set_lq_ss_params()
3606 u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params); in rs_set_lq_ss_params()
3609 bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); in rs_set_lq_ss_params()
3615 bfer_mvmsta->sta_id); in rs_set_lq_ss_params()
3618 lq_cmd->ss_params = cpu_to_le32(ss_params); in rs_set_lq_ss_params()
3626 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; in rs_fill_lq_cmd()
3630 lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START; in rs_fill_lq_cmd()
3631 lq_cmd->agg_time_limit = in rs_fill_lq_cmd()
3635 if (lq_sta->pers.dbg_fixed_rate) { in rs_fill_lq_cmd()
3637 lq_sta->band, in rs_fill_lq_cmd()
3638 lq_sta->pers.dbg_fixed_rate); in rs_fill_lq_cmd()
3647 if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_LQ_SS_PARAMS)) in rs_fill_lq_cmd()
3651 mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); in rs_fill_lq_cmd()
3653 if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2) && in rs_fill_lq_cmd()
3654 num_of_ant(initial_rate->ant) == 1) in rs_fill_lq_cmd()
3655 lq_cmd->single_stream_ant_msk = initial_rate->ant; in rs_fill_lq_cmd()
3657 lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize; in rs_fill_lq_cmd()
3665 lq_cmd->agg_frame_cnt_limit--; in rs_fill_lq_cmd()
3667 if (mvmsta->vif->p2p) in rs_fill_lq_cmd()
3668 lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK; in rs_fill_lq_cmd()
3670 lq_cmd->agg_time_limit = in rs_fill_lq_cmd()
3676 return hw->priv; in rs_alloc()
3768 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ in rs_program_fix_rate()
3769 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ in rs_program_fix_rate()
3770 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ in rs_program_fix_rate()
3773 lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate); in rs_program_fix_rate()
3775 if (lq_sta->pers.dbg_fixed_rate) { in rs_program_fix_rate()
3777 iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq); in rs_program_fix_rate()
3784 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_scale_table_write()
3790 mvm = lq_sta->pers.drv; in rs_sta_dbgfs_scale_table_write()
3792 buf_size = min(count, sizeof(buf) - 1); in rs_sta_dbgfs_scale_table_write()
3794 return -EFAULT; in rs_sta_dbgfs_scale_table_write()
3797 lq_sta->pers.dbg_fixed_rate = parsed_rate; in rs_sta_dbgfs_scale_table_write()
3799 lq_sta->pers.dbg_fixed_rate = 0; in rs_sta_dbgfs_scale_table_write()
3815 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_scale_table_read()
3819 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in rs_sta_dbgfs_scale_table_read()
3820 struct rs_rate *rate = &tbl->rate; in rs_sta_dbgfs_scale_table_read()
3823 mvm = lq_sta->pers.drv; in rs_sta_dbgfs_scale_table_read()
3826 return -ENOMEM; in rs_sta_dbgfs_scale_table_read()
3828 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3829 "sta_id %d\n", lq_sta->lq.sta_id); in rs_sta_dbgfs_scale_table_read()
3830 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3832 lq_sta->total_failed, lq_sta->total_success, in rs_sta_dbgfs_scale_table_read()
3833 lq_sta->active_legacy_rate); in rs_sta_dbgfs_scale_table_read()
3834 desc += scnprintf(buff + desc, bufsz - desc, "fixed rate 0x%X\n", in rs_sta_dbgfs_scale_table_read()
3835 lq_sta->pers.dbg_fixed_rate); in rs_sta_dbgfs_scale_table_read()
3836 desc += scnprintf(buff + desc, bufsz - desc, "valid_tx_ant %s%s%s\n", in rs_sta_dbgfs_scale_table_read()
3840 desc += scnprintf(buff + desc, bufsz - desc, "lq type %s\n", in rs_sta_dbgfs_scale_table_read()
3844 desc += scnprintf(buff + desc, bufsz - desc, " %s", in rs_sta_dbgfs_scale_table_read()
3846 desc += scnprintf(buff + desc, bufsz - desc, " %s", in rs_sta_dbgfs_scale_table_read()
3851 desc += scnprintf(buff + desc, bufsz - desc, " %s %s %s %s\n", in rs_sta_dbgfs_scale_table_read()
3852 (rate->sgi) ? "SGI" : "NGI", in rs_sta_dbgfs_scale_table_read()
3853 (rate->ldpc) ? "LDPC" : "BCC", in rs_sta_dbgfs_scale_table_read()
3854 (lq_sta->is_agg) ? "AGG on" : "", in rs_sta_dbgfs_scale_table_read()
3855 (mvmsta->amsdu_enabled) ? "AMSDU on" : ""); in rs_sta_dbgfs_scale_table_read()
3857 desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X\n", in rs_sta_dbgfs_scale_table_read()
3858 lq_sta->last_rate_n_flags); in rs_sta_dbgfs_scale_table_read()
3859 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3860 "general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n", in rs_sta_dbgfs_scale_table_read()
3861 lq_sta->lq.flags, in rs_sta_dbgfs_scale_table_read()
3862 lq_sta->lq.mimo_delim, in rs_sta_dbgfs_scale_table_read()
3863 lq_sta->lq.single_stream_ant_msk, in rs_sta_dbgfs_scale_table_read()
3864 lq_sta->lq.dual_stream_ant_msk); in rs_sta_dbgfs_scale_table_read()
3866 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3868 le16_to_cpu(lq_sta->lq.agg_time_limit), in rs_sta_dbgfs_scale_table_read()
3869 lq_sta->lq.agg_disable_start_th, in rs_sta_dbgfs_scale_table_read()
3870 lq_sta->lq.agg_frame_cnt_limit); in rs_sta_dbgfs_scale_table_read()
3872 desc += scnprintf(buff + desc, bufsz - desc, "reduced tpc=%d\n", in rs_sta_dbgfs_scale_table_read()
3873 lq_sta->lq.reduced_tpc); in rs_sta_dbgfs_scale_table_read()
3874 ss_params = le32_to_cpu(lq_sta->lq.ss_params); in rs_sta_dbgfs_scale_table_read()
3875 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3885 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3887 lq_sta->lq.initial_rate_index[0], in rs_sta_dbgfs_scale_table_read()
3888 lq_sta->lq.initial_rate_index[1], in rs_sta_dbgfs_scale_table_read()
3889 lq_sta->lq.initial_rate_index[2], in rs_sta_dbgfs_scale_table_read()
3890 lq_sta->lq.initial_rate_index[3]); in rs_sta_dbgfs_scale_table_read()
3893 u32 r = le32_to_cpu(lq_sta->lq.rs_table[i]); in rs_sta_dbgfs_scale_table_read()
3895 desc += scnprintf(buff + desc, bufsz - desc, in rs_sta_dbgfs_scale_table_read()
3897 desc += rs_pretty_print_rate(buff + desc, bufsz - desc, r); in rs_sta_dbgfs_scale_table_read()
3898 if (desc < bufsz - 1) in rs_sta_dbgfs_scale_table_read()
3922 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_stats_table_read()
3926 return -ENOMEM; in rs_sta_dbgfs_stats_table_read()
3929 tbl = &(lq_sta->lq_info[i]); in rs_sta_dbgfs_stats_table_read()
3930 rate = &tbl->rate; in rs_sta_dbgfs_stats_table_read()
3934 lq_sta->active_tbl == i ? "*" : "x", in rs_sta_dbgfs_stats_table_read()
3935 rate->type, in rs_sta_dbgfs_stats_table_read()
3936 rate->sgi, in rs_sta_dbgfs_stats_table_read()
3941 rate->index); in rs_sta_dbgfs_stats_table_read()
3945 tbl->win[j].counter, in rs_sta_dbgfs_stats_table_read()
3946 tbl->win[j].success_counter, in rs_sta_dbgfs_stats_table_read()
3947 tbl->win[j].success_ratio); in rs_sta_dbgfs_stats_table_read()
3999 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_drv_tx_stats_read()
4005 return -ENOMEM; in rs_sta_dbgfs_drv_tx_stats_read()
4010 pos += scnprintf(pos, endpos - pos, "COLUMN,"); in rs_sta_dbgfs_drv_tx_stats_read()
4012 pos += scnprintf(pos, endpos - pos, "%s,", rate_name[rate]); in rs_sta_dbgfs_drv_tx_stats_read()
4013 pos += scnprintf(pos, endpos - pos, "\n"); in rs_sta_dbgfs_drv_tx_stats_read()
4016 pos += scnprintf(pos, endpos - pos, in rs_sta_dbgfs_drv_tx_stats_read()
4020 stats = &(lq_sta->pers.tx_stats[col][rate]); in rs_sta_dbgfs_drv_tx_stats_read()
4021 pos += scnprintf(pos, endpos - pos, in rs_sta_dbgfs_drv_tx_stats_read()
4023 stats->success, in rs_sta_dbgfs_drv_tx_stats_read()
4024 stats->total); in rs_sta_dbgfs_drv_tx_stats_read()
4026 pos += scnprintf(pos, endpos - pos, "\n"); in rs_sta_dbgfs_drv_tx_stats_read()
4029 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff); in rs_sta_dbgfs_drv_tx_stats_read()
4038 struct iwl_lq_sta *lq_sta = file->private_data; in rs_sta_dbgfs_drv_tx_stats_write()
4039 memset(lq_sta->pers.tx_stats, 0, sizeof(lq_sta->pers.tx_stats)); in rs_sta_dbgfs_drv_tx_stats_write()
4055 struct iwl_lq_sta *lq_sta = file->private_data; in iwl_dbgfs_ss_force_read()
4066 pos += scnprintf(buf+pos, bufsz-pos, "%s\n", in iwl_dbgfs_ss_force_read()
4067 ss_force_name[lq_sta->pers.ss_force]); in iwl_dbgfs_ss_force_read()
4074 struct iwl_mvm *mvm = lq_sta->pers.drv; in iwl_dbgfs_ss_force_write()
4078 lq_sta->pers.ss_force = RS_SS_FORCE_NONE; in iwl_dbgfs_ss_force_write()
4080 lq_sta->pers.ss_force = RS_SS_FORCE_SISO; in iwl_dbgfs_ss_force_write()
4082 if (lq_sta->stbc_capable) { in iwl_dbgfs_ss_force_write()
4083 lq_sta->pers.ss_force = RS_SS_FORCE_STBC; in iwl_dbgfs_ss_force_write()
4087 ret = -EINVAL; in iwl_dbgfs_ss_force_write()
4090 if (lq_sta->bfer_capable) { in iwl_dbgfs_ss_force_write()
4091 lq_sta->pers.ss_force = RS_SS_FORCE_BFER; in iwl_dbgfs_ss_force_write()
4095 ret = -EINVAL; in iwl_dbgfs_ss_force_write()
4099 ret = -EINVAL; in iwl_dbgfs_ss_force_write()
4121 if (!mvmsta->vif) in rs_drv_add_sta_debugfs()
4131 &lq_sta->tx_agg_tid_en); in rs_drv_add_sta_debugfs()
4133 &lq_sta->pers.dbg_fixed_txp_reduction); in rs_drv_add_sta_debugfs()
4176 spin_lock(&mvmsta->lq_sta.rs_drv.pers.lock); in iwl_mvm_rs_rate_init()
4178 spin_unlock(&mvmsta->lq_sta.rs_drv.pers.lock); in iwl_mvm_rs_rate_init()
4195 struct iwl_lq_cmd *lq = &mvmsta->lq_sta.rs_drv.lq; in rs_drv_tx_protection()
4197 lockdep_assert_held(&mvm->mutex); in rs_drv_tx_protection()
4200 if (mvmsta->tx_protection == 0) in rs_drv_tx_protection()
4201 lq->flags |= LQ_FLAG_USE_RTS_MSK; in rs_drv_tx_protection()
4202 mvmsta->tx_protection++; in rs_drv_tx_protection()
4204 mvmsta->tx_protection--; in rs_drv_tx_protection()
4205 if (mvmsta->tx_protection == 0) in rs_drv_tx_protection()
4206 lq->flags &= ~LQ_FLAG_USE_RTS_MSK; in rs_drv_tx_protection()
4213 * iwl_mvm_tx_protection - ask FW to enable RTS/CTS protection