158391efdSNathan Chancellor // SPDX-License-Identifier: GPL-2.0 2554c0a3aSHans de Goede /****************************************************************************** 3554c0a3aSHans de Goede * 4554c0a3aSHans de Goede * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 5554c0a3aSHans de Goede * 6554c0a3aSHans de Goede ******************************************************************************/ 7554c0a3aSHans de Goede 8554c0a3aSHans de Goede #include "odm_precomp.h" 9554c0a3aSHans de Goede 10554c0a3aSHans de Goede void odm_NHMCounterStatisticsInit(void *pDM_VOID) 11554c0a3aSHans de Goede { 12f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 13554c0a3aSHans de Goede 14554c0a3aSHans de Goede /* PHY parameters initialize for n series */ 15554c0a3aSHans de Goede rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x2710); /* 0x894[31:16]= 0x2710 Time duration for NHM unit: 4us, 0x2710 =40ms */ 16554c0a3aSHans de Goede /* rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x4e20); 0x894[31:16]= 0x4e20 Time duration for NHM unit: 4us, 0x4e20 =80ms */ 17554c0a3aSHans de Goede rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff); /* 0x890[31:16]= 0xffff th_9, th_10 */ 18554c0a3aSHans de Goede /* rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff5c); 0x898 = 0xffffff5c th_3, th_2, th_1, th_0 */ 19554c0a3aSHans de Goede rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff52); /* 0x898 = 0xffffff52 th_3, th_2, th_1, th_0 */ 20554c0a3aSHans de Goede rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff); /* 0x89c = 0xffffffff th_7, th_6, th_5, th_4 */ 21554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff); /* 0xe28[7:0]= 0xff th_8 */ 22554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x7); /* 0x890[9:8]=3 enable CCX */ 23554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1); /* 0xc0c[7]= 1 max power among all RX ants */ 24554c0a3aSHans de Goede } 25554c0a3aSHans de Goede 26554c0a3aSHans de Goede void odm_NHMCounterStatistics(void *pDM_VOID) 27554c0a3aSHans de Goede { 28f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 29554c0a3aSHans de Goede 30554c0a3aSHans de Goede /* Get NHM report */ 31554c0a3aSHans de Goede odm_GetNHMCounterStatistics(pDM_Odm); 32554c0a3aSHans de Goede 33554c0a3aSHans de Goede /* Reset NHM counter */ 34554c0a3aSHans de Goede odm_NHMCounterStatisticsReset(pDM_Odm); 35554c0a3aSHans de Goede } 36554c0a3aSHans de Goede 37554c0a3aSHans de Goede void odm_GetNHMCounterStatistics(void *pDM_VOID) 38554c0a3aSHans de Goede { 39f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 40554c0a3aSHans de Goede u32 value32 = 0; 41554c0a3aSHans de Goede 42554c0a3aSHans de Goede value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_NHM_CNT_11N, bMaskDWord); 43554c0a3aSHans de Goede 44554c0a3aSHans de Goede pDM_Odm->NHM_cnt_0 = (u8)(value32 & bMaskByte0); 45554c0a3aSHans de Goede } 46554c0a3aSHans de Goede 47554c0a3aSHans de Goede void odm_NHMCounterStatisticsReset(void *pDM_VOID) 48554c0a3aSHans de Goede { 49f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 50554c0a3aSHans de Goede 51554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 0); 52554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 1); 53554c0a3aSHans de Goede } 54554c0a3aSHans de Goede 55554c0a3aSHans de Goede void odm_NHMBBInit(void *pDM_VOID) 56554c0a3aSHans de Goede { 57f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 58554c0a3aSHans de Goede 59554c0a3aSHans de Goede pDM_Odm->adaptivity_flag = 0; 60554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 3; 61554c0a3aSHans de Goede pDM_Odm->NHMLastTxOkcnt = 0; 62554c0a3aSHans de Goede pDM_Odm->NHMLastRxOkcnt = 0; 63554c0a3aSHans de Goede pDM_Odm->NHMCurTxOkcnt = 0; 64554c0a3aSHans de Goede pDM_Odm->NHMCurRxOkcnt = 0; 65554c0a3aSHans de Goede } 66554c0a3aSHans de Goede 67554c0a3aSHans de Goede /* */ 68554c0a3aSHans de Goede void odm_NHMBB(void *pDM_VOID) 69554c0a3aSHans de Goede { 70f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 71554c0a3aSHans de Goede /* u8 test_status; */ 72db07a1caSMarco Cesati /* struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; */ 73554c0a3aSHans de Goede 74554c0a3aSHans de Goede pDM_Odm->NHMCurTxOkcnt = 75554c0a3aSHans de Goede *(pDM_Odm->pNumTxBytesUnicast)-pDM_Odm->NHMLastTxOkcnt; 76554c0a3aSHans de Goede pDM_Odm->NHMCurRxOkcnt = 77554c0a3aSHans de Goede *(pDM_Odm->pNumRxBytesUnicast)-pDM_Odm->NHMLastRxOkcnt; 78554c0a3aSHans de Goede pDM_Odm->NHMLastTxOkcnt = 79554c0a3aSHans de Goede *(pDM_Odm->pNumTxBytesUnicast); 80554c0a3aSHans de Goede pDM_Odm->NHMLastRxOkcnt = 81554c0a3aSHans de Goede *(pDM_Odm->pNumRxBytesUnicast); 82554c0a3aSHans de Goede 83554c0a3aSHans de Goede 84554c0a3aSHans de Goede if ((pDM_Odm->NHMCurTxOkcnt) + 1 > (u64)(pDM_Odm->NHMCurRxOkcnt<<2) + 1) { /* Tx > 4*Rx possible for adaptivity test */ 85554c0a3aSHans de Goede if (pDM_Odm->NHM_cnt_0 >= 190 || pDM_Odm->adaptivity_flag == true) { 86554c0a3aSHans de Goede /* Enable EDCCA since it is possible running Adaptivity testing */ 87554c0a3aSHans de Goede /* test_status = 1; */ 88554c0a3aSHans de Goede pDM_Odm->adaptivity_flag = true; 89554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 0; 90554c0a3aSHans de Goede } else { 91554c0a3aSHans de Goede if (pDM_Odm->tolerance_cnt < 3) 92554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1; 93554c0a3aSHans de Goede else 94554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 4; 95554c0a3aSHans de Goede /* test_status = 5; */ 96554c0a3aSHans de Goede if (pDM_Odm->tolerance_cnt > 3) { 97554c0a3aSHans de Goede /* test_status = 3; */ 98554c0a3aSHans de Goede pDM_Odm->adaptivity_flag = false; 99554c0a3aSHans de Goede } 100554c0a3aSHans de Goede } 101554c0a3aSHans de Goede } else { /* TX<RX */ 102554c0a3aSHans de Goede if (pDM_Odm->adaptivity_flag == true && pDM_Odm->NHM_cnt_0 <= 200) { 103554c0a3aSHans de Goede /* test_status = 2; */ 104554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 0; 105554c0a3aSHans de Goede } else { 106554c0a3aSHans de Goede if (pDM_Odm->tolerance_cnt < 3) 107554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1; 108554c0a3aSHans de Goede else 109554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 4; 110554c0a3aSHans de Goede /* test_status = 5; */ 111554c0a3aSHans de Goede if (pDM_Odm->tolerance_cnt > 3) { 112554c0a3aSHans de Goede /* test_status = 4; */ 113554c0a3aSHans de Goede pDM_Odm->adaptivity_flag = false; 114554c0a3aSHans de Goede } 115554c0a3aSHans de Goede } 116554c0a3aSHans de Goede } 117554c0a3aSHans de Goede } 118554c0a3aSHans de Goede 119554c0a3aSHans de Goede void odm_SearchPwdBLowerBound(void *pDM_VOID, u8 IGI_target) 120554c0a3aSHans de Goede { 121f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 122554c0a3aSHans de Goede u32 value32 = 0; 123554c0a3aSHans de Goede u8 cnt, IGI; 124554c0a3aSHans de Goede bool bAdjust = true; 125554c0a3aSHans de Goede s8 TH_L2H_dmc, TH_H2L_dmc; 126554c0a3aSHans de Goede s8 Diff; 127554c0a3aSHans de Goede 128554c0a3aSHans de Goede IGI = 0x50; /* find H2L, L2H lower bound */ 129554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, IGI); 130554c0a3aSHans de Goede 131554c0a3aSHans de Goede 132554c0a3aSHans de Goede Diff = IGI_target-(s8)IGI; 133554c0a3aSHans de Goede TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff; 134554c0a3aSHans de Goede if (TH_L2H_dmc > 10) 135554c0a3aSHans de Goede TH_L2H_dmc = 10; 136554c0a3aSHans de Goede TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; 137554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc); 138554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc); 139554c0a3aSHans de Goede 140554c0a3aSHans de Goede mdelay(5); 141554c0a3aSHans de Goede 142554c0a3aSHans de Goede while (bAdjust) { 143554c0a3aSHans de Goede for (cnt = 0; cnt < 20; cnt++) { 144554c0a3aSHans de Goede value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_RPT_11N, bMaskDWord); 145554c0a3aSHans de Goede 146554c0a3aSHans de Goede if (value32 & BIT30) 147554c0a3aSHans de Goede pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1; 148554c0a3aSHans de Goede else if (value32 & BIT29) 149554c0a3aSHans de Goede pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1; 150554c0a3aSHans de Goede else 151554c0a3aSHans de Goede pDM_Odm->txEdcca0 = pDM_Odm->txEdcca0 + 1; 152554c0a3aSHans de Goede } 153554c0a3aSHans de Goede 154554c0a3aSHans de Goede if (pDM_Odm->txEdcca1 > 5) { 155554c0a3aSHans de Goede IGI = IGI-1; 156554c0a3aSHans de Goede TH_L2H_dmc = TH_L2H_dmc + 1; 157554c0a3aSHans de Goede if (TH_L2H_dmc > 10) 158554c0a3aSHans de Goede TH_L2H_dmc = 10; 159554c0a3aSHans de Goede TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; 160554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc); 161554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc); 162554c0a3aSHans de Goede 163554c0a3aSHans de Goede pDM_Odm->TxHangFlg = true; 164554c0a3aSHans de Goede pDM_Odm->txEdcca1 = 0; 165554c0a3aSHans de Goede pDM_Odm->txEdcca0 = 0; 166554c0a3aSHans de Goede 167554c0a3aSHans de Goede if (TH_L2H_dmc == 10) { 168554c0a3aSHans de Goede bAdjust = false; 169554c0a3aSHans de Goede pDM_Odm->TxHangFlg = false; 170554c0a3aSHans de Goede pDM_Odm->txEdcca1 = 0; 171554c0a3aSHans de Goede pDM_Odm->txEdcca0 = 0; 172554c0a3aSHans de Goede pDM_Odm->H2L_lb = TH_H2L_dmc; 173554c0a3aSHans de Goede pDM_Odm->L2H_lb = TH_L2H_dmc; 174554c0a3aSHans de Goede pDM_Odm->Adaptivity_IGI_upper = IGI; 175554c0a3aSHans de Goede } 176554c0a3aSHans de Goede } else { 177554c0a3aSHans de Goede bAdjust = false; 178554c0a3aSHans de Goede pDM_Odm->TxHangFlg = false; 179554c0a3aSHans de Goede pDM_Odm->txEdcca1 = 0; 180554c0a3aSHans de Goede pDM_Odm->txEdcca0 = 0; 181554c0a3aSHans de Goede pDM_Odm->H2L_lb = TH_H2L_dmc; 182554c0a3aSHans de Goede pDM_Odm->L2H_lb = TH_L2H_dmc; 183554c0a3aSHans de Goede pDM_Odm->Adaptivity_IGI_upper = IGI; 184554c0a3aSHans de Goede } 185554c0a3aSHans de Goede } 186554c0a3aSHans de Goede } 187554c0a3aSHans de Goede 188554c0a3aSHans de Goede void odm_AdaptivityInit(void *pDM_VOID) 189554c0a3aSHans de Goede { 190f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 191554c0a3aSHans de Goede 192554c0a3aSHans de Goede if (pDM_Odm->Carrier_Sense_enable == false) 193554c0a3aSHans de Goede pDM_Odm->TH_L2H_ini = 0xf7; /* -7 */ 194554c0a3aSHans de Goede else 195554c0a3aSHans de Goede pDM_Odm->TH_L2H_ini = 0xa; 196554c0a3aSHans de Goede 197554c0a3aSHans de Goede pDM_Odm->AdapEn_RSSI = 20; 198554c0a3aSHans de Goede pDM_Odm->TH_EDCCA_HL_diff = 7; 199554c0a3aSHans de Goede 200554c0a3aSHans de Goede pDM_Odm->IGI_Base = 0x32; 201554c0a3aSHans de Goede pDM_Odm->IGI_target = 0x1c; 202554c0a3aSHans de Goede pDM_Odm->ForceEDCCA = 0; 203554c0a3aSHans de Goede pDM_Odm->NHM_disable = false; 204554c0a3aSHans de Goede pDM_Odm->TxHangFlg = true; 205554c0a3aSHans de Goede pDM_Odm->txEdcca0 = 0; 206554c0a3aSHans de Goede pDM_Odm->txEdcca1 = 0; 207554c0a3aSHans de Goede pDM_Odm->H2L_lb = 0; 208554c0a3aSHans de Goede pDM_Odm->L2H_lb = 0; 209554c0a3aSHans de Goede pDM_Odm->Adaptivity_IGI_upper = 0; 210554c0a3aSHans de Goede odm_NHMBBInit(pDM_Odm); 211554c0a3aSHans de Goede 212554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, REG_RD_CTRL, BIT11, 1); /* stop counting if EDCCA is asserted */ 213554c0a3aSHans de Goede } 214554c0a3aSHans de Goede 215554c0a3aSHans de Goede 216554c0a3aSHans de Goede void odm_Adaptivity(void *pDM_VOID, u8 IGI) 217554c0a3aSHans de Goede { 218f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 219554c0a3aSHans de Goede s8 TH_L2H_dmc, TH_H2L_dmc; 220554c0a3aSHans de Goede s8 Diff, IGI_target; 221554c0a3aSHans de Goede bool EDCCA_State = false; 222554c0a3aSHans de Goede 223554c0a3aSHans de Goede if (!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) { 224554c0a3aSHans de Goede return; 225554c0a3aSHans de Goede } 226554c0a3aSHans de Goede 227554c0a3aSHans de Goede if (*pDM_Odm->pBandWidth == ODM_BW20M) /* CHANNEL_WIDTH_20 */ 228554c0a3aSHans de Goede IGI_target = pDM_Odm->IGI_Base; 229554c0a3aSHans de Goede else if (*pDM_Odm->pBandWidth == ODM_BW40M) 230554c0a3aSHans de Goede IGI_target = pDM_Odm->IGI_Base + 2; 231554c0a3aSHans de Goede else 232554c0a3aSHans de Goede IGI_target = pDM_Odm->IGI_Base; 233554c0a3aSHans de Goede pDM_Odm->IGI_target = (u8) IGI_target; 234554c0a3aSHans de Goede 235554c0a3aSHans de Goede /* Search pwdB lower bound */ 236554c0a3aSHans de Goede if (pDM_Odm->TxHangFlg == true) { 237554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208); 238554c0a3aSHans de Goede odm_SearchPwdBLowerBound(pDM_Odm, pDM_Odm->IGI_target); 239554c0a3aSHans de Goede } 240554c0a3aSHans de Goede 241554c0a3aSHans de Goede if ((!pDM_Odm->bLinked) || (*pDM_Odm->pChannel > 149)) { /* Band4 doesn't need adaptivity */ 242554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, 0x7f); 243554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, 0x7f); 244554c0a3aSHans de Goede return; 245554c0a3aSHans de Goede } 246554c0a3aSHans de Goede 247554c0a3aSHans de Goede if (!pDM_Odm->ForceEDCCA) { 248554c0a3aSHans de Goede if (pDM_Odm->RSSI_Min > pDM_Odm->AdapEn_RSSI) 2497bb0dffdSsimran singhal EDCCA_State = true; 250554c0a3aSHans de Goede else if (pDM_Odm->RSSI_Min < (pDM_Odm->AdapEn_RSSI - 5)) 2517bb0dffdSsimran singhal EDCCA_State = false; 252554c0a3aSHans de Goede } else 2537bb0dffdSsimran singhal EDCCA_State = true; 254554c0a3aSHans de Goede 255554c0a3aSHans de Goede if ( 256554c0a3aSHans de Goede pDM_Odm->bLinked && 257554c0a3aSHans de Goede pDM_Odm->Carrier_Sense_enable == false && 258554c0a3aSHans de Goede pDM_Odm->NHM_disable == false && 259554c0a3aSHans de Goede pDM_Odm->TxHangFlg == false 260554c0a3aSHans de Goede ) 261554c0a3aSHans de Goede odm_NHMBB(pDM_Odm); 262554c0a3aSHans de Goede 2637bb0dffdSsimran singhal if (EDCCA_State) { 264554c0a3aSHans de Goede Diff = IGI_target-(s8)IGI; 265554c0a3aSHans de Goede TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff; 266554c0a3aSHans de Goede if (TH_L2H_dmc > 10) 267554c0a3aSHans de Goede TH_L2H_dmc = 10; 268554c0a3aSHans de Goede 269554c0a3aSHans de Goede TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; 270554c0a3aSHans de Goede 271554c0a3aSHans de Goede /* replace lower bound to prevent EDCCA always equal */ 272554c0a3aSHans de Goede if (TH_H2L_dmc < pDM_Odm->H2L_lb) 273554c0a3aSHans de Goede TH_H2L_dmc = pDM_Odm->H2L_lb; 274554c0a3aSHans de Goede if (TH_L2H_dmc < pDM_Odm->L2H_lb) 275554c0a3aSHans de Goede TH_L2H_dmc = pDM_Odm->L2H_lb; 276554c0a3aSHans de Goede } else { 277554c0a3aSHans de Goede TH_L2H_dmc = 0x7f; 278554c0a3aSHans de Goede TH_H2L_dmc = 0x7f; 279554c0a3aSHans de Goede } 280554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc); 281554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc); 282554c0a3aSHans de Goede } 283554c0a3aSHans de Goede 284554c0a3aSHans de Goede void ODM_Write_DIG(void *pDM_VOID, u8 CurrentIGI) 285554c0a3aSHans de Goede { 286f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 28786d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 288554c0a3aSHans de Goede 289554c0a3aSHans de Goede if (pDM_DigTable->bStopDIG) { 290554c0a3aSHans de Goede return; 291554c0a3aSHans de Goede } 292554c0a3aSHans de Goede 293554c0a3aSHans de Goede if (pDM_DigTable->CurIGValue != CurrentIGI) { 294554c0a3aSHans de Goede /* 1 Check initial gain by upper bound */ 295554c0a3aSHans de Goede if (!pDM_DigTable->bPSDInProgress) { 296554c0a3aSHans de Goede if (CurrentIGI > pDM_DigTable->rx_gain_range_max) { 297554c0a3aSHans de Goede CurrentIGI = pDM_DigTable->rx_gain_range_max; 298554c0a3aSHans de Goede } 299554c0a3aSHans de Goede 300554c0a3aSHans de Goede } 301554c0a3aSHans de Goede 302554c0a3aSHans de Goede /* 1 Set IGI value */ 303554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); 304554c0a3aSHans de Goede 305554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); 306554c0a3aSHans de Goede 307554c0a3aSHans de Goede pDM_DigTable->CurIGValue = CurrentIGI; 308554c0a3aSHans de Goede } 309554c0a3aSHans de Goede 310554c0a3aSHans de Goede } 311554c0a3aSHans de Goede 312554c0a3aSHans de Goede void odm_PauseDIG( 313554c0a3aSHans de Goede void *pDM_VOID, 314d7c2b41fSMarco Cesati enum ODM_Pause_DIG_TYPE PauseType, 315554c0a3aSHans de Goede u8 IGIValue 316554c0a3aSHans de Goede ) 317554c0a3aSHans de Goede { 318f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 31986d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 320318dda31SJustin Vreeland static bool bPaused; 321554c0a3aSHans de Goede 322554c0a3aSHans de Goede if ( 323554c0a3aSHans de Goede (pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY) && 324554c0a3aSHans de Goede pDM_Odm->TxHangFlg == true 325554c0a3aSHans de Goede ) { 326554c0a3aSHans de Goede return; 327554c0a3aSHans de Goede } 328554c0a3aSHans de Goede 329554c0a3aSHans de Goede if ( 330554c0a3aSHans de Goede !bPaused && (!(pDM_Odm->SupportAbility & ODM_BB_DIG) || 331554c0a3aSHans de Goede !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) 332554c0a3aSHans de Goede ){ 333554c0a3aSHans de Goede return; 334554c0a3aSHans de Goede } 335554c0a3aSHans de Goede 336554c0a3aSHans de Goede switch (PauseType) { 337554c0a3aSHans de Goede /* 1 Pause DIG */ 338554c0a3aSHans de Goede case ODM_PAUSE_DIG: 339554c0a3aSHans de Goede /* 2 Disable DIG */ 340554c0a3aSHans de Goede ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility & (~ODM_BB_DIG)); 341554c0a3aSHans de Goede 342554c0a3aSHans de Goede /* 2 Backup IGI value */ 343554c0a3aSHans de Goede if (!bPaused) { 344554c0a3aSHans de Goede pDM_DigTable->IGIBackup = pDM_DigTable->CurIGValue; 345554c0a3aSHans de Goede bPaused = true; 346554c0a3aSHans de Goede } 347554c0a3aSHans de Goede 348554c0a3aSHans de Goede /* 2 Write new IGI value */ 349554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, IGIValue); 350554c0a3aSHans de Goede break; 351554c0a3aSHans de Goede 352554c0a3aSHans de Goede /* 1 Resume DIG */ 353554c0a3aSHans de Goede case ODM_RESUME_DIG: 354554c0a3aSHans de Goede if (bPaused) { 355554c0a3aSHans de Goede /* 2 Write backup IGI value */ 356554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, pDM_DigTable->IGIBackup); 357554c0a3aSHans de Goede bPaused = false; 358554c0a3aSHans de Goede 359554c0a3aSHans de Goede /* 2 Enable DIG */ 360554c0a3aSHans de Goede ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_DIG); 361554c0a3aSHans de Goede } 362554c0a3aSHans de Goede break; 363554c0a3aSHans de Goede 364554c0a3aSHans de Goede default: 365554c0a3aSHans de Goede break; 366554c0a3aSHans de Goede } 367554c0a3aSHans de Goede } 368554c0a3aSHans de Goede 369554c0a3aSHans de Goede bool odm_DigAbort(void *pDM_VOID) 370554c0a3aSHans de Goede { 371f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 372554c0a3aSHans de Goede 373554c0a3aSHans de Goede /* SupportAbility */ 374554c0a3aSHans de Goede if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) { 375554c0a3aSHans de Goede return true; 376554c0a3aSHans de Goede } 377554c0a3aSHans de Goede 378554c0a3aSHans de Goede /* SupportAbility */ 379554c0a3aSHans de Goede if (!(pDM_Odm->SupportAbility & ODM_BB_DIG)) { 380554c0a3aSHans de Goede return true; 381554c0a3aSHans de Goede } 382554c0a3aSHans de Goede 383554c0a3aSHans de Goede /* ScanInProcess */ 384554c0a3aSHans de Goede if (*(pDM_Odm->pbScanInProcess)) { 385554c0a3aSHans de Goede return true; 386554c0a3aSHans de Goede } 387554c0a3aSHans de Goede 388554c0a3aSHans de Goede /* add by Neil Chen to avoid PSD is processing */ 389554c0a3aSHans de Goede if (pDM_Odm->bDMInitialGainEnable == false) { 390554c0a3aSHans de Goede return true; 391554c0a3aSHans de Goede } 392554c0a3aSHans de Goede 393554c0a3aSHans de Goede return false; 394554c0a3aSHans de Goede } 395554c0a3aSHans de Goede 396554c0a3aSHans de Goede void odm_DIGInit(void *pDM_VOID) 397554c0a3aSHans de Goede { 398f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 39986d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 400554c0a3aSHans de Goede 401554c0a3aSHans de Goede pDM_DigTable->bStopDIG = false; 402554c0a3aSHans de Goede pDM_DigTable->bPSDInProgress = false; 403554c0a3aSHans de Goede pDM_DigTable->CurIGValue = (u8) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm)); 404554c0a3aSHans de Goede pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; 405554c0a3aSHans de Goede pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; 406554c0a3aSHans de Goede pDM_DigTable->FALowThresh = DMfalseALARM_THRESH_LOW; 407554c0a3aSHans de Goede pDM_DigTable->FAHighThresh = DMfalseALARM_THRESH_HIGH; 408554c0a3aSHans de Goede pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; 409554c0a3aSHans de Goede pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; 410554c0a3aSHans de Goede pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; 411554c0a3aSHans de Goede pDM_DigTable->PreCCK_CCAThres = 0xFF; 412554c0a3aSHans de Goede pDM_DigTable->CurCCK_CCAThres = 0x83; 413554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC; 414554c0a3aSHans de Goede pDM_DigTable->LargeFAHit = 0; 415554c0a3aSHans de Goede pDM_DigTable->Recover_cnt = 0; 416554c0a3aSHans de Goede pDM_DigTable->bMediaConnect_0 = false; 417554c0a3aSHans de Goede pDM_DigTable->bMediaConnect_1 = false; 418554c0a3aSHans de Goede 419554c0a3aSHans de Goede /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */ 420554c0a3aSHans de Goede pDM_Odm->bDMInitialGainEnable = true; 421554c0a3aSHans de Goede 422554c0a3aSHans de Goede pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC; 423554c0a3aSHans de Goede pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC; 424554c0a3aSHans de Goede 425554c0a3aSHans de Goede /* To Initi BT30 IGI */ 426554c0a3aSHans de Goede pDM_DigTable->BT30_CurIGI = 0x32; 427554c0a3aSHans de Goede 428554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; 429554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; 430554c0a3aSHans de Goede 431554c0a3aSHans de Goede } 432554c0a3aSHans de Goede 433554c0a3aSHans de Goede 434554c0a3aSHans de Goede void odm_DIG(void *pDM_VOID) 435554c0a3aSHans de Goede { 436f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 437554c0a3aSHans de Goede 438554c0a3aSHans de Goede /* Common parameters */ 43986d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 440d7c2b41fSMarco Cesati struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; 441554c0a3aSHans de Goede bool FirstConnect, FirstDisConnect; 442554c0a3aSHans de Goede u8 DIG_MaxOfMin, DIG_Dynamic_MIN; 443554c0a3aSHans de Goede u8 dm_dig_max, dm_dig_min; 444554c0a3aSHans de Goede u8 CurrentIGI = pDM_DigTable->CurIGValue; 445554c0a3aSHans de Goede u8 offset; 446554c0a3aSHans de Goede u32 dm_FA_thres[3]; 447554c0a3aSHans de Goede u8 Adap_IGI_Upper = 0; 448554c0a3aSHans de Goede u32 TxTp = 0, RxTp = 0; 449554c0a3aSHans de Goede bool bDFSBand = false; 450554c0a3aSHans de Goede bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false; 451554c0a3aSHans de Goede 452941add8eSPuranjay Mohan if (odm_DigAbort(pDM_Odm)) 453554c0a3aSHans de Goede return; 454554c0a3aSHans de Goede 455554c0a3aSHans de Goede if (pDM_Odm->adaptivity_flag == true) 456554c0a3aSHans de Goede Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper; 457554c0a3aSHans de Goede 458554c0a3aSHans de Goede 459554c0a3aSHans de Goede /* 1 Update status */ 460554c0a3aSHans de Goede DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; 461554c0a3aSHans de Goede FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == false); 462554c0a3aSHans de Goede FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == true); 463554c0a3aSHans de Goede 464554c0a3aSHans de Goede /* 1 Boundary Decision */ 465554c0a3aSHans de Goede /* 2 For WIN\CE */ 466554c0a3aSHans de Goede dm_dig_max = 0x5A; 467554c0a3aSHans de Goede dm_dig_min = DM_DIG_MIN_NIC; 468554c0a3aSHans de Goede DIG_MaxOfMin = DM_DIG_MAX_AP; 469554c0a3aSHans de Goede 470554c0a3aSHans de Goede /* 1 Adjust boundary by RSSI */ 471554c0a3aSHans de Goede if (pDM_Odm->bLinked && bPerformance) { 472554c0a3aSHans de Goede /* 2 Modify DIG upper bound */ 473554c0a3aSHans de Goede /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */ 474554c0a3aSHans de Goede if (pDM_Odm->bBtLimitedDig == 1) { 475554c0a3aSHans de Goede offset = 10; 476554c0a3aSHans de Goede } else 477554c0a3aSHans de Goede offset = 15; 478554c0a3aSHans de Goede 479554c0a3aSHans de Goede if ((pDM_Odm->RSSI_Min + offset) > dm_dig_max) 480554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = dm_dig_max; 481554c0a3aSHans de Goede else if ((pDM_Odm->RSSI_Min + offset) < dm_dig_min) 482554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = dm_dig_min; 483554c0a3aSHans de Goede else 484554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset; 485554c0a3aSHans de Goede 486554c0a3aSHans de Goede /* 2 Modify DIG lower bound */ 487554c0a3aSHans de Goede /* if (pDM_Odm->bOneEntryOnly) */ 488554c0a3aSHans de Goede { 489554c0a3aSHans de Goede if (pDM_Odm->RSSI_Min < dm_dig_min) 490554c0a3aSHans de Goede DIG_Dynamic_MIN = dm_dig_min; 491554c0a3aSHans de Goede else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) 492554c0a3aSHans de Goede DIG_Dynamic_MIN = DIG_MaxOfMin; 493554c0a3aSHans de Goede else 494554c0a3aSHans de Goede DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; 495554c0a3aSHans de Goede } 496554c0a3aSHans de Goede } else { 497554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = dm_dig_max; 498554c0a3aSHans de Goede DIG_Dynamic_MIN = dm_dig_min; 499554c0a3aSHans de Goede } 500554c0a3aSHans de Goede 501554c0a3aSHans de Goede /* 1 Force Lower Bound for AntDiv */ 502554c0a3aSHans de Goede if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) { 503554c0a3aSHans de Goede if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) { 504554c0a3aSHans de Goede if ( 505554c0a3aSHans de Goede pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV || 506554c0a3aSHans de Goede pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV || 507554c0a3aSHans de Goede pDM_Odm->AntDivType == S0S1_SW_ANTDIV 508554c0a3aSHans de Goede ) { 509554c0a3aSHans de Goede if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin) 510554c0a3aSHans de Goede DIG_Dynamic_MIN = DIG_MaxOfMin; 511554c0a3aSHans de Goede else 512554c0a3aSHans de Goede DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max; 513554c0a3aSHans de Goede } 514554c0a3aSHans de Goede } 515554c0a3aSHans de Goede } 516554c0a3aSHans de Goede 517554c0a3aSHans de Goede /* 1 Modify DIG lower bound, deal with abnormal case */ 518554c0a3aSHans de Goede /* 2 Abnormal false alarm case */ 519554c0a3aSHans de Goede if (FirstDisConnect) { 520554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; 521554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; 522554c0a3aSHans de Goede } else 523554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = 524554c0a3aSHans de Goede odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI); 525554c0a3aSHans de Goede 526554c0a3aSHans de Goede if (pDM_Odm->bLinked && !FirstConnect) { 527554c0a3aSHans de Goede if ( 528554c0a3aSHans de Goede (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) && 529554c0a3aSHans de Goede pDM_Odm->bsta_state 530554c0a3aSHans de Goede ) { 531554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = dm_dig_min; 532554c0a3aSHans de Goede } 533554c0a3aSHans de Goede } 534554c0a3aSHans de Goede 535554c0a3aSHans de Goede /* 2 Abnormal lower bound case */ 536554c0a3aSHans de Goede if (pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) { 537554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max; 538554c0a3aSHans de Goede } 539554c0a3aSHans de Goede 540554c0a3aSHans de Goede 541554c0a3aSHans de Goede /* 1 False alarm threshold decision */ 542554c0a3aSHans de Goede odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres); 543554c0a3aSHans de Goede 544554c0a3aSHans de Goede /* 1 Adjust initial gain by false alarm */ 545554c0a3aSHans de Goede if (pDM_Odm->bLinked && bPerformance) { 546554c0a3aSHans de Goede 547*98f668b3SSaurav Girepunje if (bFirstTpTarget || FirstConnect) { 548554c0a3aSHans de Goede pDM_DigTable->LargeFAHit = 0; 549554c0a3aSHans de Goede 550554c0a3aSHans de Goede if (pDM_Odm->RSSI_Min < DIG_MaxOfMin) { 551554c0a3aSHans de Goede if (CurrentIGI < pDM_Odm->RSSI_Min) 552554c0a3aSHans de Goede CurrentIGI = pDM_Odm->RSSI_Min; 553554c0a3aSHans de Goede } else { 554554c0a3aSHans de Goede if (CurrentIGI < DIG_MaxOfMin) 555554c0a3aSHans de Goede CurrentIGI = DIG_MaxOfMin; 556554c0a3aSHans de Goede } 557554c0a3aSHans de Goede 558554c0a3aSHans de Goede } else { 559554c0a3aSHans de Goede if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2]) 560554c0a3aSHans de Goede CurrentIGI = CurrentIGI + 4; 561554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1]) 562554c0a3aSHans de Goede CurrentIGI = CurrentIGI + 2; 563554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0]) 564554c0a3aSHans de Goede CurrentIGI = CurrentIGI - 2; 565554c0a3aSHans de Goede 566554c0a3aSHans de Goede if ( 567554c0a3aSHans de Goede (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) && 568554c0a3aSHans de Goede (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) && 569554c0a3aSHans de Goede (pDM_Odm->bsta_state) 570554c0a3aSHans de Goede ) { 571554c0a3aSHans de Goede CurrentIGI = pDM_DigTable->rx_gain_range_min; 572554c0a3aSHans de Goede } 573554c0a3aSHans de Goede } 574554c0a3aSHans de Goede } else { 575554c0a3aSHans de Goede 576554c0a3aSHans de Goede if (FirstDisConnect || bFirstCoverage) { 577554c0a3aSHans de Goede CurrentIGI = dm_dig_min; 578554c0a3aSHans de Goede } else { 579554c0a3aSHans de Goede if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2]) 580554c0a3aSHans de Goede CurrentIGI = CurrentIGI + 4; 581554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1]) 582554c0a3aSHans de Goede CurrentIGI = CurrentIGI + 2; 583554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0]) 584554c0a3aSHans de Goede CurrentIGI = CurrentIGI - 2; 585554c0a3aSHans de Goede } 586554c0a3aSHans de Goede } 587554c0a3aSHans de Goede 588554c0a3aSHans de Goede /* 1 Check initial gain by upper/lower bound */ 589554c0a3aSHans de Goede if (CurrentIGI < pDM_DigTable->rx_gain_range_min) 590554c0a3aSHans de Goede CurrentIGI = pDM_DigTable->rx_gain_range_min; 591554c0a3aSHans de Goede 592554c0a3aSHans de Goede if (CurrentIGI > pDM_DigTable->rx_gain_range_max) 593554c0a3aSHans de Goede CurrentIGI = pDM_DigTable->rx_gain_range_max; 594554c0a3aSHans de Goede 595554c0a3aSHans de Goede /* 1 Force upper bound and lower bound for adaptivity */ 596554c0a3aSHans de Goede if ( 597554c0a3aSHans de Goede pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY && 598554c0a3aSHans de Goede pDM_Odm->adaptivity_flag == true 599554c0a3aSHans de Goede ) { 600554c0a3aSHans de Goede if (CurrentIGI > Adap_IGI_Upper) 601554c0a3aSHans de Goede CurrentIGI = Adap_IGI_Upper; 602554c0a3aSHans de Goede 603554c0a3aSHans de Goede if (pDM_Odm->IGI_LowerBound != 0) { 604554c0a3aSHans de Goede if (CurrentIGI < pDM_Odm->IGI_LowerBound) 605554c0a3aSHans de Goede CurrentIGI = pDM_Odm->IGI_LowerBound; 606554c0a3aSHans de Goede } 607554c0a3aSHans de Goede } 608554c0a3aSHans de Goede 609554c0a3aSHans de Goede 610554c0a3aSHans de Goede /* 1 Update status */ 611554c0a3aSHans de Goede if (pDM_Odm->bBtHsOperation) { 612554c0a3aSHans de Goede if (pDM_Odm->bLinked) { 613554c0a3aSHans de Goede if (pDM_DigTable->BT30_CurIGI > (CurrentIGI)) 614554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, CurrentIGI); 615554c0a3aSHans de Goede else 616554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI); 617554c0a3aSHans de Goede 618554c0a3aSHans de Goede pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; 619554c0a3aSHans de Goede pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; 620554c0a3aSHans de Goede } else { 621554c0a3aSHans de Goede if (pDM_Odm->bLinkInProcess) 622554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, 0x1c); 623554c0a3aSHans de Goede else if (pDM_Odm->bBtConnectProcess) 624554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, 0x28); 625554c0a3aSHans de Goede else 626554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ 627554c0a3aSHans de Goede } 628554c0a3aSHans de Goede } else { /* BT is not using */ 629554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ 630554c0a3aSHans de Goede pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; 631554c0a3aSHans de Goede pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; 632554c0a3aSHans de Goede } 633554c0a3aSHans de Goede } 634554c0a3aSHans de Goede 635554c0a3aSHans de Goede void odm_DIGbyRSSI_LPS(void *pDM_VOID) 636554c0a3aSHans de Goede { 637f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 638d7c2b41fSMarco Cesati struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; 639554c0a3aSHans de Goede 640554c0a3aSHans de Goede u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */ 641554c0a3aSHans de Goede u8 CurrentIGI = pDM_Odm->RSSI_Min; 642554c0a3aSHans de Goede 643554c0a3aSHans de Goede CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG; 644554c0a3aSHans de Goede 645554c0a3aSHans de Goede /* Using FW PS mode to make IGI */ 646554c0a3aSHans de Goede /* Adjust by FA in LPS MODE */ 647554c0a3aSHans de Goede if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS) 648554c0a3aSHans de Goede CurrentIGI = CurrentIGI+4; 649554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS) 650554c0a3aSHans de Goede CurrentIGI = CurrentIGI+2; 651554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS) 652554c0a3aSHans de Goede CurrentIGI = CurrentIGI-2; 653554c0a3aSHans de Goede 654554c0a3aSHans de Goede 655554c0a3aSHans de Goede /* Lower bound checking */ 656554c0a3aSHans de Goede 657554c0a3aSHans de Goede /* RSSI Lower bound check */ 658554c0a3aSHans de Goede if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC) 659554c0a3aSHans de Goede RSSI_Lower = pDM_Odm->RSSI_Min-10; 660554c0a3aSHans de Goede else 661554c0a3aSHans de Goede RSSI_Lower = DM_DIG_MIN_NIC; 662554c0a3aSHans de Goede 663554c0a3aSHans de Goede /* Upper and Lower Bound checking */ 664554c0a3aSHans de Goede if (CurrentIGI > DM_DIG_MAX_NIC) 665554c0a3aSHans de Goede CurrentIGI = DM_DIG_MAX_NIC; 666554c0a3aSHans de Goede else if (CurrentIGI < RSSI_Lower) 667554c0a3aSHans de Goede CurrentIGI = RSSI_Lower; 668554c0a3aSHans de Goede 669554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, CurrentIGI); 670554c0a3aSHans de Goede /* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ 671554c0a3aSHans de Goede } 672554c0a3aSHans de Goede 673554c0a3aSHans de Goede /* 3 ============================================================ */ 674554c0a3aSHans de Goede /* 3 FASLE ALARM CHECK */ 675554c0a3aSHans de Goede /* 3 ============================================================ */ 676554c0a3aSHans de Goede 677554c0a3aSHans de Goede void odm_FalseAlarmCounterStatistics(void *pDM_VOID) 678554c0a3aSHans de Goede { 679f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 680db07a1caSMarco Cesati struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; 681554c0a3aSHans de Goede u32 ret_value; 682554c0a3aSHans de Goede 683554c0a3aSHans de Goede if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) 684554c0a3aSHans de Goede return; 685554c0a3aSHans de Goede 686554c0a3aSHans de Goede /* hold ofdm counter */ 687554c0a3aSHans de Goede /* hold page C counter */ 688554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1); 689554c0a3aSHans de Goede /* hold page D counter */ 690554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1); 691554c0a3aSHans de Goede 692554c0a3aSHans de Goede ret_value = PHY_QueryBBReg( 693554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord 694554c0a3aSHans de Goede ); 695554c0a3aSHans de Goede FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); 696554c0a3aSHans de Goede FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); 697554c0a3aSHans de Goede 698554c0a3aSHans de Goede ret_value = PHY_QueryBBReg( 699554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord 700554c0a3aSHans de Goede ); 701554c0a3aSHans de Goede FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); 702554c0a3aSHans de Goede FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); 703554c0a3aSHans de Goede 704554c0a3aSHans de Goede ret_value = PHY_QueryBBReg( 705554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord 706554c0a3aSHans de Goede ); 707554c0a3aSHans de Goede FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); 708554c0a3aSHans de Goede FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); 709554c0a3aSHans de Goede 710554c0a3aSHans de Goede ret_value = PHY_QueryBBReg( 711554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord 712554c0a3aSHans de Goede ); 713554c0a3aSHans de Goede FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); 714554c0a3aSHans de Goede 715554c0a3aSHans de Goede FalseAlmCnt->Cnt_Ofdm_fail = 716554c0a3aSHans de Goede FalseAlmCnt->Cnt_Parity_Fail + 717554c0a3aSHans de Goede FalseAlmCnt->Cnt_Rate_Illegal + 718554c0a3aSHans de Goede FalseAlmCnt->Cnt_Crc8_fail + 719554c0a3aSHans de Goede FalseAlmCnt->Cnt_Mcs_fail + 720554c0a3aSHans de Goede FalseAlmCnt->Cnt_Fast_Fsync + 721554c0a3aSHans de Goede FalseAlmCnt->Cnt_SB_Search_fail; 722554c0a3aSHans de Goede 723554c0a3aSHans de Goede { 724554c0a3aSHans de Goede /* hold cck counter */ 725554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1); 726554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1); 727554c0a3aSHans de Goede 728554c0a3aSHans de Goede ret_value = PHY_QueryBBReg( 729554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0 730554c0a3aSHans de Goede ); 731554c0a3aSHans de Goede FalseAlmCnt->Cnt_Cck_fail = ret_value; 732554c0a3aSHans de Goede 733554c0a3aSHans de Goede ret_value = PHY_QueryBBReg( 734554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3 735554c0a3aSHans de Goede ); 736554c0a3aSHans de Goede FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8; 737554c0a3aSHans de Goede 738554c0a3aSHans de Goede ret_value = PHY_QueryBBReg( 739554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord 740554c0a3aSHans de Goede ); 741554c0a3aSHans de Goede FalseAlmCnt->Cnt_CCK_CCA = 742554c0a3aSHans de Goede ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8); 743554c0a3aSHans de Goede } 744554c0a3aSHans de Goede 745554c0a3aSHans de Goede FalseAlmCnt->Cnt_all = ( 746554c0a3aSHans de Goede FalseAlmCnt->Cnt_Fast_Fsync + 747554c0a3aSHans de Goede FalseAlmCnt->Cnt_SB_Search_fail + 748554c0a3aSHans de Goede FalseAlmCnt->Cnt_Parity_Fail + 749554c0a3aSHans de Goede FalseAlmCnt->Cnt_Rate_Illegal + 750554c0a3aSHans de Goede FalseAlmCnt->Cnt_Crc8_fail + 751554c0a3aSHans de Goede FalseAlmCnt->Cnt_Mcs_fail + 752554c0a3aSHans de Goede FalseAlmCnt->Cnt_Cck_fail 753554c0a3aSHans de Goede ); 754554c0a3aSHans de Goede 755554c0a3aSHans de Goede FalseAlmCnt->Cnt_CCA_all = 756554c0a3aSHans de Goede FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; 757554c0a3aSHans de Goede } 758554c0a3aSHans de Goede 759554c0a3aSHans de Goede 760554c0a3aSHans de Goede void odm_FAThresholdCheck( 761554c0a3aSHans de Goede void *pDM_VOID, 762554c0a3aSHans de Goede bool bDFSBand, 763554c0a3aSHans de Goede bool bPerformance, 764554c0a3aSHans de Goede u32 RxTp, 765554c0a3aSHans de Goede u32 TxTp, 766554c0a3aSHans de Goede u32 *dm_FA_thres 767554c0a3aSHans de Goede ) 768554c0a3aSHans de Goede { 769f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 770554c0a3aSHans de Goede 771554c0a3aSHans de Goede if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) { 772554c0a3aSHans de Goede /* For NIC */ 773554c0a3aSHans de Goede dm_FA_thres[0] = DM_DIG_FA_TH0; 774554c0a3aSHans de Goede dm_FA_thres[1] = DM_DIG_FA_TH1; 775554c0a3aSHans de Goede dm_FA_thres[2] = DM_DIG_FA_TH2; 776554c0a3aSHans de Goede } else { 777554c0a3aSHans de Goede dm_FA_thres[0] = 2000; 778554c0a3aSHans de Goede dm_FA_thres[1] = 4000; 779554c0a3aSHans de Goede dm_FA_thres[2] = 5000; 780554c0a3aSHans de Goede } 781554c0a3aSHans de Goede } 782554c0a3aSHans de Goede 783554c0a3aSHans de Goede u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI) 784554c0a3aSHans de Goede { 785f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 78686d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 787db07a1caSMarco Cesati struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; 788554c0a3aSHans de Goede u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min; 789554c0a3aSHans de Goede 790554c0a3aSHans de Goede if (pFalseAlmCnt->Cnt_all > 10000) { 791554c0a3aSHans de Goede if (pDM_DigTable->LargeFAHit != 3) 792554c0a3aSHans de Goede pDM_DigTable->LargeFAHit++; 793554c0a3aSHans de Goede 794554c0a3aSHans de Goede /* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */ 795554c0a3aSHans de Goede if (pDM_DigTable->ForbiddenIGI < CurrentIGI) { 796554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI = CurrentIGI; 797554c0a3aSHans de Goede /* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */ 798554c0a3aSHans de Goede pDM_DigTable->LargeFAHit = 1; 799554c0a3aSHans de Goede } 800554c0a3aSHans de Goede 801554c0a3aSHans de Goede if (pDM_DigTable->LargeFAHit >= 3) { 802554c0a3aSHans de Goede if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max) 803554c0a3aSHans de Goede rx_gain_range_min = pDM_DigTable->rx_gain_range_max; 804554c0a3aSHans de Goede else 805554c0a3aSHans de Goede rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); 806554c0a3aSHans de Goede pDM_DigTable->Recover_cnt = 1800; 807554c0a3aSHans de Goede } 808554c0a3aSHans de Goede } else { 809554c0a3aSHans de Goede if (pDM_DigTable->Recover_cnt != 0) { 810554c0a3aSHans de Goede pDM_DigTable->Recover_cnt--; 811554c0a3aSHans de Goede } else { 812554c0a3aSHans de Goede if (pDM_DigTable->LargeFAHit < 3) { 813554c0a3aSHans de Goede if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */ 814554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ 815554c0a3aSHans de Goede rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ 816554c0a3aSHans de Goede } else { 817554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI -= 2; 818554c0a3aSHans de Goede rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); 819554c0a3aSHans de Goede } 820554c0a3aSHans de Goede } else 821554c0a3aSHans de Goede pDM_DigTable->LargeFAHit = 0; 822554c0a3aSHans de Goede } 823554c0a3aSHans de Goede } 824554c0a3aSHans de Goede 825554c0a3aSHans de Goede return rx_gain_range_min; 826554c0a3aSHans de Goede 827554c0a3aSHans de Goede } 828554c0a3aSHans de Goede 829554c0a3aSHans de Goede /* 3 ============================================================ */ 830554c0a3aSHans de Goede /* 3 CCK Packet Detect Threshold */ 831554c0a3aSHans de Goede /* 3 ============================================================ */ 832554c0a3aSHans de Goede 833554c0a3aSHans de Goede void odm_CCKPacketDetectionThresh(void *pDM_VOID) 834554c0a3aSHans de Goede { 835f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 836db07a1caSMarco Cesati struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; 837554c0a3aSHans de Goede u8 CurCCK_CCAThres; 838554c0a3aSHans de Goede 839554c0a3aSHans de Goede 840554c0a3aSHans de Goede if ( 841554c0a3aSHans de Goede !(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) || 842554c0a3aSHans de Goede !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT) 843554c0a3aSHans de Goede ) { 844554c0a3aSHans de Goede return; 845554c0a3aSHans de Goede } 846554c0a3aSHans de Goede 847554c0a3aSHans de Goede if (pDM_Odm->ExtLNA) 848554c0a3aSHans de Goede return; 849554c0a3aSHans de Goede 850554c0a3aSHans de Goede if (pDM_Odm->bLinked) { 851554c0a3aSHans de Goede if (pDM_Odm->RSSI_Min > 25) 852554c0a3aSHans de Goede CurCCK_CCAThres = 0xcd; 853554c0a3aSHans de Goede else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) 854554c0a3aSHans de Goede CurCCK_CCAThres = 0x83; 855554c0a3aSHans de Goede else { 856554c0a3aSHans de Goede if (FalseAlmCnt->Cnt_Cck_fail > 1000) 857554c0a3aSHans de Goede CurCCK_CCAThres = 0x83; 858554c0a3aSHans de Goede else 859554c0a3aSHans de Goede CurCCK_CCAThres = 0x40; 860554c0a3aSHans de Goede } 861554c0a3aSHans de Goede } else { 862554c0a3aSHans de Goede if (FalseAlmCnt->Cnt_Cck_fail > 1000) 863554c0a3aSHans de Goede CurCCK_CCAThres = 0x83; 864554c0a3aSHans de Goede else 865554c0a3aSHans de Goede CurCCK_CCAThres = 0x40; 866554c0a3aSHans de Goede } 867554c0a3aSHans de Goede 868554c0a3aSHans de Goede ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres); 869554c0a3aSHans de Goede } 870554c0a3aSHans de Goede 871554c0a3aSHans de Goede void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres) 872554c0a3aSHans de Goede { 873f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 87486d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 875554c0a3aSHans de Goede 876554c0a3aSHans de Goede /* modify by Guo.Mingzhi 2012-01-03 */ 877554c0a3aSHans de Goede if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) 878554c0a3aSHans de Goede rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres); 879554c0a3aSHans de Goede 880554c0a3aSHans de Goede pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; 881554c0a3aSHans de Goede pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; 882554c0a3aSHans de Goede } 883