Lines Matching +full:rates +full:- +full:cck
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
8 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25 #define IL4965_RS_NAME "iwl-4965-rs"
51 /*ANT_NONE -> */ ANT_NONE,
52 /*ANT_A -> */ ANT_B,
53 /*ANT_B -> */ ANT_C,
54 /*ANT_AB -> */ ANT_BC,
55 /*ANT_C -> */ ANT_A,
56 /*ANT_AC -> */ ANT_AB,
57 /*ANT_BC -> */ ANT_AC,
58 /*ANT_ABC -> */ ANT_ABC,
107 idx = idx - RATE_MIMO2_6M_PLCP; in il4965_hwrate_to_plcp_idx()
123 return -1; in il4965_hwrate_to_plcp_idx()
139 * The following tables contain the expected throughput metrics for all rates
145 * CCK rates are only valid in legacy table and will only be used in G
185 {"5.5", "BPSK CCK"},
186 {"11", "QPSK CCK"},
206 /* noinline works around https://github.com/llvm/llvm-project/issues/143908 */
210 win->data = 0; in il4965_rs_rate_scale_clear_win()
211 win->success_counter = 0; in il4965_rs_rate_scale_clear_win()
212 win->success_ratio = IL_INVALID_VALUE; in il4965_rs_rate_scale_clear_win()
213 win->counter = 0; in il4965_rs_rate_scale_clear_win()
214 win->average_tpt = IL_INVALID_VALUE; in il4965_rs_rate_scale_clear_win()
215 win->stamp = 0; in il4965_rs_rate_scale_clear_win()
232 u32 oldest_time = curr_time - TID_MAX_TIME_DIFF; in il4965_rs_tl_rm_old_stats()
234 while (tl->queue_count && tl->time_stamp < oldest_time) { in il4965_rs_tl_rm_old_stats()
235 tl->total -= tl->packet_count[tl->head]; in il4965_rs_tl_rm_old_stats()
236 tl->packet_count[tl->head] = 0; in il4965_rs_tl_rm_old_stats()
237 tl->time_stamp += TID_QUEUE_CELL_SPACING; in il4965_rs_tl_rm_old_stats()
238 tl->queue_count--; in il4965_rs_tl_rm_old_stats()
239 tl->head++; in il4965_rs_tl_rm_old_stats()
240 if (tl->head >= TID_QUEUE_MAX_SIZE) in il4965_rs_tl_rm_old_stats()
241 tl->head = 0; in il4965_rs_tl_rm_old_stats()
258 if (ieee80211_is_data_qos(hdr->frame_control)) { in il4965_rs_tl_add_packet()
267 tl = &lq_data->load[tid]; in il4965_rs_tl_add_packet()
269 curr_time -= curr_time % TID_ROUND_VALUE; in il4965_rs_tl_add_packet()
272 if (!(tl->queue_count)) { in il4965_rs_tl_add_packet()
273 tl->total = 1; in il4965_rs_tl_add_packet()
274 tl->time_stamp = curr_time; in il4965_rs_tl_add_packet()
275 tl->queue_count = 1; in il4965_rs_tl_add_packet()
276 tl->head = 0; in il4965_rs_tl_add_packet()
277 tl->packet_count[0] = 1; in il4965_rs_tl_add_packet()
281 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); in il4965_rs_tl_add_packet()
289 idx = (tl->head + idx) % TID_QUEUE_MAX_SIZE; in il4965_rs_tl_add_packet()
290 tl->packet_count[idx] = tl->packet_count[idx] + 1; in il4965_rs_tl_add_packet()
291 tl->total = tl->total + 1; in il4965_rs_tl_add_packet()
293 if ((idx + 1) > tl->queue_count) in il4965_rs_tl_add_packet()
294 tl->queue_count = idx + 1; in il4965_rs_tl_add_packet()
313 tl = &(lq_data->load[tid]); in il4965_rs_tl_get_load()
315 curr_time -= curr_time % TID_ROUND_VALUE; in il4965_rs_tl_get_load()
317 if (!(tl->queue_count)) in il4965_rs_tl_get_load()
320 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); in il4965_rs_tl_get_load()
328 return tl->total; in il4965_rs_tl_get_load()
335 int ret = -EAGAIN; in il4965_rs_tl_turn_on_agg_for_tid()
341 D_HT("Starting Tx agg: STA: %pM tid: %d\n", sta->addr, tid); in il4965_rs_tl_turn_on_agg_for_tid()
343 if (ret == -EAGAIN) { in il4965_rs_tl_turn_on_agg_for_tid()
385 if (tbl->expected_tpt) in il4965_get_expected_tpt()
386 return tbl->expected_tpt[rs_idx]; in il4965_get_expected_tpt()
391 * il4965_rs_collect_tx_data - Update the success/failure sliding win
394 * at this rate. win->data contains the bitmask of successful
402 static const u64 mask = (((u64) 1) << (RATE_MAX_WINDOW - 1)); in il4965_rs_collect_tx_data()
406 return -EINVAL; in il4965_rs_collect_tx_data()
409 win = &(tbl->win[scale_idx]); in il4965_rs_collect_tx_data()
423 if (win->counter >= RATE_MAX_WINDOW) { in il4965_rs_collect_tx_data()
426 win->counter = RATE_MAX_WINDOW - 1; in il4965_rs_collect_tx_data()
428 if (win->data & mask) { in il4965_rs_collect_tx_data()
429 win->data &= ~mask; in il4965_rs_collect_tx_data()
430 win->success_counter--; in il4965_rs_collect_tx_data()
434 /* Increment frames-attempted counter */ in il4965_rs_collect_tx_data()
435 win->counter++; in il4965_rs_collect_tx_data()
438 win->data <<= 1; in il4965_rs_collect_tx_data()
442 win->success_counter++; in il4965_rs_collect_tx_data()
443 win->data |= 0x1; in il4965_rs_collect_tx_data()
444 successes--; in il4965_rs_collect_tx_data()
447 attempts--; in il4965_rs_collect_tx_data()
450 /* Calculate current success ratio, avoid divide-by-0! */ in il4965_rs_collect_tx_data()
451 if (win->counter > 0) in il4965_rs_collect_tx_data()
452 win->success_ratio = in il4965_rs_collect_tx_data()
453 128 * (100 * win->success_counter) / win->counter; in il4965_rs_collect_tx_data()
455 win->success_ratio = IL_INVALID_VALUE; in il4965_rs_collect_tx_data()
457 fail_count = win->counter - win->success_counter; in il4965_rs_collect_tx_data()
461 win->success_counter >= RATE_MIN_SUCCESS_TH) in il4965_rs_collect_tx_data()
462 win->average_tpt = (win->success_ratio * tpt + 64) / 128; in il4965_rs_collect_tx_data()
464 win->average_tpt = IL_INVALID_VALUE; in il4965_rs_collect_tx_data()
467 win->stamp = jiffies; in il4965_rs_collect_tx_data()
481 if (is_legacy(tbl->lq_type)) { in il4965_rate_n_flags_from_tbl()
486 } else if (is_Ht(tbl->lq_type)) { in il4965_rate_n_flags_from_tbl()
493 if (is_siso(tbl->lq_type)) in il4965_rate_n_flags_from_tbl()
498 IL_ERR("Invalid tbl->lq_type %d\n", tbl->lq_type); in il4965_rate_n_flags_from_tbl()
502 ((tbl->ant_type << RATE_MCS_ANT_POS) & RATE_MCS_ANT_ABC_MSK); in il4965_rate_n_flags_from_tbl()
504 if (is_Ht(tbl->lq_type)) { in il4965_rate_n_flags_from_tbl()
505 if (tbl->is_ht40) { in il4965_rate_n_flags_from_tbl()
506 if (tbl->is_dup) in il4965_rate_n_flags_from_tbl()
511 if (tbl->is_SGI) in il4965_rate_n_flags_from_tbl()
516 if (is_siso(tbl->lq_type) && tbl->is_SGI) { in il4965_rate_n_flags_from_tbl()
543 *rate_idx = -1; in il4965_rs_get_tbl_info_from_mcs()
544 return -EINVAL; in il4965_rs_get_tbl_info_from_mcs()
546 tbl->is_SGI = 0; /* default legacy setup */ in il4965_rs_get_tbl_info_from_mcs()
547 tbl->is_ht40 = 0; in il4965_rs_get_tbl_info_from_mcs()
548 tbl->is_dup = 0; in il4965_rs_get_tbl_info_from_mcs()
549 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); in il4965_rs_get_tbl_info_from_mcs()
550 tbl->lq_type = LQ_NONE; in il4965_rs_get_tbl_info_from_mcs()
551 tbl->max_search = IL_MAX_SEARCH; in il4965_rs_get_tbl_info_from_mcs()
557 tbl->lq_type = LQ_A; in il4965_rs_get_tbl_info_from_mcs()
559 tbl->lq_type = LQ_G; in il4965_rs_get_tbl_info_from_mcs()
564 tbl->is_SGI = 1; in il4965_rs_get_tbl_info_from_mcs()
568 tbl->is_ht40 = 1; in il4965_rs_get_tbl_info_from_mcs()
571 tbl->is_dup = 1; in il4965_rs_get_tbl_info_from_mcs()
578 tbl->lq_type = LQ_SISO; /*else NONE */ in il4965_rs_get_tbl_info_from_mcs()
582 tbl->lq_type = LQ_MIMO2; in il4965_rs_get_tbl_info_from_mcs()
596 if (!tbl->ant_type || tbl->ant_type > ANT_ABC) in il4965_rs_toggle_antenna()
599 if (!il4965_rs_is_valid_ant(valid_ant, tbl->ant_type)) in il4965_rs_toggle_antenna()
602 new_ant_type = ant_toggle_lookup[tbl->ant_type]; in il4965_rs_toggle_antenna()
604 while (new_ant_type != tbl->ant_type && in il4965_rs_toggle_antenna()
608 if (new_ant_type == tbl->ant_type) in il4965_rs_toggle_antenna()
611 tbl->ant_type = new_ant_type; in il4965_rs_toggle_antenna()
618 * Green-field mode is valid if the station supports it and
619 * there are no non-GF stations present in the BSS.
624 return (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && in il4965_rs_use_green()
625 !il->ht.non_gf_sta_present; in il4965_rs_use_green()
629 * il4965_rs_get_supported_rates - get the available rates
632 * basic available rates.
641 return lq_sta->active_legacy_rate; in il4965_rs_get_supported_rates()
644 return lq_sta->active_siso_rate; in il4965_rs_get_supported_rates()
646 return lq_sta->active_mimo2_rate; in il4965_rs_get_supported_rates()
664 i = idx - 1; in il4965_rs_get_adjacent_rate()
665 for (mask = (1 << i); i >= 0; i--, mask >>= 1) { in il4965_rs_get_adjacent_rate()
716 u8 is_green = lq_sta->is_green; in il4965_rs_get_lower_rate()
717 struct il_priv *il = lq_sta->drv; in il4965_rs_get_lower_rate()
719 /* check if we need to switch from HT to legacy rates. in il4965_rs_get_lower_rate()
720 * assumption is that mandatory rates (1Mbps or 6Mbps) in il4965_rs_get_lower_rate()
722 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_idx)) { in il4965_rs_get_lower_rate()
725 if (lq_sta->band == NL80211_BAND_5GHZ) in il4965_rs_get_lower_rate()
726 tbl->lq_type = LQ_A; in il4965_rs_get_lower_rate()
728 tbl->lq_type = LQ_G; in il4965_rs_get_lower_rate()
730 if (il4965_num_of_ant(tbl->ant_type) > 1) in il4965_rs_get_lower_rate()
731 tbl->ant_type = in il4965_rs_get_lower_rate()
732 il4965_first_antenna(il->hw_params.valid_tx_ant); in il4965_rs_get_lower_rate()
734 tbl->is_ht40 = 0; in il4965_rs_get_lower_rate()
735 tbl->is_SGI = 0; in il4965_rs_get_lower_rate()
736 tbl->max_search = IL_MAX_SEARCH; in il4965_rs_get_lower_rate()
739 rate_mask = il4965_rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); in il4965_rs_get_lower_rate()
742 if (is_legacy(tbl->lq_type)) { in il4965_rs_get_lower_rate()
743 /* supp_rates has no CCK bits in A mode */ in il4965_rs_get_lower_rate()
744 if (lq_sta->band == NL80211_BAND_5GHZ) in il4965_rs_get_lower_rate()
747 (lq_sta->supp_rates << IL_FIRST_OFDM_RATE)); in il4965_rs_get_lower_rate()
749 rate_mask = (u16) (rate_mask & lq_sta->supp_rates); in il4965_rs_get_lower_rate()
759 il4965_rs_get_adjacent_rate(lq_sta->drv, scale_idx, rate_mask, in il4965_rs_get_lower_rate()
760 tbl->lq_type); in il4965_rs_get_lower_rate()
767 return il4965_rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green); in il4965_rs_get_lower_rate()
777 return (a->lq_type == b->lq_type && a->ant_type == b->ant_type && in il4965_table_type_matches()
778 a->is_SGI == b->is_SGI); in il4965_table_type_matches()
794 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; in il4965_rs_tx_status()
804 /* Treat uninitialized rate scaling data same as non-existing. */ in il4965_rs_tx_status()
808 } else if (!lq_sta->drv) { in il4965_rs_tx_status()
813 if (!ieee80211_is_data(hdr->frame_control) || in il4965_rs_tx_status()
814 (info->flags & IEEE80211_TX_CTL_NO_ACK)) in il4965_rs_tx_status()
818 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && in il4965_rs_tx_status()
819 !(info->flags & IEEE80211_TX_STAT_AMPDU)) in il4965_rs_tx_status()
830 table = &lq_sta->lq; in il4965_rs_tx_status()
831 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); in il4965_rs_tx_status()
832 il4965_rs_get_tbl_info_from_mcs(tx_rate, il->band, &tbl_type, &rs_idx); in il4965_rs_tx_status()
833 if (il->band == NL80211_BAND_5GHZ) in il4965_rs_tx_status()
834 rs_idx -= IL_FIRST_OFDM_RATE; in il4965_rs_tx_status()
835 mac_flags = info->status.rates[0].flags; in il4965_rs_tx_status()
836 mac_idx = info->status.rates[0].idx; in il4965_rs_tx_status()
840 if (mac_idx >= (RATE_9M_IDX - IL_FIRST_OFDM_RATE)) in il4965_rs_tx_status()
843 * mac80211 HT idx is always zero-idxed; we need to move in il4965_rs_tx_status()
844 * HT OFDM rates after CCK rates in 2.4 GHz band in il4965_rs_tx_status()
846 if (il->band == NL80211_BAND_2GHZ) in il4965_rs_tx_status()
854 tbl_type.ant_type != info->status.antenna || in il4965_rs_tx_status()
861 * Since rates mis-match, the last LQ command may have failed. in il4965_rs_tx_status()
862 * After IL_MISSED_RATE_MAX mis-matches, resync the uCode with in il4965_rs_tx_status()
865 lq_sta->missed_rate_counter++; in il4965_rs_tx_status()
866 if (lq_sta->missed_rate_counter > IL_MISSED_RATE_MAX) { in il4965_rs_tx_status()
867 lq_sta->missed_rate_counter = 0; in il4965_rs_tx_status()
868 il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); in il4965_rs_tx_status()
874 lq_sta->missed_rate_counter = 0; in il4965_rs_tx_status()
878 (&tbl_type, &(lq_sta->lq_info[lq_sta->active_tbl]))) { in il4965_rs_tx_status()
879 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_tx_status()
880 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); in il4965_rs_tx_status()
883 (&tbl_type, &lq_sta->lq_info[1 - lq_sta->active_tbl])) { in il4965_rs_tx_status()
884 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); in il4965_rs_tx_status()
885 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_tx_status()
888 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_tx_status()
889 D_RATE("active- lq:%x, ant:%x, SGI:%d\n", tmp_tbl->lq_type, in il4965_rs_tx_status()
890 tmp_tbl->ant_type, tmp_tbl->is_SGI); in il4965_rs_tx_status()
891 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); in il4965_rs_tx_status()
892 D_RATE("search- lq:%x, ant:%x, SGI:%d\n", tmp_tbl->lq_type, in il4965_rs_tx_status()
893 tmp_tbl->ant_type, tmp_tbl->is_SGI); in il4965_rs_tx_status()
894 D_RATE("actual- lq:%x, ant:%x, SGI:%d\n", tbl_type.lq_type, in il4965_rs_tx_status()
897 * no matching table found, let's by-pass the data collection in il4965_rs_tx_status()
911 if (info->flags & IEEE80211_TX_STAT_AMPDU) { in il4965_rs_tx_status()
912 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); in il4965_rs_tx_status()
913 il4965_rs_get_tbl_info_from_mcs(tx_rate, il->band, &tbl_type, in il4965_rs_tx_status()
916 info->status.ampdu_len, in il4965_rs_tx_status()
917 info->status.ampdu_ack_len); in il4965_rs_tx_status()
920 if (lq_sta->stay_in_tbl) { in il4965_rs_tx_status()
921 lq_sta->total_success += info->status.ampdu_ack_len; in il4965_rs_tx_status()
922 lq_sta->total_failed += in il4965_rs_tx_status()
923 (info->status.ampdu_len - in il4965_rs_tx_status()
924 info->status.ampdu_ack_len); in il4965_rs_tx_status()
930 retries = info->status.rates[0].count - 1; in il4965_rs_tx_status()
935 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); in il4965_rs_tx_status()
938 tx_rate = le32_to_cpu(table->rs_table[i].rate_n_flags); in il4965_rs_tx_status()
939 il4965_rs_get_tbl_info_from_mcs(tx_rate, il->band, in il4965_rs_tx_status()
958 if (lq_sta->stay_in_tbl) { in il4965_rs_tx_status()
959 lq_sta->total_success += legacy_success; in il4965_rs_tx_status()
960 lq_sta->total_failed += retries + (1 - legacy_success); in il4965_rs_tx_status()
964 lq_sta->last_rate_n_flags = tx_rate; in il4965_rs_tx_status()
967 if (sta->deflink.supp_rates[sband->band]) in il4965_rs_tx_status()
974 * Set frame tx success limits according to legacy vs. high-throughput,
975 * and reset overall (spanning all rates) tx success history stats.
984 lq_sta->stay_in_tbl = 1; /* only place this gets set */ in il4965_rs_set_stay_in_table()
986 lq_sta->table_count_limit = IL_LEGACY_TBL_COUNT; in il4965_rs_set_stay_in_table()
987 lq_sta->max_failure_limit = IL_LEGACY_FAILURE_LIMIT; in il4965_rs_set_stay_in_table()
988 lq_sta->max_success_limit = IL_LEGACY_SUCCESS_LIMIT; in il4965_rs_set_stay_in_table()
990 lq_sta->table_count_limit = IL_NONE_LEGACY_TBL_COUNT; in il4965_rs_set_stay_in_table()
991 lq_sta->max_failure_limit = IL_NONE_LEGACY_FAILURE_LIMIT; in il4965_rs_set_stay_in_table()
992 lq_sta->max_success_limit = IL_NONE_LEGACY_SUCCESS_LIMIT; in il4965_rs_set_stay_in_table()
994 lq_sta->table_count = 0; in il4965_rs_set_stay_in_table()
995 lq_sta->total_failed = 0; in il4965_rs_set_stay_in_table()
996 lq_sta->total_success = 0; in il4965_rs_set_stay_in_table()
997 lq_sta->flush_timer = jiffies; in il4965_rs_set_stay_in_table()
998 lq_sta->action_counter = 0; in il4965_rs_set_stay_in_table()
1012 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) { in il4965_rs_set_expected_tpt_table()
1013 tbl->expected_tpt = expected_tpt_legacy; in il4965_rs_set_expected_tpt_table()
1017 /* Legacy rates have only one table */ in il4965_rs_set_expected_tpt_table()
1018 if (is_legacy(tbl->lq_type)) { in il4965_rs_set_expected_tpt_table()
1019 tbl->expected_tpt = expected_tpt_legacy; in il4965_rs_set_expected_tpt_table()
1026 if (is_siso(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup)) in il4965_rs_set_expected_tpt_table()
1028 else if (is_siso(tbl->lq_type)) in il4965_rs_set_expected_tpt_table()
1030 else if (is_mimo2(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup)) in il4965_rs_set_expected_tpt_table()
1032 else /* if (is_mimo2(tbl->lq_type)) <-- must be true */ in il4965_rs_set_expected_tpt_table()
1035 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ in il4965_rs_set_expected_tpt_table()
1036 tbl->expected_tpt = ht_tbl_pointer[0]; in il4965_rs_set_expected_tpt_table()
1037 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */ in il4965_rs_set_expected_tpt_table()
1038 tbl->expected_tpt = ht_tbl_pointer[1]; in il4965_rs_set_expected_tpt_table()
1039 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */ in il4965_rs_set_expected_tpt_table()
1040 tbl->expected_tpt = ht_tbl_pointer[2]; in il4965_rs_set_expected_tpt_table()
1042 tbl->expected_tpt = ht_tbl_pointer[3]; in il4965_rs_set_expected_tpt_table()
1046 * Find starting rate for new "search" high-throughput mode of modulation.
1064 &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_get_best_rate()
1065 s32 active_sr = active_tbl->win[idx].success_ratio; in il4965_rs_get_best_rate()
1066 s32 active_tpt = active_tbl->expected_tpt[idx]; in il4965_rs_get_best_rate()
1069 s32 *tpt_tbl = tbl->expected_tpt; in il4965_rs_get_best_rate()
1080 tbl->lq_type); in il4965_rs_get_best_rate()
1100 if ((100 * tpt_tbl[rate] > lq_sta->last_tpt && in il4965_rs_get_best_rate()
1159 s8 is_green = lq_sta->is_green; in il4965_rs_switch_to_mimo2()
1161 if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported) in il4965_rs_switch_to_mimo2()
1162 return -1; in il4965_rs_switch_to_mimo2()
1164 if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC) in il4965_rs_switch_to_mimo2()
1165 return -1; in il4965_rs_switch_to_mimo2()
1168 if (il->hw_params.tx_chains_num < 2) in il4965_rs_switch_to_mimo2()
1169 return -1; in il4965_rs_switch_to_mimo2()
1173 tbl->lq_type = LQ_MIMO2; in il4965_rs_switch_to_mimo2()
1174 tbl->is_dup = lq_sta->is_dup; in il4965_rs_switch_to_mimo2()
1175 tbl->action = 0; in il4965_rs_switch_to_mimo2()
1176 tbl->max_search = IL_MAX_SEARCH; in il4965_rs_switch_to_mimo2()
1177 rate_mask = lq_sta->active_mimo2_rate; in il4965_rs_switch_to_mimo2()
1179 if (il_is_ht40_tx_allowed(il, &sta->deflink.ht_cap)) in il4965_rs_switch_to_mimo2()
1180 tbl->is_ht40 = 1; in il4965_rs_switch_to_mimo2()
1182 tbl->is_ht40 = 0; in il4965_rs_switch_to_mimo2()
1192 return -1; in il4965_rs_switch_to_mimo2()
1194 tbl->current_rate = in il4965_rs_switch_to_mimo2()
1197 D_RATE("LQ: Switch to new mcs %X idx is green %X\n", tbl->current_rate, in il4965_rs_switch_to_mimo2()
1211 u8 is_green = lq_sta->is_green; in il4965_rs_switch_to_siso()
1214 if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported) in il4965_rs_switch_to_siso()
1215 return -1; in il4965_rs_switch_to_siso()
1219 tbl->is_dup = lq_sta->is_dup; in il4965_rs_switch_to_siso()
1220 tbl->lq_type = LQ_SISO; in il4965_rs_switch_to_siso()
1221 tbl->action = 0; in il4965_rs_switch_to_siso()
1222 tbl->max_search = IL_MAX_SEARCH; in il4965_rs_switch_to_siso()
1223 rate_mask = lq_sta->active_siso_rate; in il4965_rs_switch_to_siso()
1225 if (il_is_ht40_tx_allowed(il, &sta->deflink.ht_cap)) in il4965_rs_switch_to_siso()
1226 tbl->is_ht40 = 1; in il4965_rs_switch_to_siso()
1228 tbl->is_ht40 = 0; in il4965_rs_switch_to_siso()
1231 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield */ in il4965_rs_switch_to_siso()
1240 return -1; in il4965_rs_switch_to_siso()
1242 tbl->current_rate = in il4965_rs_switch_to_siso()
1244 D_RATE("LQ: Switch to new mcs %X idx is green %X\n", tbl->current_rate, in il4965_rs_switch_to_siso()
1257 struct il_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_move_legacy_other()
1259 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); in il4965_rs_move_legacy_other()
1260 struct il_rate_scale_data *win = &(tbl->win[idx]); in il4965_rs_move_legacy_other()
1262 (sizeof(struct il_scale_tbl_info) - in il4965_rs_move_legacy_other()
1265 u8 valid_tx_ant = il->hw_params.valid_tx_ant; in il4965_rs_move_legacy_other()
1266 u8 tx_chains_num = il->hw_params.tx_chains_num; in il4965_rs_move_legacy_other()
1270 tbl->action = IL_LEGACY_SWITCH_SISO; in il4965_rs_move_legacy_other()
1272 start_action = tbl->action; in il4965_rs_move_legacy_other()
1274 lq_sta->action_counter++; in il4965_rs_move_legacy_other()
1275 switch (tbl->action) { in il4965_rs_move_legacy_other()
1280 if ((tbl->action == IL_LEGACY_SWITCH_ANTENNA1 && in il4965_rs_move_legacy_other()
1282 (tbl->action == IL_LEGACY_SWITCH_ANTENNA2 && in il4965_rs_move_legacy_other()
1287 if (win->success_ratio >= IL_RS_GOOD_RATIO) in il4965_rs_move_legacy_other()
1294 (valid_tx_ant, &search_tbl->current_rate, in il4965_rs_move_legacy_other()
1307 search_tbl->is_SGI = 0; in il4965_rs_move_legacy_other()
1312 lq_sta->action_counter = 0; in il4965_rs_move_legacy_other()
1324 search_tbl->is_SGI = 0; in il4965_rs_move_legacy_other()
1326 if (tbl->action == IL_LEGACY_SWITCH_MIMO2_AB) in il4965_rs_move_legacy_other()
1327 search_tbl->ant_type = ANT_AB; in il4965_rs_move_legacy_other()
1328 else if (tbl->action == IL_LEGACY_SWITCH_MIMO2_AC) in il4965_rs_move_legacy_other()
1329 search_tbl->ant_type = ANT_AC; in il4965_rs_move_legacy_other()
1331 search_tbl->ant_type = ANT_BC; in il4965_rs_move_legacy_other()
1334 (valid_tx_ant, search_tbl->ant_type)) in il4965_rs_move_legacy_other()
1341 lq_sta->action_counter = 0; in il4965_rs_move_legacy_other()
1346 tbl->action++; in il4965_rs_move_legacy_other()
1347 if (tbl->action > IL_LEGACY_SWITCH_MIMO2_BC) in il4965_rs_move_legacy_other()
1348 tbl->action = IL_LEGACY_SWITCH_ANTENNA1; in il4965_rs_move_legacy_other()
1350 if (tbl->action == start_action) in il4965_rs_move_legacy_other()
1354 search_tbl->lq_type = LQ_NONE; in il4965_rs_move_legacy_other()
1358 lq_sta->search_better_tbl = 1; in il4965_rs_move_legacy_other()
1359 tbl->action++; in il4965_rs_move_legacy_other()
1360 if (tbl->action > IL_LEGACY_SWITCH_MIMO2_BC) in il4965_rs_move_legacy_other()
1361 tbl->action = IL_LEGACY_SWITCH_ANTENNA1; in il4965_rs_move_legacy_other()
1363 search_tbl->action = tbl->action; in il4965_rs_move_legacy_other()
1376 u8 is_green = lq_sta->is_green; in il4965_rs_move_siso_to_other()
1377 struct il_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_move_siso_to_other()
1379 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); in il4965_rs_move_siso_to_other()
1380 struct il_rate_scale_data *win = &(tbl->win[idx]); in il4965_rs_move_siso_to_other()
1381 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; in il4965_rs_move_siso_to_other()
1383 (sizeof(struct il_scale_tbl_info) - in il4965_rs_move_siso_to_other()
1386 u8 valid_tx_ant = il->hw_params.valid_tx_ant; in il4965_rs_move_siso_to_other()
1387 u8 tx_chains_num = il->hw_params.tx_chains_num; in il4965_rs_move_siso_to_other()
1391 start_action = tbl->action; in il4965_rs_move_siso_to_other()
1394 lq_sta->action_counter++; in il4965_rs_move_siso_to_other()
1395 switch (tbl->action) { in il4965_rs_move_siso_to_other()
1399 if ((tbl->action == IL_SISO_SWITCH_ANTENNA1 && in il4965_rs_move_siso_to_other()
1401 (tbl->action == IL_SISO_SWITCH_ANTENNA2 && in il4965_rs_move_siso_to_other()
1405 if (win->success_ratio >= IL_RS_GOOD_RATIO) in il4965_rs_move_siso_to_other()
1410 (valid_tx_ant, &search_tbl->current_rate, in il4965_rs_move_siso_to_other()
1421 search_tbl->is_SGI = 0; in il4965_rs_move_siso_to_other()
1423 if (tbl->action == IL_SISO_SWITCH_MIMO2_AB) in il4965_rs_move_siso_to_other()
1424 search_tbl->ant_type = ANT_AB; in il4965_rs_move_siso_to_other()
1425 else if (tbl->action == IL_SISO_SWITCH_MIMO2_AC) in il4965_rs_move_siso_to_other()
1426 search_tbl->ant_type = ANT_AC; in il4965_rs_move_siso_to_other()
1428 search_tbl->ant_type = ANT_BC; in il4965_rs_move_siso_to_other()
1431 (valid_tx_ant, search_tbl->ant_type)) in il4965_rs_move_siso_to_other()
1441 if (!tbl->is_ht40 && in il4965_rs_move_siso_to_other()
1442 !(ht_cap->cap & IEEE80211_HT_CAP_SGI_20)) in il4965_rs_move_siso_to_other()
1444 if (tbl->is_ht40 && in il4965_rs_move_siso_to_other()
1445 !(ht_cap->cap & IEEE80211_HT_CAP_SGI_40)) in il4965_rs_move_siso_to_other()
1452 if (!tbl->is_SGI) in il4965_rs_move_siso_to_other()
1457 search_tbl->is_SGI = !tbl->is_SGI; in il4965_rs_move_siso_to_other()
1459 if (tbl->is_SGI) { in il4965_rs_move_siso_to_other()
1460 s32 tpt = lq_sta->last_tpt / 100; in il4965_rs_move_siso_to_other()
1461 if (tpt >= search_tbl->expected_tpt[idx]) in il4965_rs_move_siso_to_other()
1464 search_tbl->current_rate = in il4965_rs_move_siso_to_other()
1470 tbl->action++; in il4965_rs_move_siso_to_other()
1471 if (tbl->action > IL_SISO_SWITCH_GI) in il4965_rs_move_siso_to_other()
1472 tbl->action = IL_SISO_SWITCH_ANTENNA1; in il4965_rs_move_siso_to_other()
1474 if (tbl->action == start_action) in il4965_rs_move_siso_to_other()
1477 search_tbl->lq_type = LQ_NONE; in il4965_rs_move_siso_to_other()
1481 lq_sta->search_better_tbl = 1; in il4965_rs_move_siso_to_other()
1482 tbl->action++; in il4965_rs_move_siso_to_other()
1483 if (tbl->action > IL_SISO_SWITCH_GI) in il4965_rs_move_siso_to_other()
1484 tbl->action = IL_SISO_SWITCH_ANTENNA1; in il4965_rs_move_siso_to_other()
1486 search_tbl->action = tbl->action; in il4965_rs_move_siso_to_other()
1499 s8 is_green = lq_sta->is_green; in il4965_rs_move_mimo2_to_other()
1500 struct il_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_move_mimo2_to_other()
1502 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); in il4965_rs_move_mimo2_to_other()
1503 struct il_rate_scale_data *win = &(tbl->win[idx]); in il4965_rs_move_mimo2_to_other()
1504 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; in il4965_rs_move_mimo2_to_other()
1506 (sizeof(struct il_scale_tbl_info) - in il4965_rs_move_mimo2_to_other()
1509 u8 valid_tx_ant = il->hw_params.valid_tx_ant; in il4965_rs_move_mimo2_to_other()
1510 u8 tx_chains_num = il->hw_params.tx_chains_num; in il4965_rs_move_mimo2_to_other()
1514 start_action = tbl->action; in il4965_rs_move_mimo2_to_other()
1516 lq_sta->action_counter++; in il4965_rs_move_mimo2_to_other()
1517 switch (tbl->action) { in il4965_rs_move_mimo2_to_other()
1525 if (win->success_ratio >= IL_RS_GOOD_RATIO) in il4965_rs_move_mimo2_to_other()
1530 (valid_tx_ant, &search_tbl->current_rate, in il4965_rs_move_mimo2_to_other()
1544 if (tbl->action == IL_MIMO2_SWITCH_SISO_A) in il4965_rs_move_mimo2_to_other()
1545 search_tbl->ant_type = ANT_A; in il4965_rs_move_mimo2_to_other()
1546 else if (tbl->action == IL_MIMO2_SWITCH_SISO_B) in il4965_rs_move_mimo2_to_other()
1547 search_tbl->ant_type = ANT_B; in il4965_rs_move_mimo2_to_other()
1549 search_tbl->ant_type = ANT_C; in il4965_rs_move_mimo2_to_other()
1552 (valid_tx_ant, search_tbl->ant_type)) in il4965_rs_move_mimo2_to_other()
1564 if (!tbl->is_ht40 && in il4965_rs_move_mimo2_to_other()
1565 !(ht_cap->cap & IEEE80211_HT_CAP_SGI_20)) in il4965_rs_move_mimo2_to_other()
1567 if (tbl->is_ht40 && in il4965_rs_move_mimo2_to_other()
1568 !(ht_cap->cap & IEEE80211_HT_CAP_SGI_40)) in il4965_rs_move_mimo2_to_other()
1575 search_tbl->is_SGI = !tbl->is_SGI; in il4965_rs_move_mimo2_to_other()
1583 if (tbl->is_SGI) { in il4965_rs_move_mimo2_to_other()
1584 s32 tpt = lq_sta->last_tpt / 100; in il4965_rs_move_mimo2_to_other()
1585 if (tpt >= search_tbl->expected_tpt[idx]) in il4965_rs_move_mimo2_to_other()
1588 search_tbl->current_rate = in il4965_rs_move_mimo2_to_other()
1595 tbl->action++; in il4965_rs_move_mimo2_to_other()
1596 if (tbl->action > IL_MIMO2_SWITCH_GI) in il4965_rs_move_mimo2_to_other()
1597 tbl->action = IL_MIMO2_SWITCH_ANTENNA1; in il4965_rs_move_mimo2_to_other()
1599 if (tbl->action == start_action) in il4965_rs_move_mimo2_to_other()
1602 search_tbl->lq_type = LQ_NONE; in il4965_rs_move_mimo2_to_other()
1605 lq_sta->search_better_tbl = 1; in il4965_rs_move_mimo2_to_other()
1606 tbl->action++; in il4965_rs_move_mimo2_to_other()
1607 if (tbl->action > IL_MIMO2_SWITCH_GI) in il4965_rs_move_mimo2_to_other()
1608 tbl->action = IL_MIMO2_SWITCH_ANTENNA1; in il4965_rs_move_mimo2_to_other()
1610 search_tbl->action = tbl->action; in il4965_rs_move_mimo2_to_other()
1632 il = lq_sta->drv; in il4965_rs_stay_in_table()
1633 active_tbl = lq_sta->active_tbl; in il4965_rs_stay_in_table()
1635 tbl = &(lq_sta->lq_info[active_tbl]); in il4965_rs_stay_in_table()
1638 if (lq_sta->stay_in_tbl) { in il4965_rs_stay_in_table()
1641 if (lq_sta->flush_timer) in il4965_rs_stay_in_table()
1644 (unsigned long)(lq_sta->flush_timer + in il4965_rs_stay_in_table()
1656 lq_sta->total_failed > lq_sta->max_failure_limit || in il4965_rs_stay_in_table()
1657 lq_sta->total_success > lq_sta->max_success_limit || in il4965_rs_stay_in_table()
1658 (!lq_sta->search_better_tbl && lq_sta->flush_timer && in il4965_rs_stay_in_table()
1661 lq_sta->total_failed, lq_sta->total_success, in il4965_rs_stay_in_table()
1665 lq_sta->stay_in_tbl = 0; /* only place reset */ in il4965_rs_stay_in_table()
1666 lq_sta->total_failed = 0; in il4965_rs_stay_in_table()
1667 lq_sta->total_success = 0; in il4965_rs_stay_in_table()
1668 lq_sta->flush_timer = 0; in il4965_rs_stay_in_table()
1673 * history bitmaps and rate-specific stats for all rates in in il4965_rs_stay_in_table()
1677 lq_sta->table_count++; in il4965_rs_stay_in_table()
1678 if (lq_sta->table_count >= lq_sta->table_count_limit) { in il4965_rs_stay_in_table()
1679 lq_sta->table_count = 0; in il4965_rs_stay_in_table()
1684 (tbl-> in il4965_rs_stay_in_table()
1693 if (!lq_sta->stay_in_tbl) { in il4965_rs_stay_in_table()
1695 il4965_rs_rate_scale_clear_win(&(tbl->win[i])); in il4965_rs_stay_in_table()
1712 il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); in il4965_rs_update_rate_tbl()
1723 struct ieee80211_hw *hw = il->hw; in il4965_rs_rate_scale_perform()
1724 struct ieee80211_conf *conf = &hw->conf; in il4965_rs_rate_scale_perform()
1726 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; in il4965_rs_rate_scale_perform()
1753 if (!ieee80211_is_data(hdr->frame_control) || in il4965_rs_rate_scale_perform()
1754 (info->flags & IEEE80211_TX_CTL_NO_ACK)) in il4965_rs_rate_scale_perform()
1757 lq_sta->supp_rates = sta->deflink.supp_rates[lq_sta->band]; in il4965_rs_rate_scale_perform()
1760 if (tid != MAX_TID_COUNT && (lq_sta->tx_agg_tid_en & (1 << tid))) { in il4965_rs_rate_scale_perform()
1761 tid_data = &il->stations[lq_sta->lq.sta_id].tid[tid]; in il4965_rs_rate_scale_perform()
1762 if (tid_data->agg.state == IL_AGG_OFF) in il4965_rs_rate_scale_perform()
1763 lq_sta->is_agg = 0; in il4965_rs_rate_scale_perform()
1765 lq_sta->is_agg = 1; in il4965_rs_rate_scale_perform()
1767 lq_sta->is_agg = 0; in il4965_rs_rate_scale_perform()
1770 * Select rate-scale / modulation-mode table to work with in in il4965_rs_rate_scale_perform()
1774 if (!lq_sta->search_better_tbl) in il4965_rs_rate_scale_perform()
1775 active_tbl = lq_sta->active_tbl; in il4965_rs_rate_scale_perform()
1777 active_tbl = 1 - lq_sta->active_tbl; in il4965_rs_rate_scale_perform()
1779 tbl = &(lq_sta->lq_info[active_tbl]); in il4965_rs_rate_scale_perform()
1780 if (is_legacy(tbl->lq_type)) in il4965_rs_rate_scale_perform()
1781 lq_sta->is_green = 0; in il4965_rs_rate_scale_perform()
1783 lq_sta->is_green = il4965_rs_use_green(il, sta); in il4965_rs_rate_scale_perform()
1784 is_green = lq_sta->is_green; in il4965_rs_rate_scale_perform()
1787 idx = lq_sta->last_txrate_idx; in il4965_rs_rate_scale_perform()
1789 D_RATE("Rate scale idx %d for type %d\n", idx, tbl->lq_type); in il4965_rs_rate_scale_perform()
1791 /* rates available for this association, and for modulation mode */ in il4965_rs_rate_scale_perform()
1792 rate_mask = il4965_rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); in il4965_rs_rate_scale_perform()
1797 if (is_legacy(tbl->lq_type)) { in il4965_rs_rate_scale_perform()
1798 if (lq_sta->band == NL80211_BAND_5GHZ) in il4965_rs_rate_scale_perform()
1799 /* supp_rates has no CCK bits in A mode */ in il4965_rs_rate_scale_perform()
1802 (lq_sta->supp_rates << IL_FIRST_OFDM_RATE)); in il4965_rs_rate_scale_perform()
1805 (u16) (rate_mask & lq_sta->supp_rates); in il4965_rs_rate_scale_perform()
1815 if (lq_sta->search_better_tbl) { in il4965_rs_rate_scale_perform()
1817 tbl->lq_type = LQ_NONE; in il4965_rs_rate_scale_perform()
1818 lq_sta->search_better_tbl = 0; in il4965_rs_rate_scale_perform()
1819 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_rate_scale_perform()
1821 idx = il4965_hwrate_to_plcp_idx(tbl->current_rate); in il4965_rs_rate_scale_perform()
1829 if (!tbl->expected_tpt) { in il4965_rs_rate_scale_perform()
1830 IL_ERR("tbl->expected_tpt is NULL\n"); in il4965_rs_rate_scale_perform()
1835 if (lq_sta->max_rate_idx != -1 && lq_sta->max_rate_idx < idx) { in il4965_rs_rate_scale_perform()
1836 idx = lq_sta->max_rate_idx; in il4965_rs_rate_scale_perform()
1838 win = &(tbl->win[idx]); in il4965_rs_rate_scale_perform()
1842 win = &(tbl->win[idx]); in il4965_rs_rate_scale_perform()
1851 fail_count = win->counter - win->success_counter; in il4965_rs_rate_scale_perform()
1853 win->success_counter < RATE_MIN_SUCCESS_TH) { in il4965_rs_rate_scale_perform()
1855 win->success_counter, win->counter, idx); in il4965_rs_rate_scale_perform()
1858 win->average_tpt = IL_INVALID_VALUE; in il4965_rs_rate_scale_perform()
1868 if (win->average_tpt != in il4965_rs_rate_scale_perform()
1869 ((win->success_ratio * tbl->expected_tpt[idx] + 64) / 128)) { in il4965_rs_rate_scale_perform()
1871 win->average_tpt = in il4965_rs_rate_scale_perform()
1872 ((win->success_ratio * tbl->expected_tpt[idx] + 64) / 128); in il4965_rs_rate_scale_perform()
1876 if (lq_sta->search_better_tbl) { in il4965_rs_rate_scale_perform()
1880 if (win->average_tpt > lq_sta->last_tpt) { in il4965_rs_rate_scale_perform()
1883 "suc=%d cur-tpt=%d old-tpt=%d\n", in il4965_rs_rate_scale_perform()
1884 win->success_ratio, win->average_tpt, in il4965_rs_rate_scale_perform()
1885 lq_sta->last_tpt); in il4965_rs_rate_scale_perform()
1887 if (!is_legacy(tbl->lq_type)) in il4965_rs_rate_scale_perform()
1888 lq_sta->enable_counter = 1; in il4965_rs_rate_scale_perform()
1891 lq_sta->active_tbl = active_tbl; in il4965_rs_rate_scale_perform()
1892 current_tpt = win->average_tpt; in il4965_rs_rate_scale_perform()
1898 "suc=%d cur-tpt=%d old-tpt=%d\n", in il4965_rs_rate_scale_perform()
1899 win->success_ratio, win->average_tpt, in il4965_rs_rate_scale_perform()
1900 lq_sta->last_tpt); in il4965_rs_rate_scale_perform()
1903 tbl->lq_type = LQ_NONE; in il4965_rs_rate_scale_perform()
1906 active_tbl = lq_sta->active_tbl; in il4965_rs_rate_scale_perform()
1907 tbl = &(lq_sta->lq_info[active_tbl]); in il4965_rs_rate_scale_perform()
1910 idx = il4965_hwrate_to_plcp_idx(tbl->current_rate); in il4965_rs_rate_scale_perform()
1911 current_tpt = lq_sta->last_tpt; in il4965_rs_rate_scale_perform()
1919 lq_sta->search_better_tbl = 0; in il4965_rs_rate_scale_perform()
1928 tbl->lq_type); in il4965_rs_rate_scale_perform()
1933 if (lq_sta->max_rate_idx != -1 && lq_sta->max_rate_idx < high) in il4965_rs_rate_scale_perform()
1936 sr = win->success_ratio; in il4965_rs_rate_scale_perform()
1938 /* Collect measured throughputs for current and adjacent rates */ in il4965_rs_rate_scale_perform()
1939 current_tpt = win->average_tpt; in il4965_rs_rate_scale_perform()
1941 low_tpt = tbl->win[low].average_tpt; in il4965_rs_rate_scale_perform()
1943 high_tpt = tbl->win[high].average_tpt; in il4965_rs_rate_scale_perform()
1950 scale_action = -1; in il4965_rs_rate_scale_perform()
1952 /* No throughput measured yet for adjacent rates; try increase. */ in il4965_rs_rate_scale_perform()
1983 scale_action = -1; in il4965_rs_rate_scale_perform()
1992 if (scale_action == -1 && low != RATE_INVALID && in il4965_rs_rate_scale_perform()
1993 (sr > RATE_HIGH_TH || current_tpt > 100 * tbl->expected_tpt[low])) in il4965_rs_rate_scale_perform()
1997 case -1: in il4965_rs_rate_scale_perform()
2020 idx, scale_action, low, high, tbl->lq_type); in il4965_rs_rate_scale_perform()
2033 * 1) Not changing rates right now in il4965_rs_rate_scale_perform()
2037 if (!update_lq && !done_search && !lq_sta->stay_in_tbl && win->counter) { in il4965_rs_rate_scale_perform()
2039 lq_sta->last_tpt = current_tpt; in il4965_rs_rate_scale_perform()
2043 if (is_legacy(tbl->lq_type)) in il4965_rs_rate_scale_perform()
2045 else if (is_siso(tbl->lq_type)) in il4965_rs_rate_scale_perform()
2048 else /* (is_mimo2(tbl->lq_type)) */ in il4965_rs_rate_scale_perform()
2053 if (lq_sta->search_better_tbl) { in il4965_rs_rate_scale_perform()
2055 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); in il4965_rs_rate_scale_perform()
2057 il4965_rs_rate_scale_clear_win(&(tbl->win[i])); in il4965_rs_rate_scale_perform()
2060 idx = il4965_hwrate_to_plcp_idx(tbl->current_rate); in il4965_rs_rate_scale_perform()
2063 tbl->current_rate, idx); in il4965_rs_rate_scale_perform()
2064 il4965_rs_fill_link_cmd(il, lq_sta, tbl->current_rate); in il4965_rs_rate_scale_perform()
2065 il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); in il4965_rs_rate_scale_perform()
2070 if (done_search && !lq_sta->stay_in_tbl) { in il4965_rs_rate_scale_perform()
2071 /* If the "active" (non-search) mode was legacy, in il4965_rs_rate_scale_perform()
2076 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_rate_scale_perform()
2077 if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) && in il4965_rs_rate_scale_perform()
2078 lq_sta->action_counter > tbl1->max_search) { in il4965_rs_rate_scale_perform()
2086 if (lq_sta->enable_counter && in il4965_rs_rate_scale_perform()
2087 lq_sta->action_counter >= tbl1->max_search) { in il4965_rs_rate_scale_perform()
2088 if (lq_sta->last_tpt > IL_AGG_TPT_THREHOLD && in il4965_rs_rate_scale_perform()
2089 (lq_sta->tx_agg_tid_en & (1 << tid)) && in il4965_rs_rate_scale_perform()
2092 &il->stations[lq_sta->lq.sta_id].tid[tid]; in il4965_rs_rate_scale_perform()
2093 if (tid_data->agg.state == IL_AGG_OFF) { in il4965_rs_rate_scale_perform()
2105 tbl->current_rate = in il4965_rs_rate_scale_perform()
2108 lq_sta->last_txrate_idx = i; in il4965_rs_rate_scale_perform()
2112 * il4965_rs_initialize_lq - Initialize a station's hardware rate table
2114 * The uCode's station table contains a table of fallback rates
2118 * if the driver's iwl-4965-rs rate scaling algorithm is used, instead of
2142 i = lq_sta->last_txrate_idx; in il4965_rs_initialize_lq()
2144 valid_tx_ant = il->hw_params.valid_tx_ant; in il4965_rs_initialize_lq()
2146 if (!lq_sta->search_better_tbl) in il4965_rs_initialize_lq()
2147 active_tbl = lq_sta->active_tbl; in il4965_rs_initialize_lq()
2149 active_tbl = 1 - lq_sta->active_tbl; in il4965_rs_initialize_lq()
2151 tbl = &(lq_sta->lq_info[active_tbl]); in il4965_rs_initialize_lq()
2157 tbl->ant_type = il4965_first_antenna(valid_tx_ant); in il4965_rs_initialize_lq()
2158 rate |= tbl->ant_type << RATE_MCS_ANT_POS; in il4965_rs_initialize_lq()
2163 il4965_rs_get_tbl_info_from_mcs(rate, il->band, tbl, &rate_idx); in il4965_rs_initialize_lq()
2164 if (!il4965_rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) in il4965_rs_initialize_lq()
2168 tbl->current_rate = rate; in il4965_rs_initialize_lq()
2171 il->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq; in il4965_rs_initialize_lq()
2172 il_send_lq_cmd(il, &lq_sta->lq, CMD_SYNC, true); in il4965_rs_initialize_lq()
2180 struct sk_buff *skb = txrc->skb; in il4965_rs_get_rate()
2181 struct ieee80211_supported_band *sband = txrc->sband; in il4965_rs_get_rate()
2191 lq_sta->max_rate_idx = fls(txrc->rate_idx_mask) - 1; in il4965_rs_get_rate()
2192 if (sband->band == NL80211_BAND_5GHZ && in il4965_rs_get_rate()
2193 lq_sta->max_rate_idx != -1) in il4965_rs_get_rate()
2194 lq_sta->max_rate_idx += IL_FIRST_OFDM_RATE; in il4965_rs_get_rate()
2195 if (lq_sta->max_rate_idx < 0 || in il4965_rs_get_rate()
2196 lq_sta->max_rate_idx >= RATE_COUNT) in il4965_rs_get_rate()
2197 lq_sta->max_rate_idx = -1; in il4965_rs_get_rate()
2200 /* Treat uninitialized rate scaling data same as non-existing. */ in il4965_rs_get_rate()
2201 if (lq_sta && !lq_sta->drv) { in il4965_rs_get_rate()
2209 rate_idx = lq_sta->last_txrate_idx; in il4965_rs_get_rate()
2211 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { in il4965_rs_get_rate()
2212 rate_idx -= IL_FIRST_OFDM_RATE; in il4965_rs_get_rate()
2214 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0; in il4965_rs_get_rate()
2215 if (il4965_rs_extract_rate(lq_sta->last_rate_n_flags) >= in il4965_rs_get_rate()
2218 info->control.rates[0].flags = IEEE80211_TX_RC_MCS; in il4965_rs_get_rate()
2219 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK) in il4965_rs_get_rate()
2220 info->control.rates[0].flags |= in il4965_rs_get_rate()
2222 if (lq_sta->last_rate_n_flags & RATE_MCS_DUP_MSK) in il4965_rs_get_rate()
2223 info->control.rates[0].flags |= in il4965_rs_get_rate()
2225 if (lq_sta->last_rate_n_flags & RATE_MCS_HT40_MSK) in il4965_rs_get_rate()
2226 info->control.rates[0].flags |= in il4965_rs_get_rate()
2228 if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK) in il4965_rs_get_rate()
2229 info->control.rates[0].flags |= in il4965_rs_get_rate()
2232 /* Check for invalid rates */ in il4965_rs_get_rate()
2234 (sband->band == NL80211_BAND_5GHZ && in il4965_rs_get_rate()
2238 else if (sband->band == NL80211_BAND_5GHZ) in il4965_rs_get_rate()
2239 rate_idx -= IL_FIRST_OFDM_RATE; in il4965_rs_get_rate()
2240 info->control.rates[0].flags = 0; in il4965_rs_get_rate()
2242 info->control.rates[0].idx = rate_idx; in il4965_rs_get_rate()
2243 info->control.rates[0].count = 1; in il4965_rs_get_rate()
2250 (struct il_station_priv *)sta->drv_priv; in il4965_rs_alloc_sta()
2256 return &sta_priv->lq_sta; in il4965_rs_alloc_sta()
2266 struct ieee80211_hw *hw = il->hw; in il4965_rs_rate_init()
2267 struct ieee80211_conf *conf = &il->hw->conf; in il4965_rs_rate_init()
2268 struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; in il4965_rs_rate_init()
2273 sta_priv = (struct il_station_priv *)sta->drv_priv; in il4965_rs_rate_init()
2274 lq_sta = &sta_priv->lq_sta; in il4965_rs_rate_init()
2275 sband = hw->wiphy->bands[conf->chandef.chan->band]; in il4965_rs_rate_init()
2277 lq_sta->lq.sta_id = sta_id; in il4965_rs_rate_init()
2281 il4965_rs_rate_scale_clear_win(&lq_sta->lq_info[j]. in il4965_rs_rate_init()
2284 lq_sta->flush_timer = 0; in il4965_rs_rate_init()
2285 lq_sta->supp_rates = sta->deflink.supp_rates[sband->band]; in il4965_rs_rate_init()
2288 il4965_rs_rate_scale_clear_win(&lq_sta->lq_info[j]. in il4965_rs_rate_init()
2298 lq_sta->is_dup = 0; in il4965_rs_rate_init()
2299 lq_sta->max_rate_idx = -1; in il4965_rs_rate_init()
2300 lq_sta->missed_rate_counter = IL_MISSED_RATE_MAX; in il4965_rs_rate_init()
2301 lq_sta->is_green = il4965_rs_use_green(il, sta); in il4965_rs_rate_init()
2302 lq_sta->active_legacy_rate = il->active_rate & ~(0x1000); in il4965_rs_rate_init()
2303 lq_sta->band = il->band; in il4965_rs_rate_init()
2305 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), in il4965_rs_rate_init()
2308 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; in il4965_rs_rate_init()
2309 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; in il4965_rs_rate_init()
2310 lq_sta->active_siso_rate &= ~((u16) 0x2); in il4965_rs_rate_init()
2311 lq_sta->active_siso_rate <<= IL_FIRST_OFDM_RATE; in il4965_rs_rate_init()
2314 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; in il4965_rs_rate_init()
2315 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; in il4965_rs_rate_init()
2316 lq_sta->active_mimo2_rate &= ~((u16) 0x2); in il4965_rs_rate_init()
2317 lq_sta->active_mimo2_rate <<= IL_FIRST_OFDM_RATE; in il4965_rs_rate_init()
2320 lq_sta->lq.general_params.single_stream_ant_msk = in il4965_rs_rate_init()
2321 il4965_first_antenna(il->hw_params.valid_tx_ant); in il4965_rs_rate_init()
2322 lq_sta->lq.general_params.dual_stream_ant_msk = in il4965_rs_rate_init()
2323 il->hw_params.valid_tx_ant & ~il4965_first_antenna(il->hw_params. in il4965_rs_rate_init()
2325 if (!lq_sta->lq.general_params.dual_stream_ant_msk) { in il4965_rs_rate_init()
2326 lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; in il4965_rs_rate_init()
2327 } else if (il4965_num_of_ant(il->hw_params.valid_tx_ant) == 2) { in il4965_rs_rate_init()
2328 lq_sta->lq.general_params.dual_stream_ant_msk = in il4965_rs_rate_init()
2329 il->hw_params.valid_tx_ant; in il4965_rs_rate_init()
2333 lq_sta->tx_agg_tid_en = IL_AGG_ALL_TID; in il4965_rs_rate_init()
2334 lq_sta->drv = il; in il4965_rs_rate_init()
2337 lq_sta->last_txrate_idx = rate_lowest_index(sband, sta); in il4965_rs_rate_init()
2338 if (sband->band == NL80211_BAND_5GHZ) in il4965_rs_rate_init()
2339 lq_sta->last_txrate_idx += IL_FIRST_OFDM_RATE; in il4965_rs_rate_init()
2340 lq_sta->is_agg = 0; in il4965_rs_rate_init()
2343 lq_sta->dbg_fixed_rate = 0; in il4965_rs_rate_init()
2360 struct il_link_quality_cmd *lq_cmd = &lq_sta->lq; in il4965_rs_fill_link_cmd()
2366 il4965_rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, in il4965_rs_fill_link_cmd()
2377 lq_cmd->general_params.mimo_delimiter = in il4965_rs_fill_link_cmd()
2381 lq_cmd->rs_table[idx].rate_n_flags = cpu_to_le32(new_rate); in il4965_rs_fill_link_cmd()
2384 lq_cmd->general_params.single_stream_ant_msk = in il4965_rs_fill_link_cmd()
2387 lq_cmd->general_params.dual_stream_ant_msk = tbl_type.ant_type; in il4965_rs_fill_link_cmd()
2391 repeat_rate--; in il4965_rs_fill_link_cmd()
2393 valid_tx_ant = il->hw_params.valid_tx_ant; in il4965_rs_fill_link_cmd()
2400 while (repeat_rate > 0 && idx < (LINK_QUAL_MAX_RETRY_NUM - 1)) { in il4965_rs_fill_link_cmd()
2415 lq_cmd->rs_table[idx].rate_n_flags = in il4965_rs_fill_link_cmd()
2417 repeat_rate--; in il4965_rs_fill_link_cmd()
2421 il4965_rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, in il4965_rs_fill_link_cmd()
2428 lq_cmd->general_params.mimo_delimiter = idx; in il4965_rs_fill_link_cmd()
2449 /* Don't allow HT rates after next pass. in il4965_rs_fill_link_cmd()
2457 lq_cmd->rs_table[idx].rate_n_flags = cpu_to_le32(new_rate); in il4965_rs_fill_link_cmd()
2460 repeat_rate--; in il4965_rs_fill_link_cmd()
2463 lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; in il4965_rs_fill_link_cmd()
2464 lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; in il4965_rs_fill_link_cmd()
2466 lq_cmd->agg_params.agg_time_limit = in il4965_rs_fill_link_cmd()
2473 return hw->priv; in il4965_rs_alloc()
2502 il = lq_sta->drv; in il4965_rs_dbgfs_set_mcs()
2503 valid_tx_ant = il->hw_params.valid_tx_ant; in il4965_rs_dbgfs_set_mcs()
2504 if (lq_sta->dbg_fixed_rate) { in il4965_rs_dbgfs_set_mcs()
2506 ((lq_sta-> in il4965_rs_dbgfs_set_mcs()
2510 *rate_n_flags = lq_sta->dbg_fixed_rate; in il4965_rs_dbgfs_set_mcs()
2513 lq_sta->dbg_fixed_rate = 0; in il4965_rs_dbgfs_set_mcs()
2529 struct il_lq_sta *lq_sta = file->private_data; in il4965_rs_sta_dbgfs_scale_table_write()
2535 il = lq_sta->drv; in il4965_rs_sta_dbgfs_scale_table_write()
2537 buf_size = min(count, sizeof(buf) - 1); in il4965_rs_sta_dbgfs_scale_table_write()
2539 return -EFAULT; in il4965_rs_sta_dbgfs_scale_table_write()
2542 lq_sta->dbg_fixed_rate = parsed_rate; in il4965_rs_sta_dbgfs_scale_table_write()
2544 lq_sta->dbg_fixed_rate = 0; in il4965_rs_sta_dbgfs_scale_table_write()
2546 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ in il4965_rs_sta_dbgfs_scale_table_write()
2547 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ in il4965_rs_sta_dbgfs_scale_table_write()
2548 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ in il4965_rs_sta_dbgfs_scale_table_write()
2550 D_RATE("sta_id %d rate 0x%X\n", lq_sta->lq.sta_id, in il4965_rs_sta_dbgfs_scale_table_write()
2551 lq_sta->dbg_fixed_rate); in il4965_rs_sta_dbgfs_scale_table_write()
2553 if (lq_sta->dbg_fixed_rate) { in il4965_rs_sta_dbgfs_scale_table_write()
2554 il4965_rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); in il4965_rs_sta_dbgfs_scale_table_write()
2555 il_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false); in il4965_rs_sta_dbgfs_scale_table_write()
2571 struct il_lq_sta *lq_sta = file->private_data; in il4965_rs_sta_dbgfs_scale_table_read()
2573 struct il_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); in il4965_rs_sta_dbgfs_scale_table_read()
2575 il = lq_sta->drv; in il4965_rs_sta_dbgfs_scale_table_read()
2578 return -ENOMEM; in il4965_rs_sta_dbgfs_scale_table_read()
2580 desc += sprintf(buff + desc, "sta_id %d\n", lq_sta->lq.sta_id); in il4965_rs_sta_dbgfs_scale_table_read()
2583 lq_sta->total_failed, lq_sta->total_success, in il4965_rs_sta_dbgfs_scale_table_read()
2584 lq_sta->active_legacy_rate); in il4965_rs_sta_dbgfs_scale_table_read()
2586 sprintf(buff + desc, "fixed rate 0x%X\n", lq_sta->dbg_fixed_rate); in il4965_rs_sta_dbgfs_scale_table_read()
2589 (il->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", in il4965_rs_sta_dbgfs_scale_table_read()
2590 (il->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", in il4965_rs_sta_dbgfs_scale_table_read()
2591 (il->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : ""); in il4965_rs_sta_dbgfs_scale_table_read()
2594 (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); in il4965_rs_sta_dbgfs_scale_table_read()
2595 if (is_Ht(tbl->lq_type)) { in il4965_rs_sta_dbgfs_scale_table_read()
2598 (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2"); in il4965_rs_sta_dbgfs_scale_table_read()
2601 (tbl->is_ht40) ? "40MHz" : "20MHz"); in il4965_rs_sta_dbgfs_scale_table_read()
2604 (tbl->is_SGI) ? "SGI" : "", in il4965_rs_sta_dbgfs_scale_table_read()
2605 (lq_sta->is_green) ? "GF enabled" : "", in il4965_rs_sta_dbgfs_scale_table_read()
2606 (lq_sta->is_agg) ? "AGG on" : ""); in il4965_rs_sta_dbgfs_scale_table_read()
2610 lq_sta->last_rate_n_flags); in il4965_rs_sta_dbgfs_scale_table_read()
2613 "general:" "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", in il4965_rs_sta_dbgfs_scale_table_read()
2614 lq_sta->lq.general_params.flags, in il4965_rs_sta_dbgfs_scale_table_read()
2615 lq_sta->lq.general_params.mimo_delimiter, in il4965_rs_sta_dbgfs_scale_table_read()
2616 lq_sta->lq.general_params.single_stream_ant_msk, in il4965_rs_sta_dbgfs_scale_table_read()
2617 lq_sta->lq.general_params.dual_stream_ant_msk); in il4965_rs_sta_dbgfs_scale_table_read()
2623 le16_to_cpu(lq_sta->lq.agg_params.agg_time_limit), in il4965_rs_sta_dbgfs_scale_table_read()
2624 lq_sta->lq.agg_params.agg_dis_start_th, in il4965_rs_sta_dbgfs_scale_table_read()
2625 lq_sta->lq.agg_params.agg_frame_cnt_limit); in il4965_rs_sta_dbgfs_scale_table_read()
2630 lq_sta->lq.general_params.start_rate_idx[0], in il4965_rs_sta_dbgfs_scale_table_read()
2631 lq_sta->lq.general_params.start_rate_idx[1], in il4965_rs_sta_dbgfs_scale_table_read()
2632 lq_sta->lq.general_params.start_rate_idx[2], in il4965_rs_sta_dbgfs_scale_table_read()
2633 lq_sta->lq.general_params.start_rate_idx[3]); in il4965_rs_sta_dbgfs_scale_table_read()
2638 (lq_sta->lq.rs_table[i]. in il4965_rs_sta_dbgfs_scale_table_read()
2640 if (is_legacy(tbl->lq_type)) { in il4965_rs_sta_dbgfs_scale_table_read()
2643 le32_to_cpu(lq_sta->lq.rs_table[i]. in il4965_rs_sta_dbgfs_scale_table_read()
2650 le32_to_cpu(lq_sta->lq.rs_table[i]. in il4965_rs_sta_dbgfs_scale_table_read()
2678 struct il_lq_sta *lq_sta = file->private_data; in il4965_rs_sta_dbgfs_stats_table_read()
2682 return -ENOMEM; in il4965_rs_sta_dbgfs_stats_table_read()
2688 "rate=0x%X\n", lq_sta->active_tbl == i ? "*" : "x", in il4965_rs_sta_dbgfs_stats_table_read()
2689 lq_sta->lq_info[i].lq_type, in il4965_rs_sta_dbgfs_stats_table_read()
2690 lq_sta->lq_info[i].is_SGI, in il4965_rs_sta_dbgfs_stats_table_read()
2691 lq_sta->lq_info[i].is_ht40, in il4965_rs_sta_dbgfs_stats_table_read()
2692 lq_sta->lq_info[i].is_dup, lq_sta->is_green, in il4965_rs_sta_dbgfs_stats_table_read()
2693 lq_sta->lq_info[i].current_rate); in il4965_rs_sta_dbgfs_stats_table_read()
2698 lq_sta->lq_info[i].win[j].counter, in il4965_rs_sta_dbgfs_stats_table_read()
2699 lq_sta->lq_info[i].win[j].success_counter, in il4965_rs_sta_dbgfs_stats_table_read()
2700 lq_sta->lq_info[i].win[j].success_ratio); in il4965_rs_sta_dbgfs_stats_table_read()
2721 struct il_lq_sta *lq_sta = file->private_data; in il4965_rs_sta_dbgfs_rate_scale_data_read()
2722 struct il_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; in il4965_rs_sta_dbgfs_rate_scale_data_read()
2724 if (is_Ht(tbl->lq_type)) in il4965_rs_sta_dbgfs_rate_scale_data_read()
2727 tbl->expected_tpt[lq_sta->last_txrate_idx]); in il4965_rs_sta_dbgfs_rate_scale_data_read()
2731 il_rates[lq_sta->last_txrate_idx].ieee >> 1); in il4965_rs_sta_dbgfs_rate_scale_data_read()
2754 &lq_sta->tx_agg_tid_en); in il4965_rs_add_debugfs()