26 #include <linux/kernel.h>
29 #include <linux/slab.h>
32 #include <linux/netdevice.h>
41 #define RS_NAME "iwl-agn-rs"
43 #define NUM_TRY_BEFORE_ANT_TOGGLE 1
44 #define IWL_NUMBER_TRY 1
45 #define IWL_HT_NUMBER_TRY 3
47 #define IWL_RATE_MAX_WINDOW 62
48 #define IWL_RATE_MIN_FAILURE_TH 6
49 #define IWL_RATE_MIN_SUCCESS_TH 8
52 #define IWL_MISSED_RATE_MAX 15
54 #define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ)
56 static u8 rs_ht_to_legacy[] = {
66 static const u8 ant_toggle_lookup[] = {
77 #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
78 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
79 IWL_RATE_SISO_##s##M_PLCP, \
80 IWL_RATE_MIMO2_##s##M_PLCP,\
81 IWL_RATE_MIMO3_##s##M_PLCP,\
82 IWL_RATE_##r##M_IEEE, \
83 IWL_RATE_##ip##M_INDEX, \
84 IWL_RATE_##in##M_INDEX, \
85 IWL_RATE_##rp##M_INDEX, \
86 IWL_RATE_##rn##M_INDEX, \
87 IWL_RATE_##pp##M_INDEX, \
88 IWL_RATE_##np##M_INDEX }
115 static inline u8 rs_extract_rate(
u32 rate_n_flags)
120 static int iwl_hwrate_to_plcp_idx(
u32 rate_n_flags)
126 idx = rs_extract_rate(rate_n_flags);
142 for (idx = 0; idx <
ARRAY_SIZE(iwl_rates); idx++)
143 if (iwl_rates[idx].
plcp ==
144 rs_extract_rate(rate_n_flags))
151 static void rs_rate_scale_perform(
struct iwl_priv *
priv,
157 static void rs_stay_in_table(
struct iwl_lq_sta *lq_sta,
bool force_search);
160 #ifdef CONFIG_MAC80211_DEBUGFS
161 static void rs_dbgfs_set_mcs(
struct iwl_lq_sta *lq_sta,
164 static void rs_dbgfs_set_mcs(
struct iwl_lq_sta *lq_sta,
181 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0
185 {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202},
186 {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210},
187 {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362},
188 {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390},
192 {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257},
193 {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264},
194 {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586},
195 {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620},
199 {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251},
200 {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257},
201 {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560},
202 {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593},
206 {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289},
207 {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293},
208 {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805},
209 {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838},
213 {0, 0, 0, 0, 99, 0, 153, 186, 208, 239, 256, 263, 268},
214 {0, 0, 0, 0, 106, 0, 162, 194, 215, 246, 262, 268, 273},
215 {0, 0, 0, 0, 134, 0, 249, 346, 431, 574, 685, 732, 775},
216 {0, 0, 0, 0, 148, 0, 272, 376, 465, 614, 727, 775, 818},
220 {0, 0, 0, 0, 152, 0, 211, 239, 255, 279, 290, 294, 297},
221 {0, 0, 0, 0, 160, 0, 219, 245, 261, 284, 294, 297, 300},
222 {0, 0, 0, 0, 254, 0, 443, 584, 695, 868, 984, 1030, 1070},
223 {0, 0, 0, 0, 277, 0, 478, 624, 737, 911, 1026, 1070, 1109},
236 {
"24",
"16QAM 1/2"},
237 {
"36",
"16QAM 3/4"},
238 {
"48",
"64QAM 2/3"},
239 {
"54",
"64QAM 3/4"},
240 {
"60",
"64QAM 5/6"},
243 #define MCS_INDEX_PER_STREAM (8)
255 static inline u8 rs_is_valid_ant(
u8 valid_antenna,
u8 ant_type)
257 return (ant_type & valid_antenna) == ant_type;
295 u8 *qc = ieee80211_get_qos_ctl(hdr);
303 tl = &lq_data->
load[tid];
323 rs_tl_rm_old_stats(tl, curr_time);
335 #ifdef CONFIG_MAC80211_DEBUGFS
354 #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
356 if (priv->tm_fixed_rate)
357 lq_sta->dbg_fixed_rate = priv->tm_fixed_rate;
361 lq_sta->
lq.sta_id, lq_sta->dbg_fixed_rate);
363 if (lq_sta->dbg_fixed_rate) {
364 rs_fill_link_cmd(
NULL, lq_sta, lq_sta->dbg_fixed_rate);
384 tl = &(lq_data->
load[tid]);
397 rs_tl_rm_old_stats(tl, curr_time);
402 static int rs_tl_turn_on_agg_for_tid(
struct iwl_priv *priv,
414 IWL_ERR(priv,
"BT traffic (%d), no aggregation allowed\n",
419 load = rs_tl_get_load(lq_data, tid);
422 IWL_DEBUG_HT(priv,
"Starting Tx agg: STA: %pM tid: %d\n",
431 IWL_ERR(priv,
"Fail start Tx agg on tid: %d\n",
436 IWL_DEBUG_HT(priv,
"Aggregation not enabled for tid %d "
437 "because load = %u\n", tid, load);
442 static void rs_tl_turn_on_agg(
struct iwl_priv *priv,
u8 tid,
447 rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
449 IWL_ERR(priv,
"tid exceeds max TID count: %d/%d\n",
453 static inline int get_num_of_ant_from_rate(
u32 rate_n_flags)
479 int scale_index,
int attempts,
int successes)
489 window = &(tbl->
win[scale_index]);
492 tpt = get_expected_tpt(tbl, scale_index);
502 while (attempts > 0) {
508 if (window->
data & mask) {
509 window->
data &= ~mask;
556 static u32 rate_n_flags_from_tbl(
struct iwl_priv *priv,
558 int index,
u8 use_green)
560 u32 rate_n_flags = 0;
569 IWL_ERR(priv,
"Invalid HT rate index %d\n", index);
601 IWL_ERR(priv,
"GF was set with SGI:SISO\n");
612 static int rs_get_tbl_info_from_mcs(
const u32 rate_n_flags,
618 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
622 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
636 if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
637 if (num_of_ant == 1) {
655 mcs = rs_extract_rate(rate_n_flags);
667 if (num_of_ant == 3) {
678 static int rs_toggle_antenna(
u32 valid_ant,
u32 *rate_n_flags,
686 if (!rs_is_valid_ant(valid_ant, tbl->
ant_type))
689 new_ant_type = ant_toggle_lookup[tbl->
ant_type];
691 while ((new_ant_type != tbl->
ant_type) &&
692 !rs_is_valid_ant(valid_ant, new_ant_type))
693 new_ant_type = ant_toggle_lookup[new_ant_type];
743 static u16 rs_get_adjacent_rate(
struct iwl_priv *priv,
u8 index,
u16 rate_mask,
757 for (mask = (1 << i); i >= 0; i--, mask >>= 1) {
758 if (rate_mask & mask) {
767 if (rate_mask & mask) {
773 return (high << 8) |
low;
781 if (rate_mask & (1 << low))
791 if (rate_mask & (1 << high))
796 return (high << 8) |
low;
801 u8 scale_index,
u8 ht_possible)
806 u8 switch_to_legacy = 0;
814 switch_to_legacy = 1;
815 scale_index = rs_ht_to_legacy[scale_index];
830 rate_mask = rs_get_supported_rates(lq_sta,
NULL, tbl->
lq_type);
836 rate_mask = (
u16)(rate_mask &
843 if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
848 high_low = rs_get_adjacent_rate(lq_sta->
drv, scale_index, rate_mask,
850 low = high_low & 0xff;
856 return rate_n_flags_from_tbl(lq_sta->
drv, tbl, low, is_green);
881 full_concurrent =
true;
883 full_concurrent =
false;
908 int rs_index, mac_index,
i;
928 }
else if (!lq_sta->
drv) {
952 rs_get_tbl_info_from_mcs(tx_rate, priv->
band, &tbl_type, &rs_index);
955 mac_flags = info->
status.rates[0].flags;
956 mac_index = info->
status.rates[0].idx;
970 if ((mac_index < 0) ||
974 (tbl_type.ant_type != info->
status.antenna) ||
975 (!!(tx_rate & RATE_MCS_HT_MSK) != !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
977 (rs_index != mac_index)) {
978 IWL_DEBUG_RATE(priv,
"initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate);
996 if (table_type_matches(&tbl_type,
1000 }
else if (table_type_matches(&tbl_type,
1005 IWL_DEBUG_RATE(priv,
"Neither active nor search matches tx rate\n");
1013 tbl_type.lq_type, tbl_type.ant_type, tbl_type.is_SGI);
1018 rs_stay_in_table(lq_sta,
true);
1031 rs_get_tbl_info_from_mcs(tx_rate, priv->
band, &tbl_type,
1033 rs_collect_tx_data(curr_tbl, rs_index,
1035 info->
status.ampdu_ack_len);
1041 info->
status.ampdu_ack_len);
1047 retries = info->
status.rates[0].count - 1;
1049 retries =
min(retries, 15);
1056 rs_get_tbl_info_from_mcs(tx_rate, priv->
band,
1057 &tbl_type, &rs_index);
1062 if (table_type_matches(&tbl_type, curr_tbl))
1064 else if (table_type_matches(&tbl_type, other_tbl))
1065 tmp_tbl = other_tbl;
1068 rs_collect_tx_data(tmp_tbl, rs_index, 1,
1069 i < retries ? 0 : legacy_success);
1075 lq_sta->
total_failed += retries + (1 - legacy_success);
1083 rs_rate_scale_perform(priv, skb, sta, lq_sta);
1085 #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_TESTMODE)
1086 if ((priv->tm_fixed_rate) &&
1087 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
1088 rs_program_fix_rate(priv, lq_sta);
1090 if (priv->
cfg->bt_params && priv->
cfg->bt_params->advanced_bt_coexist)
1091 rs_bt_update_lq(priv, ctx, lq_sta);
1126 static void rs_set_expected_tpt_table(
struct iwl_lq_sta *lq_sta,
1148 ht_tbl_pointer = expected_tpt_siso20MHz;
1150 ht_tbl_pointer = expected_tpt_siso40MHz;
1152 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1154 ht_tbl_pointer = expected_tpt_mimo2_40MHz;
1156 ht_tbl_pointer = expected_tpt_mimo3_20MHz;
1158 ht_tbl_pointer = expected_tpt_mimo3_40MHz;
1182 static s32 rs_get_best_rate(
struct iwl_priv *priv,
1185 u16 rate_mask,
s8 index)
1190 s32 active_sr = active_tbl->
win[
index].success_ratio;
1203 high_low = rs_get_adjacent_rate(priv, rate, rate_mask,
1206 low = high_low & 0xff;
1207 high = (high_low >> 8) & 0xff;
1224 if ((((100 * tpt_tbl[rate]) > lq_sta->
last_tpt) &&
1227 (tpt_tbl[rate] <= active_tpt))) ||
1229 (tpt_tbl[rate] > active_tpt))) {
1235 new_rate = start_hi;
1276 static int rs_switch_to_mimo2(
struct iwl_priv *priv,
1288 if (!conf_is_ht(conf) || !sta->
ht_cap.ht_supported)
1312 rs_set_expected_tpt_table(lq_sta, tbl);
1314 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
1316 IWL_DEBUG_RATE(priv,
"LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
1318 IWL_DEBUG_RATE(priv,
"Can't switch with index %d rate mask %x\n",
1322 tbl->
current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
1324 IWL_DEBUG_RATE(priv,
"LQ: Switch to new mcs %X index is green %X\n",
1332 static int rs_switch_to_mimo3(
struct iwl_priv *priv,
1344 if (!conf_is_ht(conf) || !sta->
ht_cap.ht_supported)
1368 rs_set_expected_tpt_table(lq_sta, tbl);
1370 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
1375 IWL_DEBUG_RATE(priv,
"Can't switch with index %d rate mask %x\n",
1379 tbl->
current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
1381 IWL_DEBUG_RATE(priv,
"LQ: Switch to new mcs %X index is green %X\n",
1389 static int rs_switch_to_siso(
struct iwl_priv *priv,
1401 if (!conf_is_ht(conf) || !sta->
ht_cap.ht_supported)
1420 rs_set_expected_tpt_table(lq_sta, tbl);
1421 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
1423 IWL_DEBUG_RATE(priv,
"LQ: get best rate %d mask %X\n", rate, rate_mask);
1425 IWL_DEBUG_RATE(priv,
"can not switch with index %d rate mask %x\n",
1429 tbl->
current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
1430 IWL_DEBUG_RATE(priv,
"LQ: Switch to new mcs %X index is green %X\n",
1438 static int rs_move_legacy_other(
struct iwl_priv *priv,
1454 u8 update_search_tbl_counter = 0;
1496 start_action = tbl->
action;
1505 tx_chains_num <= 1) ||
1507 tx_chains_num <= 2))
1518 memcpy(search_tbl, tbl, sz);
1520 if (rs_toggle_antenna(valid_tx_ant,
1522 update_search_tbl_counter = 1;
1523 rs_set_expected_tpt_table(lq_sta, search_tbl);
1531 memcpy(search_tbl, tbl, sz);
1533 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1547 memcpy(search_tbl, tbl, sz);
1557 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->
ant_type))
1560 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1572 memcpy(search_tbl, tbl, sz);
1577 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->
ant_type))
1580 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
1592 if (tbl->
action == start_action)
1604 if (update_search_tbl_counter)
1613 static int rs_move_siso_to_other(
struct iwl_priv *priv,
1629 u8 update_search_tbl_counter = 0;
1668 start_action = tbl->
action;
1676 tx_chains_num <= 1) ||
1678 tx_chains_num <= 2))
1687 memcpy(search_tbl, tbl, sz);
1688 if (rs_toggle_antenna(valid_tx_ant,
1690 update_search_tbl_counter = 1;
1698 memcpy(search_tbl, tbl, sz);
1708 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->
ant_type))
1711 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1726 memcpy(search_tbl, tbl, sz);
1732 "SGI was set in GF+SISO\n");
1735 rs_set_expected_tpt_table(lq_sta, search_tbl);
1742 rate_n_flags_from_tbl(priv, search_tbl,
1744 update_search_tbl_counter = 1;
1748 memcpy(search_tbl, tbl, sz);
1752 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->
ant_type))
1755 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
1765 if (tbl->
action == start_action)
1776 if (update_search_tbl_counter)
1785 static int rs_move_mimo2_to_other(
struct iwl_priv *priv,
1801 u8 update_search_tbl_counter = 0;
1838 start_action = tbl->
action;
1846 if (tx_chains_num <= 2)
1852 memcpy(search_tbl, tbl, sz);
1853 if (rs_toggle_antenna(valid_tx_ant,
1855 update_search_tbl_counter = 1;
1865 memcpy(search_tbl, tbl, sz);
1874 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->
ant_type))
1877 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1895 memcpy(search_tbl, tbl, sz);
1897 rs_set_expected_tpt_table(lq_sta, search_tbl);
1910 rate_n_flags_from_tbl(priv, search_tbl,
1912 update_search_tbl_counter = 1;
1917 memcpy(search_tbl, tbl, sz);
1921 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->
ant_type))
1924 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
1935 if (tbl->
action == start_action)
1945 if (update_search_tbl_counter)
1955 static int rs_move_mimo3_to_other(
struct iwl_priv *priv,
1972 u8 update_search_tbl_counter = 0;
2008 start_action = tbl->
action;
2016 if (tx_chains_num <= 3)
2022 memcpy(search_tbl, tbl, sz);
2023 if (rs_toggle_antenna(valid_tx_ant,
2033 memcpy(search_tbl, tbl, sz);
2042 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->
ant_type))
2045 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
2057 memcpy(search_tbl, tbl, sz);
2066 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->
ant_type))
2069 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
2087 memcpy(search_tbl, tbl, sz);
2089 rs_set_expected_tpt_table(lq_sta, search_tbl);
2102 rate_n_flags_from_tbl(priv, search_tbl,
2104 update_search_tbl_counter = 1;
2111 if (tbl->
action == start_action)
2121 if (update_search_tbl_counter)
2135 static void rs_stay_in_table(
struct iwl_lq_sta *lq_sta,
bool force_search)
2140 int flush_interval_passed = 0;
2146 tbl = &(lq_sta->
lq_info[active_tbl]);
2153 flush_interval_passed =
2170 && (flush_interval_passed))) {
2174 flush_interval_passed);
2196 rs_rate_scale_clear_window(
2206 rs_rate_scale_clear_window(&(tbl->
win[i]));
2214 static void rs_update_rate_tbl(
struct iwl_priv *priv,
2218 int index,
u8 is_green)
2223 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
2224 rs_fill_link_cmd(priv, lq_sta, rate);
2231 static void rs_rate_scale_perform(
struct iwl_priv *priv,
2249 s8 scale_action = 0;
2253 u16 rate_scale_index_msk = 0;
2274 tid = rs_tl_add_packet(lq_sta, hdr);
2277 tid_data = &priv->
tid_data[lq_sta->
lq.sta_id][tid];
2295 tbl = &(lq_sta->
lq_info[active_tbl]);
2299 lq_sta->
is_green = rs_use_green(sta);
2309 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->
lq_type);
2317 rate_scale_index_msk = (
u16) (rate_mask &
2320 rate_scale_index_msk = (
u16) (rate_mask &
2324 rate_scale_index_msk = rate_mask;
2326 if (!rate_scale_index_msk)
2327 rate_scale_index_msk = rate_mask;
2329 if (!((1 << index) & rate_scale_index_msk)) {
2330 IWL_ERR(priv,
"Current Rate is not valid\n");
2338 rs_update_rate_tbl(priv, ctx, lq_sta, tbl,
2346 IWL_ERR(priv,
"tbl->expected_tpt is NULL\n");
2380 rs_stay_in_table(lq_sta,
false);
2388 IWL_ERR(priv,
"expected_tpt should have been calculated by now\n");
2402 "suc=%d cur-tpt=%d old-tpt=%d\n",
2418 "suc=%d cur-tpt=%d old-tpt=%d\n",
2428 tbl = &(lq_sta->
lq_info[active_tbl]);
2447 high_low = rs_get_adjacent_rate(priv, index, rate_scale_index_msk,
2449 low = high_low & 0xff;
2450 high = (high_low >> 8) & 0xff;
2462 low_tpt = tbl->
win[
low].average_tpt;
2464 high_tpt = tbl->
win[
high].average_tpt;
2470 IWL_DEBUG_RATE(priv,
"decrease rate because of low success_ratio\n");
2487 (low_tpt < current_tpt) &&
2488 (high_tpt < current_tpt))
2497 if (high_tpt > current_tpt &&
2507 if (low_tpt > current_tpt) {
2509 "decrease rate because of low tpt\n");
2546 rs_stay_in_table(lq_sta,
true);
2550 switch (scale_action) {
2573 IWL_DEBUG_RATE(priv,
"choose rate scale index %d action %d low %d "
2574 "high %d type %d\n",
2575 index, scale_action, low, high, tbl->
lq_type);
2580 rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green);
2585 rs_stay_in_table(lq_sta,
false);
2600 rs_move_legacy_other(priv, lq_sta, conf, sta, index);
2602 rs_move_siso_to_other(priv, lq_sta, conf, sta, index);
2604 rs_move_mimo2_to_other(priv, lq_sta, conf, sta, index);
2606 rs_move_mimo3_to_other(priv, lq_sta, conf, sta, index);
2613 rs_rate_scale_clear_window(&(tbl->
win[i]));
2633 if (
is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
2636 rs_set_stay_in_table(priv, 1, lq_sta);
2648 u8 sta_id = lq_sta->
lq.sta_id;
2649 tid_data = &priv->
tid_data[sta_id][tid];
2652 "try to aggregate tid %d\n",
2654 rs_tl_turn_on_agg(priv, tid,
2658 rs_set_stay_in_table(priv, 0, lq_sta);
2663 tbl->
current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
2681 static void rs_initialize_lq(
struct iwl_priv *priv,
2689 u8 use_green = rs_use_green(sta);
2695 if (!sta || !lq_sta)
2698 sta_priv = (
void *)sta->drv_priv;
2699 ctx = sta_priv->
ctx;
2710 tbl = &(lq_sta->
lq_info[active_tbl]);
2715 rate = iwl_rates[
i].
plcp;
2716 tbl->
ant_type = first_antenna(valid_tx_ant);
2722 rs_get_tbl_info_from_mcs(rate, priv->
band, tbl, &rate_idx);
2723 if (!rs_is_valid_ant(valid_tx_ant, tbl->
ant_type))
2724 rs_toggle_antenna(valid_tx_ant, &rate, tbl);
2726 rate = rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green);
2728 rs_set_expected_tpt_table(lq_sta, tbl);
2729 rs_fill_link_cmd(
NULL, lq_sta, rate);
2734 static void rs_get_rate(
void *priv_r,
struct ieee80211_sta *sta,
void *priv_sta,
2761 if (lq_sta && !lq_sta->
drv) {
2775 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
2796 rate_idx = rate_lowest_index(sband, sta);
2800 info->
control.rates[0].flags = 0;
2802 info->
control.rates[0].idx = rate_idx;
2806 static void *rs_alloc_sta(
void *priv_rate,
struct ieee80211_sta *sta,
2816 return &sta_priv->
lq_sta;
2834 lq_sta = &sta_priv->
lq_sta;
2838 lq_sta->
lq.sta_id = sta_id;
2842 rs_rate_scale_clear_window(&lq_sta->
lq_info[j].win[i]);
2848 rs_rate_scale_clear_window(&lq_sta->
lq_info[j].win[i]);
2850 IWL_DEBUG_RATE(priv,
"LQ: *** rate scale station global init for station %d ***\n",
2860 lq_sta->
is_green = rs_use_green(sta);
2890 IWL_DEBUG_RATE(priv,
"SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
2896 lq_sta->
lq.general_params.single_stream_ant_msk =
2898 lq_sta->
lq.general_params.dual_stream_ant_msk =
2901 if (!lq_sta->
lq.general_params.dual_stream_ant_msk) {
2902 lq_sta->
lq.general_params.dual_stream_ant_msk =
ANT_AB;
2903 }
else if (num_of_ant(priv->
eeprom_data->valid_tx_ant) == 2) {
2904 lq_sta->
lq.general_params.dual_stream_ant_msk =
2917 #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
2918 priv->tm_fixed_rate = 0;
2920 #ifdef CONFIG_MAC80211_DEBUGFS
2921 lq_sta->dbg_fixed_rate = 0;
2924 rs_initialize_lq(priv, sta, lq_sta);
2927 static void rs_fill_link_cmd(
struct iwl_priv *priv,
2933 int repeat_rate = 0;
2934 u8 ant_toggle_cnt = 0;
2935 u8 use_ht_possible = 1;
2936 u8 valid_tx_ant = 0;
2942 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2945 rs_get_tbl_info_from_mcs(new_rate, lq_sta->
band,
2946 &tbl_type, &rate_idx);
2964 is_mimo(tbl_type.lq_type) ? 1 : 0;
2969 if (num_of_ant(tbl_type.ant_type) == 1) {
2972 }
else if (num_of_ant(tbl_type.ant_type) == 2) {
2981 valid_tx_ant =
ANT_A;
2996 rs_toggle_antenna(valid_tx_ant,
2997 &new_rate, &tbl_type))
3002 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
3011 rs_get_tbl_info_from_mcs(new_rate, lq_sta->
band, &tbl_type,
3023 if (
is_mimo(tbl_type.lq_type))
3027 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
3035 rs_toggle_antenna(valid_tx_ant,
3036 &new_rate, &tbl_type))
3046 use_ht_possible = 0;
3049 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
3068 if (priv && priv->
cfg->bt_params &&
3069 priv->
cfg->bt_params->agg_time_limit &&
3080 static void rs_free(
void *priv_rate)
3085 static void rs_free_sta(
void *priv_r,
struct ieee80211_sta *sta,
3088 struct iwl_op_mode *op_mode __maybe_unused = priv_r;
3095 #ifdef CONFIG_MAC80211_DEBUGFS
3096 static void rs_dbgfs_set_mcs(
struct iwl_lq_sta *lq_sta,
3097 u32 *rate_n_flags,
int index)
3105 if (lq_sta->dbg_fixed_rate) {
3109 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
3110 *rate_n_flags = lq_sta->dbg_fixed_rate;
3113 lq_sta->dbg_fixed_rate = 0;
3115 "Invalid antenna selection 0x%X, Valid is 0x%X\n",
3116 ant_sel_tx, valid_tx_ant);
3125 const char __user *user_buf,
size_t count, loff_t *ppos)
3135 memset(buf, 0,
sizeof(buf));
3136 buf_size =
min(count,
sizeof(buf) - 1);
3140 if (
sscanf(buf,
"%x", &parsed_rate) == 1)
3141 lq_sta->dbg_fixed_rate = parsed_rate;
3143 lq_sta->dbg_fixed_rate = 0;
3145 rs_program_fix_rate(priv, lq_sta);
3150 static ssize_t rs_sta_dbgfs_scale_table_read(
struct file *file,
3151 char __user *user_buf,
size_t count, loff_t *ppos)
3168 desc +=
sprintf(buff+desc,
"sta_id %d\n", lq_sta->
lq.sta_id);
3169 desc +=
sprintf(buff+desc,
"failed=%d success=%d rate=0%X\n",
3172 desc +=
sprintf(buff+desc,
"fixed rate 0x%X\n",
3173 lq_sta->dbg_fixed_rate);
3174 desc +=
sprintf(buff+desc,
"valid_tx_ant %s%s%s\n",
3178 desc +=
sprintf(buff+desc,
"lq type %s\n",
3181 desc +=
sprintf(buff+desc,
" %s",
3184 desc +=
sprintf(buff+desc,
" %s",
3185 (tbl->
is_ht40) ?
"40MHz" :
"20MHz");
3186 desc +=
sprintf(buff+desc,
" %s %s %s\n", (tbl->
is_SGI) ?
"SGI" :
"",
3187 (lq_sta->
is_green) ?
"GF enabled" :
"",
3188 (lq_sta->
is_agg) ?
"AGG on" :
"");
3190 desc +=
sprintf(buff+desc,
"last tx rate=0x%X\n",
3192 desc +=
sprintf(buff+desc,
"general:"
3193 "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
3194 lq_sta->
lq.general_params.flags,
3195 lq_sta->
lq.general_params.mimo_delimiter,
3196 lq_sta->
lq.general_params.single_stream_ant_msk,
3197 lq_sta->
lq.general_params.dual_stream_ant_msk);
3199 desc +=
sprintf(buff+desc,
"agg:"
3200 "time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
3202 lq_sta->
lq.agg_params.agg_dis_start_th,
3203 lq_sta->
lq.agg_params.agg_frame_cnt_limit);
3206 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
3207 lq_sta->
lq.general_params.start_rate_index[0],
3208 lq_sta->
lq.general_params.start_rate_index[1],
3209 lq_sta->
lq.general_params.start_rate_index[2],
3210 lq_sta->
lq.general_params.start_rate_index[3]);
3213 index = iwl_hwrate_to_plcp_idx(
3216 desc +=
sprintf(buff+desc,
" rate[%d] 0x%X %smbps\n",
3218 iwl_rate_mcs[index].
mbps);
3220 desc +=
sprintf(buff+desc,
" rate[%d] 0x%X %smbps (%s)\n",
3222 iwl_rate_mcs[index].
mbps, iwl_rate_mcs[index].
mcs);
3232 .
write = rs_sta_dbgfs_scale_table_write,
3233 .read = rs_sta_dbgfs_scale_table_read,
3237 static ssize_t rs_sta_dbgfs_stats_table_read(
struct file *file,
3238 char __user *user_buf,
size_t count, loff_t *ppos)
3251 for (i = 0; i <
LQ_SIZE; i++) {
3253 "%s type=%d SGI=%d HT40=%d DUP=%d GF=%d\n"
3261 lq_sta->
lq_info[i].current_rate);
3264 "counter=%d success=%d %%=%d\n",
3265 lq_sta->
lq_info[i].win[j].counter,
3266 lq_sta->
lq_info[i].win[j].success_counter,
3267 lq_sta->
lq_info[i].win[j].success_ratio);
3276 .
read = rs_sta_dbgfs_stats_table_read,
3281 static ssize_t rs_sta_dbgfs_rate_scale_data_read(
struct file *file,
3282 char __user *user_buf,
size_t count, loff_t *ppos)
3291 "Bit Rate= %d Mb/s\n",
3295 "Bit Rate= %d Mb/s\n",
3301 static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
3302 .
read = rs_sta_dbgfs_rate_scale_data_read,
3307 static void rs_add_debugfs(
void *priv,
void *priv_sta,
3311 lq_sta->rs_sta_dbgfs_scale_table_file =
3313 lq_sta, &rs_sta_dbgfs_scale_table_ops);
3314 lq_sta->rs_sta_dbgfs_stats_table_file =
3316 lq_sta, &rs_sta_dbgfs_stats_table_ops);
3317 lq_sta->rs_sta_dbgfs_rate_scale_data_file =
3319 lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
3320 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
3326 static void rs_remove_debugfs(
void *priv,
void *priv_sta)
3348 .tx_status = rs_tx_status,
3349 .get_rate = rs_get_rate,
3350 .rate_init = rs_rate_init_stub,
3353 .alloc_sta = rs_alloc_sta,
3354 .free_sta = rs_free_sta,
3355 #ifdef CONFIG_MAC80211_DEBUGFS
3356 .add_sta_debugfs = rs_add_debugfs,
3357 .remove_sta_debugfs = rs_remove_debugfs,