Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
0005  *
0006  ******************************************************************************/
0007 
0008 /* include "Mp_Precomp.h" */
0009 #include "odm_precomp.h"
0010 
0011 void ConfigureTxpowerTrack(struct dm_odm_t *pDM_Odm, struct txpwrtrack_cfg *pConfig)
0012 {
0013     ConfigureTxpowerTrack_8723B(pConfig);
0014 }
0015 
0016 /*  */
0017 /*  <20121113, Kordan> This function should be called when TxAGC changed. */
0018 /*  Otherwise the previous compensation is gone, because we record the */
0019 /*  delta of temperature between two TxPowerTracking watch dogs. */
0020 /*  */
0021 /*  NOTE: If Tx BB swing or Tx scaling is varified during run-time, still */
0022 /*        need to call this function. */
0023 /*  */
0024 void ODM_ClearTxPowerTrackingState(struct dm_odm_t *pDM_Odm)
0025 {
0026     struct hal_com_data *pHalData = GET_HAL_DATA(pDM_Odm->Adapter);
0027     u8 p = 0;
0028 
0029     pDM_Odm->BbSwingIdxCckBase = pDM_Odm->DefaultCckIndex;
0030     pDM_Odm->BbSwingIdxCck = pDM_Odm->DefaultCckIndex;
0031     pDM_Odm->RFCalibrateInfo.CCK_index = 0;
0032 
0033     for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
0034         pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->DefaultOfdmIndex;
0035         pDM_Odm->BbSwingIdxOfdm[p] = pDM_Odm->DefaultOfdmIndex;
0036         pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pDM_Odm->DefaultOfdmIndex;
0037 
0038         pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
0039         pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = 0;
0040         pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] = 0;
0041         pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
0042 
0043         /*  Initial Mix mode power tracking */
0044         pDM_Odm->Absolute_OFDMSwingIdx[p] = 0;
0045         pDM_Odm->Remnant_OFDMSwingIdx[p] = 0;
0046     }
0047 
0048     /* Initial at Modify Tx Scaling Mode */
0049     pDM_Odm->Modify_TxAGC_Flag_PathA = false;
0050     /* Initial at Modify Tx Scaling Mode */
0051     pDM_Odm->Modify_TxAGC_Flag_PathB = false;
0052     pDM_Odm->Remnant_CCKSwingIdx = 0;
0053     pDM_Odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter;
0054     pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = pHalData->EEPROMThermalMeter;
0055     pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = pHalData->EEPROMThermalMeter;
0056 }
0057 
0058 void ODM_TXPowerTrackingCallback_ThermalMeter(struct adapter *Adapter)
0059 {
0060 
0061     struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
0062     struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
0063 
0064     u8 ThermalValue = 0, delta, delta_LCK, p = 0, i = 0;
0065     u8 ThermalValue_AVG_count = 0;
0066     u32 ThermalValue_AVG = 0;
0067 
0068     u8 OFDM_min_index = 0;  /*  OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
0069     u8 Indexforchannel = 0; /*  GetRightChnlPlaceforIQK(pHalData->CurrentChannel) */
0070 
0071     struct txpwrtrack_cfg c;
0072 
0073 
0074     /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
0075     u8 *deltaSwingTableIdx_TUP_A;
0076     u8 *deltaSwingTableIdx_TDOWN_A;
0077     u8 *deltaSwingTableIdx_TUP_B;
0078     u8 *deltaSwingTableIdx_TDOWN_B;
0079 
0080     /* 4 2. Initialization (7 steps in total) */
0081 
0082     ConfigureTxpowerTrack(pDM_Odm, &c);
0083 
0084     (*c.GetDeltaSwingTable)(
0085         pDM_Odm,
0086         (u8 **)&deltaSwingTableIdx_TUP_A,
0087         (u8 **)&deltaSwingTableIdx_TDOWN_A,
0088         (u8 **)&deltaSwingTableIdx_TUP_B,
0089         (u8 **)&deltaSwingTableIdx_TDOWN_B
0090     );
0091 
0092     /* cosa add for debug */
0093     pDM_Odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++;
0094     pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
0095 
0096     ThermalValue = (u8)PHY_QueryRFReg(pDM_Odm->Adapter, RF_PATH_A, c.ThermalRegAddr, 0xfc00);   /* 0x42: RF Reg[15:10] 88E */
0097     if (
0098         !pDM_Odm->RFCalibrateInfo.TxPowerTrackControl ||
0099         pHalData->EEPROMThermalMeter == 0 ||
0100         pHalData->EEPROMThermalMeter == 0xFF
0101     )
0102         return;
0103 
0104     /* 4 3. Initialize ThermalValues of RFCalibrateInfo */
0105 
0106     /* 4 4. Calculate average thermal meter */
0107 
0108     pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue;
0109     pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index++;
0110     if (pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index == c.AverageThermalNum)   /* Average times =  c.AverageThermalNum */
0111         pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
0112 
0113     for (i = 0; i < c.AverageThermalNum; i++) {
0114         if (pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
0115             ThermalValue_AVG += pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i];
0116             ThermalValue_AVG_count++;
0117         }
0118     }
0119 
0120     /* Calculate Average ThermalValue after average enough times */
0121     if (ThermalValue_AVG_count) {
0122         ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count);
0123     }
0124 
0125     /* 4 5. Calculate delta, delta_LCK */
0126     /* delta" here is used to determine whether thermal value changes or not. */
0127     delta =
0128         (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue) ?
0129         (ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue) :
0130         (pDM_Odm->RFCalibrateInfo.ThermalValue - ThermalValue);
0131     delta_LCK =
0132         (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_LCK) ?
0133         (ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_LCK) :
0134         (pDM_Odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue);
0135 
0136     /* 4 6. If necessary, do LCK. */
0137     /*  Delta temperature is equal to or larger than 20 centigrade. */
0138     if (delta_LCK >= c.Threshold_IQK) {
0139         pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
0140         if (c.PHY_LCCalibrate)
0141             (*c.PHY_LCCalibrate)(pDM_Odm);
0142     }
0143 
0144     /* 3 7. If necessary, move the index of swing table to adjust Tx power. */
0145     if (delta > 0 && pDM_Odm->RFCalibrateInfo.TxPowerTrackControl) {
0146         /* delta" here is used to record the absolute value of difference. */
0147         delta =
0148             ThermalValue > pHalData->EEPROMThermalMeter ?
0149             (ThermalValue - pHalData->EEPROMThermalMeter) :
0150             (pHalData->EEPROMThermalMeter - ThermalValue);
0151 
0152         if (delta >= TXPWR_TRACK_TABLE_SIZE)
0153             delta = TXPWR_TRACK_TABLE_SIZE - 1;
0154 
0155         /* 4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset */
0156         if (ThermalValue > pHalData->EEPROMThermalMeter) {
0157             pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[RF_PATH_A] =
0158                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_A];
0159             pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_A] =
0160                 deltaSwingTableIdx_TUP_A[delta];
0161 
0162             /*  Record delta swing for mix mode power tracking */
0163             pDM_Odm->Absolute_OFDMSwingIdx[RF_PATH_A] =
0164                 deltaSwingTableIdx_TUP_A[delta];
0165 
0166             if (c.RfPathCount > 1) {
0167                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[RF_PATH_B] =
0168                     pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_B];
0169                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_B] =
0170                     deltaSwingTableIdx_TUP_B[delta];
0171 
0172                 /*  Record delta swing for mix mode power tracking */
0173                 pDM_Odm->Absolute_OFDMSwingIdx[RF_PATH_B] =
0174                     deltaSwingTableIdx_TUP_B[delta];
0175             }
0176 
0177         } else {
0178             pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[RF_PATH_A] =
0179                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_A];
0180             pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_A] =
0181                 -1 * deltaSwingTableIdx_TDOWN_A[delta];
0182 
0183             /*  Record delta swing for mix mode power tracking */
0184             pDM_Odm->Absolute_OFDMSwingIdx[RF_PATH_A] =
0185                 -1 * deltaSwingTableIdx_TDOWN_A[delta];
0186 
0187             if (c.RfPathCount > 1) {
0188                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[RF_PATH_B] =
0189                     pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_B];
0190                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_B] =
0191                     -1 * deltaSwingTableIdx_TDOWN_B[delta];
0192 
0193                  /*  Record delta swing for mix mode power tracking */
0194                 pDM_Odm->Absolute_OFDMSwingIdx[RF_PATH_B] =
0195                     -1 * deltaSwingTableIdx_TDOWN_B[delta];
0196             }
0197         }
0198 
0199         for (p = RF_PATH_A; p < c.RfPathCount; p++) {
0200             if (
0201                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] ==
0202                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]
0203             ) /*  If Thermal value changes but lookup table value still the same */
0204                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
0205             else
0206                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] - pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p];      /*  Power Index Diff between 2 times Power Tracking */
0207 
0208             pDM_Odm->RFCalibrateInfo.OFDM_index[p] =
0209                 pDM_Odm->BbSwingIdxOfdmBase[p] +
0210                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p];
0211 
0212             pDM_Odm->RFCalibrateInfo.CCK_index =
0213                 pDM_Odm->BbSwingIdxCckBase +
0214                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p];
0215 
0216             pDM_Odm->BbSwingIdxCck =
0217                 pDM_Odm->RFCalibrateInfo.CCK_index;
0218 
0219             pDM_Odm->BbSwingIdxOfdm[p] =
0220                 pDM_Odm->RFCalibrateInfo.OFDM_index[p];
0221 
0222             /* 4 7.1 Handle boundary conditions of index. */
0223             if (pDM_Odm->RFCalibrateInfo.OFDM_index[p] > c.SwingTableSize_OFDM-1)
0224                 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = c.SwingTableSize_OFDM-1;
0225             else if (pDM_Odm->RFCalibrateInfo.OFDM_index[p] < OFDM_min_index)
0226                 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = OFDM_min_index;
0227         }
0228         if (pDM_Odm->RFCalibrateInfo.CCK_index > c.SwingTableSize_CCK-1)
0229             pDM_Odm->RFCalibrateInfo.CCK_index = c.SwingTableSize_CCK-1;
0230         /* else if (pDM_Odm->RFCalibrateInfo.CCK_index < 0) */
0231             /* pDM_Odm->RFCalibrateInfo.CCK_index = 0; */
0232     } else {
0233             for (p = RF_PATH_A; p < c.RfPathCount; p++)
0234                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
0235     }
0236 
0237     /* Print Swing base & current */
0238     for (p = RF_PATH_A; p < c.RfPathCount; p++) {
0239     }
0240 
0241     if (
0242         (pDM_Odm->RFCalibrateInfo.PowerIndexOffset[RF_PATH_A] != 0 ||
0243          pDM_Odm->RFCalibrateInfo.PowerIndexOffset[RF_PATH_B] != 0) &&
0244          pDM_Odm->RFCalibrateInfo.TxPowerTrackControl
0245      ) {
0246         /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
0247 
0248         pDM_Odm->RFCalibrateInfo.bTxPowerChanged = true; /*  Always true after Tx Power is adjusted by power tracking. */
0249         /*  */
0250         /*  2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
0251         /*  to increase TX power. Otherwise, EVM will be bad. */
0252         /*  */
0253         /*  2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
0254 
0255         if (ThermalValue > pHalData->EEPROMThermalMeter) {
0256             for (p = RF_PATH_A; p < c.RfPathCount; p++)
0257                     (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, 0);
0258         } else {
0259             for (p = RF_PATH_A; p < c.RfPathCount; p++)
0260                 (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, Indexforchannel);
0261         }
0262 
0263         /*  Record last time Power Tracking result as base. */
0264         pDM_Odm->BbSwingIdxCckBase = pDM_Odm->BbSwingIdxCck;
0265         for (p = RF_PATH_A; p < c.RfPathCount; p++)
0266             pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->BbSwingIdxOfdm[p];
0267 
0268         /* Record last Power Tracking Thermal Value */
0269         pDM_Odm->RFCalibrateInfo.ThermalValue = ThermalValue;
0270     }
0271 
0272     pDM_Odm->RFCalibrateInfo.TXPowercount = 0;
0273 }