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 #define _RTL8188E_PHYCFG_C_
21
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <rtw_iol.h>
25 #include <rtl8188e_hal.h>
26 #include <rf.h>
27 #include <phy.h>
28
29 #define MAX_PRECMD_CNT 16
30 #define MAX_RFDEPENDCMD_CNT 16
31 #define MAX_POSTCMD_CNT 16
32
33 #define MAX_DOZE_WAITING_TIMES_9x 64
34
cal_bit_shift(u32 bitmask)35 static u32 cal_bit_shift(u32 bitmask)
36 {
37 u32 i;
38
39 for (i = 0; i <= 31; i++) {
40 if (((bitmask >> i) & 0x1) == 1)
41 break;
42 }
43 return i;
44 }
45
phy_query_bb_reg(struct adapter * adapt,u32 regaddr,u32 bitmask)46 u32 phy_query_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask)
47 {
48 u32 return_value = 0, original_value, bit_shift;
49
50 original_value = usb_read32(adapt, regaddr);
51 bit_shift = cal_bit_shift(bitmask);
52 return_value = (original_value & bitmask) >> bit_shift;
53 return return_value;
54 }
55
phy_set_bb_reg(struct adapter * adapt,u32 regaddr,u32 bitmask,u32 data)56 void phy_set_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask, u32 data)
57 {
58 u32 original_value, bit_shift;
59
60 if (bitmask != bMaskDWord) { /* if not "double word" write */
61 original_value = usb_read32(adapt, regaddr);
62 bit_shift = cal_bit_shift(bitmask);
63 data = ((original_value & (~bitmask)) | (data << bit_shift));
64 }
65
66 usb_write32(adapt, regaddr, data);
67 }
68
rf_serial_read(struct adapter * adapt,enum rf_radio_path rfpath,u32 offset)69 static u32 rf_serial_read(struct adapter *adapt,
70 enum rf_radio_path rfpath, u32 offset)
71 {
72 u32 ret = 0;
73 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
74 struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath];
75 u32 newoffset;
76 u32 tmplong, tmplong2;
77 u8 rfpi_enable = 0;
78
79 offset &= 0xff;
80 newoffset = offset;
81
82 tmplong = phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord);
83 if (rfpath == RF_PATH_A)
84 tmplong2 = tmplong;
85 else
86 tmplong2 = phy_query_bb_reg(adapt, phyreg->rfHSSIPara2,
87 bMaskDWord);
88
89 tmplong2 = (tmplong2 & (~bLSSIReadAddress)) |
90 (newoffset<<23) | bLSSIReadEdge;
91
92 phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord,
93 tmplong&(~bLSSIReadEdge));
94 udelay(10);
95
96 phy_set_bb_reg(adapt, phyreg->rfHSSIPara2, bMaskDWord, tmplong2);
97 udelay(100);
98
99 udelay(10);
100
101 if (rfpath == RF_PATH_A)
102 rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, BIT8);
103 else if (rfpath == RF_PATH_B)
104 rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, BIT8);
105
106 if (rfpi_enable)
107 ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBackPi,
108 bLSSIReadBackData);
109 else
110 ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBack,
111 bLSSIReadBackData);
112 return ret;
113 }
114
rf_serial_write(struct adapter * adapt,enum rf_radio_path rfpath,u32 offset,u32 data)115 static void rf_serial_write(struct adapter *adapt,
116 enum rf_radio_path rfpath, u32 offset,
117 u32 data)
118 {
119 u32 data_and_addr = 0;
120 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
121 struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath];
122 u32 newoffset;
123
124 newoffset = offset & 0xff;
125 data_and_addr = ((newoffset<<20) | (data&0x000fffff)) & 0x0fffffff;
126 phy_set_bb_reg(adapt, phyreg->rf3wireOffset, bMaskDWord, data_and_addr);
127 }
128
phy_query_rf_reg(struct adapter * adapt,enum rf_radio_path rf_path,u32 reg_addr,u32 bit_mask)129 u32 phy_query_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
130 u32 reg_addr, u32 bit_mask)
131 {
132 u32 original_value, readback_value, bit_shift;
133
134 original_value = rf_serial_read(adapt, rf_path, reg_addr);
135 bit_shift = cal_bit_shift(bit_mask);
136 readback_value = (original_value & bit_mask) >> bit_shift;
137 return readback_value;
138 }
139
phy_set_rf_reg(struct adapter * adapt,enum rf_radio_path rf_path,u32 reg_addr,u32 bit_mask,u32 data)140 void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
141 u32 reg_addr, u32 bit_mask, u32 data)
142 {
143 u32 original_value, bit_shift;
144
145 /* RF data is 12 bits only */
146 if (bit_mask != bRFRegOffsetMask) {
147 original_value = rf_serial_read(adapt, rf_path, reg_addr);
148 bit_shift = cal_bit_shift(bit_mask);
149 data = ((original_value & (~bit_mask)) | (data << bit_shift));
150 }
151
152 rf_serial_write(adapt, rf_path, reg_addr, data);
153 }
154
get_tx_power_index(struct adapter * adapt,u8 channel,u8 * cck_pwr,u8 * ofdm_pwr,u8 * bw20_pwr,u8 * bw40_pwr)155 static void get_tx_power_index(struct adapter *adapt, u8 channel, u8 *cck_pwr,
156 u8 *ofdm_pwr, u8 *bw20_pwr, u8 *bw40_pwr)
157 {
158 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
159 u8 index = (channel - 1);
160 u8 TxCount = 0, path_nums;
161
162 if ((RF_1T2R == hal_data->rf_type) || (RF_1T1R == hal_data->rf_type))
163 path_nums = 1;
164 else
165 path_nums = 2;
166
167 for (TxCount = 0; TxCount < path_nums; TxCount++) {
168 if (TxCount == RF_PATH_A) {
169 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
170 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
171 hal_data->OFDM_24G_Diff[TxCount][RF_PATH_A];
172
173 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
174 hal_data->BW20_24G_Diff[TxCount][RF_PATH_A];
175 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
176 } else if (TxCount == RF_PATH_B) {
177 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
178 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
179 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
180 hal_data->BW20_24G_Diff[TxCount][index];
181
182 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
183 hal_data->BW20_24G_Diff[TxCount][RF_PATH_A]+
184 hal_data->BW20_24G_Diff[TxCount][index];
185 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
186 } else if (TxCount == RF_PATH_C) {
187 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
188 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
189 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
190 hal_data->BW20_24G_Diff[RF_PATH_B][index]+
191 hal_data->BW20_24G_Diff[TxCount][index];
192
193 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
194 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
195 hal_data->BW20_24G_Diff[RF_PATH_B][index]+
196 hal_data->BW20_24G_Diff[TxCount][index];
197 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
198 } else if (TxCount == RF_PATH_D) {
199 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
200 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
201 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
202 hal_data->BW20_24G_Diff[RF_PATH_B][index]+
203 hal_data->BW20_24G_Diff[RF_PATH_C][index]+
204 hal_data->BW20_24G_Diff[TxCount][index];
205
206 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
207 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
208 hal_data->BW20_24G_Diff[RF_PATH_B][index]+
209 hal_data->BW20_24G_Diff[RF_PATH_C][index]+
210 hal_data->BW20_24G_Diff[TxCount][index];
211 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
212 }
213 }
214 }
215
phy_power_index_check(struct adapter * adapt,u8 channel,u8 * cck_pwr,u8 * ofdm_pwr,u8 * bw20_pwr,u8 * bw40_pwr)216 static void phy_power_index_check(struct adapter *adapt, u8 channel,
217 u8 *cck_pwr, u8 *ofdm_pwr, u8 *bw20_pwr,
218 u8 *bw40_pwr)
219 {
220 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
221
222 hal_data->CurrentCckTxPwrIdx = cck_pwr[0];
223 hal_data->CurrentOfdm24GTxPwrIdx = ofdm_pwr[0];
224 hal_data->CurrentBW2024GTxPwrIdx = bw20_pwr[0];
225 hal_data->CurrentBW4024GTxPwrIdx = bw40_pwr[0];
226 }
227
phy_set_tx_power_level(struct adapter * adapt,u8 channel)228 void phy_set_tx_power_level(struct adapter *adapt, u8 channel)
229 {
230 u8 cck_pwr[MAX_TX_COUNT] = {0};
231 u8 ofdm_pwr[MAX_TX_COUNT] = {0};/* [0]:RF-A, [1]:RF-B */
232 u8 bw20_pwr[MAX_TX_COUNT] = {0};
233 u8 bw40_pwr[MAX_TX_COUNT] = {0};
234
235 get_tx_power_index(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
236 &bw20_pwr[0], &bw40_pwr[0]);
237
238 phy_power_index_check(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
239 &bw20_pwr[0], &bw40_pwr[0]);
240
241 rtl88eu_phy_rf6052_set_cck_txpower(adapt, &cck_pwr[0]);
242 rtl88eu_phy_rf6052_set_ofdm_txpower(adapt, &ofdm_pwr[0], &bw20_pwr[0],
243 &bw40_pwr[0], channel);
244 }
245
phy_set_bw_mode_callback(struct adapter * adapt)246 static void phy_set_bw_mode_callback(struct adapter *adapt)
247 {
248 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
249 u8 reg_bw_opmode;
250 u8 reg_prsr_rsc;
251
252 if (hal_data->rf_chip == RF_PSEUDO_11N)
253 return;
254
255 /* There is no 40MHz mode in RF_8225. */
256 if (hal_data->rf_chip == RF_8225)
257 return;
258
259 if (adapt->bDriverStopped)
260 return;
261
262 /* Set MAC register */
263
264 reg_bw_opmode = usb_read8(adapt, REG_BWOPMODE);
265 reg_prsr_rsc = usb_read8(adapt, REG_RRSR+2);
266
267 switch (hal_data->CurrentChannelBW) {
268 case HT_CHANNEL_WIDTH_20:
269 reg_bw_opmode |= BW_OPMODE_20MHZ;
270 usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode);
271 break;
272 case HT_CHANNEL_WIDTH_40:
273 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
274 usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode);
275 reg_prsr_rsc = (reg_prsr_rsc&0x90) |
276 (hal_data->nCur40MhzPrimeSC<<5);
277 usb_write8(adapt, REG_RRSR+2, reg_prsr_rsc);
278 break;
279 default:
280 break;
281 }
282
283 /* Set PHY related register */
284 switch (hal_data->CurrentChannelBW) {
285 case HT_CHANNEL_WIDTH_20:
286 phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x0);
287 phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x0);
288 break;
289 case HT_CHANNEL_WIDTH_40:
290 phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x1);
291 phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x1);
292 /* Set Control channel to upper or lower.
293 * These settings are required only for 40MHz
294 */
295 phy_set_bb_reg(adapt, rCCK0_System, bCCKSideBand,
296 (hal_data->nCur40MhzPrimeSC>>1));
297 phy_set_bb_reg(adapt, rOFDM1_LSTF, 0xC00,
298 hal_data->nCur40MhzPrimeSC);
299 phy_set_bb_reg(adapt, 0x818, (BIT26 | BIT27),
300 (hal_data->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
301 break;
302 default:
303 break;
304 }
305
306 /* Set RF related register */
307 switch (hal_data->rf_chip) {
308 case RF_8225:
309 break;
310 case RF_8256:
311 break;
312 case RF_8258:
313 break;
314 case RF_PSEUDO_11N:
315 break;
316 case RF_6052:
317 rtl88eu_phy_rf6052_set_bandwidth(adapt, hal_data->CurrentChannelBW);
318 break;
319 default:
320 break;
321 }
322 }
323
phy_set_bw_mode(struct adapter * adapt,enum ht_channel_width bandwidth,unsigned char offset)324 void phy_set_bw_mode(struct adapter *adapt, enum ht_channel_width bandwidth,
325 unsigned char offset)
326 {
327 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
328 enum ht_channel_width tmp_bw = hal_data->CurrentChannelBW;
329
330 hal_data->CurrentChannelBW = bandwidth;
331 hal_data->nCur40MhzPrimeSC = offset;
332
333 if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
334 phy_set_bw_mode_callback(adapt);
335 else
336 hal_data->CurrentChannelBW = tmp_bw;
337 }
338
phy_sw_chnl_callback(struct adapter * adapt,u8 channel)339 static void phy_sw_chnl_callback(struct adapter *adapt, u8 channel)
340 {
341 u8 rf_path;
342 u32 param1, param2;
343 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
344
345 if (adapt->bNotifyChannelChange)
346 DBG_88E("[%s] ch = %d\n", __func__, channel);
347
348 phy_set_tx_power_level(adapt, channel);
349
350 param1 = RF_CHNLBW;
351 param2 = channel;
352 for (rf_path = 0; rf_path < hal_data->NumTotalRFPath; rf_path++) {
353 hal_data->RfRegChnlVal[rf_path] = (hal_data->RfRegChnlVal[rf_path] &
354 0xfffffc00) | param2;
355 phy_set_rf_reg(adapt, (enum rf_radio_path)rf_path, param1,
356 bRFRegOffsetMask, hal_data->RfRegChnlVal[rf_path]);
357 }
358 }
359
phy_sw_chnl(struct adapter * adapt,u8 channel)360 void phy_sw_chnl(struct adapter *adapt, u8 channel)
361 {
362 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
363 u8 tmpchannel = hal_data->CurrentChannel;
364 bool result = true;
365
366 if (hal_data->rf_chip == RF_PSEUDO_11N)
367 return;
368
369 if (channel == 0)
370 channel = 1;
371
372 hal_data->CurrentChannel = channel;
373
374 if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved)) {
375 phy_sw_chnl_callback(adapt, channel);
376
377 if (!result)
378 hal_data->CurrentChannel = tmpchannel;
379
380 } else {
381 hal_data->CurrentChannel = tmpchannel;
382 }
383 }
384
385 #define ODM_TXPWRTRACK_MAX_IDX_88E 6
386
get_right_chnl_for_iqk(u8 chnl)387 static u8 get_right_chnl_for_iqk(u8 chnl)
388 {
389 u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
390 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
391 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
392 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
393 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153,
394 155, 157, 159, 161, 163, 165
395 };
396 u8 place = chnl;
397
398 if (chnl > 14) {
399 for (place = 14; place < sizeof(channel_all); place++) {
400 if (channel_all[place] == chnl)
401 return place-13;
402 }
403 }
404 return 0;
405 }
406
rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct * dm_odm,u8 type,u8 * direction,u32 * out_write_val)407 void rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct *dm_odm, u8 type,
408 u8 *direction, u32 *out_write_val)
409 {
410 u8 pwr_value = 0;
411 /* Tx power tracking BB swing table. */
412 if (type == 0) { /* For OFDM adjust */
413 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
414 ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n",
415 dm_odm->BbSwingIdxOfdm, dm_odm->BbSwingFlagOfdm));
416
417 if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
418 *direction = 1;
419 pwr_value = (dm_odm->BbSwingIdxOfdmBase -
420 dm_odm->BbSwingIdxOfdm);
421 } else {
422 *direction = 2;
423 pwr_value = (dm_odm->BbSwingIdxOfdm -
424 dm_odm->BbSwingIdxOfdmBase);
425 }
426
427 } else if (type == 1) { /* For CCK adjust. */
428 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
429 ("dm_odm->BbSwingIdxCck = %d dm_odm->BbSwingIdxCckBase = %d\n",
430 dm_odm->BbSwingIdxCck, dm_odm->BbSwingIdxCckBase));
431
432 if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
433 *direction = 1;
434 pwr_value = (dm_odm->BbSwingIdxCckBase -
435 dm_odm->BbSwingIdxCck);
436 } else {
437 *direction = 2;
438 pwr_value = (dm_odm->BbSwingIdxCck -
439 dm_odm->BbSwingIdxCckBase);
440 }
441
442 }
443
444 if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *direction == 1)
445 pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
446
447 *out_write_val = pwr_value | (pwr_value<<8) | (pwr_value<<16) |
448 (pwr_value<<24);
449 }
450
dm_txpwr_track_setpwr(struct odm_dm_struct * dm_odm)451 static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm)
452 {
453 if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
454 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
455 ("dm_txpwr_track_setpwr CH=%d\n", *(dm_odm->pChannel)));
456 phy_set_tx_power_level(dm_odm->Adapter, *(dm_odm->pChannel));
457 dm_odm->BbSwingFlagOfdm = false;
458 dm_odm->BbSwingFlagCck = false;
459 }
460 }
461
rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter * adapt)462 void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt)
463 {
464 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
465 u8 thermal_val = 0, delta, delta_lck, delta_iqk, offset;
466 u8 thermal_avg_count = 0;
467 u32 thermal_avg = 0;
468 s32 ele_a = 0, ele_d, temp_cck, x, value32;
469 s32 y, ele_c = 0;
470 s8 ofdm_index[2], cck_index = 0;
471 s8 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
472 u32 i = 0, j = 0;
473 bool is2t = false;
474
475 u8 ofdm_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB */
476 u8 indexforchannel = 0;
477 s8 ofdm_index_mapping[2][index_mapping_NUM_88E] = {
478 /* 2.4G, decrease power */
479 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
480 /* 2.4G, increase power */
481 {0, 0, -1, -2, -3, -4,-4, -4, -4, -5, -7, -8,-9, -9, -10},
482 };
483 u8 thermal_mapping[2][index_mapping_NUM_88E] = {
484 /* 2.4G, decrease power */
485 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
486 /* 2.4G, increase power */
487 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25},
488 };
489 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
490
491 dm_txpwr_track_setpwr(dm_odm);
492
493 dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++;
494 dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
495
496 dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
497
498 thermal_val = (u8)phy_query_rf_reg(adapt, RF_PATH_A,
499 RF_T_METER_88E, 0xfc00);
500
501 if (is2t)
502 rf = 2;
503 else
504 rf = 1;
505
506 if (thermal_val) {
507 /* Query OFDM path A default setting */
508 ele_d = phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord)&bMaskOFDM_D;
509 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
510 if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) {
511 ofdm_index_old[0] = (u8)i;
512 dm_odm->BbSwingIdxOfdmBase = (u8)i;
513 break;
514 }
515 }
516
517 /* Query OFDM path B default setting */
518 if (is2t) {
519 ele_d = phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord)&bMaskOFDM_D;
520 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
521 if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) {
522 ofdm_index_old[1] = (u8)i;
523 break;
524 }
525 }
526 }
527
528 /* Query CCK default setting From 0xa24 */
529 temp_cck = dm_odm->RFCalibrateInfo.RegA24;
530
531 for (i = 0; i < CCK_TABLE_SIZE; i++) {
532 if (dm_odm->RFCalibrateInfo.bCCKinCH14) {
533 if (memcmp(&temp_cck, &CCKSwingTable_Ch14[i][2], 4)) {
534 cck_index_old = (u8)i;
535 dm_odm->BbSwingIdxCckBase = (u8)i;
536 break;
537 }
538 } else {
539 if (memcmp(&temp_cck, &CCKSwingTable_Ch1_Ch13[i][2], 4)) {
540 cck_index_old = (u8)i;
541 dm_odm->BbSwingIdxCckBase = (u8)i;
542 break;
543 }
544 }
545 }
546
547 if (!dm_odm->RFCalibrateInfo.ThermalValue) {
548 dm_odm->RFCalibrateInfo.ThermalValue = hal_data->EEPROMThermalMeter;
549 dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val;
550 dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val;
551
552 for (i = 0; i < rf; i++)
553 dm_odm->RFCalibrateInfo.OFDM_index[i] = ofdm_index_old[i];
554 dm_odm->RFCalibrateInfo.CCK_index = cck_index_old;
555 }
556
557 /* calculate average thermal meter */
558 dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = thermal_val;
559 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++;
560 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
561 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
562
563 for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
564 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
565 thermal_avg += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i];
566 thermal_avg_count++;
567 }
568 }
569
570 if (thermal_avg_count)
571 thermal_val = (u8)(thermal_avg / thermal_avg_count);
572
573 if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) {
574 delta = thermal_val > hal_data->EEPROMThermalMeter ?
575 (thermal_val - hal_data->EEPROMThermalMeter) :
576 (hal_data->EEPROMThermalMeter - thermal_val);
577 dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false;
578 dm_odm->RFCalibrateInfo.bDoneTxpower = false;
579 } else if (dm_odm->RFCalibrateInfo.bDoneTxpower) {
580 delta = (thermal_val > dm_odm->RFCalibrateInfo.ThermalValue) ?
581 (thermal_val - dm_odm->RFCalibrateInfo.ThermalValue) :
582 (dm_odm->RFCalibrateInfo.ThermalValue - thermal_val);
583 } else {
584 delta = thermal_val > hal_data->EEPROMThermalMeter ?
585 (thermal_val - hal_data->EEPROMThermalMeter) :
586 (hal_data->EEPROMThermalMeter - thermal_val);
587 }
588 delta_lck = (thermal_val > dm_odm->RFCalibrateInfo.ThermalValue_LCK) ?
589 (thermal_val - dm_odm->RFCalibrateInfo.ThermalValue_LCK) :
590 (dm_odm->RFCalibrateInfo.ThermalValue_LCK - thermal_val);
591 delta_iqk = (thermal_val > dm_odm->RFCalibrateInfo.ThermalValue_IQK) ?
592 (thermal_val - dm_odm->RFCalibrateInfo.ThermalValue_IQK) :
593 (dm_odm->RFCalibrateInfo.ThermalValue_IQK - thermal_val);
594
595 /* Delta temperature is equal to or larger than 20 centigrade.*/
596 if ((delta_lck >= 8)) {
597 dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val;
598 rtl88eu_phy_lc_calibrate(adapt);
599 }
600
601 if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
602 delta = thermal_val > hal_data->EEPROMThermalMeter ?
603 (thermal_val - hal_data->EEPROMThermalMeter) :
604 (hal_data->EEPROMThermalMeter - thermal_val);
605 /* calculate new OFDM / CCK offset */
606 if (thermal_val > hal_data->EEPROMThermalMeter)
607 j = 1;
608 else
609 j = 0;
610 for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
611 if (delta < thermal_mapping[j][offset]) {
612 if (offset != 0)
613 offset--;
614 break;
615 }
616 }
617 if (offset >= index_mapping_NUM_88E)
618 offset = index_mapping_NUM_88E-1;
619 for (i = 0; i < rf; i++)
620 ofdm_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + ofdm_index_mapping[j][offset];
621 cck_index = dm_odm->RFCalibrateInfo.CCK_index + ofdm_index_mapping[j][offset];
622
623 for (i = 0; i < rf; i++) {
624 if (ofdm_index[i] > OFDM_TABLE_SIZE_92D-1)
625 ofdm_index[i] = OFDM_TABLE_SIZE_92D-1;
626 else if (ofdm_index[i] < ofdm_min_index)
627 ofdm_index[i] = ofdm_min_index;
628 }
629
630 if (cck_index > CCK_TABLE_SIZE-1)
631 cck_index = CCK_TABLE_SIZE-1;
632 else if (cck_index < 0)
633 cck_index = 0;
634
635 /* 2 temporarily remove bNOPG */
636 /* Config by SwingTable */
637 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
638 dm_odm->RFCalibrateInfo.bDoneTxpower = true;
639
640 /* Adujst OFDM Ant_A according to IQK result */
641 ele_d = (OFDMSwingTable[(u8)ofdm_index[0]] & 0xFFC00000)>>22;
642 x = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[indexforchannel].Value[0][0];
643 y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[indexforchannel].Value[0][1];
644
645 /* Revse TX power table. */
646 dm_odm->BbSwingIdxOfdm = (u8)ofdm_index[0];
647 dm_odm->BbSwingIdxCck = (u8)cck_index;
648
649 if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
650 dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
651 dm_odm->BbSwingFlagOfdm = true;
652 }
653
654 if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
655 dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
656 dm_odm->BbSwingFlagCck = true;
657 }
658
659 if (x != 0) {
660 if ((x & 0x00000200) != 0)
661 x = x | 0xFFFFFC00;
662 ele_a = ((x * ele_d)>>8)&0x000003FF;
663
664 /* new element C = element D x Y */
665 if ((y & 0x00000200) != 0)
666 y = y | 0xFFFFFC00;
667 ele_c = ((y * ele_d)>>8)&0x000003FF;
668
669 }
670
671 if (is2t) {
672 ele_d = (OFDMSwingTable[(u8)ofdm_index[1]] & 0xFFC00000)>>22;
673
674 /* new element A = element D x X */
675 x = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[indexforchannel].Value[0][4];
676 y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[indexforchannel].Value[0][5];
677
678 if ((x != 0) && (*(dm_odm->pBandType) == ODM_BAND_2_4G)) {
679 if ((x & 0x00000200) != 0) /* consider minus */
680 x = x | 0xFFFFFC00;
681 ele_a = ((x * ele_d)>>8)&0x000003FF;
682
683 /* new element C = element D x Y */
684 if ((y & 0x00000200) != 0)
685 y = y | 0xFFFFFC00;
686 ele_c = ((y * ele_d)>>8)&0x00003FF;
687
688 /* wtite new elements A, C, D to regC88 and regC9C, element B is always 0 */
689 value32 = (ele_d<<22) | ((ele_c&0x3F)<<16) | ele_a;
690 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
691
692 value32 = (ele_c&0x000003C0)>>6;
693 phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
694
695 value32 = ((x * ele_d)>>7)&0x01;
696 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT28, value32);
697 } else {
698 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable[(u8)ofdm_index[1]]);
699 phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
700 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT28, 0x00);
701 }
702
703 }
704
705 }
706 }
707
708 /* Delta temperature is equal to or larger than 20 centigrade.*/
709 if (delta_iqk >= 8) {
710 dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val;
711 rtl88eu_phy_iq_calibrate(adapt, false);
712 }
713 /* update thermal meter value */
714 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
715 dm_odm->RFCalibrateInfo.ThermalValue = thermal_val;
716 }
717 dm_odm->RFCalibrateInfo.TXPowercount = 0;
718 }
719
720 #define MAX_TOLERANCE 5
721
phy_path_a_iqk(struct adapter * adapt,bool config_pathb)722 static u8 phy_path_a_iqk(struct adapter *adapt, bool config_pathb)
723 {
724 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
725 u8 result = 0x00;
726
727 /* 1 Tx IQK */
728 /* path-A IQK setting */
729 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
730 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
731 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x8214032a);
732 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
733
734 /* LO calibration setting */
735 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
736
737 /* One shot, path A LOK & IQK */
738 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
739 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
740
741 mdelay(IQK_DELAY_TIME_88E);
742
743 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
744 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
745 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
746 reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
747
748 if (!(reg_eac & BIT28) &&
749 (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
750 (((reg_e9c & 0x03FF0000)>>16) != 0x42))
751 result |= 0x01;
752 return result;
753 }
754
phy_path_a_rx_iqk(struct adapter * adapt,bool configPathB)755 static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB)
756 {
757 u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
758 u8 result = 0x00;
759 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
760 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
761
762 /* 1 Get TXIMR setting */
763 /* modify RXIQK mode table */
764 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
765 phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
766 phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
767 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
768 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
769
770 /* PA,PAD off */
771 phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
772 phy_set_rf_reg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
773
774 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
775
776 /* IQK setting */
777 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
778 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
779
780 /* path-A IQK setting */
781 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
782 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
783 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
784 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
785
786 /* LO calibration setting */
787 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
788
789 /* One shot, path A LOK & IQK */
790 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
791 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
792
793 /* delay x ms */
794 mdelay(IQK_DELAY_TIME_88E);
795
796 /* Check failed */
797 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
798 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
799 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
800
801 if (!(reg_eac & BIT28) &&
802 (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
803 (((reg_e9c & 0x03FF0000)>>16) != 0x42))
804 result |= 0x01;
805 else /* if Tx not OK, ignore Rx */
806 return result;
807
808 u4tmp = 0x80007C00 | (reg_e94&0x3FF0000) | ((reg_e9c&0x3FF0000) >> 16);
809 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, u4tmp);
810
811 /* 1 RX IQK */
812 /* modify RXIQK mode table */
813 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
814 ("Path-A Rx IQK modify RXIQK mode table 2!\n"));
815 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
816 phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
817 phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
818 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
819 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
820 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
821
822 /* IQK setting */
823 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
824
825 /* path-A IQK setting */
826 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
827 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
828 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
829 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
830
831 /* LO calibration setting */
832 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
833
834 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
835 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
836
837 mdelay(IQK_DELAY_TIME_88E);
838
839 /* Check failed */
840 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
841 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
842 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
843 reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
844
845 /* reload RF 0xdf */
846 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
847 phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
848
849 if (!(reg_eac & BIT27) && /* if Tx is OK, check whether Rx is OK */
850 (((reg_ea4 & 0x03FF0000)>>16) != 0x132) &&
851 (((reg_eac & 0x03FF0000)>>16) != 0x36))
852 result |= 0x02;
853 else
854 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
855 ("Path A Rx IQK fail!!\n"));
856
857 return result;
858 }
859
phy_path_b_iqk(struct adapter * adapt)860 static u8 phy_path_b_iqk(struct adapter *adapt)
861 {
862 u32 regeac, regeb4, regebc, regec4, regecc;
863 u8 result = 0x00;
864 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
865 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
866
867 /* One shot, path B LOK & IQK */
868 phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
869 phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000000);
870
871 mdelay(IQK_DELAY_TIME_88E);
872
873 regeac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
874 regeb4 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, bMaskDWord);
875 regebc = phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, bMaskDWord);
876 regec4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2, bMaskDWord);
877 regecc = phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2, bMaskDWord);
878
879 if (!(regeac & BIT31) &&
880 (((regeb4 & 0x03FF0000)>>16) != 0x142) &&
881 (((regebc & 0x03FF0000)>>16) != 0x42))
882 result |= 0x01;
883 else
884 return result;
885
886 if (!(regeac & BIT30) &&
887 (((regec4 & 0x03FF0000)>>16) != 0x132) &&
888 (((regecc & 0x03FF0000)>>16) != 0x36))
889 result |= 0x02;
890 else
891 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION,
892 ODM_DBG_LOUD, ("Path B Rx IQK fail!!\n"));
893 return result;
894 }
895
patha_fill_iqk(struct adapter * adapt,bool iqkok,s32 result[][8],u8 final_candidate,bool txonly)896 static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
897 u8 final_candidate, bool txonly)
898 {
899 u32 oldval_0, x, tx0_a, reg;
900 s32 y, tx0_c;
901
902 if (final_candidate == 0xFF) {
903 return;
904 } else if (iqkok) {
905 oldval_0 = (phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
906
907 x = result[final_candidate][0];
908 if ((x & 0x00000200) != 0)
909 x = x | 0xFFFFFC00;
910
911 tx0_a = (x * oldval_0) >> 8;
912 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, tx0_a);
913 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(31),
914 ((x * oldval_0>>7) & 0x1));
915
916 y = result[final_candidate][1];
917 if ((y & 0x00000200) != 0)
918 y = y | 0xFFFFFC00;
919
920 tx0_c = (y * oldval_0) >> 8;
921 phy_set_bb_reg(adapt, rOFDM0_XCTxAFE, 0xF0000000,
922 ((tx0_c&0x3C0)>>6));
923 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000,
924 (tx0_c&0x3F));
925 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(29),
926 ((y * oldval_0>>7) & 0x1));
927
928 if (txonly)
929 return;
930
931 reg = result[final_candidate][2];
932 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
933
934 reg = result[final_candidate][3] & 0x3F;
935 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
936
937 reg = (result[final_candidate][3] >> 6) & 0xF;
938 phy_set_bb_reg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
939 }
940 }
941
pathb_fill_iqk(struct adapter * adapt,bool iqkok,s32 result[][8],u8 final_candidate,bool txonly)942 static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
943 u8 final_candidate, bool txonly)
944 {
945 u32 oldval_1, x, tx1_a, reg;
946 s32 y, tx1_c;
947
948 if (final_candidate == 0xFF) {
949 return;
950 } else if (iqkok) {
951 oldval_1 = (phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
952
953 x = result[final_candidate][4];
954 if ((x & 0x00000200) != 0)
955 x = x | 0xFFFFFC00;
956 tx1_a = (x * oldval_1) >> 8;
957 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x3FF, tx1_a);
958
959 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(27),
960 ((x * oldval_1>>7) & 0x1));
961
962 y = result[final_candidate][5];
963 if ((y & 0x00000200) != 0)
964 y = y | 0xFFFFFC00;
965
966 tx1_c = (y * oldval_1) >> 8;
967
968 phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, 0xF0000000,
969 ((tx1_c&0x3C0)>>6));
970 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x003F0000,
971 (tx1_c&0x3F));
972 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(25),
973 ((y * oldval_1>>7) & 0x1));
974
975 if (txonly)
976 return;
977
978 reg = result[final_candidate][6];
979 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
980
981 reg = result[final_candidate][7] & 0x3F;
982 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
983
984 reg = (result[final_candidate][7] >> 6) & 0xF;
985 phy_set_bb_reg(adapt, rOFDM0_AGCRSSITable, 0x0000F000, reg);
986 }
987 }
988
save_adda_registers(struct adapter * adapt,u32 * addareg,u32 * backup,u32 register_num)989 static void save_adda_registers(struct adapter *adapt, u32 *addareg,
990 u32 *backup, u32 register_num)
991 {
992 u32 i;
993
994 for (i = 0; i < register_num; i++) {
995 backup[i] = phy_query_bb_reg(adapt, addareg[i], bMaskDWord);
996 }
997 }
998
save_mac_registers(struct adapter * adapt,u32 * mac_reg,u32 * backup)999 static void save_mac_registers(struct adapter *adapt, u32 *mac_reg,
1000 u32 *backup)
1001 {
1002 u32 i;
1003
1004 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
1005 backup[i] = usb_read8(adapt, mac_reg[i]);
1006 }
1007 backup[i] = usb_read32(adapt, mac_reg[i]);
1008 }
1009
reload_adda_reg(struct adapter * adapt,u32 * adda_reg,u32 * backup,u32 regiester_num)1010 static void reload_adda_reg(struct adapter *adapt, u32 *adda_reg,
1011 u32 *backup, u32 regiester_num)
1012 {
1013 u32 i;
1014
1015 for (i = 0; i < regiester_num; i++)
1016 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, backup[i]);
1017 }
1018
reload_mac_registers(struct adapter * adapt,u32 * mac_reg,u32 * backup)1019 static void reload_mac_registers(struct adapter *adapt,
1020 u32 *mac_reg, u32 *backup)
1021 {
1022 u32 i;
1023
1024 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
1025 usb_write8(adapt, mac_reg[i], (u8)backup[i]);
1026 }
1027 usb_write32(adapt, mac_reg[i], backup[i]);
1028 }
1029
path_adda_on(struct adapter * adapt,u32 * adda_reg,bool is_path_a_on,bool is2t)1030 static void path_adda_on(struct adapter *adapt, u32 *adda_reg,
1031 bool is_path_a_on, bool is2t)
1032 {
1033 u32 path_on;
1034 u32 i;
1035
1036 path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4;
1037 if (!is2t) {
1038 path_on = 0x0bdb25a0;
1039 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, 0x0b1b25a0);
1040 } else {
1041 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, path_on);
1042 }
1043
1044 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1045 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, path_on);
1046 }
1047
mac_setting_calibration(struct adapter * adapt,u32 * mac_reg,u32 * backup)1048 static void mac_setting_calibration(struct adapter *adapt, u32 *mac_reg, u32 *backup)
1049 {
1050 u32 i = 0;
1051
1052 usb_write8(adapt, mac_reg[i], 0x3F);
1053
1054 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
1055 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT3)));
1056 }
1057 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT5)));
1058 }
1059
path_a_standby(struct adapter * adapt)1060 static void path_a_standby(struct adapter *adapt)
1061 {
1062
1063 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x0);
1064 phy_set_bb_reg(adapt, 0x840, bMaskDWord, 0x00010000);
1065 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
1066 }
1067
pi_mode_switch(struct adapter * adapt,bool pi_mode)1068 static void pi_mode_switch(struct adapter *adapt, bool pi_mode)
1069 {
1070 u32 mode;
1071
1072 mode = pi_mode ? 0x01000100 : 0x01000000;
1073 phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
1074 phy_set_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
1075 }
1076
simularity_compare(struct adapter * adapt,s32 resulta[][8],u8 c1,u8 c2)1077 static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
1078 u8 c1, u8 c2)
1079 {
1080 u32 i, j, diff, sim_bitmap, bound = 0;
1081 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1082 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1083 u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
1084 bool result = true;
1085 bool is2t;
1086 s32 tmp1 = 0, tmp2 = 0;
1087
1088 if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) ||
1089 (dm_odm->RFType == ODM_2T4R))
1090 is2t = true;
1091 else
1092 is2t = false;
1093
1094 if (is2t)
1095 bound = 8;
1096 else
1097 bound = 4;
1098
1099 sim_bitmap = 0;
1100
1101 for (i = 0; i < bound; i++) {
1102 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1103 if ((resulta[c1][i] & 0x00000200) != 0)
1104 tmp1 = resulta[c1][i] | 0xFFFFFC00;
1105 else
1106 tmp1 = resulta[c1][i];
1107
1108 if ((resulta[c2][i] & 0x00000200) != 0)
1109 tmp2 = resulta[c2][i] | 0xFFFFFC00;
1110 else
1111 tmp2 = resulta[c2][i];
1112 } else {
1113 tmp1 = resulta[c1][i];
1114 tmp2 = resulta[c2][i];
1115 }
1116
1117 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
1118
1119 if (diff > MAX_TOLERANCE) {
1120 if ((i == 2 || i == 6) && !sim_bitmap) {
1121 if (resulta[c1][i] + resulta[c1][i+1] == 0)
1122 final_candidate[(i/4)] = c2;
1123 else if (resulta[c2][i] + resulta[c2][i+1] == 0)
1124 final_candidate[(i/4)] = c1;
1125 else
1126 sim_bitmap = sim_bitmap | (1<<i);
1127 } else {
1128 sim_bitmap = sim_bitmap | (1<<i);
1129 }
1130 }
1131 }
1132
1133 if (sim_bitmap == 0) {
1134 for (i = 0; i < (bound/4); i++) {
1135 if (final_candidate[i] != 0xFF) {
1136 for (j = i*4; j < (i+1)*4-2; j++)
1137 resulta[3][j] = resulta[final_candidate[i]][j];
1138 result = false;
1139 }
1140 }
1141 return result;
1142 } else {
1143 if (!(sim_bitmap & 0x03)) { /* path A TX OK */
1144 for (i = 0; i < 2; i++)
1145 resulta[3][i] = resulta[c1][i];
1146 }
1147 if (!(sim_bitmap & 0x0c)) { /* path A RX OK */
1148 for (i = 2; i < 4; i++)
1149 resulta[3][i] = resulta[c1][i];
1150 }
1151
1152 if (!(sim_bitmap & 0x30)) { /* path B TX OK */
1153 for (i = 4; i < 6; i++)
1154 resulta[3][i] = resulta[c1][i];
1155 }
1156
1157 if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
1158 for (i = 6; i < 8; i++)
1159 resulta[3][i] = resulta[c1][i];
1160 }
1161 return false;
1162 }
1163 }
1164
phy_iq_calibrate(struct adapter * adapt,s32 result[][8],u8 t,bool is2t)1165 static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
1166 u8 t, bool is2t)
1167 {
1168 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1169 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1170 u32 i;
1171 u8 path_a_ok, path_b_ok;
1172 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1173 rFPGA0_XCD_SwitchControl, rBlue_Tooth,
1174 rRx_Wait_CCA, rTx_CCK_RFON,
1175 rTx_CCK_BBON, rTx_OFDM_RFON,
1176 rTx_OFDM_BBON, rTx_To_Rx,
1177 rTx_To_Tx, rRx_CCK,
1178 rRx_OFDM, rRx_Wait_RIFS,
1179 rRx_TO_Rx, rStandby,
1180 rSleep, rPMPD_ANAEN};
1181
1182 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1183 REG_TXPAUSE, REG_BCN_CTRL,
1184 REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
1185
1186 /* since 92C & 92D have the different define in IQK_BB_REG */
1187 u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1188 rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
1189 rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
1190 rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
1191 rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD};
1192
1193 u32 retry_count = 9;
1194 if (*(dm_odm->mp_mode) == 1)
1195 retry_count = 9;
1196 else
1197 retry_count = 2;
1198
1199 if (t == 0) {
1200
1201 /* Save ADDA parameters, turn Path A ADDA on */
1202 save_adda_registers(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1203 IQK_ADDA_REG_NUM);
1204 save_mac_registers(adapt, iqk_mac_reg,
1205 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1206 save_adda_registers(adapt, iqk_bb_reg_92c,
1207 dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1208 }
1209
1210 path_adda_on(adapt, adda_reg, true, is2t);
1211 if (t == 0)
1212 dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1,
1213 BIT(8));
1214
1215 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1216 /* Switch BB to PI mode to do IQ Calibration. */
1217 pi_mode_switch(adapt, true);
1218 }
1219
1220 /* BB setting */
1221 phy_set_bb_reg(adapt, rFPGA0_RFMOD, BIT24, 0x00);
1222 phy_set_bb_reg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1223 phy_set_bb_reg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1224 phy_set_bb_reg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1225
1226 phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01);
1227 phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01);
1228 phy_set_bb_reg(adapt, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00);
1229 phy_set_bb_reg(adapt, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00);
1230
1231 if (is2t) {
1232 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord,
1233 0x00010000);
1234 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, bMaskDWord,
1235 0x00010000);
1236 }
1237
1238 /* MAC settings */
1239 mac_setting_calibration(adapt, iqk_mac_reg,
1240 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1241
1242 /* Page B init */
1243 /* AP or IQK */
1244 phy_set_bb_reg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
1245
1246 if (is2t)
1247 phy_set_bb_reg(adapt, rConfig_AntB, bMaskDWord, 0x0f600000);
1248
1249 /* IQ calibration setting */
1250 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
1251 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
1252 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
1253
1254 for (i = 0; i < retry_count; i++) {
1255 path_a_ok = phy_path_a_iqk(adapt, is2t);
1256 if (path_a_ok == 0x01) {
1257 result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A,
1258 bMaskDWord)&0x3FF0000)>>16;
1259 result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A,
1260 bMaskDWord)&0x3FF0000)>>16;
1261 break;
1262 }
1263 }
1264
1265 for (i = 0; i < retry_count; i++) {
1266 path_a_ok = phy_path_a_rx_iqk(adapt, is2t);
1267 if (path_a_ok == 0x03) {
1268 result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2,
1269 bMaskDWord)&0x3FF0000)>>16;
1270 result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2,
1271 bMaskDWord)&0x3FF0000)>>16;
1272 break;
1273 } else {
1274 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1275 ("Path A Rx IQK Fail!!\n"));
1276 }
1277 }
1278
1279 if (0x00 == path_a_ok) {
1280 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1281 ("Path A IQK failed!!\n"));
1282 }
1283
1284 if (is2t) {
1285 path_a_standby(adapt);
1286
1287 /* Turn Path B ADDA on */
1288 path_adda_on(adapt, adda_reg, false, is2t);
1289
1290 for (i = 0; i < retry_count; i++) {
1291 path_b_ok = phy_path_b_iqk(adapt);
1292 if (path_b_ok == 0x03) {
1293 result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1294 bMaskDWord)&0x3FF0000)>>16;
1295 result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1296 bMaskDWord)&0x3FF0000)>>16;
1297 result[t][6] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2,
1298 bMaskDWord)&0x3FF0000)>>16;
1299 result[t][7] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2,
1300 bMaskDWord)&0x3FF0000)>>16;
1301 break;
1302 } else if (i == (retry_count - 1) && path_b_ok == 0x01) { /* Tx IQK OK */
1303 result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1304 bMaskDWord)&0x3FF0000)>>16;
1305 result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1306 bMaskDWord)&0x3FF0000)>>16;
1307 }
1308 }
1309
1310 if (0x00 == path_b_ok) {
1311 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1312 ("Path B IQK failed!!\n"));
1313 }
1314 }
1315
1316 /* Back to BB mode, load original value */
1317 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0);
1318
1319 if (t != 0) {
1320 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1321 /* Switch back BB to SI mode after
1322 * finish IQ Calibration.
1323 */
1324 pi_mode_switch(adapt, false);
1325 }
1326
1327 /* Reload ADDA power saving parameters */
1328 reload_adda_reg(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1329 IQK_ADDA_REG_NUM);
1330
1331 /* Reload MAC parameters */
1332 reload_mac_registers(adapt, iqk_mac_reg,
1333 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1334
1335 reload_adda_reg(adapt, iqk_bb_reg_92c, dm_odm->RFCalibrateInfo.IQK_BB_backup,
1336 IQK_BB_REG_NUM);
1337
1338 /* Restore RX initial gain */
1339 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter,
1340 bMaskDWord, 0x00032ed3);
1341 if (is2t)
1342 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter,
1343 bMaskDWord, 0x00032ed3);
1344
1345 /* load 0xe30 IQC default value */
1346 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1347 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1348 }
1349 }
1350
phy_lc_calibrate(struct adapter * adapt,bool is2t)1351 static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
1352 {
1353 u8 tmpreg;
1354 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1355
1356 /* Check continuous TX and Packet TX */
1357 tmpreg = usb_read8(adapt, 0xd03);
1358
1359 if ((tmpreg&0x70) != 0)
1360 usb_write8(adapt, 0xd03, tmpreg&0x8F);
1361 else
1362 usb_write8(adapt, REG_TXPAUSE, 0xFF);
1363
1364 if ((tmpreg&0x70) != 0) {
1365 /* 1. Read original RF mode */
1366 /* Path-A */
1367 rf_a_mode = phy_query_rf_reg(adapt, RF_PATH_A, RF_AC,
1368 bMask12Bits);
1369
1370 /* Path-B */
1371 if (is2t)
1372 rf_b_mode = phy_query_rf_reg(adapt, RF_PATH_B, RF_AC,
1373 bMask12Bits);
1374
1375 /* 2. Set RF mode = standby mode */
1376 /* Path-A */
1377 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits,
1378 (rf_a_mode&0x8FFFF)|0x10000);
1379
1380 /* Path-B */
1381 if (is2t)
1382 phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1383 (rf_b_mode&0x8FFFF)|0x10000);
1384 }
1385
1386 /* 3. Read RF reg18 */
1387 lc_cal = phy_query_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1388
1389 /* 4. Set LC calibration begin bit15 */
1390 phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits,
1391 lc_cal|0x08000);
1392
1393 msleep(100);
1394
1395 /* Restore original situation */
1396 if ((tmpreg&0x70) != 0) {
1397 /* Deal with continuous TX case */
1398 /* Path-A */
1399 usb_write8(adapt, 0xd03, tmpreg);
1400 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, rf_a_mode);
1401
1402 /* Path-B */
1403 if (is2t)
1404 phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1405 rf_b_mode);
1406 } else {
1407 /* Deal with Packet TX case */
1408 usb_write8(adapt, REG_TXPAUSE, 0x00);
1409 }
1410 }
1411
rtl88eu_phy_iq_calibrate(struct adapter * adapt,bool recovery)1412 void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
1413 {
1414 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1415 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1416 s32 result[4][8];
1417 u8 i, final, chn_index;
1418 bool pathaok, pathbok;
1419 s32 reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1420 reg_ecc;
1421 bool is12simular, is13simular, is23simular;
1422 bool singletone = false, carrier_sup = false;
1423 u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1424 rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1425 rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1426 rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1427 rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1428 rOFDM0_RxIQExtAnta};
1429 bool is2t;
1430
1431 is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1432
1433 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1434 return;
1435
1436 if (singletone || carrier_sup)
1437 return;
1438
1439 if (recovery) {
1440 ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
1441 ("phy_iq_calibrate: Return due to recovery!\n"));
1442 reload_adda_reg(adapt, iqk_bb_reg_92c,
1443 dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1444 return;
1445 }
1446
1447 for (i = 0; i < 8; i++) {
1448 result[0][i] = 0;
1449 result[1][i] = 0;
1450 result[2][i] = 0;
1451 if ((i == 0) || (i == 2) || (i == 4) || (i == 6))
1452 result[3][i] = 0x100;
1453 else
1454 result[3][i] = 0;
1455 }
1456 final = 0xff;
1457 pathaok = false;
1458 pathbok = false;
1459 is12simular = false;
1460 is23simular = false;
1461 is13simular = false;
1462
1463 for (i = 0; i < 3; i++) {
1464 phy_iq_calibrate(adapt, result, i, is2t);
1465
1466 if (i == 1) {
1467 is12simular = simularity_compare(adapt, result, 0, 1);
1468 if (is12simular) {
1469 final = 0;
1470 break;
1471 }
1472 }
1473
1474 if (i == 2) {
1475 is13simular = simularity_compare(adapt, result, 0, 2);
1476 if (is13simular) {
1477 final = 0;
1478 break;
1479 }
1480 is23simular = simularity_compare(adapt, result, 1, 2);
1481 if (is23simular)
1482 final = 1;
1483 else
1484 final = 3;
1485 }
1486 }
1487
1488 for (i = 0; i < 4; i++) {
1489 reg_e94 = result[i][0];
1490 reg_e9c = result[i][1];
1491 reg_ea4 = result[i][2];
1492 reg_eac = result[i][3];
1493 reg_eb4 = result[i][4];
1494 reg_ebc = result[i][5];
1495 reg_ec4 = result[i][6];
1496 reg_ecc = result[i][7];
1497 }
1498
1499 if (final != 0xff) {
1500 reg_e94 = result[final][0];
1501 reg_e9c = result[final][1];
1502 reg_ea4 = result[final][2];
1503 reg_eac = result[final][3];
1504 reg_eb4 = result[final][4];
1505 reg_ebc = result[final][5];
1506 dm_odm->RFCalibrateInfo.RegE94 = reg_e94;
1507 dm_odm->RFCalibrateInfo.RegE9C = reg_e9c;
1508 dm_odm->RFCalibrateInfo.RegEB4 = reg_eb4;
1509 dm_odm->RFCalibrateInfo.RegEBC = reg_ebc;
1510 reg_ec4 = result[final][6];
1511 reg_ecc = result[final][7];
1512 pathaok = true;
1513 pathbok = true;
1514 } else {
1515 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1516 ("IQK: FAIL use default value\n"));
1517 dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1518 dm_odm->RFCalibrateInfo.RegEB4 = 0x100;
1519 dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1520 dm_odm->RFCalibrateInfo.RegEBC = 0x0;
1521 }
1522 if (reg_e94 != 0)
1523 patha_fill_iqk(adapt, pathaok, result, final,
1524 (reg_ea4 == 0));
1525 if (is2t) {
1526 if (reg_eb4 != 0)
1527 pathb_fill_iqk(adapt, pathbok, result, final,
1528 (reg_ec4 == 0));
1529 }
1530
1531 chn_index = get_right_chnl_for_iqk(hal_data->CurrentChannel);
1532
1533 if (final < 4) {
1534 for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1535 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].Value[0][i] = result[final][i];
1536 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].bIQKDone = true;
1537 }
1538
1539 save_adda_registers(adapt, iqk_bb_reg_92c,
1540 dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1541 }
1542
rtl88eu_phy_lc_calibrate(struct adapter * adapt)1543 void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
1544 {
1545 bool singletone = false, carrier_sup = false;
1546 u32 timeout = 2000, timecount = 0;
1547 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1548 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1549
1550 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1551 return;
1552 if (singletone || carrier_sup)
1553 return;
1554
1555 while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1556 mdelay(50);
1557 timecount += 50;
1558 }
1559
1560 dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1561
1562 if (dm_odm->RFType == ODM_2T2R) {
1563 phy_lc_calibrate(adapt, true);
1564 } else {
1565 /* For 88C 1T1R */
1566 phy_lc_calibrate(adapt, false);
1567 }
1568
1569 dm_odm->RFCalibrateInfo.bLCKInProgress = false;
1570 }
1571