~slonua/+junk/rtl8821ce

« back to all changes in this revision

Viewing changes to hal/phydm/halphyrf_ap.c

  • Committer: Vitaliy Kulikov
  • Date: 2017-09-24 10:25:11 UTC
  • Revision ID: slonua@gmail.com-20170924102511-9q45rcjnowest8ee
init

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#ifndef index_mapping_NUM_88E
 
25
        #define index_mapping_NUM_88E   15
 
26
#endif
 
27
 
 
28
/* #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) */
 
29
 
 
30
#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
 
31
        do {\
 
32
                for (_offset = 0; _offset < _size; _offset++) { \
 
33
                        \
 
34
                        if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
 
35
                                \
 
36
                                if (_offset != 0)\
 
37
                                        _offset--;\
 
38
                                break;\
 
39
                        } \
 
40
                }                       \
 
41
                if (_offset >= _size)\
 
42
                        _offset = _size-1;\
 
43
        } while (0)
 
44
 
 
45
 
 
46
void configure_txpower_track(
 
47
        void            *p_dm_void,
 
48
        struct _TXPWRTRACK_CFG  *p_config
 
49
)
 
50
{
 
51
        struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
 
52
#if RTL8812A_SUPPORT
 
53
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
 
54
        /* if (IS_HARDWARE_TYPE_8812(p_dm_odm->adapter)) */
 
55
        if (p_dm_odm->support_ic_type == ODM_RTL8812)
 
56
                configure_txpower_track_8812a(p_config);
 
57
        /* else */
 
58
#endif
 
59
#endif
 
60
 
 
61
#if RTL8814A_SUPPORT
 
62
        if (p_dm_odm->support_ic_type == ODM_RTL8814A)
 
63
                configure_txpower_track_8814a(p_config);
 
64
#endif
 
65
 
 
66
 
 
67
#if RTL8188E_SUPPORT
 
68
        if (p_dm_odm->support_ic_type == ODM_RTL8188E)
 
69
                configure_txpower_track_8188e(p_config);
 
70
#endif
 
71
 
 
72
#if RTL8197F_SUPPORT
 
73
        if (p_dm_odm->support_ic_type == ODM_RTL8197F)
 
74
                configure_txpower_track_8197f(p_config);
 
75
#endif
 
76
 
 
77
#if RTL8822B_SUPPORT
 
78
        if (p_dm_odm->support_ic_type == ODM_RTL8822B)
 
79
                configure_txpower_track_8822b(p_config);
 
80
#endif
 
81
 
 
82
 
 
83
}
 
84
 
 
85
#if (RTL8192E_SUPPORT == 1)
 
86
void
 
87
odm_txpowertracking_callback_thermal_meter_92e(
 
88
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
 
89
        void            *p_dm_void
 
90
#else
 
91
        struct _ADAPTER *adapter
 
92
#endif
 
93
)
 
94
{
 
95
        struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
 
96
        u8      thermal_value = 0, delta, delta_IQK, delta_LCK, channel, is_decrease, rf_mimo_mode;
 
97
        u8      thermal_value_avg_count = 0;
 
98
        u8     OFDM_min_index = 10; /* OFDM BB Swing should be less than +2.5dB, which is required by Arthur */
 
99
        s8      OFDM_index[2], index ;
 
100
        u32     thermal_value_avg = 0, reg0x18;
 
101
        u32     i = 0, j = 0, rf;
 
102
        s32     value32, CCK_index = 0, ele_A, ele_D, ele_C, X, Y;
 
103
        struct rtl8192cd_priv   *priv = p_dm_odm->priv;
 
104
 
 
105
        rf_mimo_mode = p_dm_odm->rf_type;
 
106
        /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("%s:%d rf_mimo_mode:%d\n", __FUNCTION__, __LINE__, rf_mimo_mode)); */
 
107
 
 
108
#ifdef MP_TEST
 
109
        if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) {
 
110
                channel = priv->pshare->working_channel;
 
111
                if (priv->pshare->mp_txpwr_tracking == false)
 
112
                        return;
 
113
        } else
 
114
#endif
 
115
        {
 
116
                channel = (priv->pmib->dot11RFEntry.dot11channel);
 
117
        }
 
118
 
 
119
        thermal_value = (unsigned char)odm_get_rf_reg(p_dm_odm, RF_PATH_A, ODM_RF_T_METER_92E, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
 
120
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, priv->pshare->thermal_value, priv->pmib->dot11RFEntry.ther));
 
121
 
 
122
 
 
123
        switch (rf_mimo_mode) {
 
124
        case MIMO_1T1R:
 
125
                rf = 1;
 
126
                break;
 
127
        case MIMO_2T2R:
 
128
                rf = 2;
 
129
                break;
 
130
        default:
 
131
                rf = 2;
 
132
                break;
 
133
        }
 
134
 
 
135
        /* Query OFDM path A default setting    Bit[31:21] */
 
136
        ele_D = phy_query_bb_reg(priv, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKOFDM_D);
 
137
        for (i = 0; i < OFDM_TABLE_SIZE_92E; i++) {
 
138
                if (ele_D == (ofdm_swing_table_92e[i] >> 22)) {
 
139
                        OFDM_index[0] = (unsigned char)i;
 
140
                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("PathA 0xC80[31:22] = 0x%x, OFDM_index=%d\n", ele_D, OFDM_index[0]));
 
141
                        break;
 
142
                }
 
143
        }
 
144
 
 
145
        /* Query OFDM path B default setting */
 
146
        if (rf_mimo_mode == MIMO_2T2R) {
 
147
                ele_D = phy_query_bb_reg(priv, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKOFDM_D);
 
148
                for (i = 0; i < OFDM_TABLE_SIZE_92E; i++) {
 
149
                        if (ele_D == (ofdm_swing_table_92e[i] >> 22)) {
 
150
                                OFDM_index[1] = (unsigned char)i;
 
151
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("PathB 0xC88[31:22] = 0x%x, OFDM_index=%d\n", ele_D, OFDM_index[1]));
 
152
                                break;
 
153
                        }
 
154
                }
 
155
        }
 
156
 
 
157
        /* calculate average thermal meter */
 
158
        {
 
159
                priv->pshare->thermal_value_avg_88xx[priv->pshare->thermal_value_avg_index_88xx] = thermal_value;
 
160
                priv->pshare->thermal_value_avg_index_88xx++;
 
161
                if (priv->pshare->thermal_value_avg_index_88xx == AVG_THERMAL_NUM_88XX)
 
162
                        priv->pshare->thermal_value_avg_index_88xx = 0;
 
163
 
 
164
                for (i = 0; i < AVG_THERMAL_NUM_88XX; i++) {
 
165
                        if (priv->pshare->thermal_value_avg_88xx[i]) {
 
166
                                thermal_value_avg += priv->pshare->thermal_value_avg_88xx[i];
 
167
                                thermal_value_avg_count++;
 
168
                        }
 
169
                }
 
170
 
 
171
                if (thermal_value_avg_count) {
 
172
                        thermal_value = (unsigned char)(thermal_value_avg / thermal_value_avg_count);
 
173
                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("AVG Thermal Meter = 0x%x\n", thermal_value));
 
174
                }
 
175
        }
 
176
 
 
177
        /* Initialize */
 
178
        if (!priv->pshare->thermal_value) {
 
179
                priv->pshare->thermal_value = priv->pmib->dot11RFEntry.ther;
 
180
                priv->pshare->thermal_value_iqk = thermal_value;
 
181
                priv->pshare->thermal_value_lck = thermal_value;
 
182
        }
 
183
 
 
184
        if (thermal_value != priv->pshare->thermal_value) {
 
185
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\n******** START POWER TRACKING ********\n"));
 
186
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, priv->pshare->thermal_value, priv->pmib->dot11RFEntry.ther));
 
187
 
 
188
                delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
 
189
                delta_IQK = RTL_ABS(thermal_value, priv->pshare->thermal_value_iqk);
 
190
                delta_LCK = RTL_ABS(thermal_value, priv->pshare->thermal_value_lck);
 
191
                is_decrease = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 1 : 0);
 
192
 
 
193
#ifdef _TRACKING_TABLE_FILE
 
194
                if (priv->pshare->rf_ft_var.pwr_track_file) {
 
195
                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("diff: (%s)%d ==> get index from table : %d)\n", (is_decrease ? "-" : "+"), delta, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0)));
 
196
 
 
197
                        if (is_decrease) {
 
198
                                for (i = 0; i < rf; i++) {
 
199
                                        OFDM_index[i] = priv->pshare->OFDM_index0[i] + get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0);
 
200
                                        OFDM_index[i] = ((OFDM_index[i] > (OFDM_TABLE_SIZE_92E- 1)) ? (OFDM_TABLE_SIZE_92E - 1) : OFDM_index[i]);
 
201
                                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> decrese power ---> new OFDM_INDEX:%d (%d + %d)\n", OFDM_index[i], priv->pshare->OFDM_index0[i], get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0)));
 
202
                                        CCK_index = priv->pshare->CCK_index0 + get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1);
 
203
                                        CCK_index = ((CCK_index > (CCK_TABLE_SIZE_92E - 1)) ? (CCK_TABLE_SIZE_92E - 1) : CCK_index);
 
204
                                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> Decrese power ---> new CCK_INDEX:%d (%d + %d)\n",  CCK_index, priv->pshare->CCK_index0, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1)));
 
205
                                }
 
206
                        } else {
 
207
                                for (i = 0; i < rf; i++) {
 
208
                                        OFDM_index[i] = priv->pshare->OFDM_index0[i] - get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0);
 
209
                                        OFDM_index[i] = ((OFDM_index[i] < OFDM_min_index) ?  OFDM_min_index : OFDM_index[i]);
 
210
                                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> Increse power ---> new OFDM_INDEX:%d (%d - %d)\n", OFDM_index[i], priv->pshare->OFDM_index0[i], get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0)));
 
211
                                        CCK_index = priv->pshare->CCK_index0 - get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1);
 
212
                                        CCK_index = ((CCK_index < 0) ? 0 : CCK_index);
 
213
                                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> Increse power ---> new CCK_INDEX:%d (%d - %d)\n", CCK_index, priv->pshare->CCK_index0, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1)));
 
214
                                }
 
215
                        }
 
216
                }
 
217
#endif /* CFG_TRACKING_TABLE_FILE */
 
218
 
 
219
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("ofdm_swing_table_92e[(unsigned int)OFDM_index[0]] = %x\n", ofdm_swing_table_92e[(unsigned int)OFDM_index[0]]));
 
220
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("ofdm_swing_table_92e[(unsigned int)OFDM_index[1]] = %x\n", ofdm_swing_table_92e[(unsigned int)OFDM_index[1]]));
 
221
 
 
222
                /* Adujst OFDM Ant_A according to IQK result */
 
223
                ele_D = (ofdm_swing_table_92e[(unsigned int)OFDM_index[0]] & 0xFFC00000) >> 22;
 
224
                X = priv->pshare->rege94;
 
225
                Y = priv->pshare->rege9c;
 
226
 
 
227
                if (X != 0) {
 
228
                        if ((X & 0x00000200) != 0)
 
229
                                X = X | 0xFFFFFC00;
 
230
                        ele_A = ((X * ele_D) >> 8) & 0x000003FF;
 
231
 
 
232
                        /* new element C = element D x Y */
 
233
                        if ((Y & 0x00000200) != 0)
 
234
                                Y = Y | 0xFFFFFC00;
 
235
                        ele_C = ((Y * ele_D) >> 8) & 0x000003FF;
 
236
 
 
237
                        /* wirte new elements A, C, D to regC80 and regC94, element B is always 0 */
 
238
                        value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
 
239
                        phy_set_bb_reg(priv, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD, value32);
 
240
 
 
241
                        value32 = (ele_C & 0x000003C0) >> 6;
 
242
                        phy_set_bb_reg(priv, REG_OFDM_0_XC_TX_AFE, MASKH4BITS, value32);
 
243
 
 
244
                        value32 = ((X * ele_D) >> 7) & 0x01;
 
245
                        phy_set_bb_reg(priv, REG_OFDM_0_ECCA_THRESHOLD, BIT(24), value32);
 
246
                } else {
 
247
                        phy_set_bb_reg(priv, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD, ofdm_swing_table_92e[(unsigned int)OFDM_index[0]]);
 
248
                        phy_set_bb_reg(priv, REG_OFDM_0_XC_TX_AFE, MASKH4BITS, 0x00);
 
249
                        phy_set_bb_reg(priv, REG_OFDM_0_ECCA_THRESHOLD, BIT(24), 0x00);
 
250
                }
 
251
 
 
252
                set_CCK_swing_index(priv, CCK_index);
 
253
 
 
254
                if (rf == 2) {
 
255
                        ele_D = (ofdm_swing_table_92e[(unsigned int)OFDM_index[1]] & 0xFFC00000) >> 22;
 
256
                        X = priv->pshare->regeb4;
 
257
                        Y = priv->pshare->regebc;
 
258
 
 
259
                        if (X != 0) {
 
260
                                if ((X & 0x00000200) != 0)      /* consider minus */
 
261
                                        X = X | 0xFFFFFC00;
 
262
                                ele_A = ((X * ele_D) >> 8) & 0x000003FF;
 
263
 
 
264
                                /* new element C = element D x Y */
 
265
                                if ((Y & 0x00000200) != 0)
 
266
                                        Y = Y | 0xFFFFFC00;
 
267
                                ele_C = ((Y * ele_D) >> 8) & 0x00003FF;
 
268
 
 
269
                                /* wirte new elements A, C, D to regC88 and regC9C, element B is always 0 */
 
270
                                value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
 
271
                                phy_set_bb_reg(priv, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD, value32);
 
272
 
 
273
                                value32 = (ele_C & 0x000003C0) >> 6;
 
274
                                phy_set_bb_reg(priv, REG_OFDM_0_XD_TX_AFE, MASKH4BITS, value32);
 
275
 
 
276
                                value32 = ((X * ele_D) >> 7) & 0x01;
 
277
                                phy_set_bb_reg(priv, REG_OFDM_0_ECCA_THRESHOLD, BIT(28), value32);
 
278
                        } else {
 
279
                                phy_set_bb_reg(priv, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD, ofdm_swing_table_92e[(unsigned int)OFDM_index[1]]);
 
280
                                phy_set_bb_reg(priv, REG_OFDM_0_XD_TX_AFE, MASKH4BITS, 0x00);
 
281
                                phy_set_bb_reg(priv, REG_OFDM_0_ECCA_THRESHOLD, BIT(28), 0x00);
 
282
                        }
 
283
 
 
284
                }
 
285
 
 
286
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("0xc80 = 0x%x\n", phy_query_bb_reg(priv, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD)));
 
287
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("0xc88 = 0x%x\n", phy_query_bb_reg(priv, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD)));
 
288
 
 
289
                if (delta_IQK > 3) {
 
290
                        priv->pshare->thermal_value_iqk = thermal_value;
 
291
#ifdef MP_TEST
 
292
                        if (!(priv->pshare->rf_ft_var.mp_specific && (OPMODE & (WIFI_MP_CTX_BACKGROUND | WIFI_MP_CTX_PACKET))))
 
293
#endif
 
294
                                phy_iq_calibrate_8192e(p_dm_odm, false);
 
295
                }
 
296
 
 
297
                if (delta_LCK > 8) {
 
298
                        RTL_W8(0x522, 0xff);
 
299
                        reg0x18 = phy_query_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, 1);
 
300
                        phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 1);
 
301
                        phy_set_rf_reg(priv, RF_PATH_A, 0x18, BIT(15), 1);
 
302
                        delay_ms(1);
 
303
                        phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 0);
 
304
                        phy_set_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, reg0x18);
 
305
                        RTL_W8(0x522, 0x0);
 
306
                        priv->pshare->thermal_value_lck = thermal_value;
 
307
                }
 
308
        }
 
309
 
 
310
        /* update thermal meter value */
 
311
        priv->pshare->thermal_value = thermal_value;
 
312
        for (i = 0 ; i < rf ; i++)
 
313
                priv->pshare->OFDM_index[i] = OFDM_index[i];
 
314
        priv->pshare->CCK_index = CCK_index;
 
315
 
 
316
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\n******** END:%s() ********\n", __FUNCTION__));
 
317
}
 
318
#endif
 
319
 
 
320
 
 
321
 
 
322
#if (RTL8197F_SUPPORT == 1 || RTL8822B_SUPPORT == 1)
 
323
void
 
324
odm_txpowertracking_callback_thermal_meter_jaguar_series3(
 
325
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
 
326
        void            *p_dm_void
 
327
#else
 
328
        struct _ADAPTER *adapter
 
329
#endif
 
330
)
 
331
{
 
332
#if 1
 
333
        struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
 
334
        u8                      thermal_value = 0, delta, delta_LCK, delta_IQK, channel, is_increase;
 
335
        u8                      thermal_value_avg_count = 0, p = 0, i = 0;
 
336
        u32                     thermal_value_avg = 0;
 
337
        struct rtl8192cd_priv           *priv = p_dm_odm->priv;
 
338
        struct _TXPWRTRACK_CFG  c;
 
339
        struct odm_rf_calibration_structure     *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
 
340
 
 
341
        /*4 1. The following TWO tables decide the final index of OFDM/CCK swing table.*/
 
342
        u8                      *delta_swing_table_idx_tup_a = NULL, *delta_swing_table_idx_tdown_a = NULL;
 
343
        u8                      *delta_swing_table_idx_tup_b = NULL, *delta_swing_table_idx_tdown_b = NULL;
 
344
        u8                      *delta_swing_table_idx_tup_cck_a = NULL, *delta_swing_table_idx_tdown_cck_a = NULL;
 
345
        u8                      *delta_swing_table_idx_tup_cck_b = NULL, *delta_swing_table_idx_tdown_cck_b = NULL;
 
346
        /*for 8814 add by Yu Chen*/
 
347
        u8                      *delta_swing_table_idx_tup_c = NULL, *delta_swing_table_idx_tdown_c = NULL;
 
348
        u8                      *delta_swing_table_idx_tup_d = NULL, *delta_swing_table_idx_tdown_d = NULL;
 
349
        u8                      *delta_swing_table_idx_tup_cck_c = NULL, *delta_swing_table_idx_tdown_cck_c = NULL;
 
350
        u8                      *delta_swing_table_idx_tup_cck_d = NULL, *delta_swing_table_idx_tdown_cck_d = NULL;
 
351
 
 
352
#ifdef MP_TEST
 
353
        if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) {
 
354
                channel = priv->pshare->working_channel;
 
355
                if (priv->pshare->mp_txpwr_tracking == false)
 
356
                        return;
 
357
        } else
 
358
#endif
 
359
        {
 
360
                channel = (priv->pmib->dot11RFEntry.dot11channel);
 
361
        }
 
362
 
 
363
        configure_txpower_track(p_dm_odm, &c);
 
364
 
 
365
        (*c.get_delta_all_swing_table)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
 
366
                (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b,
 
367
                (u8 **)&delta_swing_table_idx_tup_cck_a, (u8 **)&delta_swing_table_idx_tdown_cck_a,
 
368
                (u8 **)&delta_swing_table_idx_tup_cck_b, (u8 **)&delta_swing_table_idx_tdown_cck_b);
 
369
 
 
370
        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*/
 
371
 
 
372
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
373
                ("Readback Thermal Meter = 0x%x(%d) EEPROMthermalmeter 0x%x(%d)\n"
 
374
                , thermal_value, thermal_value, priv->pmib->dot11RFEntry.ther, priv->pmib->dot11RFEntry.ther));
 
375
 
 
376
        /* Initialize */
 
377
        if (!p_dm_odm->rf_calibrate_info.thermal_value)
 
378
                p_dm_odm->rf_calibrate_info.thermal_value = priv->pmib->dot11RFEntry.ther;
 
379
 
 
380
        if (!p_dm_odm->rf_calibrate_info.thermal_value_lck)
 
381
                p_dm_odm->rf_calibrate_info.thermal_value_lck = priv->pmib->dot11RFEntry.ther;
 
382
 
 
383
        if (!p_dm_odm->rf_calibrate_info.thermal_value_iqk)
 
384
                p_dm_odm->rf_calibrate_info.thermal_value_iqk = priv->pmib->dot11RFEntry.ther;
 
385
 
 
386
        /* calculate average thermal meter */
 
387
        p_dm_odm->rf_calibrate_info.thermal_value_avg[p_dm_odm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
 
388
        p_dm_odm->rf_calibrate_info.thermal_value_avg_index++;
 
389
 
 
390
        if (p_dm_odm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num)   /*Average times =  c.average_thermal_num*/
 
391
                p_dm_odm->rf_calibrate_info.thermal_value_avg_index = 0;
 
392
 
 
393
        for (i = 0; i < c.average_thermal_num; i++) {
 
394
                if (p_dm_odm->rf_calibrate_info.thermal_value_avg[i]) {
 
395
                        thermal_value_avg += p_dm_odm->rf_calibrate_info.thermal_value_avg[i];
 
396
                        thermal_value_avg_count++;
 
397
                }
 
398
        }
 
399
 
 
400
        if (thermal_value_avg_count) {/*Calculate Average thermal_value after average enough times*/
 
401
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
402
                        ("thermal_value_avg=0x%x(%d)  thermal_value_avg_count = %d\n"
 
403
                        , thermal_value_avg, thermal_value_avg, thermal_value_avg_count));
 
404
 
 
405
                thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
 
406
 
 
407
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
408
                        ("AVG Thermal Meter = 0x%X(%d), EEPROMthermalmeter = 0x%X(%d)\n", thermal_value, thermal_value, priv->pmib->dot11RFEntry.ther, priv->pmib->dot11RFEntry.ther));
 
409
        }
 
410
 
 
411
        /*4 Calculate delta, delta_LCK, delta_IQK.*/
 
412
        delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
 
413
        delta_LCK = RTL_ABS(thermal_value, p_dm_odm->rf_calibrate_info.thermal_value_lck);
 
414
        delta_IQK = RTL_ABS(thermal_value, p_dm_odm->rf_calibrate_info.thermal_value_iqk);
 
415
        is_increase = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 0 : 1);
 
416
 
 
417
        if (delta > 29) { /* power track table index(thermal diff.) upper bound*/
 
418
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta(%d) > 29, set delta to 29\n", delta));
 
419
                delta = 29;
 
420
        }
 
421
 
 
422
 
 
423
        /*4 if necessary, do LCK.*/
 
424
        if (delta_LCK > c.threshold_iqk) {
 
425
                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));
 
426
                p_dm_odm->rf_calibrate_info.thermal_value_lck = thermal_value;
 
427
#if (RTL8822B_SUPPORT != 1)
 
428
                if (!(p_dm_odm->support_ic_type & ODM_RTL8822B)) {
 
429
                if (c.phy_lc_calibrate)
 
430
                        (*c.phy_lc_calibrate)(p_dm_odm);
 
431
        }
 
432
#endif
 
433
        }
 
434
 
 
435
        if (delta_IQK > c.threshold_iqk) {
 
436
                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));
 
437
                p_dm_odm->rf_calibrate_info.thermal_value_iqk = thermal_value;
 
438
                if (c.do_iqk)
 
439
                        (*c.do_iqk)(p_dm_odm, true, 0, 0);
 
440
        }
 
441
 
 
442
        if (!priv->pmib->dot11RFEntry.ther)     /*Don't do power tracking since no calibrated thermal value*/
 
443
                return;
 
444
 
 
445
        /*4 Do Power Tracking*/
 
446
 
 
447
        if (thermal_value != p_dm_odm->rf_calibrate_info.thermal_value) {
 
448
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
449
                             ("\n\n******** START POWER TRACKING ********\n"));
 
450
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
451
                        ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n",
 
452
                        thermal_value, p_dm_odm->rf_calibrate_info.thermal_value, priv->pmib->dot11RFEntry.ther));
 
453
 
 
454
#ifdef _TRACKING_TABLE_FILE
 
455
                if (priv->pshare->rf_ft_var.pwr_track_file) {
 
456
                        if (is_increase) {                      /*thermal is higher than base*/
 
457
                                for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
 
458
                                        switch (p) {
 
459
                                        case ODM_RF_PATH_B:
 
460
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
461
                                                        ("delta_swing_table_idx_tup_b[%d] = %d delta_swing_table_idx_tup_cck_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta], delta, delta_swing_table_idx_tup_cck_b[delta]));
 
462
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta];
 
463
                                                p_rf_calibrate_info->absolute_cck_swing_idx[p] = delta_swing_table_idx_tup_cck_b[delta];
 
464
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
465
                                                        ("******Temp is higher and pRF->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d pRF->absolute_cck_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p], p_rf_calibrate_info->absolute_cck_swing_idx[p]));
 
466
                                                break;
 
467
 
 
468
                                        case ODM_RF_PATH_C:
 
469
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
470
                                                        ("delta_swing_table_idx_tup_c[%d] = %d delta_swing_table_idx_tup_cck_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta], delta, delta_swing_table_idx_tup_cck_c[delta]));
 
471
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta];
 
472
                                                p_rf_calibrate_info->absolute_cck_swing_idx[p] = delta_swing_table_idx_tup_cck_c[delta];
 
473
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
474
                                                        ("******Temp is higher and pRF->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d pRF->absolute_cck_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p], p_rf_calibrate_info->absolute_cck_swing_idx[p]));
 
475
                                                break;
 
476
 
 
477
                                        case ODM_RF_PATH_D:
 
478
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
479
                                                        ("delta_swing_table_idx_tup_d[%d] = %d delta_swing_table_idx_tup_cck_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta], delta, delta_swing_table_idx_tup_cck_d[delta]));
 
480
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta];
 
481
                                                p_rf_calibrate_info->absolute_cck_swing_idx[p] = delta_swing_table_idx_tup_cck_d[delta];
 
482
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
483
                                                        ("******Temp is higher and pRF->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d pRF->absolute_cck_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p], p_rf_calibrate_info->absolute_cck_swing_idx[p]));
 
484
                                                break;
 
485
                                        default:
 
486
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
487
                                                        ("delta_swing_table_idx_tup_a[%d] = %d delta_swing_table_idx_tup_cck_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta], delta, delta_swing_table_idx_tup_cck_a[delta]));
 
488
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta];
 
489
                                                p_rf_calibrate_info->absolute_cck_swing_idx[p] = delta_swing_table_idx_tup_cck_a[delta];
 
490
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
491
                                                        ("******Temp is higher and pRF->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d pRF->absolute_cck_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p], p_rf_calibrate_info->absolute_cck_swing_idx[p]));
 
492
                                                break;
 
493
                                        }
 
494
                                }
 
495
                        } else {                        /* thermal is lower than base*/
 
496
                                for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
 
497
                                        switch (p) {
 
498
                                        case ODM_RF_PATH_B:
 
499
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
500
                                                        ("delta_swing_table_idx_tdown_b[%d] = %d   delta_swing_table_idx_tdown_cck_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta], delta, delta_swing_table_idx_tdown_cck_b[delta]));
 
501
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta];
 
502
                                                p_rf_calibrate_info->absolute_cck_swing_idx[p] = -1 * delta_swing_table_idx_tdown_cck_b[delta];
 
503
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
504
                                                        ("******Temp is lower and pRF->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d   pRF->absolute_cck_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p], p_rf_calibrate_info->absolute_cck_swing_idx[p]));
 
505
                                                break;
 
506
 
 
507
                                        case ODM_RF_PATH_C:
 
508
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
509
                                                        ("delta_swing_table_idx_tdown_c[%d] = %d   delta_swing_table_idx_tdown_cck_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta], delta, delta_swing_table_idx_tdown_cck_c[delta]));
 
510
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta];
 
511
                                                p_rf_calibrate_info->absolute_cck_swing_idx[p] = -1 * delta_swing_table_idx_tdown_cck_c[delta];
 
512
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
513
                                                        ("******Temp is lower and pRF->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d   pRF->absolute_cck_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p], p_rf_calibrate_info->absolute_cck_swing_idx[p]));
 
514
                                                break;
 
515
 
 
516
                                        case ODM_RF_PATH_D:
 
517
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
518
                                                        ("delta_swing_table_idx_tdown_d[%d] = %d   delta_swing_table_idx_tdown_cck_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta], delta, delta_swing_table_idx_tdown_cck_d[delta]));
 
519
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta];
 
520
                                                p_rf_calibrate_info->absolute_cck_swing_idx[p] = -1 * delta_swing_table_idx_tdown_cck_d[delta];
 
521
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
522
                                                        ("******Temp is lower and pRF->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d   pRF->absolute_cck_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p], p_rf_calibrate_info->absolute_cck_swing_idx[p]));
 
523
                                                break;
 
524
 
 
525
                                        default:
 
526
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
527
                                                        ("delta_swing_table_idx_tdown_a[%d] = %d   delta_swing_table_idx_tdown_cck_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta], delta, delta_swing_table_idx_tdown_cck_a[delta]));
 
528
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta];
 
529
                                                p_rf_calibrate_info->absolute_cck_swing_idx[p] = -1 * delta_swing_table_idx_tdown_cck_a[delta];
 
530
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
531
                                                        ("******Temp is lower and pRF->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d   pRF->absolute_cck_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p], p_rf_calibrate_info->absolute_cck_swing_idx[p]));
 
532
                                                break;
 
533
                                        }
 
534
                                }
 
535
                        }
 
536
 
 
537
                        if (is_increase) {
 
538
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> increse power --->\n"));
 
539
                                if (GET_CHIP_VER(priv) == VERSION_8197F) {
 
540
                                        for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
 
541
                                                (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, p, 0);
 
542
                                } else if (GET_CHIP_VER(priv) == VERSION_8822B) {
 
543
                                        for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
 
544
                                                (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
 
545
                                }
 
546
                        } else {
 
547
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> decrese power --->\n"));
 
548
                                if (GET_CHIP_VER(priv) == VERSION_8197F) {
 
549
                                        for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
 
550
                                                (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, p, 0);
 
551
                                } else if (GET_CHIP_VER(priv) == VERSION_8822B) {
 
552
                                        for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
 
553
                                                (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
 
554
                                }
 
555
                        }
 
556
                }
 
557
#endif
 
558
 
 
559
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\n******** END:%s() ********\n\n", __func__));
 
560
                /*update thermal meter value*/
 
561
                p_dm_odm->rf_calibrate_info.thermal_value =  thermal_value;
 
562
 
 
563
        }
 
564
 
 
565
#endif
 
566
}
 
567
#endif
 
568
 
 
569
/*#if (RTL8814A_SUPPORT == 1)*/
 
570
#if (RTL8814A_SUPPORT == 1)
 
571
 
 
572
void
 
573
odm_txpowertracking_callback_thermal_meter_jaguar_series2(
 
574
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
 
575
        void            *p_dm_void
 
576
#else
 
577
        struct _ADAPTER *adapter
 
578
#endif
 
579
)
 
580
{
 
581
        struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
 
582
        u8                      thermal_value = 0, delta, delta_LCK, delta_IQK, channel, is_increase;
 
583
        u8                      thermal_value_avg_count = 0, p = 0, i = 0;
 
584
        u32                     thermal_value_avg = 0, reg0x18;
 
585
        u32                     bb_swing_reg[4] = {REG_A_TX_SCALE_JAGUAR, REG_B_TX_SCALE_JAGUAR, REG_C_TX_SCALE_JAGUAR2, REG_D_TX_SCALE_JAGUAR2};
 
586
        s32                     ele_D;
 
587
        u32                     bb_swing_idx;
 
588
        struct rtl8192cd_priv   *priv = p_dm_odm->priv;
 
589
        struct _TXPWRTRACK_CFG  c;
 
590
        boolean                 is_tssi_enable = false;
 
591
        struct odm_rf_calibration_structure     *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
 
592
 
 
593
        /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
 
594
        u8                      *delta_swing_table_idx_tup_a = NULL, *delta_swing_table_idx_tdown_a = NULL;
 
595
        u8                      *delta_swing_table_idx_tup_b = NULL, *delta_swing_table_idx_tdown_b = NULL;
 
596
        /* for 8814 add by Yu Chen */
 
597
        u8                      *delta_swing_table_idx_tup_c = NULL, *delta_swing_table_idx_tdown_c = NULL;
 
598
        u8                      *delta_swing_table_idx_tup_d = NULL, *delta_swing_table_idx_tdown_d = NULL;
 
599
 
 
600
#ifdef MP_TEST
 
601
        if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) {
 
602
                channel = priv->pshare->working_channel;
 
603
                if (priv->pshare->mp_txpwr_tracking == false)
 
604
                        return;
 
605
        } else
 
606
#endif
 
607
        {
 
608
                channel = (priv->pmib->dot11RFEntry.dot11channel);
 
609
        }
 
610
 
 
611
        configure_txpower_track(p_dm_odm, &c);
 
612
        p_rf_calibrate_info->default_ofdm_index = priv->pshare->OFDM_index0[ODM_RF_PATH_A];
 
613
 
 
614
        (*c.get_delta_swing_table)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
 
615
                (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
 
616
 
 
617
        if (p_dm_odm->support_ic_type & ODM_RTL8814A)   /* for 8814 path C & D */
 
618
                (*c.get_delta_swing_table8814only)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
 
619
                        (u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
 
620
 
 
621
        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 */
 
622
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
623
                ("\nReadback Thermal Meter = 0x%x, pre thermal meter 0x%x, EEPROMthermalmeter 0x%x\n", thermal_value, p_dm_odm->rf_calibrate_info.thermal_value, priv->pmib->dot11RFEntry.ther));
 
624
 
 
625
        /* Initialize */
 
626
        if (!p_dm_odm->rf_calibrate_info.thermal_value)
 
627
                p_dm_odm->rf_calibrate_info.thermal_value = priv->pmib->dot11RFEntry.ther;
 
628
 
 
629
        if (!p_dm_odm->rf_calibrate_info.thermal_value_lck)
 
630
                p_dm_odm->rf_calibrate_info.thermal_value_lck = priv->pmib->dot11RFEntry.ther;
 
631
 
 
632
        if (!p_dm_odm->rf_calibrate_info.thermal_value_iqk)
 
633
                p_dm_odm->rf_calibrate_info.thermal_value_iqk = priv->pmib->dot11RFEntry.ther;
 
634
 
 
635
        is_tssi_enable = (boolean)odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_A, REG_RF_TX_GAIN_OFFSET, BIT(7));       /* check TSSI enable */
 
636
 
 
637
        /* 4 Query OFDM BB swing default setting        Bit[31:21] */
 
638
        for (p = ODM_RF_PATH_A ; p < c.rf_path_count ; p++) {
 
639
                ele_D = odm_get_bb_reg(p_dm_odm, bb_swing_reg[p], 0xffe00000);
 
640
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
641
                        ("0x%x:0x%x ([31:21] = 0x%x)\n", bb_swing_reg[p], odm_get_bb_reg(p_dm_odm, bb_swing_reg[p], MASKDWORD), ele_D));
 
642
 
 
643
                for (bb_swing_idx = 0; bb_swing_idx < TXSCALE_TABLE_SIZE; bb_swing_idx++) {/* 4 */
 
644
                        if (ele_D == tx_scaling_table_jaguar[bb_swing_idx]) {
 
645
                                p_dm_odm->rf_calibrate_info.OFDM_index[p] = (u8)bb_swing_idx;
 
646
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
647
                                        ("OFDM_index[%d]=%d\n", p, p_dm_odm->rf_calibrate_info.OFDM_index[p]));
 
648
                                break;
 
649
                        }
 
650
                }
 
651
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("kfree_offset[%d]=%d\n", p, p_rf_calibrate_info->kfree_offset[p]));
 
652
 
 
653
        }
 
654
 
 
655
        /* calculate average thermal meter */
 
656
        p_dm_odm->rf_calibrate_info.thermal_value_avg[p_dm_odm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
 
657
        p_dm_odm->rf_calibrate_info.thermal_value_avg_index++;
 
658
        if (p_dm_odm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num)  /* Average times =  c.average_thermal_num */
 
659
                p_dm_odm->rf_calibrate_info.thermal_value_avg_index = 0;
 
660
 
 
661
        for (i = 0; i < c.average_thermal_num; i++) {
 
662
                if (p_dm_odm->rf_calibrate_info.thermal_value_avg[i]) {
 
663
                        thermal_value_avg += p_dm_odm->rf_calibrate_info.thermal_value_avg[i];
 
664
                        thermal_value_avg_count++;
 
665
                }
 
666
        }
 
667
 
 
668
        if (thermal_value_avg_count) {            /* Calculate Average thermal_value after average enough times */
 
669
                thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
 
670
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
671
                        ("AVG Thermal Meter = 0x%X, EEPROMthermalmeter = 0x%X\n", thermal_value, priv->pmib->dot11RFEntry.ther));
 
672
        }
 
673
 
 
674
        /* 4 Calculate delta, delta_LCK, delta_IQK. */
 
675
        delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
 
676
        delta_LCK = RTL_ABS(thermal_value, p_dm_odm->rf_calibrate_info.thermal_value_lck);
 
677
        delta_IQK = RTL_ABS(thermal_value, p_dm_odm->rf_calibrate_info.thermal_value_iqk);
 
678
        is_increase = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 0 : 1);
 
679
 
 
680
        /* 4 if necessary, do LCK. */
 
681
        if (!(p_dm_odm->support_ic_type & ODM_RTL8821)) {
 
682
                if (delta_LCK > c.threshold_iqk) {
 
683
                        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));
 
684
                        p_dm_odm->rf_calibrate_info.thermal_value_lck = thermal_value;
 
685
 
 
686
                        /*Use RTLCK, so close power tracking driver LCK*/
 
687
#if (RTL8814A_SUPPORT != 1)
 
688
                        if (!(p_dm_odm->support_ic_type & ODM_RTL8814A)) {
 
689
                                if (c.phy_lc_calibrate)
 
690
                                        (*c.phy_lc_calibrate)(p_dm_odm);
 
691
                        }
 
692
#endif
 
693
                }
 
694
        }
 
695
 
 
696
        if (delta_IQK > c.threshold_iqk) {
 
697
                panic_printk("%s(%d)\n", __FUNCTION__, __LINE__);
 
698
                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));
 
699
                p_dm_odm->rf_calibrate_info.thermal_value_iqk = thermal_value;
 
700
                if (c.do_iqk)
 
701
                        (*c.do_iqk)(p_dm_odm, true, 0, 0);
 
702
        }
 
703
 
 
704
        if (!priv->pmib->dot11RFEntry.ther)     /*Don't do power tracking since no calibrated thermal value*/
 
705
                return;
 
706
 
 
707
        /* 4 Do Power Tracking */
 
708
 
 
709
        if (is_tssi_enable == true) {
 
710
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter PURE TSSI MODE**********\n"));
 
711
                for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
 
712
                        (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, TSSI_MODE, p, 0);
 
713
        } else if (thermal_value != p_dm_odm->rf_calibrate_info.thermal_value) {
 
714
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
715
                             ("\n******** START POWER TRACKING ********\n"));
 
716
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
717
                        ("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, p_dm_odm->rf_calibrate_info.thermal_value, priv->pmib->dot11RFEntry.ther));
 
718
 
 
719
#ifdef _TRACKING_TABLE_FILE
 
720
                if (priv->pshare->rf_ft_var.pwr_track_file) {
 
721
                        if (is_increase) {              /* thermal is higher than base */
 
722
                                for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
 
723
                                        switch (p) {
 
724
                                        case ODM_RF_PATH_B:
 
725
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
726
                                                        ("delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]));
 
727
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta];       /* Record delta swing for mix mode power tracking */
 
728
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
729
                                                        ("******Temp is higher and p_dm_odm->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
 
730
                                                break;
 
731
 
 
732
                                        case ODM_RF_PATH_C:
 
733
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
734
                                                        ("delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]));
 
735
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta];       /* Record delta swing for mix mode power tracking */
 
736
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
737
                                                        ("******Temp is higher and p_dm_odm->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
 
738
                                                break;
 
739
 
 
740
                                        case ODM_RF_PATH_D:
 
741
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
742
                                                        ("delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]));
 
743
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta];       /* Record delta swing for mix mode power tracking */
 
744
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
745
                                                        ("******Temp is higher and p_dm_odm->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
 
746
                                                break;
 
747
 
 
748
                                        default:
 
749
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
750
                                                        ("delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]));
 
751
                                                p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta];        /* Record delta swing for mix mode power tracking */
 
752
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
753
                                                        ("******Temp is higher and p_dm_odm->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
 
754
                                                break;
 
755
                                        }
 
756
                                }
 
757
                        } else {                                /* thermal is lower than base */
 
758
                                for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
 
759
                                        switch (p) {
 
760
                                        case ODM_RF_PATH_B:
 
761
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
762
                                                        ("delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]));
 
763
                                                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 */
 
764
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
765
                                                        ("******Temp is lower and p_dm_odm->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
 
766
                                                break;
 
767
 
 
768
                                        case ODM_RF_PATH_C:
 
769
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
770
                                                        ("delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]));
 
771
                                                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 */
 
772
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
773
                                                        ("******Temp is lower and p_dm_odm->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
 
774
                                                break;
 
775
 
 
776
                                        case ODM_RF_PATH_D:
 
777
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
778
                                                        ("delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]));
 
779
                                                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 */
 
780
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
781
                                                        ("******Temp is lower and p_dm_odm->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
 
782
                                                break;
 
783
 
 
784
                                        default:
 
785
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
786
                                                        ("delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]));
 
787
                                                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 */
 
788
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
789
                                                        ("******Temp is lower and p_dm_odm->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
 
790
                                                break;
 
791
                                        }
 
792
                                }
 
793
                        }
 
794
 
 
795
                        if (is_increase) {
 
796
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> increse power --->\n"));
 
797
                                for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
 
798
                                        (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
 
799
                        } else {
 
800
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> decrese power --->\n"));
 
801
                                for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
 
802
                                        (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
 
803
                        }
 
804
                }
 
805
#endif
 
806
 
 
807
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\n******** END:%s() ********\n", __FUNCTION__));
 
808
                /* update thermal meter value */
 
809
                p_dm_odm->rf_calibrate_info.thermal_value =  thermal_value;
 
810
 
 
811
        }
 
812
}
 
813
#endif
 
814
 
 
815
#if (RTL8812A_SUPPORT == 1 || RTL8881A_SUPPORT == 1)
 
816
void
 
817
odm_txpowertracking_callback_thermal_meter_jaguar_series(
 
818
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
 
819
        void            *p_dm_void
 
820
#else
 
821
        struct _ADAPTER *adapter
 
822
#endif
 
823
)
 
824
{
 
825
        struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
 
826
        unsigned char                   thermal_value = 0, delta, delta_LCK, channel, is_decrease;
 
827
        unsigned char                   thermal_value_avg_count = 0;
 
828
        unsigned int                    thermal_value_avg = 0, reg0x18;
 
829
        unsigned int                    bb_swing_reg[4] = {0xc1c, 0xe1c, 0x181c, 0x1a1c};
 
830
        int                                     ele_D, value32;
 
831
        char                                    OFDM_index[2], index;
 
832
        unsigned int                    i = 0, j = 0, rf_path, max_rf_path = 2, rf;
 
833
        struct rtl8192cd_priv           *priv = p_dm_odm->priv;
 
834
        unsigned char                   OFDM_min_index = 7; /* OFDM BB Swing should be less than +2.5dB, which is required by Arthur and Mimic */
 
835
 
 
836
 
 
837
 
 
838
#ifdef MP_TEST
 
839
        if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) {
 
840
                channel = priv->pshare->working_channel;
 
841
                if (priv->pshare->mp_txpwr_tracking == false)
 
842
                        return;
 
843
        } else
 
844
#endif
 
845
        {
 
846
                channel = (priv->pmib->dot11RFEntry.dot11channel);
 
847
        }
 
848
 
 
849
#if RTL8881A_SUPPORT
 
850
        if (p_dm_odm->support_ic_type == ODM_RTL8881A) {
 
851
                max_rf_path = 1;
 
852
                if ((get_bonding_type_8881A() == BOND_8881AM || get_bonding_type_8881A() == BOND_8881AN)
 
853
                    && priv->pshare->rf_ft_var.use_intpa8881A && (*p_dm_odm->p_band_type == ODM_BAND_2_4G))
 
854
                        OFDM_min_index = 6;             /* intPA - upper bond set to +3 dB (base: -2 dB)ot11RFEntry.phy_band_select == PHY_BAND_2G)) */
 
855
                else
 
856
                        OFDM_min_index = 10;            /* OFDM BB Swing should be less than +1dB, which is required by Arthur and Mimic */
 
857
        }
 
858
#endif
 
859
 
 
860
 
 
861
        thermal_value = (unsigned char)phy_query_rf_reg(priv, RF_PATH_A, 0x42, 0xfc00, 1); /* 0x42: RF Reg[15:10] 88E */
 
862
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, priv->pshare->thermal_value, priv->pmib->dot11RFEntry.ther));
 
863
 
 
864
 
 
865
        /* 4 Query OFDM BB swing default setting        Bit[31:21] */
 
866
        for (rf_path = 0 ; rf_path < max_rf_path ; rf_path++) {
 
867
                ele_D = phy_query_bb_reg(priv, bb_swing_reg[rf_path], 0xffe00000);
 
868
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("0x%x:0x%x ([31:21] = 0x%x)\n", bb_swing_reg[rf_path], phy_query_bb_reg(priv, bb_swing_reg[rf_path], MASKDWORD), ele_D));
 
869
                for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {/* 4 */
 
870
                        if (ele_D == ofdm_swing_table_8812[i]) {
 
871
                                OFDM_index[rf_path] = (unsigned char)i;
 
872
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("OFDM_index[%d]=%d\n", rf_path, OFDM_index[rf_path]));
 
873
                                break;
 
874
                        }
 
875
                }
 
876
        }
 
877
#if 0
 
878
        /* Query OFDM path A default setting    Bit[31:21] */
 
879
        ele_D = phy_query_bb_reg(priv, 0xc1c, 0xffe00000);
 
880
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("0xc1c:0x%x ([31:21] = 0x%x)\n", phy_query_bb_reg(priv, 0xc1c, MASKDWORD), ele_D));
 
881
        for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {/* 4 */
 
882
                if (ele_D == ofdm_swing_table_8812[i]) {
 
883
                        OFDM_index[0] = (unsigned char)i;
 
884
                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("OFDM_index[0]=%d\n", OFDM_index[0]));
 
885
                        break;
 
886
                }
 
887
        }
 
888
        /* Query OFDM path B default setting */
 
889
        if (rf == 2) {
 
890
                ele_D = phy_query_bb_reg(priv, 0xe1c, 0xffe00000);
 
891
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("0xe1c:0x%x ([32:21] = 0x%x)\n", phy_query_bb_reg(priv, 0xe1c, MASKDWORD), ele_D));
 
892
                for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {
 
893
                        if (ele_D == ofdm_swing_table_8812[i]) {
 
894
                                OFDM_index[1] = (unsigned char)i;
 
895
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("OFDM_index[1]=%d\n", OFDM_index[1]));
 
896
                                break;
 
897
                        }
 
898
                }
 
899
        }
 
900
#endif
 
901
        /* Initialize */
 
902
        if (!priv->pshare->thermal_value) {
 
903
                priv->pshare->thermal_value = priv->pmib->dot11RFEntry.ther;
 
904
                priv->pshare->thermal_value_lck = thermal_value;
 
905
        }
 
906
 
 
907
        /* calculate average thermal meter */
 
908
        {
 
909
                priv->pshare->thermal_value_avg_8812[priv->pshare->thermal_value_avg_index_8812] = thermal_value;
 
910
                priv->pshare->thermal_value_avg_index_8812++;
 
911
                if (priv->pshare->thermal_value_avg_index_8812 == AVG_THERMAL_NUM_8812)
 
912
                        priv->pshare->thermal_value_avg_index_8812 = 0;
 
913
 
 
914
                for (i = 0; i < AVG_THERMAL_NUM_8812; i++) {
 
915
                        if (priv->pshare->thermal_value_avg_8812[i]) {
 
916
                                thermal_value_avg += priv->pshare->thermal_value_avg_8812[i];
 
917
                                thermal_value_avg_count++;
 
918
                        }
 
919
                }
 
920
 
 
921
                if (thermal_value_avg_count) {
 
922
                        thermal_value = (unsigned char)(thermal_value_avg / thermal_value_avg_count);
 
923
                        /* printk("AVG Thermal Meter = 0x%x\n", thermal_value); */
 
924
                }
 
925
        }
 
926
 
 
927
 
 
928
        /* 4 If necessary,  do power tracking */
 
929
 
 
930
        if (!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/
 
931
                return;
 
932
 
 
933
        if (thermal_value != priv->pshare->thermal_value) {
 
934
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\n******** START POWER TRACKING ********\n"));
 
935
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, priv->pshare->thermal_value, priv->pmib->dot11RFEntry.ther));
 
936
                delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
 
937
                delta_LCK = RTL_ABS(thermal_value, priv->pshare->thermal_value_lck);
 
938
                is_decrease = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 1 : 0);
 
939
                /* if (*p_dm_odm->p_band_type == ODM_BAND_5G) */
 
940
                {
 
941
#ifdef _TRACKING_TABLE_FILE
 
942
                        if (priv->pshare->rf_ft_var.pwr_track_file) {
 
943
                                for (rf_path = 0; rf_path < max_rf_path; rf_path++) {
 
944
                                        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("diff: (%s)%d ==> get index from table : %d)\n", (is_decrease ? "-" : "+"), delta, get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0)));
 
945
                                        if (is_decrease) {
 
946
                                                OFDM_index[rf_path] = priv->pshare->OFDM_index0[rf_path] + get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0);
 
947
                                                OFDM_index[rf_path] = ((OFDM_index[rf_path] > (OFDM_TABLE_SIZE_8812 - 1)) ? (OFDM_TABLE_SIZE_8812 - 1) : OFDM_index[rf_path]);
 
948
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> decrese power ---> new OFDM_INDEX:%d (%d + %d)\n", OFDM_index[rf_path], priv->pshare->OFDM_index0[rf_path], get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0)));
 
949
#if 0/* RTL8881A_SUPPORT */
 
950
                                                if (p_dm_odm->support_ic_type == ODM_RTL8881A) {
 
951
                                                        if (priv->pshare->rf_ft_var.pwrtrk_tx_agc_enable) {
 
952
                                                                if (priv->pshare->add_tx_agc) { /* tx_agc has been added */
 
953
                                                                        add_tx_power88xx_ac(priv, 0);
 
954
                                                                        priv->pshare->add_tx_agc = 0;
 
955
                                                                        priv->pshare->add_tx_agc_index = 0;
 
956
                                                                }
 
957
                                                        }
 
958
                                                }
 
959
#endif
 
960
                                        } else {
 
961
 
 
962
                                                OFDM_index[rf_path] = priv->pshare->OFDM_index0[rf_path] - get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0);
 
963
#if 0/* RTL8881A_SUPPORT */
 
964
                                                if (p_dm_odm->support_ic_type == ODM_RTL8881A) {
 
965
                                                        if (priv->pshare->rf_ft_var.pwrtrk_tx_agc_enable) {
 
966
                                                                if (OFDM_index[i] < OFDM_min_index) {
 
967
                                                                        priv->pshare->add_tx_agc_index = (OFDM_min_index - OFDM_index[i]) / 2; /* Calculate Remnant tx_agc value,  2 index for 1 tx_agc */
 
968
                                                                        add_tx_power88xx_ac(priv, priv->pshare->add_tx_agc_index);
 
969
                                                                        priv->pshare->add_tx_agc = 1;     /* add_tx_agc Flag = 1 */
 
970
                                                                        OFDM_index[i] = OFDM_min_index;
 
971
                                                                } else {
 
972
                                                                        if (priv->pshare->add_tx_agc) { /* tx_agc been added */
 
973
                                                                                priv->pshare->add_tx_agc = 0;
 
974
                                                                                priv->pshare->add_tx_agc_index = 0;
 
975
                                                                                add_tx_power88xx_ac(priv, 0); /* minus the added TPI */
 
976
                                                                        }
 
977
                                                                }
 
978
                                                        }
 
979
                                                }
 
980
#else
 
981
                                                OFDM_index[rf_path] = ((OFDM_index[rf_path] < OFDM_min_index) ?  OFDM_min_index : OFDM_index[rf_path]);
 
982
#endif
 
983
                                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, (">>> increse power ---> new OFDM_INDEX:%d (%d - %d)\n", OFDM_index[rf_path], priv->pshare->OFDM_index0[rf_path], get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0)));
 
984
                                        }
 
985
                                }
 
986
                        }
 
987
#endif
 
988
                        /* 4 Set new BB swing index */
 
989
                        for (rf_path = 0; rf_path < max_rf_path; rf_path++) {
 
990
                                phy_set_bb_reg(priv, bb_swing_reg[rf_path], 0xffe00000, ofdm_swing_table_8812[(unsigned int)OFDM_index[rf_path]]);
 
991
                                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("Readback 0x%x[31:21] = 0x%x, OFDM_index:%d\n", bb_swing_reg[rf_path], phy_query_bb_reg(priv, bb_swing_reg[rf_path], 0xffe00000), OFDM_index[rf_path]));
 
992
                        }
 
993
 
 
994
                }
 
995
                if (delta_LCK > 8) {
 
996
                        RTL_W8(0x522, 0xff);
 
997
                        reg0x18 = phy_query_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, 1);
 
998
                        phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 1);
 
999
                        phy_set_rf_reg(priv, RF_PATH_A, 0x18, BIT(15), 1);
 
1000
                        delay_ms(200); /* frequency deviation */
 
1001
                        phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 0);
 
1002
                        phy_set_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, reg0x18);
 
1003
#ifdef CONFIG_RTL_8812_SUPPORT
 
1004
                        if (GET_CHIP_VER(priv) == VERSION_8812E)
 
1005
                                update_bbrf_val8812(priv, priv->pmib->dot11RFEntry.dot11channel);
 
1006
#endif
 
1007
                        RTL_W8(0x522, 0x0);
 
1008
                        priv->pshare->thermal_value_lck = thermal_value;
 
1009
                }
 
1010
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\n******** END:%s() ********\n", __FUNCTION__));
 
1011
 
 
1012
                /* update thermal meter value */
 
1013
                priv->pshare->thermal_value = thermal_value;
 
1014
                for (rf_path = 0; rf_path < max_rf_path; rf_path++)
 
1015
                        priv->pshare->OFDM_index[rf_path] = OFDM_index[rf_path];
 
1016
        }
 
1017
}
 
1018
 
 
1019
#endif
 
1020
 
 
1021
 
 
1022
void
 
1023
odm_txpowertracking_callback_thermal_meter(
 
1024
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
 
1025
        void            *p_dm_void
 
1026
#else
 
1027
        struct _ADAPTER *adapter
 
1028
#endif
 
1029
)
 
1030
{
 
1031
        struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
 
1032
        struct odm_rf_calibration_structure     *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
 
1033
 
 
1034
 
 
1035
#if (RTL8197F_SUPPORT == 1 || RTL8822B_SUPPORT == 1)
 
1036
        if (p_dm_odm->support_ic_type == ODM_RTL8197F || p_dm_odm->support_ic_type == ODM_RTL8822B) {
 
1037
                odm_txpowertracking_callback_thermal_meter_jaguar_series3(p_dm_odm);
 
1038
                return;
 
1039
        }
 
1040
#endif
 
1041
#if (RTL8814A_SUPPORT == 1)             /*use this function to do power tracking after 8814 by YuChen*/
 
1042
        if (p_dm_odm->support_ic_type & ODM_RTL8814A) {
 
1043
                odm_txpowertracking_callback_thermal_meter_jaguar_series2(p_dm_odm);
 
1044
                return;
 
1045
        }
 
1046
#endif
 
1047
#if (RTL8881A_SUPPORT || RTL8812A_SUPPORT == 1)
 
1048
        if (p_dm_odm->support_ic_type & ODM_RTL8812 || p_dm_odm->support_ic_type & ODM_RTL8881A) {
 
1049
                odm_txpowertracking_callback_thermal_meter_jaguar_series(p_dm_odm);
 
1050
                return;
 
1051
        }
 
1052
#endif
 
1053
 
 
1054
#if (RTL8192E_SUPPORT == 1)
 
1055
        if (p_dm_odm->support_ic_type == ODM_RTL8192E) {
 
1056
                odm_txpowertracking_callback_thermal_meter_92e(p_dm_odm);
 
1057
                return;
 
1058
        }
 
1059
#endif
 
1060
 
 
1061
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
 
1062
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(adapter);
 
1063
        /* PMGNT_INFO                   p_mgnt_info = &adapter->mgnt_info; */
 
1064
#endif
 
1065
 
 
1066
 
 
1067
        u8                      thermal_value = 0, delta, delta_LCK, delta_IQK, offset;
 
1068
        u8                      thermal_value_avg_count = 0;
 
1069
        u32                     thermal_value_avg = 0;
 
1070
        /*      s32                     ele_A=0, ele_D, TempCCk, X, value32;
 
1071
         *      s32                     Y, ele_C=0;
 
1072
         *      s8                      OFDM_index[2], CCK_index=0, OFDM_index_old[2]={0,0}, CCK_index_old=0, index;
 
1073
         *      s8                      deltaPowerIndex = 0; */
 
1074
        u32                     i = 0;/* , j = 0; */
 
1075
        boolean         is2T = false;
 
1076
        /*      bool            bInteralPA = false; */
 
1077
 
 
1078
        u8                      OFDM_max_index = 34, rf = (is2T) ? 2 : 1; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
 
1079
        u8                      indexforchannel = 0;/*get_right_chnl_place_for_iqk(p_hal_data->current_channel)*/
 
1080
        enum            _POWER_DEC_INC { POWER_DEC, POWER_INC };
 
1081
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
 
1082
        struct PHY_DM_STRUCT            *p_dm_odm = &p_hal_data->odmpriv;
 
1083
#endif
 
1084
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
 
1085
        struct PHY_DM_STRUCT            *p_dm_odm = &p_hal_data->DM_OutSrc;
 
1086
#endif
 
1087
 
 
1088
        struct _TXPWRTRACK_CFG  c;
 
1089
 
 
1090
 
 
1091
        /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
 
1092
        s8                      delta_swing_table_idx[2][index_mapping_NUM_88E] = {
 
1093
                /* {{Power decreasing(lower temperature)}, {Power increasing(higher temperature)}} */
 
1094
                {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11}, {0, 0, 1, 2, 3, 4, 4, 4, 4, 5, 7, 8, 9, 9, 10}
 
1095
        };
 
1096
        u8                      thermal_threshold[2][index_mapping_NUM_88E] = {
 
1097
                /* {{Power decreasing(lower temperature)}, {Power increasing(higher temperature)}} */
 
1098
                {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27}, {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
 
1099
        };
 
1100
 
 
1101
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
 
1102
        struct rtl8192cd_priv   *priv = p_dm_odm->priv;
 
1103
#endif
 
1104
 
 
1105
        /* 4 2. Initilization ( 7 steps in total ) */
 
1106
 
 
1107
        configure_txpower_track(p_dm_odm, &c);
 
1108
 
 
1109
        p_dm_odm->rf_calibrate_info.txpowertracking_callback_cnt++; /* cosa add for debug */
 
1110
        p_dm_odm->rf_calibrate_info.is_txpowertracking_init = true;
 
1111
 
 
1112
#if (MP_DRIVER == 1)
 
1113
        p_dm_odm->rf_calibrate_info.txpowertrack_control = p_hal_data->txpowertrack_control; /* <Kordan> We should keep updating the control variable according to HalData.
 
1114
     * <Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
 
1115
        p_dm_odm->rf_calibrate_info.rega24 = 0x090e1317;
 
1116
#endif
 
1117
 
 
1118
#if (DM_ODM_SUPPORT_TYPE == ODM_AP) && defined(MP_TEST)
 
1119
        if ((OPMODE & WIFI_MP_STATE) || p_dm_odm->priv->pshare->rf_ft_var.mp_specific) {
 
1120
                if (p_dm_odm->priv->pshare->mp_txpwr_tracking == false)
 
1121
                        return;
 
1122
        }
 
1123
#endif
 
1124
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("===>odm_txpowertracking_callback_thermal_meter_8188e, p_dm_odm->bb_swing_idx_cck_base: %d, p_dm_odm->bb_swing_idx_ofdm_base: %d\n", p_rf_calibrate_info->bb_swing_idx_cck_base, p_rf_calibrate_info->bb_swing_idx_ofdm_base));
 
1125
        /*
 
1126
                if (!p_dm_odm->rf_calibrate_info.tm_trigger) {
 
1127
                        odm_set_rf_reg(p_dm_odm, RF_PATH_A, c.thermal_reg_addr, BIT(17) | BIT(16), 0x3);
 
1128
                        p_dm_odm->rf_calibrate_info.tm_trigger = 1;
 
1129
                        return;
 
1130
                }
 
1131
        */
 
1132
        thermal_value = (u8)odm_get_rf_reg(p_dm_odm, RF_PATH_A, c.thermal_reg_addr, 0xfc00);    /* 0x42: RF Reg[15:10] 88E */
 
1133
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
 
1134
        if (!thermal_value || !p_dm_odm->rf_calibrate_info.txpowertrack_control)
 
1135
#else
 
1136
        if (!p_dm_odm->rf_calibrate_info.txpowertrack_control)
 
1137
#endif
 
1138
                return;
 
1139
 
 
1140
        /* 4 3. Initialize ThermalValues of rf_calibrate_info */
 
1141
 
 
1142
        if (!p_dm_odm->rf_calibrate_info.thermal_value) {
 
1143
                p_dm_odm->rf_calibrate_info.thermal_value_lck = thermal_value;
 
1144
                p_dm_odm->rf_calibrate_info.thermal_value_iqk = thermal_value;
 
1145
        }
 
1146
 
 
1147
        if (p_dm_odm->rf_calibrate_info.is_reloadtxpowerindex)
 
1148
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("reload ofdm index for band switch\n"));
 
1149
 
 
1150
        /* 4 4. Calculate average thermal meter */
 
1151
 
 
1152
        p_dm_odm->rf_calibrate_info.thermal_value_avg[p_dm_odm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
 
1153
        p_dm_odm->rf_calibrate_info.thermal_value_avg_index++;
 
1154
        if (p_dm_odm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num)
 
1155
                p_dm_odm->rf_calibrate_info.thermal_value_avg_index = 0;
 
1156
 
 
1157
        for (i = 0; i < c.average_thermal_num; i++) {
 
1158
                if (p_dm_odm->rf_calibrate_info.thermal_value_avg[i]) {
 
1159
                        thermal_value_avg += p_dm_odm->rf_calibrate_info.thermal_value_avg[i];
 
1160
                        thermal_value_avg_count++;
 
1161
                }
 
1162
        }
 
1163
 
 
1164
        if (thermal_value_avg_count) {
 
1165
                /* Give the new thermo value a weighting */
 
1166
                thermal_value_avg += (thermal_value * 4);
 
1167
 
 
1168
                thermal_value = (u8)(thermal_value_avg / (thermal_value_avg_count + 4));
 
1169
                p_rf_calibrate_info->thermal_value_delta = thermal_value - priv->pmib->dot11RFEntry.ther;
 
1170
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("AVG Thermal Meter = 0x%x\n", thermal_value));
 
1171
        }
 
1172
 
 
1173
        /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
 
1174
 
 
1175
        delta     = (thermal_value > p_dm_odm->rf_calibrate_info.thermal_value) ? (thermal_value - p_dm_odm->rf_calibrate_info.thermal_value) : (p_dm_odm->rf_calibrate_info.thermal_value - thermal_value);
 
1176
        delta_LCK = (thermal_value > p_dm_odm->rf_calibrate_info.thermal_value_lck) ? (thermal_value - p_dm_odm->rf_calibrate_info.thermal_value_lck) : (p_dm_odm->rf_calibrate_info.thermal_value_lck - thermal_value);
 
1177
        delta_IQK = (thermal_value > p_dm_odm->rf_calibrate_info.thermal_value_iqk) ? (thermal_value - p_dm_odm->rf_calibrate_info.thermal_value_iqk) : (p_dm_odm->rf_calibrate_info.thermal_value_iqk - thermal_value);
 
1178
 
 
1179
        /* 4 6. If necessary, do LCK. */
 
1180
        if (!(p_dm_odm->support_ic_type & ODM_RTL8821)) {
 
1181
                /*if((delta_LCK > p_hal_data->delta_lck) && (p_hal_data->delta_lck != 0))*/
 
1182
                if (delta_LCK >= c.threshold_iqk) {
 
1183
                        /*Delta temperature is equal to or larger than 20 centigrade.*/
 
1184
                        p_dm_odm->rf_calibrate_info.thermal_value_lck = thermal_value;
 
1185
                        (*c.phy_lc_calibrate)(p_dm_odm);
 
1186
                }
 
1187
        }
 
1188
 
 
1189
        /* 3 7. If necessary, move the index of swing table to adjust Tx power. */
 
1190
 
 
1191
        if (delta > 0 && p_dm_odm->rf_calibrate_info.txpowertrack_control) {
 
1192
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
 
1193
                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);
 
1194
#else
 
1195
                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);
 
1196
#endif
 
1197
 
 
1198
 
 
1199
                /* 4 7.1 The Final Power index = BaseIndex + power_index_offset */
 
1200
 
 
1201
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
 
1202
                if (thermal_value > p_hal_data->eeprom_thermal_meter) {
 
1203
#else
 
1204
                if (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther) {
 
1205
#endif
 
1206
                        CALCULATE_SWINGTALBE_OFFSET(offset, POWER_INC, index_mapping_NUM_88E, delta);
 
1207
                        p_dm_odm->rf_calibrate_info.delta_power_index_last = p_dm_odm->rf_calibrate_info.delta_power_index;
 
1208
                        p_dm_odm->rf_calibrate_info.delta_power_index =  delta_swing_table_idx[POWER_INC][offset];
 
1209
 
 
1210
                } else {
 
1211
 
 
1212
                        CALCULATE_SWINGTALBE_OFFSET(offset, POWER_DEC, index_mapping_NUM_88E, delta);
 
1213
                        p_dm_odm->rf_calibrate_info.delta_power_index_last = p_dm_odm->rf_calibrate_info.delta_power_index;
 
1214
                        p_dm_odm->rf_calibrate_info.delta_power_index = (-1) * delta_swing_table_idx[POWER_DEC][offset];
 
1215
                }
 
1216
 
 
1217
                if (p_dm_odm->rf_calibrate_info.delta_power_index == p_dm_odm->rf_calibrate_info.delta_power_index_last)
 
1218
                        p_dm_odm->rf_calibrate_info.power_index_offset = 0;
 
1219
                else
 
1220
                        p_dm_odm->rf_calibrate_info.power_index_offset = p_dm_odm->rf_calibrate_info.delta_power_index - p_dm_odm->rf_calibrate_info.delta_power_index_last;
 
1221
 
 
1222
                for (i = 0; i < rf; i++)
 
1223
                        p_dm_odm->rf_calibrate_info.OFDM_index[i] = p_rf_calibrate_info->bb_swing_idx_ofdm_base + p_dm_odm->rf_calibrate_info.power_index_offset;
 
1224
                p_dm_odm->rf_calibrate_info.CCK_index = p_rf_calibrate_info->bb_swing_idx_cck_base + p_dm_odm->rf_calibrate_info.power_index_offset;
 
1225
 
 
1226
                p_rf_calibrate_info->bb_swing_idx_cck = p_dm_odm->rf_calibrate_info.CCK_index;
 
1227
                p_rf_calibrate_info->bb_swing_idx_ofdm[RF_PATH_A] = p_dm_odm->rf_calibrate_info.OFDM_index[RF_PATH_A];
 
1228
 
 
1229
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("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_dm_odm->rf_calibrate_info.power_index_offset));
 
1230
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("The 'OFDM' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", p_rf_calibrate_info->bb_swing_idx_ofdm[RF_PATH_A], p_rf_calibrate_info->bb_swing_idx_ofdm_base, p_dm_odm->rf_calibrate_info.power_index_offset));
 
1231
 
 
1232
                /* 4 7.1 Handle boundary conditions of index. */
 
1233
 
 
1234
 
 
1235
                for (i = 0; i < rf; i++) {
 
1236
                        if (p_dm_odm->rf_calibrate_info.OFDM_index[i] > OFDM_max_index)
 
1237
                                p_dm_odm->rf_calibrate_info.OFDM_index[i] = OFDM_max_index;
 
1238
                        else if (p_dm_odm->rf_calibrate_info.OFDM_index[i] < 0)
 
1239
                                p_dm_odm->rf_calibrate_info.OFDM_index[i] = 0;
 
1240
                }
 
1241
 
 
1242
                if (p_dm_odm->rf_calibrate_info.CCK_index > c.swing_table_size_cck - 1)
 
1243
                        p_dm_odm->rf_calibrate_info.CCK_index = c.swing_table_size_cck - 1;
 
1244
                else if (p_dm_odm->rf_calibrate_info.CCK_index < 0)
 
1245
                        p_dm_odm->rf_calibrate_info.CCK_index = 0;
 
1246
        } else {
 
1247
                ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
1248
                        ("The thermal meter is unchanged or TxPowerTracking OFF: thermal_value: %d, p_dm_odm->rf_calibrate_info.thermal_value: %d)\n", thermal_value, p_dm_odm->rf_calibrate_info.thermal_value));
 
1249
                p_dm_odm->rf_calibrate_info.power_index_offset = 0;
 
1250
        }
 
1251
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
1252
                ("TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n", p_dm_odm->rf_calibrate_info.CCK_index, p_rf_calibrate_info->bb_swing_idx_cck_base));
 
1253
 
 
1254
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
 
1255
                ("TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index: %d\n", p_dm_odm->rf_calibrate_info.OFDM_index[RF_PATH_A], p_rf_calibrate_info->bb_swing_idx_ofdm_base));
 
1256
 
 
1257
        if (p_dm_odm->rf_calibrate_info.power_index_offset != 0 && p_dm_odm->rf_calibrate_info.txpowertrack_control) {
 
1258
                /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
 
1259
 
 
1260
                p_dm_odm->rf_calibrate_info.is_tx_power_changed = true; /* Always true after Tx Power is adjusted by power tracking. */
 
1261
                /*  */
 
1262
                /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
 
1263
                /* to increase TX power. Otherwise, EVM will be bad. */
 
1264
                /*  */
 
1265
                /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
 
1266
                if (thermal_value > p_dm_odm->rf_calibrate_info.thermal_value) {
 
1267
                        /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, */
 
1268
                        /*      ("Temperature Increasing: delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", */
 
1269
                        /*      p_dm_odm->rf_calibrate_info.power_index_offset, delta, thermal_value, p_hal_data->eeprom_thermal_meter, p_dm_odm->rf_calibrate_info.thermal_value)); */
 
1270
                } else if (thermal_value < p_dm_odm->rf_calibrate_info.thermal_value) { /* Low temperature */
 
1271
                        /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, */
 
1272
                        /*      ("Temperature Decreasing: delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", */
 
1273
                        /*              p_dm_odm->rf_calibrate_info.power_index_offset, delta, thermal_value, p_hal_data->eeprom_thermal_meter, p_dm_odm->rf_calibrate_info.thermal_value)); */
 
1274
                }
 
1275
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
 
1276
                if (thermal_value > p_hal_data->eeprom_thermal_meter)
 
1277
#else
 
1278
                if (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther)
 
1279
#endif
 
1280
                {
 
1281
                        /*                              ODM_RT_TRACE(p_dm_odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("Temperature(%d) hugher than PG value(%d), increases the power by tx_agc\n", thermal_value, p_hal_data->eeprom_thermal_meter)); */
 
1282
                        (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, TXAGC, 0, 0);
 
1283
                } else {
 
1284
                        /*                      ODM_RT_TRACE(p_dm_odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("Temperature(%d) lower than PG value(%d), increases the power by tx_agc\n", thermal_value, p_hal_data->eeprom_thermal_meter)); */
 
1285
                        (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, RF_PATH_A, indexforchannel);
 
1286
                        if (is2T)
 
1287
                                (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, RF_PATH_B, indexforchannel);
 
1288
                }
 
1289
 
 
1290
                p_rf_calibrate_info->bb_swing_idx_cck_base = p_rf_calibrate_info->bb_swing_idx_cck;
 
1291
                p_rf_calibrate_info->bb_swing_idx_ofdm_base = p_rf_calibrate_info->bb_swing_idx_ofdm[RF_PATH_A];
 
1292
                p_dm_odm->rf_calibrate_info.thermal_value = thermal_value;
 
1293
 
 
1294
        }
 
1295
 
 
1296
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
 
1297
        /* if((delta_IQK > p_hal_data->delta_iqk) && (p_hal_data->delta_iqk != 0)) */
 
1298
        if ((delta_IQK >= 8)) /* Delta temperature is equal to or larger than 20 centigrade. */
 
1299
                (*c.do_iqk)(p_dm_odm, delta_IQK, thermal_value, 8);
 
1300
#endif
 
1301
 
 
1302
        ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("<===dm_TXPowerTrackingCallback_ThermalMeter_8188E\n"));
 
1303
 
 
1304
        p_dm_odm->rf_calibrate_info.tx_powercount = 0;
 
1305
}
 
1306
 
 
1307
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
 
1308
 
 
1309
 
 
1310
void
 
1311
phy_path_a_stand_by(
 
1312
        struct _ADAPTER *p_adapter
 
1313
)
 
1314
{
 
1315
        RTPRINT(FINIT, INIT_IQK, ("path-A standby mode!\n"));
 
1316
 
 
1317
        phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0x0);
 
1318
        phy_set_bb_reg(p_adapter, 0x840, MASKDWORD, 0x00010000);
 
1319
        phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0x808000);
 
1320
}
 
1321
 
 
1322
/* 1 7. IQK
 
1323
 * #define MAX_TOLERANCE                5
 
1324
 * #define IQK_DELAY_TIME               1 */            /* ms */
 
1325
 
 
1326
u8                      /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 
1327
phy_path_a_iqk_8192c(
 
1328
        struct _ADAPTER *p_adapter,
 
1329
        boolean         config_path_b
 
1330
)
 
1331
{
 
1332
 
 
1333
        u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
 
1334
        u8 result = 0x00;
 
1335
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
1336
 
 
1337
        RTPRINT(FINIT, INIT_IQK, ("path A IQK!\n"));
 
1338
 
 
1339
        /* path-A IQK setting */
 
1340
        RTPRINT(FINIT, INIT_IQK, ("path-A IQK setting!\n"));
 
1341
        if (p_adapter->interface_index == 0) {
 
1342
                phy_set_bb_reg(p_adapter, REG_TX_IQK_TONE_A, MASKDWORD, 0x10008c1f);
 
1343
                phy_set_bb_reg(p_adapter, REG_RX_IQK_TONE_A, MASKDWORD, 0x10008c1f);
 
1344
        } else {
 
1345
                phy_set_bb_reg(p_adapter, REG_TX_IQK_TONE_A, MASKDWORD, 0x10008c22);
 
1346
                phy_set_bb_reg(p_adapter, REG_RX_IQK_TONE_A, MASKDWORD, 0x10008c22);
 
1347
        }
 
1348
 
 
1349
        phy_set_bb_reg(p_adapter, REG_TX_IQK_PI_A, MASKDWORD, 0x82140102);
 
1350
 
 
1351
        phy_set_bb_reg(p_adapter, REG_RX_IQK_PI_A, MASKDWORD, config_path_b ? 0x28160202 :
 
1352
                IS_81xxC_VENDOR_UMC_B_CUT(p_hal_data->version_id) ? 0x28160202 : 0x28160502);
 
1353
 
 
1354
        /* path-B IQK setting */
 
1355
        if (config_path_b) {
 
1356
                phy_set_bb_reg(p_adapter, REG_TX_IQK_TONE_B, MASKDWORD, 0x10008c22);
 
1357
                phy_set_bb_reg(p_adapter, REG_RX_IQK_TONE_B, MASKDWORD, 0x10008c22);
 
1358
                phy_set_bb_reg(p_adapter, REG_TX_IQK_PI_B, MASKDWORD, 0x82140102);
 
1359
                phy_set_bb_reg(p_adapter, REG_RX_IQK_PI_B, MASKDWORD, 0x28160202);
 
1360
        }
 
1361
 
 
1362
        /* LO calibration setting */
 
1363
        RTPRINT(FINIT, INIT_IQK, ("LO calibration setting!\n"));
 
1364
        phy_set_bb_reg(p_adapter, REG_IQK_AGC_RSP, MASKDWORD, 0x001028d1);
 
1365
 
 
1366
        /* One shot, path A LOK & IQK */
 
1367
        RTPRINT(FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
 
1368
        phy_set_bb_reg(p_adapter, REG_IQK_AGC_PTS, MASKDWORD, 0xf9000000);
 
1369
        phy_set_bb_reg(p_adapter, REG_IQK_AGC_PTS, MASKDWORD, 0xf8000000);
 
1370
 
 
1371
        /* delay x ms */
 
1372
        RTPRINT(FINIT, INIT_IQK, ("delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME));
 
1373
        platform_stall_execution(IQK_DELAY_TIME * 1000);
 
1374
 
 
1375
        /* Check failed */
 
1376
        reg_eac = phy_query_bb_reg(p_adapter, REG_RX_POWER_AFTER_IQK_A_2, MASKDWORD);
 
1377
        RTPRINT(FINIT, INIT_IQK, ("0xeac = 0x%x\n", reg_eac));
 
1378
        reg_e94 = phy_query_bb_reg(p_adapter, REG_TX_POWER_BEFORE_IQK_A, MASKDWORD);
 
1379
        RTPRINT(FINIT, INIT_IQK, ("0xe94 = 0x%x\n", reg_e94));
 
1380
        reg_e9c = phy_query_bb_reg(p_adapter, REG_TX_POWER_AFTER_IQK_A, MASKDWORD);
 
1381
        RTPRINT(FINIT, INIT_IQK, ("0xe9c = 0x%x\n", reg_e9c));
 
1382
        reg_ea4 = phy_query_bb_reg(p_adapter, REG_RX_POWER_BEFORE_IQK_A_2, MASKDWORD);
 
1383
        RTPRINT(FINIT, INIT_IQK, ("0xea4 = 0x%x\n", reg_ea4));
 
1384
 
 
1385
        if (!(reg_eac & BIT(28)) &&
 
1386
            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
 
1387
            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
 
1388
                result |= 0x01;
 
1389
        else                                                    /* if Tx not OK, ignore Rx */
 
1390
                return result;
 
1391
 
 
1392
        if (!(reg_eac & BIT(27)) &&             /* if Tx is OK, check whether Rx is OK */
 
1393
            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
 
1394
            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
 
1395
                result |= 0x02;
 
1396
        else
 
1397
                RTPRINT(FINIT, INIT_IQK, ("path A Rx IQK fail!!\n"));
 
1398
 
 
1399
        return result;
 
1400
 
 
1401
 
 
1402
}
 
1403
 
 
1404
u8                              /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 
1405
phy_path_b_iqk_8192c(
 
1406
        struct _ADAPTER *p_adapter
 
1407
)
 
1408
{
 
1409
        u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
 
1410
        u8      result = 0x00;
 
1411
        RTPRINT(FINIT, INIT_IQK, ("path B IQK!\n"));
 
1412
 
 
1413
        /* One shot, path B LOK & IQK */
 
1414
        RTPRINT(FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
 
1415
        phy_set_bb_reg(p_adapter, REG_IQK_AGC_CONT, MASKDWORD, 0x00000002);
 
1416
        phy_set_bb_reg(p_adapter, REG_IQK_AGC_CONT, MASKDWORD, 0x00000000);
 
1417
 
 
1418
        /* delay x ms */
 
1419
        RTPRINT(FINIT, INIT_IQK, ("delay %d ms for One shot, path B LOK & IQK.\n", IQK_DELAY_TIME));
 
1420
        platform_stall_execution(IQK_DELAY_TIME * 1000);
 
1421
 
 
1422
        /* Check failed */
 
1423
        reg_eac = phy_query_bb_reg(p_adapter, REG_RX_POWER_AFTER_IQK_A_2, MASKDWORD);
 
1424
        RTPRINT(FINIT, INIT_IQK, ("0xeac = 0x%x\n", reg_eac));
 
1425
        reg_eb4 = phy_query_bb_reg(p_adapter, REG_TX_POWER_BEFORE_IQK_B, MASKDWORD);
 
1426
        RTPRINT(FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", reg_eb4));
 
1427
        reg_ebc = phy_query_bb_reg(p_adapter, REG_TX_POWER_AFTER_IQK_B, MASKDWORD);
 
1428
        RTPRINT(FINIT, INIT_IQK, ("0xebc = 0x%x\n", reg_ebc));
 
1429
        reg_ec4 = phy_query_bb_reg(p_adapter, REG_RX_POWER_BEFORE_IQK_B_2, MASKDWORD);
 
1430
        RTPRINT(FINIT, INIT_IQK, ("0xec4 = 0x%x\n", reg_ec4));
 
1431
        reg_ecc = phy_query_bb_reg(p_adapter, REG_RX_POWER_AFTER_IQK_B_2, MASKDWORD);
 
1432
        RTPRINT(FINIT, INIT_IQK, ("0xecc = 0x%x\n", reg_ecc));
 
1433
 
 
1434
        if (!(reg_eac & BIT(31)) &&
 
1435
            (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
 
1436
            (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
 
1437
                result |= 0x01;
 
1438
        else
 
1439
                return result;
 
1440
 
 
1441
        if (!(reg_eac & BIT(30)) &&
 
1442
            (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
 
1443
            (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
 
1444
                result |= 0x02;
 
1445
        else
 
1446
                RTPRINT(FINIT, INIT_IQK, ("path B Rx IQK fail!!\n"));
 
1447
 
 
1448
 
 
1449
        return result;
 
1450
 
 
1451
}
 
1452
 
 
1453
void
 
1454
phy_path_a_fill_iqk_matrix(
 
1455
        struct _ADAPTER *p_adapter,
 
1456
        boolean is_iqk_ok,
 
1457
        s32             result[][8],
 
1458
        u8              final_candidate,
 
1459
        boolean         is_tx_only
 
1460
)
 
1461
{
 
1462
        u32     oldval_0, X, TX0_A, reg;
 
1463
        s32     Y, TX0_C;
 
1464
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
1465
 
 
1466
        RTPRINT(FINIT, INIT_IQK, ("path A IQ Calibration %s !\n", (is_iqk_ok) ? "Success" : "Failed"));
 
1467
 
 
1468
        if (final_candidate == 0xFF)
 
1469
                return;
 
1470
 
 
1471
        else if (is_iqk_ok) {
 
1472
                oldval_0 = (phy_query_bb_reg(p_adapter, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD) >> 22) & 0x3FF;
 
1473
 
 
1474
                X = result[final_candidate][0];
 
1475
                if ((X & 0x00000200) != 0)
 
1476
                        X = X | 0xFFFFFC00;
 
1477
                TX0_A = (X * oldval_0) >> 8;
 
1478
                RTPRINT(FINIT, INIT_IQK, ("X = 0x%x, TX0_A = 0x%x, oldval_0 0x%x\n", X, TX0_A, oldval_0));
 
1479
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 0x3FF, TX0_A);
 
1480
                phy_set_bb_reg(p_adapter, REG_OFDM_0_ECCA_THRESHOLD, BIT(31), ((X * oldval_0 >> 7) & 0x1));
 
1481
 
 
1482
                Y = result[final_candidate][1];
 
1483
                if ((Y & 0x00000200) != 0)
 
1484
                        Y = Y | 0xFFFFFC00;
 
1485
 
 
1486
                /* path B IQK result + 3 */
 
1487
                if (p_adapter->interface_index == 1 && p_hal_data->current_band_type == BAND_ON_5G)
 
1488
                        Y += 3;
 
1489
 
 
1490
                TX0_C = (Y * oldval_0) >> 8;
 
1491
                RTPRINT(FINIT, INIT_IQK, ("Y = 0x%x, TX = 0x%x\n", Y, TX0_C));
 
1492
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XC_TX_AFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6));
 
1493
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 0x003F0000, (TX0_C & 0x3F));
 
1494
                phy_set_bb_reg(p_adapter, REG_OFDM_0_ECCA_THRESHOLD, BIT(29), ((Y * oldval_0 >> 7) & 0x1));
 
1495
 
 
1496
                if (is_tx_only) {
 
1497
                        RTPRINT(FINIT, INIT_IQK, ("phy_path_a_fill_iqk_matrix only Tx OK\n"));
 
1498
                        return;
 
1499
                }
 
1500
 
 
1501
                reg = result[final_candidate][2];
 
1502
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XA_RX_IQ_IMBALANCE, 0x3FF, reg);
 
1503
 
 
1504
                reg = result[final_candidate][3] & 0x3F;
 
1505
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XA_RX_IQ_IMBALANCE, 0xFC00, reg);
 
1506
 
 
1507
                reg = (result[final_candidate][3] >> 6) & 0xF;
 
1508
                phy_set_bb_reg(p_adapter, REG_OFDM_0_RX_IQ_EXT_ANTA, 0xF0000000, reg);
 
1509
        }
 
1510
}
 
1511
 
 
1512
void
 
1513
phy_path_b_fill_iqk_matrix(
 
1514
        struct _ADAPTER *p_adapter,
 
1515
        boolean is_iqk_ok,
 
1516
        s32             result[][8],
 
1517
        u8              final_candidate,
 
1518
        boolean         is_tx_only                      /* do Tx only */
 
1519
)
 
1520
{
 
1521
        u32     oldval_1, X, TX1_A, reg;
 
1522
        s32     Y, TX1_C;
 
1523
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
1524
 
 
1525
        RTPRINT(FINIT, INIT_IQK, ("path B IQ Calibration %s !\n", (is_iqk_ok) ? "Success" : "Failed"));
 
1526
 
 
1527
        if (final_candidate == 0xFF)
 
1528
                return;
 
1529
 
 
1530
        else if (is_iqk_ok) {
 
1531
                oldval_1 = (phy_query_bb_reg(p_adapter, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD) >> 22) & 0x3FF;
 
1532
 
 
1533
                X = result[final_candidate][4];
 
1534
                if ((X & 0x00000200) != 0)
 
1535
                        X = X | 0xFFFFFC00;
 
1536
                TX1_A = (X * oldval_1) >> 8;
 
1537
                RTPRINT(FINIT, INIT_IQK, ("X = 0x%x, TX1_A = 0x%x\n", X, TX1_A));
 
1538
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XB_TX_IQ_IMBALANCE, 0x3FF, TX1_A);
 
1539
                phy_set_bb_reg(p_adapter, REG_OFDM_0_ECCA_THRESHOLD, BIT(27), ((X * oldval_1 >> 7) & 0x1));
 
1540
 
 
1541
                Y = result[final_candidate][5];
 
1542
                if ((Y & 0x00000200) != 0)
 
1543
                        Y = Y | 0xFFFFFC00;
 
1544
                if (p_hal_data->current_band_type == BAND_ON_5G)
 
1545
                        Y += 3;         /* temp modify for preformance */
 
1546
                TX1_C = (Y * oldval_1) >> 8;
 
1547
                RTPRINT(FINIT, INIT_IQK, ("Y = 0x%x, TX1_C = 0x%x\n", Y, TX1_C));
 
1548
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XD_TX_AFE, 0xF0000000, ((TX1_C & 0x3C0) >> 6));
 
1549
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XB_TX_IQ_IMBALANCE, 0x003F0000, (TX1_C & 0x3F));
 
1550
                phy_set_bb_reg(p_adapter, REG_OFDM_0_ECCA_THRESHOLD, BIT(25), ((Y * oldval_1 >> 7) & 0x1));
 
1551
 
 
1552
                if (is_tx_only)
 
1553
                        return;
 
1554
 
 
1555
                reg = result[final_candidate][6];
 
1556
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XB_RX_IQ_IMBALANCE, 0x3FF, reg);
 
1557
 
 
1558
                reg = result[final_candidate][7] & 0x3F;
 
1559
                phy_set_bb_reg(p_adapter, REG_OFDM_0_XB_RX_IQ_IMBALANCE, 0xFC00, reg);
 
1560
 
 
1561
                reg = (result[final_candidate][7] >> 6) & 0xF;
 
1562
                phy_set_bb_reg(p_adapter, REG_OFDM_0_AGC_RSSI_TABLE, 0x0000F000, reg);
 
1563
        }
 
1564
}
 
1565
 
 
1566
 
 
1567
boolean
 
1568
phy_simularity_compare_92c(
 
1569
        struct _ADAPTER *p_adapter,
 
1570
        s32             result[][8],
 
1571
        u8               c1,
 
1572
        u8               c2
 
1573
)
 
1574
{
 
1575
        u32             i, j, diff, simularity_bit_map, bound = 0;
 
1576
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
1577
        u8              final_candidate[2] = {0xFF, 0xFF};      /* for path A and path B */
 
1578
        boolean         is_result = true, is2T = IS_92C_SERIAL(p_hal_data->version_id);
 
1579
 
 
1580
        if (is2T)
 
1581
                bound = 8;
 
1582
        else
 
1583
                bound = 4;
 
1584
 
 
1585
        simularity_bit_map = 0;
 
1586
 
 
1587
        for (i = 0; i < bound; i++) {
 
1588
                diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - result[c2][i]) : (result[c2][i] - result[c1][i]);
 
1589
                if (diff > MAX_TOLERANCE) {
 
1590
                        if ((i == 2 || i == 6) && !simularity_bit_map) {
 
1591
                                if (result[c1][i] + result[c1][i + 1] == 0)
 
1592
                                        final_candidate[(i / 4)] = c2;
 
1593
                                else if (result[c2][i] + result[c2][i + 1] == 0)
 
1594
                                        final_candidate[(i / 4)] = c1;
 
1595
                                else
 
1596
                                        simularity_bit_map = simularity_bit_map | (1 << i);
 
1597
                        } else
 
1598
                                simularity_bit_map = simularity_bit_map | (1 << i);
 
1599
                }
 
1600
        }
 
1601
 
 
1602
        if (simularity_bit_map == 0) {
 
1603
                for (i = 0; i < (bound / 4); i++) {
 
1604
                        if (final_candidate[i] != 0xFF) {
 
1605
                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
 
1606
                                        result[3][j] = result[final_candidate[i]][j];
 
1607
                                is_result = false;
 
1608
                        }
 
1609
                }
 
1610
                return is_result;
 
1611
        } else if (!(simularity_bit_map & 0x0F)) {              /* path A OK */
 
1612
                for (i = 0; i < 4; i++)
 
1613
                        result[3][i] = result[c1][i];
 
1614
                return false;
 
1615
        } else if (!(simularity_bit_map & 0xF0) && is2T) {      /* path B OK */
 
1616
                for (i = 4; i < 8; i++)
 
1617
                        result[3][i] = result[c1][i];
 
1618
                return false;
 
1619
        } else
 
1620
                return false;
 
1621
 
 
1622
}
 
1623
 
 
1624
/*
 
1625
return false => do IQK again
 
1626
*/
 
1627
boolean
 
1628
phy_simularity_compare(
 
1629
        struct _ADAPTER *p_adapter,
 
1630
        s32             result[][8],
 
1631
        u8               c1,
 
1632
        u8               c2
 
1633
)
 
1634
{
 
1635
        return phy_simularity_compare_92c(p_adapter, result, c1, c2);
 
1636
 
 
1637
}
 
1638
 
 
1639
void
 
1640
_phy_iq_calibrate_8192c(
 
1641
        struct _ADAPTER *p_adapter,
 
1642
        s32             result[][8],
 
1643
        u8              t,
 
1644
        boolean         is2T
 
1645
)
 
1646
{
 
1647
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
1648
        u32                     i;
 
1649
        u8                      path_aok, path_bok;
 
1650
        u32                     ADDA_REG[IQK_ADDA_REG_NUM] = {
 
1651
                REG_FPGA0_XCD_SWITCH_CONTROL,   REG_BLUE_TOOTH,
 
1652
                REG_RX_WAIT_CCA,                REG_TX_CCK_RFON,
 
1653
                REG_TX_CCK_BBON,        REG_TX_OFDM_RFON,
 
1654
                REG_TX_OFDM_BBON,       REG_TX_TO_RX,
 
1655
                REG_TX_TO_TX,           REG_RX_CCK,
 
1656
                REG_RX_OFDM,            REG_RX_WAIT_RIFS,
 
1657
                REG_RX_TO_RX,           REG_STANDBY,
 
1658
                REG_SLEEP,                      REG_PMPD_ANAEN
 
1659
        };
 
1660
        u32                     IQK_MAC_REG[IQK_MAC_REG_NUM] = {
 
1661
                REG_TXPAUSE,            REG_BCN_CTRL,
 
1662
                REG_BCN_CTRL_1, REG_GPIO_MUXCFG
 
1663
        };
 
1664
 
 
1665
        /* since 92C & 92D have the different define in IQK_BB_REG */
 
1666
        u32     IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
 
1667
                REG_OFDM_0_TRX_PATH_ENABLE,             REG_OFDM_0_TR_MUX_PAR,
 
1668
                REG_FPGA0_XCD_RF_INTERFACE_SW,  REG_CONFIG_ANT_A,       REG_CONFIG_ANT_B,
 
1669
                REG_FPGA0_XAB_RF_INTERFACE_SW,  REG_FPGA0_XA_RF_INTERFACE_OE,
 
1670
                REG_FPGA0_XB_RF_INTERFACE_OE,   /*REG_FPGA0_RFMOD*/ REG_CCK_0_AFE_SETTING
 
1671
        };
 
1672
 
 
1673
        u32     IQK_BB_REG_92D[IQK_BB_REG_NUM_92D] = {  /* for normal */
 
1674
                REG_FPGA0_XAB_RF_INTERFACE_SW,  REG_FPGA0_XA_RF_INTERFACE_OE,
 
1675
                REG_FPGA0_XB_RF_INTERFACE_OE,   REG_OFDM_0_TR_MUX_PAR,
 
1676
                REG_FPGA0_XCD_RF_INTERFACE_SW,  REG_OFDM_0_TRX_PATH_ENABLE,
 
1677
                /*REG_FPGA0_RFMOD*/ REG_CCK_0_AFE_SETTING,                      REG_FPGA0_ANALOG_PARAMETER4,
 
1678
                REG_OFDM_0_XA_AGC_CORE1,                REG_OFDM_0_XB_AGC_CORE1
 
1679
        };
 
1680
#if MP_DRIVER
 
1681
        const u32       retry_count = 9;
 
1682
#else
 
1683
        const u32       retry_count = 2;
 
1684
#endif
 
1685
        /* Neil Chen--2011--05--19--
 
1686
        * 3 path Div */
 
1687
        u8                 rf_path_switch = 0x0;
 
1688
 
 
1689
        /* Note: IQ calibration must be performed after loading */
 
1690
        /*              PHY_REG.txt , and radio_a, radio_b.txt */
 
1691
 
 
1692
        u32 bbvalue;
 
1693
 
 
1694
        if (t == 0) {
 
1695
                /* bbvalue = phy_query_bb_reg(p_adapter, REG_FPGA0_RFMOD, MASKDWORD); */
 
1696
                /*      RTPRINT(FINIT, INIT_IQK, ("_phy_iq_calibrate_8192c()==>0x%08x\n",bbvalue)); */
 
1697
 
 
1698
                RTPRINT(FINIT, INIT_IQK, ("IQ Calibration for %s\n", (is2T ? "2T2R" : "1T1R")));
 
1699
 
 
1700
                /* Save ADDA parameters, turn path A ADDA on */
 
1701
                phy_save_adda_registers(p_adapter, ADDA_REG, p_hal_data->ADDA_backup, IQK_ADDA_REG_NUM);
 
1702
                phy_save_mac_registers(p_adapter, IQK_MAC_REG, p_hal_data->IQK_MAC_backup);
 
1703
                phy_save_adda_registers(p_adapter, IQK_BB_REG_92C, p_hal_data->IQK_BB_backup, IQK_BB_REG_NUM);
 
1704
        }
 
1705
 
 
1706
        phy_path_adda_on(p_adapter, ADDA_REG, true, is2T);
 
1707
 
 
1708
        if (t == 0)
 
1709
                p_hal_data->is_rf_pi_enable = (u8)phy_query_bb_reg(p_adapter, REG_FPGA0_XA_HSSI_PARAMETER1, BIT(8));
 
1710
 
 
1711
        if (!p_hal_data->is_rf_pi_enable) {
 
1712
                /* Switch BB to PI mode to do IQ Calibration. */
 
1713
                phy_pi_mode_switch(p_adapter, true);
 
1714
        }
 
1715
 
 
1716
        /* MAC settings */
 
1717
        phy_mac_setting_calibration(p_adapter, IQK_MAC_REG, p_hal_data->IQK_MAC_backup);
 
1718
 
 
1719
        /* phy_set_bb_reg(p_adapter, REG_FPGA0_RFMOD, BIT24, 0x00); */
 
1720
        phy_set_bb_reg(p_adapter, REG_CCK_0_AFE_SETTING, MASKDWORD, (0x0f000000 | (phy_query_bb_reg(p_adapter, REG_CCK_0_AFE_SETTING, MASKDWORD))));
 
1721
        phy_set_bb_reg(p_adapter, REG_OFDM_0_TRX_PATH_ENABLE, MASKDWORD, 0x03a05600);
 
1722
        phy_set_bb_reg(p_adapter, REG_OFDM_0_TR_MUX_PAR, MASKDWORD, 0x000800e4);
 
1723
        phy_set_bb_reg(p_adapter, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD, 0x22204000);
 
1724
        {
 
1725
                phy_set_bb_reg(p_adapter, REG_FPGA0_XAB_RF_INTERFACE_SW, BIT(10), 0x01);
 
1726
                phy_set_bb_reg(p_adapter, REG_FPGA0_XAB_RF_INTERFACE_SW, BIT(26), 0x01);
 
1727
                phy_set_bb_reg(p_adapter, REG_FPGA0_XA_RF_INTERFACE_OE, BIT(10), 0x00);
 
1728
                phy_set_bb_reg(p_adapter, REG_FPGA0_XB_RF_INTERFACE_OE, BIT(10), 0x00);
 
1729
        }
 
1730
 
 
1731
        if (is2T) {
 
1732
                phy_set_bb_reg(p_adapter, REG_FPGA0_XA_LSSI_PARAMETER, MASKDWORD, 0x00010000);
 
1733
                phy_set_bb_reg(p_adapter, REG_FPGA0_XB_LSSI_PARAMETER, MASKDWORD, 0x00010000);
 
1734
        }
 
1735
 
 
1736
        {
 
1737
                /* Page B init */
 
1738
                phy_set_bb_reg(p_adapter, REG_CONFIG_ANT_A, MASKDWORD, 0x00080000);
 
1739
 
 
1740
                if (is2T)
 
1741
                        phy_set_bb_reg(p_adapter, REG_CONFIG_ANT_B, MASKDWORD, 0x00080000);
 
1742
        }
 
1743
        /* IQ calibration setting */
 
1744
        RTPRINT(FINIT, INIT_IQK, ("IQK setting!\n"));
 
1745
        phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0x808000);
 
1746
        phy_set_bb_reg(p_adapter, REG_TX_IQK, MASKDWORD, 0x01007c00);
 
1747
        phy_set_bb_reg(p_adapter, REG_RX_IQK, MASKDWORD, 0x01004800);
 
1748
 
 
1749
        for (i = 0 ; i < retry_count ; i++) {
 
1750
                path_aok = phy_path_a_iqk_8192c(p_adapter, is2T);
 
1751
                if (path_aok == 0x03) {
 
1752
                        RTPRINT(FINIT, INIT_IQK, ("path A IQK Success!!\n"));
 
1753
                        result[t][0] = (phy_query_bb_reg(p_adapter, REG_TX_POWER_BEFORE_IQK_A, MASKDWORD) & 0x3FF0000) >> 16;
 
1754
                        result[t][1] = (phy_query_bb_reg(p_adapter, REG_TX_POWER_AFTER_IQK_A, MASKDWORD) & 0x3FF0000) >> 16;
 
1755
                        result[t][2] = (phy_query_bb_reg(p_adapter, REG_RX_POWER_BEFORE_IQK_A_2, MASKDWORD) & 0x3FF0000) >> 16;
 
1756
                        result[t][3] = (phy_query_bb_reg(p_adapter, REG_RX_POWER_AFTER_IQK_A_2, MASKDWORD) & 0x3FF0000) >> 16;
 
1757
                        break;
 
1758
                } else if (i == (retry_count - 1) && path_aok == 0x01) {        /* Tx IQK OK */
 
1759
                        RTPRINT(FINIT, INIT_IQK, ("path A IQK Only  Tx Success!!\n"));
 
1760
 
 
1761
                        result[t][0] = (phy_query_bb_reg(p_adapter, REG_TX_POWER_BEFORE_IQK_A, MASKDWORD) & 0x3FF0000) >> 16;
 
1762
                        result[t][1] = (phy_query_bb_reg(p_adapter, REG_TX_POWER_AFTER_IQK_A, MASKDWORD) & 0x3FF0000) >> 16;
 
1763
                }
 
1764
        }
 
1765
 
 
1766
        if (0x00 == path_aok)
 
1767
                RTPRINT(FINIT, INIT_IQK, ("path A IQK failed!!\n"));
 
1768
 
 
1769
        if (is2T) {
 
1770
                phy_path_a_stand_by(p_adapter);
 
1771
 
 
1772
                /* Turn path B ADDA on */
 
1773
                phy_path_adda_on(p_adapter, ADDA_REG, false, is2T);
 
1774
 
 
1775
                for (i = 0 ; i < retry_count ; i++) {
 
1776
                        path_bok = phy_path_b_iqk_8192c(p_adapter);
 
1777
                        if (path_bok == 0x03) {
 
1778
                                RTPRINT(FINIT, INIT_IQK, ("path B IQK Success!!\n"));
 
1779
                                result[t][4] = (phy_query_bb_reg(p_adapter, REG_TX_POWER_BEFORE_IQK_B, MASKDWORD) & 0x3FF0000) >> 16;
 
1780
                                result[t][5] = (phy_query_bb_reg(p_adapter, REG_TX_POWER_AFTER_IQK_B, MASKDWORD) & 0x3FF0000) >> 16;
 
1781
                                result[t][6] = (phy_query_bb_reg(p_adapter, REG_RX_POWER_BEFORE_IQK_B_2, MASKDWORD) & 0x3FF0000) >> 16;
 
1782
                                result[t][7] = (phy_query_bb_reg(p_adapter, REG_RX_POWER_AFTER_IQK_B_2, MASKDWORD) & 0x3FF0000) >> 16;
 
1783
                                break;
 
1784
                        } else if (i == (retry_count - 1) && path_bok == 0x01) {        /* Tx IQK OK */
 
1785
                                RTPRINT(FINIT, INIT_IQK, ("path B Only Tx IQK Success!!\n"));
 
1786
                                result[t][4] = (phy_query_bb_reg(p_adapter, REG_TX_POWER_BEFORE_IQK_B, MASKDWORD) & 0x3FF0000) >> 16;
 
1787
                                result[t][5] = (phy_query_bb_reg(p_adapter, REG_TX_POWER_AFTER_IQK_B, MASKDWORD) & 0x3FF0000) >> 16;
 
1788
                        }
 
1789
                }
 
1790
 
 
1791
                if (0x00 == path_bok)
 
1792
                        RTPRINT(FINIT, INIT_IQK, ("path B IQK failed!!\n"));
 
1793
        }
 
1794
 
 
1795
        /* Back to BB mode, load original value */
 
1796
        RTPRINT(FINIT, INIT_IQK, ("IQK:Back to BB mode, load original value!\n"));
 
1797
        phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0);
 
1798
 
 
1799
        if (t != 0) {
 
1800
                if (!p_hal_data->is_rf_pi_enable) {
 
1801
                        /* Switch back BB to SI mode after finish IQ Calibration. */
 
1802
                        phy_pi_mode_switch(p_adapter, false);
 
1803
                }
 
1804
 
 
1805
                /* Reload ADDA power saving parameters */
 
1806
                phy_reload_adda_registers(p_adapter, ADDA_REG, p_hal_data->ADDA_backup, IQK_ADDA_REG_NUM);
 
1807
 
 
1808
                /* Reload MAC parameters */
 
1809
                phy_reload_mac_registers(p_adapter, IQK_MAC_REG, p_hal_data->IQK_MAC_backup);
 
1810
 
 
1811
                /* Reload BB parameters */
 
1812
                phy_reload_adda_registers(p_adapter, IQK_BB_REG_92C, p_hal_data->IQK_BB_backup, IQK_BB_REG_NUM);
 
1813
 
 
1814
                /*Restore RX initial gain*/
 
1815
                phy_set_bb_reg(p_adapter, REG_FPGA0_XA_LSSI_PARAMETER, MASKDWORD, 0x00032ed3);
 
1816
                if (is2T)
 
1817
                        phy_set_bb_reg(p_adapter, REG_FPGA0_XB_LSSI_PARAMETER, MASKDWORD, 0x00032ed3);
 
1818
                /* load 0xe30 IQC default value */
 
1819
                phy_set_bb_reg(p_adapter, REG_TX_IQK_TONE_A, MASKDWORD, 0x01008c00);
 
1820
                phy_set_bb_reg(p_adapter, REG_RX_IQK_TONE_A, MASKDWORD, 0x01008c00);
 
1821
 
 
1822
        }
 
1823
        RTPRINT(FINIT, INIT_IQK, ("_phy_iq_calibrate_8192c() <==\n"));
 
1824
 
 
1825
}
 
1826
 
 
1827
 
 
1828
void
 
1829
_phy_lccalibrate92c(
 
1830
        struct _ADAPTER *p_adapter,
 
1831
        boolean         is2T
 
1832
)
 
1833
{
 
1834
        u8      tmp_reg;
 
1835
        u32     rf_amode = 0, rf_bmode = 0, lc_cal;
 
1836
        /*      HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter); */
 
1837
 
 
1838
        /* Check continuous TX and Packet TX */
 
1839
        tmp_reg = platform_efio_read_1byte(p_adapter, 0xd03);
 
1840
 
 
1841
        if ((tmp_reg & 0x70) != 0)                      /* Deal with contisuous TX case */
 
1842
                platform_efio_write_1byte(p_adapter, 0xd03, tmp_reg & 0x8F);    /* disable all continuous TX */
 
1843
        else                                                    /* Deal with Packet TX case */
 
1844
                platform_efio_write_1byte(p_adapter, REG_TXPAUSE, 0xFF);                        /* block all queues */
 
1845
 
 
1846
        if ((tmp_reg & 0x70) != 0) {
 
1847
                /* 1. Read original RF mode */
 
1848
                /* path-A */
 
1849
                rf_amode = phy_query_rf_reg(p_adapter, RF_PATH_A, RF_AC, MASK12BITS);
 
1850
 
 
1851
                /* path-B */
 
1852
                if (is2T)
 
1853
                        rf_bmode = phy_query_rf_reg(p_adapter, RF_PATH_B, RF_AC, MASK12BITS);
 
1854
 
 
1855
                /* 2. Set RF mode = standby mode */
 
1856
                /* path-A */
 
1857
                phy_set_rf_reg(p_adapter, RF_PATH_A, RF_AC, MASK12BITS, (rf_amode & 0x8FFFF) | 0x10000);
 
1858
 
 
1859
                /* path-B */
 
1860
                if (is2T)
 
1861
                        phy_set_rf_reg(p_adapter, RF_PATH_B, RF_AC, MASK12BITS, (rf_bmode & 0x8FFFF) | 0x10000);
 
1862
        }
 
1863
 
 
1864
        /* 3. Read RF reg18 */
 
1865
        lc_cal = phy_query_rf_reg(p_adapter, RF_PATH_A, RF_CHNLBW, MASK12BITS);
 
1866
 
 
1867
        /* 4. Set LC calibration begin  bit15 */
 
1868
        phy_set_rf_reg(p_adapter, RF_PATH_A, RF_CHNLBW, MASK12BITS, lc_cal | 0x08000);
 
1869
 
 
1870
        delay_ms(100);
 
1871
 
 
1872
 
 
1873
        /* Restore original situation */
 
1874
        if ((tmp_reg & 0x70) != 0) {    /* Deal with contisuous TX case */
 
1875
                /* path-A */
 
1876
                platform_efio_write_1byte(p_adapter, 0xd03, tmp_reg);
 
1877
                phy_set_rf_reg(p_adapter, RF_PATH_A, RF_AC, MASK12BITS, rf_amode);
 
1878
 
 
1879
                /* path-B */
 
1880
                if (is2T)
 
1881
                        phy_set_rf_reg(p_adapter, RF_PATH_B, RF_AC, MASK12BITS, rf_bmode);
 
1882
        } else /* Deal with Packet TX case */
 
1883
                platform_efio_write_1byte(p_adapter, REG_TXPAUSE, 0x00);
 
1884
}
 
1885
 
 
1886
 
 
1887
void
 
1888
phy_lc_calibrate(
 
1889
        struct _ADAPTER *p_adapter,
 
1890
        boolean         is2T
 
1891
)
 
1892
{
 
1893
        _phy_lccalibrate92c(p_adapter, is2T);
 
1894
}
 
1895
 
 
1896
 
 
1897
 
 
1898
/* Analog Pre-distortion calibration */
 
1899
#define         APK_BB_REG_NUM  8
 
1900
#define         APK_CURVE_REG_NUM 4
 
1901
#define         PATH_NUM                2
 
1902
 
 
1903
void
 
1904
_phy_ap_calibrate_8192c(
 
1905
        struct _ADAPTER *p_adapter,
 
1906
        s8              delta,
 
1907
        boolean         is2T
 
1908
)
 
1909
{
 
1910
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
1911
 
 
1912
        u32                     reg_d[PATH_NUM];
 
1913
        u32                     tmp_reg, index, offset, i, apkbound;
 
1914
        u8                      path, pathbound = PATH_NUM;
 
1915
        u32                     BB_backup[APK_BB_REG_NUM];
 
1916
        u32                     BB_REG[APK_BB_REG_NUM] = {
 
1917
                REG_FPGA1_TX_BLOCK,     REG_OFDM_0_TRX_PATH_ENABLE,
 
1918
                REG_FPGA0_RFMOD,        REG_OFDM_0_TR_MUX_PAR,
 
1919
                REG_FPGA0_XCD_RF_INTERFACE_SW,  REG_FPGA0_XAB_RF_INTERFACE_SW,
 
1920
                REG_FPGA0_XA_RF_INTERFACE_OE,   REG_FPGA0_XB_RF_INTERFACE_OE
 
1921
        };
 
1922
        u32                     BB_AP_MODE[APK_BB_REG_NUM] = {
 
1923
                0x00000020, 0x00a05430, 0x02040000,
 
1924
                0x000800e4, 0x00204000
 
1925
        };
 
1926
        u32                     BB_normal_AP_MODE[APK_BB_REG_NUM] = {
 
1927
                0x00000020, 0x00a05430, 0x02040000,
 
1928
                0x000800e4, 0x22204000
 
1929
        };
 
1930
 
 
1931
        u32                     AFE_backup[IQK_ADDA_REG_NUM];
 
1932
        u32                     AFE_REG[IQK_ADDA_REG_NUM] = {
 
1933
                REG_FPGA0_XCD_SWITCH_CONTROL,   REG_BLUE_TOOTH,
 
1934
                REG_RX_WAIT_CCA,                REG_TX_CCK_RFON,
 
1935
                REG_TX_CCK_BBON,        REG_TX_OFDM_RFON,
 
1936
                REG_TX_OFDM_BBON,       REG_TX_TO_RX,
 
1937
                REG_TX_TO_TX,           REG_RX_CCK,
 
1938
                REG_RX_OFDM,            REG_RX_WAIT_RIFS,
 
1939
                REG_RX_TO_RX,           REG_STANDBY,
 
1940
                REG_SLEEP,                      REG_PMPD_ANAEN
 
1941
        };
 
1942
 
 
1943
        u32                     MAC_backup[IQK_MAC_REG_NUM];
 
1944
        u32                     MAC_REG[IQK_MAC_REG_NUM] = {
 
1945
                REG_TXPAUSE,            REG_BCN_CTRL,
 
1946
                REG_BCN_CTRL_1, REG_GPIO_MUXCFG
 
1947
        };
 
1948
 
 
1949
        u32                     APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
 
1950
                {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
 
1951
                {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
 
1952
        };
 
1953
 
 
1954
        u32                     APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
 
1955
                {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c},  /* path settings equal to path b settings */
 
1956
                {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
 
1957
        };
 
1958
 
 
1959
        u32                     APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
 
1960
                {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
 
1961
                {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
 
1962
        };
 
1963
 
 
1964
        u32                     APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
 
1965
                {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a},  /* path settings equal to path b settings */
 
1966
                {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
 
1967
        };
 
1968
#if 0
 
1969
        u32                     APK_RF_value_A[PATH_NUM][APK_BB_REG_NUM] = {
 
1970
                {0x1adb0, 0x1adb0, 0x1ada0, 0x1ad90, 0x1ad80},
 
1971
                {0x00fb0, 0x00fb0, 0x00fa0, 0x00f90, 0x00f80}
 
1972
        };
 
1973
#endif
 
1974
        u32                     AFE_on_off[PATH_NUM] = {
 
1975
                0x04db25a4, 0x0b1b25a4
 
1976
        };      /* path A on path B off / path A off path B on */
 
1977
 
 
1978
        u32                     APK_offset[PATH_NUM] = {
 
1979
                REG_CONFIG_ANT_A, REG_CONFIG_ANT_B
 
1980
        };
 
1981
 
 
1982
        u32                     APK_normal_offset[PATH_NUM] = {
 
1983
                REG_CONFIG_PMPD_ANT_A, REG_CONFIG_PMPD_ANT_B
 
1984
        };
 
1985
 
 
1986
        u32                     APK_value[PATH_NUM] = {
 
1987
                0x92fc0000, 0x12fc0000
 
1988
        };
 
1989
 
 
1990
        u32                     APK_normal_value[PATH_NUM] = {
 
1991
                0x92680000, 0x12680000
 
1992
        };
 
1993
 
 
1994
        s8                      APK_delta_mapping[APK_BB_REG_NUM][13] = {
 
1995
                {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
 
1996
                {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
 
1997
                {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
 
1998
                {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
 
1999
                {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
 
2000
        };
 
2001
 
 
2002
        u32                     APK_normal_setting_value_1[13] = {
 
2003
                0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
 
2004
                0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
 
2005
                0x12680000, 0x00880000, 0x00880000
 
2006
        };
 
2007
 
 
2008
        u32                     APK_normal_setting_value_2[16] = {
 
2009
                0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
 
2010
                0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
 
2011
                0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
 
2012
                0x00050006
 
2013
        };
 
2014
 
 
2015
        u32                     APK_result[PATH_NUM][APK_BB_REG_NUM];   /* val_1_1a, val_1_2a, val_2a, val_3a, val_4a
 
2016
 *      u32                     AP_curve[PATH_NUM][APK_CURVE_REG_NUM]; */
 
2017
 
 
2018
        s32                     BB_offset, delta_V, delta_offset;
 
2019
 
 
2020
#if MP_DRIVER == 1
 
2021
        PMPT_CONTEXT    p_mpt_ctx = &(p_adapter->mpt_ctx);
 
2022
 
 
2023
        p_mpt_ctx->APK_bound[0] = 45;
 
2024
        p_mpt_ctx->APK_bound[1] = 52;
 
2025
#endif
 
2026
 
 
2027
        RTPRINT(FINIT, INIT_IQK, ("==>_phy_ap_calibrate_8192c() delta %d\n", delta));
 
2028
        RTPRINT(FINIT, INIT_IQK, ("AP Calibration for %s\n", (is2T ? "2T2R" : "1T1R")));
 
2029
        if (!is2T)
 
2030
                pathbound = 1;
 
2031
 
 
2032
        /* 2 FOR NORMAL CHIP SETTINGS */
 
2033
 
 
2034
        /* Temporarily do not allow normal driver to do the following settings because these offset
 
2035
         * and value will cause RF internal PA to be unpredictably disabled by HW, such that RF Tx signal
 
2036
         * will disappear after disable/enable card many times on 88CU. RF SD and DD have not find the
 
2037
         * root cause, so we remove these actions temporarily. Added by tynli and SD3 Allen. 2010.05.31. */
 
2038
#if MP_DRIVER != 1
 
2039
        return;
 
2040
#endif
 
2041
        /* settings adjust for normal chip */
 
2042
        for (index = 0; index < PATH_NUM; index++) {
 
2043
                APK_offset[index] = APK_normal_offset[index];
 
2044
                APK_value[index] = APK_normal_value[index];
 
2045
                AFE_on_off[index] = 0x6fdb25a4;
 
2046
        }
 
2047
 
 
2048
        for (index = 0; index < APK_BB_REG_NUM; index++) {
 
2049
                for (path = 0; path < pathbound; path++) {
 
2050
                        APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index];
 
2051
                        APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index];
 
2052
                }
 
2053
                BB_AP_MODE[index] = BB_normal_AP_MODE[index];
 
2054
        }
 
2055
 
 
2056
        apkbound = 6;
 
2057
 
 
2058
        /* save BB default value */
 
2059
        for (index = 0; index < APK_BB_REG_NUM ; index++) {
 
2060
                if (index == 0)         /* skip */
 
2061
                        continue;
 
2062
                BB_backup[index] = phy_query_bb_reg(p_adapter, BB_REG[index], MASKDWORD);
 
2063
        }
 
2064
 
 
2065
        /* save MAC default value */
 
2066
        phy_save_mac_registers(p_adapter, MAC_REG, MAC_backup);
 
2067
 
 
2068
        /* save AFE default value */
 
2069
        phy_save_adda_registers(p_adapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
 
2070
 
 
2071
        for (path = 0; path < pathbound; path++) {
 
2072
 
 
2073
 
 
2074
                if (path == RF_PATH_A) {
 
2075
                        /* path A APK */
 
2076
                        /* load APK setting */
 
2077
                        /* path-A */
 
2078
                        offset = REG_PDP_ANT_A;
 
2079
                        for (index = 0; index < 11; index++) {
 
2080
                                phy_set_bb_reg(p_adapter, offset, MASKDWORD, APK_normal_setting_value_1[index]);
 
2081
                                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x%x value 0x%x\n", offset, phy_query_bb_reg(p_adapter, offset, MASKDWORD)));
 
2082
 
 
2083
                                offset += 0x04;
 
2084
                        }
 
2085
 
 
2086
                        phy_set_bb_reg(p_adapter, REG_CONFIG_PMPD_ANT_B, MASKDWORD, 0x12680000);
 
2087
 
 
2088
                        offset = REG_CONFIG_ANT_A;
 
2089
                        for (; index < 13; index++) {
 
2090
                                phy_set_bb_reg(p_adapter, offset, MASKDWORD, APK_normal_setting_value_1[index]);
 
2091
                                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x%x value 0x%x\n", offset, phy_query_bb_reg(p_adapter, offset, MASKDWORD)));
 
2092
 
 
2093
                                offset += 0x04;
 
2094
                        }
 
2095
 
 
2096
                        /* page-B1 */
 
2097
                        phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0x400000);
 
2098
 
 
2099
                        /* path A */
 
2100
                        offset = REG_PDP_ANT_A;
 
2101
                        for (index = 0; index < 16; index++) {
 
2102
                                phy_set_bb_reg(p_adapter, offset, MASKDWORD, APK_normal_setting_value_2[index]);
 
2103
                                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x%x value 0x%x\n", offset, phy_query_bb_reg(p_adapter, offset, MASKDWORD)));
 
2104
 
 
2105
                                offset += 0x04;
 
2106
                        }
 
2107
                        phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0);
 
2108
                } else if (path == RF_PATH_B) {
 
2109
                        /* path B APK */
 
2110
                        /* load APK setting */
 
2111
                        /* path-B */
 
2112
                        offset = REG_PDP_ANT_B;
 
2113
                        for (index = 0; index < 10; index++) {
 
2114
                                phy_set_bb_reg(p_adapter, offset, MASKDWORD, APK_normal_setting_value_1[index]);
 
2115
                                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x%x value 0x%x\n", offset, phy_query_bb_reg(p_adapter, offset, MASKDWORD)));
 
2116
 
 
2117
                                offset += 0x04;
 
2118
                        }
 
2119
                        phy_set_bb_reg(p_adapter, REG_CONFIG_PMPD_ANT_A, MASKDWORD, 0x12680000);
 
2120
 
 
2121
                        phy_set_bb_reg(p_adapter, REG_CONFIG_PMPD_ANT_B, MASKDWORD, 0x12680000);
 
2122
 
 
2123
                        offset = REG_CONFIG_ANT_A;
 
2124
                        index = 11;
 
2125
                        for (; index < 13; index++) { /* offset 0xb68, 0xb6c */
 
2126
                                phy_set_bb_reg(p_adapter, offset, MASKDWORD, APK_normal_setting_value_1[index]);
 
2127
                                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x%x value 0x%x\n", offset, phy_query_bb_reg(p_adapter, offset, MASKDWORD)));
 
2128
 
 
2129
                                offset += 0x04;
 
2130
                        }
 
2131
 
 
2132
                        /* page-B1 */
 
2133
                        phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0x400000);
 
2134
 
 
2135
                        /* path B */
 
2136
                        offset = 0xb60;
 
2137
                        for (index = 0; index < 16; index++) {
 
2138
                                phy_set_bb_reg(p_adapter, offset, MASKDWORD, APK_normal_setting_value_2[index]);
 
2139
                                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x%x value 0x%x\n", offset, phy_query_bb_reg(p_adapter, offset, MASKDWORD)));
 
2140
 
 
2141
                                offset += 0x04;
 
2142
                        }
 
2143
                        phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0);
 
2144
                }
 
2145
 
 
2146
                /* save RF default value */
 
2147
                reg_d[path] = phy_query_rf_reg(p_adapter, path, RF_TXBIAS_A, RFREGOFFSETMASK);
 
2148
 
 
2149
                /* path A AFE all on, path B AFE All off or vise versa */
 
2150
                for (index = 0; index < IQK_ADDA_REG_NUM ; index++)
 
2151
                        phy_set_bb_reg(p_adapter, AFE_REG[index], MASKDWORD, AFE_on_off[path]);
 
2152
                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0xe70 %x\n", phy_query_bb_reg(p_adapter, REG_RX_WAIT_CCA, MASKDWORD)));
 
2153
 
 
2154
                /* BB to AP mode */
 
2155
                if (path == 0) {
 
2156
                        for (index = 0; index < APK_BB_REG_NUM ; index++) {
 
2157
 
 
2158
                                if (index == 0)         /* skip */
 
2159
                                        continue;
 
2160
                                else if (index < 5)
 
2161
                                        phy_set_bb_reg(p_adapter, BB_REG[index], MASKDWORD, BB_AP_MODE[index]);
 
2162
                                else if (BB_REG[index] == 0x870)
 
2163
                                        phy_set_bb_reg(p_adapter, BB_REG[index], MASKDWORD, BB_backup[index] | BIT(10) | BIT(26));
 
2164
                                else
 
2165
                                        phy_set_bb_reg(p_adapter, BB_REG[index], BIT(10), 0x0);
 
2166
                        }
 
2167
 
 
2168
                        phy_set_bb_reg(p_adapter, REG_TX_IQK_TONE_A, MASKDWORD, 0x01008c00);
 
2169
                        phy_set_bb_reg(p_adapter, REG_RX_IQK_TONE_A, MASKDWORD, 0x01008c00);
 
2170
                } else {        /* path B */
 
2171
                        phy_set_bb_reg(p_adapter, REG_TX_IQK_TONE_B, MASKDWORD, 0x01008c00);
 
2172
                        phy_set_bb_reg(p_adapter, REG_RX_IQK_TONE_B, MASKDWORD, 0x01008c00);
 
2173
 
 
2174
                }
 
2175
 
 
2176
                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x800 %x\n", phy_query_bb_reg(p_adapter, 0x800, MASKDWORD)));
 
2177
 
 
2178
                /* MAC settings */
 
2179
                phy_mac_setting_calibration(p_adapter, MAC_REG, MAC_backup);
 
2180
 
 
2181
                if (path == RF_PATH_A)  /* path B to standby mode */
 
2182
                        phy_set_rf_reg(p_adapter, RF_PATH_B, RF_AC, RFREGOFFSETMASK, 0x10000);
 
2183
                else {          /* path A to standby mode */
 
2184
                        phy_set_rf_reg(p_adapter, RF_PATH_A, RF_AC, RFREGOFFSETMASK, 0x10000);
 
2185
                        phy_set_rf_reg(p_adapter, RF_PATH_A, RF_MODE1, RFREGOFFSETMASK, 0x1000f);
 
2186
                        phy_set_rf_reg(p_adapter, RF_PATH_A, RF_MODE2, RFREGOFFSETMASK, 0x20103);
 
2187
                }
 
2188
 
 
2189
                delta_offset = ((delta + 14) / 2);
 
2190
                if (delta_offset < 0)
 
2191
                        delta_offset = 0;
 
2192
                else if (delta_offset > 12)
 
2193
                        delta_offset = 12;
 
2194
 
 
2195
                /* AP calibration */
 
2196
                for (index = 0; index < APK_BB_REG_NUM; index++) {
 
2197
                        if (index != 1) /* only DO PA11+PAD01001, AP RF setting */
 
2198
                                continue;
 
2199
 
 
2200
                        tmp_reg = APK_RF_init_value[path][index];
 
2201
#if 1
 
2202
                        if (!p_hal_data->is_apk_thermal_meter_ignore) {
 
2203
                                BB_offset = (tmp_reg & 0xF0000) >> 16;
 
2204
 
 
2205
                                if (!(tmp_reg & BIT(15))) /* sign bit 0 */
 
2206
                                        BB_offset = -BB_offset;
 
2207
 
 
2208
                                delta_V = APK_delta_mapping[index][delta_offset];
 
2209
 
 
2210
                                BB_offset += delta_V;
 
2211
 
 
2212
                                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() APK index %d tmp_reg 0x%x delta_V %d delta_offset %d\n", index, tmp_reg, delta_V, delta_offset));
 
2213
 
 
2214
                                if (BB_offset < 0) {
 
2215
                                        tmp_reg = tmp_reg & (~BIT(15));
 
2216
                                        BB_offset = -BB_offset;
 
2217
                                } else
 
2218
                                        tmp_reg = tmp_reg | BIT(15);
 
2219
                                tmp_reg = (tmp_reg & 0xFFF0FFFF) | (BB_offset << 16);
 
2220
                        }
 
2221
#endif
 
2222
 
 
2223
#if DEV_BUS_TYPE == RT_PCI_INTERFACE
 
2224
                        if (IS_81xxC_VENDOR_UMC_B_CUT(p_hal_data->version_id))
 
2225
                                phy_set_rf_reg(p_adapter, path, RF_IPA_A, RFREGOFFSETMASK, 0x894ae);
 
2226
                        else
 
2227
#endif
 
2228
                                phy_set_rf_reg(p_adapter, path, RF_IPA_A, RFREGOFFSETMASK, 0x8992e);
 
2229
                        RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0xc %x\n", phy_query_rf_reg(p_adapter, path, RF_IPA_A, RFREGOFFSETMASK)));
 
2230
                        phy_set_rf_reg(p_adapter, path, RF_AC, RFREGOFFSETMASK, APK_RF_value_0[path][index]);
 
2231
                        RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x0 %x\n", phy_query_rf_reg(p_adapter, path, RF_AC, RFREGOFFSETMASK)));
 
2232
                        phy_set_rf_reg(p_adapter, path, RF_TXBIAS_A, RFREGOFFSETMASK, tmp_reg);
 
2233
                        RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0xd %x\n", phy_query_rf_reg(p_adapter, path, RF_TXBIAS_A, RFREGOFFSETMASK)));
 
2234
 
 
2235
                        /* PA11+PAD01111, one shot */
 
2236
                        i = 0;
 
2237
                        do {
 
2238
                                phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0x800000);
 
2239
                                {
 
2240
                                        phy_set_bb_reg(p_adapter, APK_offset[path], MASKDWORD, APK_value[0]);
 
2241
                                        RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x%x value 0x%x\n", APK_offset[path], phy_query_bb_reg(p_adapter, APK_offset[path], MASKDWORD)));
 
2242
                                        delay_ms(3);
 
2243
                                        phy_set_bb_reg(p_adapter, APK_offset[path], MASKDWORD, APK_value[1]);
 
2244
                                        RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0x%x value 0x%x\n", APK_offset[path], phy_query_bb_reg(p_adapter, APK_offset[path], MASKDWORD)));
 
2245
 
 
2246
                                        delay_ms(20);
 
2247
                                }
 
2248
                                phy_set_bb_reg(p_adapter, REG_FPGA0_IQK, 0xffffff00, 0);
 
2249
 
 
2250
                                if (path == RF_PATH_A)
 
2251
                                        tmp_reg = phy_query_bb_reg(p_adapter, REG_APK, 0x03E00000);
 
2252
                                else
 
2253
                                        tmp_reg = phy_query_bb_reg(p_adapter, REG_APK, 0xF8000000);
 
2254
                                RTPRINT(FINIT, INIT_IQK, ("_phy_ap_calibrate_8192c() offset 0xbd8[25:21] %x\n", tmp_reg));
 
2255
 
 
2256
 
 
2257
                                i++;
 
2258
                        } while (tmp_reg > apkbound && i < 4);
 
2259
 
 
2260
                        APK_result[path][index] = tmp_reg;
 
2261
                }
 
2262
        }
 
2263
 
 
2264
        /* reload MAC default value */
 
2265
        phy_reload_mac_registers(p_adapter, MAC_REG, MAC_backup);
 
2266
 
 
2267
        /* reload BB default value */
 
2268
        for (index = 0; index < APK_BB_REG_NUM ; index++) {
 
2269
 
 
2270
                if (index == 0)         /* skip */
 
2271
                        continue;
 
2272
                phy_set_bb_reg(p_adapter, BB_REG[index], MASKDWORD, BB_backup[index]);
 
2273
        }
 
2274
 
 
2275
        /* reload AFE default value */
 
2276
        phy_reload_adda_registers(p_adapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
 
2277
 
 
2278
        /* reload RF path default value */
 
2279
        for (path = 0; path < pathbound; path++) {
 
2280
                phy_set_rf_reg(p_adapter, path, RF_TXBIAS_A, RFREGOFFSETMASK, reg_d[path]);
 
2281
                if (path == RF_PATH_B) {
 
2282
                        phy_set_rf_reg(p_adapter, RF_PATH_A, RF_MODE1, RFREGOFFSETMASK, 0x1000f);
 
2283
                        phy_set_rf_reg(p_adapter, RF_PATH_A, RF_MODE2, RFREGOFFSETMASK, 0x20101);
 
2284
                }
 
2285
 
 
2286
                /* note no index == 0 */
 
2287
                if (APK_result[path][1] > 6)
 
2288
                        APK_result[path][1] = 6;
 
2289
                RTPRINT(FINIT, INIT_IQK, ("apk path %d result %d 0x%x \t", path, 1, APK_result[path][1]));
 
2290
        }
 
2291
 
 
2292
        RTPRINT(FINIT, INIT_IQK, ("\n"));
 
2293
 
 
2294
 
 
2295
        for (path = 0; path < pathbound; path++) {
 
2296
                phy_set_rf_reg(p_adapter, path, RF_BS_PA_APSET_G1_G4, RFREGOFFSETMASK,
 
2297
                        ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1]));
 
2298
                if (path == RF_PATH_A)
 
2299
                        phy_set_rf_reg(p_adapter, path, RF_BS_PA_APSET_G5_G8, RFREGOFFSETMASK,
 
2300
                                ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05));
 
2301
                else
 
2302
                        phy_set_rf_reg(p_adapter, path, RF_BS_PA_APSET_G5_G8, RFREGOFFSETMASK,
 
2303
                                ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05));
 
2304
 
 
2305
                phy_set_rf_reg(p_adapter, path, RF_BS_PA_APSET_G9_G11, RFREGOFFSETMASK, ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08));
 
2306
        }
 
2307
 
 
2308
        p_hal_data->is_ap_kdone = true;
 
2309
 
 
2310
        RTPRINT(FINIT, INIT_IQK, ("<==_phy_ap_calibrate_8192c()\n"));
 
2311
}
 
2312
 
 
2313
 
 
2314
void
 
2315
phy_iq_calibrate_8192c(
 
2316
        struct _ADAPTER *p_adapter,
 
2317
        boolean is_recovery
 
2318
)
 
2319
{
 
2320
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
2321
        s32                     result[4][8];   /* last is final result */
 
2322
        u8                      i, final_candidate, indexforchannel;
 
2323
        boolean                 is_patha_ok, is_pathb_ok;
 
2324
        s32                     rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, regecc, reg_tmp = 0;
 
2325
        boolean                 is12simular, is13simular, is23simular;
 
2326
        boolean         is_start_cont_tx = false, is_single_tone = false, is_carrier_suppression = false;
 
2327
        u32                     IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
 
2328
                REG_OFDM_0_XA_RX_IQ_IMBALANCE,  REG_OFDM_0_XB_RX_IQ_IMBALANCE,
 
2329
                REG_OFDM_0_ECCA_THRESHOLD,      REG_OFDM_0_AGC_RSSI_TABLE,
 
2330
                REG_OFDM_0_XA_TX_IQ_IMBALANCE,  REG_OFDM_0_XB_TX_IQ_IMBALANCE,
 
2331
                REG_OFDM_0_XC_TX_AFE,                   REG_OFDM_0_XD_TX_AFE,
 
2332
                REG_OFDM_0_RX_IQ_EXT_ANTA
 
2333
        };
 
2334
 
 
2335
        if (odm_check_power_status(p_adapter) == false)
 
2336
                return;
 
2337
 
 
2338
#if MP_DRIVER == 1
 
2339
        is_start_cont_tx = p_adapter->mpt_ctx.is_start_cont_tx;
 
2340
        is_single_tone = p_adapter->mpt_ctx.is_single_tone;
 
2341
        is_carrier_suppression = p_adapter->mpt_ctx.is_carrier_suppression;
 
2342
#endif
 
2343
 
 
2344
        /* ignore IQK when continuous Tx */
 
2345
        if (is_start_cont_tx || is_single_tone || is_carrier_suppression)
 
2346
                return;
 
2347
 
 
2348
#ifdef DISABLE_BB_RF
 
2349
        return;
 
2350
#endif
 
2351
        if (p_adapter->is_slave_of_dmsp)
 
2352
                return;
 
2353
 
 
2354
        if (is_recovery) {
 
2355
                phy_reload_adda_registers(p_adapter, IQK_BB_REG_92C, p_hal_data->IQK_BB_backup_recover, 9);
 
2356
                return;
 
2357
 
 
2358
        }
 
2359
 
 
2360
        RTPRINT(FINIT, INIT_IQK, ("IQK:Start!!!\n"));
 
2361
 
 
2362
        for (i = 0; i < 8; i++) {
 
2363
                result[0][i] = 0;
 
2364
                result[1][i] = 0;
 
2365
                result[2][i] = 0;
 
2366
                result[3][i] = 0;
 
2367
        }
 
2368
        final_candidate = 0xff;
 
2369
        is_patha_ok = false;
 
2370
        is_pathb_ok = false;
 
2371
        is12simular = false;
 
2372
        is23simular = false;
 
2373
        is13simular = false;
 
2374
 
 
2375
        acquire_cck_and_rw_page_a_control(p_adapter);
 
2376
        /*RT_TRACE(COMP_INIT,DBG_LOUD,("Acquire Mutex in IQCalibrate\n"));*/
 
2377
        for (i = 0; i < 3; i++) {
 
2378
                /*For 88C 1T1R*/
 
2379
                _phy_iq_calibrate_8192c(p_adapter, result, i, false);
 
2380
 
 
2381
                if (i == 1) {
 
2382
                        is12simular = phy_simularity_compare(p_adapter, result, 0, 1);
 
2383
                        if (is12simular) {
 
2384
                                final_candidate = 0;
 
2385
                                break;
 
2386
                        }
 
2387
                }
 
2388
 
 
2389
                if (i == 2) {
 
2390
                        is13simular = phy_simularity_compare(p_adapter, result, 0, 2);
 
2391
                        if (is13simular) {
 
2392
                                final_candidate = 0;
 
2393
                                break;
 
2394
                        }
 
2395
 
 
2396
                        is23simular = phy_simularity_compare(p_adapter, result, 1, 2);
 
2397
                        if (is23simular)
 
2398
                                final_candidate = 1;
 
2399
                        else {
 
2400
                                for (i = 0; i < 8; i++)
 
2401
                                        reg_tmp += result[3][i];
 
2402
 
 
2403
                                if (reg_tmp != 0)
 
2404
                                        final_candidate = 3;
 
2405
                                else
 
2406
                                        final_candidate = 0xFF;
 
2407
                        }
 
2408
                }
 
2409
        }
 
2410
        /*      RT_TRACE(COMP_INIT,DBG_LOUD,("Release Mutex in IQCalibrate\n")); */
 
2411
        release_cck_and_rw_pagea_control(p_adapter);
 
2412
 
 
2413
        for (i = 0; i < 4; i++) {
 
2414
                rege94 = result[i][0];
 
2415
                rege9c = result[i][1];
 
2416
                regea4 = result[i][2];
 
2417
                regeac = result[i][3];
 
2418
                regeb4 = result[i][4];
 
2419
                regebc = result[i][5];
 
2420
                regec4 = result[i][6];
 
2421
                regecc = result[i][7];
 
2422
                RTPRINT(FINIT, INIT_IQK, ("IQK: rege94=%x rege9c=%x regea4=%x regeac=%x regeb4=%x regebc=%x regec4=%x regecc=%x\n ", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, regecc));
 
2423
        }
 
2424
 
 
2425
        if (final_candidate != 0xff) {
 
2426
                p_hal_data->rege94 = rege94 = result[final_candidate][0];
 
2427
                p_hal_data->rege9c = rege9c = result[final_candidate][1];
 
2428
                regea4 = result[final_candidate][2];
 
2429
                regeac = result[final_candidate][3];
 
2430
                p_hal_data->regeb4 = regeb4 = result[final_candidate][4];
 
2431
                p_hal_data->regebc = regebc = result[final_candidate][5];
 
2432
                regec4 = result[final_candidate][6];
 
2433
                regecc = result[final_candidate][7];
 
2434
                RTPRINT(FINIT, INIT_IQK, ("IQK: final_candidate is %x\n", final_candidate));
 
2435
                RTPRINT(FINIT, INIT_IQK, ("IQK: rege94=%x rege9c=%x regea4=%x regeac=%x regeb4=%x regebc=%x regec4=%x regecc=%x\n ", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, regecc));
 
2436
                is_patha_ok = is_pathb_ok = true;
 
2437
        } else {
 
2438
                rege94 = regeb4 = p_hal_data->rege94 = p_hal_data->regeb4 = 0x100;      /* X default value */
 
2439
                rege9c = regebc = p_hal_data->rege9c = p_hal_data->regebc = 0x0;                /* Y default value */
 
2440
        }
 
2441
 
 
2442
        if ((rege94 != 0)/*&&(regea4 != 0)*/) {
 
2443
                if (p_hal_data->current_band_type == BAND_ON_5G)
 
2444
                        phy_path_a_fill_iqk_matrix_5g_normal(p_adapter, is_patha_ok, result, final_candidate, (regea4 == 0));
 
2445
                else
 
2446
                        phy_path_a_fill_iqk_matrix(p_adapter, is_patha_ok, result, final_candidate, (regea4 == 0));
 
2447
 
 
2448
        }
 
2449
 
 
2450
        if (IS_92C_SERIAL(p_hal_data->version_id) || IS_92D_SINGLEPHY(p_hal_data->version_id)) {
 
2451
                if ((regeb4 != 0)/*&&(regec4 != 0)*/) {
 
2452
                        if (p_hal_data->current_band_type == BAND_ON_5G)
 
2453
                                phy_path_b_fill_iqk_matrix_5g_normal(p_adapter, is_pathb_ok, result, final_candidate, (regec4 == 0));
 
2454
                        else
 
2455
                                phy_path_b_fill_iqk_matrix(p_adapter, is_pathb_ok, result, final_candidate, (regec4 == 0));
 
2456
                }
 
2457
        }
 
2458
 
 
2459
        phy_save_adda_registers(p_adapter, IQK_BB_REG_92C, p_hal_data->IQK_BB_backup_recover, 9);
 
2460
 
 
2461
}
 
2462
 
 
2463
 
 
2464
void
 
2465
phy_lc_calibrate_8192c(
 
2466
        struct _ADAPTER *p_adapter
 
2467
)
 
2468
{
 
2469
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
2470
        boolean         is_start_cont_tx = false, is_single_tone = false, is_carrier_suppression = false;
 
2471
        PMGNT_INFO              p_mgnt_info = &p_adapter->MgntInfo;
 
2472
        PMGNT_INFO              p_mgnt_info_buddy_adapter;
 
2473
        u32                     timeout = 2000, timecount = 0;
 
2474
        struct _ADAPTER *buddy_adapter = p_adapter->buddy_adapter;
 
2475
 
 
2476
#if MP_DRIVER == 1
 
2477
        is_start_cont_tx = p_adapter->mpt_ctx.is_start_cont_tx;
 
2478
        is_single_tone = p_adapter->mpt_ctx.is_single_tone;
 
2479
        is_carrier_suppression = p_adapter->mpt_ctx.is_carrier_suppression;
 
2480
#endif
 
2481
 
 
2482
#ifdef DISABLE_BB_RF
 
2483
        return;
 
2484
#endif
 
2485
 
 
2486
        /* ignore LCK when continuous Tx */
 
2487
        if (is_start_cont_tx || is_single_tone || is_carrier_suppression)
 
2488
                return;
 
2489
 
 
2490
        if (buddy_adapter != NULL &&
 
2491
            ((p_adapter->interface_index == 0 && p_hal_data->current_band_type == BAND_ON_2_4G) ||
 
2492
             (p_adapter->interface_index == 1 && p_hal_data->current_band_type == BAND_ON_5G))) {
 
2493
                p_mgnt_info_buddy_adapter = &buddy_adapter->MgntInfo;
 
2494
                while (p_mgnt_info_buddy_adapter->is_scan_in_progress && timecount < timeout) {
 
2495
                        delay_ms(50);
 
2496
                        timecount += 50;
 
2497
                }
 
2498
        }
 
2499
 
 
2500
        while (p_mgnt_info->is_scan_in_progress && timecount < timeout) {
 
2501
                delay_ms(50);
 
2502
                timecount += 50;
 
2503
        }
 
2504
 
 
2505
        p_hal_data->is_lck_in_progress = true;
 
2506
 
 
2507
        RTPRINT(FINIT, INIT_IQK, ("LCK:Start!!!interface %d currentband %x delay %d ms\n", p_adapter->interface_index, p_hal_data->current_band_type, timecount));
 
2508
 
 
2509
        /* if(IS_92C_SERIAL(p_hal_data->version_id) || IS_92D_SINGLEPHY(p_hal_data->version_id)) */
 
2510
        if (IS_2T2R(p_hal_data->version_id))
 
2511
                phy_lc_calibrate(p_adapter, true);
 
2512
        else {
 
2513
                /* For 88C 1T1R */
 
2514
                phy_lc_calibrate(p_adapter, false);
 
2515
        }
 
2516
 
 
2517
        p_hal_data->is_lck_in_progress = false;
 
2518
 
 
2519
        RTPRINT(FINIT, INIT_IQK, ("LCK:Finish!!!interface %d\n", p_adapter->interface_index));
 
2520
 
 
2521
 
 
2522
}
 
2523
 
 
2524
void
 
2525
phy_ap_calibrate_8192c(
 
2526
        struct _ADAPTER *p_adapter,
 
2527
        s8              delta
 
2528
)
 
2529
{
 
2530
        HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(p_adapter);
 
2531
 
 
2532
        /* default disable APK, because Tx NG issue, suggest by Jenyu, 2011.11.25 */
 
2533
        return;
 
2534
 
 
2535
#ifdef DISABLE_BB_RF
 
2536
        return;
 
2537
#endif
 
2538
 
 
2539
#if FOR_BRAZIL_PRETEST != 1
 
2540
        if (p_hal_data->is_ap_kdone)
 
2541
#endif
 
2542
                return;
 
2543
 
 
2544
        if (IS_92C_SERIAL(p_hal_data->version_id))
 
2545
                _phy_ap_calibrate_8192c(p_adapter, delta, true);
 
2546
        else {
 
2547
                /* For 88C 1T1R */
 
2548
                _phy_ap_calibrate_8192c(p_adapter, delta, false);
 
2549
        }
 
2550
}
 
2551
 
 
2552
 
 
2553
#endif
 
2554
 
 
2555
 
 
2556
/* 3============================================================
 
2557
 * 3 IQ Calibration
 
2558
 * 3============================================================ */
 
2559
 
 
2560
void
 
2561
odm_reset_iqk_result(
 
2562
        void            *p_dm_void
 
2563
)
 
2564
{
 
2565
        return;
 
2566
}
 
2567
#if 1/* !(DM_ODM_SUPPORT_TYPE & ODM_AP) */
 
2568
u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
 
2569
{
 
2570
        u8      channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
 
2571
                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
 
2572
        };
 
2573
        u8      place = chnl;
 
2574
 
 
2575
 
 
2576
        if (chnl > 14) {
 
2577
                for (place = 14; place < sizeof(channel_all); place++) {
 
2578
                        if (channel_all[place] == chnl)
 
2579
                                return place - 13;
 
2580
                }
 
2581
        }
 
2582
        return 0;
 
2583
 
 
2584
}
 
2585
#endif
 
2586
 
 
2587
void
 
2588
odm_iq_calibrate(
 
2589
        struct PHY_DM_STRUCT    *p_dm_odm
 
2590
)
 
2591
{
 
2592
        struct _ADAPTER *adapter = p_dm_odm->adapter;
 
2593
 
 
2594
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
 
2595
        if (*p_dm_odm->p_is_fcs_mode_enable)
 
2596
                return;
 
2597
#endif
 
2598
 
 
2599
 
 
2600
 
 
2601
        if (p_dm_odm->is_linked) {
 
2602
                if ((*p_dm_odm->p_channel != p_dm_odm->pre_channel) && (!*p_dm_odm->p_is_scan_in_process)) {
 
2603
                        p_dm_odm->pre_channel = *p_dm_odm->p_channel;
 
2604
                        p_dm_odm->linked_interval = 0;
 
2605
                }
 
2606
 
 
2607
                if (p_dm_odm->linked_interval < 3)
 
2608
                        p_dm_odm->linked_interval++;
 
2609
 
 
2610
                if (p_dm_odm->linked_interval == 2) {
 
2611
 
 
2612
#if (RTL8814A_SUPPORT == 1)
 
2613
                        if (p_dm_odm->support_ic_type == ODM_RTL8814A)
 
2614
                                phy_iq_calibrate_8814a(p_dm_odm, false);
 
2615
#endif
 
2616
 
 
2617
#if (RTL8822B_SUPPORT == 1)
 
2618
                        if (p_dm_odm->support_ic_type == ODM_RTL8822B)
 
2619
                                phy_iq_calibrate_8822b(p_dm_odm, false);
 
2620
#endif
 
2621
 
 
2622
#if (RTL8821C_SUPPORT == 1)
 
2623
                        if (p_dm_odm->support_ic_type == ODM_RTL8821C)
 
2624
                                phy_iq_calibrate_8821c(p_dm_odm, false);
 
2625
#endif
 
2626
 
 
2627
#if (RTL8821A_SUPPORT == 1)
 
2628
                        if (p_dm_odm->support_ic_type == ODM_RTL8821)
 
2629
                                phy_iq_calibrate_8821a(p_dm_odm, false);
 
2630
#endif
 
2631
 
 
2632
#if (RTL8812A_SUPPORT == 1)
 
2633
                        if (p_dm_odm->support_ic_type == ODM_RTL8812)
 
2634
                                _phy_iq_calibrate_8812a(p_dm_odm, false);
 
2635
#endif
 
2636
                }
 
2637
        } else
 
2638
                p_dm_odm->linked_interval = 0;
 
2639
 
 
2640
}
 
2641
 
 
2642
void phydm_rf_init(void         *p_dm_void)
 
2643
{
 
2644
        struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
 
2645
        odm_txpowertracking_init(p_dm_odm);
 
2646
 
 
2647
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
 
2648
        odm_clear_txpowertracking_state(p_dm_odm);
 
2649
#endif
 
2650
 
 
2651
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
 
2652
#if (RTL8814A_SUPPORT == 1)
 
2653
        if (p_dm_odm->support_ic_type & ODM_RTL8814A)
 
2654
                phy_iq_calibrate_8814a_init(p_dm_odm);
 
2655
#endif
 
2656
#endif
 
2657
 
 
2658
}
 
2659
 
 
2660
void phydm_rf_watchdog(void             *p_dm_void)
 
2661
{
 
2662
        struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
 
2663
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
 
2664
        odm_txpowertracking_check(p_dm_odm);
 
2665
        if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
 
2666
                odm_iq_calibrate(p_dm_odm);
 
2667
#endif
 
2668
}