xref: /linux/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c (revision 8be4d31cb8aaeea27bde4b7ddb26e28a89062ebf)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2010  Realtek Corporation.*/
3 
4 #include "../wifi.h"
5 #include "../base.h"
6 #include "../pci.h"
7 #include "../core.h"
8 #include "reg.h"
9 #include "def.h"
10 #include "phy.h"
11 #include "dm.h"
12 #include "fw.h"
13 #include "trx.h"
14 #include "../btcoexist/rtl_btc.h"
15 
16 static const u32 txscaling_tbl[TXSCALE_TABLE_SIZE] = {
17 	0x081, /* 0, -12.0dB */
18 	0x088, /* 1, -11.5dB */
19 	0x090, /* 2, -11.0dB */
20 	0x099, /* 3, -10.5dB */
21 	0x0A2, /* 4, -10.0dB */
22 	0x0AC, /* 5, -9.5dB */
23 	0x0B6, /* 6, -9.0dB */
24 	0x0C0, /* 7, -8.5dB */
25 	0x0CC, /* 8, -8.0dB */
26 	0x0D8, /* 9, -7.5dB */
27 	0x0E5, /* 10, -7.0dB */
28 	0x0F2, /* 11, -6.5dB */
29 	0x101, /* 12, -6.0dB */
30 	0x110, /* 13, -5.5dB */
31 	0x120, /* 14, -5.0dB */
32 	0x131, /* 15, -4.5dB */
33 	0x143, /* 16, -4.0dB */
34 	0x156, /* 17, -3.5dB */
35 	0x16A, /* 18, -3.0dB */
36 	0x180, /* 19, -2.5dB */
37 	0x197, /* 20, -2.0dB */
38 	0x1AF, /* 21, -1.5dB */
39 	0x1C8, /* 22, -1.0dB */
40 	0x1E3, /* 23, -0.5dB */
41 	0x200, /* 24, +0  dB */
42 	0x21E, /* 25, +0.5dB */
43 	0x23E, /* 26, +1.0dB */
44 	0x261, /* 27, +1.5dB */
45 	0x285, /* 28, +2.0dB */
46 	0x2AB, /* 29, +2.5dB */
47 	0x2D3, /* 30, +3.0dB */
48 	0x2FE, /* 31, +3.5dB */
49 	0x32B, /* 32, +4.0dB */
50 	0x35C, /* 33, +4.5dB */
51 	0x38E, /* 34, +5.0dB */
52 	0x3C4, /* 35, +5.5dB */
53 	0x3FE  /* 36, +6.0dB */
54 };
55 
56 static const u32 rtl8821ae_txscaling_table[TXSCALE_TABLE_SIZE] = {
57 	0x081, /* 0, -12.0dB */
58 	0x088, /* 1, -11.5dB */
59 	0x090, /* 2, -11.0dB */
60 	0x099, /* 3, -10.5dB */
61 	0x0A2, /* 4, -10.0dB */
62 	0x0AC, /* 5, -9.5dB */
63 	0x0B6, /* 6, -9.0dB */
64 	0x0C0, /* 7, -8.5dB */
65 	0x0CC, /* 8, -8.0dB */
66 	0x0D8, /* 9, -7.5dB */
67 	0x0E5, /* 10, -7.0dB */
68 	0x0F2, /* 11, -6.5dB */
69 	0x101, /* 12, -6.0dB */
70 	0x110, /* 13, -5.5dB */
71 	0x120, /* 14, -5.0dB */
72 	0x131, /* 15, -4.5dB */
73 	0x143, /* 16, -4.0dB */
74 	0x156, /* 17, -3.5dB */
75 	0x16A, /* 18, -3.0dB */
76 	0x180, /* 19, -2.5dB */
77 	0x197, /* 20, -2.0dB */
78 	0x1AF, /* 21, -1.5dB */
79 	0x1C8, /* 22, -1.0dB */
80 	0x1E3, /* 23, -0.5dB */
81 	0x200, /* 24, +0  dB */
82 	0x21E, /* 25, +0.5dB */
83 	0x23E, /* 26, +1.0dB */
84 	0x261, /* 27, +1.5dB */
85 	0x285, /* 28, +2.0dB */
86 	0x2AB, /* 29, +2.5dB */
87 	0x2D3, /* 30, +3.0dB */
88 	0x2FE, /* 31, +3.5dB */
89 	0x32B, /* 32, +4.0dB */
90 	0x35C, /* 33, +4.5dB */
91 	0x38E, /* 34, +5.0dB */
92 	0x3C4, /* 35, +5.5dB */
93 	0x3FE  /* 36, +6.0dB */
94 };
95 
96 static const u32 edca_setting_dl[PEER_MAX] = {
97 	0xa44f,		/* 0 UNKNOWN */
98 	0x5ea44f,	/* 1 REALTEK_90 */
99 	0x5e4322,	/* 2 REALTEK_92SE */
100 	0x5ea42b,		/* 3 BROAD	*/
101 	0xa44f,		/* 4 RAL */
102 	0xa630,		/* 5 ATH */
103 	0x5ea630,		/* 6 CISCO */
104 	0x5ea42b,		/* 7 MARVELL */
105 };
106 
107 static const u32 edca_setting_ul[PEER_MAX] = {
108 	0x5e4322,	/* 0 UNKNOWN */
109 	0xa44f,		/* 1 REALTEK_90 */
110 	0x5ea44f,	/* 2 REALTEK_92SE */
111 	0x5ea32b,	/* 3 BROAD */
112 	0x5ea422,	/* 4 RAL */
113 	0x5ea322,	/* 5 ATH */
114 	0x3ea430,	/* 6 CISCO */
115 	0x5ea44f,	/* 7 MARV */
116 };
117 
118 static const u8 rtl8818e_delta_swing_table_idx_24gb_p[] = {
119 	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4,
120 	4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
121 
122 static const u8 rtl8818e_delta_swing_table_idx_24gb_n[] = {
123 	0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
124 	7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
125 
126 static const u8 rtl8812ae_delta_swing_table_idx_24gb_n[]  = {
127 	0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
128 	6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
129 
130 static const u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = {
131 	0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
132 	6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
133 
134 static const u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = {
135 	0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
136 	6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
137 
138 static const u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = {
139 	0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
140 	6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
141 
142 static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = {
143 	0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
144 	6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
145 
146 static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = {
147 	0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
148 	6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
149 
150 static const u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = {
151 	0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
152 	6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
153 
154 static const u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = {
155 	0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
156 	6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
157 
158 static const u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = {
159 	{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7,
160 	7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13},
161 	{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
162 	7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13},
163 	{0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11,
164 	12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18},
165 };
166 
167 static const u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = {
168 	{0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8,
169 	8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
170 	{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
171 	8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
172 	{0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9,
173 	9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
174 };
175 
176 static const u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
177 	{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
178 	8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13},
179 	{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9,
180 	9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13},
181 	{0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11,
182 	12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18},
183 };
184 
185 static const u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
186 	{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8,
187 	8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
188 	{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
189 	9, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
190 	{0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9,
191 	10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
192 };
193 
194 static const u8 rtl8821ae_delta_swing_table_idx_24ga_n[]  = {
195 	0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
196 	6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
197 
198 static const u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = {
199 	0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
200 	8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
201 
202 static const u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = {
203 	0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
204 	6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
205 
206 static const u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = {
207 	0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
208 	8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
209 
210 static const u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
211 	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
212 	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
213 	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
214 	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
215 	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
216 	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
217 };
218 
219 static const u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
220 	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
221 	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
222 	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
223 	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
224 	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
225 	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
226 };
227 
rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw * hw,u8 type,u8 * pdirection,u32 * poutwrite_val)228 void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw,
229 				       u8 type, u8 *pdirection,
230 				       u32 *poutwrite_val)
231 {
232 	struct rtl_priv *rtlpriv = rtl_priv(hw);
233 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
234 	u8 pwr_val = 0;
235 
236 	if (type == 0) {
237 		if (rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] <=
238 			rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A]) {
239 			*pdirection = 1;
240 			pwr_val = rtldm->swing_idx_ofdm_base[RF90_PATH_A] -
241 					rtldm->swing_idx_ofdm[RF90_PATH_A];
242 		} else {
243 			*pdirection = 2;
244 			pwr_val = rtldm->swing_idx_ofdm[RF90_PATH_A] -
245 				rtldm->swing_idx_ofdm_base[RF90_PATH_A];
246 		}
247 	} else if (type == 1) {
248 		if (rtldm->swing_idx_cck <= rtldm->swing_idx_cck_base) {
249 			*pdirection = 1;
250 			pwr_val = rtldm->swing_idx_cck_base -
251 					rtldm->swing_idx_cck;
252 		} else {
253 			*pdirection = 2;
254 			pwr_val = rtldm->swing_idx_cck -
255 				rtldm->swing_idx_cck_base;
256 		}
257 	}
258 
259 	if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
260 		pwr_val = TXPWRTRACK_MAX_IDX;
261 
262 	*poutwrite_val = pwr_val | (pwr_val << 8)|
263 				(pwr_val << 16)|
264 				(pwr_val << 24);
265 }
266 
rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw * hw)267 void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw)
268 {
269 	struct rtl_priv *rtlpriv = rtl_priv(hw);
270 	struct rtl_dm *rtldm = rtl_dm(rtlpriv);
271 	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
272 	u8 p = 0;
273 
274 	rtldm->swing_idx_cck_base = rtldm->default_cck_index;
275 	rtldm->swing_idx_cck = rtldm->default_cck_index;
276 	rtldm->cck_index = 0;
277 
278 	for (p = RF90_PATH_A; p <= RF90_PATH_B; ++p) {
279 		rtldm->swing_idx_ofdm_base[p] = rtldm->default_ofdm_index;
280 		rtldm->swing_idx_ofdm[p] = rtldm->default_ofdm_index;
281 		rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
282 
283 		rtldm->power_index_offset[p] = 0;
284 		rtldm->delta_power_index[p] = 0;
285 		rtldm->delta_power_index_last[p] = 0;
286 		/*Initial Mix mode power tracking*/
287 		rtldm->absolute_ofdm_swing_idx[p] = 0;
288 		rtldm->remnant_ofdm_swing_idx[p] = 0;
289 	}
290 	/*Initial at Modify Tx Scaling Mode*/
291 	rtldm->modify_txagc_flag_path_a = false;
292 	/*Initial at Modify Tx Scaling Mode*/
293 	rtldm->modify_txagc_flag_path_b = false;
294 	rtldm->remnant_cck_idx = 0;
295 	rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
296 	rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
297 	rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
298 }
299 
rtl8821ae_dm_get_swing_index(struct ieee80211_hw * hw)300 static u8  rtl8821ae_dm_get_swing_index(struct ieee80211_hw *hw)
301 {
302 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
303 	u8 i = 0;
304 	u32  bb_swing;
305 
306 	bb_swing = phy_get_tx_swing_8812A(hw, rtlhal->current_bandtype,
307 					  RF90_PATH_A);
308 
309 	for (i = 0; i < TXSCALE_TABLE_SIZE; ++i)
310 		if (bb_swing == rtl8821ae_txscaling_table[i])
311 			break;
312 
313 	return i;
314 }
315 
rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(struct ieee80211_hw * hw)316 void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(
317 				struct ieee80211_hw *hw)
318 {
319 	struct rtl_priv *rtlpriv = rtl_priv(hw);
320 	struct rtl_dm *rtldm = rtl_dm(rtlpriv);
321 	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
322 	u8 default_swing_index  = 0;
323 	u8 p = 0;
324 
325 	rtlpriv->dm.txpower_track_control = true;
326 	rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
327 	rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
328 	rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
329 	default_swing_index = rtl8821ae_dm_get_swing_index(hw);
330 
331 	rtldm->default_ofdm_index =
332 		(default_swing_index == TXSCALE_TABLE_SIZE) ?
333 		24 : default_swing_index;
334 	rtldm->default_cck_index = 24;
335 
336 	rtldm->swing_idx_cck_base = rtldm->default_cck_index;
337 	rtldm->cck_index = rtldm->default_cck_index;
338 
339 	for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) {
340 		rtldm->swing_idx_ofdm_base[p] =
341 			rtldm->default_ofdm_index;
342 		rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
343 		rtldm->delta_power_index[p] = 0;
344 		rtldm->power_index_offset[p] = 0;
345 		rtldm->delta_power_index_last[p] = 0;
346 	}
347 }
348 
rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw * hw)349 void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw)
350 {
351 	struct rtl_priv *rtlpriv = rtl_priv(hw);
352 
353 	rtlpriv->dm.current_turbo_edca = false;
354 	rtlpriv->dm.is_any_nonbepkts = false;
355 	rtlpriv->dm.is_cur_rdlstate = false;
356 }
357 
rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw * hw)358 void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
359 {
360 	struct rtl_priv *rtlpriv = rtl_priv(hw);
361 	struct rate_adaptive *p_ra = &rtlpriv->ra;
362 
363 	p_ra->ratr_state = DM_RATR_STA_INIT;
364 	p_ra->pre_ratr_state = DM_RATR_STA_INIT;
365 
366 	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
367 	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
368 		rtlpriv->dm.useramask = true;
369 	else
370 		rtlpriv->dm.useramask = false;
371 
372 	p_ra->high_rssi_thresh_for_ra = 50;
373 	p_ra->low_rssi_thresh_for_ra40m = 20;
374 }
375 
rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw * hw)376 static void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
377 {
378 	struct rtl_priv *rtlpriv = rtl_priv(hw);
379 
380 	rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
381 
382 	rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
383 	rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
384 }
385 
rtl8821ae_dm_common_info_self_init(struct ieee80211_hw * hw)386 static void rtl8821ae_dm_common_info_self_init(struct ieee80211_hw *hw)
387 {
388 	struct rtl_priv *rtlpriv = rtl_priv(hw);
389 	struct rtl_phy *rtlphy = &rtlpriv->phy;
390 	u8 tmp;
391 
392 	rtlphy->cck_high_power =
393 		(bool)rtl_get_bbreg(hw, ODM_REG_CCK_RPT_FORMAT_11AC,
394 				    ODM_BIT_CCK_RPT_FORMAT_11AC);
395 
396 	tmp = (u8)rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC,
397 				ODM_BIT_BB_RX_PATH_11AC);
398 	if (tmp & BIT(0))
399 		rtlpriv->dm.rfpath_rxenable[0] = true;
400 	if (tmp & BIT(1))
401 		rtlpriv->dm.rfpath_rxenable[1] = true;
402 }
403 
rtl8821ae_dm_init(struct ieee80211_hw * hw)404 void rtl8821ae_dm_init(struct ieee80211_hw *hw)
405 {
406 	struct rtl_priv *rtlpriv = rtl_priv(hw);
407 	struct rtl_phy *rtlphy = &rtlpriv->phy;
408 	u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
409 
410 	spin_lock(&rtlpriv->locks.iqk_lock);
411 	rtlphy->lck_inprogress = false;
412 	spin_unlock(&rtlpriv->locks.iqk_lock);
413 
414 	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
415 	rtl8821ae_dm_common_info_self_init(hw);
416 	rtl_dm_diginit(hw, cur_igvalue);
417 	rtl8821ae_dm_init_rate_adaptive_mask(hw);
418 	rtl8821ae_dm_init_edca_turbo(hw);
419 	rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw);
420 	rtl8821ae_dm_init_dynamic_atc_switch(hw);
421 }
422 
rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw * hw)423 static void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw *hw)
424 {
425 	struct rtl_priv *rtlpriv = rtl_priv(hw);
426 	struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
427 	struct rtl_mac *mac = rtl_mac(rtlpriv);
428 
429 	/* Determine the minimum RSSI  */
430 	if ((mac->link_state < MAC80211_LINKED) &&
431 	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
432 		rtl_dm_dig->min_undec_pwdb_for_dm = 0;
433 		pr_debug("rtl8821ae: Not connected to any AP\n");
434 	}
435 	if (mac->link_state >= MAC80211_LINKED) {
436 		if (mac->opmode == NL80211_IFTYPE_AP ||
437 		    mac->opmode == NL80211_IFTYPE_ADHOC) {
438 			rtl_dm_dig->min_undec_pwdb_for_dm =
439 			    rtlpriv->dm.entry_min_undec_sm_pwdb;
440 			rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
441 				"AP Client PWDB = 0x%lx\n",
442 				rtlpriv->dm.entry_min_undec_sm_pwdb);
443 		} else {
444 			rtl_dm_dig->min_undec_pwdb_for_dm =
445 			    rtlpriv->dm.undec_sm_pwdb;
446 			rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
447 				"STA Default Port PWDB = 0x%x\n",
448 				rtl_dm_dig->min_undec_pwdb_for_dm);
449 		}
450 	} else {
451 		rtl_dm_dig->min_undec_pwdb_for_dm =
452 		    rtlpriv->dm.entry_min_undec_sm_pwdb;
453 		rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
454 			"AP Ext Port or disconnect PWDB = 0x%x\n",
455 			rtl_dm_dig->min_undec_pwdb_for_dm);
456 	}
457 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
458 		"MinUndecoratedPWDBForDM =%d\n",
459 		rtl_dm_dig->min_undec_pwdb_for_dm);
460 }
461 
rtl8812ae_dm_rssi_dump_to_register(struct ieee80211_hw * hw)462 static void  rtl8812ae_dm_rssi_dump_to_register(struct ieee80211_hw *hw)
463 {
464 	struct rtl_priv *rtlpriv = rtl_priv(hw);
465 
466 	rtl_write_byte(rtlpriv, RA_RSSI_DUMP,
467 		       rtlpriv->stats.rx_rssi_percentage[0]);
468 	rtl_write_byte(rtlpriv, RB_RSSI_DUMP,
469 		       rtlpriv->stats.rx_rssi_percentage[1]);
470 
471 	/* Rx EVM*/
472 	rtl_write_byte(rtlpriv, RS1_RX_EVM_DUMP,
473 		       rtlpriv->stats.rx_evm_dbm[0]);
474 	rtl_write_byte(rtlpriv, RS2_RX_EVM_DUMP,
475 		       rtlpriv->stats.rx_evm_dbm[1]);
476 
477 	/*Rx SNR*/
478 	rtl_write_byte(rtlpriv, RA_RX_SNR_DUMP,
479 		       (u8)(rtlpriv->stats.rx_snr_db[0]));
480 	rtl_write_byte(rtlpriv, RB_RX_SNR_DUMP,
481 		       (u8)(rtlpriv->stats.rx_snr_db[1]));
482 
483 	/*Rx Cfo_Short*/
484 	rtl_write_word(rtlpriv, RA_CFO_SHORT_DUMP,
485 		       rtlpriv->stats.rx_cfo_short[0]);
486 	rtl_write_word(rtlpriv, RB_CFO_SHORT_DUMP,
487 		       rtlpriv->stats.rx_cfo_short[1]);
488 
489 	/*Rx Cfo_Tail*/
490 	rtl_write_word(rtlpriv, RA_CFO_LONG_DUMP,
491 		       rtlpriv->stats.rx_cfo_tail[0]);
492 	rtl_write_word(rtlpriv, RB_CFO_LONG_DUMP,
493 		       rtlpriv->stats.rx_cfo_tail[1]);
494 }
495 
rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw * hw)496 static void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw *hw)
497 {
498 	struct rtl_priv *rtlpriv = rtl_priv(hw);
499 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
500 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
501 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
502 	struct rtl_sta_info *drv_priv;
503 	u8 h2c_parameter[4] = { 0 };
504 	long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
505 	u8 stbc_tx = 0;
506 	u64 cur_rxokcnt = 0;
507 	static u64 last_txokcnt = 0, last_rxokcnt;
508 
509 	cur_rxokcnt = rtlpriv->stats.rxbytesunicast - last_rxokcnt;
510 	last_txokcnt = rtlpriv->stats.txbytesunicast;
511 	last_rxokcnt = rtlpriv->stats.rxbytesunicast;
512 	if (cur_rxokcnt > (last_txokcnt * 6))
513 		h2c_parameter[3] = 0x01;
514 	else
515 		h2c_parameter[3] = 0x00;
516 
517 	/* AP & ADHOC & MESH */
518 	if (mac->opmode == NL80211_IFTYPE_AP ||
519 	    mac->opmode == NL80211_IFTYPE_ADHOC ||
520 	    mac->opmode == NL80211_IFTYPE_MESH_POINT) {
521 		spin_lock_bh(&rtlpriv->locks.entry_list_lock);
522 		list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
523 			if (drv_priv->rssi_stat.undec_sm_pwdb <
524 					tmp_entry_min_pwdb)
525 				tmp_entry_min_pwdb =
526 					drv_priv->rssi_stat.undec_sm_pwdb;
527 			if (drv_priv->rssi_stat.undec_sm_pwdb >
528 					tmp_entry_max_pwdb)
529 				tmp_entry_max_pwdb =
530 					drv_priv->rssi_stat.undec_sm_pwdb;
531 		}
532 		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
533 
534 		/* If associated entry is found */
535 		if (tmp_entry_max_pwdb != 0) {
536 			rtlpriv->dm.entry_max_undec_sm_pwdb =
537 				tmp_entry_max_pwdb;
538 			RTPRINT(rtlpriv, FDM, DM_PWDB,
539 				"EntryMaxPWDB = 0x%lx(%ld)\n",
540 				tmp_entry_max_pwdb, tmp_entry_max_pwdb);
541 		} else {
542 			rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
543 		}
544 		/* If associated entry is found */
545 		if (tmp_entry_min_pwdb != 0xff) {
546 			rtlpriv->dm.entry_min_undec_sm_pwdb =
547 				tmp_entry_min_pwdb;
548 			RTPRINT(rtlpriv, FDM, DM_PWDB,
549 				"EntryMinPWDB = 0x%lx(%ld)\n",
550 				tmp_entry_min_pwdb, tmp_entry_min_pwdb);
551 		} else {
552 			rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
553 		}
554 	}
555 	/* Indicate Rx signal strength to FW. */
556 	if (rtlpriv->dm.useramask) {
557 		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
558 			if (mac->mode == WIRELESS_MODE_AC_24G ||
559 			    mac->mode == WIRELESS_MODE_AC_5G ||
560 			    mac->mode == WIRELESS_MODE_AC_ONLY)
561 				stbc_tx = (mac->vht_cur_stbc &
562 					   STBC_VHT_ENABLE_TX) ? 1 : 0;
563 			else
564 				stbc_tx = (mac->ht_cur_stbc &
565 					   STBC_HT_ENABLE_TX) ? 1 : 0;
566 			h2c_parameter[3] |= stbc_tx << 1;
567 		}
568 		h2c_parameter[2] =
569 			(u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF);
570 		h2c_parameter[1] = 0x20;
571 		h2c_parameter[0] = 0;
572 		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
573 			rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 4,
574 					       h2c_parameter);
575 		else
576 			rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 3,
577 					       h2c_parameter);
578 	} else {
579 		rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
580 	}
581 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
582 		rtl8812ae_dm_rssi_dump_to_register(hw);
583 	rtl8821ae_dm_find_minimum_rssi(hw);
584 	dm_digtable->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
585 }
586 
rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw * hw,u8 current_cca)587 void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca)
588 {
589 	struct rtl_priv *rtlpriv = rtl_priv(hw);
590 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
591 
592 	if (dm_digtable->cur_cck_cca_thres != current_cca)
593 		rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11AC, current_cca);
594 
595 	dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
596 	dm_digtable->cur_cck_cca_thres = current_cca;
597 }
598 
rtl8821ae_dm_write_dig(struct ieee80211_hw * hw,u8 current_igi)599 void rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
600 {
601 	struct rtl_priv *rtlpriv = rtl_priv(hw);
602 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
603 
604 	if (dm_digtable->stop_dig)
605 		return;
606 
607 	if (dm_digtable->cur_igvalue != current_igi) {
608 		rtl_set_bbreg(hw, DM_REG_IGI_A_11AC,
609 			      DM_BIT_IGI_11AC, current_igi);
610 		if (rtlpriv->phy.rf_type != RF_1T1R)
611 			rtl_set_bbreg(hw, DM_REG_IGI_B_11AC,
612 				      DM_BIT_IGI_11AC, current_igi);
613 	}
614 	dm_digtable->cur_igvalue = current_igi;
615 }
616 
rtl8821ae_dm_dig(struct ieee80211_hw * hw)617 static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
618 {
619 	struct rtl_priv *rtlpriv = rtl_priv(hw);
620 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
621 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
622 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
623 	u8 dig_min_0;
624 	u8 dig_max_of_min;
625 	bool first_connect, first_disconnect;
626 	u8 dm_dig_max, dm_dig_min, offset;
627 	u8 current_igi = dm_digtable->cur_igvalue;
628 
629 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "\n");
630 
631 	if (mac->act_scanning) {
632 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
633 			"Return: In Scan Progress\n");
634 		return;
635 	}
636 
637 	/*add by Neil Chen to avoid PSD is processing*/
638 	dig_min_0 = dm_digtable->dig_min_0;
639 	first_connect = (mac->link_state >= MAC80211_LINKED) &&
640 			(!dm_digtable->media_connect_0);
641 	first_disconnect = (mac->link_state < MAC80211_LINKED) &&
642 			(dm_digtable->media_connect_0);
643 
644 	/*1 Boundary Decision*/
645 
646 	dm_dig_max = 0x5A;
647 
648 	if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
649 		dm_dig_min = DM_DIG_MIN;
650 	else
651 		dm_dig_min = 0x1C;
652 
653 	dig_max_of_min = DM_DIG_MAX_AP;
654 
655 	if (mac->link_state >= MAC80211_LINKED) {
656 		if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
657 			offset = 20;
658 		else
659 			offset = 10;
660 
661 		if ((dm_digtable->rssi_val_min + offset) > dm_dig_max)
662 			dm_digtable->rx_gain_max = dm_dig_max;
663 		else if ((dm_digtable->rssi_val_min + offset) < dm_dig_min)
664 			dm_digtable->rx_gain_max = dm_dig_min;
665 		else
666 			dm_digtable->rx_gain_max =
667 				dm_digtable->rssi_val_min + offset;
668 
669 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
670 			"dm_digtable->rssi_val_min=0x%x,dm_digtable->rx_gain_max = 0x%x\n",
671 			dm_digtable->rssi_val_min,
672 			dm_digtable->rx_gain_max);
673 		if (rtlpriv->dm.one_entry_only) {
674 			offset = 0;
675 
676 			if (dm_digtable->rssi_val_min - offset < dm_dig_min)
677 				dig_min_0 = dm_dig_min;
678 			else if (dm_digtable->rssi_val_min -
679 				offset > dig_max_of_min)
680 				dig_min_0 = dig_max_of_min;
681 			else
682 				dig_min_0 =
683 					dm_digtable->rssi_val_min - offset;
684 
685 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
686 				"bOneEntryOnly=TRUE, dig_min_0=0x%x\n",
687 				dig_min_0);
688 		} else {
689 			dig_min_0 = dm_dig_min;
690 		}
691 	} else {
692 		dm_digtable->rx_gain_max = dm_dig_max;
693 		dig_min_0 = dm_dig_min;
694 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n");
695 	}
696 
697 	if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
698 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
699 			"Abnormally false alarm case.\n");
700 
701 		if (dm_digtable->large_fa_hit != 3)
702 			dm_digtable->large_fa_hit++;
703 		if (dm_digtable->forbidden_igi < current_igi) {
704 			dm_digtable->forbidden_igi = current_igi;
705 			dm_digtable->large_fa_hit = 1;
706 		}
707 
708 		if (dm_digtable->large_fa_hit >= 3) {
709 			if ((dm_digtable->forbidden_igi + 1) >
710 				dm_digtable->rx_gain_max)
711 				dm_digtable->rx_gain_min =
712 					dm_digtable->rx_gain_max;
713 			else
714 				dm_digtable->rx_gain_min =
715 					(dm_digtable->forbidden_igi + 1);
716 			dm_digtable->recover_cnt = 3600;
717 		}
718 	} else {
719 		/*Recovery mechanism for IGI lower bound*/
720 		if (dm_digtable->recover_cnt != 0) {
721 			dm_digtable->recover_cnt--;
722 		} else {
723 			if (dm_digtable->large_fa_hit < 3) {
724 				if ((dm_digtable->forbidden_igi - 1) <
725 				    dig_min_0) {
726 					dm_digtable->forbidden_igi =
727 						dig_min_0;
728 					dm_digtable->rx_gain_min =
729 						dig_min_0;
730 					rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
731 						"Normal Case: At Lower Bound\n");
732 				} else {
733 					dm_digtable->forbidden_igi--;
734 					dm_digtable->rx_gain_min =
735 					  (dm_digtable->forbidden_igi + 1);
736 					rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
737 						"Normal Case: Approach Lower Bound\n");
738 				}
739 			} else {
740 				dm_digtable->large_fa_hit = 0;
741 			}
742 		}
743 	}
744 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
745 		"pDM_DigTable->LargeFAHit=%d\n",
746 		dm_digtable->large_fa_hit);
747 
748 	if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10)
749 		dm_digtable->rx_gain_min = dm_dig_min;
750 
751 	if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max)
752 		dm_digtable->rx_gain_min = dm_digtable->rx_gain_max;
753 
754 	/*Adjust initial gain by false alarm*/
755 	if (mac->link_state >= MAC80211_LINKED) {
756 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
757 			"DIG AfterLink\n");
758 		if (first_connect) {
759 			current_igi = min(dm_digtable->rssi_val_min, dig_max_of_min);
760 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
761 				"First Connect\n");
762 		} else {
763 			if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
764 				current_igi = current_igi + 4;
765 			else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
766 				current_igi = current_igi + 2;
767 			else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
768 				current_igi = current_igi - 2;
769 
770 			if ((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) &&
771 			    (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) {
772 				current_igi = dm_digtable->rx_gain_min;
773 				rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
774 					"Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n");
775 			}
776 		}
777 	} else {
778 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
779 			"DIG BeforeLink\n");
780 		if (first_disconnect) {
781 			current_igi = dm_digtable->rx_gain_min;
782 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
783 				"First DisConnect\n");
784 		} else {
785 			/* 2012.03.30 LukeLee: enable DIG before
786 			 * link but with very high thresholds
787 			 */
788 			if (rtlpriv->falsealm_cnt.cnt_all > 2000)
789 				current_igi = current_igi + 4;
790 			else if (rtlpriv->falsealm_cnt.cnt_all > 600)
791 				current_igi = current_igi + 2;
792 			else if (rtlpriv->falsealm_cnt.cnt_all < 300)
793 				current_igi = current_igi - 2;
794 
795 			if (current_igi >= 0x3e)
796 				current_igi = 0x3e;
797 
798 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "England DIG\n");
799 		}
800 	}
801 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
802 		"DIG End Adjust IGI\n");
803 	/* Check initial gain by upper/lower bound*/
804 
805 	if (current_igi > dm_digtable->rx_gain_max)
806 		current_igi = dm_digtable->rx_gain_max;
807 	if (current_igi < dm_digtable->rx_gain_min)
808 		current_igi = dm_digtable->rx_gain_min;
809 
810 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
811 		"rx_gain_max=0x%x, rx_gain_min=0x%x\n",
812 		dm_digtable->rx_gain_max, dm_digtable->rx_gain_min);
813 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
814 		"TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all);
815 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
816 		"CurIGValue=0x%x\n", current_igi);
817 
818 	rtl8821ae_dm_write_dig(hw, current_igi);
819 	dm_digtable->media_connect_0 =
820 		((mac->link_state >= MAC80211_LINKED) ? true : false);
821 	dm_digtable->dig_min_0 = dig_min_0;
822 }
823 
rtl8821ae_dm_common_info_self_update(struct ieee80211_hw * hw)824 static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw)
825 {
826 	struct rtl_priv *rtlpriv = rtl_priv(hw);
827 	u8 cnt;
828 
829 	rtlpriv->dm.tx_rate = 0xff;
830 
831 	rtlpriv->dm.one_entry_only = false;
832 
833 	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
834 	    rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
835 		rtlpriv->dm.one_entry_only = true;
836 		return;
837 	}
838 
839 	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
840 	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
841 	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
842 		spin_lock_bh(&rtlpriv->locks.entry_list_lock);
843 		cnt = list_count_nodes(&rtlpriv->entry_list);
844 		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
845 
846 		if (cnt == 1)
847 			rtlpriv->dm.one_entry_only = true;
848 	}
849 }
850 
rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw * hw)851 static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
852 {
853 	struct rtl_priv *rtlpriv = rtl_priv(hw);
854 	struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
855 	u32 cck_enable = 0;
856 
857 	/*read OFDM FA counter*/
858 	falsealm_cnt->cnt_ofdm_fail =
859 		rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD);
860 	falsealm_cnt->cnt_cck_fail =
861 		rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD);
862 
863 	cck_enable =  rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28));
864 	if (cck_enable)  /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/
865 		falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
866 					falsealm_cnt->cnt_cck_fail;
867 	else
868 		falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail;
869 
870 	/*reset OFDM FA counter*/
871 	rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
872 	rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
873 	/* reset CCK FA counter*/
874 	rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
875 	rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
876 
877 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Cnt_Cck_fail=%d\n",
878 		falsealm_cnt->cnt_cck_fail);
879 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "cnt_ofdm_fail=%d\n",
880 		falsealm_cnt->cnt_ofdm_fail);
881 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Total False Alarm=%d\n",
882 		falsealm_cnt->cnt_all);
883 }
884 
rtl8812ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw * hw)885 static void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
886 		struct ieee80211_hw *hw)
887 {
888 	struct rtl_priv *rtlpriv = rtl_priv(hw);
889 
890 	if (!rtlpriv->dm.tm_trigger) {
891 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E,
892 			      BIT(17) | BIT(16), 0x03);
893 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
894 			"Trigger 8812 Thermal Meter!!\n");
895 		rtlpriv->dm.tm_trigger = 1;
896 		return;
897 	}
898 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
899 		"Schedule TxPowerTracking direct call!!\n");
900 	rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw);
901 }
902 
rtl8821ae_dm_iq_calibrate(struct ieee80211_hw * hw)903 static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw)
904 {
905 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
906 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
907 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
908 
909 	if (mac->link_state >= MAC80211_LINKED) {
910 		if (rtldm->linked_interval < 3)
911 			rtldm->linked_interval++;
912 
913 		if (rtldm->linked_interval == 2) {
914 			if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
915 				rtl8812ae_phy_iq_calibrate(hw, false);
916 			else
917 				rtl8821ae_phy_iq_calibrate(hw, false);
918 		}
919 	} else {
920 		rtldm->linked_interval = 0;
921 	}
922 }
923 
rtl8812ae_get_delta_swing_table(struct ieee80211_hw * hw,const u8 ** up_a,const u8 ** down_a,const u8 ** up_b,const u8 ** down_b)924 static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw,
925 					    const u8 **up_a,
926 					    const u8 **down_a,
927 					    const u8 **up_b,
928 					    const u8 **down_b)
929 {
930 	struct rtl_priv *rtlpriv = rtl_priv(hw);
931 	struct rtl_phy *rtlphy = &rtlpriv->phy;
932 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
933 	u8 channel = rtlphy->current_channel;
934 	u8 rate = rtldm->tx_rate;
935 
936 	if (1 <= channel && channel <= 14) {
937 		if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
938 			*up_a = rtl8812ae_delta_swing_table_idx_24gccka_p;
939 			*down_a = rtl8812ae_delta_swing_table_idx_24gccka_n;
940 			*up_b = rtl8812ae_delta_swing_table_idx_24gcckb_p;
941 			*down_b = rtl8812ae_delta_swing_table_idx_24gcckb_n;
942 		} else {
943 			*up_a = rtl8812ae_delta_swing_table_idx_24ga_p;
944 			*down_a = rtl8812ae_delta_swing_table_idx_24ga_n;
945 			*up_b = rtl8812ae_delta_swing_table_idx_24gb_p;
946 			*down_b = rtl8812ae_delta_swing_table_idx_24gb_n;
947 		}
948 	} else if (36 <= channel && channel <= 64) {
949 		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[0];
950 		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[0];
951 		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[0];
952 		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[0];
953 	} else if (100 <= channel && channel <= 140) {
954 		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[1];
955 		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[1];
956 		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[1];
957 		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[1];
958 	} else if (149 <= channel && channel <= 173) {
959 		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[2];
960 		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[2];
961 		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2];
962 		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2];
963 	} else {
964 		*up_a = rtl8818e_delta_swing_table_idx_24gb_p;
965 		*down_a = rtl8818e_delta_swing_table_idx_24gb_n;
966 		*up_b = rtl8818e_delta_swing_table_idx_24gb_p;
967 		*down_b = rtl8818e_delta_swing_table_idx_24gb_n;
968 	}
969 }
970 
rtl8821ae_dm_update_init_rate(struct ieee80211_hw * hw,u8 rate)971 void rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate)
972 {
973 	struct rtl_priv *rtlpriv = rtl_priv(hw);
974 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
975 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
976 	u8 p = 0;
977 
978 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
979 		"Get C2H Command! Rate=0x%x\n", rate);
980 
981 	rtldm->tx_rate = rate;
982 
983 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
984 		rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0);
985 	} else {
986 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
987 			rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0);
988 	}
989 }
990 
rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw * hw,u8 rate)991 u8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate)
992 {
993 	struct rtl_priv *rtlpriv = rtl_priv(hw);
994 	u8 ret_rate = MGN_1M;
995 
996 	switch (rate) {
997 	case DESC_RATE1M:
998 		ret_rate = MGN_1M;
999 		break;
1000 	case DESC_RATE2M:
1001 		ret_rate = MGN_2M;
1002 		break;
1003 	case DESC_RATE5_5M:
1004 		ret_rate = MGN_5_5M;
1005 		break;
1006 	case DESC_RATE11M:
1007 		ret_rate = MGN_11M;
1008 		break;
1009 	case DESC_RATE6M:
1010 		ret_rate = MGN_6M;
1011 		break;
1012 	case DESC_RATE9M:
1013 		ret_rate = MGN_9M;
1014 		break;
1015 	case DESC_RATE12M:
1016 		ret_rate = MGN_12M;
1017 		break;
1018 	case DESC_RATE18M:
1019 		ret_rate = MGN_18M;
1020 		break;
1021 	case DESC_RATE24M:
1022 		ret_rate = MGN_24M;
1023 		break;
1024 	case DESC_RATE36M:
1025 		ret_rate = MGN_36M;
1026 		break;
1027 	case DESC_RATE48M:
1028 		ret_rate = MGN_48M;
1029 		break;
1030 	case DESC_RATE54M:
1031 		ret_rate = MGN_54M;
1032 		break;
1033 	case DESC_RATEMCS0:
1034 		ret_rate = MGN_MCS0;
1035 		break;
1036 	case DESC_RATEMCS1:
1037 		ret_rate = MGN_MCS1;
1038 		break;
1039 	case DESC_RATEMCS2:
1040 		ret_rate = MGN_MCS2;
1041 		break;
1042 	case DESC_RATEMCS3:
1043 		ret_rate = MGN_MCS3;
1044 		break;
1045 	case DESC_RATEMCS4:
1046 		ret_rate = MGN_MCS4;
1047 		break;
1048 	case DESC_RATEMCS5:
1049 		ret_rate = MGN_MCS5;
1050 		break;
1051 	case DESC_RATEMCS6:
1052 		ret_rate = MGN_MCS6;
1053 		break;
1054 	case DESC_RATEMCS7:
1055 		ret_rate = MGN_MCS7;
1056 		break;
1057 	case DESC_RATEMCS8:
1058 		ret_rate = MGN_MCS8;
1059 		break;
1060 	case DESC_RATEMCS9:
1061 		ret_rate = MGN_MCS9;
1062 		break;
1063 	case DESC_RATEMCS10:
1064 		ret_rate = MGN_MCS10;
1065 		break;
1066 	case DESC_RATEMCS11:
1067 		ret_rate = MGN_MCS11;
1068 		break;
1069 	case DESC_RATEMCS12:
1070 		ret_rate = MGN_MCS12;
1071 		break;
1072 	case DESC_RATEMCS13:
1073 		ret_rate = MGN_MCS13;
1074 		break;
1075 	case DESC_RATEMCS14:
1076 		ret_rate = MGN_MCS14;
1077 		break;
1078 	case DESC_RATEMCS15:
1079 		ret_rate = MGN_MCS15;
1080 		break;
1081 	case DESC_RATEVHT1SS_MCS0:
1082 		ret_rate = MGN_VHT1SS_MCS0;
1083 		break;
1084 	case DESC_RATEVHT1SS_MCS1:
1085 		ret_rate = MGN_VHT1SS_MCS1;
1086 		break;
1087 	case DESC_RATEVHT1SS_MCS2:
1088 		ret_rate = MGN_VHT1SS_MCS2;
1089 		break;
1090 	case DESC_RATEVHT1SS_MCS3:
1091 		ret_rate = MGN_VHT1SS_MCS3;
1092 		break;
1093 	case DESC_RATEVHT1SS_MCS4:
1094 		ret_rate = MGN_VHT1SS_MCS4;
1095 		break;
1096 	case DESC_RATEVHT1SS_MCS5:
1097 		ret_rate = MGN_VHT1SS_MCS5;
1098 		break;
1099 	case DESC_RATEVHT1SS_MCS6:
1100 		ret_rate = MGN_VHT1SS_MCS6;
1101 		break;
1102 	case DESC_RATEVHT1SS_MCS7:
1103 		ret_rate = MGN_VHT1SS_MCS7;
1104 		break;
1105 	case DESC_RATEVHT1SS_MCS8:
1106 		ret_rate = MGN_VHT1SS_MCS8;
1107 		break;
1108 	case DESC_RATEVHT1SS_MCS9:
1109 		ret_rate = MGN_VHT1SS_MCS9;
1110 		break;
1111 	case DESC_RATEVHT2SS_MCS0:
1112 		ret_rate = MGN_VHT2SS_MCS0;
1113 		break;
1114 	case DESC_RATEVHT2SS_MCS1:
1115 		ret_rate = MGN_VHT2SS_MCS1;
1116 		break;
1117 	case DESC_RATEVHT2SS_MCS2:
1118 		ret_rate = MGN_VHT2SS_MCS2;
1119 		break;
1120 	case DESC_RATEVHT2SS_MCS3:
1121 		ret_rate = MGN_VHT2SS_MCS3;
1122 		break;
1123 	case DESC_RATEVHT2SS_MCS4:
1124 		ret_rate = MGN_VHT2SS_MCS4;
1125 		break;
1126 	case DESC_RATEVHT2SS_MCS5:
1127 		ret_rate = MGN_VHT2SS_MCS5;
1128 		break;
1129 	case DESC_RATEVHT2SS_MCS6:
1130 		ret_rate = MGN_VHT2SS_MCS6;
1131 		break;
1132 	case DESC_RATEVHT2SS_MCS7:
1133 		ret_rate = MGN_VHT2SS_MCS7;
1134 		break;
1135 	case DESC_RATEVHT2SS_MCS8:
1136 		ret_rate = MGN_VHT2SS_MCS8;
1137 		break;
1138 	case DESC_RATEVHT2SS_MCS9:
1139 		ret_rate = MGN_VHT2SS_MCS9;
1140 		break;
1141 	default:
1142 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1143 			"HwRateToMRate8812(): Non supported Rate [%x]!!!\n",
1144 			rate);
1145 		break;
1146 	}
1147 	return ret_rate;
1148 }
1149 
1150 /*-----------------------------------------------------------------------------
1151  * Function:	odm_TxPwrTrackSetPwr88E()
1152  *
1153  * Overview:	88E change all channel tx power accordign to flag.
1154  *				OFDM & CCK are all different.
1155  *
1156  * Input:		NONE
1157  *
1158  * Output:		NONE
1159  *
1160  * Return:		NONE
1161  *
1162  * Revised History:
1163  *	When		Who		Remark
1164  *	04/23/2012	MHC		Create Version 0.
1165  *
1166  *---------------------------------------------------------------------------
1167  */
rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw * hw,enum pwr_track_control_method method,u8 rf_path,u8 channel_mapped_index)1168 void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
1169 				      enum pwr_track_control_method method,
1170 				      u8 rf_path, u8 channel_mapped_index)
1171 {
1172 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1173 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
1174 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1175 	u32 final_swing_idx[2];
1176 	u8 pwr_tracking_limit = 26; /*+1.0dB*/
1177 	u8 tx_rate = 0xFF;
1178 	s8 final_ofdm_swing_index = 0;
1179 
1180 	if (rtldm->tx_rate != 0xFF)
1181 		tx_rate =
1182 			rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
1183 
1184 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1185 		"===>%s\n", __func__);
1186 	/*20130429 Mimic Modify High Rate BBSwing Limit.*/
1187 	if (tx_rate != 0xFF) {
1188 		/*CCK*/
1189 		if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
1190 			pwr_tracking_limit = 32; /*+4dB*/
1191 		/*OFDM*/
1192 		else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
1193 			pwr_tracking_limit = 30; /*+3dB*/
1194 		else if (tx_rate == MGN_54M)
1195 			pwr_tracking_limit = 28; /*+2dB*/
1196 		/*HT*/
1197 		 /*QPSK/BPSK*/
1198 		else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2))
1199 			pwr_tracking_limit = 34; /*+5dB*/
1200 		 /*16QAM*/
1201 		else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4))
1202 			pwr_tracking_limit = 30; /*+3dB*/
1203 		 /*64QAM*/
1204 		else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7))
1205 			pwr_tracking_limit = 28; /*+2dB*/
1206 		 /*QPSK/BPSK*/
1207 		else if ((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10))
1208 			pwr_tracking_limit = 34; /*+5dB*/
1209 		 /*16QAM*/
1210 		else if ((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12))
1211 			pwr_tracking_limit = 30; /*+3dB*/
1212 		 /*64QAM*/
1213 		else if ((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15))
1214 			pwr_tracking_limit = 28; /*+2dB*/
1215 
1216 		/*2 VHT*/
1217 		 /*QPSK/BPSK*/
1218 		else if ((tx_rate >= MGN_VHT1SS_MCS0) &&
1219 			 (tx_rate <= MGN_VHT1SS_MCS2))
1220 			pwr_tracking_limit = 34; /*+5dB*/
1221 		 /*16QAM*/
1222 		else if ((tx_rate >= MGN_VHT1SS_MCS3) &&
1223 			 (tx_rate <= MGN_VHT1SS_MCS4))
1224 			pwr_tracking_limit = 30; /*+3dB*/
1225 		 /*64QAM*/
1226 		else if ((tx_rate >= MGN_VHT1SS_MCS5) &&
1227 			 (tx_rate <= MGN_VHT1SS_MCS6))
1228 			pwr_tracking_limit = 28; /*+2dB*/
1229 		else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
1230 			pwr_tracking_limit = 26; /*+1dB*/
1231 		else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
1232 			pwr_tracking_limit = 24; /*+0dB*/
1233 		else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
1234 			pwr_tracking_limit = 22; /*-1dB*/
1235 		 /*QPSK/BPSK*/
1236 		else if ((tx_rate >= MGN_VHT2SS_MCS0) &&
1237 			 (tx_rate <= MGN_VHT2SS_MCS2))
1238 			pwr_tracking_limit = 34; /*+5dB*/
1239 		 /*16QAM*/
1240 		else if ((tx_rate >= MGN_VHT2SS_MCS3) &&
1241 			 (tx_rate <= MGN_VHT2SS_MCS4))
1242 			pwr_tracking_limit = 30; /*+3dB*/
1243 		 /*64QAM*/
1244 		else if ((tx_rate >= MGN_VHT2SS_MCS5) &&
1245 			 (tx_rate <= MGN_VHT2SS_MCS6))
1246 			pwr_tracking_limit = 28; /*+2dB*/
1247 		else if (tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/
1248 			pwr_tracking_limit = 26; /*+1dB*/
1249 		else if (tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/
1250 			pwr_tracking_limit = 24; /*+0dB*/
1251 		else if (tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/
1252 			pwr_tracking_limit = 22; /*-1dB*/
1253 		else
1254 			pwr_tracking_limit = 24;
1255 	}
1256 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1257 		"TxRate=0x%x, PwrTrackingLimit=%d\n",
1258 		tx_rate, pwr_tracking_limit);
1259 
1260 	if (method == BBSWING) {
1261 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1262 			"===>%s\n", __func__);
1263 
1264 		if (rf_path == RF90_PATH_A) {
1265 			u32 tmp;
1266 
1267 			final_swing_idx[RF90_PATH_A] =
1268 				(rtldm->ofdm_index[RF90_PATH_A] >
1269 				pwr_tracking_limit) ?
1270 				pwr_tracking_limit :
1271 				rtldm->ofdm_index[RF90_PATH_A];
1272 			tmp = final_swing_idx[RF90_PATH_A];
1273 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1274 				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
1275 				rtldm->ofdm_index[RF90_PATH_A],
1276 				final_swing_idx[RF90_PATH_A]);
1277 
1278 			rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1279 				      txscaling_tbl[tmp]);
1280 		} else {
1281 			u32 tmp;
1282 
1283 			final_swing_idx[RF90_PATH_B] =
1284 				rtldm->ofdm_index[RF90_PATH_B] >
1285 				pwr_tracking_limit ?
1286 				pwr_tracking_limit :
1287 				rtldm->ofdm_index[RF90_PATH_B];
1288 			tmp = final_swing_idx[RF90_PATH_B];
1289 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1290 				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n",
1291 				rtldm->ofdm_index[RF90_PATH_B],
1292 				final_swing_idx[RF90_PATH_B]);
1293 
1294 			rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1295 				      txscaling_tbl[tmp]);
1296 		}
1297 	} else if (method == MIX_MODE) {
1298 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1299 			"pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
1300 			rtldm->default_ofdm_index,
1301 			rtldm->absolute_ofdm_swing_idx[rf_path],
1302 			rf_path);
1303 
1304 		final_ofdm_swing_index = rtldm->default_ofdm_index +
1305 				rtldm->absolute_ofdm_swing_idx[rf_path];
1306 
1307 		if (rf_path == RF90_PATH_A) {
1308 			/*BBSwing higher then Limit*/
1309 			if (final_ofdm_swing_index > pwr_tracking_limit) {
1310 				rtldm->remnant_cck_idx =
1311 					final_ofdm_swing_index -
1312 					pwr_tracking_limit;
1313 				/* CCK Follow the same compensation value
1314 				 * as Path A
1315 				 */
1316 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1317 					final_ofdm_swing_index -
1318 					pwr_tracking_limit;
1319 
1320 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1321 					      txscaling_tbl[pwr_tracking_limit]);
1322 
1323 				rtldm->modify_txagc_flag_path_a = true;
1324 
1325 				/*Set TxAGC Page C{};*/
1326 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1327 					rtlphy->current_channel,
1328 					RF90_PATH_A);
1329 
1330 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1331 					"******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n",
1332 					pwr_tracking_limit,
1333 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1334 			} else if (final_ofdm_swing_index < 0) {
1335 				rtldm->remnant_cck_idx = final_ofdm_swing_index;
1336 				/* CCK Follow the same compensate value as Path A*/
1337 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1338 					final_ofdm_swing_index;
1339 
1340 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1341 					txscaling_tbl[0]);
1342 
1343 				rtldm->modify_txagc_flag_path_a = true;
1344 
1345 				/*Set TxAGC Page C{};*/
1346 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1347 					rtlphy->current_channel, RF90_PATH_A);
1348 
1349 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1350 					"******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
1351 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1352 			} else {
1353 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1354 					txscaling_tbl[(u8)final_ofdm_swing_index]);
1355 
1356 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1357 					"******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n",
1358 					final_ofdm_swing_index);
1359 				/*If TxAGC has changed, reset TxAGC again*/
1360 				if (rtldm->modify_txagc_flag_path_a) {
1361 					rtldm->remnant_cck_idx = 0;
1362 					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1363 
1364 					/*Set TxAGC Page C{};*/
1365 					rtl8821ae_phy_set_txpower_level_by_path(hw,
1366 						rtlphy->current_channel, RF90_PATH_A);
1367 					rtldm->modify_txagc_flag_path_a = false;
1368 
1369 					rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
1370 						DBG_LOUD,
1371 						"******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1372 				}
1373 			}
1374 		}
1375 		/*BBSwing higher then Limit*/
1376 		if (rf_path == RF90_PATH_B) {
1377 			if (final_ofdm_swing_index > pwr_tracking_limit) {
1378 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1379 					final_ofdm_swing_index -
1380 					pwr_tracking_limit;
1381 
1382 				rtl_set_bbreg(hw, RB_TXSCALE,
1383 					0xFFE00000,
1384 					txscaling_tbl[pwr_tracking_limit]);
1385 
1386 				rtldm->modify_txagc_flag_path_b = true;
1387 
1388 				/*Set TxAGC Page E{};*/
1389 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1390 					rtlphy->current_channel, RF90_PATH_B);
1391 
1392 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1393 					"******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
1394 					pwr_tracking_limit,
1395 					 rtldm->remnant_ofdm_swing_idx[rf_path]);
1396 			} else if (final_ofdm_swing_index < 0) {
1397 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1398 					final_ofdm_swing_index;
1399 
1400 				rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1401 					      txscaling_tbl[0]);
1402 
1403 				rtldm->modify_txagc_flag_path_b = true;
1404 
1405 				/*Set TxAGC Page E{};*/
1406 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1407 					rtlphy->current_channel, RF90_PATH_B);
1408 
1409 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1410 					"******Path_B Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
1411 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1412 			} else {
1413 				rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1414 					txscaling_tbl[(u8)final_ofdm_swing_index]);
1415 
1416 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1417 					"******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
1418 					final_ofdm_swing_index);
1419 				 /*If TxAGC has changed, reset TxAGC again*/
1420 				if (rtldm->modify_txagc_flag_path_b) {
1421 					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1422 
1423 					/*Set TxAGC Page E{};*/
1424 					rtl8821ae_phy_set_txpower_level_by_path(hw,
1425 					rtlphy->current_channel, RF90_PATH_B);
1426 
1427 					rtldm->modify_txagc_flag_path_b =
1428 						false;
1429 
1430 					rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1431 						"******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1432 				}
1433 			}
1434 		}
1435 	} else {
1436 		return;
1437 	}
1438 }
1439 
rtl8812ae_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw * hw)1440 void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(
1441 	struct ieee80211_hw *hw)
1442 {
1443 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1444 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1445 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
1446 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1447 	u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
1448 	u8 thermal_value_avg_count = 0;
1449 	u32 thermal_value_avg = 0;
1450 	/* OFDM BB Swing should be less than +3.0dB, */
1451 	u8 ofdm_min_index = 6;
1452 	 /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
1453 	u8 index_for_channel = 0;
1454 	/* 1. The following TWO tables decide
1455 	 * the final index of OFDM/CCK swing table.
1456 	 */
1457 	const u8 *delta_swing_table_idx_tup_a;
1458 	const u8 *delta_swing_table_idx_tdown_a;
1459 	const u8 *delta_swing_table_idx_tup_b;
1460 	const u8 *delta_swing_table_idx_tdown_b;
1461 
1462 	/*2. Initialization ( 7 steps in total )*/
1463 	rtl8812ae_get_delta_swing_table(hw,
1464 		&delta_swing_table_idx_tup_a,
1465 		&delta_swing_table_idx_tdown_a,
1466 		&delta_swing_table_idx_tup_b,
1467 		&delta_swing_table_idx_tdown_b);
1468 
1469 	rtldm->txpower_trackinginit = true;
1470 
1471 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1472 		"pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
1473 		rtldm->swing_idx_cck_base,
1474 		rtldm->swing_idx_ofdm_base[RF90_PATH_A],
1475 		rtldm->default_ofdm_index);
1476 
1477 	thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A,
1478 		/*0x42: RF Reg[15:10] 88E*/
1479 		RF_T_METER_8812A, 0xfc00);
1480 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1481 		"Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1482 		thermal_value, rtlefuse->eeprom_thermalmeter);
1483 	if (!rtldm->txpower_track_control ||
1484 	    rtlefuse->eeprom_thermalmeter == 0 ||
1485 	    rtlefuse->eeprom_thermalmeter == 0xFF)
1486 		return;
1487 
1488 	/* 3. Initialize ThermalValues of RFCalibrateInfo*/
1489 
1490 	if (rtlhal->reloadtxpowerindex)
1491 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1492 			"reload ofdm index for band switch\n");
1493 
1494 	/*4. Calculate average thermal meter*/
1495 	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
1496 	rtldm->thermalvalue_avg_index++;
1497 	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
1498 		/*Average times =  c.AverageThermalNum*/
1499 		rtldm->thermalvalue_avg_index = 0;
1500 
1501 	for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) {
1502 		if (rtldm->thermalvalue_avg[i]) {
1503 			thermal_value_avg += rtldm->thermalvalue_avg[i];
1504 			thermal_value_avg_count++;
1505 		}
1506 	}
1507 	/*Calculate Average ThermalValue after average enough times*/
1508 	if (thermal_value_avg_count) {
1509 		thermal_value = (u8)(thermal_value_avg /
1510 				thermal_value_avg_count);
1511 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1512 			"AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1513 			thermal_value, rtlefuse->eeprom_thermalmeter);
1514 	}
1515 
1516 	/*5. Calculate delta, delta_LCK, delta_IQK.
1517 	 *"delta" here is used to determine whether
1518 	 *thermal value changes or not.
1519 	 */
1520 	delta = (thermal_value > rtldm->thermalvalue) ?
1521 		(thermal_value - rtldm->thermalvalue) :
1522 		(rtldm->thermalvalue - thermal_value);
1523 	delta_lck = (thermal_value > rtldm->thermalvalue_lck) ?
1524 		(thermal_value - rtldm->thermalvalue_lck) :
1525 		(rtldm->thermalvalue_lck - thermal_value);
1526 	delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ?
1527 		(thermal_value - rtldm->thermalvalue_iqk) :
1528 		(rtldm->thermalvalue_iqk - thermal_value);
1529 
1530 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1531 		"(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
1532 		delta, delta_lck, delta_iqk);
1533 
1534 	/* 6. If necessary, do LCK.
1535 	 * Delta temperature is equal to or larger than 20 centigrade.
1536 	 */
1537 	if (delta_lck >= IQK_THRESHOLD) {
1538 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1539 			"delta_LCK(%d) >= Threshold_IQK(%d)\n",
1540 			delta_lck, IQK_THRESHOLD);
1541 		rtldm->thermalvalue_lck = thermal_value;
1542 		rtl8821ae_phy_lc_calibrate(hw);
1543 	}
1544 
1545 	/*7. If necessary, move the index of swing table to adjust Tx power.*/
1546 
1547 	if (delta > 0 && rtldm->txpower_track_control) {
1548 		/* "delta" here is used to record the
1549 		 * absolute value of differrence.
1550 		 */
1551 		delta = thermal_value > rtlefuse->eeprom_thermalmeter ?
1552 			(thermal_value - rtlefuse->eeprom_thermalmeter) :
1553 			(rtlefuse->eeprom_thermalmeter - thermal_value);
1554 
1555 		if (delta >= TXPWR_TRACK_TABLE_SIZE)
1556 			delta = TXPWR_TRACK_TABLE_SIZE - 1;
1557 
1558 		/*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
1559 
1560 		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
1561 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1562 				"delta_swing_table_idx_tup_a[%d] = %d\n",
1563 				delta, delta_swing_table_idx_tup_a[delta]);
1564 			rtldm->delta_power_index_last[RF90_PATH_A] =
1565 				rtldm->delta_power_index[RF90_PATH_A];
1566 			rtldm->delta_power_index[RF90_PATH_A] =
1567 				delta_swing_table_idx_tup_a[delta];
1568 
1569 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
1570 				delta_swing_table_idx_tup_a[delta];
1571 			/*Record delta swing for mix mode power tracking*/
1572 
1573 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1574 				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1575 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
1576 
1577 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1578 				"delta_swing_table_idx_tup_b[%d] = %d\n",
1579 				delta, delta_swing_table_idx_tup_b[delta]);
1580 			rtldm->delta_power_index_last[RF90_PATH_B] =
1581 				rtldm->delta_power_index[RF90_PATH_B];
1582 			rtldm->delta_power_index[RF90_PATH_B] =
1583 				delta_swing_table_idx_tup_b[delta];
1584 
1585 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] =
1586 				delta_swing_table_idx_tup_b[delta];
1587 			/*Record delta swing for mix mode power tracking*/
1588 
1589 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1590 				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1591 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]);
1592 		} else {
1593 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1594 				"delta_swing_table_idx_tdown_a[%d] = %d\n",
1595 				delta, delta_swing_table_idx_tdown_a[delta]);
1596 
1597 			rtldm->delta_power_index_last[RF90_PATH_A] =
1598 				rtldm->delta_power_index[RF90_PATH_A];
1599 			rtldm->delta_power_index[RF90_PATH_A] =
1600 				-1 * delta_swing_table_idx_tdown_a[delta];
1601 
1602 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
1603 				-1 * delta_swing_table_idx_tdown_a[delta];
1604 			/* Record delta swing for mix mode power tracking*/
1605 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1606 				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1607 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
1608 
1609 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1610 				"deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
1611 				delta, delta_swing_table_idx_tdown_b[delta]);
1612 
1613 			rtldm->delta_power_index_last[RF90_PATH_B] =
1614 				rtldm->delta_power_index[RF90_PATH_B];
1615 			rtldm->delta_power_index[RF90_PATH_B] =
1616 				-1 * delta_swing_table_idx_tdown_b[delta];
1617 
1618 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] =
1619 				-1 * delta_swing_table_idx_tdown_b[delta];
1620 			/*Record delta swing for mix mode power tracking*/
1621 
1622 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1623 				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1624 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]);
1625 		}
1626 
1627 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) {
1628 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1629 				"============================= [Path-%c]Calculating PowerIndexOffset =============================\n",
1630 				(p == RF90_PATH_A ? 'A' : 'B'));
1631 
1632 			if (rtldm->delta_power_index[p] ==
1633 				rtldm->delta_power_index_last[p])
1634 				/*If Thermal value changes but lookup
1635 				table value still the same*/
1636 				rtldm->power_index_offset[p] = 0;
1637 			else
1638 				rtldm->power_index_offset[p] =
1639 					rtldm->delta_power_index[p] -
1640 					rtldm->delta_power_index_last[p];
1641 				/* Power Index Diff between 2
1642 				 * times Power Tracking
1643 				 */
1644 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1645 				"[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n",
1646 				(p == RF90_PATH_A ? 'A' : 'B'),
1647 				rtldm->power_index_offset[p],
1648 				rtldm->delta_power_index[p],
1649 				rtldm->delta_power_index_last[p]);
1650 
1651 			rtldm->ofdm_index[p] =
1652 					rtldm->swing_idx_ofdm_base[p] +
1653 					rtldm->power_index_offset[p];
1654 			rtldm->cck_index =
1655 					rtldm->swing_idx_cck_base +
1656 					rtldm->power_index_offset[p];
1657 
1658 			rtldm->swing_idx_cck = rtldm->cck_index;
1659 			rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p];
1660 
1661 			/****Print BB Swing Base and Index Offset */
1662 
1663 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1664 				"The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
1665 				rtldm->swing_idx_cck,
1666 				rtldm->swing_idx_cck_base,
1667 				rtldm->power_index_offset[p]);
1668 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1669 				"The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
1670 				rtldm->swing_idx_ofdm[p],
1671 				(p == RF90_PATH_A ? 'A' : 'B'),
1672 				rtldm->swing_idx_ofdm_base[p],
1673 				rtldm->power_index_offset[p]);
1674 
1675 			/*7.1 Handle boundary conditions of index.*/
1676 
1677 			if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1)
1678 				rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1;
1679 			else if (rtldm->ofdm_index[p] < ofdm_min_index)
1680 				rtldm->ofdm_index[p] = ofdm_min_index;
1681 		}
1682 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1683 			"\n\n====================================================================================\n");
1684 		if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1)
1685 			rtldm->cck_index = TXSCALE_TABLE_SIZE - 1;
1686 		else if (rtldm->cck_index < 0)
1687 			rtldm->cck_index = 0;
1688 	} else {
1689 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1690 			"The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
1691 			rtldm->txpower_track_control,
1692 			thermal_value,
1693 			rtldm->thermalvalue);
1694 
1695 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1696 			rtldm->power_index_offset[p] = 0;
1697 	}
1698 	/*Print Swing base & current*/
1699 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1700 		"TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n",
1701 		rtldm->cck_index, rtldm->swing_idx_cck_base);
1702 	for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) {
1703 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1704 			"TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n",
1705 			rtldm->ofdm_index[p],
1706 			(p == RF90_PATH_A ? 'A' : 'B'),
1707 			rtldm->swing_idx_ofdm_base[p]);
1708 	}
1709 
1710 	if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
1711 		rtldm->power_index_offset[RF90_PATH_B] != 0) &&
1712 		rtldm->txpower_track_control) {
1713 		/*7.2 Configure the Swing Table to adjust Tx Power.
1714 		 *Always TRUE after Tx Power is adjusted by power tracking.
1715 		 *
1716 		 *2012/04/23 MH According to Luke's suggestion,
1717 		 *we can not write BB digital
1718 		 *to increase TX power. Otherwise, EVM will be bad.
1719 		 *
1720 		 *2012/04/25 MH Add for tx power tracking to set
1721 		 *tx power in tx agc for 88E.
1722 		 */
1723 		if (thermal_value > rtldm->thermalvalue) {
1724 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1725 				"Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n",
1726 				rtldm->power_index_offset[RF90_PATH_A],
1727 				delta, thermal_value,
1728 				rtlefuse->eeprom_thermalmeter,
1729 				rtldm->thermalvalue);
1730 
1731 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1732 				"Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1733 				rtldm->power_index_offset[RF90_PATH_B],
1734 				delta, thermal_value,
1735 				rtlefuse->eeprom_thermalmeter,
1736 				rtldm->thermalvalue);
1737 		} else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
1738 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1739 				"Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1740 				rtldm->power_index_offset[RF90_PATH_A],
1741 				delta, thermal_value,
1742 				rtlefuse->eeprom_thermalmeter,
1743 				rtldm->thermalvalue);
1744 
1745 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1746 				"Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1747 				rtldm->power_index_offset[RF90_PATH_B],
1748 				delta, thermal_value,
1749 				rtlefuse->eeprom_thermalmeter,
1750 				rtldm->thermalvalue);
1751 		}
1752 
1753 		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
1754 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1755 				"Temperature(%d) higher than PG value(%d)\n",
1756 				thermal_value, rtlefuse->eeprom_thermalmeter);
1757 
1758 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1759 				"**********Enter POWER Tracking MIX_MODE**********\n");
1760 			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1761 				rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE,
1762 								 p, 0);
1763 		} else {
1764 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1765 				"Temperature(%d) lower than PG value(%d)\n",
1766 				thermal_value, rtlefuse->eeprom_thermalmeter);
1767 
1768 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1769 				"**********Enter POWER Tracking MIX_MODE**********\n");
1770 			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1771 				rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE,
1772 								 p, index_for_channel);
1773 		}
1774 		/*Record last time Power Tracking result as base.*/
1775 		rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
1776 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1777 				rtldm->swing_idx_ofdm_base[p] =
1778 					rtldm->swing_idx_ofdm[p];
1779 
1780 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1781 			"pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n",
1782 			rtldm->thermalvalue, thermal_value);
1783 		/*Record last Power Tracking Thermal Value*/
1784 		rtldm->thermalvalue = thermal_value;
1785 	}
1786 	/*Delta temperature is equal to or larger than
1787 	20 centigrade (When threshold is 8).*/
1788 	if (delta_iqk >= IQK_THRESHOLD)
1789 		rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8);
1790 
1791 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1792 		"<===%s\n", __func__);
1793 }
1794 
rtl8821ae_get_delta_swing_table(struct ieee80211_hw * hw,const u8 ** up_a,const u8 ** down_a)1795 static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw,
1796 					    const u8 **up_a,
1797 					    const u8 **down_a)
1798 {
1799 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1800 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1801 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1802 	u8 channel = rtlphy->current_channel;
1803 	u8 rate = rtldm->tx_rate;
1804 
1805 	if (1 <= channel && channel <= 14) {
1806 		if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
1807 			*up_a = rtl8821ae_delta_swing_table_idx_24gccka_p;
1808 			*down_a = rtl8821ae_delta_swing_table_idx_24gccka_n;
1809 		} else {
1810 			*up_a = rtl8821ae_delta_swing_table_idx_24ga_p;
1811 			*down_a = rtl8821ae_delta_swing_table_idx_24ga_n;
1812 		}
1813 	} else if (36 <= channel && channel <= 64) {
1814 		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0];
1815 		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0];
1816 	} else if (100 <= channel && channel <= 140) {
1817 		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1];
1818 		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1];
1819 	} else if (149 <= channel && channel <= 173) {
1820 		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2];
1821 		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2];
1822 	} else {
1823 		*up_a = rtl8818e_delta_swing_table_idx_24gb_p;
1824 		*down_a = rtl8818e_delta_swing_table_idx_24gb_n;
1825 	}
1826 	return;
1827 }
1828 
1829 /*-----------------------------------------------------------------------------
1830  * Function:	odm_TxPwrTrackSetPwr88E()
1831  *
1832  * Overview:	88E change all channel tx power accordign to flag.
1833  *				OFDM & CCK are all different.
1834  *
1835  * Input:		NONE
1836  *
1837  * Output:		NONE
1838  *
1839  * Return:		NONE
1840  *
1841  * Revised History:
1842  *	When		Who		Remark
1843  *	04/23/2012	MHC		Create Version 0.
1844  *
1845  *---------------------------------------------------------------------------
1846  */
rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw * hw,enum pwr_track_control_method method,u8 rf_path,u8 channel_mapped_index)1847 void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
1848 				      enum pwr_track_control_method method,
1849 				      u8 rf_path, u8 channel_mapped_index)
1850 {
1851 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1852 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
1853 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1854 	u32 final_swing_idx[1];
1855 	u8 pwr_tracking_limit = 26; /*+1.0dB*/
1856 	u8 tx_rate = 0xFF;
1857 	s8 final_ofdm_swing_index = 0;
1858 
1859 	if (rtldm->tx_rate != 0xFF)
1860 		tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
1861 
1862 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__);
1863 
1864 	if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/
1865 		/*CCK*/
1866 		if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
1867 			pwr_tracking_limit = 32; /*+4dB*/
1868 		/*OFDM*/
1869 		else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
1870 			pwr_tracking_limit = 30; /*+3dB*/
1871 		else if (tx_rate == MGN_54M)
1872 			pwr_tracking_limit = 28; /*+2dB*/
1873 		/*HT*/
1874 		/*QPSK/BPSK*/
1875 		else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2))
1876 			pwr_tracking_limit = 34; /*+5dB*/
1877 		/*16QAM*/
1878 		else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4))
1879 			pwr_tracking_limit = 30; /*+3dB*/
1880 		/*64QAM*/
1881 		else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7))
1882 			pwr_tracking_limit = 28; /*+2dB*/
1883 		/*2 VHT*/
1884 		/*QPSK/BPSK*/
1885 		else if ((tx_rate >= MGN_VHT1SS_MCS0) &&
1886 			(tx_rate <= MGN_VHT1SS_MCS2))
1887 			pwr_tracking_limit = 34; /*+5dB*/
1888 		/*16QAM*/
1889 		else if ((tx_rate >= MGN_VHT1SS_MCS3) &&
1890 			(tx_rate <= MGN_VHT1SS_MCS4))
1891 			pwr_tracking_limit = 30; /*+3dB*/
1892 		/*64QAM*/
1893 		else if ((tx_rate >= MGN_VHT1SS_MCS5) &&
1894 			(tx_rate <= MGN_VHT1SS_MCS6))
1895 			pwr_tracking_limit = 28; /*+2dB*/
1896 		else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
1897 			pwr_tracking_limit = 26; /*+1dB*/
1898 		else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
1899 			pwr_tracking_limit = 24; /*+0dB*/
1900 		else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
1901 			pwr_tracking_limit = 22; /*-1dB*/
1902 		else
1903 			pwr_tracking_limit = 24;
1904 	}
1905 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1906 		"TxRate=0x%x, PwrTrackingLimit=%d\n",
1907 		tx_rate, pwr_tracking_limit);
1908 
1909 	if (method == BBSWING) {
1910 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1911 			"===>%s\n", __func__);
1912 		if (rf_path == RF90_PATH_A) {
1913 			final_swing_idx[RF90_PATH_A] =
1914 				(rtldm->ofdm_index[RF90_PATH_A] >
1915 				pwr_tracking_limit) ?
1916 				pwr_tracking_limit :
1917 				rtldm->ofdm_index[RF90_PATH_A];
1918 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1919 				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
1920 				rtldm->ofdm_index[RF90_PATH_A],
1921 				final_swing_idx[RF90_PATH_A]);
1922 
1923 			rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1924 				txscaling_tbl[final_swing_idx[RF90_PATH_A]]);
1925 		}
1926 	} else if (method == MIX_MODE) {
1927 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1928 			"pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
1929 			rtldm->default_ofdm_index,
1930 			rtldm->absolute_ofdm_swing_idx[rf_path],
1931 			rf_path);
1932 
1933 		final_ofdm_swing_index =
1934 			rtldm->default_ofdm_index +
1935 			rtldm->absolute_ofdm_swing_idx[rf_path];
1936 		/*BBSwing higher then Limit*/
1937 		if (rf_path == RF90_PATH_A) {
1938 			if (final_ofdm_swing_index > pwr_tracking_limit) {
1939 				rtldm->remnant_cck_idx =
1940 					final_ofdm_swing_index -
1941 					pwr_tracking_limit;
1942 				/* CCK Follow the same compensate value as Path A*/
1943 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1944 					final_ofdm_swing_index -
1945 					pwr_tracking_limit;
1946 
1947 				rtl_set_bbreg(hw, RA_TXSCALE,
1948 					0xFFE00000,
1949 					txscaling_tbl[pwr_tracking_limit]);
1950 
1951 				rtldm->modify_txagc_flag_path_a = true;
1952 
1953 				/*Set TxAGC Page C{};*/
1954 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1955 					rtlphy->current_channel,
1956 					RF90_PATH_A);
1957 
1958 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1959 					" ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
1960 					pwr_tracking_limit,
1961 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1962 			} else if (final_ofdm_swing_index < 0) {
1963 				rtldm->remnant_cck_idx = final_ofdm_swing_index;
1964 				/* CCK Follow the same compensate value as Path A*/
1965 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1966 					final_ofdm_swing_index;
1967 
1968 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1969 					txscaling_tbl[0]);
1970 
1971 				rtldm->modify_txagc_flag_path_a = true;
1972 
1973 				/*Set TxAGC Page C{};*/
1974 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1975 					rtlphy->current_channel, RF90_PATH_A);
1976 
1977 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1978 					"******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
1979 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1980 			} else {
1981 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1982 					txscaling_tbl[(u8)final_ofdm_swing_index]);
1983 
1984 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1985 					"******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
1986 					final_ofdm_swing_index);
1987 				/*If TxAGC has changed, reset TxAGC again*/
1988 				if (rtldm->modify_txagc_flag_path_a) {
1989 					rtldm->remnant_cck_idx = 0;
1990 					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1991 
1992 					/*Set TxAGC Page C{};*/
1993 					rtl8821ae_phy_set_txpower_level_by_path(hw,
1994 						rtlphy->current_channel, RF90_PATH_A);
1995 
1996 					rtldm->modify_txagc_flag_path_a = false;
1997 
1998 					rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
1999 						DBG_LOUD,
2000 						"******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n");
2001 				}
2002 			}
2003 		}
2004 	} else {
2005 		return;
2006 	}
2007 }
2008 
rtl8821ae_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw * hw)2009 void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(
2010 	struct ieee80211_hw *hw)
2011 {
2012 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2013 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2014 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
2015 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2016 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2017 
2018 	u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
2019 	u8 thermal_value_avg_count = 0;
2020 	u32 thermal_value_avg = 0;
2021 
2022 	u8 ofdm_min_index = 6;  /*OFDM BB Swing should be less than +3.0dB */
2023 	/* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
2024 	u8 index_for_channel = 0;
2025 
2026 	/* 1. The following TWO tables decide the final
2027 	 * index of OFDM/CCK swing table.
2028 	 */
2029 	const u8 *delta_swing_table_idx_tup_a;
2030 	const u8 *delta_swing_table_idx_tdown_a;
2031 
2032 	/*2. Initilization ( 7 steps in total )*/
2033 	rtl8821ae_get_delta_swing_table(hw,
2034 					&delta_swing_table_idx_tup_a,
2035 					&delta_swing_table_idx_tdown_a);
2036 
2037 	rtldm->txpower_trackinginit = true;
2038 
2039 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2040 		"===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
2041 		__func__,
2042 		rtldm->swing_idx_cck_base,
2043 		rtldm->swing_idx_ofdm_base[RF90_PATH_A],
2044 		rtldm->default_ofdm_index);
2045 	/*0x42: RF Reg[15:10] 88E*/
2046 	thermal_value = (u8)rtl_get_rfreg(hw,
2047 		RF90_PATH_A, RF_T_METER_8812A, 0xfc00);
2048 	if (!rtldm->txpower_track_control ||
2049 		rtlefuse->eeprom_thermalmeter == 0 ||
2050 		rtlefuse->eeprom_thermalmeter == 0xFF)
2051 		return;
2052 
2053 	/* 3. Initialize ThermalValues of RFCalibrateInfo*/
2054 
2055 	if (rtlhal->reloadtxpowerindex) {
2056 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2057 			"reload ofdm index for band switch\n");
2058 	}
2059 
2060 	/*4. Calculate average thermal meter*/
2061 	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
2062 	rtldm->thermalvalue_avg_index++;
2063 	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
2064 		/*Average times =  c.AverageThermalNum*/
2065 		rtldm->thermalvalue_avg_index = 0;
2066 
2067 	for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) {
2068 		if (rtldm->thermalvalue_avg[i]) {
2069 			thermal_value_avg += rtldm->thermalvalue_avg[i];
2070 			thermal_value_avg_count++;
2071 		}
2072 	}
2073 	/*Calculate Average ThermalValue after average enough times*/
2074 	if (thermal_value_avg_count) {
2075 		thermal_value = (u8)(thermal_value_avg /
2076 				thermal_value_avg_count);
2077 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2078 			"AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
2079 			thermal_value, rtlefuse->eeprom_thermalmeter);
2080 	}
2081 
2082 	/*5. Calculate delta, delta_LCK, delta_IQK.
2083 	 *"delta" here is used to determine whether
2084 	 * thermal value changes or not.
2085 	 */
2086 	delta = (thermal_value > rtldm->thermalvalue) ?
2087 		(thermal_value - rtldm->thermalvalue) :
2088 		(rtldm->thermalvalue - thermal_value);
2089 	delta_lck = (thermal_value > rtldm->thermalvalue_lck) ?
2090 		(thermal_value - rtldm->thermalvalue_lck) :
2091 		(rtldm->thermalvalue_lck - thermal_value);
2092 	delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ?
2093 		(thermal_value - rtldm->thermalvalue_iqk) :
2094 		(rtldm->thermalvalue_iqk - thermal_value);
2095 
2096 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2097 		"(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
2098 		delta, delta_lck, delta_iqk);
2099 
2100 	/* 6. If necessary, do LCK.	*/
2101 	/*Delta temperature is equal to or larger than 20 centigrade.*/
2102 	if (delta_lck >= IQK_THRESHOLD) {
2103 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2104 			"delta_LCK(%d) >= Threshold_IQK(%d)\n",
2105 			delta_lck, IQK_THRESHOLD);
2106 		rtldm->thermalvalue_lck = thermal_value;
2107 		rtl8821ae_phy_lc_calibrate(hw);
2108 	}
2109 
2110 	/*7. If necessary, move the index of swing table to adjust Tx power.*/
2111 
2112 	if (delta > 0 && rtldm->txpower_track_control) {
2113 		/*"delta" here is used to record the
2114 		 * absolute value of differrence.
2115 		 */
2116 		delta = thermal_value > rtlefuse->eeprom_thermalmeter ?
2117 			(thermal_value - rtlefuse->eeprom_thermalmeter) :
2118 			(rtlefuse->eeprom_thermalmeter - thermal_value);
2119 
2120 		if (delta >= TXSCALE_TABLE_SIZE)
2121 			delta = TXSCALE_TABLE_SIZE - 1;
2122 
2123 		/*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
2124 
2125 		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
2126 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2127 				"delta_swing_table_idx_tup_a[%d] = %d\n",
2128 				delta, delta_swing_table_idx_tup_a[delta]);
2129 			rtldm->delta_power_index_last[RF90_PATH_A] =
2130 				rtldm->delta_power_index[RF90_PATH_A];
2131 			rtldm->delta_power_index[RF90_PATH_A] =
2132 				delta_swing_table_idx_tup_a[delta];
2133 
2134 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
2135 				delta_swing_table_idx_tup_a[delta];
2136 			/*Record delta swing for mix mode power tracking*/
2137 
2138 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2139 				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2140 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
2141 		} else {
2142 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2143 				"delta_swing_table_idx_tdown_a[%d] = %d\n",
2144 				delta, delta_swing_table_idx_tdown_a[delta]);
2145 
2146 			rtldm->delta_power_index_last[RF90_PATH_A] =
2147 				rtldm->delta_power_index[RF90_PATH_A];
2148 			rtldm->delta_power_index[RF90_PATH_A] =
2149 				-1 * delta_swing_table_idx_tdown_a[delta];
2150 
2151 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
2152 				-1 * delta_swing_table_idx_tdown_a[delta];
2153 			/* Record delta swing for mix mode power tracking*/
2154 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2155 				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2156 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
2157 		}
2158 
2159 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) {
2160 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2161 				"\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n",
2162 				(p == RF90_PATH_A ? 'A' : 'B'));
2163 			/*If Thermal value changes but lookup table value
2164 			 * still the same
2165 			 */
2166 			if (rtldm->delta_power_index[p] ==
2167 				rtldm->delta_power_index_last[p])
2168 
2169 				rtldm->power_index_offset[p] = 0;
2170 			else
2171 				rtldm->power_index_offset[p] =
2172 					rtldm->delta_power_index[p] -
2173 					rtldm->delta_power_index_last[p];
2174 			/*Power Index Diff between 2 times Power Tracking*/
2175 
2176 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2177 				"[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
2178 				(p == RF90_PATH_A ? 'A' : 'B'),
2179 				rtldm->power_index_offset[p],
2180 				rtldm->delta_power_index[p] ,
2181 				rtldm->delta_power_index_last[p]);
2182 
2183 			rtldm->ofdm_index[p] =
2184 					rtldm->swing_idx_ofdm_base[p] +
2185 					rtldm->power_index_offset[p];
2186 			rtldm->cck_index =
2187 					rtldm->swing_idx_cck_base +
2188 					rtldm->power_index_offset[p];
2189 
2190 			rtldm->swing_idx_cck = rtldm->cck_index;
2191 			rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p];
2192 
2193 			/*********Print BB Swing Base and Index Offset********/
2194 
2195 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2196 				"The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
2197 				rtldm->swing_idx_cck,
2198 				rtldm->swing_idx_cck_base,
2199 				rtldm->power_index_offset[p]);
2200 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2201 				"The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
2202 				rtldm->swing_idx_ofdm[p],
2203 				(p == RF90_PATH_A ? 'A' : 'B'),
2204 				rtldm->swing_idx_ofdm_base[p],
2205 				rtldm->power_index_offset[p]);
2206 
2207 			/*7.1 Handle boundary conditions of index.*/
2208 
2209 			if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1)
2210 				rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1;
2211 			else if (rtldm->ofdm_index[p] < ofdm_min_index)
2212 				rtldm->ofdm_index[p] = ofdm_min_index;
2213 		}
2214 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2215 			"\n\n========================================================================================================\n");
2216 		if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1)
2217 			rtldm->cck_index = TXSCALE_TABLE_SIZE - 1;
2218 		else if (rtldm->cck_index < 0)
2219 			rtldm->cck_index = 0;
2220 	} else {
2221 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2222 			"The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
2223 			rtldm->txpower_track_control,
2224 			thermal_value,
2225 			rtldm->thermalvalue);
2226 
2227 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2228 			rtldm->power_index_offset[p] = 0;
2229 	}
2230 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2231 		"TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
2232 		/*Print Swing base & current*/
2233 		rtldm->cck_index, rtldm->swing_idx_cck_base);
2234 	for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) {
2235 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2236 			"TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
2237 			rtldm->ofdm_index[p],
2238 			(p == RF90_PATH_A ? 'A' : 'B'),
2239 			rtldm->swing_idx_ofdm_base[p]);
2240 	}
2241 
2242 	if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
2243 		rtldm->power_index_offset[RF90_PATH_B] != 0) &&
2244 		rtldm->txpower_track_control) {
2245 		/*7.2 Configure the Swing Table to adjust Tx Power.*/
2246 		/*Always TRUE after Tx Power is adjusted by power tracking.*/
2247 		/*
2248 		 *  2012/04/23 MH According to Luke's suggestion,
2249 		 *  we can not write BB digital
2250 		 *  to increase TX power. Otherwise, EVM will be bad.
2251 		 *
2252 		 *  2012/04/25 MH Add for tx power tracking to
2253 		 *  set tx power in tx agc for 88E.
2254 		 */
2255 		if (thermal_value > rtldm->thermalvalue) {
2256 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2257 				"Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2258 				rtldm->power_index_offset[RF90_PATH_A],
2259 				delta, thermal_value,
2260 				rtlefuse->eeprom_thermalmeter,
2261 				rtldm->thermalvalue);
2262 		} else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
2263 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2264 				"Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2265 				rtldm->power_index_offset[RF90_PATH_A],
2266 				delta, thermal_value,
2267 				rtlefuse->eeprom_thermalmeter,
2268 				rtldm->thermalvalue);
2269 		}
2270 
2271 		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
2272 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2273 				"Temperature(%d) higher than PG value(%d)\n",
2274 				thermal_value, rtlefuse->eeprom_thermalmeter);
2275 
2276 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2277 				"****Enter POWER Tracking MIX_MODE****\n");
2278 			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2279 					rtl8821ae_dm_txpwr_track_set_pwr(hw,
2280 						MIX_MODE, p, index_for_channel);
2281 		} else {
2282 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2283 				"Temperature(%d) lower than PG value(%d)\n",
2284 				thermal_value, rtlefuse->eeprom_thermalmeter);
2285 
2286 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2287 				"*****Enter POWER Tracking MIX_MODE*****\n");
2288 			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2289 				rtl8812ae_dm_txpwr_track_set_pwr(hw,
2290 					MIX_MODE, p, index_for_channel);
2291 		}
2292 		/*Record last time Power Tracking result as base.*/
2293 		rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
2294 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2295 			rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p];
2296 
2297 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2298 			"pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
2299 			rtldm->thermalvalue, thermal_value);
2300 		/*Record last Power Tracking Thermal Value*/
2301 		rtldm->thermalvalue = thermal_value;
2302 	}
2303 	/* Delta temperature is equal to or larger than
2304 	 * 20 centigrade (When threshold is 8).
2305 	 */
2306 	if (delta_iqk >= IQK_THRESHOLD) {
2307 		if (!rtlphy->lck_inprogress) {
2308 			spin_lock(&rtlpriv->locks.iqk_lock);
2309 			rtlphy->lck_inprogress = true;
2310 			spin_unlock(&rtlpriv->locks.iqk_lock);
2311 
2312 			rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8);
2313 
2314 			spin_lock(&rtlpriv->locks.iqk_lock);
2315 			rtlphy->lck_inprogress = false;
2316 			spin_unlock(&rtlpriv->locks.iqk_lock);
2317 		}
2318 	}
2319 
2320 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__);
2321 }
2322 
rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw * hw)2323 void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw)
2324 {
2325 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2326 	if (!rtlpriv->dm.tm_trigger) {
2327 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16),
2328 			      0x03);
2329 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2330 			"Trigger 8821ae Thermal Meter!!\n");
2331 		rtlpriv->dm.tm_trigger = 1;
2332 		return;
2333 	} else {
2334 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2335 			"Schedule TxPowerTracking !!\n");
2336 
2337 		rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw);
2338 		rtlpriv->dm.tm_trigger = 0;
2339 	}
2340 }
2341 
rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw * hw)2342 static void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
2343 {
2344 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2345 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2346 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2347 	struct rate_adaptive *p_ra = &rtlpriv->ra;
2348 	u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
2349 	u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
2350 	u8 go_up_gap = 5;
2351 	struct ieee80211_sta *sta = NULL;
2352 
2353 	if (is_hal_stop(rtlhal)) {
2354 		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2355 			"driver is going to unload\n");
2356 		return;
2357 	}
2358 
2359 	if (!rtlpriv->dm.useramask) {
2360 		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2361 			"driver does not control rate adaptive mask\n");
2362 		return;
2363 	}
2364 
2365 	if (mac->link_state == MAC80211_LINKED &&
2366 		mac->opmode == NL80211_IFTYPE_STATION) {
2367 		switch (p_ra->pre_ratr_state) {
2368 		case DM_RATR_STA_MIDDLE:
2369 			high_rssithresh_for_ra += go_up_gap;
2370 			break;
2371 		case DM_RATR_STA_LOW:
2372 			high_rssithresh_for_ra += go_up_gap;
2373 			low_rssithresh_for_ra += go_up_gap;
2374 			break;
2375 		default:
2376 			break;
2377 		}
2378 
2379 		if (rtlpriv->dm.undec_sm_pwdb >
2380 		    (long)high_rssithresh_for_ra)
2381 			p_ra->ratr_state = DM_RATR_STA_HIGH;
2382 		else if (rtlpriv->dm.undec_sm_pwdb >
2383 			 (long)low_rssithresh_for_ra)
2384 			p_ra->ratr_state = DM_RATR_STA_MIDDLE;
2385 		else
2386 			p_ra->ratr_state = DM_RATR_STA_LOW;
2387 
2388 		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
2389 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2390 				"RSSI = %ld\n",
2391 				rtlpriv->dm.undec_sm_pwdb);
2392 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2393 				"RSSI_LEVEL = %d\n", p_ra->ratr_state);
2394 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2395 				"PreState = %d, CurState = %d\n",
2396 				p_ra->pre_ratr_state, p_ra->ratr_state);
2397 
2398 			rcu_read_lock();
2399 			sta = rtl_find_sta(hw, mac->bssid);
2400 			if (sta)
2401 				rtlpriv->cfg->ops->update_rate_tbl(hw,
2402 						sta, p_ra->ratr_state, true);
2403 			rcu_read_unlock();
2404 
2405 			p_ra->pre_ratr_state = p_ra->ratr_state;
2406 		}
2407 	}
2408 }
2409 
rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw * hw)2410 static void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw *hw)
2411 {
2412 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2413 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2414 	struct rtl_mac *mac = &rtlpriv->mac80211;
2415 	static u8 stage;
2416 	u8 cur_stage = 0;
2417 	u16 basic_rate = RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M | RRSR_6M;
2418 
2419 	if (mac->link_state < MAC80211_LINKED)
2420 		cur_stage = 0;
2421 	else if (dm_digtable->rssi_val_min < 25)
2422 		cur_stage = 1;
2423 	else if (dm_digtable->rssi_val_min > 30)
2424 		cur_stage = 3;
2425 	else
2426 		cur_stage = 2;
2427 
2428 	if (cur_stage != stage) {
2429 		if (cur_stage == 1) {
2430 			basic_rate &= (!(basic_rate ^ mac->basic_rates));
2431 			rtlpriv->cfg->ops->set_hw_reg(hw,
2432 				HW_VAR_BASIC_RATE, (u8 *)&basic_rate);
2433 		} else if (cur_stage == 3 && (stage == 1 || stage == 2)) {
2434 			rtlpriv->cfg->ops->set_hw_reg(hw,
2435 				HW_VAR_BASIC_RATE, (u8 *)&mac->basic_rates);
2436 		}
2437 	}
2438 	stage = cur_stage;
2439 }
2440 
rtl8821ae_dm_edca_choose_traffic_idx(struct ieee80211_hw * hw,u64 cur_tx_bytes,u64 cur_rx_bytes,bool b_bias_on_rx,bool * pb_is_cur_rdl_state)2441 static void rtl8821ae_dm_edca_choose_traffic_idx(
2442 	struct ieee80211_hw *hw, u64 cur_tx_bytes,
2443 	u64 cur_rx_bytes, bool b_bias_on_rx,
2444 	bool *pb_is_cur_rdl_state)
2445 {
2446 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2447 
2448 	if (b_bias_on_rx) {
2449 		if (cur_tx_bytes > (cur_rx_bytes*4)) {
2450 			*pb_is_cur_rdl_state = false;
2451 			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2452 				"Uplink Traffic\n");
2453 		} else {
2454 			*pb_is_cur_rdl_state = true;
2455 			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2456 				"Balance Traffic\n");
2457 		}
2458 	} else {
2459 		if (cur_rx_bytes > (cur_tx_bytes*4)) {
2460 			*pb_is_cur_rdl_state = true;
2461 			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2462 				"Downlink	Traffic\n");
2463 		} else {
2464 			*pb_is_cur_rdl_state = false;
2465 			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2466 				"Balance Traffic\n");
2467 		}
2468 	}
2469 	return;
2470 }
2471 
rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw * hw)2472 static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
2473 {
2474 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2475 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2476 	struct rtl_dm *rtldm =  rtl_dm(rtl_priv(hw));
2477 
2478 	/*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/
2479 	u64 cur_tx_ok_cnt = 0;
2480 	u64 cur_rx_ok_cnt = 0;
2481 	u32 edca_be_ul = 0x5ea42b;
2482 	u32 edca_be_dl = 0x5ea42b;
2483 	u32 edca_be = 0x5ea42b;
2484 	u8 iot_peer = 0;
2485 	bool *pb_is_cur_rdl_state = NULL;
2486 	bool b_bias_on_rx = false;
2487 	bool b_edca_turbo_on = false;
2488 
2489 	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2490 		"%s=====>\n", __func__);
2491 	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2492 		"Original BE PARAM: 0x%x\n",
2493 		rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N));
2494 
2495 	if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100)
2496 		rtlpriv->dm.is_any_nonbepkts = true;
2497 	rtlpriv->dm.dbginfo.num_non_be_pkt = 0;
2498 
2499 	/*===============================
2500 	 * list parameter for different platform
2501 	 *===============================
2502 	 */
2503 	pb_is_cur_rdl_state = &rtlpriv->dm.is_cur_rdlstate;
2504 
2505 	cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt;
2506 	cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt;
2507 
2508 	rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
2509 	rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
2510 
2511 	iot_peer = rtlpriv->mac80211.vendor;
2512 	b_bias_on_rx = false;
2513 	b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
2514 			   (!rtlpriv->dm.disable_framebursting)) ?
2515 			   true : false;
2516 
2517 	if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8812AE) {
2518 		if ((iot_peer == PEER_CISCO) &&
2519 			(mac->mode == WIRELESS_MODE_N_24G)) {
2520 			edca_be_dl = edca_setting_dl[iot_peer];
2521 			edca_be_ul = edca_setting_ul[iot_peer];
2522 		}
2523 	}
2524 
2525 	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2526 		"bIsAnyNonBEPkts : 0x%x  bDisableFrameBursting : 0x%x\n",
2527 		rtlpriv->dm.is_any_nonbepkts,
2528 		rtlpriv->dm.disable_framebursting);
2529 
2530 	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2531 		"bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",
2532 		b_edca_turbo_on, b_bias_on_rx);
2533 
2534 	if (b_edca_turbo_on) {
2535 		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2536 			"curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt);
2537 		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2538 			"curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt);
2539 		if (b_bias_on_rx)
2540 			rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
2541 				cur_rx_ok_cnt, true, pb_is_cur_rdl_state);
2542 		else
2543 			rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
2544 				cur_rx_ok_cnt, false, pb_is_cur_rdl_state);
2545 
2546 		edca_be = (*pb_is_cur_rdl_state) ?  edca_be_dl : edca_be_ul;
2547 
2548 		rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be);
2549 
2550 		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2551 			"EDCA Turbo on: EDCA_BE:0x%x\n", edca_be);
2552 
2553 		rtlpriv->dm.current_turbo_edca = true;
2554 
2555 		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2556 			"EDCA_BE_DL : 0x%x  EDCA_BE_UL : 0x%x  EDCA_BE : 0x%x\n",
2557 			edca_be_dl, edca_be_ul, edca_be);
2558 	} else {
2559 		if (rtlpriv->dm.current_turbo_edca) {
2560 			u8 tmp = AC0_BE;
2561 			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
2562 						      (u8 *)(&tmp));
2563 		}
2564 		rtlpriv->dm.current_turbo_edca = false;
2565 	}
2566 
2567 	rtlpriv->dm.is_any_nonbepkts = false;
2568 	rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
2569 	rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
2570 }
2571 
rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw * hw)2572 static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
2573 {
2574 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2575 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2576 	u8 cur_cck_cca_thresh;
2577 
2578 	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
2579 		if (dm_digtable->rssi_val_min > 25) {
2580 			cur_cck_cca_thresh = 0xcd;
2581 		} else if ((dm_digtable->rssi_val_min <= 25) &&
2582 			   (dm_digtable->rssi_val_min > 10)) {
2583 			cur_cck_cca_thresh = 0x83;
2584 		} else {
2585 			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
2586 				cur_cck_cca_thresh = 0x83;
2587 			else
2588 				cur_cck_cca_thresh = 0x40;
2589 		}
2590 	} else {
2591 		if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
2592 			cur_cck_cca_thresh = 0x83;
2593 		else
2594 			cur_cck_cca_thresh = 0x40;
2595 	}
2596 
2597 	if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh)
2598 		rtl_write_byte(rtlpriv, ODM_REG_CCK_CCA_11AC,
2599 			       cur_cck_cca_thresh);
2600 
2601 	dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
2602 	dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh;
2603 	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
2604 		"CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres);
2605 }
2606 
rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw * hw)2607 static void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
2608 {
2609 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2610 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2611 	u8 crystal_cap;
2612 	u32 packet_count;
2613 	int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
2614 	int cfo_ave_diff;
2615 
2616 	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
2617 		/*1.Enable ATC*/
2618 		if (rtldm->atc_status == ATC_STATUS_OFF) {
2619 			rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON);
2620 			rtldm->atc_status = ATC_STATUS_ON;
2621 		}
2622 
2623 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No link!!\n");
2624 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2625 			"atc_status = %d\n", rtldm->atc_status);
2626 
2627 		if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
2628 			rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
2629 			crystal_cap = rtldm->crystal_cap & 0x3f;
2630 			crystal_cap = crystal_cap & 0x3f;
2631 			if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE)
2632 				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2633 					      0x7ff80000, (crystal_cap |
2634 					      (crystal_cap << 6)));
2635 			else
2636 				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2637 					      0xfff000, (crystal_cap |
2638 					      (crystal_cap << 6)));
2639 		}
2640 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "crystal_cap = 0x%x\n",
2641 			rtldm->crystal_cap);
2642 	} else{
2643 		/*1. Calculate CFO for path-A & path-B*/
2644 		cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
2645 		cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
2646 		packet_count = rtldm->packet_count;
2647 
2648 		/*2.No new packet*/
2649 		if (packet_count == rtldm->packet_count_pre) {
2650 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2651 				"packet counter doesn't change\n");
2652 			return;
2653 		}
2654 
2655 		rtldm->packet_count_pre = packet_count;
2656 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2657 			"packet counter = %d\n",
2658 			rtldm->packet_count);
2659 
2660 		/*3.Average CFO*/
2661 		if (rtlpriv->phy.rf_type == RF_1T1R)
2662 			cfo_ave = cfo_khz_a;
2663 		else
2664 			cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1;
2665 
2666 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2667 			"cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n",
2668 			cfo_khz_a, cfo_khz_b, cfo_ave);
2669 
2670 		/*4.Avoid abnormal large CFO*/
2671 		cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
2672 						(rtldm->cfo_ave_pre - cfo_ave) :
2673 						(cfo_ave - rtldm->cfo_ave_pre);
2674 
2675 		if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) {
2676 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2677 				"first large CFO hit\n");
2678 			rtldm->large_cfo_hit = true;
2679 			return;
2680 		} else
2681 			rtldm->large_cfo_hit = false;
2682 
2683 		rtldm->cfo_ave_pre = cfo_ave;
2684 
2685 		/*CFO tracking by adjusting Xtal cap.*/
2686 
2687 		/*1.Dynamic Xtal threshold*/
2688 		if (cfo_ave >= -rtldm->cfo_threshold &&
2689 			cfo_ave <= rtldm->cfo_threshold &&
2690 			rtldm->is_freeze == 0) {
2691 			if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
2692 				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
2693 				rtldm->is_freeze = 1;
2694 			} else {
2695 				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
2696 			}
2697 		}
2698 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2699 			"Dynamic threshold = %d\n",
2700 			rtldm->cfo_threshold);
2701 
2702 		/* 2.Calculate Xtal offset*/
2703 		if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
2704 			adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
2705 		else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
2706 			 rtlpriv->dm.crystal_cap > 0)
2707 			adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
2708 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2709 			"Crystal cap = 0x%x, Crystal cap offset = %d\n",
2710 			rtldm->crystal_cap, adjust_xtal);
2711 
2712 		/*3.Adjudt Crystal Cap.*/
2713 		if (adjust_xtal != 0) {
2714 			rtldm->is_freeze = 0;
2715 			rtldm->crystal_cap += adjust_xtal;
2716 
2717 			if (rtldm->crystal_cap > 0x3f)
2718 				rtldm->crystal_cap = 0x3f;
2719 			else if (rtldm->crystal_cap < 0)
2720 				rtldm->crystal_cap = 0;
2721 
2722 			crystal_cap = rtldm->crystal_cap & 0x3f;
2723 			crystal_cap = crystal_cap & 0x3f;
2724 			if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE)
2725 				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2726 					      0x7ff80000, (crystal_cap |
2727 					      (crystal_cap << 6)));
2728 			else
2729 				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2730 					      0xfff000, (crystal_cap |
2731 					      (crystal_cap << 6)));
2732 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2733 				"New crystal cap = 0x%x\n",
2734 				rtldm->crystal_cap);
2735 		}
2736 	}
2737 }
2738 
rtl8821ae_dm_watchdog(struct ieee80211_hw * hw)2739 void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw)
2740 {
2741 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2742 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2743 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2744 	bool fw_current_inpsmode = false;
2745 	bool fw_ps_awake = true;
2746 
2747 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
2748 				      (u8 *)(&fw_current_inpsmode));
2749 
2750 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
2751 				      (u8 *)(&fw_ps_awake));
2752 
2753 	if (ppsc->p2p_ps_info.p2p_ps_mode)
2754 		fw_ps_awake = false;
2755 
2756 	spin_lock(&rtlpriv->locks.rf_ps_lock);
2757 	if ((ppsc->rfpwr_state == ERFON) &&
2758 	    ((!fw_current_inpsmode) && fw_ps_awake) &&
2759 	    (!ppsc->rfchange_inprogress)) {
2760 		rtl8821ae_dm_common_info_self_update(hw);
2761 		rtl8821ae_dm_false_alarm_counter_statistics(hw);
2762 		rtl8821ae_dm_check_rssi_monitor(hw);
2763 		rtl8821ae_dm_dig(hw);
2764 		rtl8821ae_dm_cck_packet_detection_thresh(hw);
2765 		rtl8821ae_dm_refresh_rate_adaptive_mask(hw);
2766 		rtl8821ae_dm_refresh_basic_rate_mask(hw);
2767 		rtl8821ae_dm_check_edca_turbo(hw);
2768 		rtl8821ae_dm_dynamic_atc_switch(hw);
2769 		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
2770 			rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw);
2771 		else
2772 			rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw);
2773 		rtl8821ae_dm_iq_calibrate(hw);
2774 	}
2775 	spin_unlock(&rtlpriv->locks.rf_ps_lock);
2776 
2777 	rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
2778 	rtl_dbg(rtlpriv, COMP_DIG, DBG_DMESG, "\n");
2779 }
2780 
rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw * hw,u8 * pdesc,u32 mac_id)2781 void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
2782 					u8 *pdesc, u32 mac_id)
2783 {
2784 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2785 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2786 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2787 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
2788 	__le32 *pdesc32 = (__le32 *)pdesc;
2789 
2790 	if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE)
2791 		return;
2792 
2793 	if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
2794 		set_tx_desc_tx_ant(pdesc32, pfat_table->antsel_a[mac_id]);
2795 }
2796