linux/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2007 - 2011 Realtek Corporation. */
   3
   4#include "../include/odm_precomp.h"
   5
   6/*---------------------------Define Local Constant---------------------------*/
   7/*  2010/04/25 MH Define the max tx power tracking tx agc power. */
   8#define         ODM_TXPWRTRACK_MAX_IDX_88E              6
   9
  10/*---------------------------Define Local Constant---------------------------*/
  11
  12/* 3============================================================ */
  13/* 3 Tx Power Tracking */
  14/* 3============================================================ */
  15/*-----------------------------------------------------------------------------
  16 * Function:    ODM_TxPwrTrackAdjust88E()
  17 *
  18 * Overview:    88E we can not write 0xc80/c94/c4c/ 0xa2x. Instead of write TX agc.
  19 *                              No matter OFDM & CCK use the same method.
  20 *
  21 * Input:               NONE
  22 *
  23 * Output:              NONE
  24 *
  25 * Return:              NONE
  26 *
  27 * Revised History:
  28 *      When            Who             Remark
  29 *      04/23/2012      MHC             Create Version 0.
  30 *      04/23/2012      MHC             Adjust TX agc directly not throughput BB digital.
  31 *
  32 *---------------------------------------------------------------------------*/
  33void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,/*  0 = OFDM, 1 = CCK */
  34        u8 *pDirection,                 /*  1 = +(increase) 2 = -(decrease) */
  35        u32 *pOutWriteVal               /*  Tx tracking CCK/OFDM BB swing index adjust */
  36        )
  37{
  38        u8 pwr_value = 0;
  39        /*  Tx power tracking BB swing table. */
  40        /*  The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
  41        if (Type == 0) {                /*  For OFDM afjust */
  42                if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
  43                        *pDirection     = 1;
  44                        pwr_value               = (dm_odm->BbSwingIdxOfdmBase - dm_odm->BbSwingIdxOfdm);
  45                } else {
  46                        *pDirection     = 2;
  47                        pwr_value               = (dm_odm->BbSwingIdxOfdm - dm_odm->BbSwingIdxOfdmBase);
  48                }
  49        } else if (Type == 1) { /*  For CCK adjust. */
  50                if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
  51                        *pDirection     = 1;
  52                        pwr_value               = (dm_odm->BbSwingIdxCckBase - dm_odm->BbSwingIdxCck);
  53                } else {
  54                        *pDirection     = 2;
  55                        pwr_value               = (dm_odm->BbSwingIdxCck - dm_odm->BbSwingIdxCckBase);
  56                }
  57        }
  58
  59        /*  */
  60        /*  2012/04/25 MH According to Ed/Luke.Lees estimate for EVM the max tx power tracking */
  61        /*  need to be less than 6 power index for 88E. */
  62        /*  */
  63        if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *pDirection == 1)
  64                pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
  65
  66        *pOutWriteVal = pwr_value | (pwr_value << 8) | (pwr_value << 16) | (pwr_value << 24);
  67}       /*  ODM_TxPwrTrackAdjust88E */
  68
  69/*-----------------------------------------------------------------------------
  70 * Function:    odm_TxPwrTrackSetPwr88E()
  71 *
  72 * Overview:    88E change all channel tx power accordign to flag.
  73 *                              OFDM & CCK are all different.
  74 *
  75 * Input:               NONE
  76 *
  77 * Output:              NONE
  78 *
  79 * Return:              NONE
  80 *
  81 * Revised History:
  82 *      When            Who             Remark
  83 *      04/23/2012      MHC             Create Version 0.
  84 *
  85 *---------------------------------------------------------------------------*/
  86static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct *dm_odm)
  87{
  88        if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
  89                PHY_SetTxPowerLevel8188E(dm_odm->Adapter, *dm_odm->pChannel);
  90                dm_odm->BbSwingFlagOfdm = false;
  91                dm_odm->BbSwingFlagCck  = false;
  92        }
  93}       /*  odm_TxPwrTrackSetPwr88E */
  94
  95/* 091212 chiyokolin */
  96void
  97odm_TXPowerTrackingCallback_ThermalMeter_8188E(
  98        struct adapter *Adapter
  99        )
 100{
 101        struct hal_data_8188e   *pHalData = GET_HAL_DATA(Adapter);
 102        u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, offset;
 103        u8 ThermalValue_AVG_count = 0;
 104        u32 ThermalValue_AVG = 0;
 105        s32 ele_A = 0, ele_D, TempCCk, X, value32;
 106        s32 Y, ele_C = 0;
 107        s8 OFDM_index[2], CCK_index = 0;
 108        s8 OFDM_index_old[2] = {0, 0}, CCK_index_old = 0;
 109        u32 i = 0, j = 0;
 110        bool is2t = false;
 111
 112        u8 OFDM_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
 113        u8 Indexforchannel = 0/*GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/;
 114        s8 OFDM_index_mapping[2][index_mapping_NUM_88E] = {
 115                {0, 0, 2, 3, 4, 4,              /* 2.4G, decrease power */
 116                5, 6, 7, 7, 8, 9,
 117                10, 10, 11}, /*  For lower temperature, 20120220 updated on 20120220. */
 118                {0, 0, -1, -2, -3, -4,          /* 2.4G, increase power */
 119                -4, -4, -4, -5, -7, -8,
 120                -9, -9, -10},
 121        };
 122        u8 Thermal_mapping[2][index_mapping_NUM_88E] = {
 123                {0, 2, 4, 6, 8, 10,             /* 2.4G, decrease power */
 124                12, 14, 16, 18, 20, 22,
 125                24, 26, 27},
 126                {0, 2, 4, 6, 8, 10,             /* 2.4G,, increase power */
 127                12, 14, 16, 18, 20, 22,
 128                25, 25, 25},
 129        };
 130        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 131
 132        /*  2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
 133        odm_TxPwrTrackSetPwr88E(dm_odm);
 134
 135        dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; /* cosa add for debug */
 136        dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
 137
 138        /*  <Kordan> RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */
 139        dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
 140
 141        ThermalValue = (u8)ODM_GetRFReg(dm_odm, RF_PATH_A, RF_T_METER_88E, 0xfc00);     /* 0x42: RF Reg[15:10] 88E */
 142
 143        if (is2t)
 144                rf = 2;
 145        else
 146                rf = 1;
 147
 148        if (ThermalValue) {
 149                /* Query OFDM path A default setting */
 150                ele_D = ODM_GetBBReg(dm_odm, rOFDM0_XATxIQImbalance, bMaskDWord) & bMaskOFDM_D;
 151                for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {     /* find the index */
 152                        if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) {
 153                                OFDM_index_old[0] = (u8)i;
 154                                dm_odm->BbSwingIdxOfdmBase = (u8)i;
 155                                break;
 156                        }
 157                }
 158
 159                /* Query OFDM path B default setting */
 160                if (is2t) {
 161                        ele_D = ODM_GetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord) & bMaskOFDM_D;
 162                        for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {     /* find the index */
 163                                if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) {
 164                                        OFDM_index_old[1] = (u8)i;
 165                                        break;
 166                                }
 167                        }
 168                }
 169
 170                /* Query CCK default setting From 0xa24 */
 171                TempCCk = dm_odm->RFCalibrateInfo.RegA24;
 172
 173                for (i = 0; i < CCK_TABLE_SIZE; i++) {
 174                        if (dm_odm->RFCalibrateInfo.bCCKinCH14) {
 175                                if (ODM_CompareMemory(dm_odm, (void *)&TempCCk, (void *)&CCKSwingTable_Ch14[i][2], 4) == 0) {
 176                                        CCK_index_old = (u8)i;
 177                                        dm_odm->BbSwingIdxCckBase = (u8)i;
 178                                        break;
 179                                }
 180                        } else {
 181                                if (ODM_CompareMemory(dm_odm, (void *)&TempCCk, (void *)&CCKSwingTable_Ch1_Ch13[i][2], 4) == 0) {
 182                                        CCK_index_old = (u8)i;
 183                                        dm_odm->BbSwingIdxCckBase = (u8)i;
 184                                        break;
 185                                }
 186                        }
 187                }
 188
 189                if (!dm_odm->RFCalibrateInfo.ThermalValue) {
 190                        dm_odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter;
 191                        dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
 192                        dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
 193
 194                        for (i = 0; i < rf; i++)
 195                                dm_odm->RFCalibrateInfo.OFDM_index[i] = OFDM_index_old[i];
 196                        dm_odm->RFCalibrateInfo.CCK_index = CCK_index_old;
 197                }
 198
 199                /* calculate average thermal meter */
 200                dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue;
 201                dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++;
 202                if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
 203                        dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
 204
 205                for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
 206                        if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
 207                                ThermalValue_AVG += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i];
 208                                ThermalValue_AVG_count++;
 209                        }
 210                }
 211
 212                if (ThermalValue_AVG_count)
 213                        ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count);
 214
 215                if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) {
 216                        delta = ThermalValue > pHalData->EEPROMThermalMeter ?
 217                                (ThermalValue - pHalData->EEPROMThermalMeter) :
 218                                (pHalData->EEPROMThermalMeter - ThermalValue);
 219                        dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false;
 220                        dm_odm->RFCalibrateInfo.bDoneTxpower = false;
 221                } else if (dm_odm->RFCalibrateInfo.bDoneTxpower) {
 222                        delta = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue) ?
 223                                (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue) :
 224                                (dm_odm->RFCalibrateInfo.ThermalValue - ThermalValue);
 225                } else {
 226                        delta = ThermalValue > pHalData->EEPROMThermalMeter ?
 227                                (ThermalValue - pHalData->EEPROMThermalMeter) :
 228                                (pHalData->EEPROMThermalMeter - ThermalValue);
 229                }
 230                delta_LCK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_LCK) ?
 231                            (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_LCK) :
 232                            (dm_odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue);
 233                delta_IQK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_IQK) ?
 234                            (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_IQK) :
 235                            (dm_odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue);
 236
 237                if ((delta_LCK >= 8)) { /*  Delta temperature is equal to or larger than 20 centigrade. */
 238                        dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
 239                        PHY_LCCalibrate_8188E(Adapter);
 240                }
 241
 242                if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
 243                        delta = ThermalValue > pHalData->EEPROMThermalMeter ?
 244                                (ThermalValue - pHalData->EEPROMThermalMeter) :
 245                                (pHalData->EEPROMThermalMeter - ThermalValue);
 246                        /* calculate new OFDM / CCK offset */
 247                        if (ThermalValue > pHalData->EEPROMThermalMeter)
 248                                j = 1;
 249                        else
 250                                j = 0;
 251                        for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
 252                                if (delta < Thermal_mapping[j][offset]) {
 253                                        if (offset != 0)
 254                                                offset--;
 255                                        break;
 256                                }
 257                        }
 258                        if (offset >= index_mapping_NUM_88E)
 259                                offset = index_mapping_NUM_88E - 1;
 260                        for (i = 0; i < rf; i++)
 261                                OFDM_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + OFDM_index_mapping[j][offset];
 262                        CCK_index = dm_odm->RFCalibrateInfo.CCK_index + OFDM_index_mapping[j][offset];
 263
 264                        for (i = 0; i < rf; i++) {
 265                                if (OFDM_index[i] > OFDM_TABLE_SIZE_92D - 1)
 266                                        OFDM_index[i] = OFDM_TABLE_SIZE_92D - 1;
 267                                else if (OFDM_index[i] < OFDM_min_index)
 268                                        OFDM_index[i] = OFDM_min_index;
 269                        }
 270
 271                        if (CCK_index > CCK_TABLE_SIZE - 1)
 272                                CCK_index = CCK_TABLE_SIZE - 1;
 273                        else if (CCK_index < 0)
 274                                CCK_index = 0;
 275
 276                        /* 2 temporarily remove bNOPG */
 277                        /* Config by SwingTable */
 278                        if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
 279                                dm_odm->RFCalibrateInfo.bDoneTxpower = true;
 280
 281                                /* Adujst OFDM Ant_A according to IQK result */
 282                                ele_D = (OFDMSwingTable[(u8)OFDM_index[0]] & 0xFFC00000) >> 22;
 283                                X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][0];
 284                                Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][1];
 285
 286                                /*  Revse TX power table. */
 287                                dm_odm->BbSwingIdxOfdm          = (u8)OFDM_index[0];
 288                                dm_odm->BbSwingIdxCck           = (u8)CCK_index;
 289
 290                                if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
 291                                        dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
 292                                        dm_odm->BbSwingFlagOfdm = true;
 293                                }
 294
 295                                if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
 296                                        dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
 297                                        dm_odm->BbSwingFlagCck = true;
 298                                }
 299
 300                                if (X != 0) {
 301                                        if ((X & 0x00000200) != 0)
 302                                                X = X | 0xFFFFFC00;
 303                                        ele_A = ((X * ele_D) >> 8) & 0x000003FF;
 304
 305                                        /* new element C = element D x Y */
 306                                        if ((Y & 0x00000200) != 0)
 307                                                Y = Y | 0xFFFFFC00;
 308                                        ele_C = ((Y * ele_D) >> 8) & 0x000003FF;
 309
 310                                        /*  2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
 311                                        /*  to increase TX power. Otherwise, EVM will be bad. */
 312                                }
 313
 314                                if (is2t) {
 315                                        ele_D = (OFDMSwingTable[(u8)OFDM_index[1]] & 0xFFC00000) >> 22;
 316
 317                                        /* new element A = element D x X */
 318                                        X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][4];
 319                                        Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][5];
 320
 321                                        if ((X != 0) && (*dm_odm->pBandType == ODM_BAND_2_4G)) {
 322                                                if ((X & 0x00000200) != 0)      /* consider minus */
 323                                                        X = X | 0xFFFFFC00;
 324                                                ele_A = ((X * ele_D) >> 8) & 0x000003FF;
 325
 326                                                /* new element C = element D x Y */
 327                                                if ((Y & 0x00000200) != 0)
 328                                                        Y = Y | 0xFFFFFC00;
 329                                                ele_C = ((Y * ele_D) >> 8) & 0x00003FF;
 330
 331                                                /* wtite new elements A, C, D to regC88 and regC9C, element B is always 0 */
 332                                                value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
 333                                                ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
 334
 335                                                value32 = (ele_C & 0x000003C0) >> 6;
 336                                                ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
 337
 338                                                value32 = ((X * ele_D) >> 7) & 0x01;
 339                                                ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(28), value32);
 340                                        } else {
 341                                                ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable[(u8)OFDM_index[1]]);
 342                                                ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
 343                                                ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(28), 0x00);
 344                                        }
 345                                }
 346                        }
 347                }
 348
 349                if (delta_IQK >= 8) { /*  Delta temperature is equal to or larger than 20 centigrade. */
 350                        dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
 351                        PHY_IQCalibrate_8188E(Adapter, false);
 352                }
 353                /* update thermal meter value */
 354                if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
 355                        dm_odm->RFCalibrateInfo.ThermalValue = ThermalValue;
 356        }
 357        dm_odm->RFCalibrateInfo.TXPowercount = 0;
 358}
 359
 360/* 1 7. IQK */
 361#define MAX_TOLERANCE           5
 362#define IQK_DELAY_TIME          1               /* ms */
 363
 364static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 365phy_PathA_IQK_8188E(struct adapter *adapt, bool configPathB)
 366{
 367        u32 regeac, regE94, regE9C;
 368        u8 result = 0x00;
 369        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 370        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 371
 372        /* 1 Tx IQK */
 373        /* path-A IQK setting */
 374        ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
 375        ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
 376        ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x8214032a);
 377        ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
 378
 379        /* LO calibration setting */
 380        ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
 381
 382        /* One shot, path A LOK & IQK */
 383        ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 384        ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 385
 386        /*  delay x ms */
 387        /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
 388        ODM_delay_ms(IQK_DELAY_TIME_88E);
 389
 390        /*  Check failed */
 391        regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord);
 392        regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord);
 393        regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord);
 394
 395        if (!(regeac & BIT(28)) &&
 396            (((regE94 & 0x03FF0000) >> 16) != 0x142) &&
 397            (((regE9C & 0x03FF0000) >> 16) != 0x42))
 398                result |= 0x01;
 399        return result;
 400}
 401
 402static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 403phy_PathA_RxIQK(struct adapter *adapt, bool configPathB)
 404{
 405        u32 regeac, regE94, regE9C, regEA4, u4tmp;
 406        u8 result = 0x00;
 407        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 408        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 409
 410        /* 1 Get TXIMR setting */
 411        /* modify RXIQK mode table */
 412        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
 413        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
 414        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
 415        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
 416        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
 417
 418        /* PA,PAD off */
 419        ODM_SetRFReg(dm_odm, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
 420        ODM_SetRFReg(dm_odm, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
 421
 422        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000);
 423
 424        /* IQK setting */
 425        ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, 0x01007c00);
 426        ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x81004800);
 427
 428        /* path-A IQK setting */
 429        ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
 430        ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
 431        ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
 432        ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
 433
 434        /* LO calibration setting */
 435        ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
 436
 437        /* One shot, path A LOK & IQK */
 438        ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 439        ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 440
 441        /*  delay x ms */
 442        ODM_delay_ms(IQK_DELAY_TIME_88E);
 443
 444        /*  Check failed */
 445        regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord);
 446        regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord);
 447        regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord);
 448
 449        if (!(regeac & BIT(28)) &&
 450            (((regE94 & 0x03FF0000) >> 16) != 0x142) &&
 451            (((regE9C & 0x03FF0000) >> 16) != 0x42))
 452                result |= 0x01;
 453        else                                                    /* if Tx not OK, ignore Rx */
 454                return result;
 455
 456        u4tmp = 0x80007C00 | (regE94 & 0x3FF0000)  | ((regE9C & 0x3FF0000) >> 16);
 457        ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, u4tmp);
 458
 459        /* 1 RX IQK */
 460        /* modify RXIQK mode table */
 461        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
 462        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
 463        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
 464        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
 465        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
 466        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000);
 467
 468        /* IQK setting */
 469        ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x01004800);
 470
 471        /* path-A IQK setting */
 472        ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
 473        ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
 474        ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
 475        ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
 476
 477        /* LO calibration setting */
 478        ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
 479
 480        /* One shot, path A LOK & IQK */
 481        ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
 482        ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
 483
 484        /*  delay x ms */
 485        /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
 486        ODM_delay_ms(IQK_DELAY_TIME_88E);
 487
 488        /*  Check failed */
 489        regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord);
 490        regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord);
 491        regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord);
 492        regEA4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord);
 493
 494        /* reload RF 0xdf */
 495        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
 496        ODM_SetRFReg(dm_odm, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
 497
 498        if (!(regeac & BIT(27)) &&              /* if Tx is OK, check whether Rx is OK */
 499            (((regEA4 & 0x03FF0000) >> 16) != 0x132) &&
 500            (((regeac & 0x03FF0000) >> 16) != 0x36))
 501                result |= 0x02;
 502
 503        return result;
 504}
 505
 506static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
 507phy_PathB_IQK_8188E(struct adapter *adapt)
 508{
 509        u32 regeac, regeb4, regebc, regec4, regecc;
 510        u8 result = 0x00;
 511        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 512        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 513
 514        /* One shot, path B LOK & IQK */
 515        ODM_SetBBReg(dm_odm, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
 516        ODM_SetBBReg(dm_odm, rIQK_AGC_Cont, bMaskDWord, 0x00000000);
 517
 518        /*  delay x ms */
 519        ODM_delay_ms(IQK_DELAY_TIME_88E);
 520
 521        /*  Check failed */
 522        regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord);
 523        regeb4 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord);
 524        regebc = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord);
 525        regec4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_B_2, bMaskDWord);
 526        regecc = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_B_2, bMaskDWord);
 527
 528        if (!(regeac & BIT(31)) &&
 529            (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&
 530            (((regebc & 0x03FF0000) >> 16) != 0x42))
 531                result |= 0x01;
 532        else
 533                return result;
 534
 535        if (!(regeac & BIT(30)) &&
 536            (((regec4 & 0x03FF0000) >> 16) != 0x132) &&
 537            (((regecc & 0x03FF0000) >> 16) != 0x36))
 538                result |= 0x02;
 539
 540        return result;
 541}
 542
 543static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly)
 544{
 545        u32 Oldval_0, X, TX0_A, reg;
 546        s32 Y, TX0_C;
 547        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 548        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 549
 550        if (final_candidate == 0xFF) {
 551                return;
 552        } else if (iqkok) {
 553                Oldval_0 = (ODM_GetBBReg(dm_odm, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
 554
 555                X = result[final_candidate][0];
 556                if ((X & 0x00000200) != 0)
 557                        X = X | 0xFFFFFC00;
 558                TX0_A = (X * Oldval_0) >> 8;
 559                ODM_SetBBReg(dm_odm, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A);
 560
 561                ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0 >> 7) & 0x1));
 562
 563                Y = result[final_candidate][1];
 564                if ((Y & 0x00000200) != 0)
 565                        Y = Y | 0xFFFFFC00;
 566
 567                TX0_C = (Y * Oldval_0) >> 8;
 568                ODM_SetBBReg(dm_odm, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6));
 569                ODM_SetBBReg(dm_odm, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C & 0x3F));
 570
 571                ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0 >> 7) & 0x1));
 572
 573                if (txonly)
 574                        return;
 575
 576                reg = result[final_candidate][2];
 577                ODM_SetBBReg(dm_odm, rOFDM0_XARxIQImbalance, 0x3FF, reg);
 578
 579                reg = result[final_candidate][3] & 0x3F;
 580                ODM_SetBBReg(dm_odm, rOFDM0_XARxIQImbalance, 0xFC00, reg);
 581
 582                reg = (result[final_candidate][3] >> 6) & 0xF;
 583                ODM_SetBBReg(dm_odm, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
 584        }
 585}
 586
 587static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly)
 588{
 589        u32 Oldval_1, X, TX1_A, reg;
 590        s32 Y, TX1_C;
 591        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 592        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 593
 594        if (final_candidate == 0xFF) {
 595                return;
 596        } else if (iqkok) {
 597                Oldval_1 = (ODM_GetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
 598
 599                X = result[final_candidate][4];
 600                if ((X & 0x00000200) != 0)
 601                        X = X | 0xFFFFFC00;
 602                TX1_A = (X * Oldval_1) >> 8;
 603                ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A);
 604
 605                ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(27), ((X * Oldval_1 >> 7) & 0x1));
 606
 607                Y = result[final_candidate][5];
 608                if ((Y & 0x00000200) != 0)
 609                        Y = Y | 0xFFFFFC00;
 610
 611                TX1_C = (Y * Oldval_1) >> 8;
 612                ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C & 0x3C0) >> 6));
 613                ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C & 0x3F));
 614
 615                ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(25), ((Y * Oldval_1 >> 7) & 0x1));
 616
 617                if (txonly)
 618                        return;
 619
 620                reg = result[final_candidate][6];
 621                ODM_SetBBReg(dm_odm, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
 622
 623                reg = result[final_candidate][7] & 0x3F;
 624                ODM_SetBBReg(dm_odm, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
 625
 626                reg = (result[final_candidate][7] >> 6) & 0xF;
 627                ODM_SetBBReg(dm_odm, rOFDM0_AGCRSSITable, 0x0000F000, reg);
 628        }
 629}
 630
 631/*  */
 632/*  2011/07/26 MH Add an API for testing IQK fail case. */
 633/*  */
 634/*  MP Already declare in odm.c */
 635static bool ODM_CheckPowerStatus(struct adapter *Adapter)
 636{
 637        return  true;
 638}
 639
 640void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum)
 641{
 642        u32 i;
 643        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 644        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 645
 646        if (!ODM_CheckPowerStatus(adapt))
 647                return;
 648
 649        for (i = 0; i < RegisterNum; i++) {
 650                ADDABackup[i] = ODM_GetBBReg(dm_odm, ADDAReg[i], bMaskDWord);
 651        }
 652}
 653
 654static void _PHY_SaveMACRegisters(
 655                struct adapter *adapt,
 656                u32 *MACReg,
 657                u32 *MACBackup
 658        )
 659{
 660        u32 i;
 661        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 662        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 663        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
 664                MACBackup[i] = ODM_Read1Byte(dm_odm, MACReg[i]);
 665        }
 666        MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
 667}
 668
 669static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
 670{
 671        u32 i;
 672        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 673        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 674
 675        for (i = 0; i < RegiesterNum; i++)
 676                ODM_SetBBReg(dm_odm, ADDAReg[i], bMaskDWord, ADDABackup[i]);
 677}
 678
 679static void
 680_PHY_ReloadMACRegisters(
 681                struct adapter *adapt,
 682                u32 *MACReg,
 683                u32 *MACBackup
 684        )
 685{
 686        u32 i;
 687        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 688        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 689
 690        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
 691                ODM_Write1Byte(dm_odm, MACReg[i], (u8)MACBackup[i]);
 692        }
 693        ODM_Write4Byte(dm_odm, MACReg[i], MACBackup[i]);
 694}
 695
 696void
 697_PHY_PathADDAOn(
 698                struct adapter *adapt,
 699                u32 *ADDAReg,
 700                bool isPathAOn,
 701                bool is2t
 702        )
 703{
 704        u32 pathOn;
 705        u32 i;
 706        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 707        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 708
 709        pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4;
 710        if (!is2t) {
 711                pathOn = 0x0bdb25a0;
 712                ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, 0x0b1b25a0);
 713        } else {
 714                ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, pathOn);
 715        }
 716
 717        for (i = 1; i < IQK_ADDA_REG_NUM; i++)
 718                ODM_SetBBReg(dm_odm, ADDAReg[i], bMaskDWord, pathOn);
 719}
 720
 721void
 722_PHY_MACSettingCalibration(
 723                struct adapter *adapt,
 724                u32 *MACReg,
 725                u32 *MACBackup
 726        )
 727{
 728        u32 i = 0;
 729        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 730        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 731
 732        ODM_Write1Byte(dm_odm, MACReg[i], 0x3F);
 733
 734        for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
 735                ODM_Write1Byte(dm_odm, MACReg[i], (u8)(MACBackup[i] & (~BIT(3))));
 736        }
 737        ODM_Write1Byte(dm_odm, MACReg[i], (u8)(MACBackup[i] & (~BIT(5))));
 738}
 739
 740void
 741_PHY_PathAStandBy(
 742        struct adapter *adapt
 743        )
 744{
 745        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 746        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 747
 748        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x0);
 749        ODM_SetBBReg(dm_odm, 0x840, bMaskDWord, 0x00010000);
 750        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000);
 751}
 752
 753static void _PHY_PIModeSwitch(
 754                struct adapter *adapt,
 755                bool PIMode
 756        )
 757{
 758        u32 mode;
 759        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 760        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 761
 762        mode = PIMode ? 0x01000100 : 0x01000000;
 763        ODM_SetBBReg(dm_odm, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
 764        ODM_SetBBReg(dm_odm, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
 765}
 766
 767static bool phy_SimularityCompare_8188E(
 768                struct adapter *adapt,
 769                s32 resulta[][8],
 770                u8  c1,
 771                u8  c2
 772        )
 773{
 774        u32 i, j, diff, sim_bitmap, bound = 0;
 775        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 776        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 777        u8 final_candidate[2] = {0xFF, 0xFF};   /* for path A and path B */
 778        bool result = true;
 779        bool is2t;
 780        s32 tmp1 = 0, tmp2 = 0;
 781
 782        if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) || (dm_odm->RFType == ODM_2T4R))
 783                is2t = true;
 784        else
 785                is2t = false;
 786
 787        if (is2t)
 788                bound = 8;
 789        else
 790                bound = 4;
 791
 792        sim_bitmap = 0;
 793
 794        for (i = 0; i < bound; i++) {
 795                if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
 796                        if ((resulta[c1][i] & 0x00000200) != 0)
 797                                tmp1 = resulta[c1][i] | 0xFFFFFC00;
 798                        else
 799                                tmp1 = resulta[c1][i];
 800
 801                        if ((resulta[c2][i] & 0x00000200) != 0)
 802                                tmp2 = resulta[c2][i] | 0xFFFFFC00;
 803                        else
 804                                tmp2 = resulta[c2][i];
 805                } else {
 806                        tmp1 = resulta[c1][i];
 807                        tmp2 = resulta[c2][i];
 808                }
 809
 810                diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
 811
 812                if (diff > MAX_TOLERANCE) {
 813                        if ((i == 2 || i == 6) && !sim_bitmap) {
 814                                if (resulta[c1][i] + resulta[c1][i + 1] == 0)
 815                                        final_candidate[(i / 4)] = c2;
 816                                else if (resulta[c2][i] + resulta[c2][i + 1] == 0)
 817                                        final_candidate[(i / 4)] = c1;
 818                                else
 819                                        sim_bitmap = sim_bitmap | (1 << i);
 820                        } else {
 821                                sim_bitmap = sim_bitmap | (1 << i);
 822                        }
 823                }
 824        }
 825
 826        if (sim_bitmap == 0) {
 827                for (i = 0; i < (bound / 4); i++) {
 828                        if (final_candidate[i] != 0xFF) {
 829                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
 830                                        resulta[3][j] = resulta[final_candidate[i]][j];
 831                                result = false;
 832                        }
 833                }
 834                return result;
 835        } else {
 836                if (!(sim_bitmap & 0x03)) {                /* path A TX OK */
 837                        for (i = 0; i < 2; i++)
 838                                resulta[3][i] = resulta[c1][i];
 839                }
 840                if (!(sim_bitmap & 0x0c)) {                /* path A RX OK */
 841                        for (i = 2; i < 4; i++)
 842                                resulta[3][i] = resulta[c1][i];
 843                }
 844
 845                if (!(sim_bitmap & 0x30)) { /* path B TX OK */
 846                        for (i = 4; i < 6; i++)
 847                                resulta[3][i] = resulta[c1][i];
 848                }
 849
 850                if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
 851                        for (i = 6; i < 8; i++)
 852                                resulta[3][i] = resulta[c1][i];
 853                }
 854                return false;
 855        }
 856}
 857
 858static void phy_IQCalibrate_8188E(struct adapter *adapt, s32 result[][8], u8 t, bool is2t)
 859{
 860        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
 861        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 862        u32 i;
 863        u8 PathAOK, PathBOK;
 864        u32 ADDA_REG[IQK_ADDA_REG_NUM] = {
 865                                                rFPGA0_XCD_SwitchControl, rBlue_Tooth,
 866                                                rRx_Wait_CCA,   rTx_CCK_RFON,
 867                                                rTx_CCK_BBON, rTx_OFDM_RFON,
 868                                                rTx_OFDM_BBON, rTx_To_Rx,
 869                                                rTx_To_Tx,      rRx_CCK,
 870                                                rRx_OFDM,       rRx_Wait_RIFS,
 871                                                rRx_TO_Rx,      rStandby,
 872                                                rSleep,                         rPMPD_ANAEN };
 873        u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = {
 874                                                REG_TXPAUSE,    REG_BCN_CTRL,
 875                                                REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
 876
 877        /* since 92C & 92D have the different define in IQK_BB_REG */
 878        u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
 879                                                        rOFDM0_TRxPathEnable,   rOFDM0_TRMuxPar,
 880                                                        rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
 881                                                        rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
 882                                                        rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD
 883                                                        };
 884
 885        u32 retryCount = 9;
 886        if (*dm_odm->mp_mode == 1)
 887                retryCount = 9;
 888        else
 889                retryCount = 2;
 890        /*  Note: IQ calibration must be performed after loading */
 891        /*              PHY_REG.txt , and radio_a, radio_b.txt */
 892
 893        if (t == 0) {
 894                /*  Save ADDA parameters, turn Path A ADDA on */
 895                _PHY_SaveADDARegisters(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
 896                _PHY_SaveMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
 897                _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
 898        }
 899
 900        _PHY_PathADDAOn(adapt, ADDA_REG, true, is2t);
 901        if (t == 0)
 902                dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)ODM_GetBBReg(dm_odm, rFPGA0_XA_HSSIParameter1, BIT(8));
 903
 904        if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
 905                /*  Switch BB to PI mode to do IQ Calibration. */
 906                _PHY_PIModeSwitch(adapt, true);
 907        }
 908
 909        /* BB setting */
 910        ODM_SetBBReg(dm_odm, rFPGA0_RFMOD, BIT(24), 0x00);
 911        ODM_SetBBReg(dm_odm, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
 912        ODM_SetBBReg(dm_odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
 913        ODM_SetBBReg(dm_odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
 914
 915        ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01);
 916        ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01);
 917        ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00);
 918        ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00);
 919
 920        if (is2t) {
 921                ODM_SetBBReg(dm_odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000);
 922                ODM_SetBBReg(dm_odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000);
 923        }
 924
 925        /* MAC settings */
 926        _PHY_MACSettingCalibration(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
 927
 928        /* Page B init */
 929        /* AP or IQK */
 930        ODM_SetBBReg(dm_odm, rConfig_AntA, bMaskDWord, 0x0f600000);
 931
 932        if (is2t)
 933                ODM_SetBBReg(dm_odm, rConfig_AntB, bMaskDWord, 0x0f600000);
 934
 935        /*  IQ calibration setting */
 936        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000);
 937        ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, 0x01007c00);
 938        ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x81004800);
 939
 940        for (i = 0; i < retryCount; i++) {
 941                PathAOK = phy_PathA_IQK_8188E(adapt, is2t);
 942                if (PathAOK == 0x01) {
 943                        result[t][0] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16;
 944                        result[t][1] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16;
 945                        break;
 946                }
 947        }
 948
 949        for (i = 0; i < retryCount; i++) {
 950                PathAOK = phy_PathA_RxIQK(adapt, is2t);
 951                if (PathAOK == 0x03) {
 952                        result[t][2] = (ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16;
 953                        result[t][3] = (ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16;
 954                        break;
 955                }
 956        }
 957
 958        if (is2t) {
 959                _PHY_PathAStandBy(adapt);
 960
 961                /*  Turn Path B ADDA on */
 962                _PHY_PathADDAOn(adapt, ADDA_REG, false, is2t);
 963
 964                for (i = 0; i < retryCount; i++) {
 965                        PathBOK = phy_PathB_IQK_8188E(adapt);
 966                        if (PathBOK == 0x03) {
 967                                result[t][4] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord) & 0x3FF0000) >> 16;
 968                                result[t][5] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord) & 0x3FF0000) >> 16;
 969                                result[t][6] = (ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_B_2, bMaskDWord) & 0x3FF0000) >> 16;
 970                                result[t][7] = (ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_B_2, bMaskDWord) & 0x3FF0000) >> 16;
 971                                break;
 972                        } else if (i == (retryCount - 1) && PathBOK == 0x01) {  /* Tx IQK OK */
 973                                result[t][4] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord) & 0x3FF0000) >> 16;
 974                                result[t][5] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord) & 0x3FF0000) >> 16;
 975                        }
 976                }
 977        }
 978
 979        /* Back to BB mode, load original value */
 980        ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0);
 981
 982        if (t != 0) {
 983                if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
 984                        /*  Switch back BB to SI mode after finish IQ Calibration. */
 985                        _PHY_PIModeSwitch(adapt, false);
 986                }
 987
 988                /*  Reload ADDA power saving parameters */
 989                reload_adda_reg(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
 990
 991                /*  Reload MAC parameters */
 992                _PHY_ReloadMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
 993
 994                reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
 995
 996                /*  Restore RX initial gain */
 997                ODM_SetBBReg(dm_odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3);
 998                if (is2t)
 999                        ODM_SetBBReg(dm_odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00032ed3);
1000
1001                /* load 0xe30 IQC default value */
1002                ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1003                ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1004        }
1005}
1006
1007static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
1008{
1009        u8 tmpreg;
1010        u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
1011        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1012        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1013
1014        /* Check continuous TX and Packet TX */
1015        tmpreg = ODM_Read1Byte(dm_odm, 0xd03);
1016
1017        if ((tmpreg & 0x70) != 0)                       /* Deal with contisuous TX case */
1018                ODM_Write1Byte(dm_odm, 0xd03, tmpreg & 0x8F);   /* disable all continuous TX */
1019        else                                                    /*  Deal with Packet TX case */
1020                ODM_Write1Byte(dm_odm, REG_TXPAUSE, 0xFF);                      /*  block all queues */
1021
1022        if ((tmpreg & 0x70) != 0) {
1023                /* 1. Read original RF mode */
1024                /* Path-A */
1025                RF_Amode = PHY_QueryRFReg(adapt, RF_PATH_A, RF_AC, bMask12Bits);
1026
1027                /* Path-B */
1028                if (is2t)
1029                        RF_Bmode = PHY_QueryRFReg(adapt, RF_PATH_B, RF_AC, bMask12Bits);
1030
1031                /* 2. Set RF mode = standby mode */
1032                /* Path-A */
1033                ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode & 0x8FFFF) | 0x10000);
1034
1035                /* Path-B */
1036                if (is2t)
1037                        ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode & 0x8FFFF) | 0x10000);
1038        }
1039
1040        /* 3. Read RF reg18 */
1041        LC_Cal = PHY_QueryRFReg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1042
1043        /* 4. Set LC calibration begin  bit15 */
1044        ODM_SetRFReg(dm_odm, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal | 0x08000);
1045
1046        ODM_sleep_ms(100);
1047
1048        /* Restore original situation */
1049        if ((tmpreg & 0x70) != 0) {
1050                /* Deal with continuous TX case */
1051                /* Path-A */
1052                ODM_Write1Byte(dm_odm, 0xd03, tmpreg);
1053                ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode);
1054
1055                /* Path-B */
1056                if (is2t)
1057                        ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode);
1058        } else {
1059                /*  Deal with Packet TX case */
1060                ODM_Write1Byte(dm_odm, REG_TXPAUSE, 0x00);
1061        }
1062}
1063
1064void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
1065{
1066        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1067        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1068        struct mpt_context *pMptCtx = &adapt->mppriv.MptCtx;
1069        s32 result[4][8];       /* last is final result */
1070        u8 i, final_candidate;
1071        bool pathaok, pathbok;
1072        s32 RegE94, RegE9C, RegEA4, RegEB4, RegEBC, RegEC4;
1073        bool is12simular, is13simular, is23simular;
1074        bool singletone = false, carrier_sup = false;
1075        u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
1076                rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1077                rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1078                rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1079                rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1080                rOFDM0_RxIQExtAnta};
1081        bool is2t;
1082
1083        is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1084        if (!ODM_CheckPowerStatus(adapt))
1085                return;
1086
1087        if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1088                return;
1089
1090        if (*dm_odm->mp_mode == 1) {
1091                singletone = pMptCtx->bSingleTone;
1092                carrier_sup = pMptCtx->bCarrierSuppression;
1093        }
1094
1095        /*  20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1096        if (singletone || carrier_sup)
1097                return;
1098
1099        if (recovery) {
1100                reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1101                return;
1102        }
1103
1104        for (i = 0; i < 8; i++) {
1105                result[0][i] = 0;
1106                result[1][i] = 0;
1107                result[2][i] = 0;
1108                if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
1109                        result[3][i] = 0x100;
1110                else
1111                        result[3][i] = 0;
1112        }
1113        final_candidate = 0xff;
1114        pathaok = false;
1115        pathbok = false;
1116        is12simular = false;
1117        is23simular = false;
1118        is13simular = false;
1119
1120        for (i = 0; i < 3; i++) {
1121                phy_IQCalibrate_8188E(adapt, result, i, is2t);
1122
1123                if (i == 1) {
1124                        is12simular = phy_SimularityCompare_8188E(adapt, result, 0, 1);
1125                        if (is12simular) {
1126                                final_candidate = 0;
1127                                break;
1128                        }
1129                }
1130
1131                if (i == 2) {
1132                        is13simular = phy_SimularityCompare_8188E(adapt, result, 0, 2);
1133                        if (is13simular) {
1134                                final_candidate = 0;
1135
1136                                break;
1137                        }
1138                        is23simular = phy_SimularityCompare_8188E(adapt, result, 1, 2);
1139                        if (is23simular) {
1140                                final_candidate = 1;
1141                        } else {
1142                                final_candidate = 3;
1143                        }
1144                }
1145        }
1146
1147        for (i = 0; i < 4; i++) {
1148                RegE94 = result[i][0];
1149                RegE9C = result[i][1];
1150                RegEA4 = result[i][2];
1151                RegEB4 = result[i][4];
1152                RegEBC = result[i][5];
1153                RegEC4 = result[i][6];
1154        }
1155
1156        if (final_candidate != 0xff) {
1157                RegE94 = result[final_candidate][0];
1158                RegE9C = result[final_candidate][1];
1159                RegEA4 = result[final_candidate][2];
1160                RegEB4 = result[final_candidate][4];
1161                RegEBC = result[final_candidate][5];
1162                dm_odm->RFCalibrateInfo.RegE94 = RegE94;
1163                dm_odm->RFCalibrateInfo.RegE9C = RegE9C;
1164                dm_odm->RFCalibrateInfo.RegEB4 = RegEB4;
1165                dm_odm->RFCalibrateInfo.RegEBC = RegEBC;
1166                RegEC4 = result[final_candidate][6];
1167                pathaok = true;
1168                pathbok = true;
1169        } else {
1170                dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1171                dm_odm->RFCalibrateInfo.RegEB4 = 0x100; /* X default value */
1172                dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1173                dm_odm->RFCalibrateInfo.RegEBC = 0x0;   /* Y default value */
1174        }
1175        if (RegE94 != 0)
1176                patha_fill_iqk(adapt, pathaok, result, final_candidate, (RegEA4 == 0));
1177        if (is2t) {
1178                if (RegEB4 != 0)
1179                        pathb_fill_iqk(adapt, pathbok, result, final_candidate, (RegEC4 == 0));
1180        }
1181
1182/* To Fix BSOD when final_candidate is 0xff */
1183/* by sherry 20120321 */
1184        if (final_candidate < 4) {
1185                for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1186                        dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[0].Value[0][i] = result[final_candidate][i];
1187                dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[0].bIQKDone = true;
1188        }
1189
1190        _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1191}
1192
1193void PHY_LCCalibrate_8188E(struct adapter *adapt)
1194{
1195        bool singletone = false, carrier_sup = false;
1196        u32 timeout = 2000, timecount = 0;
1197        struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt);
1198        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1199        struct mpt_context *pMptCtx = &adapt->mppriv.MptCtx;
1200
1201        if (*dm_odm->mp_mode == 1) {
1202                singletone = pMptCtx->bSingleTone;
1203                carrier_sup = pMptCtx->bCarrierSuppression;
1204        }
1205        if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1206                return;
1207        /*  20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1208        if (singletone || carrier_sup)
1209                return;
1210
1211        while (*dm_odm->pbScanInProcess && timecount < timeout) {
1212                ODM_delay_ms(50);
1213                timecount += 50;
1214        }
1215
1216        dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1217
1218        if (dm_odm->RFType == ODM_2T2R) {
1219                phy_LCCalibrate_8188E(adapt, true);
1220        } else {
1221                /*  For 88C 1T1R */
1222                phy_LCCalibrate_8188E(adapt, false);
1223        }
1224
1225        dm_odm->RFCalibrateInfo.bLCKInProgress = false;
1226}
1227
1228static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2t)
1229{
1230        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1231        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1232
1233        if (!adapt->hw_init_completed) {
1234                u8 u1btmp;
1235                u1btmp = ODM_Read1Byte(dm_odm, REG_LEDCFG2) | BIT(7);
1236                ODM_Write1Byte(dm_odm, REG_LEDCFG2, u1btmp);
1237                ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
1238        }
1239
1240        if (is2t) {     /* 92C */
1241                if (main)
1242                        ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(5) | BIT(6), 0x1);    /* 92C_Path_A */
1243                else
1244                        ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(5) | BIT(6), 0x2);    /* BT */
1245        } else {                        /* 88C */
1246                if (main)
1247                        ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(8) | BIT(9), 0x2);    /* Main */
1248                else
1249                        ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(8) | BIT(9), 0x1);    /* Aux */
1250        }
1251}
1252
1253void PHY_SetRFPathSwitch_8188E(struct adapter *adapt, bool main)
1254{
1255        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1256        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1257
1258        if (dm_odm->RFType == ODM_2T2R) {
1259                phy_setrfpathswitch_8188e(adapt, main, true);
1260        } else {
1261                /*  For 88C 1T1R */
1262                phy_setrfpathswitch_8188e(adapt, main, false);
1263        }
1264}
1265