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