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