brintos

brintos / linux-shallow public Read only

0
0
Text · 118.9 KiB · a8c4e35 Raw
4175 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/******************************************************************************3 *4 * Copyright(c) 2005 - 2014, 2018 - 2023 Intel Corporation. All rights reserved.5 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH6 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH7 *****************************************************************************/8#include <linux/kernel.h>9#include <linux/skbuff.h>10#include <linux/slab.h>11#include <net/mac80211.h>12 13#include <linux/netdevice.h>14#include <linux/etherdevice.h>15#include <linux/delay.h>16 17#include <linux/workqueue.h>18#include "rs.h"19#include "fw-api.h"20#include "sta.h"21#include "iwl-op-mode.h"22#include "mvm.h"23#include "debugfs.h"24 25#define IWL_RATE_MAX_WINDOW		62	/* # tx in history window */26 27/* Calculations of success ratio are done in fixed point where 12800 is 100%.28 * Use this macro when dealing with thresholds consts set as a percentage29 */30#define RS_PERCENT(x) (128 * x)31 32static u8 rs_ht_to_legacy[] = {33	[IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,34	[IWL_RATE_MCS_1_INDEX] = IWL_RATE_9M_INDEX,35	[IWL_RATE_MCS_2_INDEX] = IWL_RATE_12M_INDEX,36	[IWL_RATE_MCS_3_INDEX] = IWL_RATE_18M_INDEX,37	[IWL_RATE_MCS_4_INDEX] = IWL_RATE_24M_INDEX,38	[IWL_RATE_MCS_5_INDEX] = IWL_RATE_36M_INDEX,39	[IWL_RATE_MCS_6_INDEX] = IWL_RATE_48M_INDEX,40	[IWL_RATE_MCS_7_INDEX] = IWL_RATE_54M_INDEX,41	[IWL_RATE_MCS_8_INDEX] = IWL_RATE_54M_INDEX,42	[IWL_RATE_MCS_9_INDEX] = IWL_RATE_54M_INDEX,43};44 45static const u8 ant_toggle_lookup[] = {46	[ANT_NONE] = ANT_NONE,47	[ANT_A] = ANT_B,48	[ANT_B] = ANT_A,49	[ANT_AB] = ANT_AB,50};51 52#define IWL_DECLARE_RATE_INFO(r, s, rp, rn)			      \53	[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,	      \54				    IWL_RATE_HT_SISO_MCS_##s##_PLCP,  \55				    IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \56				    IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \57				    IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP,\58				    IWL_RATE_##rp##M_INDEX,	      \59				    IWL_RATE_##rn##M_INDEX }60 61#define IWL_DECLARE_MCS_RATE(s)						  \62	[IWL_RATE_MCS_##s##_INDEX] = { IWL_RATE_INVM_PLCP,		  \63				       IWL_RATE_HT_SISO_MCS_##s##_PLCP,	  \64				       IWL_RATE_HT_MIMO2_MCS_##s##_PLCP,  \65				       IWL_RATE_VHT_SISO_MCS_##s##_PLCP,  \66				       IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP, \67				       IWL_RATE_INVM_INDEX,	          \68				       IWL_RATE_INVM_INDEX }69 70/*71 * Parameter order:72 *   rate, ht rate, prev rate, next rate73 *74 * If there isn't a valid next or previous rate then INV is used which75 * maps to IWL_RATE_INVALID76 *77 */78static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = {79	IWL_DECLARE_RATE_INFO(1, INV, INV, 2),   /*  1mbps */80	IWL_DECLARE_RATE_INFO(2, INV, 1, 5),     /*  2mbps */81	IWL_DECLARE_RATE_INFO(5, INV, 2, 11),    /*5.5mbps */82	IWL_DECLARE_RATE_INFO(11, INV, 9, 12),   /* 11mbps */83	IWL_DECLARE_RATE_INFO(6, 0, 5, 11),      /*  6mbps ; MCS 0 */84	IWL_DECLARE_RATE_INFO(9, INV, 6, 11),    /*  9mbps */85	IWL_DECLARE_RATE_INFO(12, 1, 11, 18),    /* 12mbps ; MCS 1 */86	IWL_DECLARE_RATE_INFO(18, 2, 12, 24),    /* 18mbps ; MCS 2 */87	IWL_DECLARE_RATE_INFO(24, 3, 18, 36),    /* 24mbps ; MCS 3 */88	IWL_DECLARE_RATE_INFO(36, 4, 24, 48),    /* 36mbps ; MCS 4 */89	IWL_DECLARE_RATE_INFO(48, 5, 36, 54),    /* 48mbps ; MCS 5 */90	IWL_DECLARE_RATE_INFO(54, 6, 48, INV),   /* 54mbps ; MCS 6 */91	IWL_DECLARE_MCS_RATE(7),                 /* MCS 7 */92	IWL_DECLARE_MCS_RATE(8),                 /* MCS 8 */93	IWL_DECLARE_MCS_RATE(9),                 /* MCS 9 */94};95 96enum rs_action {97	RS_ACTION_STAY = 0,98	RS_ACTION_DOWNSCALE = -1,99	RS_ACTION_UPSCALE = 1,100};101 102enum rs_column_mode {103	RS_INVALID = 0,104	RS_LEGACY,105	RS_SISO,106	RS_MIMO2,107};108 109#define MAX_NEXT_COLUMNS 7110#define MAX_COLUMN_CHECKS 3111 112struct rs_tx_column;113 114typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,115				     struct ieee80211_sta *sta,116				     struct rs_rate *rate,117				     const struct rs_tx_column *next_col);118 119struct rs_tx_column {120	enum rs_column_mode mode;121	u8 ant;122	bool sgi;123	enum rs_column next_columns[MAX_NEXT_COLUMNS];124	allow_column_func_t checks[MAX_COLUMN_CHECKS];125};126 127static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,128			 struct rs_rate *rate,129			 const struct rs_tx_column *next_col)130{131	return iwl_mvm_bt_coex_is_ant_avail(mvm, next_col->ant);132}133 134static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,135			  struct rs_rate *rate,136			  const struct rs_tx_column *next_col)137{138	if (!sta->deflink.ht_cap.ht_supported)139		return false;140 141	if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC)142		return false;143 144	if (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) < 2)145		return false;146 147	if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))148		return false;149 150	if (mvm->nvm_data->sku_cap_mimo_disabled)151		return false;152 153	return true;154}155 156static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,157			  struct rs_rate *rate,158			  const struct rs_tx_column *next_col)159{160	if (!sta->deflink.ht_cap.ht_supported)161		return false;162 163	return true;164}165 166static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,167			 struct rs_rate *rate,168			 const struct rs_tx_column *next_col)169{170	struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;171	struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;172 173	if (is_ht20(rate) && (ht_cap->cap &174			     IEEE80211_HT_CAP_SGI_20))175		return true;176	if (is_ht40(rate) && (ht_cap->cap &177			     IEEE80211_HT_CAP_SGI_40))178		return true;179	if (is_ht80(rate) && (vht_cap->cap &180			     IEEE80211_VHT_CAP_SHORT_GI_80))181		return true;182	if (is_ht160(rate) && (vht_cap->cap &183			     IEEE80211_VHT_CAP_SHORT_GI_160))184		return true;185 186	return false;187}188 189static const struct rs_tx_column rs_tx_columns[] = {190	[RS_COLUMN_LEGACY_ANT_A] = {191		.mode = RS_LEGACY,192		.ant = ANT_A,193		.next_columns = {194			RS_COLUMN_LEGACY_ANT_B,195			RS_COLUMN_SISO_ANT_A,196			RS_COLUMN_MIMO2,197			RS_COLUMN_INVALID,198			RS_COLUMN_INVALID,199			RS_COLUMN_INVALID,200			RS_COLUMN_INVALID,201		},202		.checks = {203			rs_ant_allow,204		},205	},206	[RS_COLUMN_LEGACY_ANT_B] = {207		.mode = RS_LEGACY,208		.ant = ANT_B,209		.next_columns = {210			RS_COLUMN_LEGACY_ANT_A,211			RS_COLUMN_SISO_ANT_B,212			RS_COLUMN_MIMO2,213			RS_COLUMN_INVALID,214			RS_COLUMN_INVALID,215			RS_COLUMN_INVALID,216			RS_COLUMN_INVALID,217		},218		.checks = {219			rs_ant_allow,220		},221	},222	[RS_COLUMN_SISO_ANT_A] = {223		.mode = RS_SISO,224		.ant = ANT_A,225		.next_columns = {226			RS_COLUMN_SISO_ANT_B,227			RS_COLUMN_MIMO2,228			RS_COLUMN_SISO_ANT_A_SGI,229			RS_COLUMN_LEGACY_ANT_A,230			RS_COLUMN_LEGACY_ANT_B,231			RS_COLUMN_INVALID,232			RS_COLUMN_INVALID,233		},234		.checks = {235			rs_siso_allow,236			rs_ant_allow,237		},238	},239	[RS_COLUMN_SISO_ANT_B] = {240		.mode = RS_SISO,241		.ant = ANT_B,242		.next_columns = {243			RS_COLUMN_SISO_ANT_A,244			RS_COLUMN_MIMO2,245			RS_COLUMN_SISO_ANT_B_SGI,246			RS_COLUMN_LEGACY_ANT_A,247			RS_COLUMN_LEGACY_ANT_B,248			RS_COLUMN_INVALID,249			RS_COLUMN_INVALID,250		},251		.checks = {252			rs_siso_allow,253			rs_ant_allow,254		},255	},256	[RS_COLUMN_SISO_ANT_A_SGI] = {257		.mode = RS_SISO,258		.ant = ANT_A,259		.sgi = true,260		.next_columns = {261			RS_COLUMN_SISO_ANT_B_SGI,262			RS_COLUMN_MIMO2_SGI,263			RS_COLUMN_SISO_ANT_A,264			RS_COLUMN_LEGACY_ANT_A,265			RS_COLUMN_LEGACY_ANT_B,266			RS_COLUMN_INVALID,267			RS_COLUMN_INVALID,268		},269		.checks = {270			rs_siso_allow,271			rs_ant_allow,272			rs_sgi_allow,273		},274	},275	[RS_COLUMN_SISO_ANT_B_SGI] = {276		.mode = RS_SISO,277		.ant = ANT_B,278		.sgi = true,279		.next_columns = {280			RS_COLUMN_SISO_ANT_A_SGI,281			RS_COLUMN_MIMO2_SGI,282			RS_COLUMN_SISO_ANT_B,283			RS_COLUMN_LEGACY_ANT_A,284			RS_COLUMN_LEGACY_ANT_B,285			RS_COLUMN_INVALID,286			RS_COLUMN_INVALID,287		},288		.checks = {289			rs_siso_allow,290			rs_ant_allow,291			rs_sgi_allow,292		},293	},294	[RS_COLUMN_MIMO2] = {295		.mode = RS_MIMO2,296		.ant = ANT_AB,297		.next_columns = {298			RS_COLUMN_SISO_ANT_A,299			RS_COLUMN_MIMO2_SGI,300			RS_COLUMN_LEGACY_ANT_A,301			RS_COLUMN_LEGACY_ANT_B,302			RS_COLUMN_INVALID,303			RS_COLUMN_INVALID,304			RS_COLUMN_INVALID,305		},306		.checks = {307			rs_mimo_allow,308		},309	},310	[RS_COLUMN_MIMO2_SGI] = {311		.mode = RS_MIMO2,312		.ant = ANT_AB,313		.sgi = true,314		.next_columns = {315			RS_COLUMN_SISO_ANT_A_SGI,316			RS_COLUMN_MIMO2,317			RS_COLUMN_LEGACY_ANT_A,318			RS_COLUMN_LEGACY_ANT_B,319			RS_COLUMN_INVALID,320			RS_COLUMN_INVALID,321			RS_COLUMN_INVALID,322		},323		.checks = {324			rs_mimo_allow,325			rs_sgi_allow,326		},327	},328};329 330static inline u8 rs_extract_rate(u32 rate_n_flags)331{332	/* also works for HT because bits 7:6 are zero there */333	return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK_V1);334}335 336static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)337{338	int idx = 0;339 340	if (rate_n_flags & RATE_MCS_HT_MSK_V1) {341		idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK_V1;342		idx += IWL_RATE_MCS_0_INDEX;343 344		/* skip 9M not supported in HT*/345		if (idx >= IWL_RATE_9M_INDEX)346			idx += 1;347		if ((idx >= IWL_FIRST_HT_RATE) && (idx <= IWL_LAST_HT_RATE))348			return idx;349	} else if (rate_n_flags & RATE_MCS_VHT_MSK_V1 ||350		   rate_n_flags & RATE_MCS_HE_MSK_V1) {351		idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;352		idx += IWL_RATE_MCS_0_INDEX;353 354		/* skip 9M not supported in VHT*/355		if (idx >= IWL_RATE_9M_INDEX)356			idx++;357		if ((idx >= IWL_FIRST_VHT_RATE) && (idx <= IWL_LAST_VHT_RATE))358			return idx;359		if ((rate_n_flags & RATE_MCS_HE_MSK_V1) &&360		    idx <= IWL_LAST_HE_RATE)361			return idx;362	} else {363		/* legacy rate format, search for match in table */364 365		u8 legacy_rate = rs_extract_rate(rate_n_flags);366		for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)367			if (iwl_rates[idx].plcp == legacy_rate)368				return idx;369	}370 371	return IWL_RATE_INVALID;372}373 374static void rs_rate_scale_perform(struct iwl_mvm *mvm,375				  struct ieee80211_sta *sta,376				  struct iwl_lq_sta *lq_sta,377				  int tid, bool ndp);378static void rs_fill_lq_cmd(struct iwl_mvm *mvm,379			   struct ieee80211_sta *sta,380			   struct iwl_lq_sta *lq_sta,381			   const struct rs_rate *initial_rate);382static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);383 384/*385 * The following tables contain the expected throughput metrics for all rates386 *387 *	1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits388 *389 * where invalid entries are zeros.390 *391 * CCK rates are only valid in legacy table and will only be used in G392 * (2.4 GHz) band.393 */394static const u16 expected_tpt_legacy[IWL_RATE_COUNT] = {395	7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0396};397 398/* Expected TpT tables. 4 indexes:399 * 0 - NGI, 1 - SGI, 2 - AGG+NGI, 3 - AGG+SGI400 */401static const u16 expected_tpt_siso_20MHz[4][IWL_RATE_COUNT] = {402	{0, 0, 0, 0, 42, 0,  76, 102, 124, 159, 183, 193, 202, 216, 0},403	{0, 0, 0, 0, 46, 0,  82, 110, 132, 168, 192, 202, 210, 225, 0},404	{0, 0, 0, 0, 49, 0,  97, 145, 192, 285, 375, 420, 464, 551, 0},405	{0, 0, 0, 0, 54, 0, 108, 160, 213, 315, 415, 465, 513, 608, 0},406};407 408static const u16 expected_tpt_siso_40MHz[4][IWL_RATE_COUNT] = {409	{0, 0, 0, 0,  77, 0, 127, 160, 184, 220, 242, 250,  257,  269,  275},410	{0, 0, 0, 0,  83, 0, 135, 169, 193, 229, 250, 257,  264,  275,  280},411	{0, 0, 0, 0, 101, 0, 199, 295, 389, 570, 744, 828,  911, 1070, 1173},412	{0, 0, 0, 0, 112, 0, 220, 326, 429, 629, 819, 912, 1000, 1173, 1284},413};414 415static const u16 expected_tpt_siso_80MHz[4][IWL_RATE_COUNT] = {416	{0, 0, 0, 0, 130, 0, 191, 223, 244,  273,  288,  294,  298,  305,  308},417	{0, 0, 0, 0, 138, 0, 200, 231, 251,  279,  293,  298,  302,  308,  312},418	{0, 0, 0, 0, 217, 0, 429, 634, 834, 1220, 1585, 1760, 1931, 2258, 2466},419	{0, 0, 0, 0, 241, 0, 475, 701, 921, 1343, 1741, 1931, 2117, 2468, 2691},420};421 422static const u16 expected_tpt_siso_160MHz[4][IWL_RATE_COUNT] = {423	{0, 0, 0, 0, 191, 0, 244, 288,  298,  308,  313,  318,  323,  328,  330},424	{0, 0, 0, 0, 200, 0, 251, 293,  302,  312,  317,  322,  327,  332,  334},425	{0, 0, 0, 0, 439, 0, 875, 1307, 1736, 2584, 3419, 3831, 4240, 5049, 5581},426	{0, 0, 0, 0, 488, 0, 972, 1451, 1925, 2864, 3785, 4240, 4691, 5581, 6165},427};428 429static const u16 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {430	{0, 0, 0, 0,  74, 0, 123, 155, 179, 213, 235, 243, 250,  261, 0},431	{0, 0, 0, 0,  81, 0, 131, 164, 187, 221, 242, 250, 256,  267, 0},432	{0, 0, 0, 0,  98, 0, 193, 286, 375, 550, 718, 799, 878, 1032, 0},433	{0, 0, 0, 0, 109, 0, 214, 316, 414, 607, 790, 879, 965, 1132, 0},434};435 436static const u16 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {437	{0, 0, 0, 0, 123, 0, 182, 214, 235,  264,  279,  285,  289,  296,  300},438	{0, 0, 0, 0, 131, 0, 191, 222, 242,  270,  284,  289,  293,  300,  303},439	{0, 0, 0, 0, 200, 0, 390, 571, 741, 1067, 1365, 1505, 1640, 1894, 2053},440	{0, 0, 0, 0, 221, 0, 430, 630, 816, 1169, 1490, 1641, 1784, 2053, 2221},441};442 443static const u16 expected_tpt_mimo2_80MHz[4][IWL_RATE_COUNT] = {444	{0, 0, 0, 0, 182, 0, 240,  264,  278,  299,  308,  311,  313,  317,  319},445	{0, 0, 0, 0, 190, 0, 247,  269,  282,  302,  310,  313,  315,  319,  320},446	{0, 0, 0, 0, 428, 0, 833, 1215, 1577, 2254, 2863, 3147, 3418, 3913, 4219},447	{0, 0, 0, 0, 474, 0, 920, 1338, 1732, 2464, 3116, 3418, 3705, 4225, 4545},448};449 450static const u16 expected_tpt_mimo2_160MHz[4][IWL_RATE_COUNT] = {451	{0, 0, 0, 0, 240, 0, 278,  308,  313,  319,  322,  324,  328,  330,   334},452	{0, 0, 0, 0, 247, 0, 282,  310,  315,  320,  323,  325,  329,  332,   338},453	{0, 0, 0, 0, 875, 0, 1735, 2582, 3414, 5043, 6619, 7389, 8147, 9629,  10592},454	{0, 0, 0, 0, 971, 0, 1925, 2861, 3779, 5574, 7304, 8147, 8976, 10592, 11640},455};456 457static const char *rs_pretty_lq_type(enum iwl_table_type type)458{459	static const char * const lq_types[] = {460		[LQ_NONE] = "NONE",461		[LQ_LEGACY_A] = "LEGACY_A",462		[LQ_LEGACY_G] = "LEGACY_G",463		[LQ_HT_SISO] = "HT SISO",464		[LQ_HT_MIMO2] = "HT MIMO",465		[LQ_VHT_SISO] = "VHT SISO",466		[LQ_VHT_MIMO2] = "VHT MIMO",467		[LQ_HE_SISO] = "HE SISO",468		[LQ_HE_MIMO2] = "HE MIMO",469	};470 471	if (type < LQ_NONE || type >= LQ_MAX)472		return "UNKNOWN";473 474	return lq_types[type];475}476 477static char *rs_pretty_rate(const struct rs_rate *rate)478{479	static char buf[40];480	static const char * const legacy_rates[] = {481		[IWL_RATE_1M_INDEX] = "1M",482		[IWL_RATE_2M_INDEX] = "2M",483		[IWL_RATE_5M_INDEX] = "5.5M",484		[IWL_RATE_11M_INDEX] = "11M",485		[IWL_RATE_6M_INDEX] = "6M",486		[IWL_RATE_9M_INDEX] = "9M",487		[IWL_RATE_12M_INDEX] = "12M",488		[IWL_RATE_18M_INDEX] = "18M",489		[IWL_RATE_24M_INDEX] = "24M",490		[IWL_RATE_36M_INDEX] = "36M",491		[IWL_RATE_48M_INDEX] = "48M",492		[IWL_RATE_54M_INDEX] = "54M",493	};494	static const char *const ht_vht_rates[] = {495		[IWL_RATE_MCS_0_INDEX] = "MCS0",496		[IWL_RATE_MCS_1_INDEX] = "MCS1",497		[IWL_RATE_MCS_2_INDEX] = "MCS2",498		[IWL_RATE_MCS_3_INDEX] = "MCS3",499		[IWL_RATE_MCS_4_INDEX] = "MCS4",500		[IWL_RATE_MCS_5_INDEX] = "MCS5",501		[IWL_RATE_MCS_6_INDEX] = "MCS6",502		[IWL_RATE_MCS_7_INDEX] = "MCS7",503		[IWL_RATE_MCS_8_INDEX] = "MCS8",504		[IWL_RATE_MCS_9_INDEX] = "MCS9",505	};506	const char *rate_str;507 508	if (is_type_legacy(rate->type) && (rate->index <= IWL_RATE_54M_INDEX))509		rate_str = legacy_rates[rate->index];510	else if ((is_type_ht(rate->type) || is_type_vht(rate->type)) &&511		 (rate->index >= IWL_RATE_MCS_0_INDEX) &&512		 (rate->index <= IWL_RATE_MCS_9_INDEX))513		rate_str = ht_vht_rates[rate->index];514	else515		rate_str = NULL;516 517	sprintf(buf, "(%s|%s|%s)", rs_pretty_lq_type(rate->type),518		iwl_rs_pretty_ant(rate->ant), rate_str ?: "BAD_RATE");519	return buf;520}521 522static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate,523				const char *prefix)524{525	IWL_DEBUG_RATE(mvm,526		       "%s: %s BW: %d SGI: %d LDPC: %d STBC: %d\n",527		       prefix, rs_pretty_rate(rate), rate->bw,528		       rate->sgi, rate->ldpc, rate->stbc);529}530 531static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)532{533	window->data = 0;534	window->success_counter = 0;535	window->success_ratio = IWL_INVALID_VALUE;536	window->counter = 0;537	window->average_tpt = IWL_INVALID_VALUE;538}539 540static void rs_rate_scale_clear_tbl_windows(struct iwl_mvm *mvm,541					    struct iwl_scale_tbl_info *tbl)542{543	int i;544 545	IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");546	for (i = 0; i < IWL_RATE_COUNT; i++)547		rs_rate_scale_clear_window(&tbl->win[i]);548 549	for (i = 0; i < ARRAY_SIZE(tbl->tpc_win); i++)550		rs_rate_scale_clear_window(&tbl->tpc_win[i]);551}552 553static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)554{555	return (ant_type & valid_antenna) == ant_type;556}557 558static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,559				     struct iwl_lq_sta *lq_data, u8 tid,560				     struct ieee80211_sta *sta)561{562	int ret;563 564	IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",565		     sta->addr, tid);566 567	/* start BA session until the peer sends del BA */568	ret = ieee80211_start_tx_ba_session(sta, tid, 0);569	if (ret == -EAGAIN) {570		/*571		 * driver and mac80211 is out of sync572		 * this might be cause by reloading firmware573		 * stop the tx ba session here574		 */575		IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n",576			tid);577		ieee80211_stop_tx_ba_session(sta, tid);578	}579	return ret;580}581 582static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,583			      u8 tid, struct iwl_lq_sta *lq_sta,584			      struct ieee80211_sta *sta)585{586	struct iwl_mvm_tid_data *tid_data;587 588	/*589	 * In AP mode, tid can be equal to IWL_MAX_TID_COUNT590	 * when the frame is not QoS591	 */592	if (WARN_ON_ONCE(tid > IWL_MAX_TID_COUNT)) {593		IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n",594			tid, IWL_MAX_TID_COUNT);595		return;596	} else if (tid == IWL_MAX_TID_COUNT) {597		return;598	}599 600	tid_data = &mvmsta->tid_data[tid];601	if (mvmsta->sta_state >= IEEE80211_STA_AUTHORIZED &&602	    tid_data->state == IWL_AGG_OFF &&603	    (lq_sta->tx_agg_tid_en & BIT(tid)) &&604	    tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) {605		IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid);606		if (rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta) == 0)607			tid_data->state = IWL_AGG_QUEUED;608	}609}610 611static inline int get_num_of_ant_from_rate(u32 rate_n_flags)612{613	return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +614	       !!(rate_n_flags & RATE_MCS_ANT_B_MSK);615}616 617/*618 * Static function to get the expected throughput from an iwl_scale_tbl_info619 * that wraps a NULL pointer check620 */621static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)622{623	if (tbl->expected_tpt)624		return tbl->expected_tpt[rs_index];625	return 0;626}627 628/*629 * rs_collect_tx_data - Update the success/failure sliding window630 *631 * We keep a sliding window of the last 62 packets transmitted632 * at this rate.  window->data contains the bitmask of successful633 * packets.634 */635static int _rs_collect_tx_data(struct iwl_mvm *mvm,636			       struct iwl_scale_tbl_info *tbl,637			       int scale_index, int attempts, int successes,638			       struct iwl_rate_scale_data *window)639{640	static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));641	s32 fail_count, tpt;642 643	/* Get expected throughput */644	tpt = get_expected_tpt(tbl, scale_index);645 646	/*647	 * Keep track of only the latest 62 tx frame attempts in this rate's648	 * history window; anything older isn't really relevant any more.649	 * If we have filled up the sliding window, drop the oldest attempt;650	 * if the oldest attempt (highest bit in bitmap) shows "success",651	 * subtract "1" from the success counter (this is the main reason652	 * we keep these bitmaps!).653	 */654	while (attempts > 0) {655		if (window->counter >= IWL_RATE_MAX_WINDOW) {656			/* remove earliest */657			window->counter = IWL_RATE_MAX_WINDOW - 1;658 659			if (window->data & mask) {660				window->data &= ~mask;661				window->success_counter--;662			}663		}664 665		/* Increment frames-attempted counter */666		window->counter++;667 668		/* Shift bitmap by one frame to throw away oldest history */669		window->data <<= 1;670 671		/* Mark the most recent #successes attempts as successful */672		if (successes > 0) {673			window->success_counter++;674			window->data |= 0x1;675			successes--;676		}677 678		attempts--;679	}680 681	/* Calculate current success ratio, avoid divide-by-0! */682	if (window->counter > 0)683		window->success_ratio = 128 * (100 * window->success_counter)684					/ window->counter;685	else686		window->success_ratio = IWL_INVALID_VALUE;687 688	fail_count = window->counter - window->success_counter;689 690	/* Calculate average throughput, if we have enough history. */691	if ((fail_count >= IWL_MVM_RS_RATE_MIN_FAILURE_TH) ||692	    (window->success_counter >= IWL_MVM_RS_RATE_MIN_SUCCESS_TH))693		window->average_tpt = (window->success_ratio * tpt + 64) / 128;694	else695		window->average_tpt = IWL_INVALID_VALUE;696 697	return 0;698}699 700static int rs_collect_tpc_data(struct iwl_mvm *mvm,701			       struct iwl_lq_sta *lq_sta,702			       struct iwl_scale_tbl_info *tbl,703			       int scale_index, int attempts, int successes,704			       u8 reduced_txp)705{706	struct iwl_rate_scale_data *window = NULL;707 708	if (WARN_ON_ONCE(reduced_txp > TPC_MAX_REDUCTION))709		return -EINVAL;710 711	window = &tbl->tpc_win[reduced_txp];712	return  _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,713				    window);714}715 716static void rs_update_tid_tpt_stats(struct iwl_mvm *mvm,717				    struct iwl_mvm_sta *mvmsta,718				    u8 tid, int successes)719{720	struct iwl_mvm_tid_data *tid_data;721 722	if (tid >= IWL_MAX_TID_COUNT)723		return;724 725	tid_data = &mvmsta->tid_data[tid];726 727	/*728	 * Measure if there're enough successful transmits per second.729	 * These statistics are used only to decide if we can start a730	 * BA session, so it should be updated only when A-MPDU is731	 * off.732	 */733	if (tid_data->state != IWL_AGG_OFF)734		return;735 736	if (time_is_before_jiffies(tid_data->tpt_meas_start + HZ) ||737	    (tid_data->tx_count >= IWL_MVM_RS_AGG_START_THRESHOLD)) {738		tid_data->tx_count_last = tid_data->tx_count;739		tid_data->tx_count = 0;740		tid_data->tpt_meas_start = jiffies;741	} else {742		tid_data->tx_count += successes;743	}744}745 746static int rs_collect_tlc_data(struct iwl_mvm *mvm,747			       struct iwl_mvm_sta *mvmsta, u8 tid,748			       struct iwl_scale_tbl_info *tbl,749			       int scale_index, int attempts, int successes)750{751	struct iwl_rate_scale_data *window = NULL;752 753	if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)754		return -EINVAL;755 756	if (tbl->column != RS_COLUMN_INVALID) {757		struct lq_sta_pers *pers = &mvmsta->deflink.lq_sta.rs_drv.pers;758 759		pers->tx_stats[tbl->column][scale_index].total += attempts;760		pers->tx_stats[tbl->column][scale_index].success += successes;761	}762 763	rs_update_tid_tpt_stats(mvm, mvmsta, tid, successes);764 765	/* Select window for current tx bit rate */766	window = &(tbl->win[scale_index]);767	return _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,768				   window);769}770 771/* Convert rs_rate object into ucode rate bitmask */772static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,773				  struct rs_rate *rate)774{775	u32 ucode_rate = 0;776	int index = rate->index;777 778	ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) &779			 RATE_MCS_ANT_AB_MSK);780 781	if (is_legacy(rate)) {782		ucode_rate |= iwl_rates[index].plcp;783		if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)784			ucode_rate |= RATE_MCS_CCK_MSK_V1;785		return ucode_rate;786	}787 788	/* set RTS protection for all non legacy rates789	 * This helps with congested environments reducing the conflict cost to790	 * RTS retries only, instead of the entire BA packet.791	 */792	ucode_rate |= RATE_MCS_RTS_REQUIRED_MSK;793 794	if (is_ht(rate)) {795		if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) {796			IWL_ERR(mvm, "Invalid HT rate index %d\n", index);797			index = IWL_LAST_HT_RATE;798		}799		ucode_rate |= RATE_MCS_HT_MSK_V1;800 801		if (is_ht_siso(rate))802			ucode_rate |= iwl_rates[index].plcp_ht_siso;803		else if (is_ht_mimo2(rate))804			ucode_rate |= iwl_rates[index].plcp_ht_mimo2;805		else806			WARN_ON_ONCE(1);807	} else if (is_vht(rate)) {808		if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) {809			IWL_ERR(mvm, "Invalid VHT rate index %d\n", index);810			index = IWL_LAST_VHT_RATE;811		}812		ucode_rate |= RATE_MCS_VHT_MSK_V1;813		if (is_vht_siso(rate))814			ucode_rate |= iwl_rates[index].plcp_vht_siso;815		else if (is_vht_mimo2(rate))816			ucode_rate |= iwl_rates[index].plcp_vht_mimo2;817		else818			WARN_ON_ONCE(1);819 820	} else {821		IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type);822	}823 824	if (is_siso(rate) && rate->stbc) {825		/* To enable STBC we need to set both a flag and ANT_AB */826		ucode_rate |= RATE_MCS_ANT_AB_MSK;827		ucode_rate |= RATE_MCS_STBC_MSK;828	}829 830	ucode_rate |= rate->bw;831	if (rate->sgi)832		ucode_rate |= RATE_MCS_SGI_MSK_V1;833	if (rate->ldpc)834		ucode_rate |= RATE_MCS_LDPC_MSK_V1;835 836	return ucode_rate;837}838 839/* Convert a ucode rate into an rs_rate object */840static int rs_rate_from_ucode_rate(const u32 ucode_rate,841				   enum nl80211_band band,842				   struct rs_rate *rate)843{844	u32 ant_msk = ucode_rate & RATE_MCS_ANT_AB_MSK;845	u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate);846	u8 nss;847 848	memset(rate, 0, sizeof(*rate));849	rate->index = iwl_hwrate_to_plcp_idx(ucode_rate);850 851	if (rate->index == IWL_RATE_INVALID)852		return -EINVAL;853 854	rate->ant = (ant_msk >> RATE_MCS_ANT_POS);855 856	/* Legacy */857	if (!(ucode_rate & RATE_MCS_HT_MSK_V1) &&858	    !(ucode_rate & RATE_MCS_VHT_MSK_V1) &&859	    !(ucode_rate & RATE_MCS_HE_MSK_V1)) {860		if (num_of_ant == 1) {861			if (band == NL80211_BAND_5GHZ)862				rate->type = LQ_LEGACY_A;863			else864				rate->type = LQ_LEGACY_G;865		}866 867		return 0;868	}869 870	/* HT, VHT or HE */871	if (ucode_rate & RATE_MCS_SGI_MSK_V1)872		rate->sgi = true;873	if (ucode_rate & RATE_MCS_LDPC_MSK_V1)874		rate->ldpc = true;875	if (ucode_rate & RATE_MCS_STBC_MSK)876		rate->stbc = true;877	if (ucode_rate & RATE_MCS_BF_MSK)878		rate->bfer = true;879 880	rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK_V1;881 882	if (ucode_rate & RATE_MCS_HT_MSK_V1) {883		nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK_V1) >>884		       RATE_HT_MCS_NSS_POS_V1) + 1;885 886		if (nss == 1) {887			rate->type = LQ_HT_SISO;888			WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1,889				  "stbc %d bfer %d",890				  rate->stbc, rate->bfer);891		} else if (nss == 2) {892			rate->type = LQ_HT_MIMO2;893			WARN_ON_ONCE(num_of_ant != 2);894		} else {895			WARN_ON_ONCE(1);896		}897	} else if (ucode_rate & RATE_MCS_VHT_MSK_V1) {898		nss = FIELD_GET(RATE_MCS_NSS_MSK, ucode_rate) + 1;899 900		if (nss == 1) {901			rate->type = LQ_VHT_SISO;902			WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1,903				  "stbc %d bfer %d",904				  rate->stbc, rate->bfer);905		} else if (nss == 2) {906			rate->type = LQ_VHT_MIMO2;907			WARN_ON_ONCE(num_of_ant != 2);908		} else {909			WARN_ON_ONCE(1);910		}911	} else if (ucode_rate & RATE_MCS_HE_MSK_V1) {912		nss = FIELD_GET(RATE_MCS_NSS_MSK, ucode_rate) + 1;913 914		if (nss == 1) {915			rate->type = LQ_HE_SISO;916			WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1,917				  "stbc %d bfer %d", rate->stbc, rate->bfer);918		} else if (nss == 2) {919			rate->type = LQ_HE_MIMO2;920			WARN_ON_ONCE(num_of_ant != 2);921		} else {922			WARN_ON_ONCE(1);923		}924	}925 926	WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 &&927		     !is_he(rate) && !is_vht(rate));928 929	return 0;930}931 932/* switch to another antenna/antennas and return 1 */933/* if no other valid antenna found, return 0 */934static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate)935{936	u8 new_ant_type;937 938	if (!rs_is_valid_ant(valid_ant, rate->ant))939		return 0;940 941	new_ant_type = ant_toggle_lookup[rate->ant];942 943	while ((new_ant_type != rate->ant) &&944	       !rs_is_valid_ant(valid_ant, new_ant_type))945		new_ant_type = ant_toggle_lookup[new_ant_type];946 947	if (new_ant_type == rate->ant)948		return 0;949 950	rate->ant = new_ant_type;951 952	return 1;953}954 955static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,956				  struct rs_rate *rate)957{958	if (is_legacy(rate))959		return lq_sta->active_legacy_rate;960	else if (is_siso(rate))961		return lq_sta->active_siso_rate;962	else if (is_mimo2(rate))963		return lq_sta->active_mimo2_rate;964 965	WARN_ON_ONCE(1);966	return 0;967}968 969static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,970				int rate_type)971{972	u8 high = IWL_RATE_INVALID;973	u8 low = IWL_RATE_INVALID;974 975	/* 802.11A or ht walks to the next literal adjacent rate in976	 * the rate table */977	if (is_type_a_band(rate_type) || !is_type_legacy(rate_type)) {978		int i;979		u32 mask;980 981		/* Find the previous rate that is in the rate mask */982		i = index - 1;983		if (i >= 0)984			mask = BIT(i);985		for (; i >= 0; i--, mask >>= 1) {986			if (rate_mask & mask) {987				low = i;988				break;989			}990		}991 992		/* Find the next rate that is in the rate mask */993		i = index + 1;994		for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {995			if (rate_mask & mask) {996				high = i;997				break;998			}999		}1000 1001		return (high << 8) | low;1002	}1003 1004	low = index;1005	while (low != IWL_RATE_INVALID) {1006		low = iwl_rates[low].prev_rs;1007		if (low == IWL_RATE_INVALID)1008			break;1009		if (rate_mask & (1 << low))1010			break;1011	}1012 1013	high = index;1014	while (high != IWL_RATE_INVALID) {1015		high = iwl_rates[high].next_rs;1016		if (high == IWL_RATE_INVALID)1017			break;1018		if (rate_mask & (1 << high))1019			break;1020	}1021 1022	return (high << 8) | low;1023}1024 1025static inline bool rs_rate_supported(struct iwl_lq_sta *lq_sta,1026				     struct rs_rate *rate)1027{1028	return BIT(rate->index) & rs_get_supported_rates(lq_sta, rate);1029}1030 1031/* Get the next supported lower rate in the current column.1032 * Return true if bottom rate in the current column was reached1033 */1034static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta,1035					struct rs_rate *rate)1036{1037	u8 low;1038	u16 high_low;1039	u16 rate_mask;1040	struct iwl_mvm *mvm = lq_sta->pers.drv;1041 1042	rate_mask = rs_get_supported_rates(lq_sta, rate);1043	high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask,1044					rate->type);1045	low = high_low & 0xff;1046 1047	/* Bottom rate of column reached */1048	if (low == IWL_RATE_INVALID)1049		return true;1050 1051	rate->index = low;1052	return false;1053}1054 1055/* Get the next rate to use following a column downgrade */1056static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,1057					  struct rs_rate *rate)1058{1059	struct iwl_mvm *mvm = lq_sta->pers.drv;1060 1061	if (is_legacy(rate)) {1062		/* No column to downgrade from Legacy */1063		return;1064	} else if (is_siso(rate)) {1065		/* Downgrade to Legacy if we were in SISO */1066		if (lq_sta->band == NL80211_BAND_5GHZ)1067			rate->type = LQ_LEGACY_A;1068		else1069			rate->type = LQ_LEGACY_G;1070 1071		rate->bw = RATE_MCS_CHAN_WIDTH_20;1072 1073		if (WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX))1074			rate->index = rs_ht_to_legacy[IWL_RATE_MCS_0_INDEX];1075		else if (WARN_ON_ONCE(rate->index > IWL_RATE_MCS_9_INDEX))1076			rate->index = rs_ht_to_legacy[IWL_RATE_MCS_9_INDEX];1077		else1078			rate->index = rs_ht_to_legacy[rate->index];1079 1080		rate->ldpc = false;1081	} else {1082		/* Downgrade to SISO with same MCS if in MIMO  */1083		rate->type = is_vht_mimo2(rate) ?1084			LQ_VHT_SISO : LQ_HT_SISO;1085	}1086 1087	if (num_of_ant(rate->ant) > 1)1088		rate->ant = first_antenna(iwl_mvm_get_valid_tx_ant(mvm));1089 1090	/* Relevant in both switching to SISO or Legacy */1091	rate->sgi = false;1092 1093	if (!rs_rate_supported(lq_sta, rate))1094		rs_get_lower_rate_in_column(lq_sta, rate);1095}1096 1097/* Check if both rates share the same column */1098static inline bool rs_rate_column_match(struct rs_rate *a,1099					struct rs_rate *b)1100{1101	bool ant_match;1102 1103	if (a->stbc || a->bfer)1104		ant_match = (b->ant == ANT_A || b->ant == ANT_B);1105	else1106		ant_match = (a->ant == b->ant);1107 1108	return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi)1109		&& ant_match;1110}1111 1112static inline enum rs_column rs_get_column_from_rate(struct rs_rate *rate)1113{1114	if (is_legacy(rate)) {1115		if (rate->ant == ANT_A)1116			return RS_COLUMN_LEGACY_ANT_A;1117 1118		if (rate->ant == ANT_B)1119			return RS_COLUMN_LEGACY_ANT_B;1120 1121		goto err;1122	}1123 1124	if (is_siso(rate)) {1125		if (rate->ant == ANT_A || rate->stbc || rate->bfer)1126			return rate->sgi ? RS_COLUMN_SISO_ANT_A_SGI :1127				RS_COLUMN_SISO_ANT_A;1128 1129		if (rate->ant == ANT_B)1130			return rate->sgi ? RS_COLUMN_SISO_ANT_B_SGI :1131				RS_COLUMN_SISO_ANT_B;1132 1133		goto err;1134	}1135 1136	if (is_mimo(rate))1137		return rate->sgi ? RS_COLUMN_MIMO2_SGI : RS_COLUMN_MIMO2;1138 1139err:1140	return RS_COLUMN_INVALID;1141}1142 1143static u8 rs_get_tid(struct ieee80211_hdr *hdr)1144{1145	u8 tid = IWL_MAX_TID_COUNT;1146 1147	if (ieee80211_is_data_qos(hdr->frame_control)) {1148		u8 *qc = ieee80211_get_qos_ctl(hdr);1149		tid = qc[0] & 0xf;1150	}1151 1152	if (unlikely(tid > IWL_MAX_TID_COUNT))1153		tid = IWL_MAX_TID_COUNT;1154 1155	return tid;1156}1157 1158/*1159 * mac80211 sends us Tx status1160 */1161static void rs_drv_mac80211_tx_status(void *mvm_r,1162				      struct ieee80211_supported_band *sband,1163				      struct ieee80211_sta *sta, void *priv_sta,1164				      struct sk_buff *skb)1165{1166	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;1167	struct iwl_op_mode *op_mode = mvm_r;1168	struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);1169	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);1170	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);1171 1172	if (!mvmsta->vif)1173		return;1174 1175	if (!ieee80211_is_data(hdr->frame_control) ||1176	    info->flags & IEEE80211_TX_CTL_NO_ACK)1177		return;1178 1179	iwl_mvm_rs_tx_status(mvm, sta, rs_get_tid(hdr), info,1180			     ieee80211_is_qos_nullfunc(hdr->frame_control));1181}1182 1183/*1184 * Begin a period of staying with a selected modulation mode.1185 * Set "stay_in_tbl" flag to prevent any mode switches.1186 * Set frame tx success limits according to legacy vs. high-throughput,1187 * and reset overall (spanning all rates) tx success history statistics.1188 * These control how long we stay using same modulation mode before1189 * searching for a new mode.1190 */1191static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,1192				 struct iwl_lq_sta *lq_sta)1193{1194	IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n");1195	lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN;1196	if (is_legacy) {1197		lq_sta->table_count_limit = IWL_MVM_RS_LEGACY_TABLE_COUNT;1198		lq_sta->max_failure_limit = IWL_MVM_RS_LEGACY_FAILURE_LIMIT;1199		lq_sta->max_success_limit = IWL_MVM_RS_LEGACY_SUCCESS_LIMIT;1200	} else {1201		lq_sta->table_count_limit = IWL_MVM_RS_NON_LEGACY_TABLE_COUNT;1202		lq_sta->max_failure_limit = IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT;1203		lq_sta->max_success_limit = IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT;1204	}1205	lq_sta->table_count = 0;1206	lq_sta->total_failed = 0;1207	lq_sta->total_success = 0;1208	lq_sta->flush_timer = jiffies;1209	lq_sta->visited_columns = 0;1210}1211 1212static inline int rs_get_max_rate_from_mask(unsigned long rate_mask)1213{1214	if (rate_mask)1215		return find_last_bit(&rate_mask, BITS_PER_LONG);1216	return IWL_RATE_INVALID;1217}1218 1219static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta,1220				   const struct rs_tx_column *column)1221{1222	switch (column->mode) {1223	case RS_LEGACY:1224		return lq_sta->max_legacy_rate_idx;1225	case RS_SISO:1226		return lq_sta->max_siso_rate_idx;1227	case RS_MIMO2:1228		return lq_sta->max_mimo2_rate_idx;1229	default:1230		WARN_ON_ONCE(1);1231	}1232 1233	return lq_sta->max_legacy_rate_idx;1234}1235 1236static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,1237					    const struct rs_tx_column *column,1238					    u32 bw)1239{1240	/* Used to choose among HT tables */1241	const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT];1242 1243	if (WARN_ON_ONCE(column->mode != RS_LEGACY &&1244			 column->mode != RS_SISO &&1245			 column->mode != RS_MIMO2))1246		return expected_tpt_legacy;1247 1248	/* Legacy rates have only one table */1249	if (column->mode == RS_LEGACY)1250		return expected_tpt_legacy;1251 1252	ht_tbl_pointer = expected_tpt_mimo2_20MHz;1253	/* Choose among many HT tables depending on number of streams1254	 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation1255	 * status */1256	if (column->mode == RS_SISO) {1257		switch (bw) {1258		case RATE_MCS_CHAN_WIDTH_20:1259			ht_tbl_pointer = expected_tpt_siso_20MHz;1260			break;1261		case RATE_MCS_CHAN_WIDTH_40:1262			ht_tbl_pointer = expected_tpt_siso_40MHz;1263			break;1264		case RATE_MCS_CHAN_WIDTH_80:1265			ht_tbl_pointer = expected_tpt_siso_80MHz;1266			break;1267		case RATE_MCS_CHAN_WIDTH_160:1268			ht_tbl_pointer = expected_tpt_siso_160MHz;1269			break;1270		default:1271			WARN_ON_ONCE(1);1272		}1273	} else if (column->mode == RS_MIMO2) {1274		switch (bw) {1275		case RATE_MCS_CHAN_WIDTH_20:1276			ht_tbl_pointer = expected_tpt_mimo2_20MHz;1277			break;1278		case RATE_MCS_CHAN_WIDTH_40:1279			ht_tbl_pointer = expected_tpt_mimo2_40MHz;1280			break;1281		case RATE_MCS_CHAN_WIDTH_80:1282			ht_tbl_pointer = expected_tpt_mimo2_80MHz;1283			break;1284		case RATE_MCS_CHAN_WIDTH_160:1285			ht_tbl_pointer = expected_tpt_mimo2_160MHz;1286			break;1287		default:1288			WARN_ON_ONCE(1);1289		}1290	} else {1291		WARN_ON_ONCE(1);1292	}1293 1294	if (!column->sgi && !lq_sta->is_agg)		/* Normal */1295		return ht_tbl_pointer[0];1296	else if (column->sgi && !lq_sta->is_agg)        /* SGI */1297		return ht_tbl_pointer[1];1298	else if (!column->sgi && lq_sta->is_agg)        /* AGG */1299		return ht_tbl_pointer[2];1300	else						/* AGG+SGI */1301		return ht_tbl_pointer[3];1302}1303 1304static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,1305				      struct iwl_scale_tbl_info *tbl)1306{1307	struct rs_rate *rate = &tbl->rate;1308	const struct rs_tx_column *column = &rs_tx_columns[tbl->column];1309 1310	tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw);1311}1312 1313/* rs uses two tables, one is active and the second is for searching better1314 * configuration. This function, according to the index of the currently1315 * active table returns the search table, which is located at the1316 * index complementary to 1 according to the active table (active = 1,1317 * search = 0 or active = 0, search = 1).1318 * Since lq_info is an arary of size 2, make sure index cannot be out of bounds.1319 */1320static inline u8 rs_search_tbl(u8 active_tbl)1321{1322	return (active_tbl ^ 1) & 1;1323}1324 1325static s32 rs_get_best_rate(struct iwl_mvm *mvm,1326			    struct iwl_lq_sta *lq_sta,1327			    struct iwl_scale_tbl_info *tbl,	/* "search" */1328			    unsigned long rate_mask, s8 index)1329{1330	struct iwl_scale_tbl_info *active_tbl =1331	    &(lq_sta->lq_info[lq_sta->active_tbl]);1332	s32 success_ratio = active_tbl->win[index].success_ratio;1333	u16 expected_current_tpt = active_tbl->expected_tpt[index];1334	const u16 *tpt_tbl = tbl->expected_tpt;1335	u16 high_low;1336	u32 target_tpt;1337	int rate_idx;1338 1339	if (success_ratio >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) {1340		target_tpt = 100 * expected_current_tpt;1341		IWL_DEBUG_RATE(mvm,1342			       "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n",1343			       success_ratio, target_tpt);1344	} else {1345		target_tpt = lq_sta->last_tpt;1346		IWL_DEBUG_RATE(mvm,1347			       "SR %d not that good. Find rate exceeding ACTUAL_TPT %d\n",1348			       success_ratio, target_tpt);1349	}1350 1351	rate_idx = find_first_bit(&rate_mask, BITS_PER_LONG);1352 1353	while (rate_idx != IWL_RATE_INVALID) {1354		if (target_tpt < (100 * tpt_tbl[rate_idx]))1355			break;1356 1357		high_low = rs_get_adjacent_rate(mvm, rate_idx, rate_mask,1358						tbl->rate.type);1359 1360		rate_idx = (high_low >> 8) & 0xff;1361	}1362 1363	IWL_DEBUG_RATE(mvm, "Best rate found %d target_tp %d expected_new %d\n",1364		       rate_idx, target_tpt,1365		       rate_idx != IWL_RATE_INVALID ?1366		       100 * tpt_tbl[rate_idx] : IWL_INVALID_VALUE);1367 1368	return rate_idx;1369}1370 1371static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)1372{1373	struct ieee80211_sta_vht_cap *sta_vht_cap = &sta->deflink.vht_cap;1374	struct ieee80211_vht_cap vht_cap = {1375		.vht_cap_info = cpu_to_le32(sta_vht_cap->cap),1376		.supp_mcs = sta_vht_cap->vht_mcs,1377	};1378 1379	switch (sta->deflink.bandwidth) {1380	case IEEE80211_STA_RX_BW_160:1381		/*1382		 * Don't use 160 MHz if VHT extended NSS support1383		 * says we cannot use 2 streams, we don't want to1384		 * deal with this.1385		 * We only check MCS 0 - they will support that if1386		 * we got here at all and we don't care which MCS,1387		 * we want to determine a more global state.1388		 */1389		if (ieee80211_get_vht_max_nss(&vht_cap,1390					      IEEE80211_VHT_CHANWIDTH_160MHZ,1391					      0, true,1392					      sta->deflink.rx_nss) < sta->deflink.rx_nss)1393			return RATE_MCS_CHAN_WIDTH_80;1394		return RATE_MCS_CHAN_WIDTH_160;1395	case IEEE80211_STA_RX_BW_80:1396		return RATE_MCS_CHAN_WIDTH_80;1397	case IEEE80211_STA_RX_BW_40:1398		return RATE_MCS_CHAN_WIDTH_40;1399	case IEEE80211_STA_RX_BW_20:1400	default:1401		return RATE_MCS_CHAN_WIDTH_20;1402	}1403}1404 1405/*1406 * Check whether we should continue using same modulation mode, or1407 * begin search for a new mode, based on:1408 * 1) # tx successes or failures while using this mode1409 * 2) # times calling this function1410 * 3) elapsed time in this mode (not used, for now)1411 */1412static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)1413{1414	struct iwl_scale_tbl_info *tbl;1415	int active_tbl;1416	int flush_interval_passed = 0;1417	struct iwl_mvm *mvm;1418 1419	mvm = lq_sta->pers.drv;1420	active_tbl = lq_sta->active_tbl;1421 1422	tbl = &(lq_sta->lq_info[active_tbl]);1423 1424	/* If we've been disallowing search, see if we should now allow it */1425	if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {1426		/* Elapsed time using current modulation mode */1427		if (lq_sta->flush_timer)1428			flush_interval_passed =1429				time_after(jiffies,1430					   (unsigned long)(lq_sta->flush_timer +1431							   (IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT * HZ)));1432 1433		/*1434		 * Check if we should allow search for new modulation mode.1435		 * If many frames have failed or succeeded, or we've used1436		 * this same modulation for a long time, allow search, and1437		 * reset history stats that keep track of whether we should1438		 * allow a new search.  Also (below) reset all bitmaps and1439		 * stats in active history.1440		 */1441		if (force_search ||1442		    (lq_sta->total_failed > lq_sta->max_failure_limit) ||1443		    (lq_sta->total_success > lq_sta->max_success_limit) ||1444		    ((!lq_sta->search_better_tbl) &&1445		     (lq_sta->flush_timer) && (flush_interval_passed))) {1446			IWL_DEBUG_RATE(mvm,1447				       "LQ: stay is expired %d %d %d\n",1448				     lq_sta->total_failed,1449				     lq_sta->total_success,1450				     flush_interval_passed);1451 1452			/* Allow search for new mode */1453			lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_STARTED;1454			IWL_DEBUG_RATE(mvm,1455				       "Moving to RS_STATE_SEARCH_CYCLE_STARTED\n");1456			lq_sta->total_failed = 0;1457			lq_sta->total_success = 0;1458			lq_sta->flush_timer = 0;1459			/* mark the current column as visited */1460			lq_sta->visited_columns = BIT(tbl->column);1461		/*1462		 * Else if we've used this modulation mode enough repetitions1463		 * (regardless of elapsed time or success/failure), reset1464		 * history bitmaps and rate-specific stats for all rates in1465		 * active table.1466		 */1467		} else {1468			lq_sta->table_count++;1469			if (lq_sta->table_count >=1470			    lq_sta->table_count_limit) {1471				lq_sta->table_count = 0;1472 1473				IWL_DEBUG_RATE(mvm,1474					       "LQ: stay in table clear win\n");1475				rs_rate_scale_clear_tbl_windows(mvm, tbl);1476			}1477		}1478 1479		/* If transitioning to allow "search", reset all history1480		 * bitmaps and stats in active table (this will become the new1481		 * "search" table). */1482		if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) {1483			rs_rate_scale_clear_tbl_windows(mvm, tbl);1484		}1485	}1486}1487 1488static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,1489			     struct iwl_scale_tbl_info *tbl,1490			     enum rs_action scale_action)1491{1492	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);1493	struct ieee80211_bss_conf *bss_conf = &mvmsta->vif->bss_conf;1494	int i;1495 1496	sta->deflink.agg.max_amsdu_len =1497		rs_fw_get_max_amsdu_len(sta, bss_conf, &sta->deflink);1498 1499	/*1500	 * In case TLC offload is not active amsdu_enabled is either 0xFFFF1501	 * or 0, since there is no per-TID alg.1502	 */1503	if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) ||1504	    tbl->rate.index < IWL_RATE_MCS_5_INDEX ||1505	    scale_action == RS_ACTION_DOWNSCALE)1506		mvmsta->amsdu_enabled = 0;1507	else1508		mvmsta->amsdu_enabled = 0xFFFF;1509 1510	if (bss_conf->he_support &&1511	    !iwlwifi_mod_params.disable_11ax)1512		mvmsta->max_amsdu_len = sta->deflink.agg.max_amsdu_len;1513	else1514		mvmsta->max_amsdu_len =1515			min_t(int, sta->deflink.agg.max_amsdu_len, 8500);1516 1517	sta->deflink.agg.max_rc_amsdu_len = mvmsta->max_amsdu_len;1518 1519	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {1520		if (mvmsta->amsdu_enabled)1521			sta->deflink.agg.max_tid_amsdu_len[i] =1522				iwl_mvm_max_amsdu_size(mvm, sta, i);1523		else1524			/*1525			 * Not so elegant, but this will effectively1526			 * prevent AMSDU on this TID1527			 */1528			sta->deflink.agg.max_tid_amsdu_len[i] = 1;1529	}1530}1531 1532/*1533 * setup rate table in uCode1534 */1535static void rs_update_rate_tbl(struct iwl_mvm *mvm,1536			       struct ieee80211_sta *sta,1537			       struct iwl_lq_sta *lq_sta,1538			       struct iwl_scale_tbl_info *tbl)1539{1540	rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate);1541	iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);1542}1543 1544static bool rs_tweak_rate_tbl(struct iwl_mvm *mvm,1545			      struct ieee80211_sta *sta,1546			      struct iwl_lq_sta *lq_sta,1547			      struct iwl_scale_tbl_info *tbl,1548			      enum rs_action scale_action)1549{1550	if (rs_bw_from_sta_bw(sta) != RATE_MCS_CHAN_WIDTH_80)1551		return false;1552 1553	if (!is_vht_siso(&tbl->rate))1554		return false;1555 1556	if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_80) &&1557	    (tbl->rate.index == IWL_RATE_MCS_0_INDEX) &&1558	    (scale_action == RS_ACTION_DOWNSCALE)) {1559		tbl->rate.bw = RATE_MCS_CHAN_WIDTH_20;1560		tbl->rate.index = IWL_RATE_MCS_4_INDEX;1561		IWL_DEBUG_RATE(mvm, "Switch 80Mhz SISO MCS0 -> 20Mhz MCS4\n");1562		goto tweaked;1563	}1564 1565	/* Go back to 80Mhz MCS1 only if we've established that 20Mhz MCS5 is1566	 * sustainable, i.e. we're past the test window. We can't go back1567	 * if MCS5 is just tested as this will happen always after switching1568	 * to 20Mhz MCS4 because the rate stats are cleared.1569	 */1570	if ((tbl->rate.bw == RATE_MCS_CHAN_WIDTH_20) &&1571	    (((tbl->rate.index == IWL_RATE_MCS_5_INDEX) &&1572	     (scale_action == RS_ACTION_STAY)) ||1573	     ((tbl->rate.index > IWL_RATE_MCS_5_INDEX) &&1574	      (scale_action == RS_ACTION_UPSCALE)))) {1575		tbl->rate.bw = RATE_MCS_CHAN_WIDTH_80;1576		tbl->rate.index = IWL_RATE_MCS_1_INDEX;1577		IWL_DEBUG_RATE(mvm, "Switch 20Mhz SISO MCS5 -> 80Mhz MCS1\n");1578		goto tweaked;1579	}1580 1581	return false;1582 1583tweaked:1584	rs_set_expected_tpt_table(lq_sta, tbl);1585	rs_rate_scale_clear_tbl_windows(mvm, tbl);1586	return true;1587}1588 1589static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,1590					 struct iwl_lq_sta *lq_sta,1591					 struct ieee80211_sta *sta,1592					 struct iwl_scale_tbl_info *tbl)1593{1594	int i, j, max_rate;1595	enum rs_column next_col_id;1596	const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];1597	const struct rs_tx_column *next_col;1598	allow_column_func_t allow_func;1599	u8 valid_ants = iwl_mvm_get_valid_tx_ant(mvm);1600	const u16 *expected_tpt_tbl;1601	u16 tpt, max_expected_tpt;1602 1603	for (i = 0; i < MAX_NEXT_COLUMNS; i++) {1604		next_col_id = curr_col->next_columns[i];1605 1606		if (next_col_id == RS_COLUMN_INVALID)1607			continue;1608 1609		if (lq_sta->visited_columns & BIT(next_col_id)) {1610			IWL_DEBUG_RATE(mvm, "Skip already visited column %d\n",1611				       next_col_id);1612			continue;1613		}1614 1615		next_col = &rs_tx_columns[next_col_id];1616 1617		if (!rs_is_valid_ant(valid_ants, next_col->ant)) {1618			IWL_DEBUG_RATE(mvm,1619				       "Skip column %d as ANT config isn't supported by chip. valid_ants 0x%x column ant 0x%x\n",1620				       next_col_id, valid_ants, next_col->ant);1621			continue;1622		}1623 1624		for (j = 0; j < MAX_COLUMN_CHECKS; j++) {1625			allow_func = next_col->checks[j];1626			if (allow_func && !allow_func(mvm, sta, &tbl->rate,1627						      next_col))1628				break;1629		}1630 1631		if (j != MAX_COLUMN_CHECKS) {1632			IWL_DEBUG_RATE(mvm,1633				       "Skip column %d: not allowed (check %d failed)\n",1634				       next_col_id, j);1635 1636			continue;1637		}1638 1639		tpt = lq_sta->last_tpt / 100;1640		expected_tpt_tbl = rs_get_expected_tpt_table(lq_sta, next_col,1641						     rs_bw_from_sta_bw(sta));1642		if (WARN_ON_ONCE(!expected_tpt_tbl))1643			continue;1644 1645		max_rate = rs_get_max_allowed_rate(lq_sta, next_col);1646		if (max_rate == IWL_RATE_INVALID) {1647			IWL_DEBUG_RATE(mvm,1648				       "Skip column %d: no rate is allowed in this column\n",1649				       next_col_id);1650			continue;1651		}1652 1653		max_expected_tpt = expected_tpt_tbl[max_rate];1654		if (tpt >= max_expected_tpt) {1655			IWL_DEBUG_RATE(mvm,1656				       "Skip column %d: can't beat current TPT. Max expected %d current %d\n",1657				       next_col_id, max_expected_tpt, tpt);1658			continue;1659		}1660 1661		IWL_DEBUG_RATE(mvm,1662			       "Found potential column %d. Max expected %d current %d\n",1663			       next_col_id, max_expected_tpt, tpt);1664		break;1665	}1666 1667	if (i == MAX_NEXT_COLUMNS)1668		return RS_COLUMN_INVALID;1669 1670	return next_col_id;1671}1672 1673static int rs_switch_to_column(struct iwl_mvm *mvm,1674			       struct iwl_lq_sta *lq_sta,1675			       struct ieee80211_sta *sta,1676			       enum rs_column col_id)1677{1678	struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];1679	struct iwl_scale_tbl_info *search_tbl =1680		&lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];1681	struct rs_rate *rate = &search_tbl->rate;1682	const struct rs_tx_column *column = &rs_tx_columns[col_id];1683	const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column];1684	unsigned long rate_mask = 0;1685	u32 rate_idx = 0;1686 1687	memcpy(search_tbl, tbl, offsetof(struct iwl_scale_tbl_info, win));1688 1689	rate->sgi = column->sgi;1690	rate->ant = column->ant;1691 1692	if (column->mode == RS_LEGACY) {1693		if (lq_sta->band == NL80211_BAND_5GHZ)1694			rate->type = LQ_LEGACY_A;1695		else1696			rate->type = LQ_LEGACY_G;1697 1698		rate->bw = RATE_MCS_CHAN_WIDTH_20;1699		rate->ldpc = false;1700		rate_mask = lq_sta->active_legacy_rate;1701	} else if (column->mode == RS_SISO) {1702		rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;1703		rate_mask = lq_sta->active_siso_rate;1704	} else if (column->mode == RS_MIMO2) {1705		rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;1706		rate_mask = lq_sta->active_mimo2_rate;1707	} else {1708		WARN_ONCE(1, "Bad column mode");1709	}1710 1711	if (column->mode != RS_LEGACY) {1712		rate->bw = rs_bw_from_sta_bw(sta);1713		rate->ldpc = lq_sta->ldpc;1714	}1715 1716	search_tbl->column = col_id;1717	rs_set_expected_tpt_table(lq_sta, search_tbl);1718 1719	lq_sta->visited_columns |= BIT(col_id);1720 1721	/* Get the best matching rate if we're changing modes. e.g.1722	 * SISO->MIMO, LEGACY->SISO, MIMO->SISO1723	 */1724	if (curr_column->mode != column->mode) {1725		rate_idx = rs_get_best_rate(mvm, lq_sta, search_tbl,1726					    rate_mask, rate->index);1727 1728		if ((rate_idx == IWL_RATE_INVALID) ||1729		    !(BIT(rate_idx) & rate_mask)) {1730			IWL_DEBUG_RATE(mvm,1731				       "can not switch with index %d"1732				       " rate mask %lx\n",1733				       rate_idx, rate_mask);1734 1735			goto err;1736		}1737 1738		rate->index = rate_idx;1739	}1740 1741	IWL_DEBUG_RATE(mvm, "Switched to column %d: Index %d\n",1742		       col_id, rate->index);1743 1744	return 0;1745 1746err:1747	rate->type = LQ_NONE;1748	return -1;1749}1750 1751static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,1752					 struct iwl_scale_tbl_info *tbl,1753					 s32 sr, int low, int high,1754					 int current_tpt,1755					 int low_tpt, int high_tpt)1756{1757	enum rs_action action = RS_ACTION_STAY;1758 1759	if ((sr <= RS_PERCENT(IWL_MVM_RS_SR_FORCE_DECREASE)) ||1760	    (current_tpt == 0)) {1761		IWL_DEBUG_RATE(mvm,1762			       "Decrease rate because of low SR\n");1763		return RS_ACTION_DOWNSCALE;1764	}1765 1766	if ((low_tpt == IWL_INVALID_VALUE) &&1767	    (high_tpt == IWL_INVALID_VALUE) &&1768	    (high != IWL_RATE_INVALID)) {1769		IWL_DEBUG_RATE(mvm,1770			       "No data about high/low rates. Increase rate\n");1771		return RS_ACTION_UPSCALE;1772	}1773 1774	if ((high_tpt == IWL_INVALID_VALUE) &&1775	    (high != IWL_RATE_INVALID) &&1776	    (low_tpt != IWL_INVALID_VALUE) &&1777	    (low_tpt < current_tpt)) {1778		IWL_DEBUG_RATE(mvm,1779			       "No data about high rate and low rate is worse. Increase rate\n");1780		return RS_ACTION_UPSCALE;1781	}1782 1783	if ((high_tpt != IWL_INVALID_VALUE) &&1784	    (high_tpt > current_tpt)) {1785		IWL_DEBUG_RATE(mvm,1786			       "Higher rate is better. Increate rate\n");1787		return RS_ACTION_UPSCALE;1788	}1789 1790	if ((low_tpt != IWL_INVALID_VALUE) &&1791	    (high_tpt != IWL_INVALID_VALUE) &&1792	    (low_tpt < current_tpt) &&1793	    (high_tpt < current_tpt)) {1794		IWL_DEBUG_RATE(mvm,1795			       "Both high and low are worse. Maintain rate\n");1796		return RS_ACTION_STAY;1797	}1798 1799	if ((low_tpt != IWL_INVALID_VALUE) &&1800	    (low_tpt > current_tpt)) {1801		IWL_DEBUG_RATE(mvm,1802			       "Lower rate is better\n");1803		action = RS_ACTION_DOWNSCALE;1804		goto out;1805	}1806 1807	if ((low_tpt == IWL_INVALID_VALUE) &&1808	    (low != IWL_RATE_INVALID)) {1809		IWL_DEBUG_RATE(mvm,1810			       "No data about lower rate\n");1811		action = RS_ACTION_DOWNSCALE;1812		goto out;1813	}1814 1815	IWL_DEBUG_RATE(mvm, "Maintain rate\n");1816 1817out:1818	if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) {1819		if (sr >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) {1820			IWL_DEBUG_RATE(mvm,1821				       "SR is above NO DECREASE. Avoid downscale\n");1822			action = RS_ACTION_STAY;1823		} else if (current_tpt > (100 * tbl->expected_tpt[low])) {1824			IWL_DEBUG_RATE(mvm,1825				       "Current TPT is higher than max expected in low rate. Avoid downscale\n");1826			action = RS_ACTION_STAY;1827		} else {1828			IWL_DEBUG_RATE(mvm, "Decrease rate\n");1829		}1830	}1831 1832	return action;1833}1834 1835static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,1836			  struct iwl_lq_sta *lq_sta)1837{1838	/* Our chip supports Tx STBC and the peer is an HT/VHT STA which1839	 * supports STBC of at least 1*SS1840	 */1841	if (!lq_sta->stbc_capable)1842		return false;1843 1844	if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))1845		return false;1846 1847	return true;1848}1849 1850static void rs_get_adjacent_txp(struct iwl_mvm *mvm, int index,1851				int *weaker, int *stronger)1852{1853	*weaker = index + IWL_MVM_RS_TPC_TX_POWER_STEP;1854	if (*weaker > TPC_MAX_REDUCTION)1855		*weaker = TPC_INVALID;1856 1857	*stronger = index - IWL_MVM_RS_TPC_TX_POWER_STEP;1858	if (*stronger < 0)1859		*stronger = TPC_INVALID;1860}1861 1862static bool rs_tpc_allowed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,1863			   struct rs_rate *rate, enum nl80211_band band)1864{1865	int index = rate->index;1866	bool cam = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM);1867	bool sta_ps_disabled = (vif->type == NL80211_IFTYPE_STATION &&1868				!vif->cfg.ps);1869 1870	IWL_DEBUG_RATE(mvm, "cam: %d sta_ps_disabled %d\n",1871		       cam, sta_ps_disabled);1872	/*1873	 * allow tpc only if power management is enabled, or bt coex1874	 * activity grade allows it and we are on 2.4Ghz.1875	 */1876	if ((cam || sta_ps_disabled) &&1877	    !iwl_mvm_bt_coex_is_tpc_allowed(mvm, band))1878		return false;1879 1880	IWL_DEBUG_RATE(mvm, "check rate, table type: %d\n", rate->type);1881	if (is_legacy(rate))1882		return index == IWL_RATE_54M_INDEX;1883	if (is_ht(rate))1884		return index == IWL_RATE_MCS_7_INDEX;1885	if (is_vht(rate))1886		return index == IWL_RATE_MCS_9_INDEX;1887 1888	WARN_ON_ONCE(1);1889	return false;1890}1891 1892enum tpc_action {1893	TPC_ACTION_STAY,1894	TPC_ACTION_DECREASE,1895	TPC_ACTION_INCREASE,1896	TPC_ACTION_NO_RESTIRCTION,1897};1898 1899static enum tpc_action rs_get_tpc_action(struct iwl_mvm *mvm,1900					 s32 sr, int weak, int strong,1901					 int current_tpt,1902					 int weak_tpt, int strong_tpt)1903{1904	/* stay until we have valid tpt */1905	if (current_tpt == IWL_INVALID_VALUE) {1906		IWL_DEBUG_RATE(mvm, "no current tpt. stay.\n");1907		return TPC_ACTION_STAY;1908	}1909 1910	/* Too many failures, increase txp */1911	if (sr <= RS_PERCENT(IWL_MVM_RS_TPC_SR_FORCE_INCREASE) ||1912	    current_tpt == 0) {1913		IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n");1914		return TPC_ACTION_NO_RESTIRCTION;1915	}1916 1917	/* try decreasing first if applicable */1918	if (sr >= RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) &&1919	    weak != TPC_INVALID) {1920		if (weak_tpt == IWL_INVALID_VALUE &&1921		    (strong_tpt == IWL_INVALID_VALUE ||1922		     current_tpt >= strong_tpt)) {1923			IWL_DEBUG_RATE(mvm,1924				       "no weak txp measurement. decrease txp\n");1925			return TPC_ACTION_DECREASE;1926		}1927 1928		if (weak_tpt > current_tpt) {1929			IWL_DEBUG_RATE(mvm,1930				       "lower txp has better tpt. decrease txp\n");1931			return TPC_ACTION_DECREASE;1932		}1933	}1934 1935	/* next, increase if needed */1936	if (sr < RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) &&1937	    strong != TPC_INVALID) {1938		if (weak_tpt == IWL_INVALID_VALUE &&1939		    strong_tpt != IWL_INVALID_VALUE &&1940		    current_tpt < strong_tpt) {1941			IWL_DEBUG_RATE(mvm,1942				       "higher txp has better tpt. increase txp\n");1943			return TPC_ACTION_INCREASE;1944		}1945 1946		if (weak_tpt < current_tpt &&1947		    (strong_tpt == IWL_INVALID_VALUE ||1948		     strong_tpt > current_tpt)) {1949			IWL_DEBUG_RATE(mvm,1950				       "lower txp has worse tpt. increase txp\n");1951			return TPC_ACTION_INCREASE;1952		}1953	}1954 1955	IWL_DEBUG_RATE(mvm, "no need to increase or decrease txp - stay\n");1956	return TPC_ACTION_STAY;1957}1958 1959static bool rs_tpc_perform(struct iwl_mvm *mvm,1960			   struct ieee80211_sta *sta,1961			   struct iwl_lq_sta *lq_sta,1962			   struct iwl_scale_tbl_info *tbl)1963{1964	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);1965	struct ieee80211_vif *vif = mvm_sta->vif;1966	struct ieee80211_chanctx_conf *chanctx_conf;1967	enum nl80211_band band;1968	struct iwl_rate_scale_data *window;1969	struct rs_rate *rate = &tbl->rate;1970	enum tpc_action action;1971	s32 sr;1972	u8 cur = lq_sta->lq.reduced_tpc;1973	int current_tpt;1974	int weak, strong;1975	int weak_tpt = IWL_INVALID_VALUE, strong_tpt = IWL_INVALID_VALUE;1976 1977#ifdef CONFIG_MAC80211_DEBUGFS1978	if (lq_sta->pers.dbg_fixed_txp_reduction <= TPC_MAX_REDUCTION) {1979		IWL_DEBUG_RATE(mvm, "fixed tpc: %d\n",1980			       lq_sta->pers.dbg_fixed_txp_reduction);1981		lq_sta->lq.reduced_tpc = lq_sta->pers.dbg_fixed_txp_reduction;1982		return cur != lq_sta->pers.dbg_fixed_txp_reduction;1983	}1984#endif1985 1986	rcu_read_lock();1987	chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf);1988	if (WARN_ON(!chanctx_conf))1989		band = NUM_NL80211_BANDS;1990	else1991		band = chanctx_conf->def.chan->band;1992	rcu_read_unlock();1993 1994	if (!rs_tpc_allowed(mvm, vif, rate, band)) {1995		IWL_DEBUG_RATE(mvm,1996			       "tpc is not allowed. remove txp restrictions\n");1997		lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION;1998		return cur != TPC_NO_REDUCTION;1999	}2000 2001	rs_get_adjacent_txp(mvm, cur, &weak, &strong);2002 2003	/* Collect measured throughputs for current and adjacent rates */2004	window = tbl->tpc_win;2005	sr = window[cur].success_ratio;2006	current_tpt = window[cur].average_tpt;2007	if (weak != TPC_INVALID)2008		weak_tpt = window[weak].average_tpt;2009	if (strong != TPC_INVALID)2010		strong_tpt = window[strong].average_tpt;2011 2012	IWL_DEBUG_RATE(mvm,2013		       "(TPC: %d): cur_tpt %d SR %d weak %d strong %d weak_tpt %d strong_tpt %d\n",2014		       cur, current_tpt, sr, weak, strong,2015		       weak_tpt, strong_tpt);2016 2017	action = rs_get_tpc_action(mvm, sr, weak, strong,2018				   current_tpt, weak_tpt, strong_tpt);2019 2020	/* override actions if we are on the edge */2021	if (weak == TPC_INVALID && action == TPC_ACTION_DECREASE) {2022		IWL_DEBUG_RATE(mvm, "already in lowest txp, stay\n");2023		action = TPC_ACTION_STAY;2024	} else if (strong == TPC_INVALID &&2025		   (action == TPC_ACTION_INCREASE ||2026		    action == TPC_ACTION_NO_RESTIRCTION)) {2027		IWL_DEBUG_RATE(mvm, "already in highest txp, stay\n");2028		action = TPC_ACTION_STAY;2029	}2030 2031	switch (action) {2032	case TPC_ACTION_DECREASE:2033		lq_sta->lq.reduced_tpc = weak;2034		return true;2035	case TPC_ACTION_INCREASE:2036		lq_sta->lq.reduced_tpc = strong;2037		return true;2038	case TPC_ACTION_NO_RESTIRCTION:2039		lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION;2040		return true;2041	case TPC_ACTION_STAY:2042		/* do nothing */2043		break;2044	}2045	return false;2046}2047 2048/*2049 * Do rate scaling and search for new modulation mode.2050 */2051static void rs_rate_scale_perform(struct iwl_mvm *mvm,2052				  struct ieee80211_sta *sta,2053				  struct iwl_lq_sta *lq_sta,2054				  int tid, bool ndp)2055{2056	int low = IWL_RATE_INVALID;2057	int high = IWL_RATE_INVALID;2058	int index;2059	struct iwl_rate_scale_data *window = NULL;2060	int current_tpt = IWL_INVALID_VALUE;2061	int low_tpt = IWL_INVALID_VALUE;2062	int high_tpt = IWL_INVALID_VALUE;2063	u32 fail_count;2064	enum rs_action scale_action = RS_ACTION_STAY;2065	u16 rate_mask;2066	u8 update_lq = 0;2067	struct iwl_scale_tbl_info *tbl, *tbl1;2068	u8 active_tbl = 0;2069	u8 done_search = 0;2070	u16 high_low;2071	s32 sr;2072	u8 prev_agg = lq_sta->is_agg;2073	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);2074	struct rs_rate *rate;2075 2076	lq_sta->is_agg = !!mvmsta->agg_tids;2077 2078	/*2079	 * Select rate-scale / modulation-mode table to work with in2080	 * the rest of this function:  "search" if searching for better2081	 * modulation mode, or "active" if doing rate scaling within a mode.2082	 */2083	if (!lq_sta->search_better_tbl)2084		active_tbl = lq_sta->active_tbl;2085	else2086		active_tbl = rs_search_tbl(lq_sta->active_tbl);2087 2088	tbl = &(lq_sta->lq_info[active_tbl]);2089	rate = &tbl->rate;2090 2091	if (prev_agg != lq_sta->is_agg) {2092		IWL_DEBUG_RATE(mvm,2093			       "Aggregation changed: prev %d current %d. Update expected TPT table\n",2094			       prev_agg, lq_sta->is_agg);2095		rs_set_expected_tpt_table(lq_sta, tbl);2096		rs_rate_scale_clear_tbl_windows(mvm, tbl);2097	}2098 2099	/* current tx rate */2100	index = rate->index;2101 2102	/* rates available for this association, and for modulation mode */2103	rate_mask = rs_get_supported_rates(lq_sta, rate);2104 2105	if (!(BIT(index) & rate_mask)) {2106		IWL_ERR(mvm, "Current Rate is not valid\n");2107		if (lq_sta->search_better_tbl) {2108			/* revert to active table if search table is not valid*/2109			rate->type = LQ_NONE;2110			lq_sta->search_better_tbl = 0;2111			tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);2112			rs_update_rate_tbl(mvm, sta, lq_sta, tbl);2113		}2114		return;2115	}2116 2117	/* Get expected throughput table and history window for current rate */2118	if (!tbl->expected_tpt) {2119		IWL_ERR(mvm, "tbl->expected_tpt is NULL\n");2120		return;2121	}2122 2123	/* TODO: handle rate_idx_mask and rate_idx_mcs_mask */2124	window = &(tbl->win[index]);2125 2126	/*2127	 * If there is not enough history to calculate actual average2128	 * throughput, keep analyzing results of more tx frames, without2129	 * changing rate or mode (bypass most of the rest of this function).2130	 * Set up new rate table in uCode only if old rate is not supported2131	 * in current association (use new rate found above).2132	 */2133	fail_count = window->counter - window->success_counter;2134	if ((fail_count < IWL_MVM_RS_RATE_MIN_FAILURE_TH) &&2135	    (window->success_counter < IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) {2136		IWL_DEBUG_RATE(mvm,2137			       "%s: Test Window: succ %d total %d\n",2138			       rs_pretty_rate(rate),2139			       window->success_counter, window->counter);2140 2141		/* Can't calculate this yet; not enough history */2142		window->average_tpt = IWL_INVALID_VALUE;2143 2144		/* Should we stay with this modulation mode,2145		 * or search for a new one? */2146		rs_stay_in_table(lq_sta, false);2147 2148		return;2149	}2150 2151	/* If we are searching for better modulation mode, check success. */2152	if (lq_sta->search_better_tbl) {2153		/* If good success, continue using the "search" mode;2154		 * no need to send new link quality command, since we're2155		 * continuing to use the setup that we've been trying. */2156		if (window->average_tpt > lq_sta->last_tpt) {2157			IWL_DEBUG_RATE(mvm,2158				       "SWITCHING TO NEW TABLE SR: %d "2159				       "cur-tpt %d old-tpt %d\n",2160				       window->success_ratio,2161				       window->average_tpt,2162				       lq_sta->last_tpt);2163 2164			/* Swap tables; "search" becomes "active" */2165			lq_sta->active_tbl = active_tbl;2166			current_tpt = window->average_tpt;2167		/* Else poor success; go back to mode in "active" table */2168		} else {2169			IWL_DEBUG_RATE(mvm,2170				       "GOING BACK TO THE OLD TABLE: SR %d "2171				       "cur-tpt %d old-tpt %d\n",2172				       window->success_ratio,2173				       window->average_tpt,2174				       lq_sta->last_tpt);2175 2176			/* Nullify "search" table */2177			rate->type = LQ_NONE;2178 2179			/* Revert to "active" table */2180			active_tbl = lq_sta->active_tbl;2181			tbl = &(lq_sta->lq_info[active_tbl]);2182 2183			/* Revert to "active" rate and throughput info */2184			index = tbl->rate.index;2185			current_tpt = lq_sta->last_tpt;2186 2187			/* Need to set up a new rate table in uCode */2188			update_lq = 1;2189		}2190 2191		/* Either way, we've made a decision; modulation mode2192		 * search is done, allow rate adjustment next time. */2193		lq_sta->search_better_tbl = 0;2194		done_search = 1;	/* Don't switch modes below! */2195		goto lq_update;2196	}2197 2198	/* (Else) not in search of better modulation mode, try for better2199	 * starting rate, while staying in this mode. */2200	high_low = rs_get_adjacent_rate(mvm, index, rate_mask, rate->type);2201	low = high_low & 0xff;2202	high = (high_low >> 8) & 0xff;2203 2204	/* TODO: handle rate_idx_mask and rate_idx_mcs_mask */2205 2206	sr = window->success_ratio;2207 2208	/* Collect measured throughputs for current and adjacent rates */2209	current_tpt = window->average_tpt;2210	if (low != IWL_RATE_INVALID)2211		low_tpt = tbl->win[low].average_tpt;2212	if (high != IWL_RATE_INVALID)2213		high_tpt = tbl->win[high].average_tpt;2214 2215	IWL_DEBUG_RATE(mvm,2216		       "%s: cur_tpt %d SR %d low %d high %d low_tpt %d high_tpt %d\n",2217		       rs_pretty_rate(rate), current_tpt, sr,2218		       low, high, low_tpt, high_tpt);2219 2220	scale_action = rs_get_rate_action(mvm, tbl, sr, low, high,2221					  current_tpt, low_tpt, high_tpt);2222 2223	/* Force a search in case BT doesn't like us being in MIMO */2224	if (is_mimo(rate) &&2225	    !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) {2226		IWL_DEBUG_RATE(mvm,2227			       "BT Coex forbids MIMO. Search for new config\n");2228		rs_stay_in_table(lq_sta, true);2229		goto lq_update;2230	}2231 2232	switch (scale_action) {2233	case RS_ACTION_DOWNSCALE:2234		/* Decrease starting rate, update uCode's rate table */2235		if (low != IWL_RATE_INVALID) {2236			update_lq = 1;2237			index = low;2238		} else {2239			IWL_DEBUG_RATE(mvm,2240				       "At the bottom rate. Can't decrease\n");2241		}2242 2243		break;2244	case RS_ACTION_UPSCALE:2245		/* Increase starting rate, update uCode's rate table */2246		if (high != IWL_RATE_INVALID) {2247			update_lq = 1;2248			index = high;2249		} else {2250			IWL_DEBUG_RATE(mvm,2251				       "At the top rate. Can't increase\n");2252		}2253 2254		break;2255	case RS_ACTION_STAY:2256		/* No change */2257		if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN)2258			update_lq = rs_tpc_perform(mvm, sta, lq_sta, tbl);2259		break;2260	default:2261		break;2262	}2263 2264lq_update:2265	/* Replace uCode's rate table for the destination station. */2266	if (update_lq) {2267		tbl->rate.index = index;2268		if (IWL_MVM_RS_80_20_FAR_RANGE_TWEAK)2269			rs_tweak_rate_tbl(mvm, sta, lq_sta, tbl, scale_action);2270		rs_set_amsdu_len(mvm, sta, tbl, scale_action);2271		rs_update_rate_tbl(mvm, sta, lq_sta, tbl);2272	}2273 2274	rs_stay_in_table(lq_sta, false);2275 2276	/*2277	 * Search for new modulation mode if we're:2278	 * 1)  Not changing rates right now2279	 * 2)  Not just finishing up a search2280	 * 3)  Allowing a new search2281	 */2282	if (!update_lq && !done_search &&2283	    lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED2284	    && window->counter) {2285		enum rs_column next_column;2286 2287		/* Save current throughput to compare with "search" throughput*/2288		lq_sta->last_tpt = current_tpt;2289 2290		IWL_DEBUG_RATE(mvm,2291			       "Start Search: update_lq %d done_search %d rs_state %d win->counter %d\n",2292			       update_lq, done_search, lq_sta->rs_state,2293			       window->counter);2294 2295		next_column = rs_get_next_column(mvm, lq_sta, sta, tbl);2296		if (next_column != RS_COLUMN_INVALID) {2297			int ret = rs_switch_to_column(mvm, lq_sta, sta,2298						      next_column);2299			if (!ret)2300				lq_sta->search_better_tbl = 1;2301		} else {2302			IWL_DEBUG_RATE(mvm,2303				       "No more columns to explore in search cycle. Go to RS_STATE_SEARCH_CYCLE_ENDED\n");2304			lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_ENDED;2305		}2306 2307		/* If new "search" mode was selected, set up in uCode table */2308		if (lq_sta->search_better_tbl) {2309			/* Access the "search" table, clear its history. */2310			tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];2311			rs_rate_scale_clear_tbl_windows(mvm, tbl);2312 2313			/* Use new "search" start rate */2314			index = tbl->rate.index;2315 2316			rs_dump_rate(mvm, &tbl->rate,2317				     "Switch to SEARCH TABLE:");2318			rs_update_rate_tbl(mvm, sta, lq_sta, tbl);2319		} else {2320			done_search = 1;2321		}2322	}2323 2324	if (!ndp)2325		rs_tl_turn_on_agg(mvm, mvmsta, tid, lq_sta, sta);2326 2327	if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) {2328		tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);2329		rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_sta);2330	}2331}2332 2333struct rs_init_rate_info {2334	s8 rssi;2335	u8 rate_idx;2336};2337 2338static const struct rs_init_rate_info rs_optimal_rates_24ghz_legacy[] = {2339	{ -60, IWL_RATE_54M_INDEX },2340	{ -64, IWL_RATE_48M_INDEX },2341	{ -68, IWL_RATE_36M_INDEX },2342	{ -80, IWL_RATE_24M_INDEX },2343	{ -84, IWL_RATE_18M_INDEX },2344	{ -85, IWL_RATE_12M_INDEX },2345	{ -86, IWL_RATE_11M_INDEX },2346	{ -88, IWL_RATE_5M_INDEX  },2347	{ -90, IWL_RATE_2M_INDEX  },2348	{ S8_MIN, IWL_RATE_1M_INDEX },2349};2350 2351static const struct rs_init_rate_info rs_optimal_rates_5ghz_legacy[] = {2352	{ -60, IWL_RATE_54M_INDEX },2353	{ -64, IWL_RATE_48M_INDEX },2354	{ -72, IWL_RATE_36M_INDEX },2355	{ -80, IWL_RATE_24M_INDEX },2356	{ -84, IWL_RATE_18M_INDEX },2357	{ -85, IWL_RATE_12M_INDEX },2358	{ -87, IWL_RATE_9M_INDEX  },2359	{ S8_MIN, IWL_RATE_6M_INDEX },2360};2361 2362static const struct rs_init_rate_info rs_optimal_rates_ht[] = {2363	{ -60, IWL_RATE_MCS_7_INDEX },2364	{ -64, IWL_RATE_MCS_6_INDEX },2365	{ -68, IWL_RATE_MCS_5_INDEX },2366	{ -72, IWL_RATE_MCS_4_INDEX },2367	{ -80, IWL_RATE_MCS_3_INDEX },2368	{ -84, IWL_RATE_MCS_2_INDEX },2369	{ -85, IWL_RATE_MCS_1_INDEX },2370	{ S8_MIN, IWL_RATE_MCS_0_INDEX},2371};2372 2373/* MCS index 9 is not valid for 20MHz VHT channel width,2374 * but is ok for 40, 80 and 160MHz channels.2375 */2376static const struct rs_init_rate_info rs_optimal_rates_vht_20mhz[] = {2377	{ -60, IWL_RATE_MCS_8_INDEX },2378	{ -64, IWL_RATE_MCS_7_INDEX },2379	{ -68, IWL_RATE_MCS_6_INDEX },2380	{ -72, IWL_RATE_MCS_5_INDEX },2381	{ -80, IWL_RATE_MCS_4_INDEX },2382	{ -84, IWL_RATE_MCS_3_INDEX },2383	{ -85, IWL_RATE_MCS_2_INDEX },2384	{ -87, IWL_RATE_MCS_1_INDEX },2385	{ S8_MIN, IWL_RATE_MCS_0_INDEX},2386};2387 2388static const struct rs_init_rate_info rs_optimal_rates_vht[] = {2389	{ -60, IWL_RATE_MCS_9_INDEX },2390	{ -64, IWL_RATE_MCS_8_INDEX },2391	{ -68, IWL_RATE_MCS_7_INDEX },2392	{ -72, IWL_RATE_MCS_6_INDEX },2393	{ -80, IWL_RATE_MCS_5_INDEX },2394	{ -84, IWL_RATE_MCS_4_INDEX },2395	{ -85, IWL_RATE_MCS_3_INDEX },2396	{ -87, IWL_RATE_MCS_2_INDEX },2397	{ -88, IWL_RATE_MCS_1_INDEX },2398	{ S8_MIN, IWL_RATE_MCS_0_INDEX },2399};2400 2401#define IWL_RS_LOW_RSSI_THRESHOLD (-76) /* dBm */2402 2403/* Init the optimal rate based on STA caps2404 * This combined with rssi is used to report the last tx rate2405 * to userspace when we haven't transmitted enough frames.2406 */2407static void rs_init_optimal_rate(struct iwl_mvm *mvm,2408				 struct ieee80211_sta *sta,2409				 struct iwl_lq_sta *lq_sta)2410{2411	struct rs_rate *rate = &lq_sta->optimal_rate;2412 2413	if (lq_sta->max_mimo2_rate_idx != IWL_RATE_INVALID)2414		rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;2415	else if (lq_sta->max_siso_rate_idx != IWL_RATE_INVALID)2416		rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;2417	else if (lq_sta->band == NL80211_BAND_5GHZ)2418		rate->type = LQ_LEGACY_A;2419	else2420		rate->type = LQ_LEGACY_G;2421 2422	rate->bw = rs_bw_from_sta_bw(sta);2423	rate->sgi = rs_sgi_allow(mvm, sta, rate, NULL);2424 2425	/* ANT/LDPC/STBC aren't relevant for the rate reported to userspace */2426 2427	if (is_mimo(rate)) {2428		lq_sta->optimal_rate_mask = lq_sta->active_mimo2_rate;2429	} else if (is_siso(rate)) {2430		lq_sta->optimal_rate_mask = lq_sta->active_siso_rate;2431	} else {2432		lq_sta->optimal_rate_mask = lq_sta->active_legacy_rate;2433 2434		if (lq_sta->band == NL80211_BAND_5GHZ) {2435			lq_sta->optimal_rates = rs_optimal_rates_5ghz_legacy;2436			lq_sta->optimal_nentries =2437				ARRAY_SIZE(rs_optimal_rates_5ghz_legacy);2438		} else {2439			lq_sta->optimal_rates = rs_optimal_rates_24ghz_legacy;2440			lq_sta->optimal_nentries =2441				ARRAY_SIZE(rs_optimal_rates_24ghz_legacy);2442		}2443	}2444 2445	if (is_vht(rate)) {2446		if (rate->bw == RATE_MCS_CHAN_WIDTH_20) {2447			lq_sta->optimal_rates = rs_optimal_rates_vht_20mhz;2448			lq_sta->optimal_nentries =2449				ARRAY_SIZE(rs_optimal_rates_vht_20mhz);2450		} else {2451			lq_sta->optimal_rates = rs_optimal_rates_vht;2452			lq_sta->optimal_nentries =2453				ARRAY_SIZE(rs_optimal_rates_vht);2454		}2455	} else if (is_ht(rate)) {2456		lq_sta->optimal_rates = rs_optimal_rates_ht;2457		lq_sta->optimal_nentries = ARRAY_SIZE(rs_optimal_rates_ht);2458	}2459}2460 2461/* Compute the optimal rate index based on RSSI */2462static struct rs_rate *rs_get_optimal_rate(struct iwl_mvm *mvm,2463					   struct iwl_lq_sta *lq_sta)2464{2465	struct rs_rate *rate = &lq_sta->optimal_rate;2466	int i;2467 2468	rate->index = find_first_bit(&lq_sta->optimal_rate_mask,2469				     BITS_PER_LONG);2470 2471	for (i = 0; i < lq_sta->optimal_nentries; i++) {2472		int rate_idx = lq_sta->optimal_rates[i].rate_idx;2473 2474		if ((lq_sta->pers.last_rssi >= lq_sta->optimal_rates[i].rssi) &&2475		    (BIT(rate_idx) & lq_sta->optimal_rate_mask)) {2476			rate->index = rate_idx;2477			break;2478		}2479	}2480 2481	return rate;2482}2483 2484/* Choose an initial legacy rate and antenna to use based on the RSSI2485 * of last Rx2486 */2487static void rs_get_initial_rate(struct iwl_mvm *mvm,2488				struct ieee80211_sta *sta,2489				struct iwl_lq_sta *lq_sta,2490				enum nl80211_band band,2491				struct rs_rate *rate)2492{2493	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);2494	int i, nentries;2495	unsigned long active_rate;2496	s8 best_rssi = S8_MIN;2497	u8 best_ant = ANT_NONE;2498	u8 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);2499	const struct rs_init_rate_info *initial_rates;2500 2501	for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) {2502		if (!(lq_sta->pers.chains & BIT(i)))2503			continue;2504 2505		if (lq_sta->pers.chain_signal[i] > best_rssi) {2506			best_rssi = lq_sta->pers.chain_signal[i];2507			best_ant = BIT(i);2508		}2509	}2510 2511	IWL_DEBUG_RATE(mvm, "Best ANT: %s Best RSSI: %d\n",2512		       iwl_rs_pretty_ant(best_ant), best_rssi);2513 2514	if (best_ant != ANT_A && best_ant != ANT_B)2515		rate->ant = first_antenna(valid_tx_ant);2516	else2517		rate->ant = best_ant;2518 2519	rate->sgi = false;2520	rate->ldpc = false;2521	rate->bw = RATE_MCS_CHAN_WIDTH_20;2522 2523	rate->index = find_first_bit(&lq_sta->active_legacy_rate,2524				     BITS_PER_LONG);2525 2526	if (band == NL80211_BAND_5GHZ) {2527		rate->type = LQ_LEGACY_A;2528		initial_rates = rs_optimal_rates_5ghz_legacy;2529		nentries = ARRAY_SIZE(rs_optimal_rates_5ghz_legacy);2530	} else {2531		rate->type = LQ_LEGACY_G;2532		initial_rates = rs_optimal_rates_24ghz_legacy;2533		nentries = ARRAY_SIZE(rs_optimal_rates_24ghz_legacy);2534	}2535 2536	if (!IWL_MVM_RS_RSSI_BASED_INIT_RATE)2537		goto out;2538 2539	/* Start from a higher rate if the corresponding debug capability2540	 * is enabled. The rate is chosen according to AP capabilities.2541	 * In case of VHT/HT when the rssi is low fallback to the case of2542	 * legacy rates.2543	 */2544	if (sta->deflink.vht_cap.vht_supported &&2545	    best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) {2546		/*2547		 * In AP mode, when a new station associates, rs is initialized2548		 * immediately upon association completion, before the phy2549		 * context is updated with the association parameters, so the2550		 * sta bandwidth might be wider than the phy context allows.2551		 * To avoid this issue, always initialize rs with 20mhz2552		 * bandwidth rate, and after authorization, when the phy context2553		 * is already up-to-date, re-init rs with the correct bw.2554		 */2555		u32 bw = mvmsta->sta_state < IEEE80211_STA_AUTHORIZED ?2556				RATE_MCS_CHAN_WIDTH_20 : rs_bw_from_sta_bw(sta);2557 2558		switch (bw) {2559		case RATE_MCS_CHAN_WIDTH_40:2560		case RATE_MCS_CHAN_WIDTH_80:2561		case RATE_MCS_CHAN_WIDTH_160:2562			initial_rates = rs_optimal_rates_vht;2563			nentries = ARRAY_SIZE(rs_optimal_rates_vht);2564			break;2565		case RATE_MCS_CHAN_WIDTH_20:2566			initial_rates = rs_optimal_rates_vht_20mhz;2567			nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz);2568			break;2569		default:2570			IWL_ERR(mvm, "Invalid BW %d\n",2571				sta->deflink.bandwidth);2572			goto out;2573		}2574 2575		active_rate = lq_sta->active_siso_rate;2576		rate->type = LQ_VHT_SISO;2577		rate->bw = bw;2578	} else if (sta->deflink.ht_cap.ht_supported &&2579		   best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) {2580		initial_rates = rs_optimal_rates_ht;2581		nentries = ARRAY_SIZE(rs_optimal_rates_ht);2582		active_rate = lq_sta->active_siso_rate;2583		rate->type = LQ_HT_SISO;2584	} else {2585		active_rate = lq_sta->active_legacy_rate;2586	}2587 2588	for (i = 0; i < nentries; i++) {2589		int rate_idx = initial_rates[i].rate_idx;2590 2591		if ((best_rssi >= initial_rates[i].rssi) &&2592		    (BIT(rate_idx) & active_rate)) {2593			rate->index = rate_idx;2594			break;2595		}2596	}2597 2598out:2599	rs_dump_rate(mvm, rate, "INITIAL");2600}2601 2602/* Save info about RSSI of last Rx */2603void rs_update_last_rssi(struct iwl_mvm *mvm,2604			 struct iwl_mvm_sta *mvmsta,2605			 struct ieee80211_rx_status *rx_status)2606{2607	struct iwl_lq_sta *lq_sta = &mvmsta->deflink.lq_sta.rs_drv;2608	int i;2609 2610	lq_sta->pers.chains = rx_status->chains;2611	lq_sta->pers.chain_signal[0] = rx_status->chain_signal[0];2612	lq_sta->pers.chain_signal[1] = rx_status->chain_signal[1];2613	lq_sta->pers.last_rssi = S8_MIN;2614 2615	for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) {2616		if (!(lq_sta->pers.chains & BIT(i)))2617			continue;2618 2619		if (lq_sta->pers.chain_signal[i] > lq_sta->pers.last_rssi)2620			lq_sta->pers.last_rssi = lq_sta->pers.chain_signal[i];2621	}2622}2623 2624/*2625 * rs_initialize_lq - Initialize a station's hardware rate table2626 *2627 * The uCode's station table contains a table of fallback rates2628 * for automatic fallback during transmission.2629 *2630 * NOTE: This sets up a default set of values.  These will be replaced later2631 *       if the driver's iwl-agn-rs rate scaling algorithm is used, instead of2632 *       rc80211_simple.2633 *2634 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before2635 *       calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,2636 *       which requires station table entry to exist).2637 */2638static void rs_initialize_lq(struct iwl_mvm *mvm,2639			     struct ieee80211_sta *sta,2640			     struct iwl_lq_sta *lq_sta,2641			     enum nl80211_band band)2642{2643	struct iwl_scale_tbl_info *tbl;2644	struct rs_rate *rate;2645	u8 active_tbl = 0;2646 2647	if (!sta || !lq_sta)2648		return;2649 2650	if (!lq_sta->search_better_tbl)2651		active_tbl = lq_sta->active_tbl;2652	else2653		active_tbl = rs_search_tbl(lq_sta->active_tbl);2654 2655	tbl = &(lq_sta->lq_info[active_tbl]);2656	rate = &tbl->rate;2657 2658	rs_get_initial_rate(mvm, sta, lq_sta, band, rate);2659	rs_init_optimal_rate(mvm, sta, lq_sta);2660 2661	WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B,2662		  "ant: 0x%x, chains 0x%x, fw tx ant: 0x%x, nvm tx ant: 0x%x\n",2663		  rate->ant, lq_sta->pers.chains, mvm->fw->valid_tx_ant,2664		  mvm->nvm_data ? mvm->nvm_data->valid_tx_ant : ANT_INVALID);2665 2666	tbl->column = rs_get_column_from_rate(rate);2667 2668	rs_set_expected_tpt_table(lq_sta, tbl);2669	rs_fill_lq_cmd(mvm, sta, lq_sta, rate);2670	/* TODO restore station should remember the lq cmd */2671	iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);2672}2673 2674static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,2675			    void *mvm_sta,2676			    struct ieee80211_tx_rate_control *txrc)2677{2678	struct iwl_op_mode *op_mode = mvm_r;2679	struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);2680	struct sk_buff *skb = txrc->skb;2681	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);2682	struct iwl_lq_sta *lq_sta;2683	struct rs_rate *optimal_rate;2684	u32 last_ucode_rate;2685 2686	if (sta && !iwl_mvm_sta_from_mac80211(sta)->vif) {2687		/* if vif isn't initialized mvm doesn't know about2688		 * this station, so don't do anything with the it2689		 */2690		mvm_sta = NULL;2691	}2692 2693	if (!mvm_sta)2694		return;2695 2696	lq_sta = mvm_sta;2697 2698	spin_lock_bh(&lq_sta->pers.lock);2699	iwl_mvm_hwrate_to_tx_rate_v1(lq_sta->last_rate_n_flags,2700				     info->band, &info->control.rates[0]);2701	info->control.rates[0].count = 1;2702 2703	/* Report the optimal rate based on rssi and STA caps if we haven't2704	 * converged yet (too little traffic) or exploring other modulations2705	 */2706	if (lq_sta->rs_state != RS_STATE_STAY_IN_COLUMN) {2707		optimal_rate = rs_get_optimal_rate(mvm, lq_sta);2708		last_ucode_rate = ucode_rate_from_rs_rate(mvm,2709							  optimal_rate);2710		iwl_mvm_hwrate_to_tx_rate_v1(last_ucode_rate, info->band,2711					     &txrc->reported_rate);2712	}2713	spin_unlock_bh(&lq_sta->pers.lock);2714}2715 2716static void *rs_drv_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,2717			      gfp_t gfp)2718{2719	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);2720	struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;2721	struct iwl_mvm *mvm  = IWL_OP_MODE_GET_MVM(op_mode);2722	struct iwl_lq_sta *lq_sta = &mvmsta->deflink.lq_sta.rs_drv;2723 2724	IWL_DEBUG_RATE(mvm, "create station rate scale window\n");2725 2726	lq_sta->pers.drv = mvm;2727#ifdef CONFIG_MAC80211_DEBUGFS2728	lq_sta->pers.dbg_fixed_rate = 0;2729	lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID;2730	lq_sta->pers.ss_force = RS_SS_FORCE_NONE;2731#endif2732	lq_sta->pers.chains = 0;2733	memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));2734	lq_sta->pers.last_rssi = S8_MIN;2735 2736	return lq_sta;2737}2738 2739static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,2740				       int nss)2741{2742	u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) &2743		(0x3 << (2 * (nss - 1)));2744	rx_mcs >>= (2 * (nss - 1));2745 2746	if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_7)2747		return IWL_RATE_MCS_7_INDEX;2748	else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_8)2749		return IWL_RATE_MCS_8_INDEX;2750	else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_9)2751		return IWL_RATE_MCS_9_INDEX;2752 2753	WARN_ON_ONCE(rx_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED);2754	return -1;2755}2756 2757static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,2758				     struct ieee80211_sta_vht_cap *vht_cap,2759				     struct iwl_lq_sta *lq_sta)2760{2761	int i;2762	int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1);2763 2764	if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {2765		for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {2766			if (i == IWL_RATE_9M_INDEX)2767				continue;2768 2769			/* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */2770			if (i == IWL_RATE_MCS_9_INDEX &&2771			    sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)2772				continue;2773 2774			lq_sta->active_siso_rate |= BIT(i);2775		}2776	}2777 2778	if (sta->deflink.rx_nss < 2)2779		return;2780 2781	highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);2782	if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {2783		for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {2784			if (i == IWL_RATE_9M_INDEX)2785				continue;2786 2787			/* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */2788			if (i == IWL_RATE_MCS_9_INDEX &&2789			    sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)2790				continue;2791 2792			lq_sta->active_mimo2_rate |= BIT(i);2793		}2794	}2795}2796 2797static void rs_ht_init(struct iwl_mvm *mvm,2798		       struct ieee80211_sta *sta,2799		       struct iwl_lq_sta *lq_sta,2800		       struct ieee80211_sta_ht_cap *ht_cap)2801{2802	/* active_siso_rate mask includes 9 MBits (bit 5),2803	 * and CCK (bits 0-3), supp_rates[] does not;2804	 * shift to convert format, force 9 MBits off.2805	 */2806	lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;2807	lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;2808	lq_sta->active_siso_rate &= ~((u16)0x2);2809	lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;2810 2811	lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;2812	lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;2813	lq_sta->active_mimo2_rate &= ~((u16)0x2);2814	lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;2815 2816	if (mvm->cfg->ht_params->ldpc &&2817	    (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING))2818		lq_sta->ldpc = true;2819 2820	if (mvm->cfg->ht_params->stbc &&2821	    (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&2822	    (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC))2823		lq_sta->stbc_capable = true;2824 2825	lq_sta->is_vht = false;2826}2827 2828static void rs_vht_init(struct iwl_mvm *mvm,2829			struct ieee80211_sta *sta,2830			struct iwl_lq_sta *lq_sta,2831			struct ieee80211_sta_vht_cap *vht_cap)2832{2833	rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);2834 2835	if (mvm->cfg->ht_params->ldpc &&2836	    (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))2837		lq_sta->ldpc = true;2838 2839	if (mvm->cfg->ht_params->stbc &&2840	    (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&2841	    (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))2842		lq_sta->stbc_capable = true;2843 2844	if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_BEAMFORMER) &&2845	    (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&2846	    (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE))2847		lq_sta->bfer_capable = true;2848 2849	lq_sta->is_vht = true;2850}2851 2852#ifdef CONFIG_IWLWIFI_DEBUGFS2853void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm)2854{2855	spin_lock_bh(&mvm->drv_stats_lock);2856	memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats));2857	spin_unlock_bh(&mvm->drv_stats_lock);2858}2859 2860void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)2861{2862	u8 nss = 0;2863 2864	spin_lock(&mvm->drv_stats_lock);2865 2866	if (agg)2867		mvm->drv_rx_stats.agg_frames++;2868 2869	mvm->drv_rx_stats.success_frames++;2870 2871	switch (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) {2872	case RATE_MCS_CHAN_WIDTH_20:2873		mvm->drv_rx_stats.bw_20_frames++;2874		break;2875	case RATE_MCS_CHAN_WIDTH_40:2876		mvm->drv_rx_stats.bw_40_frames++;2877		break;2878	case RATE_MCS_CHAN_WIDTH_80:2879		mvm->drv_rx_stats.bw_80_frames++;2880		break;2881	case RATE_MCS_CHAN_WIDTH_160:2882		mvm->drv_rx_stats.bw_160_frames++;2883		break;2884	default:2885		WARN_ONCE(1, "bad BW. rate 0x%x", rate);2886	}2887 2888	if (rate & RATE_MCS_HT_MSK_V1) {2889		mvm->drv_rx_stats.ht_frames++;2890		nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) >> RATE_HT_MCS_NSS_POS_V1) + 1;2891	} else if (rate & RATE_MCS_VHT_MSK_V1) {2892		mvm->drv_rx_stats.vht_frames++;2893		nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1;2894	} else {2895		mvm->drv_rx_stats.legacy_frames++;2896	}2897 2898	if (nss == 1)2899		mvm->drv_rx_stats.siso_frames++;2900	else if (nss == 2)2901		mvm->drv_rx_stats.mimo2_frames++;2902 2903	if (rate & RATE_MCS_SGI_MSK_V1)2904		mvm->drv_rx_stats.sgi_frames++;2905	else2906		mvm->drv_rx_stats.ngi_frames++;2907 2908	mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate;2909	mvm->drv_rx_stats.last_frame_idx =2910		(mvm->drv_rx_stats.last_frame_idx + 1) %2911			ARRAY_SIZE(mvm->drv_rx_stats.last_rates);2912 2913	spin_unlock(&mvm->drv_stats_lock);2914}2915#endif2916 2917/*2918 * Called after adding a new station to initialize rate scaling2919 */2920static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,2921			     enum nl80211_band band)2922{2923	int i, j;2924	struct ieee80211_hw *hw = mvm->hw;2925	struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;2926	struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;2927	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);2928	struct iwl_lq_sta *lq_sta = &mvmsta->deflink.lq_sta.rs_drv;2929	struct ieee80211_supported_band *sband;2930	unsigned long supp; /* must be unsigned long for for_each_set_bit */2931 2932	lockdep_assert_held(&mvmsta->deflink.lq_sta.rs_drv.pers.lock);2933 2934	/* clear all non-persistent lq data */2935	memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));2936 2937	sband = hw->wiphy->bands[band];2938 2939	lq_sta->lq.sta_id = mvmsta->deflink.sta_id;2940	mvmsta->amsdu_enabled = 0;2941	mvmsta->max_amsdu_len = sta->cur->max_amsdu_len;2942 2943	for (j = 0; j < LQ_SIZE; j++)2944		rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);2945 2946	lq_sta->flush_timer = 0;2947	lq_sta->last_tx = jiffies;2948 2949	IWL_DEBUG_RATE(mvm,2950		       "LQ: *** rate scale station global init for station %d ***\n",2951		       mvmsta->deflink.sta_id);2952	/* TODO: what is a good starting rate for STA? About middle? Maybe not2953	 * the lowest or the highest rate.. Could consider using RSSI from2954	 * previous packets? Need to have IEEE 802.1X auth succeed immediately2955	 * after assoc.. */2956 2957	lq_sta->missed_rate_counter = IWL_MVM_RS_MISSED_RATE_MAX;2958	lq_sta->band = sband->band;2959	/*2960	 * active legacy rates as per supported rates bitmap2961	 */2962	supp = sta->deflink.supp_rates[sband->band];2963	lq_sta->active_legacy_rate = 0;2964	for_each_set_bit(i, &supp, BITS_PER_LONG)2965		lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);2966 2967	/* TODO: should probably account for rx_highest for both HT/VHT */2968	if (!vht_cap || !vht_cap->vht_supported)2969		rs_ht_init(mvm, sta, lq_sta, ht_cap);2970	else2971		rs_vht_init(mvm, sta, lq_sta, vht_cap);2972 2973	lq_sta->max_legacy_rate_idx =2974		rs_get_max_rate_from_mask(lq_sta->active_legacy_rate);2975	lq_sta->max_siso_rate_idx =2976		rs_get_max_rate_from_mask(lq_sta->active_siso_rate);2977	lq_sta->max_mimo2_rate_idx =2978		rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate);2979 2980	IWL_DEBUG_RATE(mvm,2981		       "LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n",2982		       lq_sta->active_legacy_rate,2983		       lq_sta->active_siso_rate,2984		       lq_sta->active_mimo2_rate,2985		       lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable,2986		       lq_sta->bfer_capable);2987	IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n",2988		       lq_sta->max_legacy_rate_idx,2989		       lq_sta->max_siso_rate_idx,2990		       lq_sta->max_mimo2_rate_idx);2991 2992	/* These values will be overridden later */2993	lq_sta->lq.single_stream_ant_msk =2994		iwl_mvm_bt_coex_get_single_ant_msk(mvm, iwl_mvm_get_valid_tx_ant(mvm));2995	lq_sta->lq.dual_stream_ant_msk = ANT_AB;2996 2997	/* as default allow aggregation for all tids */2998	lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;2999	lq_sta->is_agg = 0;3000#ifdef CONFIG_IWLWIFI_DEBUGFS3001	iwl_mvm_reset_frame_stats(mvm);3002#endif3003	rs_initialize_lq(mvm, sta, lq_sta, band);3004}3005 3006static void rs_drv_rate_update(void *mvm_r,3007			       struct ieee80211_supported_band *sband,3008			       struct cfg80211_chan_def *chandef,3009			       struct ieee80211_sta *sta,3010			       void *priv_sta, u32 changed)3011{3012	struct iwl_op_mode *op_mode = mvm_r;3013	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);3014	struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);3015	u8 tid;3016 3017	if (!mvmsta->vif)3018		return;3019 3020	/* Stop any ongoing aggregations as rs starts off assuming no agg */3021	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)3022		ieee80211_stop_tx_ba_session(sta, tid);3023 3024	iwl_mvm_rs_rate_init(mvm, mvmsta->vif, sta,3025			     &mvmsta->vif->bss_conf, &sta->deflink,3026			     sband->band);3027}3028 3029static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm,3030				   struct ieee80211_sta *sta,3031				   int tid, struct ieee80211_tx_info *info,3032				   bool ndp)3033{3034	int legacy_success;3035	int retries;3036	int i;3037	struct iwl_lq_cmd *table;3038	u32 lq_hwrate;3039	struct rs_rate lq_rate, tx_resp_rate;3040	struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;3041	u32 tlc_info = (uintptr_t)info->status.status_driver_data[0];3042	u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK;3043	u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);3044	u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];3045	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);3046	struct iwl_lq_sta *lq_sta = &mvmsta->deflink.lq_sta.rs_drv;3047 3048	if (!lq_sta->pers.drv) {3049		IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");3050		return;3051	}3052 3053	/* This packet was aggregated but doesn't carry status info */3054	if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&3055	    !(info->flags & IEEE80211_TX_STAT_AMPDU))3056		return;3057 3058	if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band,3059				    &tx_resp_rate)) {3060		WARN_ON_ONCE(1);3061		return;3062	}3063 3064#ifdef CONFIG_MAC80211_DEBUGFS3065	/* Disable last tx check if we are debugging with fixed rate but3066	 * update tx stats3067	 */3068	if (lq_sta->pers.dbg_fixed_rate) {3069		int index = tx_resp_rate.index;3070		enum rs_column column;3071		int attempts, success;3072 3073		column = rs_get_column_from_rate(&tx_resp_rate);3074		if (WARN_ONCE(column == RS_COLUMN_INVALID,3075			      "Can't map rate 0x%x to column",3076			      tx_resp_hwrate))3077			return;3078 3079		if (info->flags & IEEE80211_TX_STAT_AMPDU) {3080			attempts = info->status.ampdu_len;3081			success = info->status.ampdu_ack_len;3082		} else {3083			attempts = info->status.rates[0].count;3084			success = !!(info->flags & IEEE80211_TX_STAT_ACK);3085		}3086 3087		lq_sta->pers.tx_stats[column][index].total += attempts;3088		lq_sta->pers.tx_stats[column][index].success += success;3089 3090		IWL_DEBUG_RATE(mvm, "Fixed rate 0x%x success %d attempts %d\n",3091			       tx_resp_hwrate, success, attempts);3092		return;3093	}3094#endif3095 3096	if (time_after(jiffies,3097		       (unsigned long)(lq_sta->last_tx +3098				       (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {3099		IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");3100		/* reach here only in case of driver RS, call directly3101		 * the unlocked version3102		 */3103		rs_drv_rate_init(mvm, sta, info->band);3104		return;3105	}3106	lq_sta->last_tx = jiffies;3107 3108	/* Ignore this Tx frame response if its initial rate doesn't match3109	 * that of latest Link Quality command.  There may be stragglers3110	 * from a previous Link Quality command, but we're no longer interested3111	 * in those; they're either from the "active" mode while we're trying3112	 * to check "search" mode, or a prior "search" mode after we've moved3113	 * to a new "search" mode (which might become the new "active" mode).3114	 */3115	table = &lq_sta->lq;3116	lq_hwrate = le32_to_cpu(table->rs_table[0]);3117	if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) {3118		WARN_ON_ONCE(1);3119		return;3120	}3121 3122	/* Here we actually compare this rate to the latest LQ command */3123	if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {3124		IWL_DEBUG_RATE(mvm,3125			       "tx resp color 0x%x does not match 0x%x\n",3126			       lq_color, LQ_FLAG_COLOR_GET(table->flags));3127 3128		/* Since rates mis-match, the last LQ command may have failed.3129		 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with3130		 * ... driver.3131		 */3132		lq_sta->missed_rate_counter++;3133		if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) {3134			lq_sta->missed_rate_counter = 0;3135			IWL_DEBUG_RATE(mvm,3136				       "Too many rates mismatch. Send sync LQ. rs_state %d\n",3137				       lq_sta->rs_state);3138			iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);3139		}3140		/* Regardless, ignore this status info for outdated rate */3141		return;3142	}3143 3144	/* Rate did match, so reset the missed_rate_counter */3145	lq_sta->missed_rate_counter = 0;3146 3147	if (!lq_sta->search_better_tbl) {3148		curr_tbl = &lq_sta->lq_info[lq_sta->active_tbl];3149		other_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];3150	} else {3151		curr_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];3152		other_tbl = &lq_sta->lq_info[lq_sta->active_tbl];3153	}3154 3155	if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) {3156		IWL_DEBUG_RATE(mvm,3157			       "Neither active nor search matches tx rate\n");3158		tmp_tbl = &lq_sta->lq_info[lq_sta->active_tbl];3159		rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");3160		tmp_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];3161		rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");3162		rs_dump_rate(mvm, &lq_rate, "ACTUAL");3163 3164		/* no matching table found, let's by-pass the data collection3165		 * and continue to perform rate scale to find the rate table3166		 */3167		rs_stay_in_table(lq_sta, true);3168		goto done;3169	}3170 3171	/* Updating the frame history depends on whether packets were3172	 * aggregated.3173	 *3174	 * For aggregation, all packets were transmitted at the same rate, the3175	 * first index into rate scale table.3176	 */3177	if (info->flags & IEEE80211_TX_STAT_AMPDU) {3178		rs_collect_tpc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index,3179				    info->status.ampdu_len,3180				    info->status.ampdu_ack_len,3181				    reduced_txp);3182 3183		/* ampdu_ack_len = 0 marks no BA was received. For TLC, treat3184		 * it as a single frame loss as we don't want the success ratio3185		 * to dip too quickly because a BA wasn't received.3186		 * For TPC, there's no need for this optimisation since we want3187		 * to recover very quickly from a bad power reduction and,3188		 * therefore we'd like the success ratio to get an immediate hit3189		 * when failing to get a BA, so we'd switch back to a lower or3190		 * zero power reduction. When FW transmits agg with a rate3191		 * different from the initial rate, it will not use reduced txp3192		 * and will send BA notification twice (one empty with reduced3193		 * txp equal to the value from LQ and one with reduced txp 0).3194		 * We need to update counters for each txp level accordingly.3195		 */3196		if (info->status.ampdu_ack_len == 0)3197			info->status.ampdu_len = 1;3198 3199		rs_collect_tlc_data(mvm, mvmsta, tid, curr_tbl,3200				    tx_resp_rate.index,3201				    info->status.ampdu_len,3202				    info->status.ampdu_ack_len);3203 3204		/* Update success/fail counts if not searching for new mode */3205		if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {3206			lq_sta->total_success += info->status.ampdu_ack_len;3207			lq_sta->total_failed += (info->status.ampdu_len -3208					info->status.ampdu_ack_len);3209		}3210	} else {3211		/* For legacy, update frame history with for each Tx retry. */3212		retries = info->status.rates[0].count - 1;3213		/* HW doesn't send more than 15 retries */3214		retries = min(retries, 15);3215 3216		/* The last transmission may have been successful */3217		legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);3218		/* Collect data for each rate used during failed TX attempts */3219		for (i = 0; i <= retries; ++i) {3220			lq_hwrate = le32_to_cpu(table->rs_table[i]);3221			if (rs_rate_from_ucode_rate(lq_hwrate, info->band,3222						    &lq_rate)) {3223				WARN_ON_ONCE(1);3224				return;3225			}3226 3227			/* Only collect stats if retried rate is in the same RS3228			 * table as active/search.3229			 */3230			if (rs_rate_column_match(&lq_rate, &curr_tbl->rate))3231				tmp_tbl = curr_tbl;3232			else if (rs_rate_column_match(&lq_rate,3233						      &other_tbl->rate))3234				tmp_tbl = other_tbl;3235			else3236				continue;3237 3238			rs_collect_tpc_data(mvm, lq_sta, tmp_tbl,3239					    tx_resp_rate.index, 1,3240					    i < retries ? 0 : legacy_success,3241					    reduced_txp);3242			rs_collect_tlc_data(mvm, mvmsta, tid, tmp_tbl,3243					    tx_resp_rate.index, 1,3244					    i < retries ? 0 : legacy_success);3245		}3246 3247		/* Update success/fail counts if not searching for new mode */3248		if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {3249			lq_sta->total_success += legacy_success;3250			lq_sta->total_failed += retries + (1 - legacy_success);3251		}3252	}3253	/* The last TX rate is cached in lq_sta; it's set in if/else above */3254	lq_sta->last_rate_n_flags = lq_hwrate;3255	IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);3256done:3257	/* See if there's a better rate or modulation mode to try. */3258	if (sta->deflink.supp_rates[info->band])3259		rs_rate_scale_perform(mvm, sta, lq_sta, tid, ndp);3260}3261 3262void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,3263			  int tid, struct ieee80211_tx_info *info, bool ndp)3264{3265	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);3266 3267	/* If it's locked we are in middle of init flow3268	 * just wait for next tx status to update the lq_sta data3269	 */3270	if (!spin_trylock_bh(&mvmsta->deflink.lq_sta.rs_drv.pers.lock))3271		return;3272 3273	__iwl_mvm_rs_tx_status(mvm, sta, tid, info, ndp);3274	spin_unlock_bh(&mvmsta->deflink.lq_sta.rs_drv.pers.lock);3275}3276 3277#ifdef CONFIG_MAC80211_DEBUGFS3278static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,3279					    struct iwl_lq_cmd *lq_cmd,3280					    enum nl80211_band band,3281					    u32 ucode_rate)3282{3283	struct rs_rate rate;3284	int i;3285	int num_rates = ARRAY_SIZE(lq_cmd->rs_table);3286	__le32 ucode_rate_le32 = cpu_to_le32(ucode_rate);3287	u8 ant = (ucode_rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;3288 3289	for (i = 0; i < num_rates; i++)3290		lq_cmd->rs_table[i] = ucode_rate_le32;3291 3292	if (rs_rate_from_ucode_rate(ucode_rate, band, &rate)) {3293		WARN_ON_ONCE(1);3294		return;3295	}3296 3297	if (is_mimo(&rate))3298		lq_cmd->mimo_delim = num_rates - 1;3299	else3300		lq_cmd->mimo_delim = 0;3301 3302	lq_cmd->reduced_tpc = 0;3303 3304	if (num_of_ant(ant) == 1)3305		lq_cmd->single_stream_ant_msk = ant;3306 3307	if (!mvm->trans->trans_cfg->gen2)3308		lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;3309	else3310		lq_cmd->agg_frame_cnt_limit =3311			LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF;3312}3313#endif /* CONFIG_MAC80211_DEBUGFS */3314 3315static void rs_fill_rates_for_column(struct iwl_mvm *mvm,3316				     struct iwl_lq_sta *lq_sta,3317				     struct rs_rate *rate,3318				     __le32 *rs_table, int *rs_table_index,3319				     int num_rates, int num_retries,3320				     u8 valid_tx_ant, bool toggle_ant)3321{3322	int i, j;3323	__le32 ucode_rate;3324	bool bottom_reached = false;3325	int prev_rate_idx = rate->index;3326	int end = LINK_QUAL_MAX_RETRY_NUM;3327	int index = *rs_table_index;3328 3329	for (i = 0; i < num_rates && index < end; i++) {3330		for (j = 0; j < num_retries && index < end; j++, index++) {3331			ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm,3332									 rate));3333			rs_table[index] = ucode_rate;3334			if (toggle_ant)3335				rs_toggle_antenna(valid_tx_ant, rate);3336		}3337 3338		prev_rate_idx = rate->index;3339		bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate);3340		if (bottom_reached && !is_legacy(rate))3341			break;3342	}3343 3344	if (!bottom_reached && !is_legacy(rate))3345		rate->index = prev_rate_idx;3346 3347	*rs_table_index = index;3348}3349 3350/* Building the rate table is non trivial. When we're in MIMO2/VHT/80Mhz/SGI3351 * column the rate table should look like this:3352 *3353 * rate[0] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI3354 * rate[1] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI3355 * rate[2] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI3356 * rate[3] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI3357 * rate[4] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI3358 * rate[5] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI3359 * rate[6] 0x4005007 VHT | ANT: A BW: 80Mhz MCS: 7 NSS: 1 NGI3360 * rate[7] 0x4009006 VHT | ANT: B BW: 80Mhz MCS: 6 NSS: 1 NGI3361 * rate[8] 0x4005005 VHT | ANT: A BW: 80Mhz MCS: 5 NSS: 1 NGI3362 * rate[9] 0x800B Legacy | ANT: B Rate: 36 Mbps3363 * rate[10] 0x4009 Legacy | ANT: A Rate: 24 Mbps3364 * rate[11] 0x8007 Legacy | ANT: B Rate: 18 Mbps3365 * rate[12] 0x4005 Legacy | ANT: A Rate: 12 Mbps3366 * rate[13] 0x800F Legacy | ANT: B Rate: 9 Mbps3367 * rate[14] 0x400D Legacy | ANT: A Rate: 6 Mbps3368 * rate[15] 0x800D Legacy | ANT: B Rate: 6 Mbps3369 */3370static void rs_build_rates_table(struct iwl_mvm *mvm,3371				 struct ieee80211_sta *sta,3372				 struct iwl_lq_sta *lq_sta,3373				 const struct rs_rate *initial_rate)3374{3375	struct rs_rate rate;3376	int num_rates, num_retries, index = 0;3377	u8 valid_tx_ant = 0;3378	struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;3379	bool toggle_ant = false;3380	u32 color;3381 3382	memcpy(&rate, initial_rate, sizeof(rate));3383 3384	valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);3385 3386	/* TODO: remove old API when min FW API hits 14 */3387	if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_LQ_SS_PARAMS) &&3388	    rs_stbc_allow(mvm, sta, lq_sta))3389		rate.stbc = true;3390 3391	if (is_siso(&rate)) {3392		num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES;3393		num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;3394	} else if (is_mimo(&rate)) {3395		num_rates = IWL_MVM_RS_INITIAL_MIMO_NUM_RATES;3396		num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;3397	} else {3398		num_rates = IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES;3399		num_retries = IWL_MVM_RS_INITIAL_LEGACY_RETRIES;3400		toggle_ant = true;3401	}3402 3403	rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,3404				 num_rates, num_retries, valid_tx_ant,3405				 toggle_ant);3406 3407	rs_get_lower_rate_down_column(lq_sta, &rate);3408 3409	if (is_siso(&rate)) {3410		num_rates = IWL_MVM_RS_SECONDARY_SISO_NUM_RATES;3411		num_retries = IWL_MVM_RS_SECONDARY_SISO_RETRIES;3412		lq_cmd->mimo_delim = index;3413	} else if (is_legacy(&rate)) {3414		num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;3415		num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES;3416	} else {3417		WARN_ON_ONCE(1);3418	}3419 3420	toggle_ant = true;3421 3422	rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,3423				 num_rates, num_retries, valid_tx_ant,3424				 toggle_ant);3425 3426	rs_get_lower_rate_down_column(lq_sta, &rate);3427 3428	num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;3429	num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES;3430 3431	rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,3432				 num_rates, num_retries, valid_tx_ant,3433				 toggle_ant);3434 3435	/* update the color of the LQ command (as a counter at bits 1-3) */3436	color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags));3437	lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color);3438}3439 3440struct rs_bfer_active_iter_data {3441	struct ieee80211_sta *exclude_sta;3442	struct iwl_mvm_sta *bfer_mvmsta;3443};3444 3445static void rs_bfer_active_iter(void *_data,3446				struct ieee80211_sta *sta)3447{3448	struct rs_bfer_active_iter_data *data = _data;3449	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);3450	struct iwl_lq_cmd *lq_cmd = &mvmsta->deflink.lq_sta.rs_drv.lq;3451	u32 ss_params = le32_to_cpu(lq_cmd->ss_params);3452 3453	if (sta == data->exclude_sta)3454		return;3455 3456	/* The current sta has BFER allowed */3457	if (ss_params & LQ_SS_BFER_ALLOWED) {3458		WARN_ON_ONCE(data->bfer_mvmsta != NULL);3459 3460		data->bfer_mvmsta = mvmsta;3461	}3462}3463 3464static int rs_bfer_priority(struct iwl_mvm_sta *sta)3465{3466	int prio = -1;3467	enum nl80211_iftype viftype = ieee80211_vif_type_p2p(sta->vif);3468 3469	switch (viftype) {3470	case NL80211_IFTYPE_AP:3471	case NL80211_IFTYPE_P2P_GO:3472		prio = 3;3473		break;3474	case NL80211_IFTYPE_P2P_CLIENT:3475		prio = 2;3476		break;3477	case NL80211_IFTYPE_STATION:3478		prio = 1;3479		break;3480	default:3481		WARN_ONCE(true, "viftype %d sta_id %d", viftype,3482			  sta->deflink.sta_id);3483		prio = -1;3484	}3485 3486	return prio;3487}3488 3489/* Returns >0 if sta1 has a higher BFER priority compared to sta2 */3490static int rs_bfer_priority_cmp(struct iwl_mvm_sta *sta1,3491				struct iwl_mvm_sta *sta2)3492{3493	int prio1 = rs_bfer_priority(sta1);3494	int prio2 = rs_bfer_priority(sta2);3495 3496	if (prio1 > prio2)3497		return 1;3498	if (prio1 < prio2)3499		return -1;3500	return 0;3501}3502 3503static void rs_set_lq_ss_params(struct iwl_mvm *mvm,3504				struct ieee80211_sta *sta,3505				struct iwl_lq_sta *lq_sta,3506				const struct rs_rate *initial_rate)3507{3508	struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;3509	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);3510	struct rs_bfer_active_iter_data data = {3511		.exclude_sta = sta,3512		.bfer_mvmsta = NULL,3513	};3514	struct iwl_mvm_sta *bfer_mvmsta = NULL;3515	u32 ss_params = LQ_SS_PARAMS_VALID;3516 3517	if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))3518		goto out;3519 3520#ifdef CONFIG_MAC80211_DEBUGFS3521	/* Check if forcing the decision is configured.3522	 * Note that SISO is forced by not allowing STBC or BFER3523	 */3524	if (lq_sta->pers.ss_force == RS_SS_FORCE_STBC)3525		ss_params |= (LQ_SS_STBC_1SS_ALLOWED | LQ_SS_FORCE);3526	else if (lq_sta->pers.ss_force == RS_SS_FORCE_BFER)3527		ss_params |= (LQ_SS_BFER_ALLOWED | LQ_SS_FORCE);3528 3529	if (lq_sta->pers.ss_force != RS_SS_FORCE_NONE) {3530		IWL_DEBUG_RATE(mvm, "Forcing single stream Tx decision %d\n",3531			       lq_sta->pers.ss_force);3532		goto out;3533	}3534#endif3535 3536	if (lq_sta->stbc_capable)3537		ss_params |= LQ_SS_STBC_1SS_ALLOWED;3538 3539	if (!lq_sta->bfer_capable)3540		goto out;3541 3542	ieee80211_iterate_stations_atomic(mvm->hw,3543					  rs_bfer_active_iter,3544					  &data);3545	bfer_mvmsta = data.bfer_mvmsta;3546 3547	/* This code is safe as it doesn't run concurrently for different3548	 * stations. This is guaranteed by the fact that calls to3549	 * ieee80211_tx_status wouldn't run concurrently for a single HW.3550	 */3551	if (!bfer_mvmsta) {3552		IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n");3553 3554		ss_params |= LQ_SS_BFER_ALLOWED;3555		goto out;3556	}3557 3558	IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n",3559		       bfer_mvmsta->deflink.sta_id);3560 3561	/* Disallow BFER on another STA if active and we're a higher priority */3562	if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) {3563		struct iwl_lq_cmd *bfersta_lq_cmd =3564			&bfer_mvmsta->deflink.lq_sta.rs_drv.lq;3565		u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params);3566 3567		bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED;3568		bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params);3569		iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd);3570 3571		ss_params |= LQ_SS_BFER_ALLOWED;3572		IWL_DEBUG_RATE(mvm,3573			       "Lower priority BFER sta found (%d). Switch BFER\n",3574			       bfer_mvmsta->deflink.sta_id);3575	}3576out:3577	lq_cmd->ss_params = cpu_to_le32(ss_params);3578}3579 3580static void rs_fill_lq_cmd(struct iwl_mvm *mvm,3581			   struct ieee80211_sta *sta,3582			   struct iwl_lq_sta *lq_sta,3583			   const struct rs_rate *initial_rate)3584{3585	struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;3586	struct iwl_mvm_sta *mvmsta;3587	struct iwl_mvm_vif *mvmvif;3588 3589	lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START;3590	lq_cmd->agg_time_limit =3591		cpu_to_le16(IWL_MVM_RS_AGG_TIME_LIMIT);3592 3593#ifdef CONFIG_MAC80211_DEBUGFS3594	if (lq_sta->pers.dbg_fixed_rate) {3595		rs_build_rates_table_from_fixed(mvm, lq_cmd,3596						lq_sta->band,3597						lq_sta->pers.dbg_fixed_rate);3598		return;3599	}3600#endif3601	if (WARN_ON_ONCE(!sta || !initial_rate))3602		return;3603 3604	rs_build_rates_table(mvm, sta, lq_sta, initial_rate);3605 3606	if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_LQ_SS_PARAMS))3607		rs_set_lq_ss_params(mvm, sta, lq_sta, initial_rate);3608 3609	mvmsta = iwl_mvm_sta_from_mac80211(sta);3610	mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);3611 3612	if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2) &&3613	    num_of_ant(initial_rate->ant) == 1)3614		lq_cmd->single_stream_ant_msk = initial_rate->ant;3615 3616	lq_cmd->agg_frame_cnt_limit = lq_sta->pers.max_agg_bufsize;3617 3618	/*3619	 * In case of low latency, tell the firmware to leave a frame in the3620	 * Tx Fifo so that it can start a transaction in the same TxOP. This3621	 * basically allows the firmware to send bursts.3622	 */3623	if (iwl_mvm_vif_low_latency(mvmvif))3624		lq_cmd->agg_frame_cnt_limit--;3625 3626	if (mvmsta->vif->p2p)3627		lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK;3628 3629	lq_cmd->agg_time_limit =3630			cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta));3631}3632 3633static void *rs_alloc(struct ieee80211_hw *hw)3634{3635	return hw->priv;3636}3637 3638/* rate scale requires free function to be implemented */3639static void rs_free(void *mvm_rate)3640{3641	return;3642}3643 3644static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta)3645{3646	struct iwl_op_mode *op_mode __maybe_unused = mvm_r;3647	struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);3648 3649	IWL_DEBUG_RATE(mvm, "enter\n");3650	IWL_DEBUG_RATE(mvm, "leave\n");3651}3652 3653int rs_pretty_print_rate_v1(char *buf, int bufsz, const u32 rate)3654{3655 3656	char *type;3657	u8 mcs = 0, nss = 0;3658	u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;3659	u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) >>3660		RATE_MCS_CHAN_WIDTH_POS;3661 3662	if (!(rate & RATE_MCS_HT_MSK_V1) &&3663	    !(rate & RATE_MCS_VHT_MSK_V1) &&3664	    !(rate & RATE_MCS_HE_MSK_V1)) {3665		int index = iwl_hwrate_to_plcp_idx(rate);3666 3667		return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps",3668				 iwl_rs_pretty_ant(ant),3669				 index == IWL_RATE_INVALID ? "BAD" :3670				 iwl_rate_mcs(index)->mbps);3671	}3672 3673	if (rate & RATE_MCS_VHT_MSK_V1) {3674		type = "VHT";3675		mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;3676		nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1;3677	} else if (rate & RATE_MCS_HT_MSK_V1) {3678		type = "HT";3679		mcs = rate & RATE_HT_MCS_INDEX_MSK_V1;3680		nss = ((rate & RATE_HT_MCS_NSS_MSK_V1)3681		       >> RATE_HT_MCS_NSS_POS_V1) + 1;3682	} else if (rate & RATE_MCS_HE_MSK_V1) {3683		type = "HE";3684		mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;3685		nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1;3686	} else {3687		type = "Unknown"; /* shouldn't happen */3688	}3689 3690	return scnprintf(buf, bufsz,3691			 "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s",3692			 rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss,3693			 (rate & RATE_MCS_SGI_MSK_V1) ? "SGI " : "NGI ",3694			 (rate & RATE_MCS_STBC_MSK) ? "STBC " : "",3695			 (rate & RATE_MCS_LDPC_MSK_V1) ? "LDPC " : "",3696			 (rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "",3697			 (rate & RATE_MCS_BF_MSK) ? "BF " : "");3698}3699 3700#ifdef CONFIG_MAC80211_DEBUGFS3701/*3702 * Program the device to use fixed rate for frame transmit3703 * This is for debugging/testing only3704 * once the device start use fixed rate, we need to reload the module3705 * to being back the normal operation.3706 */3707static void rs_program_fix_rate(struct iwl_mvm *mvm,3708				struct iwl_lq_sta *lq_sta)3709{3710	lq_sta->active_legacy_rate = 0x0FFF;	/* 1 - 54 MBits, includes CCK */3711	lq_sta->active_siso_rate   = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */3712	lq_sta->active_mimo2_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */3713 3714	IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",3715		       lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate);3716 3717	if (lq_sta->pers.dbg_fixed_rate) {3718		rs_fill_lq_cmd(mvm, NULL, lq_sta, NULL);3719		iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq);3720	}3721}3722 3723static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,3724			const char __user *user_buf, size_t count, loff_t *ppos)3725{3726	struct iwl_lq_sta *lq_sta = file->private_data;3727	struct iwl_mvm *mvm;3728	char buf[64];3729	size_t buf_size;3730	u32 parsed_rate;3731 3732	mvm = lq_sta->pers.drv;3733	memset(buf, 0, sizeof(buf));3734	buf_size = min(count, sizeof(buf) -  1);3735	if (copy_from_user(buf, user_buf, buf_size))3736		return -EFAULT;3737 3738	if (sscanf(buf, "%x", &parsed_rate) == 1)3739		lq_sta->pers.dbg_fixed_rate = parsed_rate;3740	else3741		lq_sta->pers.dbg_fixed_rate = 0;3742 3743	rs_program_fix_rate(mvm, lq_sta);3744 3745	return count;3746}3747 3748static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,3749			char __user *user_buf, size_t count, loff_t *ppos)3750{3751	char *buff;3752	int desc = 0;3753	int i = 0;3754	ssize_t ret;3755	static const size_t bufsz = 2048;3756 3757	struct iwl_lq_sta *lq_sta = file->private_data;3758	struct iwl_mvm_sta *mvmsta =3759		container_of(lq_sta, struct iwl_mvm_sta, deflink.lq_sta.rs_drv);3760	struct iwl_mvm *mvm;3761	struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);3762	struct rs_rate *rate = &tbl->rate;3763	u32 ss_params;3764 3765	mvm = lq_sta->pers.drv;3766	buff = kmalloc(bufsz, GFP_KERNEL);3767	if (!buff)3768		return -ENOMEM;3769 3770	desc += scnprintf(buff + desc, bufsz - desc,3771			  "sta_id %d\n", lq_sta->lq.sta_id);3772	desc += scnprintf(buff + desc, bufsz - desc,3773			  "failed=%d success=%d rate=0%lX\n",3774			  lq_sta->total_failed, lq_sta->total_success,3775			  lq_sta->active_legacy_rate);3776	desc += scnprintf(buff + desc, bufsz - desc, "fixed rate 0x%X\n",3777			  lq_sta->pers.dbg_fixed_rate);3778	desc += scnprintf(buff + desc, bufsz - desc, "valid_tx_ant %s%s\n",3779	    (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",3780	    (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "");3781	desc += scnprintf(buff + desc, bufsz - desc, "lq type %s\n",3782			  (is_legacy(rate)) ? "legacy" :3783			  is_vht(rate) ? "VHT" : "HT");3784	if (!is_legacy(rate)) {3785		desc += scnprintf(buff + desc, bufsz - desc, " %s",3786		   (is_siso(rate)) ? "SISO" : "MIMO2");3787		desc += scnprintf(buff + desc, bufsz - desc, " %s",3788				(is_ht20(rate)) ? "20MHz" :3789				(is_ht40(rate)) ? "40MHz" :3790				(is_ht80(rate)) ? "80MHz" :3791				(is_ht160(rate)) ? "160MHz" : "BAD BW");3792		desc += scnprintf(buff + desc, bufsz - desc, " %s %s %s %s\n",3793				(rate->sgi) ? "SGI" : "NGI",3794				(rate->ldpc) ? "LDPC" : "BCC",3795				(lq_sta->is_agg) ? "AGG on" : "",3796				(mvmsta->amsdu_enabled) ? "AMSDU on" : "");3797	}3798	desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X\n",3799			lq_sta->last_rate_n_flags);3800	desc += scnprintf(buff + desc, bufsz - desc,3801			"general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n",3802			lq_sta->lq.flags,3803			lq_sta->lq.mimo_delim,3804			lq_sta->lq.single_stream_ant_msk,3805			lq_sta->lq.dual_stream_ant_msk);3806 3807	desc += scnprintf(buff + desc, bufsz - desc,3808			"agg: time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",3809			le16_to_cpu(lq_sta->lq.agg_time_limit),3810			lq_sta->lq.agg_disable_start_th,3811			lq_sta->lq.agg_frame_cnt_limit);3812 3813	desc += scnprintf(buff + desc, bufsz - desc, "reduced tpc=%d\n",3814			  lq_sta->lq.reduced_tpc);3815	ss_params = le32_to_cpu(lq_sta->lq.ss_params);3816	desc += scnprintf(buff + desc, bufsz - desc,3817			"single stream params: %s%s%s%s\n",3818			(ss_params & LQ_SS_PARAMS_VALID) ?3819			"VALID" : "INVALID",3820			(ss_params & LQ_SS_BFER_ALLOWED) ?3821			", BFER" : "",3822			(ss_params & LQ_SS_STBC_1SS_ALLOWED) ?3823			", STBC" : "",3824			(ss_params & LQ_SS_FORCE) ?3825			", FORCE" : "");3826	desc += scnprintf(buff + desc, bufsz - desc,3827			"Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",3828			lq_sta->lq.initial_rate_index[0],3829			lq_sta->lq.initial_rate_index[1],3830			lq_sta->lq.initial_rate_index[2],3831			lq_sta->lq.initial_rate_index[3]);3832 3833	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {3834		u32 r = le32_to_cpu(lq_sta->lq.rs_table[i]);3835 3836		desc += scnprintf(buff + desc, bufsz - desc,3837				  " rate[%d] 0x%X ", i, r);3838		desc += rs_pretty_print_rate_v1(buff + desc, bufsz - desc, r);3839		if (desc < bufsz - 1)3840			buff[desc++] = '\n';3841	}3842 3843	ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);3844	kfree(buff);3845	return ret;3846}3847 3848static const struct file_operations rs_sta_dbgfs_scale_table_ops = {3849	.write = rs_sta_dbgfs_scale_table_write,3850	.read = rs_sta_dbgfs_scale_table_read,3851	.open = simple_open,3852	.llseek = default_llseek,3853};3854static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,3855			char __user *user_buf, size_t count, loff_t *ppos)3856{3857	char *buff;3858	int desc = 0;3859	int i, j;3860	ssize_t ret;3861	struct iwl_scale_tbl_info *tbl;3862	struct rs_rate *rate;3863	struct iwl_lq_sta *lq_sta = file->private_data;3864 3865	buff = kmalloc(1024, GFP_KERNEL);3866	if (!buff)3867		return -ENOMEM;3868 3869	for (i = 0; i < LQ_SIZE; i++) {3870		tbl = &(lq_sta->lq_info[i]);3871		rate = &tbl->rate;3872		desc += sprintf(buff+desc,3873				"%s type=%d SGI=%d BW=%s DUP=0\n"3874				"index=%d\n",3875				lq_sta->active_tbl == i ? "*" : "x",3876				rate->type,3877				rate->sgi,3878				is_ht20(rate) ? "20MHz" :3879				is_ht40(rate) ? "40MHz" :3880				is_ht80(rate) ? "80MHz" :3881				is_ht160(rate) ? "160MHz" : "ERR",3882				rate->index);3883		for (j = 0; j < IWL_RATE_COUNT; j++) {3884			desc += sprintf(buff+desc,3885				"counter=%d success=%d %%=%d\n",3886				tbl->win[j].counter,3887				tbl->win[j].success_counter,3888				tbl->win[j].success_ratio);3889		}3890	}3891	ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);3892	kfree(buff);3893	return ret;3894}3895 3896static const struct file_operations rs_sta_dbgfs_stats_table_ops = {3897	.read = rs_sta_dbgfs_stats_table_read,3898	.open = simple_open,3899	.llseek = default_llseek,3900};3901 3902static ssize_t rs_sta_dbgfs_drv_tx_stats_read(struct file *file,3903					      char __user *user_buf,3904					      size_t count, loff_t *ppos)3905{3906	static const char * const column_name[] = {3907		[RS_COLUMN_LEGACY_ANT_A] = "LEGACY_ANT_A",3908		[RS_COLUMN_LEGACY_ANT_B] = "LEGACY_ANT_B",3909		[RS_COLUMN_SISO_ANT_A] = "SISO_ANT_A",3910		[RS_COLUMN_SISO_ANT_B] = "SISO_ANT_B",3911		[RS_COLUMN_SISO_ANT_A_SGI] = "SISO_ANT_A_SGI",3912		[RS_COLUMN_SISO_ANT_B_SGI] = "SISO_ANT_B_SGI",3913		[RS_COLUMN_MIMO2] = "MIMO2",3914		[RS_COLUMN_MIMO2_SGI] = "MIMO2_SGI",3915	};3916 3917	static const char * const rate_name[] = {3918		[IWL_RATE_1M_INDEX] = "1M",3919		[IWL_RATE_2M_INDEX] = "2M",3920		[IWL_RATE_5M_INDEX] = "5.5M",3921		[IWL_RATE_11M_INDEX] = "11M",3922		[IWL_RATE_6M_INDEX] = "6M|MCS0",3923		[IWL_RATE_9M_INDEX] = "9M",3924		[IWL_RATE_12M_INDEX] = "12M|MCS1",3925		[IWL_RATE_18M_INDEX] = "18M|MCS2",3926		[IWL_RATE_24M_INDEX] = "24M|MCS3",3927		[IWL_RATE_36M_INDEX] = "36M|MCS4",3928		[IWL_RATE_48M_INDEX] = "48M|MCS5",3929		[IWL_RATE_54M_INDEX] = "54M|MCS6",3930		[IWL_RATE_MCS_7_INDEX] = "MCS7",3931		[IWL_RATE_MCS_8_INDEX] = "MCS8",3932		[IWL_RATE_MCS_9_INDEX] = "MCS9",3933		[IWL_RATE_MCS_10_INDEX] = "MCS10",3934		[IWL_RATE_MCS_11_INDEX] = "MCS11",3935	};3936 3937	char *buff, *pos, *endpos;3938	int col, rate;3939	ssize_t ret;3940	struct iwl_lq_sta *lq_sta = file->private_data;3941	struct rs_rate_stats *stats;3942	static const size_t bufsz = 1024;3943 3944	buff = kmalloc(bufsz, GFP_KERNEL);3945	if (!buff)3946		return -ENOMEM;3947 3948	pos = buff;3949	endpos = pos + bufsz;3950 3951	pos += scnprintf(pos, endpos - pos, "COLUMN,");3952	for (rate = 0; rate < IWL_RATE_COUNT; rate++)3953		pos += scnprintf(pos, endpos - pos, "%s,", rate_name[rate]);3954	pos += scnprintf(pos, endpos - pos, "\n");3955 3956	for (col = 0; col < RS_COLUMN_COUNT; col++) {3957		pos += scnprintf(pos, endpos - pos,3958				 "%s,", column_name[col]);3959 3960		for (rate = 0; rate < IWL_RATE_COUNT; rate++) {3961			stats = &(lq_sta->pers.tx_stats[col][rate]);3962			pos += scnprintf(pos, endpos - pos,3963					 "%llu/%llu,",3964					 stats->success,3965					 stats->total);3966		}3967		pos += scnprintf(pos, endpos - pos, "\n");3968	}3969 3970	ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);3971	kfree(buff);3972	return ret;3973}3974 3975static ssize_t rs_sta_dbgfs_drv_tx_stats_write(struct file *file,3976					       const char __user *user_buf,3977					       size_t count, loff_t *ppos)3978{3979	struct iwl_lq_sta *lq_sta = file->private_data;3980	memset(lq_sta->pers.tx_stats, 0, sizeof(lq_sta->pers.tx_stats));3981 3982	return count;3983}3984 3985static const struct file_operations rs_sta_dbgfs_drv_tx_stats_ops = {3986	.read = rs_sta_dbgfs_drv_tx_stats_read,3987	.write = rs_sta_dbgfs_drv_tx_stats_write,3988	.open = simple_open,3989	.llseek = default_llseek,3990};3991 3992static ssize_t iwl_dbgfs_ss_force_read(struct file *file,3993				       char __user *user_buf,3994				       size_t count, loff_t *ppos)3995{3996	struct iwl_lq_sta *lq_sta = file->private_data;3997	char buf[12];3998	int bufsz = sizeof(buf);3999	int pos = 0;4000	static const char * const ss_force_name[] = {4001		[RS_SS_FORCE_NONE] = "none",4002		[RS_SS_FORCE_STBC] = "stbc",4003		[RS_SS_FORCE_BFER] = "bfer",4004		[RS_SS_FORCE_SISO] = "siso",4005	};4006 4007	pos += scnprintf(buf+pos, bufsz-pos, "%s\n",4008			 ss_force_name[lq_sta->pers.ss_force]);4009	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);4010}4011 4012static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf,4013					size_t count, loff_t *ppos)4014{4015	struct iwl_mvm *mvm = lq_sta->pers.drv;4016	int ret = 0;4017 4018	if (!strncmp("none", buf, 4)) {4019		lq_sta->pers.ss_force = RS_SS_FORCE_NONE;4020	} else if (!strncmp("siso", buf, 4)) {4021		lq_sta->pers.ss_force = RS_SS_FORCE_SISO;4022	} else if (!strncmp("stbc", buf, 4)) {4023		if (lq_sta->stbc_capable) {4024			lq_sta->pers.ss_force = RS_SS_FORCE_STBC;4025		} else {4026			IWL_ERR(mvm,4027				"can't force STBC. peer doesn't support\n");4028			ret = -EINVAL;4029		}4030	} else if (!strncmp("bfer", buf, 4)) {4031		if (lq_sta->bfer_capable) {4032			lq_sta->pers.ss_force = RS_SS_FORCE_BFER;4033		} else {4034			IWL_ERR(mvm,4035				"can't force BFER. peer doesn't support\n");4036			ret = -EINVAL;4037		}4038	} else {4039		IWL_ERR(mvm, "valid values none|siso|stbc|bfer\n");4040		ret = -EINVAL;4041	}4042	return ret ?: count;4043}4044 4045#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \4046	_MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_lq_sta)4047#define MVM_DEBUGFS_ADD_FILE_RS(name, parent, mode) do {		\4048		debugfs_create_file(#name, mode, parent, lq_sta,	\4049				    &iwl_dbgfs_##name##_ops);		\4050	} while (0)4051 4052MVM_DEBUGFS_READ_WRITE_FILE_OPS(ss_force, 32);4053 4054static void rs_drv_add_sta_debugfs(void *mvm, void *priv_sta,4055				   struct dentry *dir)4056{4057	struct iwl_lq_sta *lq_sta = priv_sta;4058	struct iwl_mvm_sta *mvmsta;4059 4060	mvmsta = container_of(lq_sta, struct iwl_mvm_sta,4061			      deflink.lq_sta.rs_drv);4062 4063	if (!mvmsta->vif)4064		return;4065 4066	debugfs_create_file("rate_scale_table", 0600, dir,4067			    lq_sta, &rs_sta_dbgfs_scale_table_ops);4068	debugfs_create_file("rate_stats_table", 0400, dir,4069			    lq_sta, &rs_sta_dbgfs_stats_table_ops);4070	debugfs_create_file("drv_tx_stats", 0600, dir,4071			    lq_sta, &rs_sta_dbgfs_drv_tx_stats_ops);4072	debugfs_create_u8("tx_agg_tid_enable", 0600, dir,4073			  &lq_sta->tx_agg_tid_en);4074	debugfs_create_u8("reduced_tpc", 0600, dir,4075			  &lq_sta->pers.dbg_fixed_txp_reduction);4076 4077	MVM_DEBUGFS_ADD_FILE_RS(ss_force, dir, 0600);4078}4079#endif4080 4081/*4082 * Initialization of rate scaling information is done by driver after4083 * the station is added. Since mac80211 calls this function before a4084 * station is added we ignore it.4085 */4086static void rs_rate_init_ops(void *mvm_r,4087			     struct ieee80211_supported_band *sband,4088			     struct cfg80211_chan_def *chandef,4089			     struct ieee80211_sta *sta, void *mvm_sta)4090{4091}4092 4093/* ops for rate scaling implemented in the driver */4094static const struct rate_control_ops rs_mvm_ops_drv = {4095	.name = RS_NAME,4096	.tx_status = rs_drv_mac80211_tx_status,4097	.get_rate = rs_drv_get_rate,4098	.rate_init = rs_rate_init_ops,4099	.alloc = rs_alloc,4100	.free = rs_free,4101	.alloc_sta = rs_drv_alloc_sta,4102	.free_sta = rs_free_sta,4103	.rate_update = rs_drv_rate_update,4104#ifdef CONFIG_MAC80211_DEBUGFS4105	.add_sta_debugfs = rs_drv_add_sta_debugfs,4106#endif4107	.capa = RATE_CTRL_CAPA_VHT_EXT_NSS_BW,4108};4109 4110void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm,4111			  struct ieee80211_vif *vif,4112			  struct ieee80211_sta *sta,4113			  struct ieee80211_bss_conf *link_conf,4114			  struct ieee80211_link_sta *link_sta,4115			  enum nl80211_band band)4116{4117	if (iwl_mvm_has_tlc_offload(mvm)) {4118		iwl_mvm_rs_fw_rate_init(mvm, vif, sta, link_conf,4119					link_sta, band);4120	} else {4121		struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);4122 4123		spin_lock_bh(&mvmsta->deflink.lq_sta.rs_drv.pers.lock);4124		rs_drv_rate_init(mvm, sta, band);4125		spin_unlock_bh(&mvmsta->deflink.lq_sta.rs_drv.pers.lock);4126	}4127}4128 4129int iwl_mvm_rate_control_register(void)4130{4131	return ieee80211_rate_control_register(&rs_mvm_ops_drv);4132}4133 4134void iwl_mvm_rate_control_unregister(void)4135{4136	ieee80211_rate_control_unregister(&rs_mvm_ops_drv);4137}4138 4139static int rs_drv_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,4140				bool enable)4141{4142	struct iwl_lq_cmd *lq = &mvmsta->deflink.lq_sta.rs_drv.lq;4143 4144	lockdep_assert_held(&mvm->mutex);4145 4146	if (enable) {4147		if (mvmsta->tx_protection == 0)4148			lq->flags |= LQ_FLAG_USE_RTS_MSK;4149		mvmsta->tx_protection++;4150	} else {4151		mvmsta->tx_protection--;4152		if (mvmsta->tx_protection == 0)4153			lq->flags &= ~LQ_FLAG_USE_RTS_MSK;4154	}4155 4156	return iwl_mvm_send_lq_cmd(mvm, lq);4157}4158 4159/**4160 * iwl_mvm_tx_protection - ask FW to enable RTS/CTS protection4161 * @mvm: The mvm component4162 * @mvmsta: The station4163 * @enable: Enable Tx protection?4164 *4165 * Returns: an error code4166 */4167int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,4168			  bool enable)4169{4170	if (iwl_mvm_has_tlc_offload(mvm))4171		return rs_fw_tx_protection(mvm, mvmsta, enable);4172	else4173		return rs_drv_tx_protection(mvm, mvmsta, enable);4174}4175