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