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