linux/drivers/staging/rtl8723bs/hal/odm_DIG.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7
   8#include "odm_precomp.h"
   9
  10#define ADAPTIVITY_VERSION "5.0"
  11
  12void odm_NHMCounterStatisticsInit(void *pDM_VOID)
  13{
  14        PDM_ODM_T               pDM_Odm = (PDM_ODM_T)pDM_VOID;
  15
  16        /* PHY parameters initialize for n series */
  17        rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x2710); /* 0x894[31:16]= 0x2710 Time duration for NHM unit: 4us, 0x2710 =40ms */
  18        /* rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x4e20);      0x894[31:16]= 0x4e20    Time duration for NHM unit: 4us, 0x4e20 =80ms */
  19        rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff);      /* 0x890[31:16]= 0xffff th_9, th_10 */
  20        /* rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff5c);       0x898 = 0xffffff5c              th_3, th_2, th_1, th_0 */
  21        rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff52);  /* 0x898 = 0xffffff52           th_3, th_2, th_1, th_0 */
  22        rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff);  /* 0x89c = 0xffffffff           th_7, th_6, th_5, th_4 */
  23        PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff);                /* 0xe28[7:0]= 0xff             th_8 */
  24        PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x7); /* 0x890[9:8]=3                 enable CCX */
  25        PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1);            /* 0xc0c[7]= 1                  max power among all RX ants */
  26}
  27
  28void odm_NHMCounterStatistics(void *pDM_VOID)
  29{
  30        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  31
  32        /*  Get NHM report */
  33        odm_GetNHMCounterStatistics(pDM_Odm);
  34
  35        /*  Reset NHM counter */
  36        odm_NHMCounterStatisticsReset(pDM_Odm);
  37}
  38
  39void odm_GetNHMCounterStatistics(void *pDM_VOID)
  40{
  41        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  42        u32 value32 = 0;
  43
  44        value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_NHM_CNT_11N, bMaskDWord);
  45
  46        pDM_Odm->NHM_cnt_0 = (u8)(value32 & bMaskByte0);
  47}
  48
  49void odm_NHMCounterStatisticsReset(void *pDM_VOID)
  50{
  51        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  52
  53        PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 0);
  54        PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 1);
  55}
  56
  57void odm_NHMBBInit(void *pDM_VOID)
  58{
  59        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  60
  61        pDM_Odm->adaptivity_flag = 0;
  62        pDM_Odm->tolerance_cnt = 3;
  63        pDM_Odm->NHMLastTxOkcnt = 0;
  64        pDM_Odm->NHMLastRxOkcnt = 0;
  65        pDM_Odm->NHMCurTxOkcnt = 0;
  66        pDM_Odm->NHMCurRxOkcnt = 0;
  67}
  68
  69/*  */
  70void odm_NHMBB(void *pDM_VOID)
  71{
  72        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
  73        /* u8 test_status; */
  74        /* Pfalse_ALARM_STATISTICS pFalseAlmCnt = &(pDM_Odm->FalseAlmCnt); */
  75
  76        pDM_Odm->NHMCurTxOkcnt =
  77                *(pDM_Odm->pNumTxBytesUnicast)-pDM_Odm->NHMLastTxOkcnt;
  78        pDM_Odm->NHMCurRxOkcnt =
  79                *(pDM_Odm->pNumRxBytesUnicast)-pDM_Odm->NHMLastRxOkcnt;
  80        pDM_Odm->NHMLastTxOkcnt =
  81                *(pDM_Odm->pNumTxBytesUnicast);
  82        pDM_Odm->NHMLastRxOkcnt =
  83                *(pDM_Odm->pNumRxBytesUnicast);
  84        ODM_RT_TRACE(
  85                pDM_Odm,
  86                ODM_COMP_DIG,
  87                ODM_DBG_LOUD,
  88                (
  89                        "NHM_cnt_0 =%d, NHMCurTxOkcnt = %llu, NHMCurRxOkcnt = %llu\n",
  90                        pDM_Odm->NHM_cnt_0,
  91                        pDM_Odm->NHMCurTxOkcnt,
  92                        pDM_Odm->NHMCurRxOkcnt
  93                )
  94        );
  95
  96
  97        if ((pDM_Odm->NHMCurTxOkcnt) + 1 > (u64)(pDM_Odm->NHMCurRxOkcnt<<2) + 1) { /* Tx > 4*Rx possible for adaptivity test */
  98                if (pDM_Odm->NHM_cnt_0 >= 190 || pDM_Odm->adaptivity_flag == true) {
  99                        /* Enable EDCCA since it is possible running Adaptivity testing */
 100                        /* test_status = 1; */
 101                        pDM_Odm->adaptivity_flag = true;
 102                        pDM_Odm->tolerance_cnt = 0;
 103                } else {
 104                        if (pDM_Odm->tolerance_cnt < 3)
 105                                pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
 106                        else
 107                                pDM_Odm->tolerance_cnt = 4;
 108                        /* test_status = 5; */
 109                        if (pDM_Odm->tolerance_cnt > 3) {
 110                                /* test_status = 3; */
 111                                pDM_Odm->adaptivity_flag = false;
 112                        }
 113                }
 114        } else { /*  TX<RX */
 115                if (pDM_Odm->adaptivity_flag == true && pDM_Odm->NHM_cnt_0 <= 200) {
 116                        /* test_status = 2; */
 117                        pDM_Odm->tolerance_cnt = 0;
 118                } else {
 119                        if (pDM_Odm->tolerance_cnt < 3)
 120                                pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
 121                        else
 122                                pDM_Odm->tolerance_cnt = 4;
 123                        /* test_status = 5; */
 124                        if (pDM_Odm->tolerance_cnt > 3) {
 125                                /* test_status = 4; */
 126                                pDM_Odm->adaptivity_flag = false;
 127                        }
 128                }
 129        }
 130
 131        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("adaptivity_flag = %d\n ", pDM_Odm->adaptivity_flag));
 132}
 133
 134void odm_SearchPwdBLowerBound(void *pDM_VOID, u8 IGI_target)
 135{
 136        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 137        u32 value32 = 0;
 138        u8 cnt, IGI;
 139        bool bAdjust = true;
 140        s8 TH_L2H_dmc, TH_H2L_dmc;
 141        s8 Diff;
 142
 143        IGI = 0x50; /*  find H2L, L2H lower bound */
 144        ODM_Write_DIG(pDM_Odm, IGI);
 145
 146
 147        Diff = IGI_target-(s8)IGI;
 148        TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
 149        if (TH_L2H_dmc > 10)
 150                TH_L2H_dmc = 10;
 151        TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
 152        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
 153        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
 154
 155        mdelay(5);
 156
 157        while (bAdjust) {
 158                for (cnt = 0; cnt < 20; cnt++) {
 159                        value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_RPT_11N, bMaskDWord);
 160
 161                        if (value32 & BIT30)
 162                                pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
 163                        else if (value32 & BIT29)
 164                                pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
 165                        else
 166                                pDM_Odm->txEdcca0 = pDM_Odm->txEdcca0 + 1;
 167                }
 168                /* DbgPrint("txEdcca1 = %d, txEdcca0 = %d\n", pDM_Odm->txEdcca1, pDM_Odm->txEdcca0); */
 169
 170                if (pDM_Odm->txEdcca1 > 5) {
 171                        IGI = IGI-1;
 172                        TH_L2H_dmc = TH_L2H_dmc + 1;
 173                        if (TH_L2H_dmc > 10)
 174                                TH_L2H_dmc = 10;
 175                        TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
 176                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
 177                        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
 178
 179                        pDM_Odm->TxHangFlg = true;
 180                        pDM_Odm->txEdcca1 = 0;
 181                        pDM_Odm->txEdcca0 = 0;
 182
 183                        if (TH_L2H_dmc == 10) {
 184                                bAdjust = false;
 185                                pDM_Odm->TxHangFlg = false;
 186                                pDM_Odm->txEdcca1 = 0;
 187                                pDM_Odm->txEdcca0 = 0;
 188                                pDM_Odm->H2L_lb = TH_H2L_dmc;
 189                                pDM_Odm->L2H_lb = TH_L2H_dmc;
 190                                pDM_Odm->Adaptivity_IGI_upper = IGI;
 191                        }
 192                } else {
 193                        bAdjust = false;
 194                        pDM_Odm->TxHangFlg = false;
 195                        pDM_Odm->txEdcca1 = 0;
 196                        pDM_Odm->txEdcca0 = 0;
 197                        pDM_Odm->H2L_lb = TH_H2L_dmc;
 198                        pDM_Odm->L2H_lb = TH_L2H_dmc;
 199                        pDM_Odm->Adaptivity_IGI_upper = IGI;
 200                }
 201        }
 202
 203        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("IGI = 0x%x, H2L_lb = 0x%x, L2H_lb = 0x%x\n", IGI, pDM_Odm->H2L_lb, pDM_Odm->L2H_lb));
 204}
 205
 206void odm_AdaptivityInit(void *pDM_VOID)
 207{
 208        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 209
 210        if (pDM_Odm->Carrier_Sense_enable == false)
 211                pDM_Odm->TH_L2H_ini = 0xf7; /*  -7 */
 212        else
 213                pDM_Odm->TH_L2H_ini = 0xa;
 214
 215        pDM_Odm->AdapEn_RSSI = 20;
 216        pDM_Odm->TH_EDCCA_HL_diff = 7;
 217
 218        pDM_Odm->IGI_Base = 0x32;
 219        pDM_Odm->IGI_target = 0x1c;
 220        pDM_Odm->ForceEDCCA = 0;
 221        pDM_Odm->NHM_disable = false;
 222        pDM_Odm->TxHangFlg = true;
 223        pDM_Odm->txEdcca0 = 0;
 224        pDM_Odm->txEdcca1 = 0;
 225        pDM_Odm->H2L_lb = 0;
 226        pDM_Odm->L2H_lb = 0;
 227        pDM_Odm->Adaptivity_IGI_upper = 0;
 228        odm_NHMBBInit(pDM_Odm);
 229
 230        PHY_SetBBReg(pDM_Odm->Adapter, REG_RD_CTRL, BIT11, 1); /*  stop counting if EDCCA is asserted */
 231}
 232
 233
 234void odm_Adaptivity(void *pDM_VOID, u8 IGI)
 235{
 236        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 237        s8 TH_L2H_dmc, TH_H2L_dmc;
 238        s8 Diff, IGI_target;
 239        bool EDCCA_State = false;
 240
 241        if (!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) {
 242                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Go to odm_DynamicEDCCA()\n"));
 243                return;
 244        }
 245        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_Adaptivity() =====>\n"));
 246        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("ForceEDCCA =%d, IGI_Base = 0x%x, TH_L2H_ini = %d, TH_EDCCA_HL_diff = %d, AdapEn_RSSI = %d\n",
 247                pDM_Odm->ForceEDCCA, pDM_Odm->IGI_Base, pDM_Odm->TH_L2H_ini, pDM_Odm->TH_EDCCA_HL_diff, pDM_Odm->AdapEn_RSSI));
 248
 249        if (*pDM_Odm->pBandWidth == ODM_BW20M) /* CHANNEL_WIDTH_20 */
 250                IGI_target = pDM_Odm->IGI_Base;
 251        else if (*pDM_Odm->pBandWidth == ODM_BW40M)
 252                IGI_target = pDM_Odm->IGI_Base + 2;
 253        else if (*pDM_Odm->pBandWidth == ODM_BW80M)
 254                IGI_target = pDM_Odm->IGI_Base + 2;
 255        else
 256                IGI_target = pDM_Odm->IGI_Base;
 257        pDM_Odm->IGI_target = (u8) IGI_target;
 258
 259        /* Search pwdB lower bound */
 260        if (pDM_Odm->TxHangFlg == true) {
 261                PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208);
 262                odm_SearchPwdBLowerBound(pDM_Odm, pDM_Odm->IGI_target);
 263        }
 264
 265        if ((!pDM_Odm->bLinked) || (*pDM_Odm->pChannel > 149)) { /*  Band4 doesn't need adaptivity */
 266                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, 0x7f);
 267                PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, 0x7f);
 268                return;
 269        }
 270
 271        if (!pDM_Odm->ForceEDCCA) {
 272                if (pDM_Odm->RSSI_Min > pDM_Odm->AdapEn_RSSI)
 273                        EDCCA_State = true;
 274                else if (pDM_Odm->RSSI_Min < (pDM_Odm->AdapEn_RSSI - 5))
 275                        EDCCA_State = false;
 276        } else
 277                EDCCA_State = true;
 278
 279        if (
 280                pDM_Odm->bLinked &&
 281                pDM_Odm->Carrier_Sense_enable == false &&
 282                pDM_Odm->NHM_disable == false &&
 283                pDM_Odm->TxHangFlg == false
 284        )
 285                odm_NHMBB(pDM_Odm);
 286
 287        ODM_RT_TRACE(
 288                pDM_Odm,
 289                ODM_COMP_DIG,
 290                ODM_DBG_LOUD,
 291                (
 292                        "BandWidth =%s, IGI_target = 0x%x, EDCCA_State =%d\n",
 293                        (*pDM_Odm->pBandWidth == ODM_BW80M) ? "80M" :
 294                        ((*pDM_Odm->pBandWidth == ODM_BW40M) ? "40M" : "20M"),
 295                        IGI_target,
 296                        EDCCA_State
 297                )
 298        );
 299
 300        if (EDCCA_State) {
 301                Diff = IGI_target-(s8)IGI;
 302                TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
 303                if (TH_L2H_dmc > 10)
 304                        TH_L2H_dmc = 10;
 305
 306                TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
 307
 308                /* replace lower bound to prevent EDCCA always equal  */
 309                if (TH_H2L_dmc < pDM_Odm->H2L_lb)
 310                        TH_H2L_dmc = pDM_Odm->H2L_lb;
 311                if (TH_L2H_dmc < pDM_Odm->L2H_lb)
 312                        TH_L2H_dmc = pDM_Odm->L2H_lb;
 313        } else {
 314                TH_L2H_dmc = 0x7f;
 315                TH_H2L_dmc = 0x7f;
 316        }
 317        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("IGI = 0x%x, TH_L2H_dmc = %d, TH_H2L_dmc = %d\n",
 318                IGI, TH_L2H_dmc, TH_H2L_dmc));
 319        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
 320        PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
 321}
 322
 323void ODM_Write_DIG(void *pDM_VOID, u8 CurrentIGI)
 324{
 325        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 326        pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
 327
 328        if (pDM_DigTable->bStopDIG) {
 329                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Stop Writing IGI\n"));
 330                return;
 331        }
 332
 333        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("ODM_REG(IGI_A, pDM_Odm) = 0x%x, ODM_BIT(IGI, pDM_Odm) = 0x%x\n",
 334                ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm)));
 335
 336        if (pDM_DigTable->CurIGValue != CurrentIGI) {
 337                /* 1 Check initial gain by upper bound */
 338                if (!pDM_DigTable->bPSDInProgress) {
 339                        if (CurrentIGI > pDM_DigTable->rx_gain_range_max) {
 340                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("CurrentIGI(0x%02x) is larger than upper bound !!\n", pDM_DigTable->rx_gain_range_max));
 341                                CurrentIGI = pDM_DigTable->rx_gain_range_max;
 342                        }
 343
 344                }
 345
 346                /* 1 Set IGI value */
 347                PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
 348
 349                if (pDM_Odm->RFType > ODM_1T1R)
 350                        PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
 351
 352                pDM_DigTable->CurIGValue = CurrentIGI;
 353        }
 354
 355        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("CurrentIGI(0x%02x).\n", CurrentIGI));
 356
 357}
 358
 359void odm_PauseDIG(
 360        void *pDM_VOID,
 361        ODM_Pause_DIG_TYPE PauseType,
 362        u8 IGIValue
 363)
 364{
 365        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 366        pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
 367        static bool bPaused;
 368
 369        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG() =========>\n"));
 370
 371        if (
 372                (pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY) &&
 373                pDM_Odm->TxHangFlg == true
 374        ) {
 375                ODM_RT_TRACE(
 376                        pDM_Odm,
 377                        ODM_COMP_DIG,
 378                        ODM_DBG_LOUD,
 379                        ("odm_PauseDIG(): Dynamic adjust threshold in progress !!\n")
 380                );
 381                return;
 382        }
 383
 384        if (
 385                !bPaused && (!(pDM_Odm->SupportAbility & ODM_BB_DIG) ||
 386                !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
 387        ){
 388                ODM_RT_TRACE(
 389                        pDM_Odm,
 390                        ODM_COMP_DIG,
 391                        ODM_DBG_LOUD,
 392                        ("odm_PauseDIG(): Return: SupportAbility ODM_BB_DIG or ODM_BB_FA_CNT is disabled\n")
 393                );
 394                return;
 395        }
 396
 397        switch (PauseType) {
 398        /* 1 Pause DIG */
 399        case ODM_PAUSE_DIG:
 400                /* 2 Disable DIG */
 401                ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility & (~ODM_BB_DIG));
 402                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Pause DIG !!\n"));
 403
 404                /* 2 Backup IGI value */
 405                if (!bPaused) {
 406                        pDM_DigTable->IGIBackup = pDM_DigTable->CurIGValue;
 407                        bPaused = true;
 408                }
 409                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Backup IGI  = 0x%x\n", pDM_DigTable->IGIBackup));
 410
 411                /* 2 Write new IGI value */
 412                ODM_Write_DIG(pDM_Odm, IGIValue);
 413                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Write new IGI = 0x%x\n", IGIValue));
 414                break;
 415
 416        /* 1 Resume DIG */
 417        case ODM_RESUME_DIG:
 418                if (bPaused) {
 419                        /* 2 Write backup IGI value */
 420                        ODM_Write_DIG(pDM_Odm, pDM_DigTable->IGIBackup);
 421                        bPaused = false;
 422                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Write original IGI = 0x%x\n", pDM_DigTable->IGIBackup));
 423
 424                        /* 2 Enable DIG */
 425                        ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_DIG);
 426                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Resume DIG !!\n"));
 427                }
 428                break;
 429
 430        default:
 431                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Wrong  type !!\n"));
 432                break;
 433        }
 434}
 435
 436bool odm_DigAbort(void *pDM_VOID)
 437{
 438        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 439
 440        /* SupportAbility */
 441        if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) {
 442                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: SupportAbility ODM_BB_FA_CNT is disabled\n"));
 443                return  true;
 444        }
 445
 446        /* SupportAbility */
 447        if (!(pDM_Odm->SupportAbility & ODM_BB_DIG)) {
 448                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: SupportAbility ODM_BB_DIG is disabled\n"));
 449                return  true;
 450        }
 451
 452        /* ScanInProcess */
 453        if (*(pDM_Odm->pbScanInProcess)) {
 454                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: In Scan Progress\n"));
 455                return  true;
 456        }
 457
 458        /* add by Neil Chen to avoid PSD is processing */
 459        if (pDM_Odm->bDMInitialGainEnable == false) {
 460                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: PSD is Processing\n"));
 461                return  true;
 462        }
 463
 464        return  false;
 465}
 466
 467void odm_DIGInit(void *pDM_VOID)
 468{
 469        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 470        pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
 471
 472        pDM_DigTable->bStopDIG = false;
 473        pDM_DigTable->bPSDInProgress = false;
 474        pDM_DigTable->CurIGValue = (u8) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm));
 475        pDM_DigTable->RssiLowThresh     = DM_DIG_THRESH_LOW;
 476        pDM_DigTable->RssiHighThresh    = DM_DIG_THRESH_HIGH;
 477        pDM_DigTable->FALowThresh       = DMfalseALARM_THRESH_LOW;
 478        pDM_DigTable->FAHighThresh      = DMfalseALARM_THRESH_HIGH;
 479        pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT;
 480        pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
 481        pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
 482        pDM_DigTable->PreCCK_CCAThres = 0xFF;
 483        pDM_DigTable->CurCCK_CCAThres = 0x83;
 484        pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC;
 485        pDM_DigTable->LargeFAHit = 0;
 486        pDM_DigTable->Recover_cnt = 0;
 487        pDM_DigTable->bMediaConnect_0 = false;
 488        pDM_DigTable->bMediaConnect_1 = false;
 489
 490        /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */
 491        pDM_Odm->bDMInitialGainEnable = true;
 492
 493        pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC;
 494        pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC;
 495
 496        /* To Initi BT30 IGI */
 497        pDM_DigTable->BT30_CurIGI = 0x32;
 498
 499        if (pDM_Odm->BoardType & (ODM_BOARD_EXT_PA|ODM_BOARD_EXT_LNA)) {
 500                pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
 501                pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
 502        } else {
 503                pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
 504                pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
 505        }
 506
 507}
 508
 509
 510void odm_DIG(void *pDM_VOID)
 511{
 512        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 513
 514        /*  Common parameters */
 515        pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
 516        Pfalse_ALARM_STATISTICS pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
 517        bool FirstConnect, FirstDisConnect;
 518        u8 DIG_MaxOfMin, DIG_Dynamic_MIN;
 519        u8 dm_dig_max, dm_dig_min;
 520        u8 CurrentIGI = pDM_DigTable->CurIGValue;
 521        u8 offset;
 522        u32 dm_FA_thres[3];
 523        u8 Adap_IGI_Upper = 0;
 524        u32 TxTp = 0, RxTp = 0;
 525        bool bDFSBand = false;
 526        bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false;
 527
 528        if (odm_DigAbort(pDM_Odm) == true)
 529                return;
 530
 531        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG() ===========================>\n\n"));
 532
 533        if (pDM_Odm->adaptivity_flag == true)
 534                Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper;
 535
 536
 537        /* 1 Update status */
 538        DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
 539        FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == false);
 540        FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == true);
 541
 542        /* 1 Boundary Decision */
 543        /* 2 For WIN\CE */
 544        dm_dig_max = 0x5A;
 545        dm_dig_min = DM_DIG_MIN_NIC;
 546        DIG_MaxOfMin = DM_DIG_MAX_AP;
 547
 548        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Absolutely upper bound = 0x%x, lower bound = 0x%x\n", dm_dig_max, dm_dig_min));
 549
 550        /* 1 Adjust boundary by RSSI */
 551        if (pDM_Odm->bLinked && bPerformance) {
 552                /* 2 Modify DIG upper bound */
 553                /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
 554                if (pDM_Odm->bBtLimitedDig == 1) {
 555                        offset = 10;
 556                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Coex. case: Force upper bound to RSSI + %d !!!!!!\n", offset));
 557                } else
 558                        offset = 15;
 559
 560                if ((pDM_Odm->RSSI_Min + offset) > dm_dig_max)
 561                        pDM_DigTable->rx_gain_range_max = dm_dig_max;
 562                else if ((pDM_Odm->RSSI_Min + offset) < dm_dig_min)
 563                        pDM_DigTable->rx_gain_range_max = dm_dig_min;
 564                else
 565                        pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset;
 566
 567                /* 2 Modify DIG lower bound */
 568                /* if (pDM_Odm->bOneEntryOnly) */
 569                {
 570                        if (pDM_Odm->RSSI_Min < dm_dig_min)
 571                                DIG_Dynamic_MIN = dm_dig_min;
 572                        else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
 573                                DIG_Dynamic_MIN = DIG_MaxOfMin;
 574                        else
 575                                DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
 576                }
 577        } else {
 578                pDM_DigTable->rx_gain_range_max = dm_dig_max;
 579                DIG_Dynamic_MIN = dm_dig_min;
 580        }
 581
 582        /* 1 Force Lower Bound for AntDiv */
 583        if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) {
 584                if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
 585                        if (
 586                                pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV ||
 587                                pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV ||
 588                                pDM_Odm->AntDivType == S0S1_SW_ANTDIV
 589                        ) {
 590                                if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin)
 591                                        DIG_Dynamic_MIN = DIG_MaxOfMin;
 592                                else
 593                                        DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max;
 594                                ODM_RT_TRACE(
 595                                        pDM_Odm,
 596                                        ODM_COMP_ANT_DIV,
 597                                        ODM_DBG_LOUD,
 598                                        (
 599                                                "odm_DIG(): Antenna diversity case: Force lower bound to 0x%x !!!!!!\n",
 600                                                DIG_Dynamic_MIN
 601                                        )
 602                                );
 603                                ODM_RT_TRACE(
 604                                        pDM_Odm,
 605                                        ODM_COMP_ANT_DIV,
 606                                        ODM_DBG_LOUD,
 607                                        (
 608                                                "odm_DIG(): Antenna diversity case: RSSI_max = 0x%x !!!!!!\n",
 609                                                pDM_DigTable->AntDiv_RSSI_max
 610                                        )
 611                                );
 612                        }
 613                }
 614        }
 615        ODM_RT_TRACE(
 616                pDM_Odm,
 617                ODM_COMP_DIG,
 618                ODM_DBG_LOUD,
 619                (
 620                        "odm_DIG(): Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n",
 621                        pDM_DigTable->rx_gain_range_max,
 622                        DIG_Dynamic_MIN
 623                )
 624        );
 625        ODM_RT_TRACE(
 626                pDM_Odm,
 627                ODM_COMP_DIG,
 628                ODM_DBG_LOUD,
 629                (
 630                        "odm_DIG(): Link status: bLinked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n\n",
 631                        pDM_Odm->bLinked,
 632                        pDM_Odm->RSSI_Min,
 633                        FirstConnect,
 634                        FirstDisConnect
 635                )
 636        );
 637
 638        /* 1 Modify DIG lower bound, deal with abnormal case */
 639        /* 2 Abnormal false alarm case */
 640        if (FirstDisConnect) {
 641                pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN;
 642                pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN;
 643        } else
 644                pDM_DigTable->rx_gain_range_min =
 645                        odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI);
 646
 647        if (pDM_Odm->bLinked && !FirstConnect) {
 648                if (
 649                        (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
 650                        pDM_Odm->bsta_state
 651                ) {
 652                        pDM_DigTable->rx_gain_range_min = dm_dig_min;
 653                        ODM_RT_TRACE(
 654                                pDM_Odm,
 655                                ODM_COMP_DIG,
 656                                ODM_DBG_LOUD,
 657                                (
 658                                        "odm_DIG(): Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x !!!!!!\n\n",
 659                                        pDM_Odm->PhyDbgInfo.NumQryBeaconPkt,
 660                                        pDM_DigTable->rx_gain_range_min
 661                                )
 662                        );
 663                }
 664        }
 665
 666        /* 2 Abnormal lower bound case */
 667        if (pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) {
 668                pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
 669                ODM_RT_TRACE(
 670                        pDM_Odm,
 671                        ODM_COMP_DIG,
 672                        ODM_DBG_LOUD,
 673                        (
 674                                "odm_DIG(): Abnrormal lower bound case: Force lower bound to 0x%x !!!!!!\n\n",
 675                                pDM_DigTable->rx_gain_range_min
 676                        )
 677                );
 678        }
 679
 680
 681        /* 1 False alarm threshold decision */
 682        odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres);
 683        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): False alarm threshold = %d, %d, %d\n\n", dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2]));
 684
 685        /* 1 Adjust initial gain by false alarm */
 686        if (pDM_Odm->bLinked && bPerformance) {
 687                /* 2 After link */
 688                ODM_RT_TRACE(
 689                        pDM_Odm,
 690                        ODM_COMP_DIG,
 691                        ODM_DBG_LOUD,
 692                        ("odm_DIG(): Adjust IGI after link\n")
 693                );
 694
 695                if (bFirstTpTarget || (FirstConnect && bPerformance)) {
 696                        pDM_DigTable->LargeFAHit = 0;
 697
 698                        if (pDM_Odm->RSSI_Min < DIG_MaxOfMin) {
 699                                if (CurrentIGI < pDM_Odm->RSSI_Min)
 700                                        CurrentIGI = pDM_Odm->RSSI_Min;
 701                        } else {
 702                                if (CurrentIGI < DIG_MaxOfMin)
 703                                        CurrentIGI = DIG_MaxOfMin;
 704                        }
 705
 706                        ODM_RT_TRACE(
 707                                pDM_Odm,
 708                                ODM_COMP_DIG,
 709                                ODM_DBG_LOUD,
 710                                (
 711                                        "odm_DIG(): First connect case: IGI does on-shot to 0x%x\n",
 712                                        CurrentIGI
 713                                )
 714                        );
 715
 716                } else {
 717                        if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
 718                                CurrentIGI = CurrentIGI + 4;
 719                        else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
 720                                CurrentIGI = CurrentIGI + 2;
 721                        else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
 722                                CurrentIGI = CurrentIGI - 2;
 723
 724                        if (
 725                                (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
 726                                (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) &&
 727                                (pDM_Odm->bsta_state)
 728                        ) {
 729                                CurrentIGI = pDM_DigTable->rx_gain_range_min;
 730                                ODM_RT_TRACE(
 731                                        pDM_Odm,
 732                                        ODM_COMP_DIG,
 733                                        ODM_DBG_LOUD,
 734                                        (
 735                                                "odm_DIG(): Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n",
 736                                                pDM_Odm->PhyDbgInfo.NumQryBeaconPkt,
 737                                                CurrentIGI
 738                                        )
 739                                );
 740                        }
 741                }
 742        } else {
 743                /* 2 Before link */
 744                ODM_RT_TRACE(
 745                        pDM_Odm,
 746                        ODM_COMP_DIG,
 747                        ODM_DBG_LOUD,
 748                        ("odm_DIG(): Adjust IGI before link\n")
 749                );
 750
 751                if (FirstDisConnect || bFirstCoverage) {
 752                        CurrentIGI = dm_dig_min;
 753                        ODM_RT_TRACE(
 754                                pDM_Odm,
 755                                ODM_COMP_DIG,
 756                                ODM_DBG_LOUD,
 757                                ("odm_DIG(): First disconnect case: IGI does on-shot to lower bound\n")
 758                        );
 759                } else {
 760                        if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
 761                                CurrentIGI = CurrentIGI + 4;
 762                        else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
 763                                CurrentIGI = CurrentIGI + 2;
 764                        else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
 765                                CurrentIGI = CurrentIGI - 2;
 766                }
 767        }
 768
 769        /* 1 Check initial gain by upper/lower bound */
 770        if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
 771                CurrentIGI = pDM_DigTable->rx_gain_range_min;
 772
 773        if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
 774                CurrentIGI = pDM_DigTable->rx_gain_range_max;
 775
 776        ODM_RT_TRACE(
 777                pDM_Odm,
 778                ODM_COMP_DIG,
 779                ODM_DBG_LOUD,
 780                (
 781                        "odm_DIG(): CurIGValue = 0x%x, TotalFA = %d\n\n",
 782                        CurrentIGI,
 783                        pFalseAlmCnt->Cnt_all
 784                )
 785        );
 786
 787        /* 1 Force upper bound and lower bound for adaptivity */
 788        if (
 789                pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY &&
 790                pDM_Odm->adaptivity_flag == true
 791        ) {
 792                if (CurrentIGI > Adap_IGI_Upper)
 793                        CurrentIGI = Adap_IGI_Upper;
 794
 795                if (pDM_Odm->IGI_LowerBound != 0) {
 796                        if (CurrentIGI < pDM_Odm->IGI_LowerBound)
 797                                CurrentIGI = pDM_Odm->IGI_LowerBound;
 798                }
 799                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adaptivity case: Force upper bound to 0x%x !!!!!!\n", Adap_IGI_Upper));
 800                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adaptivity case: Force lower bound to 0x%x !!!!!!\n\n", pDM_Odm->IGI_LowerBound));
 801        }
 802
 803
 804        /* 1 Update status */
 805        if (pDM_Odm->bBtHsOperation) {
 806                if (pDM_Odm->bLinked) {
 807                        if (pDM_DigTable->BT30_CurIGI > (CurrentIGI))
 808                                ODM_Write_DIG(pDM_Odm, CurrentIGI);
 809                        else
 810                                ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);
 811
 812                        pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
 813                        pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
 814                } else {
 815                        if (pDM_Odm->bLinkInProcess)
 816                                ODM_Write_DIG(pDM_Odm, 0x1c);
 817                        else if (pDM_Odm->bBtConnectProcess)
 818                                ODM_Write_DIG(pDM_Odm, 0x28);
 819                        else
 820                                ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
 821                }
 822        } else { /*  BT is not using */
 823                ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
 824                pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
 825                pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
 826        }
 827}
 828
 829void odm_DIGbyRSSI_LPS(void *pDM_VOID)
 830{
 831        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 832        Pfalse_ALARM_STATISTICS pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
 833
 834        u8 RSSI_Lower = DM_DIG_MIN_NIC;   /* 0x1E or 0x1C */
 835        u8 CurrentIGI = pDM_Odm->RSSI_Min;
 836
 837        CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
 838
 839        ODM_RT_TRACE(
 840                pDM_Odm,
 841                ODM_COMP_DIG,
 842                ODM_DBG_LOUD,
 843                ("odm_DIGbyRSSI_LPS() ==>\n")
 844        );
 845
 846        /*  Using FW PS mode to make IGI */
 847        /* Adjust by  FA in LPS MODE */
 848        if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS)
 849                CurrentIGI = CurrentIGI+4;
 850        else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS)
 851                CurrentIGI = CurrentIGI+2;
 852        else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS)
 853                CurrentIGI = CurrentIGI-2;
 854
 855
 856        /* Lower bound checking */
 857
 858        /* RSSI Lower bound check */
 859        if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC)
 860                RSSI_Lower = pDM_Odm->RSSI_Min-10;
 861        else
 862                RSSI_Lower = DM_DIG_MIN_NIC;
 863
 864        /* Upper and Lower Bound checking */
 865        if (CurrentIGI > DM_DIG_MAX_NIC)
 866                CurrentIGI = DM_DIG_MAX_NIC;
 867        else if (CurrentIGI < RSSI_Lower)
 868                CurrentIGI = RSSI_Lower;
 869
 870
 871        ODM_RT_TRACE(
 872                pDM_Odm,
 873                ODM_COMP_DIG,
 874                ODM_DBG_LOUD,
 875                ("odm_DIGbyRSSI_LPS(): pFalseAlmCnt->Cnt_all = %d\n", pFalseAlmCnt->Cnt_all)
 876        );
 877        ODM_RT_TRACE(
 878                pDM_Odm,
 879                ODM_COMP_DIG,
 880                ODM_DBG_LOUD,
 881                ("odm_DIGbyRSSI_LPS(): pDM_Odm->RSSI_Min = %d\n", pDM_Odm->RSSI_Min)
 882        );
 883        ODM_RT_TRACE(
 884                pDM_Odm,
 885                ODM_COMP_DIG,
 886                ODM_DBG_LOUD,
 887                ("odm_DIGbyRSSI_LPS(): CurrentIGI = 0x%x\n", CurrentIGI)
 888        );
 889
 890        ODM_Write_DIG(pDM_Odm, CurrentIGI);
 891        /* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
 892}
 893
 894/* 3 ============================================================ */
 895/* 3 FASLE ALARM CHECK */
 896/* 3 ============================================================ */
 897
 898void odm_FalseAlarmCounterStatistics(void *pDM_VOID)
 899{
 900        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
 901        Pfalse_ALARM_STATISTICS FalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
 902        u32 ret_value;
 903
 904        if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
 905                return;
 906
 907        /* hold ofdm counter */
 908        /* hold page C counter */
 909        PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1);
 910        /* hold page D counter */
 911        PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1);
 912
 913        ret_value = PHY_QueryBBReg(
 914                pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord
 915        );
 916        FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
 917        FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16);
 918
 919        ret_value = PHY_QueryBBReg(
 920                pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord
 921        );
 922        FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
 923        FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
 924
 925        ret_value = PHY_QueryBBReg(
 926                pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord
 927        );
 928        FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
 929        FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
 930
 931        ret_value = PHY_QueryBBReg(
 932                pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord
 933        );
 934        FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
 935
 936        FalseAlmCnt->Cnt_Ofdm_fail =
 937                FalseAlmCnt->Cnt_Parity_Fail +
 938                FalseAlmCnt->Cnt_Rate_Illegal +
 939                FalseAlmCnt->Cnt_Crc8_fail +
 940                FalseAlmCnt->Cnt_Mcs_fail +
 941                FalseAlmCnt->Cnt_Fast_Fsync +
 942                FalseAlmCnt->Cnt_SB_Search_fail;
 943
 944        {
 945                /* hold cck counter */
 946                PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1);
 947                PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1);
 948
 949                ret_value = PHY_QueryBBReg(
 950                        pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0
 951                );
 952                FalseAlmCnt->Cnt_Cck_fail = ret_value;
 953
 954                ret_value = PHY_QueryBBReg(
 955                        pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3
 956                );
 957                FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8;
 958
 959                ret_value = PHY_QueryBBReg(
 960                        pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord
 961                );
 962                FalseAlmCnt->Cnt_CCK_CCA =
 963                        ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
 964        }
 965
 966        FalseAlmCnt->Cnt_all = (
 967                FalseAlmCnt->Cnt_Fast_Fsync +
 968                FalseAlmCnt->Cnt_SB_Search_fail +
 969                FalseAlmCnt->Cnt_Parity_Fail +
 970                FalseAlmCnt->Cnt_Rate_Illegal +
 971                FalseAlmCnt->Cnt_Crc8_fail +
 972                FalseAlmCnt->Cnt_Mcs_fail +
 973                FalseAlmCnt->Cnt_Cck_fail
 974        );
 975
 976        FalseAlmCnt->Cnt_CCA_all =
 977                FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
 978
 979        ODM_RT_TRACE(
 980                pDM_Odm,
 981                ODM_COMP_FA_CNT,
 982                ODM_DBG_LOUD,
 983                ("Enter odm_FalseAlarmCounterStatistics\n")
 984        );
 985        ODM_RT_TRACE(
 986                pDM_Odm,
 987                ODM_COMP_FA_CNT,
 988                ODM_DBG_LOUD,
 989                (
 990                        "Cnt_Fast_Fsync =%d, Cnt_SB_Search_fail =%d\n",
 991                        FalseAlmCnt->Cnt_Fast_Fsync,
 992                        FalseAlmCnt->Cnt_SB_Search_fail
 993                )
 994        );
 995        ODM_RT_TRACE(
 996                pDM_Odm,
 997                ODM_COMP_FA_CNT,
 998                ODM_DBG_LOUD,
 999                (
1000                        "Cnt_Parity_Fail =%d, Cnt_Rate_Illegal =%d\n",
1001                        FalseAlmCnt->Cnt_Parity_Fail,
1002                        FalseAlmCnt->Cnt_Rate_Illegal
1003                )
1004        );
1005        ODM_RT_TRACE(
1006                pDM_Odm,
1007                ODM_COMP_FA_CNT,
1008                ODM_DBG_LOUD,
1009                (
1010                        "Cnt_Crc8_fail =%d, Cnt_Mcs_fail =%d\n",
1011                        FalseAlmCnt->Cnt_Crc8_fail,
1012                        FalseAlmCnt->Cnt_Mcs_fail
1013                )
1014        );
1015
1016        ODM_RT_TRACE(
1017                pDM_Odm,
1018                ODM_COMP_FA_CNT,
1019                ODM_DBG_LOUD,
1020                ("Cnt_OFDM_CCA =%d\n", FalseAlmCnt->Cnt_OFDM_CCA)
1021        );
1022        ODM_RT_TRACE(
1023                pDM_Odm,
1024                ODM_COMP_FA_CNT,
1025                ODM_DBG_LOUD,
1026                ("Cnt_CCK_CCA =%d\n", FalseAlmCnt->Cnt_CCK_CCA)
1027        );
1028        ODM_RT_TRACE(
1029                pDM_Odm,
1030                ODM_COMP_FA_CNT,
1031                ODM_DBG_LOUD,
1032                ("Cnt_CCA_all =%d\n", FalseAlmCnt->Cnt_CCA_all)
1033        );
1034        ODM_RT_TRACE(
1035                pDM_Odm,
1036                ODM_COMP_FA_CNT,
1037                ODM_DBG_LOUD,
1038                ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail)
1039        );
1040        ODM_RT_TRACE(
1041                pDM_Odm,
1042                ODM_COMP_FA_CNT,
1043                ODM_DBG_LOUD,
1044                ("Cnt_Cck_fail =%d\n",  FalseAlmCnt->Cnt_Cck_fail)
1045        );
1046        ODM_RT_TRACE(
1047                pDM_Odm,
1048                ODM_COMP_FA_CNT,
1049                ODM_DBG_LOUD,
1050                ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail)
1051        );
1052        ODM_RT_TRACE(
1053                pDM_Odm,
1054                ODM_COMP_FA_CNT,
1055                ODM_DBG_LOUD,
1056                ("Total False Alarm =%d\n",     FalseAlmCnt->Cnt_all)
1057        );
1058}
1059
1060
1061void odm_FAThresholdCheck(
1062        void *pDM_VOID,
1063        bool bDFSBand,
1064        bool bPerformance,
1065        u32 RxTp,
1066        u32 TxTp,
1067        u32 *dm_FA_thres
1068)
1069{
1070        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
1071
1072        if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) {
1073                /*  For NIC */
1074                dm_FA_thres[0] = DM_DIG_FA_TH0;
1075                dm_FA_thres[1] = DM_DIG_FA_TH1;
1076                dm_FA_thres[2] = DM_DIG_FA_TH2;
1077        } else {
1078                dm_FA_thres[0] = 2000;
1079                dm_FA_thres[1] = 4000;
1080                dm_FA_thres[2] = 5000;
1081        }
1082        return;
1083}
1084
1085u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI)
1086{
1087        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
1088        pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
1089        Pfalse_ALARM_STATISTICS pFalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
1090        u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min;
1091
1092        if (pFalseAlmCnt->Cnt_all > 10000) {
1093                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case.\n"));
1094
1095                if (pDM_DigTable->LargeFAHit != 3)
1096                        pDM_DigTable->LargeFAHit++;
1097
1098                /* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */
1099                if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
1100                        pDM_DigTable->ForbiddenIGI = CurrentIGI;
1101                        /* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */
1102                        pDM_DigTable->LargeFAHit = 1;
1103                }
1104
1105                if (pDM_DigTable->LargeFAHit >= 3) {
1106                        if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max)
1107                                rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
1108                        else
1109                                rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
1110                        pDM_DigTable->Recover_cnt = 1800;
1111                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case: Recover_cnt = %d\n", pDM_DigTable->Recover_cnt));
1112                }
1113        } else {
1114                if (pDM_DigTable->Recover_cnt != 0) {
1115                        pDM_DigTable->Recover_cnt--;
1116                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Recover_cnt = %d\n", pDM_DigTable->Recover_cnt));
1117                } else {
1118                        if (pDM_DigTable->LargeFAHit < 3) {
1119                                if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */
1120                                        pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
1121                                        rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
1122                                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: At Lower Bound\n"));
1123                                } else {
1124                                        pDM_DigTable->ForbiddenIGI -= 2;
1125                                        rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
1126                                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Approach Lower Bound\n"));
1127                                }
1128                        } else
1129                                pDM_DigTable->LargeFAHit = 0;
1130                }
1131        }
1132
1133        return rx_gain_range_min;
1134
1135}
1136
1137/* 3 ============================================================ */
1138/* 3 CCK Packet Detect Threshold */
1139/* 3 ============================================================ */
1140
1141void odm_CCKPacketDetectionThresh(void *pDM_VOID)
1142{
1143        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
1144        Pfalse_ALARM_STATISTICS FalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
1145        u8 CurCCK_CCAThres;
1146
1147
1148        if (
1149                !(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) ||
1150                !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)
1151        ) {
1152                ODM_RT_TRACE(
1153                        pDM_Odm,
1154                        ODM_COMP_CCK_PD,
1155                        ODM_DBG_LOUD,
1156                        ("odm_CCKPacketDetectionThresh()  return ==========\n")
1157                );
1158                return;
1159        }
1160
1161        if (pDM_Odm->ExtLNA)
1162                return;
1163
1164        ODM_RT_TRACE(
1165                pDM_Odm,
1166                ODM_COMP_CCK_PD,
1167                ODM_DBG_LOUD,
1168                ("odm_CCKPacketDetectionThresh()  ==========>\n")
1169        );
1170
1171        if (pDM_Odm->bLinked) {
1172                if (pDM_Odm->RSSI_Min > 25)
1173                        CurCCK_CCAThres = 0xcd;
1174                else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10))
1175                        CurCCK_CCAThres = 0x83;
1176                else {
1177                        if (FalseAlmCnt->Cnt_Cck_fail > 1000)
1178                                CurCCK_CCAThres = 0x83;
1179                        else
1180                                CurCCK_CCAThres = 0x40;
1181                }
1182        } else {
1183                if (FalseAlmCnt->Cnt_Cck_fail > 1000)
1184                        CurCCK_CCAThres = 0x83;
1185                else
1186                        CurCCK_CCAThres = 0x40;
1187        }
1188
1189        ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres);
1190
1191        ODM_RT_TRACE(
1192                pDM_Odm,
1193                ODM_COMP_CCK_PD,
1194                ODM_DBG_LOUD,
1195                (
1196                        "odm_CCKPacketDetectionThresh()  CurCCK_CCAThres = 0x%x\n",
1197                        CurCCK_CCAThres
1198                )
1199        );
1200}
1201
1202void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres)
1203{
1204        PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
1205        pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
1206
1207        /* modify by Guo.Mingzhi 2012-01-03 */
1208        if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
1209                rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres);
1210
1211        pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
1212        pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
1213}
1214