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