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