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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 			if (dm_digtable->rssi_val_min <= dig_max_of_min)
760 				current_igi = dm_digtable->rssi_val_min;
761 			else
762 				current_igi = dig_max_of_min;
763 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
764 				"First Connect\n");
765 		} else {
766 			if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
767 				current_igi = current_igi + 4;
768 			else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
769 				current_igi = current_igi + 2;
770 			else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
771 				current_igi = current_igi - 2;
772 
773 			if ((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) &&
774 			    (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) {
775 				current_igi = dm_digtable->rx_gain_min;
776 				rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
777 					"Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n");
778 			}
779 		}
780 	} else {
781 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
782 			"DIG BeforeLink\n");
783 		if (first_disconnect) {
784 			current_igi = dm_digtable->rx_gain_min;
785 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
786 				"First DisConnect\n");
787 		} else {
788 			/* 2012.03.30 LukeLee: enable DIG before
789 			 * link but with very high thresholds
790 			 */
791 			if (rtlpriv->falsealm_cnt.cnt_all > 2000)
792 				current_igi = current_igi + 4;
793 			else if (rtlpriv->falsealm_cnt.cnt_all > 600)
794 				current_igi = current_igi + 2;
795 			else if (rtlpriv->falsealm_cnt.cnt_all < 300)
796 				current_igi = current_igi - 2;
797 
798 			if (current_igi >= 0x3e)
799 				current_igi = 0x3e;
800 
801 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "England DIG\n");
802 		}
803 	}
804 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
805 		"DIG End Adjust IGI\n");
806 	/* Check initial gain by upper/lower bound*/
807 
808 	if (current_igi > dm_digtable->rx_gain_max)
809 		current_igi = dm_digtable->rx_gain_max;
810 	if (current_igi < dm_digtable->rx_gain_min)
811 		current_igi = dm_digtable->rx_gain_min;
812 
813 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
814 		"rx_gain_max=0x%x, rx_gain_min=0x%x\n",
815 		dm_digtable->rx_gain_max, dm_digtable->rx_gain_min);
816 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
817 		"TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all);
818 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
819 		"CurIGValue=0x%x\n", current_igi);
820 
821 	rtl8821ae_dm_write_dig(hw, current_igi);
822 	dm_digtable->media_connect_0 =
823 		((mac->link_state >= MAC80211_LINKED) ? true : false);
824 	dm_digtable->dig_min_0 = dig_min_0;
825 }
826 
827 static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw)
828 {
829 	struct rtl_priv *rtlpriv = rtl_priv(hw);
830 	u8 cnt;
831 
832 	rtlpriv->dm.tx_rate = 0xff;
833 
834 	rtlpriv->dm.one_entry_only = false;
835 
836 	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
837 	    rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
838 		rtlpriv->dm.one_entry_only = true;
839 		return;
840 	}
841 
842 	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
843 	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
844 	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
845 		spin_lock_bh(&rtlpriv->locks.entry_list_lock);
846 		cnt = list_count_nodes(&rtlpriv->entry_list);
847 		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
848 
849 		if (cnt == 1)
850 			rtlpriv->dm.one_entry_only = true;
851 	}
852 }
853 
854 static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
855 {
856 	struct rtl_priv *rtlpriv = rtl_priv(hw);
857 	struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
858 	u32 cck_enable = 0;
859 
860 	/*read OFDM FA counter*/
861 	falsealm_cnt->cnt_ofdm_fail =
862 		rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD);
863 	falsealm_cnt->cnt_cck_fail =
864 		rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD);
865 
866 	cck_enable =  rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28));
867 	if (cck_enable)  /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/
868 		falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
869 					falsealm_cnt->cnt_cck_fail;
870 	else
871 		falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail;
872 
873 	/*reset OFDM FA counter*/
874 	rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
875 	rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
876 	/* reset CCK FA counter*/
877 	rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
878 	rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
879 
880 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Cnt_Cck_fail=%d\n",
881 		falsealm_cnt->cnt_cck_fail);
882 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "cnt_ofdm_fail=%d\n",
883 		falsealm_cnt->cnt_ofdm_fail);
884 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Total False Alarm=%d\n",
885 		falsealm_cnt->cnt_all);
886 }
887 
888 static void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
889 		struct ieee80211_hw *hw)
890 {
891 	struct rtl_priv *rtlpriv = rtl_priv(hw);
892 
893 	if (!rtlpriv->dm.tm_trigger) {
894 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E,
895 			      BIT(17) | BIT(16), 0x03);
896 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
897 			"Trigger 8812 Thermal Meter!!\n");
898 		rtlpriv->dm.tm_trigger = 1;
899 		return;
900 	}
901 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
902 		"Schedule TxPowerTracking direct call!!\n");
903 	rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw);
904 }
905 
906 static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw)
907 {
908 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
909 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
910 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
911 
912 	if (mac->link_state >= MAC80211_LINKED) {
913 		if (rtldm->linked_interval < 3)
914 			rtldm->linked_interval++;
915 
916 		if (rtldm->linked_interval == 2) {
917 			if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
918 				rtl8812ae_phy_iq_calibrate(hw, false);
919 			else
920 				rtl8821ae_phy_iq_calibrate(hw, false);
921 		}
922 	} else {
923 		rtldm->linked_interval = 0;
924 	}
925 }
926 
927 static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw,
928 					    const u8 **up_a,
929 					    const u8 **down_a,
930 					    const u8 **up_b,
931 					    const u8 **down_b)
932 {
933 	struct rtl_priv *rtlpriv = rtl_priv(hw);
934 	struct rtl_phy *rtlphy = &rtlpriv->phy;
935 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
936 	u8 channel = rtlphy->current_channel;
937 	u8 rate = rtldm->tx_rate;
938 
939 	if (1 <= channel && channel <= 14) {
940 		if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
941 			*up_a = rtl8812ae_delta_swing_table_idx_24gccka_p;
942 			*down_a = rtl8812ae_delta_swing_table_idx_24gccka_n;
943 			*up_b = rtl8812ae_delta_swing_table_idx_24gcckb_p;
944 			*down_b = rtl8812ae_delta_swing_table_idx_24gcckb_n;
945 		} else {
946 			*up_a = rtl8812ae_delta_swing_table_idx_24ga_p;
947 			*down_a = rtl8812ae_delta_swing_table_idx_24ga_n;
948 			*up_b = rtl8812ae_delta_swing_table_idx_24gb_p;
949 			*down_b = rtl8812ae_delta_swing_table_idx_24gb_n;
950 		}
951 	} else if (36 <= channel && channel <= 64) {
952 		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[0];
953 		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[0];
954 		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[0];
955 		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[0];
956 	} else if (100 <= channel && channel <= 140) {
957 		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[1];
958 		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[1];
959 		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[1];
960 		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[1];
961 	} else if (149 <= channel && channel <= 173) {
962 		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[2];
963 		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[2];
964 		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2];
965 		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2];
966 	} else {
967 		*up_a = rtl8818e_delta_swing_table_idx_24gb_p;
968 		*down_a = rtl8818e_delta_swing_table_idx_24gb_n;
969 		*up_b = rtl8818e_delta_swing_table_idx_24gb_p;
970 		*down_b = rtl8818e_delta_swing_table_idx_24gb_n;
971 	}
972 }
973 
974 void rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate)
975 {
976 	struct rtl_priv *rtlpriv = rtl_priv(hw);
977 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
978 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
979 	u8 p = 0;
980 
981 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
982 		"Get C2H Command! Rate=0x%x\n", rate);
983 
984 	rtldm->tx_rate = rate;
985 
986 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
987 		rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0);
988 	} else {
989 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
990 			rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0);
991 	}
992 }
993 
994 u8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate)
995 {
996 	struct rtl_priv *rtlpriv = rtl_priv(hw);
997 	u8 ret_rate = MGN_1M;
998 
999 	switch (rate) {
1000 	case DESC_RATE1M:
1001 		ret_rate = MGN_1M;
1002 		break;
1003 	case DESC_RATE2M:
1004 		ret_rate = MGN_2M;
1005 		break;
1006 	case DESC_RATE5_5M:
1007 		ret_rate = MGN_5_5M;
1008 		break;
1009 	case DESC_RATE11M:
1010 		ret_rate = MGN_11M;
1011 		break;
1012 	case DESC_RATE6M:
1013 		ret_rate = MGN_6M;
1014 		break;
1015 	case DESC_RATE9M:
1016 		ret_rate = MGN_9M;
1017 		break;
1018 	case DESC_RATE12M:
1019 		ret_rate = MGN_12M;
1020 		break;
1021 	case DESC_RATE18M:
1022 		ret_rate = MGN_18M;
1023 		break;
1024 	case DESC_RATE24M:
1025 		ret_rate = MGN_24M;
1026 		break;
1027 	case DESC_RATE36M:
1028 		ret_rate = MGN_36M;
1029 		break;
1030 	case DESC_RATE48M:
1031 		ret_rate = MGN_48M;
1032 		break;
1033 	case DESC_RATE54M:
1034 		ret_rate = MGN_54M;
1035 		break;
1036 	case DESC_RATEMCS0:
1037 		ret_rate = MGN_MCS0;
1038 		break;
1039 	case DESC_RATEMCS1:
1040 		ret_rate = MGN_MCS1;
1041 		break;
1042 	case DESC_RATEMCS2:
1043 		ret_rate = MGN_MCS2;
1044 		break;
1045 	case DESC_RATEMCS3:
1046 		ret_rate = MGN_MCS3;
1047 		break;
1048 	case DESC_RATEMCS4:
1049 		ret_rate = MGN_MCS4;
1050 		break;
1051 	case DESC_RATEMCS5:
1052 		ret_rate = MGN_MCS5;
1053 		break;
1054 	case DESC_RATEMCS6:
1055 		ret_rate = MGN_MCS6;
1056 		break;
1057 	case DESC_RATEMCS7:
1058 		ret_rate = MGN_MCS7;
1059 		break;
1060 	case DESC_RATEMCS8:
1061 		ret_rate = MGN_MCS8;
1062 		break;
1063 	case DESC_RATEMCS9:
1064 		ret_rate = MGN_MCS9;
1065 		break;
1066 	case DESC_RATEMCS10:
1067 		ret_rate = MGN_MCS10;
1068 		break;
1069 	case DESC_RATEMCS11:
1070 		ret_rate = MGN_MCS11;
1071 		break;
1072 	case DESC_RATEMCS12:
1073 		ret_rate = MGN_MCS12;
1074 		break;
1075 	case DESC_RATEMCS13:
1076 		ret_rate = MGN_MCS13;
1077 		break;
1078 	case DESC_RATEMCS14:
1079 		ret_rate = MGN_MCS14;
1080 		break;
1081 	case DESC_RATEMCS15:
1082 		ret_rate = MGN_MCS15;
1083 		break;
1084 	case DESC_RATEVHT1SS_MCS0:
1085 		ret_rate = MGN_VHT1SS_MCS0;
1086 		break;
1087 	case DESC_RATEVHT1SS_MCS1:
1088 		ret_rate = MGN_VHT1SS_MCS1;
1089 		break;
1090 	case DESC_RATEVHT1SS_MCS2:
1091 		ret_rate = MGN_VHT1SS_MCS2;
1092 		break;
1093 	case DESC_RATEVHT1SS_MCS3:
1094 		ret_rate = MGN_VHT1SS_MCS3;
1095 		break;
1096 	case DESC_RATEVHT1SS_MCS4:
1097 		ret_rate = MGN_VHT1SS_MCS4;
1098 		break;
1099 	case DESC_RATEVHT1SS_MCS5:
1100 		ret_rate = MGN_VHT1SS_MCS5;
1101 		break;
1102 	case DESC_RATEVHT1SS_MCS6:
1103 		ret_rate = MGN_VHT1SS_MCS6;
1104 		break;
1105 	case DESC_RATEVHT1SS_MCS7:
1106 		ret_rate = MGN_VHT1SS_MCS7;
1107 		break;
1108 	case DESC_RATEVHT1SS_MCS8:
1109 		ret_rate = MGN_VHT1SS_MCS8;
1110 		break;
1111 	case DESC_RATEVHT1SS_MCS9:
1112 		ret_rate = MGN_VHT1SS_MCS9;
1113 		break;
1114 	case DESC_RATEVHT2SS_MCS0:
1115 		ret_rate = MGN_VHT2SS_MCS0;
1116 		break;
1117 	case DESC_RATEVHT2SS_MCS1:
1118 		ret_rate = MGN_VHT2SS_MCS1;
1119 		break;
1120 	case DESC_RATEVHT2SS_MCS2:
1121 		ret_rate = MGN_VHT2SS_MCS2;
1122 		break;
1123 	case DESC_RATEVHT2SS_MCS3:
1124 		ret_rate = MGN_VHT2SS_MCS3;
1125 		break;
1126 	case DESC_RATEVHT2SS_MCS4:
1127 		ret_rate = MGN_VHT2SS_MCS4;
1128 		break;
1129 	case DESC_RATEVHT2SS_MCS5:
1130 		ret_rate = MGN_VHT2SS_MCS5;
1131 		break;
1132 	case DESC_RATEVHT2SS_MCS6:
1133 		ret_rate = MGN_VHT2SS_MCS6;
1134 		break;
1135 	case DESC_RATEVHT2SS_MCS7:
1136 		ret_rate = MGN_VHT2SS_MCS7;
1137 		break;
1138 	case DESC_RATEVHT2SS_MCS8:
1139 		ret_rate = MGN_VHT2SS_MCS8;
1140 		break;
1141 	case DESC_RATEVHT2SS_MCS9:
1142 		ret_rate = MGN_VHT2SS_MCS9;
1143 		break;
1144 	default:
1145 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1146 			"HwRateToMRate8812(): Non supported Rate [%x]!!!\n",
1147 			rate);
1148 		break;
1149 	}
1150 	return ret_rate;
1151 }
1152 
1153 /*-----------------------------------------------------------------------------
1154  * Function:	odm_TxPwrTrackSetPwr88E()
1155  *
1156  * Overview:	88E change all channel tx power accordign to flag.
1157  *				OFDM & CCK are all different.
1158  *
1159  * Input:		NONE
1160  *
1161  * Output:		NONE
1162  *
1163  * Return:		NONE
1164  *
1165  * Revised History:
1166  *	When		Who		Remark
1167  *	04/23/2012	MHC		Create Version 0.
1168  *
1169  *---------------------------------------------------------------------------
1170  */
1171 void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
1172 				      enum pwr_track_control_method method,
1173 				      u8 rf_path, u8 channel_mapped_index)
1174 {
1175 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1176 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
1177 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1178 	u32 final_swing_idx[2];
1179 	u8 pwr_tracking_limit = 26; /*+1.0dB*/
1180 	u8 tx_rate = 0xFF;
1181 	s8 final_ofdm_swing_index = 0;
1182 
1183 	if (rtldm->tx_rate != 0xFF)
1184 		tx_rate =
1185 			rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
1186 
1187 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1188 		"===>%s\n", __func__);
1189 	/*20130429 Mimic Modify High Rate BBSwing Limit.*/
1190 	if (tx_rate != 0xFF) {
1191 		/*CCK*/
1192 		if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
1193 			pwr_tracking_limit = 32; /*+4dB*/
1194 		/*OFDM*/
1195 		else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
1196 			pwr_tracking_limit = 30; /*+3dB*/
1197 		else if (tx_rate == MGN_54M)
1198 			pwr_tracking_limit = 28; /*+2dB*/
1199 		/*HT*/
1200 		 /*QPSK/BPSK*/
1201 		else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2))
1202 			pwr_tracking_limit = 34; /*+5dB*/
1203 		 /*16QAM*/
1204 		else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4))
1205 			pwr_tracking_limit = 30; /*+3dB*/
1206 		 /*64QAM*/
1207 		else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7))
1208 			pwr_tracking_limit = 28; /*+2dB*/
1209 		 /*QPSK/BPSK*/
1210 		else if ((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10))
1211 			pwr_tracking_limit = 34; /*+5dB*/
1212 		 /*16QAM*/
1213 		else if ((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12))
1214 			pwr_tracking_limit = 30; /*+3dB*/
1215 		 /*64QAM*/
1216 		else if ((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15))
1217 			pwr_tracking_limit = 28; /*+2dB*/
1218 
1219 		/*2 VHT*/
1220 		 /*QPSK/BPSK*/
1221 		else if ((tx_rate >= MGN_VHT1SS_MCS0) &&
1222 			 (tx_rate <= MGN_VHT1SS_MCS2))
1223 			pwr_tracking_limit = 34; /*+5dB*/
1224 		 /*16QAM*/
1225 		else if ((tx_rate >= MGN_VHT1SS_MCS3) &&
1226 			 (tx_rate <= MGN_VHT1SS_MCS4))
1227 			pwr_tracking_limit = 30; /*+3dB*/
1228 		 /*64QAM*/
1229 		else if ((tx_rate >= MGN_VHT1SS_MCS5) &&
1230 			 (tx_rate <= MGN_VHT1SS_MCS6))
1231 			pwr_tracking_limit = 28; /*+2dB*/
1232 		else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
1233 			pwr_tracking_limit = 26; /*+1dB*/
1234 		else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
1235 			pwr_tracking_limit = 24; /*+0dB*/
1236 		else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
1237 			pwr_tracking_limit = 22; /*-1dB*/
1238 		 /*QPSK/BPSK*/
1239 		else if ((tx_rate >= MGN_VHT2SS_MCS0) &&
1240 			 (tx_rate <= MGN_VHT2SS_MCS2))
1241 			pwr_tracking_limit = 34; /*+5dB*/
1242 		 /*16QAM*/
1243 		else if ((tx_rate >= MGN_VHT2SS_MCS3) &&
1244 			 (tx_rate <= MGN_VHT2SS_MCS4))
1245 			pwr_tracking_limit = 30; /*+3dB*/
1246 		 /*64QAM*/
1247 		else if ((tx_rate >= MGN_VHT2SS_MCS5) &&
1248 			 (tx_rate <= MGN_VHT2SS_MCS6))
1249 			pwr_tracking_limit = 28; /*+2dB*/
1250 		else if (tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/
1251 			pwr_tracking_limit = 26; /*+1dB*/
1252 		else if (tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/
1253 			pwr_tracking_limit = 24; /*+0dB*/
1254 		else if (tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/
1255 			pwr_tracking_limit = 22; /*-1dB*/
1256 		else
1257 			pwr_tracking_limit = 24;
1258 	}
1259 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1260 		"TxRate=0x%x, PwrTrackingLimit=%d\n",
1261 		tx_rate, pwr_tracking_limit);
1262 
1263 	if (method == BBSWING) {
1264 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1265 			"===>%s\n", __func__);
1266 
1267 		if (rf_path == RF90_PATH_A) {
1268 			u32 tmp;
1269 
1270 			final_swing_idx[RF90_PATH_A] =
1271 				(rtldm->ofdm_index[RF90_PATH_A] >
1272 				pwr_tracking_limit) ?
1273 				pwr_tracking_limit :
1274 				rtldm->ofdm_index[RF90_PATH_A];
1275 			tmp = final_swing_idx[RF90_PATH_A];
1276 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1277 				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
1278 				rtldm->ofdm_index[RF90_PATH_A],
1279 				final_swing_idx[RF90_PATH_A]);
1280 
1281 			rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1282 				      txscaling_tbl[tmp]);
1283 		} else {
1284 			u32 tmp;
1285 
1286 			final_swing_idx[RF90_PATH_B] =
1287 				rtldm->ofdm_index[RF90_PATH_B] >
1288 				pwr_tracking_limit ?
1289 				pwr_tracking_limit :
1290 				rtldm->ofdm_index[RF90_PATH_B];
1291 			tmp = final_swing_idx[RF90_PATH_B];
1292 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1293 				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n",
1294 				rtldm->ofdm_index[RF90_PATH_B],
1295 				final_swing_idx[RF90_PATH_B]);
1296 
1297 			rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1298 				      txscaling_tbl[tmp]);
1299 		}
1300 	} else if (method == MIX_MODE) {
1301 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1302 			"pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
1303 			rtldm->default_ofdm_index,
1304 			rtldm->absolute_ofdm_swing_idx[rf_path],
1305 			rf_path);
1306 
1307 		final_ofdm_swing_index = rtldm->default_ofdm_index +
1308 				rtldm->absolute_ofdm_swing_idx[rf_path];
1309 
1310 		if (rf_path == RF90_PATH_A) {
1311 			/*BBSwing higher then Limit*/
1312 			if (final_ofdm_swing_index > pwr_tracking_limit) {
1313 				rtldm->remnant_cck_idx =
1314 					final_ofdm_swing_index -
1315 					pwr_tracking_limit;
1316 				/* CCK Follow the same compensation value
1317 				 * as Path A
1318 				 */
1319 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1320 					final_ofdm_swing_index -
1321 					pwr_tracking_limit;
1322 
1323 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1324 					      txscaling_tbl[pwr_tracking_limit]);
1325 
1326 				rtldm->modify_txagc_flag_path_a = true;
1327 
1328 				/*Set TxAGC Page C{};*/
1329 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1330 					rtlphy->current_channel,
1331 					RF90_PATH_A);
1332 
1333 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1334 					"******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n",
1335 					pwr_tracking_limit,
1336 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1337 			} else if (final_ofdm_swing_index < 0) {
1338 				rtldm->remnant_cck_idx = final_ofdm_swing_index;
1339 				/* CCK Follow the same compensate value as Path A*/
1340 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1341 					final_ofdm_swing_index;
1342 
1343 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1344 					txscaling_tbl[0]);
1345 
1346 				rtldm->modify_txagc_flag_path_a = true;
1347 
1348 				/*Set TxAGC Page C{};*/
1349 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1350 					rtlphy->current_channel, RF90_PATH_A);
1351 
1352 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1353 					"******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
1354 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1355 			} else {
1356 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1357 					txscaling_tbl[(u8)final_ofdm_swing_index]);
1358 
1359 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1360 					"******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n",
1361 					final_ofdm_swing_index);
1362 				/*If TxAGC has changed, reset TxAGC again*/
1363 				if (rtldm->modify_txagc_flag_path_a) {
1364 					rtldm->remnant_cck_idx = 0;
1365 					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1366 
1367 					/*Set TxAGC Page C{};*/
1368 					rtl8821ae_phy_set_txpower_level_by_path(hw,
1369 						rtlphy->current_channel, RF90_PATH_A);
1370 					rtldm->modify_txagc_flag_path_a = false;
1371 
1372 					rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
1373 						DBG_LOUD,
1374 						"******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1375 				}
1376 			}
1377 		}
1378 		/*BBSwing higher then Limit*/
1379 		if (rf_path == RF90_PATH_B) {
1380 			if (final_ofdm_swing_index > pwr_tracking_limit) {
1381 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1382 					final_ofdm_swing_index -
1383 					pwr_tracking_limit;
1384 
1385 				rtl_set_bbreg(hw, RB_TXSCALE,
1386 					0xFFE00000,
1387 					txscaling_tbl[pwr_tracking_limit]);
1388 
1389 				rtldm->modify_txagc_flag_path_b = true;
1390 
1391 				/*Set TxAGC Page E{};*/
1392 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1393 					rtlphy->current_channel, RF90_PATH_B);
1394 
1395 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1396 					"******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
1397 					pwr_tracking_limit,
1398 					 rtldm->remnant_ofdm_swing_idx[rf_path]);
1399 			} else if (final_ofdm_swing_index < 0) {
1400 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1401 					final_ofdm_swing_index;
1402 
1403 				rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1404 					      txscaling_tbl[0]);
1405 
1406 				rtldm->modify_txagc_flag_path_b = true;
1407 
1408 				/*Set TxAGC Page E{};*/
1409 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1410 					rtlphy->current_channel, RF90_PATH_B);
1411 
1412 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1413 					"******Path_B Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
1414 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1415 			} else {
1416 				rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1417 					txscaling_tbl[(u8)final_ofdm_swing_index]);
1418 
1419 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1420 					"******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
1421 					final_ofdm_swing_index);
1422 				 /*If TxAGC has changed, reset TxAGC again*/
1423 				if (rtldm->modify_txagc_flag_path_b) {
1424 					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1425 
1426 					/*Set TxAGC Page E{};*/
1427 					rtl8821ae_phy_set_txpower_level_by_path(hw,
1428 					rtlphy->current_channel, RF90_PATH_B);
1429 
1430 					rtldm->modify_txagc_flag_path_b =
1431 						false;
1432 
1433 					rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1434 						"******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1435 				}
1436 			}
1437 		}
1438 	} else {
1439 		return;
1440 	}
1441 }
1442 
1443 void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(
1444 	struct ieee80211_hw *hw)
1445 {
1446 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1447 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1448 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
1449 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1450 	u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
1451 	u8 thermal_value_avg_count = 0;
1452 	u32 thermal_value_avg = 0;
1453 	/* OFDM BB Swing should be less than +3.0dB, */
1454 	u8 ofdm_min_index = 6;
1455 	 /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
1456 	u8 index_for_channel = 0;
1457 	/* 1. The following TWO tables decide
1458 	 * the final index of OFDM/CCK swing table.
1459 	 */
1460 	const u8 *delta_swing_table_idx_tup_a;
1461 	const u8 *delta_swing_table_idx_tdown_a;
1462 	const u8 *delta_swing_table_idx_tup_b;
1463 	const u8 *delta_swing_table_idx_tdown_b;
1464 
1465 	/*2. Initialization ( 7 steps in total )*/
1466 	rtl8812ae_get_delta_swing_table(hw,
1467 		&delta_swing_table_idx_tup_a,
1468 		&delta_swing_table_idx_tdown_a,
1469 		&delta_swing_table_idx_tup_b,
1470 		&delta_swing_table_idx_tdown_b);
1471 
1472 	rtldm->txpower_trackinginit = true;
1473 
1474 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1475 		"pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
1476 		rtldm->swing_idx_cck_base,
1477 		rtldm->swing_idx_ofdm_base[RF90_PATH_A],
1478 		rtldm->default_ofdm_index);
1479 
1480 	thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A,
1481 		/*0x42: RF Reg[15:10] 88E*/
1482 		RF_T_METER_8812A, 0xfc00);
1483 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1484 		"Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1485 		thermal_value, rtlefuse->eeprom_thermalmeter);
1486 	if (!rtldm->txpower_track_control ||
1487 	    rtlefuse->eeprom_thermalmeter == 0 ||
1488 	    rtlefuse->eeprom_thermalmeter == 0xFF)
1489 		return;
1490 
1491 	/* 3. Initialize ThermalValues of RFCalibrateInfo*/
1492 
1493 	if (rtlhal->reloadtxpowerindex)
1494 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1495 			"reload ofdm index for band switch\n");
1496 
1497 	/*4. Calculate average thermal meter*/
1498 	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
1499 	rtldm->thermalvalue_avg_index++;
1500 	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
1501 		/*Average times =  c.AverageThermalNum*/
1502 		rtldm->thermalvalue_avg_index = 0;
1503 
1504 	for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) {
1505 		if (rtldm->thermalvalue_avg[i]) {
1506 			thermal_value_avg += rtldm->thermalvalue_avg[i];
1507 			thermal_value_avg_count++;
1508 		}
1509 	}
1510 	/*Calculate Average ThermalValue after average enough times*/
1511 	if (thermal_value_avg_count) {
1512 		thermal_value = (u8)(thermal_value_avg /
1513 				thermal_value_avg_count);
1514 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1515 			"AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1516 			thermal_value, rtlefuse->eeprom_thermalmeter);
1517 	}
1518 
1519 	/*5. Calculate delta, delta_LCK, delta_IQK.
1520 	 *"delta" here is used to determine whether
1521 	 *thermal value changes or not.
1522 	 */
1523 	delta = (thermal_value > rtldm->thermalvalue) ?
1524 		(thermal_value - rtldm->thermalvalue) :
1525 		(rtldm->thermalvalue - thermal_value);
1526 	delta_lck = (thermal_value > rtldm->thermalvalue_lck) ?
1527 		(thermal_value - rtldm->thermalvalue_lck) :
1528 		(rtldm->thermalvalue_lck - thermal_value);
1529 	delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ?
1530 		(thermal_value - rtldm->thermalvalue_iqk) :
1531 		(rtldm->thermalvalue_iqk - thermal_value);
1532 
1533 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1534 		"(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
1535 		delta, delta_lck, delta_iqk);
1536 
1537 	/* 6. If necessary, do LCK.
1538 	 * Delta temperature is equal to or larger than 20 centigrade.
1539 	 */
1540 	if (delta_lck >= IQK_THRESHOLD) {
1541 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1542 			"delta_LCK(%d) >= Threshold_IQK(%d)\n",
1543 			delta_lck, IQK_THRESHOLD);
1544 		rtldm->thermalvalue_lck = thermal_value;
1545 		rtl8821ae_phy_lc_calibrate(hw);
1546 	}
1547 
1548 	/*7. If necessary, move the index of swing table to adjust Tx power.*/
1549 
1550 	if (delta > 0 && rtldm->txpower_track_control) {
1551 		/* "delta" here is used to record the
1552 		 * absolute value of differrence.
1553 		 */
1554 		delta = thermal_value > rtlefuse->eeprom_thermalmeter ?
1555 			(thermal_value - rtlefuse->eeprom_thermalmeter) :
1556 			(rtlefuse->eeprom_thermalmeter - thermal_value);
1557 
1558 		if (delta >= TXPWR_TRACK_TABLE_SIZE)
1559 			delta = TXPWR_TRACK_TABLE_SIZE - 1;
1560 
1561 		/*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
1562 
1563 		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
1564 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1565 				"delta_swing_table_idx_tup_a[%d] = %d\n",
1566 				delta, delta_swing_table_idx_tup_a[delta]);
1567 			rtldm->delta_power_index_last[RF90_PATH_A] =
1568 				rtldm->delta_power_index[RF90_PATH_A];
1569 			rtldm->delta_power_index[RF90_PATH_A] =
1570 				delta_swing_table_idx_tup_a[delta];
1571 
1572 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
1573 				delta_swing_table_idx_tup_a[delta];
1574 			/*Record delta swing for mix mode power tracking*/
1575 
1576 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1577 				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1578 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
1579 
1580 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1581 				"delta_swing_table_idx_tup_b[%d] = %d\n",
1582 				delta, delta_swing_table_idx_tup_b[delta]);
1583 			rtldm->delta_power_index_last[RF90_PATH_B] =
1584 				rtldm->delta_power_index[RF90_PATH_B];
1585 			rtldm->delta_power_index[RF90_PATH_B] =
1586 				delta_swing_table_idx_tup_b[delta];
1587 
1588 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] =
1589 				delta_swing_table_idx_tup_b[delta];
1590 			/*Record delta swing for mix mode power tracking*/
1591 
1592 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1593 				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1594 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]);
1595 		} else {
1596 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1597 				"delta_swing_table_idx_tdown_a[%d] = %d\n",
1598 				delta, delta_swing_table_idx_tdown_a[delta]);
1599 
1600 			rtldm->delta_power_index_last[RF90_PATH_A] =
1601 				rtldm->delta_power_index[RF90_PATH_A];
1602 			rtldm->delta_power_index[RF90_PATH_A] =
1603 				-1 * delta_swing_table_idx_tdown_a[delta];
1604 
1605 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
1606 				-1 * delta_swing_table_idx_tdown_a[delta];
1607 			/* Record delta swing for mix mode power tracking*/
1608 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1609 				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1610 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
1611 
1612 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1613 				"deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
1614 				delta, delta_swing_table_idx_tdown_b[delta]);
1615 
1616 			rtldm->delta_power_index_last[RF90_PATH_B] =
1617 				rtldm->delta_power_index[RF90_PATH_B];
1618 			rtldm->delta_power_index[RF90_PATH_B] =
1619 				-1 * delta_swing_table_idx_tdown_b[delta];
1620 
1621 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] =
1622 				-1 * delta_swing_table_idx_tdown_b[delta];
1623 			/*Record delta swing for mix mode power tracking*/
1624 
1625 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1626 				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1627 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]);
1628 		}
1629 
1630 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) {
1631 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1632 				"============================= [Path-%c]Calculating PowerIndexOffset =============================\n",
1633 				(p == RF90_PATH_A ? 'A' : 'B'));
1634 
1635 			if (rtldm->delta_power_index[p] ==
1636 				rtldm->delta_power_index_last[p])
1637 				/*If Thermal value changes but lookup
1638 				table value still the same*/
1639 				rtldm->power_index_offset[p] = 0;
1640 			else
1641 				rtldm->power_index_offset[p] =
1642 					rtldm->delta_power_index[p] -
1643 					rtldm->delta_power_index_last[p];
1644 				/* Power Index Diff between 2
1645 				 * times Power Tracking
1646 				 */
1647 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1648 				"[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n",
1649 				(p == RF90_PATH_A ? 'A' : 'B'),
1650 				rtldm->power_index_offset[p],
1651 				rtldm->delta_power_index[p],
1652 				rtldm->delta_power_index_last[p]);
1653 
1654 			rtldm->ofdm_index[p] =
1655 					rtldm->swing_idx_ofdm_base[p] +
1656 					rtldm->power_index_offset[p];
1657 			rtldm->cck_index =
1658 					rtldm->swing_idx_cck_base +
1659 					rtldm->power_index_offset[p];
1660 
1661 			rtldm->swing_idx_cck = rtldm->cck_index;
1662 			rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p];
1663 
1664 			/****Print BB Swing Base and Index Offset */
1665 
1666 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1667 				"The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
1668 				rtldm->swing_idx_cck,
1669 				rtldm->swing_idx_cck_base,
1670 				rtldm->power_index_offset[p]);
1671 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1672 				"The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
1673 				rtldm->swing_idx_ofdm[p],
1674 				(p == RF90_PATH_A ? 'A' : 'B'),
1675 				rtldm->swing_idx_ofdm_base[p],
1676 				rtldm->power_index_offset[p]);
1677 
1678 			/*7.1 Handle boundary conditions of index.*/
1679 
1680 			if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1)
1681 				rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1;
1682 			else if (rtldm->ofdm_index[p] < ofdm_min_index)
1683 				rtldm->ofdm_index[p] = ofdm_min_index;
1684 		}
1685 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1686 			"\n\n====================================================================================\n");
1687 		if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1)
1688 			rtldm->cck_index = TXSCALE_TABLE_SIZE - 1;
1689 		else if (rtldm->cck_index < 0)
1690 			rtldm->cck_index = 0;
1691 	} else {
1692 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1693 			"The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
1694 			rtldm->txpower_track_control,
1695 			thermal_value,
1696 			rtldm->thermalvalue);
1697 
1698 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1699 			rtldm->power_index_offset[p] = 0;
1700 	}
1701 	/*Print Swing base & current*/
1702 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1703 		"TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n",
1704 		rtldm->cck_index, rtldm->swing_idx_cck_base);
1705 	for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) {
1706 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1707 			"TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n",
1708 			rtldm->ofdm_index[p],
1709 			(p == RF90_PATH_A ? 'A' : 'B'),
1710 			rtldm->swing_idx_ofdm_base[p]);
1711 	}
1712 
1713 	if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
1714 		rtldm->power_index_offset[RF90_PATH_B] != 0) &&
1715 		rtldm->txpower_track_control) {
1716 		/*7.2 Configure the Swing Table to adjust Tx Power.
1717 		 *Always TRUE after Tx Power is adjusted by power tracking.
1718 		 *
1719 		 *2012/04/23 MH According to Luke's suggestion,
1720 		 *we can not write BB digital
1721 		 *to increase TX power. Otherwise, EVM will be bad.
1722 		 *
1723 		 *2012/04/25 MH Add for tx power tracking to set
1724 		 *tx power in tx agc for 88E.
1725 		 */
1726 		if (thermal_value > rtldm->thermalvalue) {
1727 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1728 				"Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n",
1729 				rtldm->power_index_offset[RF90_PATH_A],
1730 				delta, thermal_value,
1731 				rtlefuse->eeprom_thermalmeter,
1732 				rtldm->thermalvalue);
1733 
1734 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1735 				"Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1736 				rtldm->power_index_offset[RF90_PATH_B],
1737 				delta, thermal_value,
1738 				rtlefuse->eeprom_thermalmeter,
1739 				rtldm->thermalvalue);
1740 		} else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
1741 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1742 				"Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1743 				rtldm->power_index_offset[RF90_PATH_A],
1744 				delta, thermal_value,
1745 				rtlefuse->eeprom_thermalmeter,
1746 				rtldm->thermalvalue);
1747 
1748 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1749 				"Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1750 				rtldm->power_index_offset[RF90_PATH_B],
1751 				delta, thermal_value,
1752 				rtlefuse->eeprom_thermalmeter,
1753 				rtldm->thermalvalue);
1754 		}
1755 
1756 		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
1757 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1758 				"Temperature(%d) higher than PG value(%d)\n",
1759 				thermal_value, rtlefuse->eeprom_thermalmeter);
1760 
1761 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1762 				"**********Enter POWER Tracking MIX_MODE**********\n");
1763 			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1764 				rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE,
1765 								 p, 0);
1766 		} else {
1767 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1768 				"Temperature(%d) lower than PG value(%d)\n",
1769 				thermal_value, rtlefuse->eeprom_thermalmeter);
1770 
1771 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1772 				"**********Enter POWER Tracking MIX_MODE**********\n");
1773 			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1774 				rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE,
1775 								 p, index_for_channel);
1776 		}
1777 		/*Record last time Power Tracking result as base.*/
1778 		rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
1779 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1780 				rtldm->swing_idx_ofdm_base[p] =
1781 					rtldm->swing_idx_ofdm[p];
1782 
1783 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1784 			"pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n",
1785 			rtldm->thermalvalue, thermal_value);
1786 		/*Record last Power Tracking Thermal Value*/
1787 		rtldm->thermalvalue = thermal_value;
1788 	}
1789 	/*Delta temperature is equal to or larger than
1790 	20 centigrade (When threshold is 8).*/
1791 	if (delta_iqk >= IQK_THRESHOLD)
1792 		rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8);
1793 
1794 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1795 		"<===%s\n", __func__);
1796 }
1797 
1798 static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw,
1799 					    const u8 **up_a,
1800 					    const u8 **down_a)
1801 {
1802 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1803 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1804 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1805 	u8 channel = rtlphy->current_channel;
1806 	u8 rate = rtldm->tx_rate;
1807 
1808 	if (1 <= channel && channel <= 14) {
1809 		if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
1810 			*up_a = rtl8821ae_delta_swing_table_idx_24gccka_p;
1811 			*down_a = rtl8821ae_delta_swing_table_idx_24gccka_n;
1812 		} else {
1813 			*up_a = rtl8821ae_delta_swing_table_idx_24ga_p;
1814 			*down_a = rtl8821ae_delta_swing_table_idx_24ga_n;
1815 		}
1816 	} else if (36 <= channel && channel <= 64) {
1817 		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0];
1818 		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0];
1819 	} else if (100 <= channel && channel <= 140) {
1820 		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1];
1821 		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1];
1822 	} else if (149 <= channel && channel <= 173) {
1823 		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2];
1824 		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2];
1825 	} else {
1826 		*up_a = rtl8818e_delta_swing_table_idx_24gb_p;
1827 		*down_a = rtl8818e_delta_swing_table_idx_24gb_n;
1828 	}
1829 	return;
1830 }
1831 
1832 /*-----------------------------------------------------------------------------
1833  * Function:	odm_TxPwrTrackSetPwr88E()
1834  *
1835  * Overview:	88E change all channel tx power accordign to flag.
1836  *				OFDM & CCK are all different.
1837  *
1838  * Input:		NONE
1839  *
1840  * Output:		NONE
1841  *
1842  * Return:		NONE
1843  *
1844  * Revised History:
1845  *	When		Who		Remark
1846  *	04/23/2012	MHC		Create Version 0.
1847  *
1848  *---------------------------------------------------------------------------
1849  */
1850 void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
1851 				      enum pwr_track_control_method method,
1852 				      u8 rf_path, u8 channel_mapped_index)
1853 {
1854 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1855 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
1856 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1857 	u32 final_swing_idx[1];
1858 	u8 pwr_tracking_limit = 26; /*+1.0dB*/
1859 	u8 tx_rate = 0xFF;
1860 	s8 final_ofdm_swing_index = 0;
1861 
1862 	if (rtldm->tx_rate != 0xFF)
1863 		tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
1864 
1865 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__);
1866 
1867 	if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/
1868 		/*CCK*/
1869 		if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
1870 			pwr_tracking_limit = 32; /*+4dB*/
1871 		/*OFDM*/
1872 		else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
1873 			pwr_tracking_limit = 30; /*+3dB*/
1874 		else if (tx_rate == MGN_54M)
1875 			pwr_tracking_limit = 28; /*+2dB*/
1876 		/*HT*/
1877 		/*QPSK/BPSK*/
1878 		else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2))
1879 			pwr_tracking_limit = 34; /*+5dB*/
1880 		/*16QAM*/
1881 		else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4))
1882 			pwr_tracking_limit = 30; /*+3dB*/
1883 		/*64QAM*/
1884 		else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7))
1885 			pwr_tracking_limit = 28; /*+2dB*/
1886 		/*2 VHT*/
1887 		/*QPSK/BPSK*/
1888 		else if ((tx_rate >= MGN_VHT1SS_MCS0) &&
1889 			(tx_rate <= MGN_VHT1SS_MCS2))
1890 			pwr_tracking_limit = 34; /*+5dB*/
1891 		/*16QAM*/
1892 		else if ((tx_rate >= MGN_VHT1SS_MCS3) &&
1893 			(tx_rate <= MGN_VHT1SS_MCS4))
1894 			pwr_tracking_limit = 30; /*+3dB*/
1895 		/*64QAM*/
1896 		else if ((tx_rate >= MGN_VHT1SS_MCS5) &&
1897 			(tx_rate <= MGN_VHT1SS_MCS6))
1898 			pwr_tracking_limit = 28; /*+2dB*/
1899 		else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
1900 			pwr_tracking_limit = 26; /*+1dB*/
1901 		else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
1902 			pwr_tracking_limit = 24; /*+0dB*/
1903 		else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
1904 			pwr_tracking_limit = 22; /*-1dB*/
1905 		else
1906 			pwr_tracking_limit = 24;
1907 	}
1908 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1909 		"TxRate=0x%x, PwrTrackingLimit=%d\n",
1910 		tx_rate, pwr_tracking_limit);
1911 
1912 	if (method == BBSWING) {
1913 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1914 			"===>%s\n", __func__);
1915 		if (rf_path == RF90_PATH_A) {
1916 			final_swing_idx[RF90_PATH_A] =
1917 				(rtldm->ofdm_index[RF90_PATH_A] >
1918 				pwr_tracking_limit) ?
1919 				pwr_tracking_limit :
1920 				rtldm->ofdm_index[RF90_PATH_A];
1921 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1922 				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
1923 				rtldm->ofdm_index[RF90_PATH_A],
1924 				final_swing_idx[RF90_PATH_A]);
1925 
1926 			rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1927 				txscaling_tbl[final_swing_idx[RF90_PATH_A]]);
1928 		}
1929 	} else if (method == MIX_MODE) {
1930 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1931 			"pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
1932 			rtldm->default_ofdm_index,
1933 			rtldm->absolute_ofdm_swing_idx[rf_path],
1934 			rf_path);
1935 
1936 		final_ofdm_swing_index =
1937 			rtldm->default_ofdm_index +
1938 			rtldm->absolute_ofdm_swing_idx[rf_path];
1939 		/*BBSwing higher then Limit*/
1940 		if (rf_path == RF90_PATH_A) {
1941 			if (final_ofdm_swing_index > pwr_tracking_limit) {
1942 				rtldm->remnant_cck_idx =
1943 					final_ofdm_swing_index -
1944 					pwr_tracking_limit;
1945 				/* CCK Follow the same compensate value as Path A*/
1946 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1947 					final_ofdm_swing_index -
1948 					pwr_tracking_limit;
1949 
1950 				rtl_set_bbreg(hw, RA_TXSCALE,
1951 					0xFFE00000,
1952 					txscaling_tbl[pwr_tracking_limit]);
1953 
1954 				rtldm->modify_txagc_flag_path_a = true;
1955 
1956 				/*Set TxAGC Page C{};*/
1957 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1958 					rtlphy->current_channel,
1959 					RF90_PATH_A);
1960 
1961 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1962 					" ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
1963 					pwr_tracking_limit,
1964 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1965 			} else if (final_ofdm_swing_index < 0) {
1966 				rtldm->remnant_cck_idx = final_ofdm_swing_index;
1967 				/* CCK Follow the same compensate value as Path A*/
1968 				rtldm->remnant_ofdm_swing_idx[rf_path] =
1969 					final_ofdm_swing_index;
1970 
1971 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1972 					txscaling_tbl[0]);
1973 
1974 				rtldm->modify_txagc_flag_path_a = true;
1975 
1976 				/*Set TxAGC Page C{};*/
1977 				rtl8821ae_phy_set_txpower_level_by_path(hw,
1978 					rtlphy->current_channel, RF90_PATH_A);
1979 
1980 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1981 					"******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
1982 					rtldm->remnant_ofdm_swing_idx[rf_path]);
1983 			} else {
1984 				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1985 					txscaling_tbl[(u8)final_ofdm_swing_index]);
1986 
1987 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1988 					"******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
1989 					final_ofdm_swing_index);
1990 				/*If TxAGC has changed, reset TxAGC again*/
1991 				if (rtldm->modify_txagc_flag_path_a) {
1992 					rtldm->remnant_cck_idx = 0;
1993 					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1994 
1995 					/*Set TxAGC Page C{};*/
1996 					rtl8821ae_phy_set_txpower_level_by_path(hw,
1997 						rtlphy->current_channel, RF90_PATH_A);
1998 
1999 					rtldm->modify_txagc_flag_path_a = false;
2000 
2001 					rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
2002 						DBG_LOUD,
2003 						"******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n");
2004 				}
2005 			}
2006 		}
2007 	} else {
2008 		return;
2009 	}
2010 }
2011 
2012 void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(
2013 	struct ieee80211_hw *hw)
2014 {
2015 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2016 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2017 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
2018 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2019 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2020 
2021 	u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
2022 	u8 thermal_value_avg_count = 0;
2023 	u32 thermal_value_avg = 0;
2024 
2025 	u8 ofdm_min_index = 6;  /*OFDM BB Swing should be less than +3.0dB */
2026 	/* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
2027 	u8 index_for_channel = 0;
2028 
2029 	/* 1. The following TWO tables decide the final
2030 	 * index of OFDM/CCK swing table.
2031 	 */
2032 	const u8 *delta_swing_table_idx_tup_a;
2033 	const u8 *delta_swing_table_idx_tdown_a;
2034 
2035 	/*2. Initilization ( 7 steps in total )*/
2036 	rtl8821ae_get_delta_swing_table(hw,
2037 					&delta_swing_table_idx_tup_a,
2038 					&delta_swing_table_idx_tdown_a);
2039 
2040 	rtldm->txpower_trackinginit = true;
2041 
2042 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2043 		"===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
2044 		__func__,
2045 		rtldm->swing_idx_cck_base,
2046 		rtldm->swing_idx_ofdm_base[RF90_PATH_A],
2047 		rtldm->default_ofdm_index);
2048 	/*0x42: RF Reg[15:10] 88E*/
2049 	thermal_value = (u8)rtl_get_rfreg(hw,
2050 		RF90_PATH_A, RF_T_METER_8812A, 0xfc00);
2051 	if (!rtldm->txpower_track_control ||
2052 		rtlefuse->eeprom_thermalmeter == 0 ||
2053 		rtlefuse->eeprom_thermalmeter == 0xFF)
2054 		return;
2055 
2056 	/* 3. Initialize ThermalValues of RFCalibrateInfo*/
2057 
2058 	if (rtlhal->reloadtxpowerindex) {
2059 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2060 			"reload ofdm index for band switch\n");
2061 	}
2062 
2063 	/*4. Calculate average thermal meter*/
2064 	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
2065 	rtldm->thermalvalue_avg_index++;
2066 	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
2067 		/*Average times =  c.AverageThermalNum*/
2068 		rtldm->thermalvalue_avg_index = 0;
2069 
2070 	for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) {
2071 		if (rtldm->thermalvalue_avg[i]) {
2072 			thermal_value_avg += rtldm->thermalvalue_avg[i];
2073 			thermal_value_avg_count++;
2074 		}
2075 	}
2076 	/*Calculate Average ThermalValue after average enough times*/
2077 	if (thermal_value_avg_count) {
2078 		thermal_value = (u8)(thermal_value_avg /
2079 				thermal_value_avg_count);
2080 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2081 			"AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
2082 			thermal_value, rtlefuse->eeprom_thermalmeter);
2083 	}
2084 
2085 	/*5. Calculate delta, delta_LCK, delta_IQK.
2086 	 *"delta" here is used to determine whether
2087 	 * thermal value changes or not.
2088 	 */
2089 	delta = (thermal_value > rtldm->thermalvalue) ?
2090 		(thermal_value - rtldm->thermalvalue) :
2091 		(rtldm->thermalvalue - thermal_value);
2092 	delta_lck = (thermal_value > rtldm->thermalvalue_lck) ?
2093 		(thermal_value - rtldm->thermalvalue_lck) :
2094 		(rtldm->thermalvalue_lck - thermal_value);
2095 	delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ?
2096 		(thermal_value - rtldm->thermalvalue_iqk) :
2097 		(rtldm->thermalvalue_iqk - thermal_value);
2098 
2099 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2100 		"(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
2101 		delta, delta_lck, delta_iqk);
2102 
2103 	/* 6. If necessary, do LCK.	*/
2104 	/*Delta temperature is equal to or larger than 20 centigrade.*/
2105 	if (delta_lck >= IQK_THRESHOLD) {
2106 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2107 			"delta_LCK(%d) >= Threshold_IQK(%d)\n",
2108 			delta_lck, IQK_THRESHOLD);
2109 		rtldm->thermalvalue_lck = thermal_value;
2110 		rtl8821ae_phy_lc_calibrate(hw);
2111 	}
2112 
2113 	/*7. If necessary, move the index of swing table to adjust Tx power.*/
2114 
2115 	if (delta > 0 && rtldm->txpower_track_control) {
2116 		/*"delta" here is used to record the
2117 		 * absolute value of differrence.
2118 		 */
2119 		delta = thermal_value > rtlefuse->eeprom_thermalmeter ?
2120 			(thermal_value - rtlefuse->eeprom_thermalmeter) :
2121 			(rtlefuse->eeprom_thermalmeter - thermal_value);
2122 
2123 		if (delta >= TXSCALE_TABLE_SIZE)
2124 			delta = TXSCALE_TABLE_SIZE - 1;
2125 
2126 		/*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
2127 
2128 		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
2129 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2130 				"delta_swing_table_idx_tup_a[%d] = %d\n",
2131 				delta, delta_swing_table_idx_tup_a[delta]);
2132 			rtldm->delta_power_index_last[RF90_PATH_A] =
2133 				rtldm->delta_power_index[RF90_PATH_A];
2134 			rtldm->delta_power_index[RF90_PATH_A] =
2135 				delta_swing_table_idx_tup_a[delta];
2136 
2137 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
2138 				delta_swing_table_idx_tup_a[delta];
2139 			/*Record delta swing for mix mode power tracking*/
2140 
2141 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2142 				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2143 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
2144 		} else {
2145 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2146 				"delta_swing_table_idx_tdown_a[%d] = %d\n",
2147 				delta, delta_swing_table_idx_tdown_a[delta]);
2148 
2149 			rtldm->delta_power_index_last[RF90_PATH_A] =
2150 				rtldm->delta_power_index[RF90_PATH_A];
2151 			rtldm->delta_power_index[RF90_PATH_A] =
2152 				-1 * delta_swing_table_idx_tdown_a[delta];
2153 
2154 			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
2155 				-1 * delta_swing_table_idx_tdown_a[delta];
2156 			/* Record delta swing for mix mode power tracking*/
2157 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2158 				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2159 				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
2160 		}
2161 
2162 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) {
2163 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2164 				"\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n",
2165 				(p == RF90_PATH_A ? 'A' : 'B'));
2166 			/*If Thermal value changes but lookup table value
2167 			 * still the same
2168 			 */
2169 			if (rtldm->delta_power_index[p] ==
2170 				rtldm->delta_power_index_last[p])
2171 
2172 				rtldm->power_index_offset[p] = 0;
2173 			else
2174 				rtldm->power_index_offset[p] =
2175 					rtldm->delta_power_index[p] -
2176 					rtldm->delta_power_index_last[p];
2177 			/*Power Index Diff between 2 times Power Tracking*/
2178 
2179 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2180 				"[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
2181 				(p == RF90_PATH_A ? 'A' : 'B'),
2182 				rtldm->power_index_offset[p],
2183 				rtldm->delta_power_index[p] ,
2184 				rtldm->delta_power_index_last[p]);
2185 
2186 			rtldm->ofdm_index[p] =
2187 					rtldm->swing_idx_ofdm_base[p] +
2188 					rtldm->power_index_offset[p];
2189 			rtldm->cck_index =
2190 					rtldm->swing_idx_cck_base +
2191 					rtldm->power_index_offset[p];
2192 
2193 			rtldm->swing_idx_cck = rtldm->cck_index;
2194 			rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p];
2195 
2196 			/*********Print BB Swing Base and Index Offset********/
2197 
2198 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2199 				"The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
2200 				rtldm->swing_idx_cck,
2201 				rtldm->swing_idx_cck_base,
2202 				rtldm->power_index_offset[p]);
2203 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2204 				"The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
2205 				rtldm->swing_idx_ofdm[p],
2206 				(p == RF90_PATH_A ? 'A' : 'B'),
2207 				rtldm->swing_idx_ofdm_base[p],
2208 				rtldm->power_index_offset[p]);
2209 
2210 			/*7.1 Handle boundary conditions of index.*/
2211 
2212 			if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1)
2213 				rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1;
2214 			else if (rtldm->ofdm_index[p] < ofdm_min_index)
2215 				rtldm->ofdm_index[p] = ofdm_min_index;
2216 		}
2217 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2218 			"\n\n========================================================================================================\n");
2219 		if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1)
2220 			rtldm->cck_index = TXSCALE_TABLE_SIZE - 1;
2221 		else if (rtldm->cck_index < 0)
2222 			rtldm->cck_index = 0;
2223 	} else {
2224 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2225 			"The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
2226 			rtldm->txpower_track_control,
2227 			thermal_value,
2228 			rtldm->thermalvalue);
2229 
2230 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2231 			rtldm->power_index_offset[p] = 0;
2232 	}
2233 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2234 		"TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
2235 		/*Print Swing base & current*/
2236 		rtldm->cck_index, rtldm->swing_idx_cck_base);
2237 	for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) {
2238 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2239 			"TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
2240 			rtldm->ofdm_index[p],
2241 			(p == RF90_PATH_A ? 'A' : 'B'),
2242 			rtldm->swing_idx_ofdm_base[p]);
2243 	}
2244 
2245 	if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
2246 		rtldm->power_index_offset[RF90_PATH_B] != 0) &&
2247 		rtldm->txpower_track_control) {
2248 		/*7.2 Configure the Swing Table to adjust Tx Power.*/
2249 		/*Always TRUE after Tx Power is adjusted by power tracking.*/
2250 		/*
2251 		 *  2012/04/23 MH According to Luke's suggestion,
2252 		 *  we can not write BB digital
2253 		 *  to increase TX power. Otherwise, EVM will be bad.
2254 		 *
2255 		 *  2012/04/25 MH Add for tx power tracking to
2256 		 *  set tx power in tx agc for 88E.
2257 		 */
2258 		if (thermal_value > rtldm->thermalvalue) {
2259 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2260 				"Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2261 				rtldm->power_index_offset[RF90_PATH_A],
2262 				delta, thermal_value,
2263 				rtlefuse->eeprom_thermalmeter,
2264 				rtldm->thermalvalue);
2265 		} else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
2266 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2267 				"Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2268 				rtldm->power_index_offset[RF90_PATH_A],
2269 				delta, thermal_value,
2270 				rtlefuse->eeprom_thermalmeter,
2271 				rtldm->thermalvalue);
2272 		}
2273 
2274 		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
2275 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2276 				"Temperature(%d) higher than PG value(%d)\n",
2277 				thermal_value, rtlefuse->eeprom_thermalmeter);
2278 
2279 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2280 				"****Enter POWER Tracking MIX_MODE****\n");
2281 			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2282 					rtl8821ae_dm_txpwr_track_set_pwr(hw,
2283 						MIX_MODE, p, index_for_channel);
2284 		} else {
2285 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2286 				"Temperature(%d) lower than PG value(%d)\n",
2287 				thermal_value, rtlefuse->eeprom_thermalmeter);
2288 
2289 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2290 				"*****Enter POWER Tracking MIX_MODE*****\n");
2291 			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2292 				rtl8812ae_dm_txpwr_track_set_pwr(hw,
2293 					MIX_MODE, p, index_for_channel);
2294 		}
2295 		/*Record last time Power Tracking result as base.*/
2296 		rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
2297 		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2298 			rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p];
2299 
2300 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2301 			"pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
2302 			rtldm->thermalvalue, thermal_value);
2303 		/*Record last Power Tracking Thermal Value*/
2304 		rtldm->thermalvalue = thermal_value;
2305 	}
2306 	/* Delta temperature is equal to or larger than
2307 	 * 20 centigrade (When threshold is 8).
2308 	 */
2309 	if (delta_iqk >= IQK_THRESHOLD) {
2310 		if (!rtlphy->lck_inprogress) {
2311 			spin_lock(&rtlpriv->locks.iqk_lock);
2312 			rtlphy->lck_inprogress = true;
2313 			spin_unlock(&rtlpriv->locks.iqk_lock);
2314 
2315 			rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8);
2316 
2317 			spin_lock(&rtlpriv->locks.iqk_lock);
2318 			rtlphy->lck_inprogress = false;
2319 			spin_unlock(&rtlpriv->locks.iqk_lock);
2320 		}
2321 	}
2322 
2323 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__);
2324 }
2325 
2326 void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw)
2327 {
2328 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2329 	if (!rtlpriv->dm.tm_trigger) {
2330 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16),
2331 			      0x03);
2332 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2333 			"Trigger 8821ae Thermal Meter!!\n");
2334 		rtlpriv->dm.tm_trigger = 1;
2335 		return;
2336 	} else {
2337 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2338 			"Schedule TxPowerTracking !!\n");
2339 
2340 		rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw);
2341 		rtlpriv->dm.tm_trigger = 0;
2342 	}
2343 }
2344 
2345 static void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
2346 {
2347 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2348 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2349 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2350 	struct rate_adaptive *p_ra = &rtlpriv->ra;
2351 	u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
2352 	u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
2353 	u8 go_up_gap = 5;
2354 	struct ieee80211_sta *sta = NULL;
2355 
2356 	if (is_hal_stop(rtlhal)) {
2357 		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2358 			"driver is going to unload\n");
2359 		return;
2360 	}
2361 
2362 	if (!rtlpriv->dm.useramask) {
2363 		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2364 			"driver does not control rate adaptive mask\n");
2365 		return;
2366 	}
2367 
2368 	if (mac->link_state == MAC80211_LINKED &&
2369 		mac->opmode == NL80211_IFTYPE_STATION) {
2370 		switch (p_ra->pre_ratr_state) {
2371 		case DM_RATR_STA_MIDDLE:
2372 			high_rssithresh_for_ra += go_up_gap;
2373 			break;
2374 		case DM_RATR_STA_LOW:
2375 			high_rssithresh_for_ra += go_up_gap;
2376 			low_rssithresh_for_ra += go_up_gap;
2377 			break;
2378 		default:
2379 			break;
2380 		}
2381 
2382 		if (rtlpriv->dm.undec_sm_pwdb >
2383 		    (long)high_rssithresh_for_ra)
2384 			p_ra->ratr_state = DM_RATR_STA_HIGH;
2385 		else if (rtlpriv->dm.undec_sm_pwdb >
2386 			 (long)low_rssithresh_for_ra)
2387 			p_ra->ratr_state = DM_RATR_STA_MIDDLE;
2388 		else
2389 			p_ra->ratr_state = DM_RATR_STA_LOW;
2390 
2391 		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
2392 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2393 				"RSSI = %ld\n",
2394 				rtlpriv->dm.undec_sm_pwdb);
2395 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2396 				"RSSI_LEVEL = %d\n", p_ra->ratr_state);
2397 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
2398 				"PreState = %d, CurState = %d\n",
2399 				p_ra->pre_ratr_state, p_ra->ratr_state);
2400 
2401 			rcu_read_lock();
2402 			sta = rtl_find_sta(hw, mac->bssid);
2403 			if (sta)
2404 				rtlpriv->cfg->ops->update_rate_tbl(hw,
2405 						sta, p_ra->ratr_state, true);
2406 			rcu_read_unlock();
2407 
2408 			p_ra->pre_ratr_state = p_ra->ratr_state;
2409 		}
2410 	}
2411 }
2412 
2413 static void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw *hw)
2414 {
2415 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2416 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2417 	struct rtl_mac *mac = &rtlpriv->mac80211;
2418 	static u8 stage;
2419 	u8 cur_stage = 0;
2420 	u16 basic_rate = RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M | RRSR_6M;
2421 
2422 	if (mac->link_state < MAC80211_LINKED)
2423 		cur_stage = 0;
2424 	else if (dm_digtable->rssi_val_min < 25)
2425 		cur_stage = 1;
2426 	else if (dm_digtable->rssi_val_min > 30)
2427 		cur_stage = 3;
2428 	else
2429 		cur_stage = 2;
2430 
2431 	if (cur_stage != stage) {
2432 		if (cur_stage == 1) {
2433 			basic_rate &= (!(basic_rate ^ mac->basic_rates));
2434 			rtlpriv->cfg->ops->set_hw_reg(hw,
2435 				HW_VAR_BASIC_RATE, (u8 *)&basic_rate);
2436 		} else if (cur_stage == 3 && (stage == 1 || stage == 2)) {
2437 			rtlpriv->cfg->ops->set_hw_reg(hw,
2438 				HW_VAR_BASIC_RATE, (u8 *)&mac->basic_rates);
2439 		}
2440 	}
2441 	stage = cur_stage;
2442 }
2443 
2444 static void rtl8821ae_dm_edca_choose_traffic_idx(
2445 	struct ieee80211_hw *hw, u64 cur_tx_bytes,
2446 	u64 cur_rx_bytes, bool b_bias_on_rx,
2447 	bool *pb_is_cur_rdl_state)
2448 {
2449 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2450 
2451 	if (b_bias_on_rx) {
2452 		if (cur_tx_bytes > (cur_rx_bytes*4)) {
2453 			*pb_is_cur_rdl_state = false;
2454 			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2455 				"Uplink Traffic\n");
2456 		} else {
2457 			*pb_is_cur_rdl_state = true;
2458 			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2459 				"Balance Traffic\n");
2460 		}
2461 	} else {
2462 		if (cur_rx_bytes > (cur_tx_bytes*4)) {
2463 			*pb_is_cur_rdl_state = true;
2464 			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2465 				"Downlink	Traffic\n");
2466 		} else {
2467 			*pb_is_cur_rdl_state = false;
2468 			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2469 				"Balance Traffic\n");
2470 		}
2471 	}
2472 	return;
2473 }
2474 
2475 static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
2476 {
2477 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2478 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2479 	struct rtl_dm *rtldm =  rtl_dm(rtl_priv(hw));
2480 
2481 	/*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/
2482 	u64 cur_tx_ok_cnt = 0;
2483 	u64 cur_rx_ok_cnt = 0;
2484 	u32 edca_be_ul = 0x5ea42b;
2485 	u32 edca_be_dl = 0x5ea42b;
2486 	u32 edca_be = 0x5ea42b;
2487 	u8 iot_peer = 0;
2488 	bool *pb_is_cur_rdl_state = NULL;
2489 	bool b_bias_on_rx = false;
2490 	bool b_edca_turbo_on = false;
2491 
2492 	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2493 		"%s=====>\n", __func__);
2494 	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2495 		"Original BE PARAM: 0x%x\n",
2496 		rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N));
2497 
2498 	if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100)
2499 		rtlpriv->dm.is_any_nonbepkts = true;
2500 	rtlpriv->dm.dbginfo.num_non_be_pkt = 0;
2501 
2502 	/*===============================
2503 	 * list parameter for different platform
2504 	 *===============================
2505 	 */
2506 	pb_is_cur_rdl_state = &rtlpriv->dm.is_cur_rdlstate;
2507 
2508 	cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt;
2509 	cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt;
2510 
2511 	rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
2512 	rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
2513 
2514 	iot_peer = rtlpriv->mac80211.vendor;
2515 	b_bias_on_rx = false;
2516 	b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
2517 			   (!rtlpriv->dm.disable_framebursting)) ?
2518 			   true : false;
2519 
2520 	if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8812AE) {
2521 		if ((iot_peer == PEER_CISCO) &&
2522 			(mac->mode == WIRELESS_MODE_N_24G)) {
2523 			edca_be_dl = edca_setting_dl[iot_peer];
2524 			edca_be_ul = edca_setting_ul[iot_peer];
2525 		}
2526 	}
2527 
2528 	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2529 		"bIsAnyNonBEPkts : 0x%x  bDisableFrameBursting : 0x%x\n",
2530 		rtlpriv->dm.is_any_nonbepkts,
2531 		rtlpriv->dm.disable_framebursting);
2532 
2533 	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2534 		"bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",
2535 		b_edca_turbo_on, b_bias_on_rx);
2536 
2537 	if (b_edca_turbo_on) {
2538 		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2539 			"curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt);
2540 		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2541 			"curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt);
2542 		if (b_bias_on_rx)
2543 			rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
2544 				cur_rx_ok_cnt, true, pb_is_cur_rdl_state);
2545 		else
2546 			rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
2547 				cur_rx_ok_cnt, false, pb_is_cur_rdl_state);
2548 
2549 		edca_be = (*pb_is_cur_rdl_state) ?  edca_be_dl : edca_be_ul;
2550 
2551 		rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be);
2552 
2553 		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2554 			"EDCA Turbo on: EDCA_BE:0x%x\n", edca_be);
2555 
2556 		rtlpriv->dm.current_turbo_edca = true;
2557 
2558 		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
2559 			"EDCA_BE_DL : 0x%x  EDCA_BE_UL : 0x%x  EDCA_BE : 0x%x\n",
2560 			edca_be_dl, edca_be_ul, edca_be);
2561 	} else {
2562 		if (rtlpriv->dm.current_turbo_edca) {
2563 			u8 tmp = AC0_BE;
2564 			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
2565 						      (u8 *)(&tmp));
2566 		}
2567 		rtlpriv->dm.current_turbo_edca = false;
2568 	}
2569 
2570 	rtlpriv->dm.is_any_nonbepkts = false;
2571 	rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
2572 	rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
2573 }
2574 
2575 static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
2576 {
2577 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2578 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2579 	u8 cur_cck_cca_thresh;
2580 
2581 	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
2582 		if (dm_digtable->rssi_val_min > 25) {
2583 			cur_cck_cca_thresh = 0xcd;
2584 		} else if ((dm_digtable->rssi_val_min <= 25) &&
2585 			   (dm_digtable->rssi_val_min > 10)) {
2586 			cur_cck_cca_thresh = 0x83;
2587 		} else {
2588 			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
2589 				cur_cck_cca_thresh = 0x83;
2590 			else
2591 				cur_cck_cca_thresh = 0x40;
2592 		}
2593 	} else {
2594 		if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
2595 			cur_cck_cca_thresh = 0x83;
2596 		else
2597 			cur_cck_cca_thresh = 0x40;
2598 	}
2599 
2600 	if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh)
2601 		rtl_write_byte(rtlpriv, ODM_REG_CCK_CCA_11AC,
2602 			       cur_cck_cca_thresh);
2603 
2604 	dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
2605 	dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh;
2606 	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
2607 		"CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres);
2608 }
2609 
2610 static void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
2611 {
2612 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2613 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2614 	u8 crystal_cap;
2615 	u32 packet_count;
2616 	int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
2617 	int cfo_ave_diff;
2618 
2619 	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
2620 		/*1.Enable ATC*/
2621 		if (rtldm->atc_status == ATC_STATUS_OFF) {
2622 			rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON);
2623 			rtldm->atc_status = ATC_STATUS_ON;
2624 		}
2625 
2626 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No link!!\n");
2627 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2628 			"atc_status = %d\n", rtldm->atc_status);
2629 
2630 		if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
2631 			rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
2632 			crystal_cap = rtldm->crystal_cap & 0x3f;
2633 			crystal_cap = crystal_cap & 0x3f;
2634 			if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE)
2635 				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2636 					      0x7ff80000, (crystal_cap |
2637 					      (crystal_cap << 6)));
2638 			else
2639 				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2640 					      0xfff000, (crystal_cap |
2641 					      (crystal_cap << 6)));
2642 		}
2643 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "crystal_cap = 0x%x\n",
2644 			rtldm->crystal_cap);
2645 	} else{
2646 		/*1. Calculate CFO for path-A & path-B*/
2647 		cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
2648 		cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
2649 		packet_count = rtldm->packet_count;
2650 
2651 		/*2.No new packet*/
2652 		if (packet_count == rtldm->packet_count_pre) {
2653 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2654 				"packet counter doesn't change\n");
2655 			return;
2656 		}
2657 
2658 		rtldm->packet_count_pre = packet_count;
2659 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2660 			"packet counter = %d\n",
2661 			rtldm->packet_count);
2662 
2663 		/*3.Average CFO*/
2664 		if (rtlpriv->phy.rf_type == RF_1T1R)
2665 			cfo_ave = cfo_khz_a;
2666 		else
2667 			cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1;
2668 
2669 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2670 			"cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n",
2671 			cfo_khz_a, cfo_khz_b, cfo_ave);
2672 
2673 		/*4.Avoid abnormal large CFO*/
2674 		cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
2675 						(rtldm->cfo_ave_pre - cfo_ave) :
2676 						(cfo_ave - rtldm->cfo_ave_pre);
2677 
2678 		if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) {
2679 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2680 				"first large CFO hit\n");
2681 			rtldm->large_cfo_hit = true;
2682 			return;
2683 		} else
2684 			rtldm->large_cfo_hit = false;
2685 
2686 		rtldm->cfo_ave_pre = cfo_ave;
2687 
2688 		/*CFO tracking by adjusting Xtal cap.*/
2689 
2690 		/*1.Dynamic Xtal threshold*/
2691 		if (cfo_ave >= -rtldm->cfo_threshold &&
2692 			cfo_ave <= rtldm->cfo_threshold &&
2693 			rtldm->is_freeze == 0) {
2694 			if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
2695 				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
2696 				rtldm->is_freeze = 1;
2697 			} else {
2698 				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
2699 			}
2700 		}
2701 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2702 			"Dynamic threshold = %d\n",
2703 			rtldm->cfo_threshold);
2704 
2705 		/* 2.Calculate Xtal offset*/
2706 		if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
2707 			adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
2708 		else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
2709 			 rtlpriv->dm.crystal_cap > 0)
2710 			adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
2711 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2712 			"Crystal cap = 0x%x, Crystal cap offset = %d\n",
2713 			rtldm->crystal_cap, adjust_xtal);
2714 
2715 		/*3.Adjudt Crystal Cap.*/
2716 		if (adjust_xtal != 0) {
2717 			rtldm->is_freeze = 0;
2718 			rtldm->crystal_cap += adjust_xtal;
2719 
2720 			if (rtldm->crystal_cap > 0x3f)
2721 				rtldm->crystal_cap = 0x3f;
2722 			else if (rtldm->crystal_cap < 0)
2723 				rtldm->crystal_cap = 0;
2724 
2725 			crystal_cap = rtldm->crystal_cap & 0x3f;
2726 			crystal_cap = crystal_cap & 0x3f;
2727 			if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE)
2728 				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2729 					      0x7ff80000, (crystal_cap |
2730 					      (crystal_cap << 6)));
2731 			else
2732 				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2733 					      0xfff000, (crystal_cap |
2734 					      (crystal_cap << 6)));
2735 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
2736 				"New crystal cap = 0x%x\n",
2737 				rtldm->crystal_cap);
2738 		}
2739 	}
2740 }
2741 
2742 void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw)
2743 {
2744 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2745 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2746 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2747 	bool fw_current_inpsmode = false;
2748 	bool fw_ps_awake = true;
2749 
2750 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
2751 				      (u8 *)(&fw_current_inpsmode));
2752 
2753 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
2754 				      (u8 *)(&fw_ps_awake));
2755 
2756 	if (ppsc->p2p_ps_info.p2p_ps_mode)
2757 		fw_ps_awake = false;
2758 
2759 	spin_lock(&rtlpriv->locks.rf_ps_lock);
2760 	if ((ppsc->rfpwr_state == ERFON) &&
2761 	    ((!fw_current_inpsmode) && fw_ps_awake) &&
2762 	    (!ppsc->rfchange_inprogress)) {
2763 		rtl8821ae_dm_common_info_self_update(hw);
2764 		rtl8821ae_dm_false_alarm_counter_statistics(hw);
2765 		rtl8821ae_dm_check_rssi_monitor(hw);
2766 		rtl8821ae_dm_dig(hw);
2767 		rtl8821ae_dm_cck_packet_detection_thresh(hw);
2768 		rtl8821ae_dm_refresh_rate_adaptive_mask(hw);
2769 		rtl8821ae_dm_refresh_basic_rate_mask(hw);
2770 		rtl8821ae_dm_check_edca_turbo(hw);
2771 		rtl8821ae_dm_dynamic_atc_switch(hw);
2772 		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
2773 			rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw);
2774 		else
2775 			rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw);
2776 		rtl8821ae_dm_iq_calibrate(hw);
2777 	}
2778 	spin_unlock(&rtlpriv->locks.rf_ps_lock);
2779 
2780 	rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
2781 	rtl_dbg(rtlpriv, COMP_DIG, DBG_DMESG, "\n");
2782 }
2783 
2784 void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
2785 					u8 *pdesc, u32 mac_id)
2786 {
2787 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2788 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2789 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2790 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
2791 	__le32 *pdesc32 = (__le32 *)pdesc;
2792 
2793 	if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE)
2794 		return;
2795 
2796 	if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
2797 		set_tx_desc_tx_ant(pdesc32, pfat_table->antsel_a[mac_id]);
2798 }
2799