linux/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*****************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7
   8#include <drv_types.h>
   9#include <rtw_debug.h>
  10#include "odm_precomp.h"
  11
  12
  13
  14/*---------------------------Define Local Constant---------------------------*/
  15/*  2010/04/25 MH Define the max tx power tracking tx agc power. */
  16#define         ODM_TXPWRTRACK_MAX_IDX8723B     6
  17
  18/*  MACRO definition for pRFCalibrateInfo->TxIQC_8723B[0] */
  19#define         PATH_S0                                                 1 /*  RF_PATH_B */
  20#define         IDX_0xC94                                               0
  21#define         IDX_0xC80                                               1
  22#define         IDX_0xC4C                                               2
  23#define         IDX_0xC14                                               0
  24#define         IDX_0xCA0                                               1
  25#define         KEY                                                     0
  26#define         VAL                                                     1
  27
  28/*  MACRO definition for pRFCalibrateInfo->TxIQC_8723B[1] */
  29#define         PATH_S1                                                 0 /*  RF_PATH_A */
  30#define         IDX_0xC9C                                               0
  31#define         IDX_0xC88                                               1
  32#define         IDX_0xC4C                                               2
  33#define         IDX_0xC1C                                               0
  34#define         IDX_0xC78                                               1
  35
  36
  37/*---------------------------Define Local Constant---------------------------*/
  38
  39/* In the case that we fail to read TxPowerTrack.txt, we use the table for
  40 * 88E as the default table.
  41 */
  42static u8 DeltaSwingTableIdx_2GA_N_8188E[] = {
  43        0, 0, 0, 2, 2, 3, 3, 4,  4,  4,  4,  5,  5,  6,  6,
  44        7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11
  45};
  46static u8 DeltaSwingTableIdx_2GA_P_8188E[] = {
  47        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4,
  48        4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9
  49};
  50
  51/* 3 ============================================================ */
  52/* 3 Tx Power Tracking */
  53/* 3 ============================================================ */
  54
  55
  56static void setIqkMatrix_8723B(
  57        struct dm_odm_t *pDM_Odm,
  58        u8 OFDM_index,
  59        u8 RFPath,
  60        s32 IqkResult_X,
  61        s32 IqkResult_Y
  62)
  63{
  64        s32 ele_A = 0, ele_D, ele_C = 0, value32;
  65
  66        if (OFDM_index >= OFDM_TABLE_SIZE)
  67                OFDM_index = OFDM_TABLE_SIZE-1;
  68
  69        ele_D = (OFDMSwingTable_New[OFDM_index] & 0xFFC00000)>>22;
  70
  71        /* new element A = element D x X */
  72        if (IqkResult_X != 0) {
  73                if ((IqkResult_X & 0x00000200) != 0)    /* consider minus */
  74                        IqkResult_X = IqkResult_X | 0xFFFFFC00;
  75                ele_A = ((IqkResult_X * ele_D)>>8)&0x000003FF;
  76
  77                /* new element C = element D x Y */
  78                if ((IqkResult_Y & 0x00000200) != 0)
  79                        IqkResult_Y = IqkResult_Y | 0xFFFFFC00;
  80                ele_C = ((IqkResult_Y * ele_D)>>8)&0x000003FF;
  81
  82                /* if (RFPath == ODM_RF_PATH_A) */
  83                switch (RFPath) {
  84                case ODM_RF_PATH_A:
  85                        /* write new elements A, C, D to regC80 and regC94,
  86                         * element B is always 0
  87                         */
  88                        value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A;
  89                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, value32);
  90
  91                        value32 = (ele_C&0x000003C0)>>6;
  92                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, value32);
  93
  94                        value32 = ((IqkResult_X * ele_D)>>7)&0x01;
  95                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT24, value32);
  96                        break;
  97                case ODM_RF_PATH_B:
  98                        /* write new elements A, C, D to regC88 and regC9C,
  99                         * element B is always 0
 100                         */
 101                        value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A;
 102                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
 103
 104                        value32 = (ele_C&0x000003C0)>>6;
 105                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
 106
 107                        value32 = ((IqkResult_X * ele_D)>>7)&0x01;
 108                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT28, value32);
 109
 110                        break;
 111                default:
 112                        break;
 113                }
 114        } else {
 115                switch (RFPath) {
 116                case ODM_RF_PATH_A:
 117                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable_New[OFDM_index]);
 118                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00);
 119                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT24, 0x00);
 120                        break;
 121
 122                case ODM_RF_PATH_B:
 123                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable_New[OFDM_index]);
 124                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
 125                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT28, 0x00);
 126                        break;
 127
 128                default:
 129                        break;
 130                }
 131        }
 132}
 133
 134
 135static void setCCKFilterCoefficient(struct dm_odm_t *pDM_Odm, u8 CCKSwingIndex)
 136{
 137        if (!pDM_Odm->RFCalibrateInfo.bCCKinCH14) {
 138                rtw_write8(pDM_Odm->Adapter, 0xa22, CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][0]);
 139                rtw_write8(pDM_Odm->Adapter, 0xa23, CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][1]);
 140                rtw_write8(pDM_Odm->Adapter, 0xa24, CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][2]);
 141                rtw_write8(pDM_Odm->Adapter, 0xa25, CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][3]);
 142                rtw_write8(pDM_Odm->Adapter, 0xa26, CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][4]);
 143                rtw_write8(pDM_Odm->Adapter, 0xa27, CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][5]);
 144                rtw_write8(pDM_Odm->Adapter, 0xa28, CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][6]);
 145                rtw_write8(pDM_Odm->Adapter, 0xa29, CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][7]);
 146        } else {
 147                rtw_write8(pDM_Odm->Adapter, 0xa22, CCKSwingTable_Ch14_New[CCKSwingIndex][0]);
 148                rtw_write8(pDM_Odm->Adapter, 0xa23, CCKSwingTable_Ch14_New[CCKSwingIndex][1]);
 149                rtw_write8(pDM_Odm->Adapter, 0xa24, CCKSwingTable_Ch14_New[CCKSwingIndex][2]);
 150                rtw_write8(pDM_Odm->Adapter, 0xa25, CCKSwingTable_Ch14_New[CCKSwingIndex][3]);
 151                rtw_write8(pDM_Odm->Adapter, 0xa26, CCKSwingTable_Ch14_New[CCKSwingIndex][4]);
 152                rtw_write8(pDM_Odm->Adapter, 0xa27, CCKSwingTable_Ch14_New[CCKSwingIndex][5]);
 153                rtw_write8(pDM_Odm->Adapter, 0xa28, CCKSwingTable_Ch14_New[CCKSwingIndex][6]);
 154                rtw_write8(pDM_Odm->Adapter, 0xa29, CCKSwingTable_Ch14_New[CCKSwingIndex][7]);
 155        }
 156}
 157
 158void DoIQK_8723B(
 159        struct dm_odm_t *pDM_Odm,
 160        u8 DeltaThermalIndex,
 161        u8 ThermalValue,
 162        u8 Threshold
 163)
 164{
 165}
 166
 167/*-----------------------------------------------------------------------------
 168 * Function:    odm_TxPwrTrackSetPwr88E()
 169 *
 170 * Overview:    88E change all channel tx power according to flag.
 171 *                      OFDM & CCK are all different.
 172 *
 173 * Input:               NONE
 174 *
 175 * Output:              NONE
 176 *
 177 * Return:              NONE
 178 *
 179 * Revised History:
 180 *When          Who     Remark
 181 *04/23/2012    MHC     Create Version 0.
 182 *
 183 *---------------------------------------------------------------------------*/
 184void ODM_TxPwrTrackSetPwr_8723B(
 185        struct dm_odm_t *pDM_Odm,
 186        enum pwrtrack_method Method,
 187        u8 RFPath,
 188        u8 ChannelMappedIndex
 189)
 190{
 191        struct adapter *Adapter = pDM_Odm->Adapter;
 192        struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
 193        u8 PwrTrackingLimit_OFDM = 34; /* 0dB */
 194        u8 PwrTrackingLimit_CCK = 28; /* 2dB */
 195        u8 TxRate = 0xFF;
 196        u8 Final_OFDM_Swing_Index = 0;
 197        u8 Final_CCK_Swing_Index = 0;
 198
 199        {
 200                u16 rate = *(pDM_Odm->pForcedDataRate);
 201
 202                if (!rate) { /* auto rate */
 203                        if (pDM_Odm->TxRate != 0xFF)
 204                                TxRate = HwRateToMRate(pDM_Odm->TxRate);
 205                } else /* force rate */
 206                        TxRate = (u8)rate;
 207
 208        }
 209
 210        if (TxRate != 0xFF) {
 211                /* 2 CCK */
 212                if ((TxRate >= MGN_1M) && (TxRate <= MGN_11M))
 213                        PwrTrackingLimit_CCK = 28;      /* 2dB */
 214                /* 2 OFDM */
 215                else if ((TxRate >= MGN_6M) && (TxRate <= MGN_48M))
 216                        PwrTrackingLimit_OFDM = 36; /* 3dB */
 217                else if (TxRate == MGN_54M)
 218                        PwrTrackingLimit_OFDM = 34; /* 2dB */
 219
 220                /* 2 HT */
 221                else if ((TxRate >= MGN_MCS0) && (TxRate <= MGN_MCS2)) /* QPSK/BPSK */
 222                        PwrTrackingLimit_OFDM = 38; /* 4dB */
 223                else if ((TxRate >= MGN_MCS3) && (TxRate <= MGN_MCS4)) /* 16QAM */
 224                        PwrTrackingLimit_OFDM = 36; /* 3dB */
 225                else if ((TxRate >= MGN_MCS5) && (TxRate <= MGN_MCS7)) /* 64QAM */
 226                        PwrTrackingLimit_OFDM = 34; /* 2dB */
 227
 228                else
 229                        PwrTrackingLimit_OFDM =  pDM_Odm->DefaultOfdmIndex;   /* Default OFDM index = 30 */
 230        }
 231
 232        if (Method == TXAGC) {
 233                struct adapter *Adapter = pDM_Odm->Adapter;
 234
 235                pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
 236
 237                pDM_Odm->Modify_TxAGC_Flag_PathA = true;
 238                pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = true;
 239
 240                PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, CCK);
 241                PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM);
 242                PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7);
 243        } else if (Method == BBSWING) {
 244                Final_OFDM_Swing_Index = pDM_Odm->DefaultOfdmIndex + pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
 245                Final_CCK_Swing_Index = pDM_Odm->DefaultCckIndex + pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
 246
 247                /*  Adjust BB swing by OFDM IQ matrix */
 248                if (Final_OFDM_Swing_Index >= PwrTrackingLimit_OFDM)
 249                        Final_OFDM_Swing_Index = PwrTrackingLimit_OFDM;
 250                else if (Final_OFDM_Swing_Index <= 0)
 251                        Final_OFDM_Swing_Index = 0;
 252
 253                if (Final_CCK_Swing_Index >= CCK_TABLE_SIZE)
 254                        Final_CCK_Swing_Index = CCK_TABLE_SIZE-1;
 255                else if (pDM_Odm->BbSwingIdxCck <= 0)
 256                        Final_CCK_Swing_Index = 0;
 257
 258                setIqkMatrix_8723B(pDM_Odm, Final_OFDM_Swing_Index, RFPath,
 259                        pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0],
 260                        pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]);
 261
 262                setCCKFilterCoefficient(pDM_Odm, Final_CCK_Swing_Index);
 263
 264        } else if (Method == MIX_MODE) {
 265                Final_OFDM_Swing_Index = pDM_Odm->DefaultOfdmIndex + pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
 266                Final_CCK_Swing_Index = pDM_Odm->DefaultCckIndex + pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
 267
 268                if (Final_OFDM_Swing_Index > PwrTrackingLimit_OFDM) { /* BBSwing higher then Limit */
 269                        pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index - PwrTrackingLimit_OFDM;
 270
 271                        setIqkMatrix_8723B(pDM_Odm, PwrTrackingLimit_OFDM, RFPath,
 272                                pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0],
 273                                pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]);
 274
 275                        pDM_Odm->Modify_TxAGC_Flag_PathA = true;
 276                        PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM);
 277                        PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7);
 278                } else if (Final_OFDM_Swing_Index <= 0) {
 279                        pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index;
 280
 281                        setIqkMatrix_8723B(pDM_Odm, 0, RFPath,
 282                                pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0],
 283                                pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]);
 284
 285                        pDM_Odm->Modify_TxAGC_Flag_PathA = true;
 286                        PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM);
 287                        PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7);
 288                } else {
 289                        setIqkMatrix_8723B(pDM_Odm, Final_OFDM_Swing_Index, RFPath,
 290                                pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0],
 291                                pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]);
 292
 293                        if (pDM_Odm->Modify_TxAGC_Flag_PathA) { /* If TxAGC has changed, reset TxAGC again */
 294                                pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = 0;
 295                                PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM);
 296                                PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7);
 297                                pDM_Odm->Modify_TxAGC_Flag_PathA = false;
 298                        }
 299                }
 300
 301                if (Final_CCK_Swing_Index > PwrTrackingLimit_CCK) {
 302                        pDM_Odm->Remnant_CCKSwingIdx = Final_CCK_Swing_Index - PwrTrackingLimit_CCK;
 303                        setCCKFilterCoefficient(pDM_Odm, PwrTrackingLimit_CCK);
 304                        pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = true;
 305                        PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, CCK);
 306                } else if (Final_CCK_Swing_Index <= 0) { /*  Lowest CCK Index = 0 */
 307                        pDM_Odm->Remnant_CCKSwingIdx = Final_CCK_Swing_Index;
 308                        setCCKFilterCoefficient(pDM_Odm, 0);
 309                        pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = true;
 310                        PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, CCK);
 311                } else {
 312                        setCCKFilterCoefficient(pDM_Odm, Final_CCK_Swing_Index);
 313
 314                        if (pDM_Odm->Modify_TxAGC_Flag_PathA_CCK) { /* If TxAGC has changed, reset TxAGC again */
 315                                pDM_Odm->Remnant_CCKSwingIdx = 0;
 316                                PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, CCK);
 317                                pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = false;
 318                        }
 319                }
 320        } else
 321                return; /*  This method is not supported. */
 322}
 323
 324static void GetDeltaSwingTable_8723B(
 325        struct dm_odm_t *pDM_Odm,
 326        u8 **TemperatureUP_A,
 327        u8 **TemperatureDOWN_A,
 328        u8 **TemperatureUP_B,
 329        u8 **TemperatureDOWN_B
 330)
 331{
 332        struct adapter *Adapter = pDM_Odm->Adapter;
 333        struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
 334        struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
 335        u16 rate = *(pDM_Odm->pForcedDataRate);
 336        u8 channel = pHalData->CurrentChannel;
 337
 338        if (1 <= channel && channel <= 14) {
 339                if (IS_CCK_RATE(rate)) {
 340                        *TemperatureUP_A   = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P;
 341                        *TemperatureDOWN_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N;
 342                        *TemperatureUP_B   = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P;
 343                        *TemperatureDOWN_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N;
 344                } else {
 345                        *TemperatureUP_A   = pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P;
 346                        *TemperatureDOWN_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N;
 347                        *TemperatureUP_B   = pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P;
 348                        *TemperatureDOWN_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N;
 349                }
 350        } else {
 351                *TemperatureUP_A   = (u8 *)DeltaSwingTableIdx_2GA_P_8188E;
 352                *TemperatureDOWN_A = (u8 *)DeltaSwingTableIdx_2GA_N_8188E;
 353                *TemperatureUP_B   = (u8 *)DeltaSwingTableIdx_2GA_P_8188E;
 354                *TemperatureDOWN_B = (u8 *)DeltaSwingTableIdx_2GA_N_8188E;
 355        }
 356}
 357
 358
 359void ConfigureTxpowerTrack_8723B(struct txpwrtrack_cfg *pConfig)
 360{
 361        pConfig->SwingTableSize_CCK = CCK_TABLE_SIZE;
 362        pConfig->SwingTableSize_OFDM = OFDM_TABLE_SIZE;
 363        pConfig->Threshold_IQK = IQK_THRESHOLD;
 364        pConfig->AverageThermalNum = AVG_THERMAL_NUM_8723B;
 365        pConfig->RfPathCount = MAX_PATH_NUM_8723B;
 366        pConfig->ThermalRegAddr = RF_T_METER_8723B;
 367
 368        pConfig->ODM_TxPwrTrackSetPwr = ODM_TxPwrTrackSetPwr_8723B;
 369        pConfig->DoIQK = DoIQK_8723B;
 370        pConfig->PHY_LCCalibrate = PHY_LCCalibrate_8723B;
 371        pConfig->GetDeltaSwingTable = GetDeltaSwingTable_8723B;
 372}
 373
 374/* 1 7. IQK */
 375#define MAX_TOLERANCE           5
 376#define IQK_DELAY_TIME          1               /* ms */
 377
 378/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 379static u8 phy_PathA_IQK_8723B(
 380        struct adapter *padapter, bool configPathB, u8 RF_Path
 381)
 382{
 383        u32 regEAC, regE94, regE9C, tmp, Path_SEL_BB /*, regEA4*/;
 384        u8 result = 0x00;
 385
 386        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
 387        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
 388
 389        /*  Save RF Path */
 390        Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord);
 391
 392        /* leave IQK mode */
 393        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 394
 395        /*      enable path A PA in TXIQK mode */
 396        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
 397        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
 398        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0003f);
 399        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xc7f87);
 400        /*      disable path B PA in TXIQK mode */
 401/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xed, bRFRegOffsetMask, 0x00020); */
 402/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x43, bRFRegOffsetMask, 0x40ec1); */
 403
 404        /* 1 Tx IQK */
 405        /* IQK setting */
 406        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, 0x01007c00);
 407        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
 408        /* path-A IQK setting */
 409        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
 410        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
 411        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 412        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 413/*      PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x8214010a); */
 414        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x821303ea);
 415        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
 416        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
 417        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
 418
 419        /* LO calibration setting */
 420        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
 421
 422        /* enter IQK mode */
 423        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
 424
 425        /* Ant switch */
 426        if (configPathB || (RF_Path == 0))
 427                /*  wifi switch to S1 */
 428                PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000000);
 429        else
 430                /*  wifi switch to S0 */
 431                PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
 432
 433        /* GNT_BT = 0 */
 434        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
 435
 436        /* One shot, path A LOK & IQK */
 437        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 438        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 439
 440        /*  delay x ms */
 441        /* PlatformStallExecution(IQK_DELAY_TIME_8723B*1000); */
 442        mdelay(IQK_DELAY_TIME_8723B);
 443
 444        /* restore Ant Path */
 445        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
 446        /* GNT_BT = 1 */
 447        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
 448
 449        /* leave IQK mode */
 450        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 451
 452
 453        /*  Check failed */
 454        regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
 455        regE94 = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord);
 456        regE9C = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord);
 457
 458
 459        /* Allen 20131125 */
 460        tmp = (regE9C & 0x03FF0000)>>16;
 461        if ((tmp & 0x200) > 0)
 462                tmp = 0x400 - tmp;
 463
 464        if (
 465                !(regEAC & BIT28) &&
 466                (((regE94 & 0x03FF0000)>>16) != 0x142) &&
 467                (((regE9C & 0x03FF0000)>>16) != 0x42) &&
 468                (((regE94 & 0x03FF0000)>>16) < 0x110) &&
 469                (((regE94 & 0x03FF0000)>>16) > 0xf0) &&
 470                (tmp < 0xf)
 471        )
 472                result |= 0x01;
 473        else                                    /* if Tx not OK, ignore Rx */
 474                return result;
 475
 476        return result;
 477}
 478
 479/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 480static u8 phy_PathA_RxIQK8723B(
 481        struct adapter *padapter, bool configPathB, u8 RF_Path
 482)
 483{
 484        u32 regEAC, regE94, regE9C, regEA4, u4tmp, tmp, Path_SEL_BB;
 485        u8 result = 0x00;
 486        struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
 487        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
 488
 489        /*  Save RF Path */
 490        Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord);
 491
 492        /* leave IQK mode */
 493        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 494        /* 1 Get TXIMR setting */
 495        /* modify RXIQK mode table */
 496        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
 497        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
 498        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
 499        /* LNA2 off, PA on for Dcut */
 500        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7fb7);
 501/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x0); */
 502        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
 503
 504        /* IQK setting */
 505        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, 0x01007c00);
 506        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
 507
 508        /* path-A IQK setting */
 509        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
 510        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
 511        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 512        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 513
 514/*      PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f); */
 515        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82130ff0);
 516        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
 517        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
 518        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
 519
 520        /* LO calibration setting */
 521        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
 522
 523        /* enter IQK mode */
 524        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
 525
 526        /* Ant switch */
 527        if (configPathB || (RF_Path == 0))
 528                /*  wifi switch to S1 */
 529                PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000000);
 530        else
 531                /*  wifi switch to S0 */
 532                PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
 533
 534        /* GNT_BT = 0 */
 535        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
 536
 537        /* One shot, path A LOK & IQK */
 538        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 539        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 540
 541        /*  delay x ms */
 542        /* PlatformStallExecution(IQK_DELAY_TIME_8723B*1000); */
 543        mdelay(IQK_DELAY_TIME_8723B);
 544
 545        /* restore Ant Path */
 546        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
 547        /* GNT_BT = 1 */
 548        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
 549
 550        /* leave IQK mode */
 551        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 552
 553        /*  Check failed */
 554        regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
 555        regE94 = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord);
 556        regE9C = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord);
 557
 558        /* Allen 20131125 */
 559        tmp = (regE9C & 0x03FF0000)>>16;
 560        if ((tmp & 0x200) > 0)
 561                tmp = 0x400 - tmp;
 562
 563        if (
 564                !(regEAC & BIT28) &&
 565                (((regE94 & 0x03FF0000)>>16) != 0x142) &&
 566                (((regE9C & 0x03FF0000)>>16) != 0x42) &&
 567                (((regE94 & 0x03FF0000)>>16) < 0x110) &&
 568                (((regE94 & 0x03FF0000)>>16) > 0xf0) &&
 569                (tmp < 0xf)
 570        )
 571                result |= 0x01;
 572        else                            /* if Tx not OK, ignore Rx */
 573                return result;
 574
 575        u4tmp = 0x80007C00 | (regE94&0x3FF0000) | ((regE9C&0x3FF0000) >> 16);
 576        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, u4tmp);
 577
 578        /* modify RXIQK mode table */
 579        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 580        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
 581        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
 582        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
 583        /* LAN2 on, PA off for Dcut */
 584        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7d77);
 585/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x0); */
 586
 587        /* PA, PAD setting */
 588        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0xf80);
 589        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x55, bRFRegOffsetMask, 0x4021f);
 590
 591
 592        /* IQK setting */
 593        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
 594
 595        /* path-A IQK setting */
 596        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
 597        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
 598        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 599        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 600
 601        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82110000);
 602/*      PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x281604c2); */
 603        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x2813001f);
 604        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
 605        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
 606
 607        /* LO calibration setting */
 608        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x0046a8d1);
 609
 610        /* enter IQK mode */
 611        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
 612
 613        /* Ant switch */
 614        if (configPathB || (RF_Path == 0))
 615                /*  wifi switch to S1 */
 616                PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000000);
 617        else
 618                /*  wifi switch to S0 */
 619                PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
 620
 621        /* GNT_BT = 0 */
 622        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
 623
 624        /* One shot, path A LOK & IQK */
 625        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 626        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 627
 628        /*  delay x ms */
 629        /* PlatformStallExecution(IQK_DELAY_TIME_8723B*1000); */
 630        mdelay(IQK_DELAY_TIME_8723B);
 631
 632        /* restore Ant Path */
 633        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
 634        /* GNT_BT = 1 */
 635        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
 636
 637    /* leave IQK mode */
 638        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 639
 640        /*  Check failed */
 641        regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
 642        regEA4 = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord);
 643
 644        /*      PA/PAD controlled by 0x0 */
 645        /* leave IQK mode */
 646        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 647        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x780);
 648
 649        /* Allen 20131125 */
 650        tmp = (regEAC & 0x03FF0000)>>16;
 651        if ((tmp & 0x200) > 0)
 652                tmp = 0x400 - tmp;
 653
 654        if (
 655                !(regEAC & BIT27) && /* if Tx is OK, check whether Rx is OK */
 656                (((regEA4 & 0x03FF0000)>>16) != 0x132) &&
 657                (((regEAC & 0x03FF0000)>>16) != 0x36) &&
 658                (((regEA4 & 0x03FF0000)>>16) < 0x110) &&
 659                (((regEA4 & 0x03FF0000)>>16) > 0xf0) &&
 660                (tmp < 0xf)
 661        )
 662                result |= 0x02;
 663
 664        return result;
 665}
 666
 667/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 668static u8 phy_PathB_IQK_8723B(struct adapter *padapter)
 669{
 670        u32 regEAC, regE94, regE9C, tmp, Path_SEL_BB/*, regEC4, regECC, Path_SEL_BB*/;
 671        u8 result = 0x00;
 672        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
 673        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
 674
 675        /*  Save RF Path */
 676        Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord);
 677
 678    /* leave IQK mode */
 679        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 680
 681        /*      in TXIQK mode */
 682/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1); */
 683/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x20000); */
 684/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0003f); */
 685/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xc7f87); */
 686        /*      enable path B PA in TXIQK mode */
 687        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xed, 0x20, 0x1);
 688        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x43, bRFRegOffsetMask, 0x30fc1);
 689
 690
 691
 692        /* 1 Tx IQK */
 693        /* IQK setting */
 694        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, 0x01007c00);
 695        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
 696        /* path-A IQK setting */
 697        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
 698        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
 699        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 700        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 701
 702/*      PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82140114); */
 703        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x821303ea);
 704        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
 705        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
 706        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
 707
 708        /* LO calibration setting */
 709        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
 710
 711        /* enter IQK mode */
 712        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
 713
 714        /* switch to path B */
 715        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
 716/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xb0, bRFRegOffsetMask, 0xeffe0); */
 717
 718        /* GNT_BT = 0 */
 719        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
 720
 721        /* One shot, path B LOK & IQK */
 722        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 723        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 724
 725        /*  delay x ms */
 726        /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
 727        mdelay(IQK_DELAY_TIME_8723B);
 728
 729        /* restore Ant Path */
 730        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
 731        /* GNT_BT = 1 */
 732        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
 733
 734    /* leave IQK mode */
 735        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 736
 737        /*  Check failed */
 738        regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
 739        regE94 = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord);
 740        regE9C = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord);
 741
 742        /* Allen 20131125 */
 743        tmp = (regE9C & 0x03FF0000)>>16;
 744        if ((tmp & 0x200) > 0)
 745                tmp = 0x400 - tmp;
 746
 747        if (
 748                !(regEAC & BIT28) &&
 749                (((regE94 & 0x03FF0000)>>16) != 0x142) &&
 750                (((regE9C & 0x03FF0000)>>16) != 0x42) &&
 751                (((regE94 & 0x03FF0000)>>16) < 0x110) &&
 752                (((regE94 & 0x03FF0000)>>16) > 0xf0) &&
 753                (tmp < 0xf)
 754        )
 755                result |= 0x01;
 756
 757        return result;
 758}
 759
 760/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 761static u8 phy_PathB_RxIQK8723B(struct adapter *padapter, bool configPathB)
 762{
 763        u32 regE94, regE9C, regEA4, regEAC, u4tmp, tmp, Path_SEL_BB;
 764        u8 result = 0x00;
 765        struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
 766        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
 767
 768        /*  Save RF Path */
 769        Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord);
 770    /* leave IQK mode */
 771        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 772
 773        /* switch to path B */
 774        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
 775        /* modify RXIQK mode table */
 776        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
 777        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
 778        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
 779        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7fb7);
 780        /* open PA S1 & SMIXER */
 781        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xed, 0x20, 0x1);
 782        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x43, bRFRegOffsetMask, 0x30fcd);
 783
 784
 785        /* IQK setting */
 786        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, 0x01007c00);
 787        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
 788
 789
 790        /* path-B IQK setting */
 791        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
 792        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
 793        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 794        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 795
 796/*      PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f); */
 797        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82130ff0);
 798        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
 799        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
 800        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
 801
 802        /* LO calibration setting */
 803        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
 804
 805    /* enter IQK mode */
 806        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
 807
 808        /* switch to path B */
 809        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
 810/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xb0, bRFRegOffsetMask, 0xeffe0); */
 811
 812        /* GNT_BT = 0 */
 813        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
 814
 815        /* One shot, path B TXIQK @ RXIQK */
 816        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 817        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 818
 819
 820        /*  delay x ms */
 821        /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
 822        mdelay(IQK_DELAY_TIME_8723B);
 823
 824        /* restore Ant Path */
 825        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
 826        /* GNT_BT = 1 */
 827        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
 828
 829    /* leave IQK mode */
 830        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 831
 832        /*  Check failed */
 833        regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
 834        regE94 = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord);
 835        regE9C = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord);
 836
 837        /* Allen 20131125 */
 838        tmp = (regE9C & 0x03FF0000)>>16;
 839        if ((tmp & 0x200) > 0)
 840                tmp = 0x400 - tmp;
 841
 842        if (
 843                !(regEAC & BIT28) &&
 844                (((regE94 & 0x03FF0000)>>16) != 0x142) &&
 845                (((regE9C & 0x03FF0000)>>16) != 0x42)  &&
 846                (((regE94 & 0x03FF0000)>>16) < 0x110) &&
 847                (((regE94 & 0x03FF0000)>>16) > 0xf0) &&
 848                (tmp < 0xf)
 849        )
 850                        result |= 0x01;
 851        else    /* if Tx not OK, ignore Rx */
 852                return result;
 853
 854        u4tmp = 0x80007C00 | (regE94&0x3FF0000)  | ((regE9C&0x3FF0000) >> 16);
 855        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, u4tmp);
 856
 857        /* modify RXIQK mode table */
 858        /* 20121009, Kordan> RF Mode = 3 */
 859        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 860        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
 861        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
 862        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
 863        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7d77);
 864/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x0); */
 865
 866        /* open PA S1 & close SMIXER */
 867        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xed, 0x20, 0x1);
 868        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x43, bRFRegOffsetMask, 0x30ebd);
 869
 870        /* PA, PAD setting */
 871/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0xf80); */
 872/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000); */
 873
 874        /* IQK setting */
 875        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
 876
 877        /* path-B IQK setting */
 878        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
 879        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
 880        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 881        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
 882
 883        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82110000);
 884/*      PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x281604c2); */
 885        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x2813001f);
 886        PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
 887        PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
 888
 889        /* LO calibration setting */
 890        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x0046a8d1);
 891
 892    /* enter IQK mode */
 893        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
 894
 895        /* switch to path B */
 896        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
 897/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xb0, bRFRegOffsetMask, 0xeffe0); */
 898
 899        /* GNT_BT = 0 */
 900        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
 901
 902        /* One shot, path B LOK & IQK */
 903        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 904        PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 905
 906        /*  delay x ms */
 907        /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
 908        mdelay(IQK_DELAY_TIME_8723B);
 909
 910        /* restore Ant Path */
 911        PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
 912        /* GNT_BT = 1 */
 913        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
 914
 915    /* leave IQK mode */
 916        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
 917
 918        /*  Check failed */
 919        regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
 920        regEA4 = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord);
 921
 922        /*      PA/PAD controlled by 0x0 */
 923        /* leave IQK mode */
 924/*      PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, 0xffffff00, 0x00000000); */
 925/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_B, 0xdf, bRFRegOffsetMask, 0x180); */
 926
 927
 928
 929        /* Allen 20131125 */
 930        tmp = (regEAC & 0x03FF0000)>>16;
 931        if ((tmp & 0x200) > 0)
 932                tmp = 0x400 - tmp;
 933
 934        if (
 935                !(regEAC & BIT27) && /* if Tx is OK, check whether Rx is OK */
 936                (((regEA4 & 0x03FF0000)>>16) != 0x132) &&
 937                (((regEAC & 0x03FF0000)>>16) != 0x36) &&
 938                (((regEA4 & 0x03FF0000)>>16) < 0x110) &&
 939                (((regEA4 & 0x03FF0000)>>16) > 0xf0) &&
 940                (tmp < 0xf)
 941        )
 942                result |= 0x02;
 943
 944        return result;
 945}
 946
 947static void _PHY_PathAFillIQKMatrix8723B(
 948        struct adapter *padapter,
 949        bool bIQKOK,
 950        s32 result[][8],
 951        u8 final_candidate,
 952        bool bTxOnly
 953)
 954{
 955        u32 Oldval_0, X, TX0_A, reg;
 956        s32 Y, TX0_C;
 957        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
 958        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
 959
 960        struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
 961
 962        if (final_candidate == 0xFF)
 963                return;
 964
 965        else if (bIQKOK) {
 966                Oldval_0 = (PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
 967
 968                X = result[final_candidate][0];
 969                if ((X & 0x00000200) != 0)
 970                        X = X | 0xFFFFFC00;
 971                TX0_A = (X * Oldval_0) >> 8;
 972                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A);
 973
 974                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT(31), ((X*Oldval_0>>7) & 0x1));
 975
 976                Y = result[final_candidate][1];
 977                if ((Y & 0x00000200) != 0)
 978                        Y = Y | 0xFFFFFC00;
 979
 980                /* 2 Tx IQC */
 981                TX0_C = (Y * Oldval_0) >> 8;
 982                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C&0x3C0)>>6));
 983                pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][KEY] = rOFDM0_XCTxAFE;
 984                pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XCTxAFE, bMaskDWord);
 985
 986                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C&0x3F));
 987                pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][KEY] = rOFDM0_XATxIQImbalance;
 988                pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord);
 989
 990                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT(29), ((Y*Oldval_0>>7) & 0x1));
 991                pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][KEY] = rOFDM0_ECCAThreshold;
 992                pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskDWord);
 993
 994                if (bTxOnly) {
 995                        /*  <20130226, Kordan> Saving RxIQC, otherwise not initialized. */
 996                        pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
 997                        pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL] = 0xfffffff & PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, bMaskDWord);
 998                        pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
 999/*                      pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, bMaskDWord); */
1000                        pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] = 0x40000100;
1001                        return;
1002                }
1003
1004                reg = result[final_candidate][2];
1005
1006                /* 2 Rx IQC */
1007                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, 0x3FF, reg);
1008                reg = result[final_candidate][3] & 0x3F;
1009                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, 0xFC00, reg);
1010                pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
1011                pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, bMaskDWord);
1012
1013                reg = (result[final_candidate][3] >> 6) & 0xF;
1014                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
1015                pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
1016                pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, bMaskDWord);
1017
1018        }
1019}
1020
1021static void _PHY_PathBFillIQKMatrix8723B(
1022        struct adapter *padapter,
1023        bool bIQKOK,
1024        s32 result[][8],
1025        u8 final_candidate,
1026        bool bTxOnly /* do Tx only */
1027)
1028{
1029        u32 Oldval_1, X, TX1_A, reg;
1030        s32     Y, TX1_C;
1031        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1032        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1033
1034        struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
1035
1036        if (final_candidate == 0xFF)
1037                return;
1038
1039        else if (bIQKOK) {
1040                Oldval_1 = (PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
1041
1042                X = result[final_candidate][4];
1043                if ((X & 0x00000200) != 0)
1044                        X = X | 0xFFFFFC00;
1045                TX1_A = (X * Oldval_1) >> 8;
1046
1047                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A);
1048
1049                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT(27), ((X*Oldval_1>>7) & 0x1));
1050
1051                Y = result[final_candidate][5];
1052                if ((Y & 0x00000200) != 0)
1053                        Y = Y | 0xFFFFFC00;
1054
1055                TX1_C = (Y * Oldval_1) >> 8;
1056
1057                /* 2 Tx IQC */
1058                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C&0x3C0)>>6));
1059/*              pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC9C][KEY] = rOFDM0_XDTxAFE; */
1060/*              pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC9C][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, bMaskDWord); */
1061                pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][KEY] = rOFDM0_XCTxAFE;
1062                pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, bMaskDWord);
1063
1064                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C&0x3F));
1065                pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][KEY] = rOFDM0_XATxIQImbalance;
1066                pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord);
1067
1068                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT(25), ((Y*Oldval_1>>7) & 0x1));
1069                pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][KEY] = rOFDM0_ECCAThreshold;
1070                pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskDWord);
1071
1072                if (bTxOnly) {
1073                        pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
1074/*                      pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, bMaskDWord); */
1075                        pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL] = 0x40000100;
1076                        pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
1077                        pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][VAL] = 0x0fffffff & PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, bMaskDWord);
1078                        return;
1079                }
1080
1081                /* 2 Rx IQC */
1082                reg = result[final_candidate][6];
1083                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
1084                reg = result[final_candidate][7] & 0x3F;
1085                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
1086                pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
1087                pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBRxIQImbalance, bMaskDWord);
1088
1089                reg = (result[final_candidate][7] >> 6) & 0xF;
1090/*              PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_AGCRSSITable, 0x0000F000, reg); */
1091                pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
1092                pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][VAL] = (reg << 28)|(PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, bMaskDWord)&0x0fffffff);
1093        }
1094}
1095
1096/*  */
1097/*  2011/07/26 MH Add an API for testing IQK fail case. */
1098/*  */
1099/*  MP Already declare in odm.c */
1100
1101void ODM_SetIQCbyRFpath(struct dm_odm_t *pDM_Odm, u32 RFpath)
1102{
1103
1104        struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
1105
1106        if (
1107                (pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][VAL] != 0x0) &&
1108                (pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL] != 0x0) &&
1109                (pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL] != 0x0) &&
1110                (pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] != 0x0)
1111        ) {
1112                if (RFpath) { /* S1: RFpath = 0, S0:RFpath = 1 */
1113                        /* S0 TX IQC */
1114                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][VAL]);
1115                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][VAL]);
1116                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][VAL]);
1117                        /* S0 RX IQC */
1118                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL]);
1119                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][VAL]);
1120                } else {
1121                        /* S1 TX IQC */
1122                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][VAL]);
1123                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL]);
1124                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][VAL]);
1125                        /* S1 RX IQC */
1126                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL]);
1127                        PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL]);
1128                }
1129        }
1130}
1131
1132static bool ODM_CheckPowerStatus(struct adapter *Adapter)
1133{
1134        return true;
1135}
1136
1137static void _PHY_SaveADDARegisters8723B(
1138        struct adapter *padapter,
1139        u32 *ADDAReg,
1140        u32 *ADDABackup,
1141        u32 RegisterNum
1142)
1143{
1144        u32 i;
1145        struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1146        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1147
1148        if (!ODM_CheckPowerStatus(padapter))
1149                return;
1150
1151        for (i = 0 ; i < RegisterNum ; i++) {
1152                ADDABackup[i] = PHY_QueryBBReg(pDM_Odm->Adapter, ADDAReg[i], bMaskDWord);
1153        }
1154}
1155
1156
1157static void _PHY_SaveMACRegisters8723B(
1158        struct adapter *padapter, u32 *MACReg, u32 *MACBackup
1159)
1160{
1161        u32 i;
1162        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1163        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1164
1165        for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++) {
1166                MACBackup[i] = rtw_read8(pDM_Odm->Adapter, MACReg[i]);
1167        }
1168        MACBackup[i] = rtw_read32(pDM_Odm->Adapter, MACReg[i]);
1169
1170}
1171
1172
1173static void _PHY_ReloadADDARegisters8723B(
1174        struct adapter *padapter,
1175        u32 *ADDAReg,
1176        u32 *ADDABackup,
1177        u32 RegiesterNum
1178)
1179{
1180        u32 i;
1181        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1182        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1183
1184        for (i = 0 ; i < RegiesterNum; i++) {
1185                PHY_SetBBReg(pDM_Odm->Adapter, ADDAReg[i], bMaskDWord, ADDABackup[i]);
1186        }
1187}
1188
1189static void _PHY_ReloadMACRegisters8723B(
1190        struct adapter *padapter, u32 *MACReg, u32 *MACBackup
1191)
1192{
1193        u32 i;
1194
1195        for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++) {
1196                rtw_write8(padapter, MACReg[i], (u8)MACBackup[i]);
1197        }
1198        rtw_write32(padapter, MACReg[i], MACBackup[i]);
1199}
1200
1201
1202static void _PHY_PathADDAOn8723B(
1203        struct adapter *padapter,
1204        u32 *ADDAReg,
1205        bool is2T
1206)
1207{
1208        u32 pathOn;
1209        u32 i;
1210        struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1211        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1212
1213        pathOn = 0x01c00014;
1214        if (!is2T) {
1215                pathOn = 0x01c00014;
1216                PHY_SetBBReg(pDM_Odm->Adapter, ADDAReg[0], bMaskDWord, 0x01c00014);
1217        } else {
1218                PHY_SetBBReg(pDM_Odm->Adapter, ADDAReg[0], bMaskDWord, pathOn);
1219        }
1220
1221        for (i = 1 ; i < IQK_ADDA_REG_NUM ; i++) {
1222                PHY_SetBBReg(pDM_Odm->Adapter, ADDAReg[i], bMaskDWord, pathOn);
1223        }
1224
1225}
1226
1227static void _PHY_MACSettingCalibration8723B(
1228        struct adapter *padapter, u32 *MACReg, u32 *MACBackup
1229)
1230{
1231        u32 i = 0;
1232        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1233        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1234
1235        rtw_write8(pDM_Odm->Adapter, MACReg[i], 0x3F);
1236
1237        for (i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++) {
1238                rtw_write8(pDM_Odm->Adapter, MACReg[i], (u8)(MACBackup[i]&(~BIT3)));
1239        }
1240        rtw_write8(pDM_Odm->Adapter, MACReg[i], (u8)(MACBackup[i]&(~BIT5)));
1241
1242}
1243
1244static bool phy_SimularityCompare_8723B(
1245        struct adapter *padapter,
1246        s32 result[][8],
1247        u8  c1,
1248        u8  c2
1249)
1250{
1251        u32 i, j, diff, SimularityBitMap, bound = 0;
1252        u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
1253        bool bResult = true;
1254        s32 tmp1 = 0, tmp2 = 0;
1255
1256        bound = 8;
1257        SimularityBitMap = 0;
1258
1259        for (i = 0; i < bound; i++) {
1260
1261                if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1262                        if ((result[c1][i] & 0x00000200) != 0)
1263                                tmp1 = result[c1][i] | 0xFFFFFC00;
1264                        else
1265                                tmp1 = result[c1][i];
1266
1267                        if ((result[c2][i] & 0x00000200) != 0)
1268                                tmp2 = result[c2][i] | 0xFFFFFC00;
1269                        else
1270                                tmp2 = result[c2][i];
1271                } else {
1272                        tmp1 = result[c1][i];
1273                        tmp2 = result[c2][i];
1274                }
1275
1276                diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
1277
1278                if (diff > MAX_TOLERANCE) {
1279                        if ((i == 2 || i == 6) && !SimularityBitMap) {
1280                                if (result[c1][i]+result[c1][i+1] == 0)
1281                                        final_candidate[(i/4)] = c2;
1282                                else if (result[c2][i]+result[c2][i+1] == 0)
1283                                        final_candidate[(i/4)] = c1;
1284                                else
1285                                        SimularityBitMap = SimularityBitMap|(1<<i);
1286                        } else
1287                                SimularityBitMap = SimularityBitMap|(1<<i);
1288                }
1289        }
1290
1291        if (SimularityBitMap == 0) {
1292                for (i = 0; i < (bound/4); i++) {
1293                        if (final_candidate[i] != 0xFF) {
1294                                for (j = i*4; j < (i+1)*4-2; j++)
1295                                        result[3][j] = result[final_candidate[i]][j];
1296                                bResult = false;
1297                        }
1298                }
1299                return bResult;
1300        } else {
1301
1302                if (!(SimularityBitMap & 0x03)) { /* path A TX OK */
1303                        for (i = 0; i < 2; i++)
1304                                result[3][i] = result[c1][i];
1305                }
1306
1307                if (!(SimularityBitMap & 0x0c)) { /* path A RX OK */
1308                        for (i = 2; i < 4; i++)
1309                                result[3][i] = result[c1][i];
1310                }
1311
1312                if (!(SimularityBitMap & 0x30)) { /* path B TX OK */
1313                        for (i = 4; i < 6; i++)
1314                                result[3][i] = result[c1][i];
1315                }
1316
1317                if (!(SimularityBitMap & 0xc0)) { /* path B RX OK */
1318                        for (i = 6; i < 8; i++)
1319                                result[3][i] = result[c1][i];
1320                }
1321                return false;
1322        }
1323}
1324
1325
1326
1327static void phy_IQCalibrate_8723B(
1328        struct adapter *padapter,
1329        s32 result[][8],
1330        u8 t,
1331        bool is2T,
1332        u8 RF_Path
1333)
1334{
1335        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1336        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1337
1338        u32 i;
1339        u8 PathAOK, PathBOK;
1340        u8 tmp0xc50 = (u8)PHY_QueryBBReg(pDM_Odm->Adapter, 0xC50, bMaskByte0);
1341        u8 tmp0xc58 = (u8)PHY_QueryBBReg(pDM_Odm->Adapter, 0xC58, bMaskByte0);
1342        u32 ADDA_REG[IQK_ADDA_REG_NUM] = {
1343                rFPGA0_XCD_SwitchControl,
1344                rBlue_Tooth,
1345                rRx_Wait_CCA,
1346                rTx_CCK_RFON,
1347                rTx_CCK_BBON,
1348                rTx_OFDM_RFON,
1349                rTx_OFDM_BBON,
1350                rTx_To_Rx,
1351                rTx_To_Tx,
1352                rRx_CCK,
1353                rRx_OFDM,
1354                rRx_Wait_RIFS,
1355                rRx_TO_Rx,
1356                rStandby,
1357                rSleep,
1358                rPMPD_ANAEN
1359        };
1360        u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = {
1361                REG_TXPAUSE,
1362                REG_BCN_CTRL,
1363                REG_BCN_CTRL_1,
1364                REG_GPIO_MUXCFG
1365        };
1366
1367        /* since 92C & 92D have the different define in IQK_BB_REG */
1368        u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
1369                rOFDM0_TRxPathEnable,
1370                rOFDM0_TRMuxPar,
1371                rFPGA0_XCD_RFInterfaceSW,
1372                rConfig_AntA,
1373                rConfig_AntB,
1374                rFPGA0_XAB_RFInterfaceSW,
1375                rFPGA0_XA_RFInterfaceOE,
1376                rFPGA0_XB_RFInterfaceOE,
1377                rCCK0_AFESetting
1378        };
1379        const u32 retryCount = 2;
1380
1381        /*  Note: IQ calibration must be performed after loading */
1382        /*              PHY_REG.txt , and radio_a, radio_b.txt */
1383
1384        /* u32 bbvalue; */
1385
1386        if (t == 0) {
1387
1388                /*  Save ADDA parameters, turn Path A ADDA on */
1389                _PHY_SaveADDARegisters8723B(padapter, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
1390                _PHY_SaveMACRegisters8723B(padapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
1391                _PHY_SaveADDARegisters8723B(padapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1392        }
1393
1394        _PHY_PathADDAOn8723B(padapter, ADDA_REG, is2T);
1395
1396/* no serial mode */
1397
1398        /* save RF path for 8723B */
1399/*      Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord); */
1400/*      Path_SEL_RF = PHY_QueryRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xb0, 0xfffff); */
1401
1402        /* MAC settings */
1403        _PHY_MACSettingCalibration8723B(padapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
1404
1405        /* BB setting */
1406        /* PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_RFMOD, BIT24, 0x00); */
1407        PHY_SetBBReg(pDM_Odm->Adapter, rCCK0_AFESetting, 0x0f000000, 0xf);
1408        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1409        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1410        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1411
1412
1413/*      PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01); */
1414/*      PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01); */
1415/*      PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00); */
1416/*      PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00); */
1417
1418
1419/* RX IQ calibration setting for 8723B D cut large current issue when leaving IPS */
1420
1421        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
1422        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1423        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
1424        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
1425        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7fb7);
1426        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xed, 0x20, 0x1);
1427        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x43, bRFRegOffsetMask, 0x60fbd);
1428
1429/* path A TX IQK */
1430        for (i = 0 ; i < retryCount ; i++) {
1431                PathAOK = phy_PathA_IQK_8723B(padapter, is2T, RF_Path);
1432/*              if (PathAOK == 0x03) { */
1433                if (PathAOK == 0x01) {
1434                        /*  Path A Tx IQK Success */
1435                        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
1436                        pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_A] = PHY_QueryRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x8, bRFRegOffsetMask);
1437
1438                                result[t][0] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1439                                result[t][1] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1440                        break;
1441                }
1442        }
1443
1444/* path A RXIQK */
1445        for (i = 0 ; i < retryCount ; i++) {
1446                PathAOK = phy_PathA_RxIQK8723B(padapter, is2T, RF_Path);
1447                if (PathAOK == 0x03) {
1448/*                              result[t][0] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; */
1449/*                              result[t][1] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; */
1450                                result[t][2] = (PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1451                                result[t][3] = (PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1452                        break;
1453                }
1454        }
1455
1456        if (0x00 == PathAOK) {
1457        }
1458
1459/* path B IQK */
1460        if (is2T) {
1461
1462                /* path B TX IQK */
1463                for (i = 0 ; i < retryCount ; i++) {
1464                        PathBOK = phy_PathB_IQK_8723B(padapter);
1465                        if (PathBOK == 0x01) {
1466                                /*  Path B Tx IQK Success */
1467                                PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
1468                                pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_B] = PHY_QueryRFReg(pDM_Odm->Adapter, ODM_RF_PATH_B, 0x8, bRFRegOffsetMask);
1469
1470                                result[t][4] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1471                                result[t][5] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1472                                break;
1473                        }
1474                }
1475
1476/* path B RX IQK */
1477                for (i = 0 ; i < retryCount ; i++) {
1478                        PathBOK = phy_PathB_RxIQK8723B(padapter, is2T);
1479                        if (PathBOK == 0x03) {
1480/*                              result[t][0] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; */
1481/*                              result[t][1] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; */
1482                                result[t][6] = (PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1483                                result[t][7] = (PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1484                                break;
1485                        }
1486                }
1487
1488/* Allen end */
1489        }
1490
1491        /* Back to BB mode, load original value */
1492        PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0);
1493
1494        if (t != 0) {
1495                /*  Reload ADDA power saving parameters */
1496                _PHY_ReloadADDARegisters8723B(padapter, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
1497
1498                /*  Reload MAC parameters */
1499                _PHY_ReloadMACRegisters8723B(padapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
1500
1501                _PHY_ReloadADDARegisters8723B(padapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1502
1503                /* Reload RF path */
1504/*              PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB); */
1505/*              PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xb0, 0xfffff, Path_SEL_RF); */
1506
1507                /* Allen initial gain 0xc50 */
1508                /*  Restore RX initial gain */
1509                PHY_SetBBReg(pDM_Odm->Adapter, 0xc50, bMaskByte0, 0x50);
1510                PHY_SetBBReg(pDM_Odm->Adapter, 0xc50, bMaskByte0, tmp0xc50);
1511                if (is2T) {
1512                        PHY_SetBBReg(pDM_Odm->Adapter, 0xc58, bMaskByte0, 0x50);
1513                        PHY_SetBBReg(pDM_Odm->Adapter, 0xc58, bMaskByte0, tmp0xc58);
1514                }
1515
1516                /* load 0xe30 IQC default value */
1517                PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1518                PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1519
1520        }
1521
1522}
1523
1524
1525static void phy_LCCalibrate_8723B(struct dm_odm_t *pDM_Odm, bool is2T)
1526{
1527        u8 tmpReg;
1528        u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
1529        struct adapter *padapter = pDM_Odm->Adapter;
1530
1531        /* Check continuous TX and Packet TX */
1532        tmpReg = rtw_read8(pDM_Odm->Adapter, 0xd03);
1533
1534        if ((tmpReg&0x70) != 0)                 /* Deal with contisuous TX case */
1535                rtw_write8(pDM_Odm->Adapter, 0xd03, tmpReg&0x8F);       /* disable all continuous TX */
1536        else                                                    /*  Deal with Packet TX case */
1537                rtw_write8(pDM_Odm->Adapter, REG_TXPAUSE, 0xFF);                /*  block all queues */
1538
1539        if ((tmpReg&0x70) != 0) {
1540                /* 1. Read original RF mode */
1541                /* Path-A */
1542                RF_Amode = PHY_QueryRFReg(padapter, ODM_RF_PATH_A, RF_AC, bMask12Bits);
1543
1544                /* Path-B */
1545                if (is2T)
1546                        RF_Bmode = PHY_QueryRFReg(padapter, ODM_RF_PATH_B, RF_AC, bMask12Bits);
1547
1548                /* 2. Set RF mode = standby mode */
1549                /* Path-A */
1550                PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode&0x8FFFF)|0x10000);
1551
1552                /* Path-B */
1553                if (is2T)
1554                        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode&0x8FFFF)|0x10000);
1555        }
1556
1557        /* 3. Read RF reg18 */
1558        LC_Cal = PHY_QueryRFReg(padapter, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits);
1559
1560        /* 4. Set LC calibration begin  bit15 */
1561        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0); /*  LDO ON */
1562        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal|0x08000);
1563
1564        mdelay(100);
1565
1566        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0); /*  LDO OFF */
1567
1568        /*  Channel 10 LC calibration issue for 8723bs with 26M xtal */
1569        if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO && pDM_Odm->PackageType >= 0x2) {
1570                PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal);
1571        }
1572
1573        /* Restore original situation */
1574        if ((tmpReg&0x70) != 0) { /* Deal with contisuous TX case */
1575                /* Path-A */
1576                rtw_write8(pDM_Odm->Adapter, 0xd03, tmpReg);
1577                PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_AC, bMask12Bits, RF_Amode);
1578
1579                /* Path-B */
1580                if (is2T)
1581                        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode);
1582        } else /*  Deal with Packet TX case */
1583                rtw_write8(pDM_Odm->Adapter, REG_TXPAUSE, 0x00);
1584}
1585
1586/* Analog Pre-distortion calibration */
1587#define         APK_BB_REG_NUM  8
1588#define         APK_CURVE_REG_NUM 4
1589#define         PATH_NUM                2
1590
1591#define         DP_BB_REG_NUM           7
1592#define         DP_RF_REG_NUM           1
1593#define         DP_RETRY_LIMIT          10
1594#define         DP_PATH_NUM     2
1595#define         DP_DPK_NUM                      3
1596#define         DP_DPK_VALUE_NUM        2
1597
1598
1599
1600/* IQK version:V2.5    20140123 */
1601/* IQK is controlled by Is2ant, RF path */
1602void PHY_IQCalibrate_8723B(
1603        struct adapter *padapter,
1604        bool bReCovery,
1605        bool bRestore,
1606        bool Is2ant,    /* false:1ant, true:2-ant */
1607        u8 RF_Path      /* 0:S1, 1:S0 */
1608)
1609{
1610        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1611
1612        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1613
1614        s32 result[4][8];       /* last is final result */
1615        u8 i, final_candidate;
1616        bool bPathAOK, bPathBOK;
1617        s32 RegE94, RegE9C, RegEA4, RegEB4, RegEBC, RegEC4, RegTmp = 0;
1618        bool is12simular, is13simular, is23simular;
1619        bool bSingleTone = false, bCarrierSuppression = false;
1620        u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
1621                rOFDM0_XARxIQImbalance,
1622                rOFDM0_XBRxIQImbalance,
1623                rOFDM0_ECCAThreshold,
1624                rOFDM0_AGCRSSITable,
1625                rOFDM0_XATxIQImbalance,
1626                rOFDM0_XBTxIQImbalance,
1627                rOFDM0_XCTxAFE,
1628                rOFDM0_XDTxAFE,
1629                rOFDM0_RxIQExtAnta
1630        };
1631/*      u32             Path_SEL_BB = 0; */
1632        u32             GNT_BT_default;
1633
1634        if (!ODM_CheckPowerStatus(padapter))
1635                return;
1636
1637        if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION))
1638                return;
1639
1640        /*  20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1641        if (bSingleTone || bCarrierSuppression)
1642                return;
1643
1644        if (pDM_Odm->RFCalibrateInfo.bIQKInProgress)
1645                return;
1646
1647
1648        pDM_Odm->RFCalibrateInfo.bIQKInProgress = true;
1649
1650        if (bRestore) {
1651                u32 offset, data;
1652                u8 path, bResult = SUCCESS;
1653                struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
1654
1655                path = (PHY_QueryBBReg(pDM_Odm->Adapter, rS0S1_PathSwitch, bMaskByte0) == 0x00) ? ODM_RF_PATH_A : ODM_RF_PATH_B;
1656
1657                /*  Restore TX IQK */
1658                for (i = 0; i < 3; ++i) {
1659                        offset = pRFCalibrateInfo->TxIQC_8723B[path][i][0];
1660                        data = pRFCalibrateInfo->TxIQC_8723B[path][i][1];
1661                        if ((offset == 0) || (data == 0)) {
1662                                bResult = FAIL;
1663                                break;
1664                        }
1665                        PHY_SetBBReg(pDM_Odm->Adapter, offset, bMaskDWord, data);
1666                }
1667
1668                /*  Restore RX IQK */
1669                for (i = 0; i < 2; ++i) {
1670                        offset = pRFCalibrateInfo->RxIQC_8723B[path][i][0];
1671                        data = pRFCalibrateInfo->RxIQC_8723B[path][i][1];
1672                        if ((offset == 0) || (data == 0)) {
1673                                bResult = FAIL;
1674                                break;
1675                        }
1676                        PHY_SetBBReg(pDM_Odm->Adapter, offset, bMaskDWord, data);
1677                }
1678
1679                if (pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_A] == 0) {
1680                        bResult = FAIL;
1681                } else {
1682                        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXM_IDAC, bRFRegOffsetMask, pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_A]);
1683                        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_B, RF_TXM_IDAC, bRFRegOffsetMask, pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_B]);
1684                }
1685
1686                if (bResult == SUCCESS)
1687                        return;
1688        }
1689
1690        if (bReCovery) {
1691                _PHY_ReloadADDARegisters8723B(padapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1692                return;
1693        }
1694
1695        /* save default GNT_BT */
1696        GNT_BT_default = PHY_QueryBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord);
1697        /*  Save RF Path */
1698/*      Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord); */
1699/*      Path_SEL_RF = PHY_QueryRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xb0, 0xfffff); */
1700
1701    /* set GNT_BT = 0, pause BT traffic */
1702/*      PHY_SetBBReg(pDM_Odm->Adapter, 0x764, BIT12, 0x0); */
1703/*      PHY_SetBBReg(pDM_Odm->Adapter, 0x764, BIT11, 0x1); */
1704
1705
1706        for (i = 0; i < 8; i++) {
1707                result[0][i] = 0;
1708                result[1][i] = 0;
1709                result[2][i] = 0;
1710                result[3][i] = 0;
1711        }
1712
1713        final_candidate = 0xff;
1714        bPathAOK = false;
1715        bPathBOK = false;
1716        is12simular = false;
1717        is23simular = false;
1718        is13simular = false;
1719
1720
1721        for (i = 0; i < 3; i++) {
1722                phy_IQCalibrate_8723B(padapter, result, i, Is2ant, RF_Path);
1723
1724                if (i == 1) {
1725                        is12simular = phy_SimularityCompare_8723B(padapter, result, 0, 1);
1726                        if (is12simular) {
1727                                final_candidate = 0;
1728                                break;
1729                        }
1730                }
1731
1732                if (i == 2) {
1733                        is13simular = phy_SimularityCompare_8723B(padapter, result, 0, 2);
1734                        if (is13simular) {
1735                                final_candidate = 0;
1736
1737                                break;
1738                        }
1739
1740                        is23simular = phy_SimularityCompare_8723B(padapter, result, 1, 2);
1741                        if (is23simular) {
1742                                final_candidate = 1;
1743                        } else {
1744                                for (i = 0; i < 8; i++)
1745                                        RegTmp += result[3][i];
1746
1747                                if (RegTmp != 0)
1748                                        final_candidate = 3;
1749                                else
1750                                        final_candidate = 0xFF;
1751                        }
1752                }
1753        }
1754
1755        for (i = 0; i < 4; i++) {
1756                RegE94 = result[i][0];
1757                RegE9C = result[i][1];
1758                RegEA4 = result[i][2];
1759                RegEB4 = result[i][4];
1760                RegEBC = result[i][5];
1761                RegEC4 = result[i][6];
1762        }
1763
1764        if (final_candidate != 0xff) {
1765                pDM_Odm->RFCalibrateInfo.RegE94 = RegE94 = result[final_candidate][0];
1766                pDM_Odm->RFCalibrateInfo.RegE9C = RegE9C = result[final_candidate][1];
1767                RegEA4 = result[final_candidate][2];
1768                pDM_Odm->RFCalibrateInfo.RegEB4 = RegEB4 = result[final_candidate][4];
1769                pDM_Odm->RFCalibrateInfo.RegEBC = RegEBC = result[final_candidate][5];
1770                RegEC4 = result[final_candidate][6];
1771                bPathAOK = bPathBOK = true;
1772        } else {
1773                pDM_Odm->RFCalibrateInfo.RegE94 = pDM_Odm->RFCalibrateInfo.RegEB4 = 0x100;      /* X default value */
1774                pDM_Odm->RFCalibrateInfo.RegE9C = pDM_Odm->RFCalibrateInfo.RegEBC = 0x0;                /* Y default value */
1775        }
1776
1777        {
1778                if (RegE94 != 0)
1779                        _PHY_PathAFillIQKMatrix8723B(padapter, bPathAOK, result, final_candidate, (RegEA4 == 0));
1780        }
1781        {
1782                if (RegEB4 != 0)
1783                        _PHY_PathBFillIQKMatrix8723B(padapter, bPathBOK, result, final_candidate, (RegEC4 == 0));
1784        }
1785
1786/* To Fix BSOD when final_candidate is 0xff */
1787/* by sherry 20120321 */
1788        if (final_candidate < 4) {
1789                for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1790                        pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[0].Value[0][i] = result[final_candidate][i];
1791                pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[0].bIQKDone = true;
1792        }
1793
1794        _PHY_SaveADDARegisters8723B(padapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1795
1796        /* restore GNT_BT */
1797        PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, GNT_BT_default);
1798        /*  Restore RF Path */
1799/*      PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB); */
1800/*      PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xb0, 0xfffff, Path_SEL_RF); */
1801
1802        /* Resotr RX mode table parameter */
1803        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1804        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
1805        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
1806        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xe6177);
1807        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0xed, 0x20, 0x1);
1808        PHY_SetRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, 0x43, bRFRegOffsetMask, 0x300bd);
1809
1810        /* set GNT_BT = HW control */
1811/*      PHY_SetBBReg(pDM_Odm->Adapter, 0x764, BIT12, 0x0); */
1812/*      PHY_SetBBReg(pDM_Odm->Adapter, 0x764, BIT11, 0x0); */
1813
1814        if (Is2ant) {
1815                if (RF_Path == 0x0)     /* S1 */
1816                        ODM_SetIQCbyRFpath(pDM_Odm, 0);
1817                else    /* S0 */
1818                        ODM_SetIQCbyRFpath(pDM_Odm, 1);
1819        }
1820
1821        pDM_Odm->RFCalibrateInfo.bIQKInProgress = false;
1822}
1823
1824
1825void PHY_LCCalibrate_8723B(struct dm_odm_t *pDM_Odm)
1826{
1827        bool            bSingleTone = false, bCarrierSuppression = false;
1828        u32             timeout = 2000, timecount = 0;
1829
1830        if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION))
1831                return;
1832
1833        /*  20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1834        if (bSingleTone || bCarrierSuppression)
1835                return;
1836
1837        while (*(pDM_Odm->pbScanInProcess) && timecount < timeout) {
1838                mdelay(50);
1839                timecount += 50;
1840        }
1841
1842        pDM_Odm->RFCalibrateInfo.bLCKInProgress = true;
1843
1844
1845        phy_LCCalibrate_8723B(pDM_Odm, false);
1846
1847
1848        pDM_Odm->RFCalibrateInfo.bLCKInProgress = false;
1849}
1850