1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
20 #define _RTL8188E_PHYCFG_C_
22 #include <osdep_service.h>
23 #include <drv_types.h>
25 #include <rtl8188e_hal.h>
29 #define MAX_PRECMD_CNT 16
30 #define MAX_RFDEPENDCMD_CNT 16
31 #define MAX_POSTCMD_CNT 16
33 #define MAX_DOZE_WAITING_TIMES_9x 64
35 static u32 cal_bit_shift(u32 bitmask)
39 for (i = 0; i <= 31; i++) {
40 if (((bitmask >> i) & 0x1) == 1)
46 u32 phy_query_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask)
48 u32 return_value = 0, original_value, bit_shift;
50 original_value = usb_read32(adapt, regaddr);
51 bit_shift = cal_bit_shift(bitmask);
52 return_value = (original_value & bitmask) >> bit_shift;
56 void phy_set_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask, u32 data)
58 u32 original_value, bit_shift;
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);
66 usb_write32(adapt, regaddr, data);
69 static u32 rf_serial_read(struct adapter *adapt,
70 enum rf_radio_path rfpath, u32 offset)
73 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
74 struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath];
75 u32 tmplong, tmplong2;
80 tmplong = phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord);
81 if (rfpath == RF_PATH_A)
84 tmplong2 = phy_query_bb_reg(adapt, phyreg->rfHSSIPara2,
87 tmplong2 = (tmplong2 & (~bLSSIReadAddress)) |
88 (offset<<23) | bLSSIReadEdge;
90 phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord,
91 tmplong&(~bLSSIReadEdge));
94 phy_set_bb_reg(adapt, phyreg->rfHSSIPara2, bMaskDWord, tmplong2);
99 if (rfpath == RF_PATH_A)
100 rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, BIT(8));
101 else if (rfpath == RF_PATH_B)
102 rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, BIT(8));
105 ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBackPi,
108 ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBack,
113 static void rf_serial_write(struct adapter *adapt,
114 enum rf_radio_path rfpath, u32 offset,
117 u32 data_and_addr = 0;
118 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
119 struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath];
122 data_and_addr = ((offset<<20) | (data&0x000fffff)) & 0x0fffffff;
123 phy_set_bb_reg(adapt, phyreg->rf3wireOffset, bMaskDWord, data_and_addr);
126 u32 phy_query_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
127 u32 reg_addr, u32 bit_mask)
129 u32 original_value, readback_value, bit_shift;
131 original_value = rf_serial_read(adapt, rf_path, reg_addr);
132 bit_shift = cal_bit_shift(bit_mask);
133 readback_value = (original_value & bit_mask) >> bit_shift;
134 return readback_value;
137 void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
138 u32 reg_addr, u32 bit_mask, u32 data)
140 u32 original_value, bit_shift;
142 /* RF data is 12 bits only */
143 if (bit_mask != bRFRegOffsetMask) {
144 original_value = rf_serial_read(adapt, rf_path, reg_addr);
145 bit_shift = cal_bit_shift(bit_mask);
146 data = (original_value & (~bit_mask)) | (data << bit_shift);
149 rf_serial_write(adapt, rf_path, reg_addr, data);
152 static void get_tx_power_index(struct adapter *adapt, u8 channel, u8 *cck_pwr,
153 u8 *ofdm_pwr, u8 *bw20_pwr, u8 *bw40_pwr)
155 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
156 u8 index = (channel - 1);
157 u8 TxCount = 0, path_nums;
159 if ((RF_1T2R == hal_data->rf_type) || (RF_1T1R == hal_data->rf_type))
164 for (TxCount = 0; TxCount < path_nums; TxCount++) {
165 if (TxCount == RF_PATH_A) {
166 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
167 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
168 hal_data->OFDM_24G_Diff[TxCount][RF_PATH_A];
170 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
171 hal_data->BW20_24G_Diff[TxCount][RF_PATH_A];
172 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
173 } else if (TxCount == RF_PATH_B) {
174 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
175 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
176 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
177 hal_data->BW20_24G_Diff[TxCount][index];
179 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
180 hal_data->BW20_24G_Diff[TxCount][RF_PATH_A]+
181 hal_data->BW20_24G_Diff[TxCount][index];
182 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
183 } else if (TxCount == RF_PATH_C) {
184 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
185 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
186 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
187 hal_data->BW20_24G_Diff[RF_PATH_B][index]+
188 hal_data->BW20_24G_Diff[TxCount][index];
190 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
191 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
192 hal_data->BW20_24G_Diff[RF_PATH_B][index]+
193 hal_data->BW20_24G_Diff[TxCount][index];
194 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
195 } else if (TxCount == RF_PATH_D) {
196 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
197 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
198 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
199 hal_data->BW20_24G_Diff[RF_PATH_B][index]+
200 hal_data->BW20_24G_Diff[RF_PATH_C][index]+
201 hal_data->BW20_24G_Diff[TxCount][index];
203 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
204 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
205 hal_data->BW20_24G_Diff[RF_PATH_B][index]+
206 hal_data->BW20_24G_Diff[RF_PATH_C][index]+
207 hal_data->BW20_24G_Diff[TxCount][index];
208 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
213 static void phy_power_index_check(struct adapter *adapt, u8 channel,
214 u8 *cck_pwr, u8 *ofdm_pwr, u8 *bw20_pwr,
217 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
219 hal_data->CurrentCckTxPwrIdx = cck_pwr[0];
220 hal_data->CurrentOfdm24GTxPwrIdx = ofdm_pwr[0];
221 hal_data->CurrentBW2024GTxPwrIdx = bw20_pwr[0];
222 hal_data->CurrentBW4024GTxPwrIdx = bw40_pwr[0];
225 void phy_set_tx_power_level(struct adapter *adapt, u8 channel)
227 u8 cck_pwr[MAX_TX_COUNT] = {0};
228 u8 ofdm_pwr[MAX_TX_COUNT] = {0};/* [0]:RF-A, [1]:RF-B */
229 u8 bw20_pwr[MAX_TX_COUNT] = {0};
230 u8 bw40_pwr[MAX_TX_COUNT] = {0};
232 get_tx_power_index(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
233 &bw20_pwr[0], &bw40_pwr[0]);
235 phy_power_index_check(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
236 &bw20_pwr[0], &bw40_pwr[0]);
238 rtl88eu_phy_rf6052_set_cck_txpower(adapt, &cck_pwr[0]);
239 rtl88eu_phy_rf6052_set_ofdm_txpower(adapt, &ofdm_pwr[0], &bw20_pwr[0],
240 &bw40_pwr[0], channel);
243 static void phy_set_bw_mode_callback(struct adapter *adapt)
245 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
249 if (hal_data->rf_chip == RF_PSEUDO_11N)
252 /* There is no 40MHz mode in RF_8225. */
253 if (hal_data->rf_chip == RF_8225)
256 if (adapt->bDriverStopped)
259 /* Set MAC register */
261 reg_bw_opmode = usb_read8(adapt, REG_BWOPMODE);
262 reg_prsr_rsc = usb_read8(adapt, REG_RRSR+2);
264 switch (hal_data->CurrentChannelBW) {
265 case HT_CHANNEL_WIDTH_20:
266 reg_bw_opmode |= BW_OPMODE_20MHZ;
267 usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode);
269 case HT_CHANNEL_WIDTH_40:
270 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
271 usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode);
272 reg_prsr_rsc = (reg_prsr_rsc&0x90) |
273 (hal_data->nCur40MhzPrimeSC<<5);
274 usb_write8(adapt, REG_RRSR+2, reg_prsr_rsc);
280 /* Set PHY related register */
281 switch (hal_data->CurrentChannelBW) {
282 case HT_CHANNEL_WIDTH_20:
283 phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x0);
284 phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x0);
286 case HT_CHANNEL_WIDTH_40:
287 phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x1);
288 phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x1);
289 /* Set Control channel to upper or lower.
290 * These settings are required only for 40MHz
292 phy_set_bb_reg(adapt, rCCK0_System, bCCKSideBand,
293 (hal_data->nCur40MhzPrimeSC>>1));
294 phy_set_bb_reg(adapt, rOFDM1_LSTF, 0xC00,
295 hal_data->nCur40MhzPrimeSC);
296 phy_set_bb_reg(adapt, 0x818, (BIT(26) | BIT(27)),
297 (hal_data->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
303 /* Set RF related register */
304 if (hal_data->rf_chip == RF_6052)
305 rtl88eu_phy_rf6052_set_bandwidth(adapt, hal_data->CurrentChannelBW);
308 void phy_set_bw_mode(struct adapter *adapt, enum ht_channel_width bandwidth,
309 unsigned char offset)
311 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
312 enum ht_channel_width tmp_bw = hal_data->CurrentChannelBW;
314 hal_data->CurrentChannelBW = bandwidth;
315 hal_data->nCur40MhzPrimeSC = offset;
317 if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
318 phy_set_bw_mode_callback(adapt);
320 hal_data->CurrentChannelBW = tmp_bw;
323 static void phy_sw_chnl_callback(struct adapter *adapt, u8 channel)
327 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
329 if (adapt->bNotifyChannelChange)
330 DBG_88E("[%s] ch = %d\n", __func__, channel);
332 phy_set_tx_power_level(adapt, channel);
336 for (rf_path = 0; rf_path < hal_data->NumTotalRFPath; rf_path++) {
337 hal_data->RfRegChnlVal[rf_path] = (hal_data->RfRegChnlVal[rf_path] &
338 0xfffffc00) | param2;
339 phy_set_rf_reg(adapt, (enum rf_radio_path)rf_path, param1,
340 bRFRegOffsetMask, hal_data->RfRegChnlVal[rf_path]);
344 void phy_sw_chnl(struct adapter *adapt, u8 channel)
346 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
347 u8 tmpchannel = hal_data->CurrentChannel;
349 if (hal_data->rf_chip == RF_PSEUDO_11N)
355 hal_data->CurrentChannel = channel;
357 if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
358 phy_sw_chnl_callback(adapt, channel);
360 hal_data->CurrentChannel = tmpchannel;
363 #define ODM_TXPWRTRACK_MAX_IDX_88E 6
365 static u8 get_right_chnl_for_iqk(u8 chnl)
368 u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
369 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
370 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
371 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153,
372 155, 157, 159, 161, 163, 165
376 for (place = 0; place < sizeof(channel_all); place++) {
377 if (channel_all[place] == chnl)
384 void rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct *dm_odm, u8 type,
385 u8 *direction, u32 *out_write_val)
388 /* Tx power tracking BB swing table. */
389 if (type == 0) { /* For OFDM adjust */
390 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
391 ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n",
392 dm_odm->BbSwingIdxOfdm, dm_odm->BbSwingFlagOfdm));
394 if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
396 pwr_value = dm_odm->BbSwingIdxOfdmBase -
397 dm_odm->BbSwingIdxOfdm;
400 pwr_value = dm_odm->BbSwingIdxOfdm -
401 dm_odm->BbSwingIdxOfdmBase;
404 } else if (type == 1) { /* For CCK adjust. */
405 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
406 ("dm_odm->BbSwingIdxCck = %d dm_odm->BbSwingIdxCckBase = %d\n",
407 dm_odm->BbSwingIdxCck, dm_odm->BbSwingIdxCckBase));
409 if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
411 pwr_value = dm_odm->BbSwingIdxCckBase -
412 dm_odm->BbSwingIdxCck;
415 pwr_value = dm_odm->BbSwingIdxCck -
416 dm_odm->BbSwingIdxCckBase;
421 if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *direction == 1)
422 pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
424 *out_write_val = pwr_value | (pwr_value<<8) | (pwr_value<<16) |
428 static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm)
430 if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
431 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
432 ("dm_txpwr_track_setpwr CH=%d\n", *(dm_odm->pChannel)));
433 phy_set_tx_power_level(dm_odm->Adapter, *(dm_odm->pChannel));
434 dm_odm->BbSwingFlagOfdm = false;
435 dm_odm->BbSwingFlagCck = false;
439 void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt)
441 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
442 u8 thermal_val = 0, delta, delta_lck, delta_iqk, offset;
443 u8 thermal_avg_count = 0;
446 s8 ofdm_index[2], cck_index = 0;
447 s8 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
451 u8 ofdm_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB */
452 s8 ofdm_index_mapping[2][index_mapping_NUM_88E] = {
453 /* 2.4G, decrease power */
454 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
455 /* 2.4G, increase power */
456 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10},
458 u8 thermal_mapping[2][index_mapping_NUM_88E] = {
459 /* 2.4G, decrease power */
460 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
461 /* 2.4G, increase power */
462 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25},
464 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
466 dm_txpwr_track_setpwr(dm_odm);
468 dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++;
469 dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
471 dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
473 thermal_val = (u8)phy_query_rf_reg(adapt, RF_PATH_A,
474 RF_T_METER_88E, 0xfc00);
482 /* Query OFDM path A default setting */
483 ele_d = phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord)&bMaskOFDM_D;
484 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
485 if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) {
486 ofdm_index_old[0] = (u8)i;
487 dm_odm->BbSwingIdxOfdmBase = (u8)i;
492 /* Query OFDM path B default setting */
494 ele_d = phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord)&bMaskOFDM_D;
495 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
496 if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) {
497 ofdm_index_old[1] = (u8)i;
503 /* Query CCK default setting From 0xa24 */
504 temp_cck = dm_odm->RFCalibrateInfo.RegA24;
506 for (i = 0; i < CCK_TABLE_SIZE; i++) {
507 if ((dm_odm->RFCalibrateInfo.bCCKinCH14 &&
508 memcmp(&temp_cck, &CCKSwingTable_Ch14[i][2], 4)) ||
509 memcmp(&temp_cck, &CCKSwingTable_Ch1_Ch13[i][2], 4)) {
510 cck_index_old = (u8)i;
511 dm_odm->BbSwingIdxCckBase = (u8)i;
516 if (!dm_odm->RFCalibrateInfo.ThermalValue) {
517 dm_odm->RFCalibrateInfo.ThermalValue = hal_data->EEPROMThermalMeter;
518 dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val;
519 dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val;
521 for (i = 0; i < rf; i++)
522 dm_odm->RFCalibrateInfo.OFDM_index[i] = ofdm_index_old[i];
523 dm_odm->RFCalibrateInfo.CCK_index = cck_index_old;
526 /* calculate average thermal meter */
527 dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = thermal_val;
528 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++;
529 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
530 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
532 for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
533 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
534 thermal_avg += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i];
539 if (thermal_avg_count)
540 thermal_val = (u8)(thermal_avg / thermal_avg_count);
542 if (dm_odm->RFCalibrateInfo.bDoneTxpower &&
543 !dm_odm->RFCalibrateInfo.bReloadtxpowerindex)
544 delta = abs(thermal_val - dm_odm->RFCalibrateInfo.ThermalValue);
546 delta = abs(thermal_val - hal_data->EEPROMThermalMeter);
547 if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) {
548 dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false;
549 dm_odm->RFCalibrateInfo.bDoneTxpower = false;
553 delta_lck = abs(dm_odm->RFCalibrateInfo.ThermalValue_LCK - thermal_val);
554 delta_iqk = abs(dm_odm->RFCalibrateInfo.ThermalValue_IQK - thermal_val);
556 /* Delta temperature is equal to or larger than 20 centigrade.*/
557 if ((delta_lck >= 8)) {
558 dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val;
559 rtl88eu_phy_lc_calibrate(adapt);
562 if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
563 delta = abs(hal_data->EEPROMThermalMeter - thermal_val);
565 /* calculate new OFDM / CCK offset */
566 if (thermal_val > hal_data->EEPROMThermalMeter)
570 for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
571 if (delta < thermal_mapping[j][offset]) {
577 if (offset >= index_mapping_NUM_88E)
578 offset = index_mapping_NUM_88E-1;
580 /* Updating ofdm_index values with new OFDM / CCK offset */
581 for (i = 0; i < rf; i++) {
582 ofdm_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + ofdm_index_mapping[j][offset];
583 if (ofdm_index[i] > OFDM_TABLE_SIZE_92D-1)
584 ofdm_index[i] = OFDM_TABLE_SIZE_92D-1;
585 else if (ofdm_index[i] < ofdm_min_index)
586 ofdm_index[i] = ofdm_min_index;
589 cck_index = dm_odm->RFCalibrateInfo.CCK_index + ofdm_index_mapping[j][offset];
590 if (cck_index > CCK_TABLE_SIZE-1)
591 cck_index = CCK_TABLE_SIZE-1;
592 else if (cck_index < 0)
595 /* 2 temporarily remove bNOPG */
596 /* Config by SwingTable */
597 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
598 dm_odm->RFCalibrateInfo.bDoneTxpower = true;
600 /* Revse TX power table. */
601 dm_odm->BbSwingIdxOfdm = (u8)ofdm_index[0];
602 dm_odm->BbSwingIdxCck = (u8)cck_index;
604 if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
605 dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
606 dm_odm->BbSwingFlagOfdm = true;
609 if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
610 dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
611 dm_odm->BbSwingFlagCck = true;
616 /* Delta temperature is equal to or larger than 20 centigrade.*/
617 if (delta_iqk >= 8) {
618 dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val;
619 rtl88eu_phy_iq_calibrate(adapt, false);
621 /* update thermal meter value */
622 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
623 dm_odm->RFCalibrateInfo.ThermalValue = thermal_val;
625 dm_odm->RFCalibrateInfo.TXPowercount = 0;
628 #define MAX_TOLERANCE 5
630 static u8 phy_path_a_iqk(struct adapter *adapt, bool config_pathb)
632 u32 reg_eac, reg_e94, reg_e9c;
636 /* path-A IQK setting */
637 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
638 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
639 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x8214032a);
640 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
642 /* LO calibration setting */
643 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
645 /* One shot, path A LOK & IQK */
646 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
647 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
649 mdelay(IQK_DELAY_TIME_88E);
651 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
652 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
653 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
655 if (!(reg_eac & BIT(28)) &&
656 (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
657 (((reg_e9c & 0x03FF0000)>>16) != 0x42))
662 static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB)
664 u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
666 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
667 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
669 /* 1 Get TXIMR setting */
670 /* modify RXIQK mode table */
671 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
672 phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
673 phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
674 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
675 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
678 phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
679 phy_set_rf_reg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
681 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
684 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
685 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
687 /* path-A IQK setting */
688 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
689 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
690 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
691 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
693 /* LO calibration setting */
694 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
696 /* One shot, path A LOK & IQK */
697 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
698 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
701 mdelay(IQK_DELAY_TIME_88E);
704 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
705 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
706 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
708 if (!(reg_eac & BIT(28)) &&
709 (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
710 (((reg_e9c & 0x03FF0000)>>16) != 0x42))
712 else /* if Tx not OK, ignore Rx */
715 u4tmp = 0x80007C00 | (reg_e94&0x3FF0000) | ((reg_e9c&0x3FF0000) >> 16);
716 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, u4tmp);
719 /* modify RXIQK mode table */
720 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
721 ("Path-A Rx IQK modify RXIQK mode table 2!\n"));
722 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
723 phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
724 phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
725 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
726 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
727 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
730 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
732 /* path-A IQK setting */
733 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
734 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
735 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
736 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
738 /* LO calibration setting */
739 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
741 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
742 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
744 mdelay(IQK_DELAY_TIME_88E);
747 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
748 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
749 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
750 reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
753 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
754 phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
756 if (!(reg_eac & BIT(27)) && /* if Tx is OK, check whether Rx is OK */
757 (((reg_ea4 & 0x03FF0000)>>16) != 0x132) &&
758 (((reg_eac & 0x03FF0000)>>16) != 0x36))
761 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
762 ("Path A Rx IQK fail!!\n"));
767 static u8 phy_path_b_iqk(struct adapter *adapt)
769 u32 regeac, regeb4, regebc, regec4, regecc;
771 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
772 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
774 /* One shot, path B LOK & IQK */
775 phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
776 phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000000);
778 mdelay(IQK_DELAY_TIME_88E);
780 regeac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
781 regeb4 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, bMaskDWord);
782 regebc = phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, bMaskDWord);
783 regec4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2, bMaskDWord);
784 regecc = phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2, bMaskDWord);
786 if (!(regeac & BIT(31)) &&
787 (((regeb4 & 0x03FF0000)>>16) != 0x142) &&
788 (((regebc & 0x03FF0000)>>16) != 0x42))
793 if (!(regeac & BIT(30)) &&
794 (((regec4 & 0x03FF0000)>>16) != 0x132) &&
795 (((regecc & 0x03FF0000)>>16) != 0x36))
798 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION,
799 ODM_DBG_LOUD, ("Path B Rx IQK fail!!\n"));
803 static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
804 u8 final_candidate, bool txonly)
806 u32 oldval_0, x, tx0_a, reg;
809 if (final_candidate == 0xFF) {
812 oldval_0 = (phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
814 x = result[final_candidate][0];
815 if ((x & 0x00000200) != 0)
818 tx0_a = (x * oldval_0) >> 8;
819 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, tx0_a);
820 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(31),
821 ((x * oldval_0>>7) & 0x1));
823 y = result[final_candidate][1];
824 if ((y & 0x00000200) != 0)
827 tx0_c = (y * oldval_0) >> 8;
828 phy_set_bb_reg(adapt, rOFDM0_XCTxAFE, 0xF0000000,
830 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000,
832 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(29),
833 ((y * oldval_0>>7) & 0x1));
838 reg = result[final_candidate][2];
839 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
841 reg = result[final_candidate][3] & 0x3F;
842 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
844 reg = (result[final_candidate][3] >> 6) & 0xF;
845 phy_set_bb_reg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
849 static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
850 u8 final_candidate, bool txonly)
852 u32 oldval_1, x, tx1_a, reg;
855 if (final_candidate == 0xFF) {
858 oldval_1 = (phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
860 x = result[final_candidate][4];
861 if ((x & 0x00000200) != 0)
863 tx1_a = (x * oldval_1) >> 8;
864 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x3FF, tx1_a);
866 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(27),
867 ((x * oldval_1>>7) & 0x1));
869 y = result[final_candidate][5];
870 if ((y & 0x00000200) != 0)
873 tx1_c = (y * oldval_1) >> 8;
875 phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, 0xF0000000,
877 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x003F0000,
879 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(25),
880 ((y * oldval_1>>7) & 0x1));
885 reg = result[final_candidate][6];
886 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
888 reg = result[final_candidate][7] & 0x3F;
889 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
891 reg = (result[final_candidate][7] >> 6) & 0xF;
892 phy_set_bb_reg(adapt, rOFDM0_AGCRSSITable, 0x0000F000, reg);
896 static void save_adda_registers(struct adapter *adapt, u32 *addareg,
897 u32 *backup, u32 register_num)
901 for (i = 0; i < register_num; i++) {
902 backup[i] = phy_query_bb_reg(adapt, addareg[i], bMaskDWord);
906 static void save_mac_registers(struct adapter *adapt, u32 *mac_reg,
911 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
912 backup[i] = usb_read8(adapt, mac_reg[i]);
914 backup[i] = usb_read32(adapt, mac_reg[i]);
917 static void reload_adda_reg(struct adapter *adapt, u32 *adda_reg,
918 u32 *backup, u32 regiester_num)
922 for (i = 0; i < regiester_num; i++)
923 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, backup[i]);
926 static void reload_mac_registers(struct adapter *adapt,
927 u32 *mac_reg, u32 *backup)
931 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
932 usb_write8(adapt, mac_reg[i], (u8)backup[i]);
934 usb_write32(adapt, mac_reg[i], backup[i]);
937 static void path_adda_on(struct adapter *adapt, u32 *adda_reg,
938 bool is_path_a_on, bool is2t)
944 path_on = 0x0bdb25a0;
945 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, 0x0b1b25a0);
947 path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4;
948 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, path_on);
951 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
952 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, path_on);
955 static void mac_setting_calibration(struct adapter *adapt, u32 *mac_reg, u32 *backup)
959 usb_write8(adapt, mac_reg[i], 0x3F);
961 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
962 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(3))));
964 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(5))));
967 static void path_a_standby(struct adapter *adapt)
970 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x0);
971 phy_set_bb_reg(adapt, 0x840, bMaskDWord, 0x00010000);
972 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
975 static void pi_mode_switch(struct adapter *adapt, bool pi_mode)
979 mode = pi_mode ? 0x01000100 : 0x01000000;
980 phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
981 phy_set_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
984 static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
987 u32 i, j, diff, sim_bitmap = 0, bound;
988 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
989 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
990 u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
992 s32 tmp1 = 0, tmp2 = 0;
994 if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) ||
995 (dm_odm->RFType == ODM_2T4R))
1000 for (i = 0; i < bound; i++) {
1001 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1002 if ((resulta[c1][i] & 0x00000200) != 0)
1003 tmp1 = resulta[c1][i] | 0xFFFFFC00;
1005 tmp1 = resulta[c1][i];
1007 if ((resulta[c2][i] & 0x00000200) != 0)
1008 tmp2 = resulta[c2][i] | 0xFFFFFC00;
1010 tmp2 = resulta[c2][i];
1012 tmp1 = resulta[c1][i];
1013 tmp2 = resulta[c2][i];
1016 diff = abs(tmp1 - tmp2);
1018 if (diff > MAX_TOLERANCE) {
1019 if ((i == 2 || i == 6) && !sim_bitmap) {
1020 if (resulta[c1][i] + resulta[c1][i+1] == 0)
1021 final_candidate[(i/4)] = c2;
1022 else if (resulta[c2][i] + resulta[c2][i+1] == 0)
1023 final_candidate[(i/4)] = c1;
1025 sim_bitmap = sim_bitmap | (1<<i);
1027 sim_bitmap = sim_bitmap | (1<<i);
1032 if (sim_bitmap == 0) {
1033 for (i = 0; i < (bound/4); i++) {
1034 if (final_candidate[i] != 0xFF) {
1035 for (j = i*4; j < (i+1)*4-2; j++)
1036 resulta[3][j] = resulta[final_candidate[i]][j];
1042 if (!(sim_bitmap & 0x03)) { /* path A TX OK */
1043 for (i = 0; i < 2; i++)
1044 resulta[3][i] = resulta[c1][i];
1046 if (!(sim_bitmap & 0x0c)) { /* path A RX OK */
1047 for (i = 2; i < 4; i++)
1048 resulta[3][i] = resulta[c1][i];
1051 if (!(sim_bitmap & 0x30)) { /* path B TX OK */
1052 for (i = 4; i < 6; i++)
1053 resulta[3][i] = resulta[c1][i];
1056 if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
1057 for (i = 6; i < 8; i++)
1058 resulta[3][i] = resulta[c1][i];
1064 static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
1067 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1068 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1070 u8 path_a_ok, path_b_ok;
1071 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1072 rFPGA0_XCD_SwitchControl, rBlue_Tooth,
1073 rRx_Wait_CCA, rTx_CCK_RFON,
1074 rTx_CCK_BBON, rTx_OFDM_RFON,
1075 rTx_OFDM_BBON, rTx_To_Rx,
1077 rRx_OFDM, rRx_Wait_RIFS,
1078 rRx_TO_Rx, rStandby,
1079 rSleep, rPMPD_ANAEN};
1081 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1082 REG_TXPAUSE, REG_BCN_CTRL,
1083 REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
1085 /* since 92C & 92D have the different define in IQK_BB_REG */
1086 u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1087 rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
1088 rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
1089 rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
1090 rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD};
1092 u32 retry_count = 9;
1093 if (*(dm_odm->mp_mode) == 1)
1100 /* Save ADDA parameters, turn Path A ADDA on */
1101 save_adda_registers(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1103 save_mac_registers(adapt, iqk_mac_reg,
1104 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1105 save_adda_registers(adapt, iqk_bb_reg_92c,
1106 dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1109 path_adda_on(adapt, adda_reg, true, is2t);
1111 dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1,
1114 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1115 /* Switch BB to PI mode to do IQ Calibration. */
1116 pi_mode_switch(adapt, true);
1120 phy_set_bb_reg(adapt, rFPGA0_RFMOD, BIT(24), 0x00);
1121 phy_set_bb_reg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1122 phy_set_bb_reg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1123 phy_set_bb_reg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1125 phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01);
1126 phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01);
1127 phy_set_bb_reg(adapt, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00);
1128 phy_set_bb_reg(adapt, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00);
1131 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord,
1133 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, bMaskDWord,
1138 mac_setting_calibration(adapt, iqk_mac_reg,
1139 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1143 phy_set_bb_reg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
1146 phy_set_bb_reg(adapt, rConfig_AntB, bMaskDWord, 0x0f600000);
1148 /* IQ calibration setting */
1149 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
1150 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
1151 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
1153 for (i = 0; i < retry_count; i++) {
1154 path_a_ok = phy_path_a_iqk(adapt, is2t);
1155 if (path_a_ok == 0x01) {
1156 result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A,
1157 bMaskDWord)&0x3FF0000)>>16;
1158 result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A,
1159 bMaskDWord)&0x3FF0000)>>16;
1164 for (i = 0; i < retry_count; i++) {
1165 path_a_ok = phy_path_a_rx_iqk(adapt, is2t);
1166 if (path_a_ok == 0x03) {
1167 result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2,
1168 bMaskDWord)&0x3FF0000)>>16;
1169 result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2,
1170 bMaskDWord)&0x3FF0000)>>16;
1173 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1174 ("Path A Rx IQK Fail!!\n"));
1178 if (0x00 == path_a_ok) {
1179 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1180 ("Path A IQK failed!!\n"));
1184 path_a_standby(adapt);
1186 /* Turn Path B ADDA on */
1187 path_adda_on(adapt, adda_reg, false, is2t);
1189 for (i = 0; i < retry_count; i++) {
1190 path_b_ok = phy_path_b_iqk(adapt);
1191 if (path_b_ok == 0x03) {
1192 result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1193 bMaskDWord)&0x3FF0000)>>16;
1194 result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1195 bMaskDWord)&0x3FF0000)>>16;
1196 result[t][6] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2,
1197 bMaskDWord)&0x3FF0000)>>16;
1198 result[t][7] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2,
1199 bMaskDWord)&0x3FF0000)>>16;
1201 } else if (i == (retry_count - 1) && path_b_ok == 0x01) { /* Tx IQK OK */
1202 result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1203 bMaskDWord)&0x3FF0000)>>16;
1204 result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1205 bMaskDWord)&0x3FF0000)>>16;
1209 if (0x00 == path_b_ok) {
1210 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1211 ("Path B IQK failed!!\n"));
1215 /* Back to BB mode, load original value */
1216 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0);
1219 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1220 /* Switch back BB to SI mode after
1221 * finish IQ Calibration.
1223 pi_mode_switch(adapt, false);
1226 /* Reload ADDA power saving parameters */
1227 reload_adda_reg(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1230 /* Reload MAC parameters */
1231 reload_mac_registers(adapt, iqk_mac_reg,
1232 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1234 reload_adda_reg(adapt, iqk_bb_reg_92c, dm_odm->RFCalibrateInfo.IQK_BB_backup,
1237 /* Restore RX initial gain */
1238 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter,
1239 bMaskDWord, 0x00032ed3);
1241 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter,
1242 bMaskDWord, 0x00032ed3);
1244 /* load 0xe30 IQC default value */
1245 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1246 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1250 static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
1253 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1255 /* Check continuous TX and Packet TX */
1256 tmpreg = usb_read8(adapt, 0xd03);
1258 if ((tmpreg&0x70) != 0)
1259 usb_write8(adapt, 0xd03, tmpreg&0x8F);
1261 usb_write8(adapt, REG_TXPAUSE, 0xFF);
1263 if ((tmpreg&0x70) != 0) {
1264 /* 1. Read original RF mode */
1266 rf_a_mode = phy_query_rf_reg(adapt, RF_PATH_A, RF_AC,
1271 rf_b_mode = phy_query_rf_reg(adapt, RF_PATH_B, RF_AC,
1274 /* 2. Set RF mode = standby mode */
1276 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits,
1277 (rf_a_mode&0x8FFFF)|0x10000);
1281 phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1282 (rf_b_mode&0x8FFFF)|0x10000);
1285 /* 3. Read RF reg18 */
1286 lc_cal = phy_query_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1288 /* 4. Set LC calibration begin bit15 */
1289 phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits,
1294 /* Restore original situation */
1295 if ((tmpreg&0x70) != 0) {
1296 /* Deal with continuous TX case */
1298 usb_write8(adapt, 0xd03, tmpreg);
1299 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, rf_a_mode);
1303 phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1306 /* Deal with Packet TX case */
1307 usb_write8(adapt, REG_TXPAUSE, 0x00);
1311 void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
1313 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1314 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1316 u8 i, final, chn_index;
1317 bool pathaok, pathbok;
1318 s32 reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4;
1319 bool is12simular, is13simular, is23simular;
1320 bool singletone = false, carrier_sup = false;
1321 u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1322 rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1323 rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1324 rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1325 rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1326 rOFDM0_RxIQExtAnta};
1329 is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1331 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1334 if (singletone || carrier_sup)
1338 ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
1339 ("phy_iq_calibrate: Return due to recovery!\n"));
1340 reload_adda_reg(adapt, iqk_bb_reg_92c,
1341 dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1345 for (i = 0; i < 8; i++) {
1349 if ((i == 0) || (i == 2) || (i == 4) || (i == 6))
1350 result[3][i] = 0x100;
1357 is12simular = false;
1358 is23simular = false;
1359 is13simular = false;
1361 for (i = 0; i < 3; i++) {
1362 phy_iq_calibrate(adapt, result, i, is2t);
1365 is12simular = simularity_compare(adapt, result, 0, 1);
1373 is13simular = simularity_compare(adapt, result, 0, 2);
1378 is23simular = simularity_compare(adapt, result, 1, 2);
1386 for (i = 0; i < 4; i++) {
1387 reg_e94 = result[i][0];
1388 reg_e9c = result[i][1];
1389 reg_ea4 = result[i][2];
1390 reg_eb4 = result[i][4];
1391 reg_ebc = result[i][5];
1392 reg_ec4 = result[i][6];
1395 if (final != 0xff) {
1396 reg_e94 = result[final][0];
1397 reg_e9c = result[final][1];
1398 reg_ea4 = result[final][2];
1399 reg_eb4 = result[final][4];
1400 reg_ebc = result[final][5];
1401 dm_odm->RFCalibrateInfo.RegE94 = reg_e94;
1402 dm_odm->RFCalibrateInfo.RegE9C = reg_e9c;
1403 dm_odm->RFCalibrateInfo.RegEB4 = reg_eb4;
1404 dm_odm->RFCalibrateInfo.RegEBC = reg_ebc;
1405 reg_ec4 = result[final][6];
1409 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1410 ("IQK: FAIL use default value\n"));
1411 dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1412 dm_odm->RFCalibrateInfo.RegEB4 = 0x100;
1413 dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1414 dm_odm->RFCalibrateInfo.RegEBC = 0x0;
1417 patha_fill_iqk(adapt, pathaok, result, final,
1421 pathb_fill_iqk(adapt, pathbok, result, final,
1425 chn_index = get_right_chnl_for_iqk(hal_data->CurrentChannel);
1428 for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1429 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].Value[0][i] = result[final][i];
1430 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].bIQKDone = true;
1433 save_adda_registers(adapt, iqk_bb_reg_92c,
1434 dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1437 void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
1439 bool singletone = false, carrier_sup = false;
1440 u32 timeout = 2000, timecount = 0;
1441 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1442 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1444 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1446 if (singletone || carrier_sup)
1449 while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1454 dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1456 if (dm_odm->RFType == ODM_2T2R) {
1457 phy_lc_calibrate(adapt, true);
1460 phy_lc_calibrate(adapt, false);
1463 dm_odm->RFCalibrateInfo.bLCKInProgress = false;