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 ******************************************************************************/
15 #define _RTL8188E_PHYCFG_C_
17 #include <osdep_service.h>
18 #include <drv_types.h>
20 #include <rtl8188e_hal.h>
24 #define MAX_PRECMD_CNT 16
25 #define MAX_RFDEPENDCMD_CNT 16
26 #define MAX_POSTCMD_CNT 16
28 #define MAX_DOZE_WAITING_TIMES_9x 64
30 static u32 cal_bit_shift(u32 bitmask)
34 for (i = 0; i <= 31; i++) {
35 if (((bitmask >> i) & 0x1) == 1)
41 u32 phy_query_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask)
43 u32 original_value, bit_shift;
45 original_value = usb_read32(adapt, regaddr);
46 bit_shift = cal_bit_shift(bitmask);
47 return (original_value & bitmask) >> bit_shift;
50 void phy_set_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask, u32 data)
52 u32 original_value, bit_shift;
54 if (bitmask != bMaskDWord) { /* if not "double word" write */
55 original_value = usb_read32(adapt, regaddr);
56 bit_shift = cal_bit_shift(bitmask);
57 data = (original_value & (~bitmask)) | (data << bit_shift);
60 usb_write32(adapt, regaddr, data);
63 static u32 rf_serial_read(struct adapter *adapt,
64 enum rf_radio_path rfpath, u32 offset)
67 struct bb_reg_def *phyreg = &adapt->HalData->PHYRegDef[rfpath];
68 u32 tmplong, tmplong2;
73 tmplong = phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord);
74 if (rfpath == RF_PATH_A)
77 tmplong2 = phy_query_bb_reg(adapt, phyreg->rfHSSIPara2,
80 tmplong2 = (tmplong2 & (~bLSSIReadAddress)) |
81 (offset<<23) | bLSSIReadEdge;
83 phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord,
84 tmplong&(~bLSSIReadEdge));
87 phy_set_bb_reg(adapt, phyreg->rfHSSIPara2, bMaskDWord, tmplong2);
92 if (rfpath == RF_PATH_A)
93 rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, BIT(8));
94 else if (rfpath == RF_PATH_B)
95 rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, BIT(8));
98 ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBackPi,
101 ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBack,
106 static void rf_serial_write(struct adapter *adapt,
107 enum rf_radio_path rfpath, u32 offset,
110 u32 data_and_addr = 0;
111 struct bb_reg_def *phyreg = &adapt->HalData->PHYRegDef[rfpath];
114 data_and_addr = ((offset<<20) | (data&0x000fffff)) & 0x0fffffff;
115 phy_set_bb_reg(adapt, phyreg->rf3wireOffset, bMaskDWord, data_and_addr);
118 u32 rtw_hal_read_rfreg(struct adapter *adapt, enum rf_radio_path rf_path,
119 u32 reg_addr, u32 bit_mask)
121 u32 original_value, bit_shift;
123 original_value = rf_serial_read(adapt, rf_path, reg_addr);
124 bit_shift = cal_bit_shift(bit_mask);
125 return (original_value & bit_mask) >> bit_shift;
128 void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
129 u32 reg_addr, u32 bit_mask, u32 data)
131 u32 original_value, bit_shift;
133 /* RF data is 12 bits only */
134 if (bit_mask != bRFRegOffsetMask) {
135 original_value = rf_serial_read(adapt, rf_path, reg_addr);
136 bit_shift = cal_bit_shift(bit_mask);
137 data = (original_value & (~bit_mask)) | (data << bit_shift);
140 rf_serial_write(adapt, rf_path, reg_addr, data);
143 static void get_tx_power_index(struct adapter *adapt, u8 channel, u8 *cck_pwr,
144 u8 *ofdm_pwr, u8 *bw20_pwr, u8 *bw40_pwr)
146 struct hal_data_8188e *hal_data = adapt->HalData;
147 u8 index = (channel - 1);
148 u8 TxCount = 0, path_nums;
152 for (TxCount = 0; TxCount < path_nums; TxCount++) {
153 if (TxCount == RF_PATH_A) {
154 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
155 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
156 hal_data->OFDM_24G_Diff[TxCount][RF_PATH_A];
158 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
159 hal_data->BW20_24G_Diff[TxCount][RF_PATH_A];
160 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
161 } else if (TxCount == RF_PATH_B) {
162 cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
163 ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
164 hal_data->BW20_24G_Diff[RF_PATH_A][index]+
165 hal_data->BW20_24G_Diff[TxCount][index];
167 bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
168 hal_data->BW20_24G_Diff[TxCount][RF_PATH_A]+
169 hal_data->BW20_24G_Diff[TxCount][index];
170 bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
175 static void phy_power_index_check(struct adapter *adapt, u8 channel,
176 u8 *cck_pwr, u8 *ofdm_pwr, u8 *bw20_pwr,
179 struct hal_data_8188e *hal_data = adapt->HalData;
181 hal_data->CurrentCckTxPwrIdx = cck_pwr[0];
182 hal_data->CurrentOfdm24GTxPwrIdx = ofdm_pwr[0];
183 hal_data->CurrentBW2024GTxPwrIdx = bw20_pwr[0];
184 hal_data->CurrentBW4024GTxPwrIdx = bw40_pwr[0];
187 void phy_set_tx_power_level(struct adapter *adapt, u8 channel)
189 u8 cck_pwr[MAX_TX_COUNT] = {0};
190 u8 ofdm_pwr[MAX_TX_COUNT] = {0};/* [0]:RF-A, [1]:RF-B */
191 u8 bw20_pwr[MAX_TX_COUNT] = {0};
192 u8 bw40_pwr[MAX_TX_COUNT] = {0};
194 get_tx_power_index(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
195 &bw20_pwr[0], &bw40_pwr[0]);
197 phy_power_index_check(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
198 &bw20_pwr[0], &bw40_pwr[0]);
200 rtl88eu_phy_rf6052_set_cck_txpower(adapt, &cck_pwr[0]);
201 rtl88eu_phy_rf6052_set_ofdm_txpower(adapt, &ofdm_pwr[0], &bw20_pwr[0],
202 &bw40_pwr[0], channel);
205 static void phy_set_bw_mode_callback(struct adapter *adapt)
207 struct hal_data_8188e *hal_data = adapt->HalData;
211 if (adapt->bDriverStopped)
214 /* Set MAC register */
216 reg_bw_opmode = usb_read8(adapt, REG_BWOPMODE);
217 reg_prsr_rsc = usb_read8(adapt, REG_RRSR+2);
219 switch (hal_data->CurrentChannelBW) {
220 case HT_CHANNEL_WIDTH_20:
221 reg_bw_opmode |= BW_OPMODE_20MHZ;
222 usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode);
224 case HT_CHANNEL_WIDTH_40:
225 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
226 usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode);
227 reg_prsr_rsc = (reg_prsr_rsc&0x90) |
228 (hal_data->nCur40MhzPrimeSC<<5);
229 usb_write8(adapt, REG_RRSR+2, reg_prsr_rsc);
235 /* Set PHY related register */
236 switch (hal_data->CurrentChannelBW) {
237 case HT_CHANNEL_WIDTH_20:
238 phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x0);
239 phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x0);
241 case HT_CHANNEL_WIDTH_40:
242 phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x1);
243 phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x1);
244 /* Set Control channel to upper or lower.
245 * These settings are required only for 40MHz
247 phy_set_bb_reg(adapt, rCCK0_System, bCCKSideBand,
248 (hal_data->nCur40MhzPrimeSC>>1));
249 phy_set_bb_reg(adapt, rOFDM1_LSTF, 0xC00,
250 hal_data->nCur40MhzPrimeSC);
251 phy_set_bb_reg(adapt, 0x818, (BIT(26) | BIT(27)),
252 (hal_data->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
258 /* Set RF related register */
259 rtl88eu_phy_rf6052_set_bandwidth(adapt, hal_data->CurrentChannelBW);
262 void rtw_hal_set_bwmode(struct adapter *adapt, enum ht_channel_width bandwidth,
263 unsigned char offset)
265 struct hal_data_8188e *hal_data = adapt->HalData;
266 enum ht_channel_width tmp_bw = hal_data->CurrentChannelBW;
268 hal_data->CurrentChannelBW = bandwidth;
269 hal_data->nCur40MhzPrimeSC = offset;
271 if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
272 phy_set_bw_mode_callback(adapt);
274 hal_data->CurrentChannelBW = tmp_bw;
277 static void phy_sw_chnl_callback(struct adapter *adapt, u8 channel)
280 struct hal_data_8188e *hal_data = adapt->HalData;
282 phy_set_tx_power_level(adapt, channel);
286 hal_data->RfRegChnlVal[0] = (hal_data->RfRegChnlVal[0] &
287 0xfffffc00) | param2;
288 phy_set_rf_reg(adapt, 0, param1,
289 bRFRegOffsetMask, hal_data->RfRegChnlVal[0]);
292 void rtw_hal_set_chan(struct adapter *adapt, u8 channel)
294 struct hal_data_8188e *hal_data = adapt->HalData;
295 u8 tmpchannel = hal_data->CurrentChannel;
300 hal_data->CurrentChannel = channel;
302 if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
303 phy_sw_chnl_callback(adapt, channel);
305 hal_data->CurrentChannel = tmpchannel;
308 #define ODM_TXPWRTRACK_MAX_IDX_88E 6
310 static u8 get_right_chnl_for_iqk(u8 chnl)
313 u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
314 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
315 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
316 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153,
317 155, 157, 159, 161, 163, 165
321 for (place = 0; place < sizeof(channel_all); place++) {
322 if (channel_all[place] == chnl)
329 void rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct *dm_odm, u8 type,
330 u8 *direction, u32 *out_write_val)
333 /* Tx power tracking BB swing table. */
334 if (type == 0) { /* For OFDM adjust */
335 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
336 ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n",
337 dm_odm->BbSwingIdxOfdm, dm_odm->BbSwingFlagOfdm));
339 if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
341 pwr_value = dm_odm->BbSwingIdxOfdmBase -
342 dm_odm->BbSwingIdxOfdm;
345 pwr_value = dm_odm->BbSwingIdxOfdm -
346 dm_odm->BbSwingIdxOfdmBase;
349 } else if (type == 1) { /* For CCK adjust. */
350 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
351 ("dm_odm->BbSwingIdxCck = %d dm_odm->BbSwingIdxCckBase = %d\n",
352 dm_odm->BbSwingIdxCck, dm_odm->BbSwingIdxCckBase));
354 if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
356 pwr_value = dm_odm->BbSwingIdxCckBase -
357 dm_odm->BbSwingIdxCck;
360 pwr_value = dm_odm->BbSwingIdxCck -
361 dm_odm->BbSwingIdxCckBase;
366 if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *direction == 1)
367 pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
369 *out_write_val = pwr_value | (pwr_value<<8) | (pwr_value<<16) |
373 static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm)
375 if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
376 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
377 ("dm_txpwr_track_setpwr CH=%d\n", *(dm_odm->pChannel)));
378 phy_set_tx_power_level(dm_odm->Adapter, *(dm_odm->pChannel));
379 dm_odm->BbSwingFlagOfdm = false;
380 dm_odm->BbSwingFlagCck = false;
384 void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt)
386 struct hal_data_8188e *hal_data = adapt->HalData;
387 u8 thermal_val = 0, delta, delta_lck, delta_iqk, offset;
388 u8 thermal_avg_count = 0;
391 s8 ofdm_index[2], cck_index = 0;
392 s8 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
395 u8 ofdm_min_index = 6; /* OFDM BB Swing should be less than +3.0dB */
396 s8 ofdm_index_mapping[2][index_mapping_NUM_88E] = {
397 /* 2.4G, decrease power */
398 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
399 /* 2.4G, increase power */
400 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10},
402 u8 thermal_mapping[2][index_mapping_NUM_88E] = {
403 /* 2.4G, decrease power */
404 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
405 /* 2.4G, increase power */
406 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25},
408 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
410 dm_txpwr_track_setpwr(dm_odm);
412 dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++;
414 dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
416 thermal_val = (u8)rtw_hal_read_rfreg(adapt, RF_PATH_A,
417 RF_T_METER_88E, 0xfc00);
420 /* Query OFDM path A default setting */
421 ele_d = phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord)&bMaskOFDM_D;
422 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
423 if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) {
424 ofdm_index_old[0] = (u8)i;
425 dm_odm->BbSwingIdxOfdmBase = (u8)i;
430 /* Query CCK default setting From 0xa24 */
431 temp_cck = dm_odm->RFCalibrateInfo.RegA24;
433 for (i = 0; i < CCK_TABLE_SIZE; i++) {
434 if ((dm_odm->RFCalibrateInfo.bCCKinCH14 &&
435 memcmp(&temp_cck, &CCKSwingTable_Ch14[i][2], 4)) ||
436 memcmp(&temp_cck, &CCKSwingTable_Ch1_Ch13[i][2], 4)) {
437 cck_index_old = (u8)i;
438 dm_odm->BbSwingIdxCckBase = (u8)i;
443 if (!dm_odm->RFCalibrateInfo.ThermalValue) {
444 dm_odm->RFCalibrateInfo.ThermalValue = hal_data->EEPROMThermalMeter;
445 dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val;
446 dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val;
448 dm_odm->RFCalibrateInfo.OFDM_index[0] = ofdm_index_old[0];
449 dm_odm->RFCalibrateInfo.CCK_index = cck_index_old;
452 /* calculate average thermal meter */
453 dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = thermal_val;
454 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++;
455 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
456 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
458 for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
459 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
460 thermal_avg += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i];
465 if (thermal_avg_count)
466 thermal_val = (u8)(thermal_avg / thermal_avg_count);
468 if (dm_odm->RFCalibrateInfo.bDoneTxpower &&
469 !dm_odm->RFCalibrateInfo.bReloadtxpowerindex)
470 delta = abs(thermal_val - dm_odm->RFCalibrateInfo.ThermalValue);
472 delta = abs(thermal_val - hal_data->EEPROMThermalMeter);
473 if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) {
474 dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false;
475 dm_odm->RFCalibrateInfo.bDoneTxpower = false;
479 delta_lck = abs(dm_odm->RFCalibrateInfo.ThermalValue_LCK - thermal_val);
480 delta_iqk = abs(dm_odm->RFCalibrateInfo.ThermalValue_IQK - thermal_val);
482 /* Delta temperature is equal to or larger than 20 centigrade.*/
483 if ((delta_lck >= 8)) {
484 dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val;
485 rtl88eu_phy_lc_calibrate(adapt);
488 if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
489 delta = abs(hal_data->EEPROMThermalMeter - thermal_val);
491 /* calculate new OFDM / CCK offset */
492 if (thermal_val > hal_data->EEPROMThermalMeter)
496 for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
497 if (delta < thermal_mapping[j][offset]) {
503 if (offset >= index_mapping_NUM_88E)
504 offset = index_mapping_NUM_88E-1;
506 /* Updating ofdm_index values with new OFDM / CCK offset */
507 ofdm_index[0] = dm_odm->RFCalibrateInfo.OFDM_index[0] + ofdm_index_mapping[j][offset];
508 if (ofdm_index[0] > OFDM_TABLE_SIZE_92D-1)
509 ofdm_index[0] = OFDM_TABLE_SIZE_92D-1;
510 else if (ofdm_index[0] < ofdm_min_index)
511 ofdm_index[0] = ofdm_min_index;
513 cck_index = dm_odm->RFCalibrateInfo.CCK_index + ofdm_index_mapping[j][offset];
514 if (cck_index > CCK_TABLE_SIZE-1)
515 cck_index = CCK_TABLE_SIZE-1;
516 else if (cck_index < 0)
519 /* 2 temporarily remove bNOPG */
520 /* Config by SwingTable */
521 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
522 dm_odm->RFCalibrateInfo.bDoneTxpower = true;
524 /* Revse TX power table. */
525 dm_odm->BbSwingIdxOfdm = (u8)ofdm_index[0];
526 dm_odm->BbSwingIdxCck = (u8)cck_index;
528 if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
529 dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
530 dm_odm->BbSwingFlagOfdm = true;
533 if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
534 dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
535 dm_odm->BbSwingFlagCck = true;
540 /* Delta temperature is equal to or larger than 20 centigrade.*/
541 if (delta_iqk >= 8) {
542 dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val;
543 rtl88eu_phy_iq_calibrate(adapt, false);
545 /* update thermal meter value */
546 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
547 dm_odm->RFCalibrateInfo.ThermalValue = thermal_val;
549 dm_odm->RFCalibrateInfo.TXPowercount = 0;
552 #define MAX_TOLERANCE 5
554 static u8 phy_path_a_iqk(struct adapter *adapt, bool config_pathb)
556 u32 reg_eac, reg_e94, reg_e9c;
560 /* path-A IQK setting */
561 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
562 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
563 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x8214032a);
564 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
566 /* LO calibration setting */
567 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
569 /* One shot, path A LOK & IQK */
570 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
571 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
573 mdelay(IQK_DELAY_TIME_88E);
575 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
576 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
577 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
579 if (!(reg_eac & BIT(28)) &&
580 (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
581 (((reg_e9c & 0x03FF0000)>>16) != 0x42))
586 static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB)
588 u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
590 struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
592 /* 1 Get TXIMR setting */
593 /* modify RXIQK mode table */
594 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
595 phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
596 phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
597 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
598 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
601 phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
602 phy_set_rf_reg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
604 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
607 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
608 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
610 /* path-A IQK setting */
611 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
612 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
613 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
614 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
616 /* LO calibration setting */
617 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
619 /* One shot, path A LOK & IQK */
620 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
621 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
624 mdelay(IQK_DELAY_TIME_88E);
627 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
628 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
629 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
631 if (!(reg_eac & BIT(28)) &&
632 (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
633 (((reg_e9c & 0x03FF0000)>>16) != 0x42))
635 else /* if Tx not OK, ignore Rx */
638 u4tmp = 0x80007C00 | (reg_e94&0x3FF0000) | ((reg_e9c&0x3FF0000) >> 16);
639 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, u4tmp);
642 /* modify RXIQK mode table */
643 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
644 ("Path-A Rx IQK modify RXIQK mode table 2!\n"));
645 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
646 phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
647 phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
648 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
649 phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
650 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
653 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
655 /* path-A IQK setting */
656 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
657 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
658 phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
659 phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
661 /* LO calibration setting */
662 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
664 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
665 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
667 mdelay(IQK_DELAY_TIME_88E);
670 reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
671 reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
672 reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
673 reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
676 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
677 phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
679 if (!(reg_eac & BIT(27)) && /* if Tx is OK, check whether Rx is OK */
680 (((reg_ea4 & 0x03FF0000)>>16) != 0x132) &&
681 (((reg_eac & 0x03FF0000)>>16) != 0x36))
684 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
685 ("Path A Rx IQK fail!!\n"));
690 static u8 phy_path_b_iqk(struct adapter *adapt)
692 u32 regeac, regeb4, regebc, regec4, regecc;
694 struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
696 /* One shot, path B LOK & IQK */
697 phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
698 phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000000);
700 mdelay(IQK_DELAY_TIME_88E);
702 regeac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
703 regeb4 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, bMaskDWord);
704 regebc = phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, bMaskDWord);
705 regec4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2, bMaskDWord);
706 regecc = phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2, bMaskDWord);
708 if (!(regeac & BIT(31)) &&
709 (((regeb4 & 0x03FF0000)>>16) != 0x142) &&
710 (((regebc & 0x03FF0000)>>16) != 0x42))
715 if (!(regeac & BIT(30)) &&
716 (((regec4 & 0x03FF0000)>>16) != 0x132) &&
717 (((regecc & 0x03FF0000)>>16) != 0x36))
720 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION,
721 ODM_DBG_LOUD, ("Path B Rx IQK fail!!\n"));
725 static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
726 u8 final_candidate, bool txonly)
728 u32 oldval_0, x, tx0_a, reg;
731 if (final_candidate == 0xFF) {
734 oldval_0 = (phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
736 x = result[final_candidate][0];
737 if ((x & 0x00000200) != 0)
740 tx0_a = (x * oldval_0) >> 8;
741 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, tx0_a);
742 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(31),
743 ((x * oldval_0>>7) & 0x1));
745 y = result[final_candidate][1];
746 if ((y & 0x00000200) != 0)
749 tx0_c = (y * oldval_0) >> 8;
750 phy_set_bb_reg(adapt, rOFDM0_XCTxAFE, 0xF0000000,
752 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000,
754 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(29),
755 ((y * oldval_0>>7) & 0x1));
760 reg = result[final_candidate][2];
761 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
763 reg = result[final_candidate][3] & 0x3F;
764 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
766 reg = (result[final_candidate][3] >> 6) & 0xF;
767 phy_set_bb_reg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
771 static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
772 u8 final_candidate, bool txonly)
774 u32 oldval_1, x, tx1_a, reg;
777 if (final_candidate == 0xFF) {
780 oldval_1 = (phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
782 x = result[final_candidate][4];
783 if ((x & 0x00000200) != 0)
785 tx1_a = (x * oldval_1) >> 8;
786 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x3FF, tx1_a);
788 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(27),
789 ((x * oldval_1>>7) & 0x1));
791 y = result[final_candidate][5];
792 if ((y & 0x00000200) != 0)
795 tx1_c = (y * oldval_1) >> 8;
797 phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, 0xF0000000,
799 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x003F0000,
801 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(25),
802 ((y * oldval_1>>7) & 0x1));
807 reg = result[final_candidate][6];
808 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
810 reg = result[final_candidate][7] & 0x3F;
811 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
813 reg = (result[final_candidate][7] >> 6) & 0xF;
814 phy_set_bb_reg(adapt, rOFDM0_AGCRSSITable, 0x0000F000, reg);
818 static void save_adda_registers(struct adapter *adapt, u32 *addareg,
819 u32 *backup, u32 register_num)
823 for (i = 0; i < register_num; i++) {
824 backup[i] = phy_query_bb_reg(adapt, addareg[i], bMaskDWord);
828 static void save_mac_registers(struct adapter *adapt, u32 *mac_reg,
833 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
834 backup[i] = usb_read8(adapt, mac_reg[i]);
836 backup[i] = usb_read32(adapt, mac_reg[i]);
839 static void reload_adda_reg(struct adapter *adapt, u32 *adda_reg,
840 u32 *backup, u32 regiester_num)
844 for (i = 0; i < regiester_num; i++)
845 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, backup[i]);
848 static void reload_mac_registers(struct adapter *adapt,
849 u32 *mac_reg, u32 *backup)
853 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
854 usb_write8(adapt, mac_reg[i], (u8)backup[i]);
856 usb_write32(adapt, mac_reg[i], backup[i]);
859 static void path_adda_on(struct adapter *adapt, u32 *adda_reg,
860 bool is_path_a_on, bool is2t)
866 path_on = 0x0bdb25a0;
867 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, 0x0b1b25a0);
869 path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4;
870 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, path_on);
873 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
874 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, path_on);
877 static void mac_setting_calibration(struct adapter *adapt, u32 *mac_reg, u32 *backup)
881 usb_write8(adapt, mac_reg[i], 0x3F);
883 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
884 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(3))));
886 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(5))));
889 static void path_a_standby(struct adapter *adapt)
892 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x0);
893 phy_set_bb_reg(adapt, 0x840, bMaskDWord, 0x00010000);
894 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
897 static void pi_mode_switch(struct adapter *adapt, bool pi_mode)
901 mode = pi_mode ? 0x01000100 : 0x01000000;
902 phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
903 phy_set_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
906 static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
909 u32 i, j, diff, sim_bitmap = 0, bound;
910 u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
912 s32 tmp1 = 0, tmp2 = 0;
916 for (i = 0; i < bound; i++) {
917 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
918 if ((resulta[c1][i] & 0x00000200) != 0)
919 tmp1 = resulta[c1][i] | 0xFFFFFC00;
921 tmp1 = resulta[c1][i];
923 if ((resulta[c2][i] & 0x00000200) != 0)
924 tmp2 = resulta[c2][i] | 0xFFFFFC00;
926 tmp2 = resulta[c2][i];
928 tmp1 = resulta[c1][i];
929 tmp2 = resulta[c2][i];
932 diff = abs(tmp1 - tmp2);
934 if (diff > MAX_TOLERANCE) {
935 if ((i == 2 || i == 6) && !sim_bitmap) {
936 if (resulta[c1][i] + resulta[c1][i+1] == 0)
937 final_candidate[(i/4)] = c2;
938 else if (resulta[c2][i] + resulta[c2][i+1] == 0)
939 final_candidate[(i/4)] = c1;
941 sim_bitmap = sim_bitmap | (1<<i);
943 sim_bitmap = sim_bitmap | (1<<i);
948 if (sim_bitmap == 0) {
949 for (i = 0; i < (bound/4); i++) {
950 if (final_candidate[i] != 0xFF) {
951 for (j = i*4; j < (i+1)*4-2; j++)
952 resulta[3][j] = resulta[final_candidate[i]][j];
958 if (!(sim_bitmap & 0x03)) { /* path A TX OK */
959 for (i = 0; i < 2; i++)
960 resulta[3][i] = resulta[c1][i];
962 if (!(sim_bitmap & 0x0c)) { /* path A RX OK */
963 for (i = 2; i < 4; i++)
964 resulta[3][i] = resulta[c1][i];
967 if (!(sim_bitmap & 0x30)) { /* path B TX OK */
968 for (i = 4; i < 6; i++)
969 resulta[3][i] = resulta[c1][i];
972 if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
973 for (i = 6; i < 8; i++)
974 resulta[3][i] = resulta[c1][i];
980 static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
983 struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
985 u8 path_a_ok, path_b_ok;
986 u32 adda_reg[IQK_ADDA_REG_NUM] = {
987 rFPGA0_XCD_SwitchControl, rBlue_Tooth,
988 rRx_Wait_CCA, rTx_CCK_RFON,
989 rTx_CCK_BBON, rTx_OFDM_RFON,
990 rTx_OFDM_BBON, rTx_To_Rx,
992 rRx_OFDM, rRx_Wait_RIFS,
994 rSleep, rPMPD_ANAEN};
996 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
997 REG_TXPAUSE, REG_BCN_CTRL,
998 REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
1000 /* since 92C & 92D have the different define in IQK_BB_REG */
1001 u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1002 rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
1003 rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
1004 rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
1005 rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD};
1007 u32 retry_count = 9;
1009 if (*(dm_odm->mp_mode) == 1)
1016 /* Save ADDA parameters, turn Path A ADDA on */
1017 save_adda_registers(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1019 save_mac_registers(adapt, iqk_mac_reg,
1020 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1021 save_adda_registers(adapt, iqk_bb_reg_92c,
1022 dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1025 path_adda_on(adapt, adda_reg, true, is2t);
1027 dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1,
1030 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1031 /* Switch BB to PI mode to do IQ Calibration. */
1032 pi_mode_switch(adapt, true);
1036 phy_set_bb_reg(adapt, rFPGA0_RFMOD, BIT(24), 0x00);
1037 phy_set_bb_reg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1038 phy_set_bb_reg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1039 phy_set_bb_reg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1041 phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01);
1042 phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01);
1043 phy_set_bb_reg(adapt, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00);
1044 phy_set_bb_reg(adapt, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00);
1047 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord,
1049 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, bMaskDWord,
1054 mac_setting_calibration(adapt, iqk_mac_reg,
1055 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1059 phy_set_bb_reg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
1062 phy_set_bb_reg(adapt, rConfig_AntB, bMaskDWord, 0x0f600000);
1064 /* IQ calibration setting */
1065 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
1066 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
1067 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
1069 for (i = 0; i < retry_count; i++) {
1070 path_a_ok = phy_path_a_iqk(adapt, is2t);
1071 if (path_a_ok == 0x01) {
1072 result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A,
1073 bMaskDWord)&0x3FF0000)>>16;
1074 result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A,
1075 bMaskDWord)&0x3FF0000)>>16;
1080 for (i = 0; i < retry_count; i++) {
1081 path_a_ok = phy_path_a_rx_iqk(adapt, is2t);
1082 if (path_a_ok == 0x03) {
1083 result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2,
1084 bMaskDWord)&0x3FF0000)>>16;
1085 result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2,
1086 bMaskDWord)&0x3FF0000)>>16;
1089 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1090 ("Path A Rx IQK Fail!!\n"));
1094 if (path_a_ok == 0x00) {
1095 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1096 ("Path A IQK failed!!\n"));
1100 path_a_standby(adapt);
1102 /* Turn Path B ADDA on */
1103 path_adda_on(adapt, adda_reg, false, is2t);
1105 for (i = 0; i < retry_count; i++) {
1106 path_b_ok = phy_path_b_iqk(adapt);
1107 if (path_b_ok == 0x03) {
1108 result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1109 bMaskDWord)&0x3FF0000)>>16;
1110 result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1111 bMaskDWord)&0x3FF0000)>>16;
1112 result[t][6] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2,
1113 bMaskDWord)&0x3FF0000)>>16;
1114 result[t][7] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2,
1115 bMaskDWord)&0x3FF0000)>>16;
1117 } else if (i == (retry_count - 1) && path_b_ok == 0x01) { /* Tx IQK OK */
1118 result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1119 bMaskDWord)&0x3FF0000)>>16;
1120 result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1121 bMaskDWord)&0x3FF0000)>>16;
1125 if (path_b_ok == 0x00) {
1126 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1127 ("Path B IQK failed!!\n"));
1131 /* Back to BB mode, load original value */
1132 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0);
1135 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1136 /* Switch back BB to SI mode after
1137 * finish IQ Calibration.
1139 pi_mode_switch(adapt, false);
1142 /* Reload ADDA power saving parameters */
1143 reload_adda_reg(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1146 /* Reload MAC parameters */
1147 reload_mac_registers(adapt, iqk_mac_reg,
1148 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1150 reload_adda_reg(adapt, iqk_bb_reg_92c, dm_odm->RFCalibrateInfo.IQK_BB_backup,
1153 /* Restore RX initial gain */
1154 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter,
1155 bMaskDWord, 0x00032ed3);
1157 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter,
1158 bMaskDWord, 0x00032ed3);
1160 /* load 0xe30 IQC default value */
1161 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1162 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1166 static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
1169 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1171 /* Check continuous TX and Packet TX */
1172 tmpreg = usb_read8(adapt, 0xd03);
1174 if ((tmpreg&0x70) != 0)
1175 usb_write8(adapt, 0xd03, tmpreg&0x8F);
1177 usb_write8(adapt, REG_TXPAUSE, 0xFF);
1179 if ((tmpreg&0x70) != 0) {
1180 /* 1. Read original RF mode */
1182 rf_a_mode = rtw_hal_read_rfreg(adapt, RF_PATH_A, RF_AC,
1187 rf_b_mode = rtw_hal_read_rfreg(adapt, RF_PATH_B, RF_AC,
1190 /* 2. Set RF mode = standby mode */
1192 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits,
1193 (rf_a_mode&0x8FFFF)|0x10000);
1197 phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1198 (rf_b_mode&0x8FFFF)|0x10000);
1201 /* 3. Read RF reg18 */
1202 lc_cal = rtw_hal_read_rfreg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1204 /* 4. Set LC calibration begin bit15 */
1205 phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits,
1210 /* Restore original situation */
1211 if ((tmpreg&0x70) != 0) {
1212 /* Deal with continuous TX case */
1214 usb_write8(adapt, 0xd03, tmpreg);
1215 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, rf_a_mode);
1219 phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1222 /* Deal with Packet TX case */
1223 usb_write8(adapt, REG_TXPAUSE, 0x00);
1227 void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
1229 struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
1231 u8 i, final, chn_index;
1232 bool pathaok, pathbok;
1233 s32 reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4;
1234 bool is12simular, is13simular, is23simular;
1235 bool singletone = false, carrier_sup = false;
1236 u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1237 rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1238 rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1239 rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1240 rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1241 rOFDM0_RxIQExtAnta};
1246 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1249 if (singletone || carrier_sup)
1253 ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
1254 ("phy_iq_calibrate: Return due to recovery!\n"));
1255 reload_adda_reg(adapt, iqk_bb_reg_92c,
1256 dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1260 for (i = 0; i < 8; i++) {
1264 if ((i == 0) || (i == 2) || (i == 4) || (i == 6))
1265 result[3][i] = 0x100;
1272 is12simular = false;
1273 is23simular = false;
1274 is13simular = false;
1276 for (i = 0; i < 3; i++) {
1277 phy_iq_calibrate(adapt, result, i, is2t);
1280 is12simular = simularity_compare(adapt, result, 0, 1);
1288 is13simular = simularity_compare(adapt, result, 0, 2);
1293 is23simular = simularity_compare(adapt, result, 1, 2);
1301 for (i = 0; i < 4; i++) {
1302 reg_e94 = result[i][0];
1303 reg_e9c = result[i][1];
1304 reg_ea4 = result[i][2];
1305 reg_eb4 = result[i][4];
1306 reg_ebc = result[i][5];
1307 reg_ec4 = result[i][6];
1310 if (final != 0xff) {
1311 reg_e94 = result[final][0];
1312 reg_e9c = result[final][1];
1313 reg_ea4 = result[final][2];
1314 reg_eb4 = result[final][4];
1315 reg_ebc = result[final][5];
1316 dm_odm->RFCalibrateInfo.RegE94 = reg_e94;
1317 dm_odm->RFCalibrateInfo.RegE9C = reg_e9c;
1318 dm_odm->RFCalibrateInfo.RegEB4 = reg_eb4;
1319 dm_odm->RFCalibrateInfo.RegEBC = reg_ebc;
1320 reg_ec4 = result[final][6];
1324 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1325 ("IQK: FAIL use default value\n"));
1326 dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1327 dm_odm->RFCalibrateInfo.RegEB4 = 0x100;
1328 dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1329 dm_odm->RFCalibrateInfo.RegEBC = 0x0;
1332 patha_fill_iqk(adapt, pathaok, result, final,
1336 pathb_fill_iqk(adapt, pathbok, result, final,
1340 chn_index = get_right_chnl_for_iqk(adapt->HalData->CurrentChannel);
1343 for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1344 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].Value[0][i] = result[final][i];
1345 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].bIQKDone = true;
1348 save_adda_registers(adapt, iqk_bb_reg_92c,
1349 dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1352 void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
1354 bool singletone = false, carrier_sup = false;
1355 u32 timeout = 2000, timecount = 0;
1356 struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
1358 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1360 if (singletone || carrier_sup)
1363 while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1368 dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1370 phy_lc_calibrate(adapt, false);
1372 dm_odm->RFCalibrateInfo.bLCKInProgress = false;