root/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. odm_SetCrystalCap
  2. odm_GetDefaultCrytaltalCap
  3. odm_SetATCStatus
  4. odm_GetATCStatus
  5. ODM_CfoTrackingReset
  6. ODM_CfoTrackingInit
  7. ODM_CfoTracking
  8. ODM_ParsingCFO

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   5  *
   6  ******************************************************************************/
   7 
   8 #include "odm_precomp.h"
   9 
  10 static void odm_SetCrystalCap(void *pDM_VOID, u8 CrystalCap)
  11 {
  12         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  13         PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
  14 
  15         if (pCfoTrack->CrystalCap == CrystalCap)
  16                 return;
  17 
  18         pCfoTrack->CrystalCap = CrystalCap;
  19 
  20         /*  0x2C[23:18] = 0x2C[17:12] = CrystalCap */
  21         CrystalCap = CrystalCap & 0x3F;
  22         PHY_SetBBReg(
  23                 pDM_Odm->Adapter,
  24                 REG_MAC_PHY_CTRL,
  25                 0x00FFF000,
  26                 (CrystalCap | (CrystalCap << 6))
  27         );
  28 
  29         ODM_RT_TRACE(
  30                 pDM_Odm,
  31                 ODM_COMP_CFO_TRACKING,
  32                 ODM_DBG_LOUD,
  33                 (
  34                         "odm_SetCrystalCap(): CrystalCap = 0x%x\n",
  35                         CrystalCap
  36                 )
  37         );
  38 }
  39 
  40 static u8 odm_GetDefaultCrytaltalCap(void *pDM_VOID)
  41 {
  42         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  43         u8 CrystalCap = 0x20;
  44 
  45         struct adapter *Adapter = pDM_Odm->Adapter;
  46         struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
  47 
  48         CrystalCap = pHalData->CrystalCap;
  49 
  50         CrystalCap = CrystalCap & 0x3f;
  51 
  52         return CrystalCap;
  53 }
  54 
  55 static void odm_SetATCStatus(void *pDM_VOID, bool ATCStatus)
  56 {
  57         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  58         PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
  59 
  60         if (pCfoTrack->bATCStatus == ATCStatus)
  61                 return;
  62 
  63         PHY_SetBBReg(
  64                 pDM_Odm->Adapter,
  65                 ODM_REG(BB_ATC, pDM_Odm),
  66                 ODM_BIT(BB_ATC, pDM_Odm),
  67                 ATCStatus
  68         );
  69         pCfoTrack->bATCStatus = ATCStatus;
  70 }
  71 
  72 static bool odm_GetATCStatus(void *pDM_VOID)
  73 {
  74         bool ATCStatus;
  75         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  76 
  77         ATCStatus = (bool)PHY_QueryBBReg(
  78                 pDM_Odm->Adapter,
  79                 ODM_REG(BB_ATC, pDM_Odm),
  80                 ODM_BIT(BB_ATC, pDM_Odm)
  81         );
  82         return ATCStatus;
  83 }
  84 
  85 void ODM_CfoTrackingReset(void *pDM_VOID)
  86 {
  87         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  88         PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
  89 
  90         pCfoTrack->DefXCap = odm_GetDefaultCrytaltalCap(pDM_Odm);
  91         pCfoTrack->bAdjust = true;
  92 
  93         odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap);
  94         odm_SetATCStatus(pDM_Odm, true);
  95 }
  96 
  97 void ODM_CfoTrackingInit(void *pDM_VOID)
  98 {
  99         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 100         PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
 101 
 102         pCfoTrack->DefXCap =
 103                 pCfoTrack->CrystalCap = odm_GetDefaultCrytaltalCap(pDM_Odm);
 104         pCfoTrack->bATCStatus = odm_GetATCStatus(pDM_Odm);
 105         pCfoTrack->bAdjust = true;
 106         ODM_RT_TRACE(
 107                 pDM_Odm,
 108                 ODM_COMP_CFO_TRACKING,
 109                 ODM_DBG_LOUD,
 110                 ("ODM_CfoTracking_init() =========>\n")
 111         );
 112         ODM_RT_TRACE(
 113                 pDM_Odm,
 114                 ODM_COMP_CFO_TRACKING,
 115                 ODM_DBG_LOUD,
 116                 (
 117                         "ODM_CfoTracking_init(): bATCStatus = %d, CrystalCap = 0x%x\n",
 118                         pCfoTrack->bATCStatus,
 119                         pCfoTrack->DefXCap
 120                 )
 121         );
 122 }
 123 
 124 void ODM_CfoTracking(void *pDM_VOID)
 125 {
 126         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 127         PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
 128         int CFO_kHz_A, CFO_kHz_B, CFO_ave = 0;
 129         int CFO_ave_diff;
 130         int CrystalCap = (int)pCfoTrack->CrystalCap;
 131         u8 Adjust_Xtal = 1;
 132 
 133         /* 4 Support ability */
 134         if (!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING)) {
 135                 ODM_RT_TRACE(
 136                         pDM_Odm,
 137                         ODM_COMP_CFO_TRACKING,
 138                         ODM_DBG_LOUD,
 139                         ("ODM_CfoTracking(): Return: SupportAbility ODM_BB_CFO_TRACKING is disabled\n")
 140                 );
 141                 return;
 142         }
 143 
 144         ODM_RT_TRACE(
 145                 pDM_Odm,
 146                 ODM_COMP_CFO_TRACKING,
 147                 ODM_DBG_LOUD,
 148                 ("ODM_CfoTracking() =========>\n")
 149         );
 150 
 151         if (!pDM_Odm->bLinked || !pDM_Odm->bOneEntryOnly) {
 152                 /* 4 No link or more than one entry */
 153                 ODM_CfoTrackingReset(pDM_Odm);
 154                 ODM_RT_TRACE(
 155                         pDM_Odm,
 156                         ODM_COMP_CFO_TRACKING,
 157                         ODM_DBG_LOUD,
 158                         (
 159                                 "ODM_CfoTracking(): Reset: bLinked = %d, bOneEntryOnly = %d\n",
 160                                 pDM_Odm->bLinked,
 161                                 pDM_Odm->bOneEntryOnly
 162                         )
 163                 );
 164         } else {
 165                 /* 3 1. CFO Tracking */
 166                 /* 4 1.1 No new packet */
 167                 if (pCfoTrack->packetCount == pCfoTrack->packetCount_pre) {
 168                         ODM_RT_TRACE(
 169                                 pDM_Odm,
 170                                 ODM_COMP_CFO_TRACKING,
 171                                 ODM_DBG_LOUD,
 172                                 (
 173                                         "ODM_CfoTracking(): packet counter doesn't change\n"
 174                                 )
 175                         );
 176                         return;
 177                 }
 178                 pCfoTrack->packetCount_pre = pCfoTrack->packetCount;
 179 
 180                 /* 4 1.2 Calculate CFO */
 181                 CFO_kHz_A =  (int)(pCfoTrack->CFO_tail[0] * 3125)  / 1280;
 182                 CFO_kHz_B =  (int)(pCfoTrack->CFO_tail[1] * 3125)  / 1280;
 183 
 184                 if (pDM_Odm->RFType < ODM_2T2R)
 185                         CFO_ave = CFO_kHz_A;
 186                 else
 187                         CFO_ave = (int)(CFO_kHz_A + CFO_kHz_B) >> 1;
 188                 ODM_RT_TRACE(
 189                         pDM_Odm,
 190                         ODM_COMP_CFO_TRACKING,
 191                         ODM_DBG_LOUD,
 192                         (
 193                                 "ODM_CfoTracking(): CFO_kHz_A = %dkHz, CFO_kHz_B = %dkHz, CFO_ave = %dkHz\n",
 194                                 CFO_kHz_A,
 195                                 CFO_kHz_B,
 196                                 CFO_ave
 197                         )
 198                 );
 199 
 200                 /* 4 1.3 Avoid abnormal large CFO */
 201                 CFO_ave_diff =
 202                         (pCfoTrack->CFO_ave_pre >= CFO_ave) ?
 203                         (pCfoTrack->CFO_ave_pre-CFO_ave) :
 204                         (CFO_ave-pCfoTrack->CFO_ave_pre);
 205 
 206                 if (
 207                         CFO_ave_diff > 20 &&
 208                         pCfoTrack->largeCFOHit == 0 &&
 209                         !pCfoTrack->bAdjust
 210                 ) {
 211                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): first large CFO hit\n"));
 212                         pCfoTrack->largeCFOHit = 1;
 213                         return;
 214                 } else
 215                         pCfoTrack->largeCFOHit = 0;
 216                 pCfoTrack->CFO_ave_pre = CFO_ave;
 217 
 218                 /* 4 1.4 Dynamic Xtal threshold */
 219                 if (pCfoTrack->bAdjust == false) {
 220                         if (CFO_ave > CFO_TH_XTAL_HIGH || CFO_ave < (-CFO_TH_XTAL_HIGH))
 221                                 pCfoTrack->bAdjust = true;
 222                 } else {
 223                         if (CFO_ave < CFO_TH_XTAL_LOW && CFO_ave > (-CFO_TH_XTAL_LOW))
 224                                 pCfoTrack->bAdjust = false;
 225                 }
 226 
 227                 /* 4 1.5 BT case: Disable CFO tracking */
 228                 if (pDM_Odm->bBtEnabled) {
 229                         pCfoTrack->bAdjust = false;
 230                         odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap);
 231                         ODM_RT_TRACE(
 232                                 pDM_Odm,
 233                                 ODM_COMP_CFO_TRACKING,
 234                                 ODM_DBG_LOUD,
 235                                 ("ODM_CfoTracking(): Disable CFO tracking for BT!!\n")
 236                         );
 237                 }
 238 
 239                 /* 4 1.6 Big jump */
 240                 if (pCfoTrack->bAdjust) {
 241                         if (CFO_ave > CFO_TH_XTAL_LOW)
 242                                 Adjust_Xtal = Adjust_Xtal+((CFO_ave-CFO_TH_XTAL_LOW)>>2);
 243                         else if (CFO_ave < (-CFO_TH_XTAL_LOW))
 244                                 Adjust_Xtal = Adjust_Xtal+((CFO_TH_XTAL_LOW-CFO_ave)>>2);
 245 
 246                         ODM_RT_TRACE(
 247                                 pDM_Odm,
 248                                 ODM_COMP_CFO_TRACKING,
 249                                 ODM_DBG_LOUD,
 250                                 (
 251                                         "ODM_CfoTracking(): Crystal cap offset = %d\n",
 252                                         Adjust_Xtal
 253                                 )
 254                         );
 255                 }
 256 
 257                 /* 4 1.7 Adjust Crystal Cap. */
 258                 if (pCfoTrack->bAdjust) {
 259                         if (CFO_ave > CFO_TH_XTAL_LOW)
 260                                 CrystalCap = CrystalCap + Adjust_Xtal;
 261                         else if (CFO_ave < (-CFO_TH_XTAL_LOW))
 262                                 CrystalCap = CrystalCap - Adjust_Xtal;
 263 
 264                         if (CrystalCap > 0x3f)
 265                                 CrystalCap = 0x3f;
 266                         else if (CrystalCap < 0)
 267                                 CrystalCap = 0;
 268 
 269                         odm_SetCrystalCap(pDM_Odm, (u8)CrystalCap);
 270                 }
 271                 ODM_RT_TRACE(
 272                         pDM_Odm,
 273                         ODM_COMP_CFO_TRACKING,
 274                         ODM_DBG_LOUD,
 275                         (
 276                                 "ODM_CfoTracking(): Crystal cap = 0x%x, Default Crystal cap = 0x%x\n",
 277                                 pCfoTrack->CrystalCap,
 278                                 pCfoTrack->DefXCap
 279                         )
 280                 );
 281 
 282                 /* 3 2. Dynamic ATC switch */
 283                 if (CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC) {
 284                         odm_SetATCStatus(pDM_Odm, false);
 285                         ODM_RT_TRACE(
 286                                 pDM_Odm,
 287                                 ODM_COMP_CFO_TRACKING,
 288                                 ODM_DBG_LOUD,
 289                                 ("ODM_CfoTracking(): Disable ATC!!\n")
 290                         );
 291                 } else {
 292                         odm_SetATCStatus(pDM_Odm, true);
 293                         ODM_RT_TRACE(
 294                                 pDM_Odm,
 295                                 ODM_COMP_CFO_TRACKING,
 296                                 ODM_DBG_LOUD,
 297                                 ("ODM_CfoTracking(): Enable ATC!!\n")
 298                         );
 299                 }
 300         }
 301 }
 302 
 303 void ODM_ParsingCFO(void *pDM_VOID, void *pPktinfo_VOID, s8 *pcfotail)
 304 {
 305         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 306         struct odm_packet_info *pPktinfo = (struct odm_packet_info *)pPktinfo_VOID;
 307         PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
 308         u8 i;
 309 
 310         if (!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))
 311                 return;
 312 
 313         if (pPktinfo->station_id != 0) {
 314                 /* 3 Update CFO report for path-A & path-B */
 315                 /*  Only paht-A and path-B have CFO tail and short CFO */
 316                 for (i = ODM_RF_PATH_A; i <= ODM_RF_PATH_B; i++)
 317                         pCfoTrack->CFO_tail[i] = (int)pcfotail[i];
 318 
 319                 /* 3 Update packet counter */
 320                 if (pCfoTrack->packetCount == 0xffffffff)
 321                         pCfoTrack->packetCount = 0;
 322                 else
 323                         pCfoTrack->packetCount++;
 324         }
 325 }

/* [<][>][^][v][top][bottom][index][help] */