net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / hal / phydm / halphyrf_ce.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20
21 #include "mp_precomp.h"
22 #include "phydm_precomp.h"
23
24 #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
25         do {\
26                 for (_offset = 0; _offset < _size; _offset++) { \
27                         \
28                         if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
29                                 \
30                                 if (_offset != 0)\
31                                         _offset--;\
32                                 break;\
33                         } \
34                 }                       \
35                 if (_offset >= _size)\
36                         _offset = _size-1;\
37         } while (0)
38
39 void configure_txpower_track(
40         void                                    *p_dm_void,
41         struct _TXPWRTRACK_CFG  *p_config
42 )
43 {
44         struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
45
46 #if RTL8192E_SUPPORT
47         if (p_dm_odm->support_ic_type == ODM_RTL8192E)
48                 configure_txpower_track_8192e(p_config);
49 #endif
50 #if RTL8821A_SUPPORT
51         if (p_dm_odm->support_ic_type == ODM_RTL8821)
52                 configure_txpower_track_8821a(p_config);
53 #endif
54 #if RTL8812A_SUPPORT
55         if (p_dm_odm->support_ic_type == ODM_RTL8812)
56                 configure_txpower_track_8812a(p_config);
57 #endif
58 #if RTL8188E_SUPPORT
59         if (p_dm_odm->support_ic_type == ODM_RTL8188E)
60                 configure_txpower_track_8188e(p_config);
61 #endif
62
63 #if RTL8723B_SUPPORT
64         if (p_dm_odm->support_ic_type == ODM_RTL8723B)
65                 configure_txpower_track_8723b(p_config);
66 #endif
67
68 #if RTL8814A_SUPPORT
69         if (p_dm_odm->support_ic_type == ODM_RTL8814A)
70                 configure_txpower_track_8814a(p_config);
71 #endif
72
73 #if RTL8703B_SUPPORT
74         if (p_dm_odm->support_ic_type == ODM_RTL8703B)
75                 configure_txpower_track_8703b(p_config);
76 #endif
77
78 #if RTL8188F_SUPPORT
79         if (p_dm_odm->support_ic_type == ODM_RTL8188F)
80                 configure_txpower_track_8188f(p_config);
81 #endif
82 #if RTL8723D_SUPPORT
83         if (p_dm_odm->support_ic_type == ODM_RTL8723D)
84                 configure_txpower_track_8723d(p_config);
85 #endif
86 /* JJ ADD 20161014 */
87 #if RTL8710B_SUPPORT
88         if (p_dm_odm->support_ic_type == ODM_RTL8710B)
89                 configure_txpower_track_8710b(p_config);
90 #endif
91
92 #if RTL8822B_SUPPORT
93         if (p_dm_odm->support_ic_type == ODM_RTL8822B)
94                 configure_txpower_track_8822b(p_config);
95 #endif
96 #if RTL8821C_SUPPORT
97         if (p_dm_odm->support_ic_type == ODM_RTL8821C)
98                 configure_txpower_track_8821c(p_config);
99 #endif
100
101 }
102
103 /* **********************************************************************
104  * <20121113, Kordan> This function should be called when tx_agc changed.
105  * Otherwise the previous compensation is gone, because we record the
106  * delta of temperature between two TxPowerTracking watch dogs.
107  *
108  * NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
109  * need to call this function.
110  * ********************************************************************** */
111 void
112 odm_clear_txpowertracking_state(
113         void                                    *p_dm_void
114 )
115 {
116         struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
117         PHAL_DATA_TYPE  p_hal_data = GET_HAL_DATA(p_dm_odm->adapter);
118         u8                      p = 0;
119         struct odm_rf_calibration_structure     *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
120
121         p_rf_calibrate_info->bb_swing_idx_cck_base = p_rf_calibrate_info->default_cck_index;
122         p_rf_calibrate_info->bb_swing_idx_cck = p_rf_calibrate_info->default_cck_index;
123         p_dm_odm->rf_calibrate_info.CCK_index = 0;
124
125         for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
126                 p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] = p_rf_calibrate_info->default_ofdm_index;
127                 p_rf_calibrate_info->bb_swing_idx_ofdm[p] = p_rf_calibrate_info->default_ofdm_index;
128                 p_rf_calibrate_info->OFDM_index[p] = p_rf_calibrate_info->default_ofdm_index;
129
130                 p_rf_calibrate_info->power_index_offset[p] = 0;
131                 p_rf_calibrate_info->delta_power_index[p] = 0;
132                 p_rf_calibrate_info->delta_power_index_last[p] = 0;
133
134                 p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = 0;    /* Initial Mix mode power tracking*/
135                 p_rf_calibrate_info->remnant_ofdm_swing_idx[p] = 0;
136                 p_rf_calibrate_info->kfree_offset[p] = 0;
137         }
138
139         p_rf_calibrate_info->modify_tx_agc_flag_path_a = false;       /*Initial at Modify Tx Scaling mode*/
140         p_rf_calibrate_info->modify_tx_agc_flag_path_b = false;       /*Initial at Modify Tx Scaling mode*/
141         p_rf_calibrate_info->modify_tx_agc_flag_path_c = false;       /*Initial at Modify Tx Scaling mode*/
142         p_rf_calibrate_info->modify_tx_agc_flag_path_d = false;       /*Initial at Modify Tx Scaling mode*/
143         p_rf_calibrate_info->remnant_cck_swing_idx = 0;
144         p_rf_calibrate_info->thermal_value = p_hal_data->eeprom_thermal_meter;
145
146         p_rf_calibrate_info->modify_tx_agc_value_cck = 0;                       /* modify by Mingzhi.Guo */
147         p_rf_calibrate_info->modify_tx_agc_value_ofdm = 0;              /* modify by Mingzhi.Guo */
148
149 }
150
151 void
152 odm_txpowertracking_callback_thermal_meter(
153 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)
154         struct PHY_DM_STRUCT            *p_dm_odm
155 #else
156         struct _ADAPTER *adapter
157 #endif
158 )
159 {
160
161 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
162         HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(adapter);
163 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
164         struct PHY_DM_STRUCT            *p_dm_odm = &p_hal_data->DM_OutSrc;
165 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
166         struct PHY_DM_STRUCT            *p_dm_odm = &p_hal_data->odmpriv;
167 #endif
168 #endif
169
170         struct odm_rf_calibration_structure     *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
171
172         u8                      thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
173         s8                      diff_DPK[4] = {0};
174         u8                      thermal_value_avg_count = 0;
175         u32                     thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
176
177         u8                      OFDM_min_index = 0;  /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
178         u8                      indexforchannel = 0; /* get_right_chnl_place_for_iqk(p_hal_data->current_channel) */
179         u8                      power_tracking_type = p_hal_data->rf_power_tracking_type;
180         u8                      xtal_offset_eanble = 0;
181
182         struct _TXPWRTRACK_CFG  c;
183
184         /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
185         u8                      *delta_swing_table_idx_tup_a = NULL;
186         u8                      *delta_swing_table_idx_tdown_a = NULL;
187         u8                      *delta_swing_table_idx_tup_b = NULL;
188         u8                      *delta_swing_table_idx_tdown_b = NULL;
189         /*for 8814 add by Yu Chen*/
190         u8                      *delta_swing_table_idx_tup_c = NULL;
191         u8                      *delta_swing_table_idx_tdown_c = NULL;
192         u8                      *delta_swing_table_idx_tup_d = NULL;
193         u8                      *delta_swing_table_idx_tdown_d = NULL;
194         /*for Xtal Offset by James.Tung*/
195         s8                      *delta_swing_table_xtal_up = NULL;
196         s8                      *delta_swing_table_xtal_down = NULL;
197
198         /* 4 2. Initilization ( 7 steps in total ) */
199
200         configure_txpower_track(p_dm_odm, &c);
201
202         (*c.get_delta_swing_table)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
203                 (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
204
205         if (p_dm_odm->support_ic_type & ODM_RTL8814A)   /*for 8814 path C & D*/
206                 (*c.get_delta_swing_table8814only)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
207                         (u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
208         /* JJ ADD 20161014 */
209         if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B))   /*for Xtal Offset*/
210                 (*c.get_delta_swing_xtal_table)(p_dm_odm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down);
211
212         p_rf_calibrate_info->txpowertracking_callback_cnt++;    /*cosa add for debug*/
213         p_rf_calibrate_info->is_txpowertracking_init = true;
214
215         /*p_rf_calibrate_info->txpowertrack_control = p_hal_data->txpowertrack_control;
216         <Kordan> We should keep updating the control variable according to HalData.
217         <Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
218 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
219 #if (MP_DRIVER == 1)
220         p_rf_calibrate_info->rega24 = 0x090e1317;
221 #endif
222 #elif (DM_ODM_SUPPORT_TYPE & ODM_CE)
223         if (p_dm_odm->mp_mode == true)
224                 p_rf_calibrate_info->rega24 = 0x090e1317;
225 #endif
226
227         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
228                 ("===>odm_txpowertracking_callback_thermal_meter\n p_rf_calibrate_info->bb_swing_idx_cck_base: %d, p_rf_calibrate_info->bb_swing_idx_ofdm_base[A]: %d, p_rf_calibrate_info->default_ofdm_index: %d\n",
229                 p_rf_calibrate_info->bb_swing_idx_cck_base, p_rf_calibrate_info->bb_swing_idx_ofdm_base[ODM_RF_PATH_A], p_rf_calibrate_info->default_ofdm_index));
230
231         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
232                 ("p_rf_calibrate_info->txpowertrack_control=%d,  p_hal_data->eeprom_thermal_meter %d\n", p_rf_calibrate_info->txpowertrack_control,  p_hal_data->eeprom_thermal_meter));
233         thermal_value = (u8)odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_A, c.thermal_reg_addr, 0xfc00);        /* 0x42: RF Reg[15:10] 88E */
234
235         /*add log by zhao he, check c80/c94/c14/ca0 value*/
236         if (p_dm_odm->support_ic_type == ODM_RTL8723D) {
237                 regc80 = odm_get_bb_reg(p_dm_odm, 0xc80, MASKDWORD);
238                 regcd0 = odm_get_bb_reg(p_dm_odm, 0xcd0, MASKDWORD);
239                 regcd4 = odm_get_bb_reg(p_dm_odm, 0xcd4, MASKDWORD);
240                 regab4 = odm_get_bb_reg(p_dm_odm, 0xab4, 0x000007FF);
241                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4));
242         }
243         /* JJ ADD 20161014 */
244         if (p_dm_odm->support_ic_type == ODM_RTL8710B) {
245                 regc80 = odm_get_bb_reg(p_dm_odm, 0xc80, MASKDWORD);
246                 regcd0 = odm_get_bb_reg(p_dm_odm, 0xcd0, MASKDWORD);
247                 regcd4 = odm_get_bb_reg(p_dm_odm, 0xcd4, MASKDWORD);
248                 regab4 = odm_get_bb_reg(p_dm_odm, 0xab4, 0x000007FF);
249                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4));
250         }
251
252         if (!p_rf_calibrate_info->txpowertrack_control)
253                 return;
254
255
256         /*4 3. Initialize ThermalValues of rf_calibrate_info*/
257
258         if (p_rf_calibrate_info->is_reloadtxpowerindex)
259                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("reload ofdm index for band switch\n"));
260
261         /*4 4. Calculate average thermal meter*/
262
263         p_rf_calibrate_info->thermal_value_avg[p_rf_calibrate_info->thermal_value_avg_index] = thermal_value;
264         p_rf_calibrate_info->thermal_value_avg_index++;
265         if (p_rf_calibrate_info->thermal_value_avg_index == c.average_thermal_num)   /*Average times =  c.average_thermal_num*/
266                 p_rf_calibrate_info->thermal_value_avg_index = 0;
267
268         for (i = 0; i < c.average_thermal_num; i++) {
269                 if (p_rf_calibrate_info->thermal_value_avg[i]) {
270                         thermal_value_avg += p_rf_calibrate_info->thermal_value_avg[i];
271                         thermal_value_avg_count++;
272                 }
273         }
274
275         if (thermal_value_avg_count) {            /* Calculate Average thermal_value after average enough times */
276                 thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
277                 p_rf_calibrate_info->thermal_value_delta = thermal_value - p_hal_data->eeprom_thermal_meter;
278                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
279                         ("AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, p_hal_data->eeprom_thermal_meter));
280         }
281
282         /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
283
284         /* "delta" here is used to determine whether thermal value changes or not. */
285         delta   = (thermal_value > p_rf_calibrate_info->thermal_value) ? (thermal_value - p_rf_calibrate_info->thermal_value) : (p_rf_calibrate_info->thermal_value - thermal_value);
286         delta_LCK = (thermal_value > p_rf_calibrate_info->thermal_value_lck) ? (thermal_value - p_rf_calibrate_info->thermal_value_lck) : (p_rf_calibrate_info->thermal_value_lck - thermal_value);
287         delta_IQK = (thermal_value > p_rf_calibrate_info->thermal_value_iqk) ? (thermal_value - p_rf_calibrate_info->thermal_value_iqk) : (p_rf_calibrate_info->thermal_value_iqk - thermal_value);
288
289         if (p_rf_calibrate_info->thermal_value_iqk == 0xff) {   /*no PG, use thermal value for IQK*/
290                 p_rf_calibrate_info->thermal_value_iqk = thermal_value;
291                 delta_IQK = (thermal_value > p_rf_calibrate_info->thermal_value_iqk) ? (thermal_value - p_rf_calibrate_info->thermal_value_iqk) : (p_rf_calibrate_info->thermal_value_iqk - thermal_value);
292                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, use thermal_value for IQK\n"));
293         }
294
295         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
296                 diff_DPK[p] = (s8)thermal_value - (s8)p_rf_calibrate_info->dpk_thermal[p];
297
298         /*4 6. If necessary, do LCK.*/
299
300         if (!(p_dm_odm->support_ic_type & ODM_RTL8821)) {       /*no PG, do LCK at initial status*/
301                 if (p_rf_calibrate_info->thermal_value_lck == 0xff) {
302                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, do LCK\n"));
303                         p_rf_calibrate_info->thermal_value_lck = thermal_value;
304
305                         /*Use RTLCK, so close power tracking driver LCK*/
306                         if (!(p_dm_odm->support_ic_type & ODM_RTL8814A)) {
307                                 if (c.phy_lc_calibrate)
308                                         (*c.phy_lc_calibrate)(p_dm_odm);
309                         }
310
311                         delta_LCK = (thermal_value > p_rf_calibrate_info->thermal_value_lck) ? (thermal_value - p_rf_calibrate_info->thermal_value_lck) : (p_rf_calibrate_info->thermal_value_lck - thermal_value);
312                 }
313
314                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK));
315
316                 /* Delta temperature is equal to or larger than 20 centigrade.*/
317                 if (delta_LCK >= c.threshold_iqk) {
318                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk));
319                         p_rf_calibrate_info->thermal_value_lck = thermal_value;
320
321                         /*Use RTLCK, so close power tracking driver LCK*/
322                         if (!(p_dm_odm->support_ic_type & ODM_RTL8814A)) {
323                                 if (c.phy_lc_calibrate)
324                                         (*c.phy_lc_calibrate)(p_dm_odm);
325                         }
326                 }
327         }
328
329         /*3 7. If necessary, move the index of swing table to adjust Tx power.*/
330
331         if (delta > 0 && p_rf_calibrate_info->txpowertrack_control) {
332                 /* "delta" here is used to record the absolute value of differrence. */
333 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
334                 delta = thermal_value > p_hal_data->eeprom_thermal_meter ? (thermal_value - p_hal_data->eeprom_thermal_meter) : (p_hal_data->eeprom_thermal_meter - thermal_value);
335 #else
336                 delta = (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther) ? (thermal_value - p_dm_odm->priv->pmib->dot11RFEntry.ther) : (p_dm_odm->priv->pmib->dot11RFEntry.ther - thermal_value);
337 #endif
338                 if (delta >= TXPWR_TRACK_TABLE_SIZE)
339                         delta = TXPWR_TRACK_TABLE_SIZE - 1;
340
341                 /*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
342
343 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
344                 if (thermal_value > p_hal_data->eeprom_thermal_meter) {
345 #else
346                 if (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther) {
347 #endif
348
349                         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
350                                 p_rf_calibrate_info->delta_power_index_last[p] = p_rf_calibrate_info->delta_power_index[p];     /*recording poer index offset*/
351                                 switch (p) {
352                                 case ODM_RF_PATH_B:
353                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
354                                                 ("delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]));
355
356                                         p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_b[delta];
357                                         p_rf_calibrate_info->absolute_ofdm_swing_idx[p] =  delta_swing_table_idx_tup_b[delta];       /*Record delta swing for mix mode power tracking*/
358                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
359                                                 ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
360                                         break;
361
362                                 case ODM_RF_PATH_C:
363                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
364                                                 ("delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]));
365
366                                         p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_c[delta];
367                                         p_rf_calibrate_info->absolute_ofdm_swing_idx[p] =  delta_swing_table_idx_tup_c[delta];       /*Record delta swing for mix mode power tracking*/
368                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
369                                                 ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
370                                         break;
371
372                                 case ODM_RF_PATH_D:
373                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
374                                                 ("delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]));
375
376                                         p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_d[delta];
377                                         p_rf_calibrate_info->absolute_ofdm_swing_idx[p] =  delta_swing_table_idx_tup_d[delta];       /*Record delta swing for mix mode power tracking*/
378                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
379                                                 ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
380                                         break;
381
382                                 default:
383                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
384                                                 ("delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]));
385
386                                         p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];
387                                         p_rf_calibrate_info->absolute_ofdm_swing_idx[p] =  delta_swing_table_idx_tup_a[delta];        /*Record delta swing for mix mode power tracking*/
388                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
389                                                 ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
390                                         break;
391                                 }
392                         }
393                         /* JJ ADD 20161014 */
394                         if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
395                                 /*Save xtal_offset from Xtal table*/
396                                 p_rf_calibrate_info->xtal_offset_last = p_rf_calibrate_info->xtal_offset;       /*recording last Xtal offset*/
397                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
398                                         ("[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]));
399                                 p_rf_calibrate_info->xtal_offset = delta_swing_table_xtal_up[delta];
400
401                                 if (p_rf_calibrate_info->xtal_offset_last == p_rf_calibrate_info->xtal_offset)
402                                         xtal_offset_eanble = 0;
403                                 else
404                                         xtal_offset_eanble = 1;
405                         }
406
407                 } else {
408                         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
409                                 p_rf_calibrate_info->delta_power_index_last[p] = p_rf_calibrate_info->delta_power_index[p];     /*recording poer index offset*/
410
411                                 switch (p) {
412                                 case ODM_RF_PATH_B:
413                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
414                                                 ("delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]));
415                                         p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];
416                                         p_rf_calibrate_info->absolute_ofdm_swing_idx[p] =  -1 * delta_swing_table_idx_tdown_b[delta];        /*Record delta swing for mix mode power tracking*/
417                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
418                                                 ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
419                                         break;
420
421                                 case ODM_RF_PATH_C:
422                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
423                                                 ("delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]));
424                                         p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_c[delta];
425                                         p_rf_calibrate_info->absolute_ofdm_swing_idx[p] =  -1 * delta_swing_table_idx_tdown_c[delta];        /*Record delta swing for mix mode power tracking*/
426                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
427                                                 ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
428                                         break;
429
430                                 case ODM_RF_PATH_D:
431                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
432                                                 ("delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]));
433                                         p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_d[delta];
434                                         p_rf_calibrate_info->absolute_ofdm_swing_idx[p] =  -1 * delta_swing_table_idx_tdown_d[delta];        /*Record delta swing for mix mode power tracking*/
435                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
436                                                 ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
437                                         break;
438
439                                 default:
440                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
441                                                 ("delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]));
442                                         p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];
443                                         p_rf_calibrate_info->absolute_ofdm_swing_idx[p] =  -1 * delta_swing_table_idx_tdown_a[delta];        /*Record delta swing for mix mode power tracking*/
444                                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
445                                                 ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
446                                         break;
447                                 }
448                         }
449                         /* JJ ADD 20161014 */
450                         if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
451                                 /*Save xtal_offset from Xtal table*/
452                                 p_rf_calibrate_info->xtal_offset_last = p_rf_calibrate_info->xtal_offset;       /*recording last Xtal offset*/
453                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
454                                         ("[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]));
455                                 p_rf_calibrate_info->xtal_offset = delta_swing_table_xtal_down[delta];
456
457                                 if (p_rf_calibrate_info->xtal_offset_last == p_rf_calibrate_info->xtal_offset)
458                                         xtal_offset_eanble = 0;
459                                 else
460                                         xtal_offset_eanble = 1;
461                         }
462
463                 }
464
465                 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
466                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
467                                 ("\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p));
468
469                         if (p_rf_calibrate_info->delta_power_index[p] == p_rf_calibrate_info->delta_power_index_last[p])         /*If Thermal value changes but lookup table value still the same*/
470                                 p_rf_calibrate_info->power_index_offset[p] = 0;
471                         else
472                                 p_rf_calibrate_info->power_index_offset[p] = p_rf_calibrate_info->delta_power_index[p] - p_rf_calibrate_info->delta_power_index_last[p];      /*Power index diff between 2 times Power Tracking*/
473
474                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
475                                 ("[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n", p, p_rf_calibrate_info->power_index_offset[p], p_rf_calibrate_info->delta_power_index[p], p_rf_calibrate_info->delta_power_index_last[p]));
476
477                         p_rf_calibrate_info->OFDM_index[p] = p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] + p_rf_calibrate_info->power_index_offset[p];
478                         p_rf_calibrate_info->CCK_index = p_rf_calibrate_info->bb_swing_idx_cck_base + p_rf_calibrate_info->power_index_offset[p];
479
480                         p_rf_calibrate_info->bb_swing_idx_cck = p_rf_calibrate_info->CCK_index;
481                         p_rf_calibrate_info->bb_swing_idx_ofdm[p] = p_rf_calibrate_info->OFDM_index[p];
482
483                         /*************Print BB Swing base and index Offset*************/
484
485                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
486                                 ("The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", p_rf_calibrate_info->bb_swing_idx_cck, p_rf_calibrate_info->bb_swing_idx_cck_base, p_rf_calibrate_info->power_index_offset[p]));
487                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
488                                 ("The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n", p_rf_calibrate_info->bb_swing_idx_ofdm[p], p, p_rf_calibrate_info->bb_swing_idx_ofdm_base[p], p_rf_calibrate_info->power_index_offset[p]));
489
490                         /*4 7.1 Handle boundary conditions of index.*/
491
492                         if (p_rf_calibrate_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)
493                                 p_rf_calibrate_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;
494                         else if (p_rf_calibrate_info->OFDM_index[p] <= OFDM_min_index)
495                                 p_rf_calibrate_info->OFDM_index[p] = OFDM_min_index;
496                 }
497
498                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
499                         ("\n\n========================================================================================================\n"));
500
501                 if (p_rf_calibrate_info->CCK_index > c.swing_table_size_cck - 1)
502                         p_rf_calibrate_info->CCK_index = c.swing_table_size_cck - 1;
503                 else if (p_rf_calibrate_info->CCK_index <= 0)
504                         p_rf_calibrate_info->CCK_index = 0;
505         } else {
506                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
507                         ("The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, p_rf_calibrate_info->thermal_value: %d\n",
508                         p_rf_calibrate_info->txpowertrack_control, thermal_value, p_rf_calibrate_info->thermal_value));
509
510                 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
511                         p_rf_calibrate_info->power_index_offset[p] = 0;
512         }
513
514         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
515                 ("TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
516                 p_rf_calibrate_info->CCK_index, p_rf_calibrate_info->bb_swing_idx_cck_base));       /*Print Swing base & current*/
517
518         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
519                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
520                         ("TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
521                         p_rf_calibrate_info->OFDM_index[p], p, p_rf_calibrate_info->bb_swing_idx_ofdm_base[p]));
522         }
523
524         if ((p_dm_odm->support_ic_type & ODM_RTL8814A)) {
525                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("power_tracking_type=%d\n", power_tracking_type));
526
527                 if (power_tracking_type == 0) {
528                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
529                         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
530                                 (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
531                 } else if (power_tracking_type == 1) {
532                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n"));
533                         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
534                                 (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_2G_TSSI_5G_MODE, p, 0);
535                 } else if (power_tracking_type == 2) {
536                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n"));
537                         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
538                                 (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_5G_TSSI_2G_MODE, p, 0);
539                 } else if (power_tracking_type == 3) {
540                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking TSSI MODE**********\n"));
541                         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
542                                 (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, TSSI_MODE, p, 0);
543                 }
544                 p_rf_calibrate_info->thermal_value = thermal_value;         /*Record last Power Tracking Thermal value*/
545
546         } else if ((p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_A] != 0 ||
547                 p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_B] != 0 ||
548                 p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_C] != 0 ||
549                 p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_D] != 0) &&
550                 p_rf_calibrate_info->txpowertrack_control && (p_hal_data->eeprom_thermal_meter != 0xff)) {
551                 /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
552
553                 p_rf_calibrate_info->is_tx_power_changed = true;        /*Always true after Tx Power is adjusted by power tracking.*/
554                 /*  */
555                 /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
556                 /* to increase TX power. Otherwise, EVM will be bad. */
557                 /*  */
558                 /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
559                 if (thermal_value > p_rf_calibrate_info->thermal_value) {
560                         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
561                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
562                                         ("Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
563                                         p, p_rf_calibrate_info->power_index_offset[p], delta, thermal_value, p_hal_data->eeprom_thermal_meter, p_rf_calibrate_info->thermal_value));
564                         }
565                 } else if (thermal_value < p_rf_calibrate_info->thermal_value) {        /*Low temperature*/
566                         for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
567                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
568                                         ("Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
569                                         p, p_rf_calibrate_info->power_index_offset[p], delta, thermal_value, p_hal_data->eeprom_thermal_meter, p_rf_calibrate_info->thermal_value));
570                         }
571                 }
572
573 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
574                 if (thermal_value > p_hal_data->eeprom_thermal_meter)
575 #else
576                 if (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther)
577 #endif
578                 {
579                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
580                                 ("Temperature(%d) higher than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
581
582                         if (p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8821 ||
583                             p_dm_odm->support_ic_type == ODM_RTL8812 || p_dm_odm->support_ic_type == ODM_RTL8723B || p_dm_odm->support_ic_type == ODM_RTL8814A ||
584                             p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8188F || p_dm_odm->support_ic_type == ODM_RTL8822B ||
585                             p_dm_odm->support_ic_type == ODM_RTL8723D || p_dm_odm->support_ic_type == ODM_RTL8821C || p_dm_odm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
586
587                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
588                                 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
589                                         (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
590                         } else {
591                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking BBSWING_MODE**********\n"));
592                                 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
593                                         (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, p, indexforchannel);
594                         }
595                 } else {
596                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
597                                 ("Temperature(%d) lower than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
598
599                         if (p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8821 ||
600                             p_dm_odm->support_ic_type == ODM_RTL8812 || p_dm_odm->support_ic_type == ODM_RTL8723B || p_dm_odm->support_ic_type == ODM_RTL8814A ||
601                             p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8188F || p_dm_odm->support_ic_type == ODM_RTL8822B ||
602                             p_dm_odm->support_ic_type == ODM_RTL8723D || p_dm_odm->support_ic_type == ODM_RTL8821C || p_dm_odm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
603
604                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
605                                 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
606                                         (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, indexforchannel);
607                         } else {
608                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking BBSWING_MODE**********\n"));
609                                 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
610                                         (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, p, indexforchannel);
611                         }
612
613                 }
614
615                 p_rf_calibrate_info->bb_swing_idx_cck_base = p_rf_calibrate_info->bb_swing_idx_cck;    /*Record last time Power Tracking result as base.*/
616                 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
617                         p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] = p_rf_calibrate_info->bb_swing_idx_ofdm[p];
618
619                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
620                         ("p_rf_calibrate_info->thermal_value = %d thermal_value= %d\n", p_rf_calibrate_info->thermal_value, thermal_value));
621
622                 p_rf_calibrate_info->thermal_value = thermal_value;         /*Record last Power Tracking Thermal value*/
623
624         }
625
626
627         if (p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8723D || p_dm_odm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
628
629                 if (xtal_offset_eanble != 0 && p_rf_calibrate_info->txpowertrack_control && (p_hal_data->eeprom_thermal_meter != 0xff)) {
630
631                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter Xtal Tracking**********\n"));
632
633 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
634                         if (thermal_value > p_hal_data->eeprom_thermal_meter) {
635 #else
636                         if (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther) {
637 #endif
638                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
639                                         ("Temperature(%d) higher than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
640                                 (*c.odm_txxtaltrack_set_xtal)(p_dm_odm);
641                         } else {
642                                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
643                                         ("Temperature(%d) lower than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
644                                 (*c.odm_txxtaltrack_set_xtal)(p_dm_odm);
645                         }
646                 }
647                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********End Xtal Tracking**********\n"));
648         }
649
650 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
651
652         if (!IS_HARDWARE_TYPE_8723B(adapter)) {
653                 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
654                 if (delta_IQK >= c.threshold_iqk) {
655                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk));
656                         if (!p_rf_calibrate_info->is_iqk_in_progress)
657                                 (*c.do_iqk)(p_dm_odm, delta_IQK, thermal_value, 8);
658                 }
659         }
660         if (p_rf_calibrate_info->dpk_thermal[ODM_RF_PATH_A] != 0) {
661                 if (diff_DPK[ODM_RF_PATH_A] >= c.threshold_dpk) {
662                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
663                         odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk));
664                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
665                 } else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.threshold_dpk)) {
666                         s32 value = 0x20 + (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk);
667
668                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
669                         odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
670                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
671                 } else {
672                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
673                         odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
674                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
675                 }
676         }
677         if (p_rf_calibrate_info->dpk_thermal[ODM_RF_PATH_B] != 0) {
678                 if (diff_DPK[ODM_RF_PATH_B] >= c.threshold_dpk) {
679                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
680                         odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk));
681                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
682                 } else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.threshold_dpk)) {
683                         s32 value = 0x20 + (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk);
684
685                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
686                         odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
687                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
688                 } else {
689                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
690                         odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
691                         odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
692                 }
693         }
694
695 #endif
696
697         ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("<===odm_txpowertracking_callback_thermal_meter\n"));
698
699         p_rf_calibrate_info->tx_powercount = 0;
700 }
701
702
703
704 /* 3============================================================
705  * 3 IQ Calibration
706  * 3============================================================ */
707
708 void
709 odm_reset_iqk_result(
710         void                                    *p_dm_void
711 )
712 {
713         return;
714 }
715 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
716 u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
717 {
718         u8      channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
719                 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165
720         };
721         u8      place = chnl;
722
723
724         if (chnl > 14) {
725                 for (place = 14; place < sizeof(channel_all); place++) {
726                         if (channel_all[place] == chnl)
727                                 return place - 13;
728                 }
729         }
730         return 0;
731
732 }
733 #endif
734
735 void
736 odm_iq_calibrate(
737         struct PHY_DM_STRUCT    *p_dm_odm
738 )
739 {
740         struct _ADAPTER *adapter = p_dm_odm->adapter;
741
742 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
743         if (*p_dm_odm->p_is_fcs_mode_enable)
744                 return;
745 #endif
746
747 #if (DM_ODM_SUPPORT_TYPE & (ODM_CE))
748         if (IS_HARDWARE_TYPE_8812AU(adapter))
749                 return;
750 #endif
751
752         if (p_dm_odm->is_linked) {
753                 if ((*p_dm_odm->p_channel != p_dm_odm->pre_channel) && (!*p_dm_odm->p_is_scan_in_process)) {
754                         p_dm_odm->pre_channel = *p_dm_odm->p_channel;
755                         p_dm_odm->linked_interval = 0;
756                 }
757
758                 if (p_dm_odm->linked_interval < 3)
759                         p_dm_odm->linked_interval++;
760
761                 if (p_dm_odm->linked_interval == 2) {
762                         if (IS_HARDWARE_TYPE_8814A(adapter)) {
763 #if (RTL8814A_SUPPORT == 1)
764                                 phy_iq_calibrate_8814a(p_dm_odm, false);
765 #endif
766                         }
767
768 #if (RTL8822B_SUPPORT == 1)
769                         else if (IS_HARDWARE_TYPE_8822B(adapter))
770                                 phy_iq_calibrate_8822b(p_dm_odm, false);
771 #endif
772
773 #if (RTL8821C_SUPPORT == 1)
774                         else if (IS_HARDWARE_TYPE_8821C(adapter))
775                                 phy_iq_calibrate_8821c(p_dm_odm, false);
776 #endif
777
778 #if (RTL8821A_SUPPORT == 1)
779                         else if (IS_HARDWARE_TYPE_8821(adapter))
780                                 phy_iq_calibrate_8821a(p_dm_odm, false);
781 #endif
782                 }
783         } else
784                 p_dm_odm->linked_interval = 0;
785 }
786
787 void phydm_rf_init(void         *p_dm_void)
788 {
789         struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
790         odm_txpowertracking_init(p_dm_odm);
791
792 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
793         odm_clear_txpowertracking_state(p_dm_odm);
794 #endif
795
796 #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
797 #if (RTL8814A_SUPPORT == 1)
798         if (p_dm_odm->support_ic_type & ODM_RTL8814A)
799                 phy_iq_calibrate_8814a_init(p_dm_odm);
800 #endif
801 #endif
802
803 }
804
805 void phydm_rf_watchdog(void             *p_dm_void)
806 {
807         struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
808 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
809         odm_txpowertracking_check(p_dm_odm);
810         if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
811                 odm_iq_calibrate(p_dm_odm);
812 #endif
813 }