rtl8723cs/hal/phydm/rtl8703b/halphyrf_8703b.c
2017-01-30 21:28:09 +01:00

2229 lines
74 KiB
C

/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#include "mp_precomp.h"
#include "../phydm_precomp.h"
/*---------------------------Define Local Constant---------------------------*/
//IQK
#define IQK_DELAY_TIME_8703B 10
#define LCK_DELAY_TIME_8703B 100
/* LTE_COEX */
#define REG_LTECOEX_CTRL 0x07C0
#define REG_LTECOEX_WRITE_DATA 0x07C4
#define REG_LTECOEX_READ_DATA 0x07C8
#define REG_LTECOEX_PATH_CONTROL 0x70
// 2010/04/25 MH Define the max tx power tracking tx agc power.
#define ODM_TXPWRTRACK_MAX_IDX8703B 6
#define IDX_0xC94 0
#define IDX_0xC80 1
#define IDX_0xC4C 2
#define IDX_0xC14 0
#define IDX_0xCA0 1
#define KEY 0
#define VAL 1
/*---------------------------Define Local Constant---------------------------*/
//3============================================================
//3 Tx Power Tracking
//3============================================================
void setIqkMatrix_8703B(
PDM_ODM_T pDM_Odm,
u1Byte OFDM_index,
u1Byte RFPath,
s4Byte IqkResult_X,
s4Byte IqkResult_Y
)
{
s4Byte ele_A = 0, ele_D = 0, ele_C = 0, value32, tmp;
s4Byte ele_A_ext = 0, ele_C_ext = 0, ele_D_ext = 0;
RFPath = ODM_RF_PATH_A;
if (OFDM_index >= OFDM_TABLE_SIZE)
OFDM_index = OFDM_TABLE_SIZE-1;
else if (OFDM_index < 0)
OFDM_index = 0;
if ((IqkResult_X != 0) && (*(pDM_Odm->pBandType) == ODM_BAND_2_4G)) {
/* new element D */
ele_D = (OFDMSwingTable_New[OFDM_index] & 0xFFC00000)>>22;
ele_D_ext = (((IqkResult_X * ele_D)>>7)&0x01);
/* new element A */
if ((IqkResult_X & 0x00000200) != 0) /* consider minus */
IqkResult_X = IqkResult_X | 0xFFFFFC00;
ele_A = ((IqkResult_X * ele_D)>>8)&0x000003FF;
ele_A_ext = ((IqkResult_X * ele_D)>>7) & 0x1;
/* new element C */
if ((IqkResult_Y & 0x00000200) != 0)
IqkResult_Y = IqkResult_Y | 0xFFFFFC00;
ele_C = ((IqkResult_Y * ele_D)>>8)&0x000003FF;
ele_C_ext = ((IqkResult_Y * ele_D)>>7) & 0x1;
switch (RFPath) {
case ODM_RF_PATH_A:
/* write new elements A, C, D to regC80, regC94, reg0xc4c, and element B is always 0 */
/* write 0xc80 */
value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
ODM_SetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord, value32);
/* write 0xc94 */
value32 = (ele_C & 0x000003C0) >> 6;
ODM_SetBBReg(pDM_Odm, rOFDM0_XCTxAFE, bMaskH4Bits, value32);
/* write 0xc4c */
value32 = (ele_D_ext << 28) | (ele_A_ext << 31) | (ele_C_ext << 29);
value32 = (ODM_GetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord)&(~(BIT31|BIT29|BIT28))) | value32;
ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord, value32);
break;
case ODM_RF_PATH_B:
/* write new elements A, C, D to regC88, regC9C, regC4C, and element B is always 0 */
/* write 0xc88 */
value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
ODM_SetBBReg(pDM_Odm, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
/* write 0xc9c */
value32 = (ele_C & 0x000003C0) >> 6;
ODM_SetBBReg(pDM_Odm, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
/* write 0xc4c */
value32 = (ele_D_ext << 24) | (ele_A_ext << 27) | (ele_C_ext << 25);
value32 = (ODM_GetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord)&(~(BIT24|BIT27|BIT25))) | value32;
ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord, value32);
break;
default:
break;
}
} else {
switch (RFPath) {
case ODM_RF_PATH_A:
ODM_SetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable_New[OFDM_index]);
ODM_SetBBReg(pDM_Odm, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00);
value32 = ODM_GetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord)&(~(BIT31|BIT29|BIT28));
ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord, value32);
break;
case ODM_RF_PATH_B:
ODM_SetBBReg(pDM_Odm, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable_New[OFDM_index]);
ODM_SetBBReg(pDM_Odm, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
value32 = ODM_GetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord)&(~(BIT24|BIT27|BIT25));
ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord, value32);
break;
default:
break;
}
}
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("TxPwrTracking path %c: X = 0x%x, Y = 0x%x ele_A = 0x%x ele_C = 0x%x ele_D = 0x%x ele_A_ext = 0x%x ele_C_ext = 0x%x ele_D_ext = 0x%x\n",
(RFPath == ODM_RF_PATH_A ? 'A' : 'B'), (u4Byte)IqkResult_X, (u4Byte)IqkResult_Y, (u4Byte)ele_A, (u4Byte)ele_C, (u4Byte)ele_D, (u4Byte)ele_A_ext, (u4Byte)ele_C_ext, (u4Byte)ele_D_ext));
}
VOID
setCCKFilterCoefficient_8703B(
PDM_ODM_T pDM_Odm,
u1Byte CCKSwingIndex
)
{
ODM_Write1Byte(pDM_Odm, 0xa22, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][0]);
ODM_Write1Byte(pDM_Odm, 0xa23, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][1]);
ODM_Write1Byte(pDM_Odm, 0xa24, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][2]);
ODM_Write1Byte(pDM_Odm, 0xa25, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][3]);
ODM_Write1Byte(pDM_Odm, 0xa26, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][4]);
ODM_Write1Byte(pDM_Odm, 0xa27, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][5]);
ODM_Write1Byte(pDM_Odm, 0xa28, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][6]);
ODM_Write1Byte(pDM_Odm, 0xa29, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][7]);
ODM_Write1Byte(pDM_Odm, 0xa9a, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][8]);
ODM_Write1Byte(pDM_Odm, 0xa9b, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][9]);
ODM_Write1Byte(pDM_Odm, 0xa9c, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][10]);
ODM_Write1Byte(pDM_Odm, 0xa9d, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][11]);
ODM_Write1Byte(pDM_Odm, 0xaa0, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][12]);
ODM_Write1Byte(pDM_Odm, 0xaa1, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][13]);
ODM_Write1Byte(pDM_Odm, 0xaa2, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][14]);
ODM_Write1Byte(pDM_Odm, 0xaa3, CCKSwingTable_Ch1_Ch14_88F[CCKSwingIndex][15]);
}
void DoIQK_8703B(
PVOID pDM_VOID,
u1Byte DeltaThermalIndex,
u1Byte ThermalValue,
u1Byte Threshold
)
{
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
PADAPTER Adapter = pDM_Odm->Adapter;
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
#endif
ODM_ResetIQKResult(pDM_Odm);
pDM_Odm->RFCalibrateInfo.ThermalValue_IQK= ThermalValue;
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
PHY_IQCalibrate_8703B(pDM_Odm, FALSE);
#else
PHY_IQCalibrate_8703B(Adapter, FALSE);
#endif
}
/*-----------------------------------------------------------------------------
* Function: odm_TxPwrTrackSetPwr88E()
*
* Overview: 88E change all channel tx power accordign to flag.
* OFDM & CCK are all different.
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 04/23/2012 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
VOID
ODM_TxPwrTrackSetPwr_8703B(
IN PVOID pDM_VOID,
PWRTRACK_METHOD Method,
u1Byte RFPath,
u1Byte ChannelMappedIndex
)
{
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
PADAPTER Adapter = pDM_Odm->Adapter;
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
u1Byte PwrTrackingLimit_OFDM = 34; /* +0dB */
u1Byte PwrTrackingLimit_CCK = CCK_TABLE_SIZE_88F - 1; /* -2dB */
u1Byte TxRate = 0xFF;
u1Byte Final_OFDM_Swing_Index = 0;
u1Byte Final_CCK_Swing_Index = 0;
u1Byte i = 0;
PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN))
#if (MP_DRIVER == 1) /*win MP */
PMPT_CONTEXT pMptCtx = &(Adapter->MptCtx);
TxRate = MptToMgntRate(pMptCtx->MptRateIndex);
#else /*win normal*/
PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
if (!pMgntInfo->ForcedDataRate) { /*auto rate*/
if (pDM_Odm->TxRate != 0xFF)
TxRate = Adapter->HalFunc.GetHwRateFromMRateHandler(pDM_Odm->TxRate);
} else {
TxRate = (u1Byte) pMgntInfo->ForcedDataRate;
}
#endif
#elif (DM_ODM_SUPPORT_TYPE & (ODM_CE))
if (pDM_Odm->mp_mode == TRUE) { /*CE MP*/
PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.MptCtx);
TxRate = MptToMgntRate(pMptCtx->MptRateIndex);
} else { /*CE normal*/
u2Byte rate = *(pDM_Odm->pForcedDataRate);
if (!rate) { /*auto rate*/
if (pDM_Odm->TxRate != 0xFF)
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN))
TxRate = Adapter->HalFunc.GetHwRateFromMRateHandler(pDM_Odm->TxRate);
#elif (DM_ODM_SUPPORT_TYPE & (ODM_CE))
TxRate = HwRateToMRate(pDM_Odm->TxRate);
#endif
} else { /*force rate*/
TxRate = (u1Byte)rate;
}
}
#endif
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("===>ODM_TxPwrTrackSetPwr8703B\n"));
if (TxRate != 0xFF) {
/*2 CCK*/
if ((TxRate >= MGN_1M) && (TxRate <= MGN_11M))
PwrTrackingLimit_CCK = CCK_TABLE_SIZE_88F - 1;
/*2 OFDM*/
else if ((TxRate >= MGN_6M) && (TxRate <= MGN_48M))
PwrTrackingLimit_OFDM = 36; /*+3dB*/
else if (TxRate == MGN_54M)
PwrTrackingLimit_OFDM = 34; /*+2dB*/
/*2 HT*/
else if ((TxRate >= MGN_MCS0) && (TxRate <= MGN_MCS2)) /*QPSK/BPSK*/
PwrTrackingLimit_OFDM = 38; /*+4dB*/
else if ((TxRate >= MGN_MCS3) && (TxRate <= MGN_MCS4)) /*16QAM*/
PwrTrackingLimit_OFDM = 36; /*+3dB*/
else if ((TxRate >= MGN_MCS5) && (TxRate <= MGN_MCS7)) /*64QAM*/
PwrTrackingLimit_OFDM = 34; /*+2dB*/
else
PwrTrackingLimit_OFDM = pRFCalibrateInfo->DefaultOfdmIndex; /*Default OFDM index = 30*/
}
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("TxRate=0x%x, PwrTrackingLimit=%d\n", TxRate, PwrTrackingLimit_OFDM));
if (Method == TXAGC) {
u1Byte rf = 0;
u4Byte pwr = 0, TxAGC = 0;
PADAPTER Adapter = pDM_Odm->Adapter;
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("odm_TxPwrTrackSetPwr8703B CH=%d\n", *(pDM_Odm->pChannel)));
pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath];
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE ))
#if (MP_DRIVER != 1)
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA = TRUE;
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK = TRUE;
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, CCK);
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM);
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7);
#else
pwr = PHY_QueryBBReg(Adapter, rTxAGC_A_Rate18_06, 0xFF);
pwr += pRFCalibrateInfo->PowerIndexOffset[RFPath];
PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, pwr);
TxAGC = (pwr<<16)|(pwr<<8)|(pwr);
PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, TxAGC);
RT_DISP(FPHY, PHY_TXPWR, ("ODM_TxPwrTrackSetPwr8703B: CCK Tx-rf(A) Power = 0x%x\n", TxAGC));
pwr = PHY_QueryBBReg(Adapter, rTxAGC_A_Rate18_06, 0xFF);
pwr += (pRFCalibrateInfo->BbSwingIdxOfdm[RFPath] - pRFCalibrateInfo->BbSwingIdxOfdmBase[RFPath]);
TxAGC |= ((pwr<<24)|(pwr<<16)|(pwr<<8)|pwr);
PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC);
PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC);
PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC);
PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC);
PHY_SetBBReg(Adapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC);
PHY_SetBBReg(Adapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC);
RT_DISP(FPHY, PHY_TXPWR, ("ODM_TxPwrTrackSetPwr8703B: OFDM Tx-rf(A) Power = 0x%x\n", TxAGC));
#endif
#endif
} else if (Method == BBSWING) {
Final_OFDM_Swing_Index = pRFCalibrateInfo->DefaultOfdmIndex + pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath];
Final_CCK_Swing_Index = pRFCalibrateInfo->DefaultCckIndex + pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath];
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" pRFCalibrateInfo->DefaultOfdmIndex=%d, pRFCalibrateInfo->DefaultCCKIndex=%d, pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath]=%d, pRFCalibrateInfo->Remnant_CCKSwingIdx=%d RF_Path = %d\n",
pRFCalibrateInfo->DefaultOfdmIndex, pRFCalibrateInfo->DefaultCckIndex, pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath], pRFCalibrateInfo->Remnant_CCKSwingIdx, RFPath));
/* Adjust BB swing by OFDM IQ matrix */
if (Final_OFDM_Swing_Index >= PwrTrackingLimit_OFDM)
Final_OFDM_Swing_Index = PwrTrackingLimit_OFDM;
else if (Final_OFDM_Swing_Index < 0)
Final_OFDM_Swing_Index = 0;
if (Final_CCK_Swing_Index >= CCK_TABLE_SIZE)
Final_CCK_Swing_Index = CCK_TABLE_SIZE-1;
else if (pRFCalibrateInfo->BbSwingIdxCck < 0)
Final_CCK_Swing_Index = 0;
setIqkMatrix_8703B(pDM_Odm, Final_OFDM_Swing_Index, ODM_RF_PATH_A,
pRFCalibrateInfo->IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0],
pRFCalibrateInfo->IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]);
setCCKFilterCoefficient_8703B(pDM_Odm, Final_CCK_Swing_Index);
} else if (Method == MIX_MODE) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->DefaultCCKIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, pDM_Odm->Remnant_CCKSwingIdx=%d RF_Path = %d\n",
pRFCalibrateInfo->DefaultOfdmIndex, pRFCalibrateInfo->DefaultCckIndex, pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath], pRFCalibrateInfo->Remnant_CCKSwingIdx, RFPath));
Final_OFDM_Swing_Index = pRFCalibrateInfo->DefaultOfdmIndex + pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath];
Final_CCK_Swing_Index = pRFCalibrateInfo->DefaultCckIndex + pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath];
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->DefaultCCKIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d RF_Path = %d\n",
pRFCalibrateInfo->DefaultOfdmIndex, pRFCalibrateInfo->DefaultCckIndex, pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath], RFPath));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" Final_OFDM_Swing_Index=%d, Final_CCK_Swing_Index=%d RFPath=%d\n",
Final_OFDM_Swing_Index, Final_CCK_Swing_Index, RFPath));
if (Final_OFDM_Swing_Index > PwrTrackingLimit_OFDM) { /*BBSwing higher then Limit*/
pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index - PwrTrackingLimit_OFDM;
setIqkMatrix_8703B(pDM_Odm, PwrTrackingLimit_OFDM, ODM_RF_PATH_A,
pRFCalibrateInfo->IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0],
pRFCalibrateInfo->IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]);
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA = TRUE;
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM);
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
PwrTrackingLimit_OFDM, pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath]));
} else if (Final_OFDM_Swing_Index < 0) {
pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index;
setIqkMatrix_8703B(pDM_Odm, 0, ODM_RF_PATH_A,
pRFCalibrateInfo->IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0],
pRFCalibrateInfo->IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]);
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA = TRUE;
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM);
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" ******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n",
pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath]));
} else {
setIqkMatrix_8703B(pDM_Odm, Final_OFDM_Swing_Index, ODM_RF_PATH_A,
pRFCalibrateInfo->IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0],
pRFCalibrateInfo->IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" ******Path_A Compensate with BBSwing , Final_OFDM_Swing_Index = %d\n", Final_OFDM_Swing_Index));
if (pRFCalibrateInfo->Modify_TxAGC_Flag_PathA) { /*If TxAGC has changed, reset TxAGC again*/
pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = 0;
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM);
PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7);
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA = FALSE;
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" ******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n"));
}
}
if (Final_CCK_Swing_Index > PwrTrackingLimit_CCK) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" Final_CCK_Swing_Index(%d) > PwrTrackingLimit_CCK(%d)\n", Final_CCK_Swing_Index, PwrTrackingLimit_CCK));
pRFCalibrateInfo->Remnant_CCKSwingIdx = Final_CCK_Swing_Index - PwrTrackingLimit_CCK;
setCCKFilterCoefficient_8703B(pDM_Odm, PwrTrackingLimit_CCK);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A CCK Over Limit , PwrTrackingLimit_CCK = %d , pDM_Odm->Remnant_CCKSwingIdx = %d\n", PwrTrackingLimit_CCK, pRFCalibrateInfo->Remnant_CCKSwingIdx));
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK = TRUE;
PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, CCK);
} else if (Final_CCK_Swing_Index < 0) { /* Lowest CCK Index = 0 */
ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" Final_CCK_Swing_Index(%d) < 0 PwrTrackingLimit_CCK(%d)\n", Final_CCK_Swing_Index, PwrTrackingLimit_CCK));
pRFCalibrateInfo->Remnant_CCKSwingIdx = Final_CCK_Swing_Index;
setCCKFilterCoefficient_8703B(pDM_Odm, 0);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A CCK Under Limit , PwrTrackingLimit_CCK = %d , pDM_Odm->Remnant_CCKSwingIdx = %d\n", 0, pRFCalibrateInfo->Remnant_CCKSwingIdx));
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK = TRUE;
PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, CCK);
} else {
ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
(" else Final_CCK_Swing_Index=%d PwrTrackingLimit_CCK(%d)\n", Final_CCK_Swing_Index, PwrTrackingLimit_CCK));
setCCKFilterCoefficient_8703B(pDM_Odm, Final_CCK_Swing_Index);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A CCK Compensate with BBSwing , Final_CCK_Swing_Index = %d\n", Final_CCK_Swing_Index));
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK = FALSE;
pRFCalibrateInfo->Remnant_CCKSwingIdx = 0;
if (pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK) { /*If TxAGC has changed, reset TxAGC again*/
pRFCalibrateInfo->Remnant_CCKSwingIdx = 0;
PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, CCK);
pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK = FALSE;
}
}
} else {
return; // This method is not supported.
}
}
VOID
GetDeltaSwingTable_8703B(
IN PVOID pDM_VOID,
OUT pu1Byte *TemperatureUP_A,
OUT pu1Byte *TemperatureDOWN_A,
OUT pu1Byte *TemperatureUP_B,
OUT pu1Byte *TemperatureDOWN_B
)
{
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
PADAPTER Adapter = pDM_Odm->Adapter;
PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
u1Byte TxRate = 0xFF;
u1Byte channel = pHalData->CurrentChannel;
if (pDM_Odm->mp_mode == TRUE) {
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
#if (MP_DRIVER == 1)
PMPT_CONTEXT pMptCtx = &(Adapter->MptCtx);
TxRate = MptToMgntRate(pMptCtx->MptRateIndex);
#endif
#elif (DM_ODM_SUPPORT_TYPE & ODM_CE)
PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.MptCtx);
TxRate = MptToMgntRate(pMptCtx->MptRateIndex);
#endif
#endif
} else {
u2Byte rate = *(pDM_Odm->pForcedDataRate);
if (!rate) { /*auto rate*/
if (rate != 0xFF) {
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
TxRate = Adapter->HalFunc.GetHwRateFromMRateHandler(pDM_Odm->TxRate);
#elif (DM_ODM_SUPPORT_TYPE & ODM_CE)
TxRate = HwRateToMRate(pDM_Odm->TxRate);
#endif
}
} else { /*force rate*/
TxRate = (u1Byte)rate;
}
}
ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("Power Tracking TxRate=0x%X\n", TxRate));
if ( 1 <= channel && channel <= 14) {
if (IS_CCK_RATE(TxRate)) {
*TemperatureUP_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P;
*TemperatureDOWN_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N;
*TemperatureUP_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P;
*TemperatureDOWN_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N;
} else {
*TemperatureUP_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P;
*TemperatureDOWN_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N;
*TemperatureUP_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P;
*TemperatureDOWN_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N;
}
} else {
*TemperatureUP_A = (pu1Byte)DeltaSwingTableIdx_2GA_P_8188E;
*TemperatureDOWN_A = (pu1Byte)DeltaSwingTableIdx_2GA_N_8188E;
*TemperatureUP_B = (pu1Byte)DeltaSwingTableIdx_2GA_P_8188E;
*TemperatureDOWN_B = (pu1Byte)DeltaSwingTableIdx_2GA_N_8188E;
}
return;
}
void ConfigureTxpowerTrack_8703B(
PTXPWRTRACK_CFG pConfig
)
{
pConfig->SwingTableSize_CCK = CCK_TABLE_SIZE;
pConfig->SwingTableSize_OFDM = OFDM_TABLE_SIZE;
pConfig->Threshold_IQK = IQK_THRESHOLD;
pConfig->AverageThermalNum = AVG_THERMAL_NUM_8703B;
pConfig->RfPathCount = MAX_PATH_NUM_8703B;
pConfig->ThermalRegAddr = RF_T_METER_8703B;
pConfig->ODM_TxPwrTrackSetPwr = ODM_TxPwrTrackSetPwr_8703B;
pConfig->DoIQK = DoIQK_8703B;
pConfig->PHY_LCCalibrate = PHY_LCCalibrate_8703B;
pConfig->GetDeltaSwingTable = GetDeltaSwingTable_8703B;
}
//1 7. IQK
#define MAX_TOLERANCE 5
#define IQK_DELAY_TIME 1 //ms
u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK
phy_PathA_IQK_8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm
#else
IN PADAPTER pAdapter
#endif
)
{
u4Byte regEAC, regE94, regE9C, tmp/*, regEA4*/;
u1Byte result = 0x00, Ktime;
u4Byte originalPath, originalGNT;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]TX IQK!\n"));
/*8703b IQK v2.0 20150713*/
/*1 Tx IQK*/
/*IQK setting*/
ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00);
ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800);
/*path-A IQK setting*/
ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
/* ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x8214010a);*/
ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x8214030f);
ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
/*LO calibration setting*/
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
/*leave IQK mode*/
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000);
/*PA, PAD setting*/
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, 0x800, 0x1);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x55, 0x0007f, 0x7);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x7f, bRFRegOffsetMask, 0x0d400);
/*enter IQK mode*/
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x808000);
#if 1
/*path setting*/
/*Save Original Path Owner, Original GNT*/
originalPath = ODM_GetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, bMaskDWord); /*save 0x70*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0x800f0038);
ODM_delay_ms(1);
originalGNT = ODM_GetBBReg(pDM_Odm, REG_LTECOEX_READ_DATA, bMaskDWord); /*save 0x38*/
/*set GNT_WL=1/GNT_BT=0 and Path owner to WiFi for pause BT traffic*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_WRITE_DATA, bMaskDWord, 0x00007700);
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0xc0020038); /*0x38[15:8] = 0x77*/
ODM_SetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, BIT26, 0x1); /*0x70[26] =1 --> Path Owner to WiFi*/
#endif
/*One shot, path A LOK & IQK*/
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
/* delay x ms */
ODM_delay_ms(IQK_DELAY_TIME_8703B);
Ktime = 0;
while ((ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord) == 0) && Ktime < 10) {
ODM_delay_ms(5);
Ktime++;
}
#if 1
/*path setting*/
/*Restore GNT_WL/GNT_BT and Path owner*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_WRITE_DATA, bMaskDWord, originalGNT);
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0xc00f0038);
ODM_SetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, 0xffffffff, originalPath);
originalPath = ODM_GetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, bMaskDWord); /*save 0x70*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0x800f0038);
ODM_delay_ms(1);
originalGNT = ODM_GetBBReg(pDM_Odm, REG_LTECOEX_READ_DATA, bMaskDWord); /*save 0x38*/
/* DBG_871X("[COEXDBG] REG 0x38 = 0x%08X, 0x70=0x%08x After Tx IQK !!!!!!!!!!\n", originalGNT, originalPath);*/
#endif
/*leave IQK mode*/
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000);
/* PA/PAD controlled by 0x0*/
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, 0x800, 0x0);
/* Check failed*/
regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord);
regE94 = ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord);
regE9C= ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xeac = 0x%x\n", regEAC));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xe94 = 0x%x, 0xe9c = 0x%x\n", regE94, regE9C));
/*monitor image power before & after IQK*/
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n",
ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xe98, bMaskDWord)));
if (!(regEAC & BIT28) &&
(((regE94 & 0x03FF0000)>>16) != 0x142) &&
(((regE9C & 0x03FF0000)>>16) != 0x42))
result |= 0x01;
return result;
}
u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK
phy_PathA_RxIQK8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm
#else
IN PADAPTER pAdapter
#endif
)
{
u4Byte regEAC, regE94, regE9C, regEA4, u4tmp,tmp;
u1Byte result = 0x00, Ktime;
u4Byte originalPath, originalGNT;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]RX IQK:Get TXIMR setting\n"));
//1 Get TX_XY
//IQK setting
ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00);
ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800);
//path-A IQK setting
ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
// ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x8216000f);
ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
//LO calibration setting
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
//leave IQK mode
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000);
//modify RXIQK mode table
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x00007);
/*IQK PA off*/
// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7fb7);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0x57db7);
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x808000);
#if 1
/*path setting*/
/*Save Original Path Owner, Original GNT*/
originalPath = ODM_GetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, bMaskDWord); /*save 0x70*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0x800f0038);
ODM_delay_ms(1);
originalGNT = ODM_GetBBReg(pDM_Odm, REG_LTECOEX_READ_DATA, bMaskDWord); /*save 0x38*/
/*set GNT_WL=1/GNT_BT=0 and Path owner to WiFi for pause BT traffic*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_WRITE_DATA, bMaskDWord, 0x00007700);
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0xc0020038); /*0x38[15:8] = 0x77*/
ODM_SetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, BIT26, 0x1); /*0x70[26] =1 --> Path Owner to WiFi*/
#endif
//One shot, path A LOK & IQK
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
// delay x ms
ODM_delay_ms(IQK_DELAY_TIME_8703B);
Ktime = 0;
while ((ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord) == 0) && Ktime < 10) {
ODM_delay_ms(5);
Ktime++;
}
#if 1
/*path setting*/
/*Restore GNT_WL/GNT_BT and Path owner*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_WRITE_DATA, bMaskDWord, originalGNT);
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0xc00f0038);
ODM_SetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, 0xffffffff, originalPath);
originalPath = ODM_GetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, bMaskDWord); /*save 0x70*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0x800f0038);
ODM_delay_ms(1);
originalGNT = ODM_GetBBReg(pDM_Odm, REG_LTECOEX_READ_DATA, bMaskDWord); /*save 0x38*/
/* DBG_871X("[COEXDBG] REG 0x38 = 0x%08X, 0x70=0x%08x After Get TXIMR !!!!!!!!!!\n", originalGNT, originalPath);*/
#endif
//leave IQK mode
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000);
// Check failed
regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord);
regE94 = ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord);
regE9C= ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xeac = 0x%x\n", regEAC));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xe94 = 0x%x, 0xe9c = 0x%x\n", regE94, regE9C));
/*monitor image power before & after IQK*/
ODM_RT_TRACE(pDM_Odm , ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n",
ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xe98, bMaskDWord)));
//Allen 20131125
tmp = (regE9C & 0x03FF0000)>>16;
if ((tmp & 0x200) > 0)
tmp = 0x400 - tmp;
if (!(regEAC & BIT28) &&
(((regE94 & 0x03FF0000)>>16) != 0x142) &&
(((regE9C & 0x03FF0000)>>16) != 0x42))
result |= 0x01;
else //if Tx not OK, ignore Rx
return result;
u4tmp = 0x80007C00 | (regE94&0x3FF0000) | ((regE9C&0x3FF0000) >> 16);
ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, u4tmp);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xe40 = 0x%x u4tmp = 0x%x\n", ODM_GetBBReg(pDM_Odm, rTx_IQK, bMaskDWord), u4tmp));
//1 RX IQK
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]RX IQK\n"));
//IQK setting
ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800);
//path-A IQK setting
ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82110000);
ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
/* ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x2816001f);*/
ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
//LO calibration setting
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a8d1);
//modify RXIQK mode table
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x00007);
/*PA off*/
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7d77);
/*PA, PAD setting*/
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, 0x800, 0x1);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x55, 0x0007f, 0x5);
/*enter IQK mode*/
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x808000);
#if 1
/*path setting*/
/*Save Original Path Owner, Original GNT*/
originalPath = ODM_GetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, bMaskDWord); /*save 0x70*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0x800f0038);
ODM_delay_ms(1);
originalGNT = ODM_GetBBReg(pDM_Odm, REG_LTECOEX_READ_DATA, bMaskDWord); /*save 0x38*/
/*set GNT_WL=1/GNT_BT=0 and Path owner to WiFi for pause BT traffic*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_WRITE_DATA, bMaskDWord, 0x00007700);
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0xc0020038); /*0x38[15:8] = 0x77*/
ODM_SetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, BIT26, 0x1); /*0x70[26] =1 --> Path Owner to WiFi*/
#endif
//One shot, path A LOK & IQK
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
// delay x ms
ODM_delay_ms(IQK_DELAY_TIME_8703B);
Ktime = 0;
while ((ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord) == 0) && Ktime < 10) {
ODM_delay_ms(5);
Ktime++;
}
#if 1
/*path setting*/
/*Restore GNT_WL/GNT_BT and Path owner*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_WRITE_DATA, bMaskDWord, originalGNT);
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0xc00f0038);
ODM_SetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, 0xffffffff, originalPath);
originalPath = ODM_GetMACReg(pDM_Odm, REG_LTECOEX_PATH_CONTROL, bMaskDWord); /*save 0x70*/
ODM_SetBBReg(pDM_Odm, REG_LTECOEX_CTRL, bMaskDWord, 0x800f0038);
ODM_delay_ms(1);
originalGNT = ODM_GetBBReg(pDM_Odm, REG_LTECOEX_READ_DATA, bMaskDWord); /*save 0x38*/
/* DBG_871X("[COEXDBG] REG 0x38 = 0x%08X, 0x70=0x%08x After Rx IQK !!!!!!!!!!\n", originalGNT, originalPath);*/
#endif
/*leave IQK mode*/
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000);
// PA/PAD controlled by 0x0
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, 0x800, 0x0);
// Check failed
regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord);
regEA4= ODM_GetBBReg(pDM_Odm, rRx_Power_Before_IQK_A_2, bMaskDWord);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xeac = 0x%x\n", regEAC));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xea4 = 0x%x, 0xeac = 0x%x\n", regEA4, regEAC));
//monitor image power before & after IQK
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n",
ODM_GetBBReg(pDM_Odm, 0xea0, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xea8, bMaskDWord)));
//Allen 20131125
tmp = (regEAC & 0x03FF0000)>>16;
if ((tmp & 0x200) > 0)
tmp = 0x400 - tmp;
if (!(regEAC & BIT27) && /*if Tx is OK, check whether Rx is OK*/
(((regEA4 & 0x03FF0000)>>16) != 0x132) &&
(((regEAC & 0x03FF0000)>>16) != 0x36) &&
(((regEA4 & 0x03FF0000)>>16) < 0x11a) &&
(((regEA4 & 0x03FF0000)>>16) > 0xe6) &&
(tmp < 0x1a))
result |= 0x02;
else //if Tx not OK, ignore Rx
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Rx IQK fail!!\n"));
return result;
}
VOID
_PHY_PathAFillIQKMatrix8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN BOOLEAN bIQKOK,
IN s4Byte result[][8],
IN u1Byte final_candidate,
IN BOOLEAN bTxOnly
)
{
u4Byte Oldval_0, X, TX0_A, reg, tmp0xc80, tmp0xc94, tmp0xc4c, tmp0xc14, tmp0xca0;
s4Byte Y, TX0_C;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]Path A IQ Calibration %s !\n",(bIQKOK)?"Success":"Failed"));
if(final_candidate == 0xFF)
return;
else if (bIQKOK) {
Oldval_0 = (ODM_GetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
X = result[final_candidate][0];
if ((X & 0x00000200) != 0)
X = X | 0xFFFFFC00;
TX0_A = (X * Oldval_0) >> 8;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]X = 0x%x, TX0_A = 0x%x, Oldval_0 0x%x\n", X, TX0_A, Oldval_0));
tmp0xc80 = (ODM_GetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord) & 0xfffffc00) | (TX0_A & 0x3ff);
tmp0xc4c = (((X* Oldval_0>>7) & 0x1) << 31 ) | (ODM_GetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord) & 0x7fffffff);
Y = result[final_candidate][1];
if ((Y & 0x00000200) != 0)
Y = Y | 0xFFFFFC00;
//2 Tx IQC
TX0_C = (Y * Oldval_0) >> 8;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]Y = 0x%x, TX = 0x%x\n", Y, TX0_C));
tmp0xc94 = (((TX0_C&0x3C0)>>6) << 28) | (ODM_GetBBReg(pDM_Odm, rOFDM0_XCTxAFE, bMaskDWord) & 0x0fffffff);
pRFCalibrateInfo->TxIQC_8703B[IDX_0xC94][KEY] = rOFDM0_XCTxAFE;
pRFCalibrateInfo->TxIQC_8703B[IDX_0xC94][VAL] = tmp0xc94;
tmp0xc80 = (tmp0xc80 & 0xffc0ffff) | (TX0_C & 0x3F)<<16;
pRFCalibrateInfo->TxIQC_8703B[IDX_0xC80][KEY] = rOFDM0_XATxIQImbalance;
pRFCalibrateInfo->TxIQC_8703B[IDX_0xC80][VAL] = tmp0xc80;
tmp0xc4c = (tmp0xc4c & 0xdfffffff) | (((Y* Oldval_0>>7) & 0x1)<<29);
pRFCalibrateInfo->TxIQC_8703B[IDX_0xC4C][KEY] = rOFDM0_ECCAThreshold;
pRFCalibrateInfo->TxIQC_8703B[IDX_0xC4C][VAL] = tmp0xc4c;
if (bTxOnly) {
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]_PHY_PathAFillIQKMatrix8703B only Tx OK\n"));
// <20130226, Kordan> Saving RxIQC, otherwise not initialized.
pRFCalibrateInfo->RxIQC_8703B[IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
pRFCalibrateInfo->RxIQC_8703B[IDX_0xCA0][VAL] = 0xfffffff & ODM_GetBBReg(pDM_Odm, rOFDM0_RxIQExtAnta, bMaskDWord);
pRFCalibrateInfo->RxIQC_8703B[IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
pRFCalibrateInfo->RxIQC_8703B[IDX_0xC14][VAL] = 0x40000100;
return;
}
reg = result[final_candidate][2];
#if (DM_ODM_SUPPORT_TYPE == ODM_AP)
if (RTL_ABS(reg , 0x100) >= 16)
reg = 0x100;
#endif
//2 Rx IQC
tmp0xc14 = (0x40000100 & 0xfffffc00) | reg;
reg = result[final_candidate][3] & 0x3F;
tmp0xc14 = (tmp0xc14 & 0xffff03ff) | (reg << 10);
pRFCalibrateInfo->RxIQC_8703B[IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
pRFCalibrateInfo->RxIQC_8703B[IDX_0xC14][VAL] = tmp0xc14;
reg = (result[final_candidate][3] >> 6) & 0xF;
tmp0xca0 = ODM_GetBBReg(pDM_Odm, rOFDM0_RxIQExtAnta, 0x0fffffff) | (reg << 28);
pRFCalibrateInfo->RxIQC_8703B[IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
pRFCalibrateInfo->RxIQC_8703B[IDX_0xCA0][VAL] = tmp0xca0;
}
}
#if 0
VOID
_PHY_PathBFillIQKMatrix8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN BOOLEAN bIQKOK,
IN s4Byte result[][8],
IN u1Byte final_candidate,
IN BOOLEAN bTxOnly //do Tx only
)
{
u4Byte Oldval_1, X, TX1_A, reg, tmp0xc80, tmp0xc94, tmp0xc4c, tmp0xc14, tmp0xca0;
s4Byte Y, TX1_C;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]Path B IQ Calibration %s !\n",(bIQKOK)?"Success":"Failed"));
if(final_candidate == 0xFF)
return;
else if(bIQKOK)
{
Oldval_1 = (ODM_GetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
X = result[final_candidate][4];
if ((X & 0x00000200) != 0)
X = X | 0xFFFFFC00;
TX1_A = (X * Oldval_1) >> 8;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]X = 0x%x, TX1_A = 0x%x\n", X, TX1_A));
tmp0xc80 = (ODM_GetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord) & 0xfffffc00) | (TX1_A & 0x3ff);
tmp0xc4c = (((X* Oldval_1>>7) & 0x1) << 31 ) | (ODM_GetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord) & 0x7fffffff);
Y = result[final_candidate][5];
if ((Y & 0x00000200) != 0)
Y = Y | 0xFFFFFC00;
TX1_C = (Y * Oldval_1) >> 8;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]Y = 0x%x, TX1_C = 0x%x\n", Y, TX1_C));
/*2 Tx IQC*/
tmp0xc94 = (((TX1_C&0x3C0)>>6) << 28) | (ODM_GetBBReg(pDM_Odm,rOFDM0_XCTxAFE, bMaskDWord) & 0x0fffffff);
pRFCalibrateInfo->TxIQC_8703B[PATH_S0][IDX_0xC94][KEY] = rOFDM0_XCTxAFE;
pRFCalibrateInfo->TxIQC_8703B[PATH_S0][IDX_0xC94][VAL] = tmp0xc94;
tmp0xc80 = (tmp0xc80 & 0xffc0ffff) | (TX1_C&0x3F)<<16;
pRFCalibrateInfo->TxIQC_8703B[PATH_S0][IDX_0xC80][KEY] = rOFDM0_XATxIQImbalance;
pRFCalibrateInfo->TxIQC_8703B[PATH_S0][IDX_0xC80][VAL] = tmp0xc80;
tmp0xc4c = (tmp0xc4c & 0xdfffffff) | (((Y* Oldval_1>>7) & 0x1)<<29);
pRFCalibrateInfo->TxIQC_8703B[PATH_S0][IDX_0xC4C][KEY] = rOFDM0_ECCAThreshold;
pRFCalibrateInfo->TxIQC_8703B[PATH_S0][IDX_0xC4C][VAL] = tmp0xc4c;
if(bTxOnly) {
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]_PHY_PathBFillIQKMatrix8703B only Tx OK\n"));
pRFCalibrateInfo->RxIQC_8703B[PATH_S0][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
pRFCalibrateInfo->RxIQC_8703B[PATH_S0][IDX_0xC14][VAL] = 0x40000100;
pRFCalibrateInfo->RxIQC_8703B[PATH_S0][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
pRFCalibrateInfo->RxIQC_8703B[PATH_S0][IDX_0xCA0][VAL] = 0x0fffffff & ODM_GetBBReg(pDM_Odm, rOFDM0_RxIQExtAnta, bMaskDWord);
return;
}
//2 Rx IQC
reg = result[final_candidate][6];
tmp0xc14 = (0x40000100 & 0xfffffc00) | reg;
reg = result[final_candidate][7] & 0x3F;
tmp0xc14 = (tmp0xc14 & 0xffff03ff) | (reg << 10);
pRFCalibrateInfo->RxIQC_8703B[PATH_S0][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
pRFCalibrateInfo->RxIQC_8703B[PATH_S0][IDX_0xC14][VAL] = tmp0xc14;
reg = (result[final_candidate][7] >> 6) & 0xF;
tmp0xca0 = ODM_GetBBReg(pDM_Odm, rOFDM0_RxIQExtAnta, 0x0fffffff) | (reg << 28);
pRFCalibrateInfo->RxIQC_8703B[PATH_S0][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
pRFCalibrateInfo->RxIQC_8703B[PATH_S0][IDX_0xCA0][VAL] = tmp0xca0;
}
}
#endif
BOOLEAN
ODM_SetIQCbyRFpath_8703B(
IN PDM_ODM_T pDM_Odm
)
{
PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
if ((pRFCalibrateInfo->TxIQC_8703B[IDX_0xC80][VAL] != 0x0) && (pRFCalibrateInfo->RxIQC_8703B[IDX_0xC14][VAL] != 0x0)) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]reload RF IQC!!!\n"));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xc80 = 0x%x!!!\n", pRFCalibrateInfo->TxIQC_8703B[IDX_0xC80][VAL]));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]0xc14 = 0x%x!!!\n", pRFCalibrateInfo->TxIQC_8703B[IDX_0xC14][VAL]));
/* TX IQC */
ODM_SetBBReg(pDM_Odm, pRFCalibrateInfo->TxIQC_8703B[IDX_0xC94][KEY], bMaskH4Bits, (pRFCalibrateInfo->TxIQC_8703B[IDX_0xC94][VAL]>>28));
ODM_SetBBReg(pDM_Odm, pRFCalibrateInfo->TxIQC_8703B[IDX_0xC80][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8703B[IDX_0xC80][VAL]);
ODM_SetBBReg(pDM_Odm, pRFCalibrateInfo->TxIQC_8703B[IDX_0xC4C][KEY], BIT31, (pRFCalibrateInfo->TxIQC_8703B[IDX_0xC4C][VAL]>>31));
ODM_SetBBReg(pDM_Odm, pRFCalibrateInfo->TxIQC_8703B[IDX_0xC4C][KEY], BIT29, ((pRFCalibrateInfo->TxIQC_8703B[IDX_0xC4C][VAL] & BIT29)>>29));
/* RX IQC */
ODM_SetBBReg(pDM_Odm, pRFCalibrateInfo->RxIQC_8703B[IDX_0xC14][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8703B[IDX_0xC14][VAL]);
ODM_SetBBReg(pDM_Odm, pRFCalibrateInfo->RxIQC_8703B[IDX_0xCA0][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8703B[IDX_0xCA0][VAL]);
return TRUE;
} else {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQC value invalid!!!\n"));
return FALSE;
}
}
#if !(DM_ODM_SUPPORT_TYPE & ODM_WIN)
BOOLEAN
ODM_CheckPowerStatus(
IN PADAPTER Adapter)
{
#if 0
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
RT_RF_POWER_STATE rtState;
PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
/* 2011/07/27 MH We are not testing ready~~!! We may fail to get correct value when init sequence.*/
if (pMgntInfo->init_adpt_in_progress == TRUE) {
ODM_RT_TRACE(pDM_Odm, COMP_INIT, DBG_LOUD, ("ODM_CheckPowerStatus Return TRUE, due to initadapter"));
return TRUE;
}
/* 2011/07/19 MH We can not execute tx power tracking/ LLC calibrate or IQK.*/
Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
if (Adapter->bDriverStopped || Adapter->bDriverIsGoingToPnpSetPowerSleep || rtState == eRfOff) {
ODM_RT_TRACE(pDM_Odm, COMP_INIT, DBG_LOUD, ("ODM_CheckPowerStatus Return FALSE, due to %d/%d/%d\n",
Adapter->bDriverStopped, Adapter->bDriverIsGoingToPnpSetPowerSleep, rtState));
return FALSE;
}
#endif
return TRUE;
}
#endif
VOID
_PHY_SaveADDARegisters8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN pu4Byte ADDAReg,
IN pu4Byte ADDABackup,
IN u4Byte RegisterNum
)
{
u4Byte i;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
if (ODM_CheckPowerStatus(pAdapter) == FALSE)
return;
#endif
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save ADDA parameters.\n"));
for (i = 0; i < RegisterNum; i++)
ADDABackup[i] = ODM_GetBBReg(pDM_Odm, ADDAReg[i], bMaskDWord);
}
VOID
_PHY_SaveMACRegisters8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN pu4Byte MACReg,
IN pu4Byte MACBackup
)
{
u4Byte i;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save MAC parameters.\n"));
for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
MACBackup[i] = ODM_Read1Byte(pDM_Odm, MACReg[i]);
MACBackup[i] = ODM_Read4Byte(pDM_Odm, MACReg[i]);
}
VOID
_PHY_ReloadADDARegisters8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN pu4Byte ADDAReg,
IN pu4Byte ADDABackup,
IN u4Byte RegiesterNum
)
{
u4Byte i;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Reload ADDA power saving parameters !\n"));
for (i = 0 ; i < RegiesterNum; i++)
ODM_SetBBReg(pDM_Odm, ADDAReg[i], bMaskDWord, ADDABackup[i]);
}
VOID
_PHY_ReloadMACRegisters8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN pu4Byte MACReg,
IN pu4Byte MACBackup
)
{
u4Byte i;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Reload MAC parameters !\n"));
for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++)
ODM_Write1Byte(pDM_Odm, MACReg[i], (u1Byte)MACBackup[i]);
ODM_Write4Byte(pDM_Odm, MACReg[i], MACBackup[i]);
}
VOID
_PHY_PathADDAOn8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN pu4Byte ADDAReg,
IN BOOLEAN isPathAOn
)
{
u4Byte pathOn;
u4Byte i;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("ADDA ON.\n"));
pathOn = 0x03c00014;
for (i = 0; i < IQK_ADDA_REG_NUM; i++)
ODM_SetBBReg(pDM_Odm,ADDAReg[i], bMaskDWord, pathOn);
}
VOID
_PHY_MACSettingCalibration8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN pu4Byte MACReg,
IN pu4Byte MACBackup
)
{
u4Byte i = 0;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("MAC settings for Calibration.\n"));
ODM_Write1Byte(pDM_Odm, MACReg[i], 0x3F);
for (i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++)
ODM_Write1Byte(pDM_Odm, MACReg[i], (u1Byte)(MACBackup[i]&(~BIT3)));
ODM_Write1Byte(pDM_Odm, MACReg[i], (u1Byte)(MACBackup[i]&(~BIT5)));
}
BOOLEAN
phy_SimularityCompare_8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN s4Byte result[][8],
IN u1Byte c1,
IN u1Byte c2
)
{
u4Byte i, j, diff, SimularityBitMap, bound = 0;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
u1Byte final_candidate[2] = {0xFF, 0xFF}; //for path A and path B
BOOLEAN bResult = TRUE;
//#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
// BOOLEAN is2T = IS_92C_SERIAL( pHalData->VersionID);
//#else
BOOLEAN is2T = TRUE;
//#endif
s4Byte tmp1 = 0,tmp2 = 0;
if(is2T)
bound = 8;
else
bound = 4;
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("===> IQK:phy_SimularityCompare_8192E c1 %d c2 %d!!!\n", c1, c2));
SimularityBitMap = 0;
for (i = 0; i < bound; i++) {
if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
if((result[c1][i]& 0x00000200) != 0)
tmp1 = result[c1][i] | 0xFFFFFC00;
else
tmp1 = result[c1][i];
if((result[c2][i]& 0x00000200) != 0)
tmp2 = result[c2][i] | 0xFFFFFC00;
else
tmp2 = result[c2][i];
} else {
tmp1 = result[c1][i];
tmp2 = result[c2][i];
}
diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
if (diff > MAX_TOLERANCE) {
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:differnece overflow %d index %d compare1 0x%x compare2 0x%x!!!\n", diff, i, result[c1][i], result[c2][i]));
if ((i == 2 || i == 6) && !SimularityBitMap) {
if(result[c1][i]+result[c1][i+1] == 0)
final_candidate[(i/4)] = c2;
else if (result[c2][i]+result[c2][i+1] == 0)
final_candidate[(i/4)] = c1;
else
SimularityBitMap = SimularityBitMap|(1<<i);
} else
SimularityBitMap = SimularityBitMap|(1<<i);
}
}
// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:phy_SimularityCompare_8192E SimularityBitMap %x !!!\n", SimularityBitMap));
if (SimularityBitMap == 0) {
for (i = 0; i < (bound/4); i++) {
if (final_candidate[i] != 0xFF) {
for (j = i*4; j < (i+1)*4-2; j++)
result[3][j] = result[final_candidate[i]][j];
bResult = FALSE;
}
}
return bResult;
} else {
if (!(SimularityBitMap & 0x03)) { /*path A TX OK*/
for (i = 0; i < 2; i++)
result[3][i] = result[c1][i];
}
if (!(SimularityBitMap & 0x0c)) { /*path A RX OK*/
for (i = 2; i < 4; i++)
result[3][i] = result[c1][i];
}
if (!(SimularityBitMap & 0x30)) { /*path B TX OK*/
for (i = 4; i < 6; i++)
result[3][i] = result[c1][i];
}
if (!(SimularityBitMap & 0xc0)) { /*path B RX OK*/
for (i = 6; i < 8; i++)
result[3][i] = result[c1][i];
}
return FALSE;
}
}
VOID
phy_IQCalibrate_8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN s4Byte result[][8],
IN u1Byte t
)
{
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#endif
#endif
u4Byte i;
u1Byte PathAOK, PathBOK;
u1Byte tmp0xc50 = (u1Byte)ODM_GetBBReg(pDM_Odm, 0xC50, bMaskByte0);
u1Byte tmp0xc58 = (u1Byte)ODM_GetBBReg(pDM_Odm, 0xC58, bMaskByte0);
u4Byte ADDA_REG[IQK_ADDA_REG_NUM] = {
rFPGA0_XCD_SwitchControl, rBlue_Tooth,
rRx_Wait_CCA, rTx_CCK_RFON,
rTx_CCK_BBON, rTx_OFDM_RFON,
rTx_OFDM_BBON, rTx_To_Rx,
rTx_To_Tx, rRx_CCK,
rRx_OFDM, rRx_Wait_RIFS,
rRx_TO_Rx, rStandby,
rSleep, rPMPD_ANAEN
};
u4Byte IQK_MAC_REG[IQK_MAC_REG_NUM] = {
REG_TXPAUSE, REG_BCN_CTRL,
REG_BCN_CTRL_1, REG_GPIO_MUXCFG
};
/*since 92C & 92D have the different define in IQK_BB_REG*/
u4Byte IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
rFPGA0_XB_RFInterfaceOE, rCCK0_AFESetting
};
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
u4Byte retryCount = 2;
#else
#if MP_DRIVER
const u4Byte retryCount = 1;
#else
const u4Byte retryCount = 2;
#endif
#endif
/* Note: IQ calibration must be performed after loading*/
/*PHY_REG.txt , and radio_a, radio_b.txt*/
//u4Byte bbvalue;
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
#ifdef MP_TEST
if (pDM_Odm->priv->pshare->rf_ft_var.mp_specific)
retryCount = 9;
#endif
#endif
if (t == 0) {
// bbvalue = ODM_GetBBReg(pDM_Odm, rFPGA0_RFMOD, bMaskDWord);
// RT_DISP(FINIT, INIT_IQK, ("phy_IQCalibrate_8188E()==>0x%08x\n",bbvalue));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQ Calibration for %d times\n", t));
/* Save ADDA parameters, turn Path A ADDA on*/
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
_PHY_SaveADDARegisters8703B(pAdapter, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
_PHY_SaveMACRegisters8703B(pAdapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
_PHY_SaveADDARegisters8703B(pAdapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
#else
_PHY_SaveADDARegisters8703B(pDM_Odm, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
_PHY_SaveMACRegisters8703B(pDM_Odm, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
_PHY_SaveADDARegisters8703B(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
#endif
}
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQ Calibration for %d times\n", t));
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
_PHY_PathADDAOn8703B(pAdapter, ADDA_REG, TRUE);
#else
_PHY_PathADDAOn8703B(pDM_Odm, ADDA_REG, TRUE);
#endif
//MAC settings
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
_PHY_MACSettingCalibration8703B(pAdapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
#else
_PHY_MACSettingCalibration8703B(pDM_Odm, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
#endif
//BB setting
/*ODM_SetBBReg(pDM_Odm, rFPGA0_RFMOD, BIT24, 0x00);*/
ODM_SetBBReg(pDM_Odm, rCCK0_AFESetting, 0x0f000000, 0xf);
ODM_SetBBReg(pDM_Odm, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x25204000);
//path A TX IQK
#if 1
for (i = 0 ; i < retryCount ; i++) {
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
PathAOK = phy_PathA_IQK_8703B(pAdapter);
#else
PathAOK = phy_PathA_IQK_8703B(pDM_Odm);
#endif
if (PathAOK == 0x01) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]Tx IQK Success!!\n"));
result[t][0] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
result[t][1] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
break;
}
}
#endif
//path A RXIQK
#if 1
for (i = 0 ; i < retryCount ; i++) {
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
PathAOK = phy_PathA_RxIQK8703B(pAdapter);
#else
PathAOK = phy_PathA_RxIQK8703B(pDM_Odm);
#endif
if (PathAOK == 0x03) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]Rx IQK Success!!\n"));
// result[t][0] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
// result[t][1] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
result[t][2] = (ODM_GetBBReg(pDM_Odm, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
result[t][3] = (ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
break;
} else {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]Rx IQK Fail!!\n"));
}
}
if (0x00 == PathAOK)
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK failed!!\n"));
#endif
//path B TX IQK
#if 0
#if MP_DRIVER != 1
if ((*pDM_Odm->pIs1Antenna == FALSE) || ((*pDM_Odm->pIs1Antenna == TRUE) && (*pDM_Odm->pRFDefaultPath == 1))
|| (pDM_Odm->SupportInterface == ODM_ITRF_USB))
#endif
{
for (i = 0 ; i < retryCount ; i++) {
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
PathBOK = phy_PathB_IQK_8703B(pAdapter);
#else
PathBOK = phy_PathB_IQK_8703B(pDM_Odm);
#endif
// if(PathBOK == 0x03){
if (PathBOK == 0x01) {
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]S0 Tx IQK Success!!\n"));
result[t][4] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
result[t][5] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
break;
}
}
#endif
//path B RX IQK
#if 0
for (i = 0 ; i < retryCount ; i++) {
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
PathBOK = phy_PathB_RxIQK8703B(pAdapter);
#else
PathBOK = phy_PathB_RxIQK8703B(pDM_Odm);
#endif
if (PathBOK == 0x03) {
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]S0 Rx IQK Success!!\n"));
// result[t][0] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
// result[t][1] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
result[t][6] = (ODM_GetBBReg(pDM_Odm, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
result[t][7] = (ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
break;
} else
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]S0 Rx IQK Fail!!\n"));
}
if (0x00 == PathBOK)
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]S0 IQK failed!!\n"));
}
#endif
//Back to BB mode, load original value
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK:Back to BB mode, load original value!\n"));
ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000);
if (t != 0) {
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
/* Reload ADDA power saving parameters*/
_PHY_ReloadADDARegisters8703B(pAdapter, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
/* Reload MAC parameters*/
_PHY_ReloadMACRegisters8703B(pAdapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
_PHY_ReloadADDARegisters8703B(pAdapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
#else
/* Reload ADDA power saving parameters*/
_PHY_ReloadADDARegisters8703B(pDM_Odm, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
/* Reload MAC parameters*/
_PHY_ReloadMACRegisters8703B(pDM_Odm, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
_PHY_ReloadADDARegisters8703B(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
#endif
//Allen initial gain 0xc50
// Restore RX initial gain
ODM_SetBBReg(pDM_Odm, 0xc50, bMaskByte0, 0x50);
ODM_SetBBReg(pDM_Odm, 0xc50, bMaskByte0, tmp0xc50);
//load 0xe30 IQC default value
ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
}
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]phy_IQCalibrate_8703B() <==\n"));
}
VOID
phy_LCCalibrate_8703B(
IN PDM_ODM_T pDM_Odm,
IN BOOLEAN is2T
)
{
u1Byte tmpReg;
u4Byte RF_Amode=0, RF_Bmode=0, LC_Cal;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
PADAPTER pAdapter = pDM_Odm->Adapter;
#endif
//Check continuous TX and Packet TX
tmpReg = ODM_Read1Byte(pDM_Odm, 0xd03);
if ((tmpReg&0x70) != 0) /*Deal with contisuous TX case*/
ODM_Write1Byte(pDM_Odm, 0xd03, tmpReg&0x8F); //disable all continuous TX
else // Deal with Packet TX case
ODM_Write1Byte(pDM_Odm, REG_TXPAUSE, 0xFF); // block all queues
if ((tmpReg&0x70) != 0) {
//1. Read original RF mode
//Path-A
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
RF_Amode = PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, bMask12Bits);
//Path-B
if(is2T)
RF_Bmode = PHY_QueryRFReg(pAdapter, ODM_RF_PATH_B, RF_AC, bMask12Bits);
#else
RF_Amode = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMask12Bits);
//Path-B
if(is2T)
RF_Bmode = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMask12Bits);
#endif
//2. Set RF mode = standby mode
//Path-A
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode&0x8FFFF)|0x10000);
//Path-B
if(is2T)
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode&0x8FFFF)|0x10000);
}
//3. Read RF reg18
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
LC_Cal = PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits);
#else
LC_Cal = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits);
#endif
//4. Set LC calibration begin bit15
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0); // LDO ON
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal|0x08000);
ODM_delay_ms(LCK_DELAY_TIME_8703B);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0); // LDO OFF
/*disable below for 8703B by jerrychou 20150720
// Channel 10 LC calibration issue for 8703Bs with 26M xtal
if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO && pDM_Odm->PackageType >= 0x2)
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal);
*/
//Restore original situation
if ((tmpReg&0x70) != 0) { /*Deal with contisuous TX case*/
//Path-A
ODM_Write1Byte(pDM_Odm, 0xd03, tmpReg);
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMask12Bits, RF_Amode);
//Path-B
if(is2T)
ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode);
} else { /* Deal with Packet TX case*/
ODM_Write1Byte(pDM_Odm, REG_TXPAUSE, 0x00);
}
}
/* IQK version:V0.4*/
/* 1. add coex. related setting*/
VOID
PHY_IQCalibrate_8703B(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
IN PDM_ODM_T pDM_Odm,
#else
IN PADAPTER pAdapter,
#endif
IN BOOLEAN bReCovery
)
{
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
#else /* (DM_ODM_SUPPORT_TYPE == ODM_CE)*/
PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
#endif
#if (MP_DRIVER == 1)
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PMPT_CONTEXT pMptCtx = &(pAdapter->MptCtx);
#else/* (DM_ODM_SUPPORT_TYPE == ODM_CE)*/
PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx);
#endif
#endif/*(MP_DRIVER == 1)*/
u1Byte u1bTmp;
u2Byte count=0;
#endif
PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
s4Byte result[4][8]; //last is final result
u1Byte i, final_candidate, Indexforchannel;
BOOLEAN bPathAOK, bPathBOK;
s4Byte RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC, RegTmp = 0;
BOOLEAN is12simular, is13simular, is23simular;
BOOLEAN bStartContTx = FALSE, bSingleTone = FALSE, bCarrierSuppression = FALSE;
u4Byte IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
rOFDM0_RxIQExtAnta
};
BOOLEAN bReloadIQK = FALSE;
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE) )
if (ODM_CheckPowerStatus(pAdapter) == FALSE)
return;
#else
prtl8192cd_priv priv = pDM_Odm->priv;
#ifdef MP_TEST
if (priv->pshare->rf_ft_var.mp_specific) {
if((OPMODE & WIFI_MP_CTX_PACKET) || (OPMODE & WIFI_MP_CTX_ST))
return;
}
#endif
if(priv->pshare->IQK_88E_done)
bReCovery= 1;
priv->pshare->IQK_88E_done = 1;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION))
return;
#endif
if (pDM_Odm->mp_mode == TRUE) {
#if MP_DRIVER == 1
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
/* <VincentL, 131231> Add to determine IQK ON/OFF in certain case, Suggested by Cheng.*/
if (!pHalData->IQK_MP_Switch)
return;
#endif
bStartContTx = pMptCtx->bStartContTx;
bSingleTone = pMptCtx->bSingleTone;
bCarrierSuppression = pMptCtx->bCarrierSuppression;
/* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu)*/
if (bSingleTone || bCarrierSuppression)
return;
#endif
}
#if DISABLE_BB_RF
return;
#endif
if (pDM_Odm->RFCalibrateInfo.bIQKInProgress)
return;
#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_AP))
if(bReCovery)
#else//for ODM_WIN
if(bReCovery && (!pAdapter->bInHctTest)) //YJ,add for PowerTest,120405
#endif
{
ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("[IQK]PHY_IQCalibrate_8703B: Return due to bReCovery!\n"));
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
_PHY_ReloadADDARegisters8703B(pAdapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
#else
_PHY_ReloadADDARegisters8703B(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
#endif
return;
}
if (pDM_Odm->mp_mode == FALSE) {
#if MP_DRIVER != 1
//check if IQK had been done before!!
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK] 0xc80 = 0x%x\n", pRFCalibrateInfo->TxIQC_8703B[IDX_0xC80][VAL]));
if (ODM_SetIQCbyRFpath_8703B(pDM_Odm)) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK value is reloaded!!!\n"));
bReloadIQK = TRUE;
}
if(bReloadIQK)
return;
#endif
}
/*Check & wait if BT is doing IQK*/
if (pDM_Odm->mp_mode == FALSE) {
#if MP_DRIVER != 1
// Set H2C cmd to inform FW (enable).
SetFwWiFiCalibrationCmd(pAdapter, 1);
// Check 0x1e6
count=0;
u1bTmp = PlatformEFIORead1Byte(pAdapter, 0x1e6);
while (u1bTmp != 0x1 && count < 1000) {
PlatformStallExecution(10);
u1bTmp = PlatformEFIORead1Byte(pAdapter, 0x1e6);
count++;
}
if (count >= 1000)
RT_TRACE(COMP_INIT, DBG_LOUD, ("[IQK]Polling 0x1e6 to 1 for WiFi calibration H2C cmd FAIL! count(%d)", count));
// Wait BT IQK finished.
// polling 0x1e7[0]=1 or 300ms timeout
u1bTmp = PlatformEFIORead1Byte(pAdapter, 0x1e7);
while ((!(u1bTmp&BIT0)) && count < 6000) {
PlatformStallExecution(50);
u1bTmp = PlatformEFIORead1Byte(pAdapter, 0x1e7);
count++;
}
#endif
}
//IQK start!!!!!!!!!!
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK:Start!!!\n"));
ODM_AcquireSpinLock(pDM_Odm, RT_IQK_SPINLOCK);
pDM_Odm->RFCalibrateInfo.bIQKInProgress = TRUE;
ODM_ReleaseSpinLock(pDM_Odm, RT_IQK_SPINLOCK);
for (i = 0; i < 8; i++) {
result[0][i] = 0;
result[1][i] = 0;
result[2][i] = 0;
result[3][i] = 0;
}
final_candidate = 0xff;
bPathAOK = FALSE;
bPathBOK = FALSE;
is12simular = FALSE;
is23simular = FALSE;
is13simular = FALSE;
for (i = 0; i < 3; i++) {
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
phy_IQCalibrate_8703B(pAdapter, result, i);
#else
phy_IQCalibrate_8703B(pDM_Odm, result, i);
#endif
if (i == 1) {
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
is12simular = phy_SimularityCompare_8703B(pAdapter, result, 0, 1);
#else
is12simular = phy_SimularityCompare_8703B(pDM_Odm, result, 0, 1);
#endif
if (is12simular) {
final_candidate = 0;
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK: is12simular final_candidate is %x\n", final_candidate));
break;
}
}
if (i == 2) {
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
is13simular = phy_SimularityCompare_8703B(pAdapter, result, 0, 2);
#else
is13simular = phy_SimularityCompare_8703B(pDM_Odm, result, 0, 2);
#endif
if (is13simular) {
final_candidate = 0;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK: is13simular final_candidate is %x\n",final_candidate));
break;
}
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
is23simular = phy_SimularityCompare_8703B(pAdapter, result, 1, 2);
#else
is23simular = phy_SimularityCompare_8703B(pDM_Odm, result, 1, 2);
#endif
if (is23simular) {
final_candidate = 1;
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK: is23simular final_candidate is %x\n", final_candidate));
} else {
for(i = 0; i < 8; i++)
RegTmp += result[3][i];
if(RegTmp != 0)
final_candidate = 3;
else
final_candidate = 0xFF;
}
}
}
/* RT_TRACE(COMP_INIT,DBG_LOUD,("Release Mutex in IQCalibrate\n"));*/
for (i = 0; i < 4; i++) {
RegE94 = result[i][0];
RegE9C = result[i][1];
RegEA4 = result[i][2];
RegEAC = result[i][3];
RegEB4 = result[i][4];
RegEBC = result[i][5];
RegEC4 = result[i][6];
RegECC = result[i][7];
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n ", RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC));
}
if (final_candidate != 0xff) {
pDM_Odm->RFCalibrateInfo.RegE94 = RegE94 = result[final_candidate][0];
pDM_Odm->RFCalibrateInfo.RegE9C = RegE9C = result[final_candidate][1];
RegEA4 = result[final_candidate][2];
RegEAC = result[final_candidate][3];
pDM_Odm->RFCalibrateInfo.RegEB4 = RegEB4 = result[final_candidate][4];
pDM_Odm->RFCalibrateInfo.RegEBC = RegEBC = result[final_candidate][5];
RegEC4 = result[final_candidate][6];
RegECC = result[final_candidate][7];
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK: final_candidate is %x\n",final_candidate));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n ", RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC));
bPathAOK = bPathBOK = TRUE;
} else {
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK: FAIL use default value\n"));
pDM_Odm->RFCalibrateInfo.RegE94 = pDM_Odm->RFCalibrateInfo.RegEB4 = 0x100; //X default value
pDM_Odm->RFCalibrateInfo.RegE9C = pDM_Odm->RFCalibrateInfo.RegEBC = 0x0; //Y default value
}
// fill IQK matrix
if (RegE94 != 0)
_PHY_PathAFillIQKMatrix8703B(pAdapter, bPathAOK, result, final_candidate, (RegEA4 == 0));
// if (RegEB4 != 0)
// _PHY_PathBFillIQKMatrix8703B(pAdapter, bPathBOK, result, final_candidate, (RegEC4 == 0));
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
Indexforchannel = ODM_GetRightChnlPlaceforIQK(pHalData->CurrentChannel);
#else
Indexforchannel = 0;
#endif
//To Fix BSOD when final_candidate is 0xff
//by sherry 20120321
if (final_candidate < 4) {
for(i = 0; i < IQK_Matrix_REG_NUM; i++)
pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][i] = result[final_candidate][i];
pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].bIQKDone = TRUE;
}
//RT_DISP(FINIT, INIT_IQK, ("\nIQK OK Indexforchannel %d.\n", Indexforchannel));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]\nIQK OK Indexforchannel %d.\n", Indexforchannel));
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
_PHY_SaveADDARegisters8703B(pAdapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
#else
_PHY_SaveADDARegisters8703B(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, IQK_BB_REG_NUM);
#endif
//fill IQK register
ODM_SetIQCbyRFpath_8703B(pDM_Odm);
if (pDM_Odm->mp_mode == FALSE) {
#if MP_DRIVER != 1
// Set H2C cmd to inform FW (disable).
SetFwWiFiCalibrationCmd(pAdapter, 0);
// Check 0x1e6
count = 0;
u1bTmp = PlatformEFIORead1Byte(pAdapter, 0x1e6);
while (u1bTmp != 0 && count < 1000) {
PlatformStallExecution(10);
u1bTmp = PlatformEFIORead1Byte(pAdapter, 0x1e6);
count++;
}
if (count >= 1000)
RT_TRACE(COMP_INIT, DBG_LOUD, ("[IQK]Polling 0x1e6 to 0 for WiFi calibration H2C cmd FAIL! count(%d)", count));
#endif
}
ODM_AcquireSpinLock(pDM_Odm, RT_IQK_SPINLOCK);
pDM_Odm->RFCalibrateInfo.bIQKInProgress = FALSE;
ODM_ReleaseSpinLock(pDM_Odm, RT_IQK_SPINLOCK);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("[IQK]IQK finished\n"));
}
VOID
PHY_LCCalibrate_8703B(
PVOID pDM_VOID
)
{
BOOLEAN bStartContTx = FALSE, bSingleTone = FALSE, bCarrierSuppression = FALSE;
u4Byte timeout = 2000, timecount = 0;
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
PADAPTER pAdapter = pDM_Odm->Adapter;
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
#if (MP_DRIVER == 1)
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
PMPT_CONTEXT pMptCtx = &(pAdapter->MptCtx);
#else/* (DM_ODM_SUPPORT_TYPE == ODM_CE)*/
PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx);
#endif
#endif/*(MP_DRIVER == 1)*/
#endif
#if MP_DRIVER == 1
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
// <VincentL, 140319> Add to Disable Default LCK when Cont Tx, For Lab Test Usage.
if (!pHalData->IQK_MP_Switch)
return;
#endif
bStartContTx = pMptCtx->bStartContTx;
bSingleTone = pMptCtx->bSingleTone;
bCarrierSuppression = pMptCtx->bCarrierSuppression;
#endif
#if DISABLE_BB_RF
return;
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION))
return;
#endif
// 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu)
if(bSingleTone || bCarrierSuppression)
return;
while (*(pDM_Odm->pbScanInProcess) && timecount < timeout) {
ODM_delay_ms(50);
timecount += 50;
}
pDM_Odm->RFCalibrateInfo.bLCKInProgress = TRUE;
phy_LCCalibrate_8703B(pDM_Odm, FALSE);
pDM_Odm->RFCalibrateInfo.bLCKInProgress = FALSE;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LCK:Finish!!!interface %d\n", pDM_Odm->InterfaceIndex));
}