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 void odm_NHMCounterStatisticsInit(void *pDM_VOID) 11 { 12 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 13 14 /* PHY parameters initialize for n series */ 15 rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x2710); /* 0x894[31:16]= 0x2710 Time duration for NHM unit: 4us, 0x2710 =40ms */ 16 /* rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x4e20); 0x894[31:16]= 0x4e20 Time duration for NHM unit: 4us, 0x4e20 =80ms */ 17 rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff); /* 0x890[31:16]= 0xffff th_9, th_10 */ 18 /* rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff5c); 0x898 = 0xffffff5c th_3, th_2, th_1, th_0 */ 19 rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff52); /* 0x898 = 0xffffff52 th_3, th_2, th_1, th_0 */ 20 rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff); /* 0x89c = 0xffffffff th_7, th_6, th_5, th_4 */ 21 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff); /* 0xe28[7:0]= 0xff th_8 */ 22 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x7); /* 0x890[9:8]=3 enable CCX */ 23 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1); /* 0xc0c[7]= 1 max power among all RX ants */ 24 } 25 26 void odm_NHMCounterStatistics(void *pDM_VOID) 27 { 28 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 29 30 /* Get NHM report */ 31 odm_GetNHMCounterStatistics(pDM_Odm); 32 33 /* Reset NHM counter */ 34 odm_NHMCounterStatisticsReset(pDM_Odm); 35 } 36 37 void odm_GetNHMCounterStatistics(void *pDM_VOID) 38 { 39 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 40 u32 value32 = 0; 41 42 value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_NHM_CNT_11N, bMaskDWord); 43 44 pDM_Odm->NHM_cnt_0 = (u8)(value32 & bMaskByte0); 45 } 46 47 void odm_NHMCounterStatisticsReset(void *pDM_VOID) 48 { 49 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 50 51 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 0); 52 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 1); 53 } 54 55 void odm_NHMBBInit(void *pDM_VOID) 56 { 57 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 58 59 pDM_Odm->adaptivity_flag = 0; 60 pDM_Odm->tolerance_cnt = 3; 61 pDM_Odm->NHMLastTxOkcnt = 0; 62 pDM_Odm->NHMLastRxOkcnt = 0; 63 pDM_Odm->NHMCurTxOkcnt = 0; 64 pDM_Odm->NHMCurRxOkcnt = 0; 65 } 66 67 /* */ 68 void odm_NHMBB(void *pDM_VOID) 69 { 70 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 71 /* u8 test_status; */ 72 /* struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; */ 73 74 pDM_Odm->NHMCurTxOkcnt = 75 *(pDM_Odm->pNumTxBytesUnicast)-pDM_Odm->NHMLastTxOkcnt; 76 pDM_Odm->NHMCurRxOkcnt = 77 *(pDM_Odm->pNumRxBytesUnicast)-pDM_Odm->NHMLastRxOkcnt; 78 pDM_Odm->NHMLastTxOkcnt = 79 *(pDM_Odm->pNumTxBytesUnicast); 80 pDM_Odm->NHMLastRxOkcnt = 81 *(pDM_Odm->pNumRxBytesUnicast); 82 83 84 if ((pDM_Odm->NHMCurTxOkcnt) + 1 > (u64)(pDM_Odm->NHMCurRxOkcnt<<2) + 1) { /* Tx > 4*Rx possible for adaptivity test */ 85 if (pDM_Odm->NHM_cnt_0 >= 190 || pDM_Odm->adaptivity_flag == true) { 86 /* Enable EDCCA since it is possible running Adaptivity testing */ 87 /* test_status = 1; */ 88 pDM_Odm->adaptivity_flag = true; 89 pDM_Odm->tolerance_cnt = 0; 90 } else { 91 if (pDM_Odm->tolerance_cnt < 3) 92 pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1; 93 else 94 pDM_Odm->tolerance_cnt = 4; 95 /* test_status = 5; */ 96 if (pDM_Odm->tolerance_cnt > 3) { 97 /* test_status = 3; */ 98 pDM_Odm->adaptivity_flag = false; 99 } 100 } 101 } else { /* TX<RX */ 102 if (pDM_Odm->adaptivity_flag == true && pDM_Odm->NHM_cnt_0 <= 200) { 103 /* test_status = 2; */ 104 pDM_Odm->tolerance_cnt = 0; 105 } else { 106 if (pDM_Odm->tolerance_cnt < 3) 107 pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1; 108 else 109 pDM_Odm->tolerance_cnt = 4; 110 /* test_status = 5; */ 111 if (pDM_Odm->tolerance_cnt > 3) { 112 /* test_status = 4; */ 113 pDM_Odm->adaptivity_flag = false; 114 } 115 } 116 } 117 } 118 119 void odm_SearchPwdBLowerBound(void *pDM_VOID, u8 IGI_target) 120 { 121 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 122 u32 value32 = 0; 123 u8 cnt, IGI; 124 bool bAdjust = true; 125 s8 TH_L2H_dmc, TH_H2L_dmc; 126 s8 Diff; 127 128 IGI = 0x50; /* find H2L, L2H lower bound */ 129 ODM_Write_DIG(pDM_Odm, IGI); 130 131 132 Diff = IGI_target-(s8)IGI; 133 TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff; 134 if (TH_L2H_dmc > 10) 135 TH_L2H_dmc = 10; 136 TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; 137 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc); 138 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc); 139 140 mdelay(5); 141 142 while (bAdjust) { 143 for (cnt = 0; cnt < 20; cnt++) { 144 value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_RPT_11N, bMaskDWord); 145 146 if (value32 & BIT30) 147 pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1; 148 else if (value32 & BIT29) 149 pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1; 150 else 151 pDM_Odm->txEdcca0 = pDM_Odm->txEdcca0 + 1; 152 } 153 154 if (pDM_Odm->txEdcca1 > 5) { 155 IGI = IGI-1; 156 TH_L2H_dmc = TH_L2H_dmc + 1; 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 pDM_Odm->TxHangFlg = true; 164 pDM_Odm->txEdcca1 = 0; 165 pDM_Odm->txEdcca0 = 0; 166 167 if (TH_L2H_dmc == 10) { 168 bAdjust = false; 169 pDM_Odm->TxHangFlg = false; 170 pDM_Odm->txEdcca1 = 0; 171 pDM_Odm->txEdcca0 = 0; 172 pDM_Odm->H2L_lb = TH_H2L_dmc; 173 pDM_Odm->L2H_lb = TH_L2H_dmc; 174 pDM_Odm->Adaptivity_IGI_upper = IGI; 175 } 176 } else { 177 bAdjust = false; 178 pDM_Odm->TxHangFlg = false; 179 pDM_Odm->txEdcca1 = 0; 180 pDM_Odm->txEdcca0 = 0; 181 pDM_Odm->H2L_lb = TH_H2L_dmc; 182 pDM_Odm->L2H_lb = TH_L2H_dmc; 183 pDM_Odm->Adaptivity_IGI_upper = IGI; 184 } 185 } 186 } 187 188 void odm_AdaptivityInit(void *pDM_VOID) 189 { 190 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 191 192 if (pDM_Odm->Carrier_Sense_enable == false) 193 pDM_Odm->TH_L2H_ini = 0xf7; /* -7 */ 194 else 195 pDM_Odm->TH_L2H_ini = 0xa; 196 197 pDM_Odm->AdapEn_RSSI = 20; 198 pDM_Odm->TH_EDCCA_HL_diff = 7; 199 200 pDM_Odm->IGI_Base = 0x32; 201 pDM_Odm->IGI_target = 0x1c; 202 pDM_Odm->ForceEDCCA = 0; 203 pDM_Odm->NHM_disable = false; 204 pDM_Odm->TxHangFlg = true; 205 pDM_Odm->txEdcca0 = 0; 206 pDM_Odm->txEdcca1 = 0; 207 pDM_Odm->H2L_lb = 0; 208 pDM_Odm->L2H_lb = 0; 209 pDM_Odm->Adaptivity_IGI_upper = 0; 210 odm_NHMBBInit(pDM_Odm); 211 212 PHY_SetBBReg(pDM_Odm->Adapter, REG_RD_CTRL, BIT11, 1); /* stop counting if EDCCA is asserted */ 213 } 214 215 216 void odm_Adaptivity(void *pDM_VOID, u8 IGI) 217 { 218 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 219 s8 TH_L2H_dmc, TH_H2L_dmc; 220 s8 Diff, IGI_target; 221 bool EDCCA_State = false; 222 223 if (!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) { 224 return; 225 } 226 227 if (*pDM_Odm->pBandWidth == ODM_BW20M) /* CHANNEL_WIDTH_20 */ 228 IGI_target = pDM_Odm->IGI_Base; 229 else if (*pDM_Odm->pBandWidth == ODM_BW40M) 230 IGI_target = pDM_Odm->IGI_Base + 2; 231 else 232 IGI_target = pDM_Odm->IGI_Base; 233 pDM_Odm->IGI_target = (u8) IGI_target; 234 235 /* Search pwdB lower bound */ 236 if (pDM_Odm->TxHangFlg == true) { 237 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208); 238 odm_SearchPwdBLowerBound(pDM_Odm, pDM_Odm->IGI_target); 239 } 240 241 if ((!pDM_Odm->bLinked) || (*pDM_Odm->pChannel > 149)) { /* Band4 doesn't need adaptivity */ 242 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, 0x7f); 243 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, 0x7f); 244 return; 245 } 246 247 if (!pDM_Odm->ForceEDCCA) { 248 if (pDM_Odm->RSSI_Min > pDM_Odm->AdapEn_RSSI) 249 EDCCA_State = true; 250 else if (pDM_Odm->RSSI_Min < (pDM_Odm->AdapEn_RSSI - 5)) 251 EDCCA_State = false; 252 } else 253 EDCCA_State = true; 254 255 if ( 256 pDM_Odm->bLinked && 257 pDM_Odm->Carrier_Sense_enable == false && 258 pDM_Odm->NHM_disable == false && 259 pDM_Odm->TxHangFlg == false 260 ) 261 odm_NHMBB(pDM_Odm); 262 263 if (EDCCA_State) { 264 Diff = IGI_target-(s8)IGI; 265 TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff; 266 if (TH_L2H_dmc > 10) 267 TH_L2H_dmc = 10; 268 269 TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; 270 271 /* replace lower bound to prevent EDCCA always equal */ 272 if (TH_H2L_dmc < pDM_Odm->H2L_lb) 273 TH_H2L_dmc = pDM_Odm->H2L_lb; 274 if (TH_L2H_dmc < pDM_Odm->L2H_lb) 275 TH_L2H_dmc = pDM_Odm->L2H_lb; 276 } else { 277 TH_L2H_dmc = 0x7f; 278 TH_H2L_dmc = 0x7f; 279 } 280 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc); 281 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc); 282 } 283 284 void ODM_Write_DIG(void *pDM_VOID, u8 CurrentIGI) 285 { 286 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 287 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 288 289 if (pDM_DigTable->bStopDIG) { 290 return; 291 } 292 293 if (pDM_DigTable->CurIGValue != CurrentIGI) { 294 /* 1 Check initial gain by upper bound */ 295 if (!pDM_DigTable->bPSDInProgress) { 296 if (CurrentIGI > pDM_DigTable->rx_gain_range_max) { 297 CurrentIGI = pDM_DigTable->rx_gain_range_max; 298 } 299 300 } 301 302 /* 1 Set IGI value */ 303 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); 304 305 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); 306 307 pDM_DigTable->CurIGValue = CurrentIGI; 308 } 309 310 } 311 312 bool odm_DigAbort(void *pDM_VOID) 313 { 314 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 315 316 /* SupportAbility */ 317 if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) { 318 return true; 319 } 320 321 /* SupportAbility */ 322 if (!(pDM_Odm->SupportAbility & ODM_BB_DIG)) { 323 return true; 324 } 325 326 /* ScanInProcess */ 327 if (*(pDM_Odm->pbScanInProcess)) { 328 return true; 329 } 330 331 /* add by Neil Chen to avoid PSD is processing */ 332 if (pDM_Odm->bDMInitialGainEnable == false) { 333 return true; 334 } 335 336 return false; 337 } 338 339 void odm_DIGInit(void *pDM_VOID) 340 { 341 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 342 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 343 344 pDM_DigTable->bStopDIG = false; 345 pDM_DigTable->bPSDInProgress = false; 346 pDM_DigTable->CurIGValue = (u8) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm)); 347 pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; 348 pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; 349 pDM_DigTable->FALowThresh = DMfalseALARM_THRESH_LOW; 350 pDM_DigTable->FAHighThresh = DMfalseALARM_THRESH_HIGH; 351 pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; 352 pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; 353 pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; 354 pDM_DigTable->PreCCK_CCAThres = 0xFF; 355 pDM_DigTable->CurCCK_CCAThres = 0x83; 356 pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC; 357 pDM_DigTable->LargeFAHit = 0; 358 pDM_DigTable->Recover_cnt = 0; 359 pDM_DigTable->bMediaConnect_0 = false; 360 pDM_DigTable->bMediaConnect_1 = false; 361 362 /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */ 363 pDM_Odm->bDMInitialGainEnable = true; 364 365 pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC; 366 pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC; 367 368 /* To Initi BT30 IGI */ 369 pDM_DigTable->BT30_CurIGI = 0x32; 370 371 pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; 372 pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; 373 374 } 375 376 377 void odm_DIG(void *pDM_VOID) 378 { 379 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 380 381 /* Common parameters */ 382 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 383 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; 384 bool FirstConnect, FirstDisConnect; 385 u8 DIG_MaxOfMin, DIG_Dynamic_MIN; 386 u8 dm_dig_max, dm_dig_min; 387 u8 CurrentIGI = pDM_DigTable->CurIGValue; 388 u8 offset; 389 u32 dm_FA_thres[3]; 390 u8 Adap_IGI_Upper = 0; 391 u32 TxTp = 0, RxTp = 0; 392 bool bDFSBand = false; 393 bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false; 394 395 if (odm_DigAbort(pDM_Odm)) 396 return; 397 398 if (pDM_Odm->adaptivity_flag == true) 399 Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper; 400 401 402 /* 1 Update status */ 403 DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; 404 FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == false); 405 FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == true); 406 407 /* 1 Boundary Decision */ 408 /* 2 For WIN\CE */ 409 dm_dig_max = 0x5A; 410 dm_dig_min = DM_DIG_MIN_NIC; 411 DIG_MaxOfMin = DM_DIG_MAX_AP; 412 413 /* 1 Adjust boundary by RSSI */ 414 if (pDM_Odm->bLinked && bPerformance) { 415 /* 2 Modify DIG upper bound */ 416 /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */ 417 if (pDM_Odm->bBtLimitedDig == 1) { 418 offset = 10; 419 } else 420 offset = 15; 421 422 if ((pDM_Odm->RSSI_Min + offset) > dm_dig_max) 423 pDM_DigTable->rx_gain_range_max = dm_dig_max; 424 else if ((pDM_Odm->RSSI_Min + offset) < dm_dig_min) 425 pDM_DigTable->rx_gain_range_max = dm_dig_min; 426 else 427 pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset; 428 429 /* 2 Modify DIG lower bound */ 430 /* if (pDM_Odm->bOneEntryOnly) */ 431 { 432 if (pDM_Odm->RSSI_Min < dm_dig_min) 433 DIG_Dynamic_MIN = dm_dig_min; 434 else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) 435 DIG_Dynamic_MIN = DIG_MaxOfMin; 436 else 437 DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; 438 } 439 } else { 440 pDM_DigTable->rx_gain_range_max = dm_dig_max; 441 DIG_Dynamic_MIN = dm_dig_min; 442 } 443 444 /* 1 Force Lower Bound for AntDiv */ 445 if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) { 446 if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) { 447 if ( 448 pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV || 449 pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV || 450 pDM_Odm->AntDivType == S0S1_SW_ANTDIV 451 ) { 452 if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin) 453 DIG_Dynamic_MIN = DIG_MaxOfMin; 454 else 455 DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max; 456 } 457 } 458 } 459 460 /* 1 Modify DIG lower bound, deal with abnormal case */ 461 /* 2 Abnormal false alarm case */ 462 if (FirstDisConnect) { 463 pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; 464 pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; 465 } else 466 pDM_DigTable->rx_gain_range_min = 467 odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI); 468 469 if (pDM_Odm->bLinked && !FirstConnect) { 470 if ( 471 (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) && 472 pDM_Odm->bsta_state 473 ) { 474 pDM_DigTable->rx_gain_range_min = dm_dig_min; 475 } 476 } 477 478 /* 2 Abnormal lower bound case */ 479 if (pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) { 480 pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max; 481 } 482 483 484 /* 1 False alarm threshold decision */ 485 odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres); 486 487 /* 1 Adjust initial gain by false alarm */ 488 if (pDM_Odm->bLinked && bPerformance) { 489 490 if (bFirstTpTarget || FirstConnect) { 491 pDM_DigTable->LargeFAHit = 0; 492 493 if (pDM_Odm->RSSI_Min < DIG_MaxOfMin) { 494 if (CurrentIGI < pDM_Odm->RSSI_Min) 495 CurrentIGI = pDM_Odm->RSSI_Min; 496 } else { 497 if (CurrentIGI < DIG_MaxOfMin) 498 CurrentIGI = DIG_MaxOfMin; 499 } 500 501 } else { 502 if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2]) 503 CurrentIGI = CurrentIGI + 4; 504 else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1]) 505 CurrentIGI = CurrentIGI + 2; 506 else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0]) 507 CurrentIGI = CurrentIGI - 2; 508 509 if ( 510 (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) && 511 (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) && 512 (pDM_Odm->bsta_state) 513 ) { 514 CurrentIGI = pDM_DigTable->rx_gain_range_min; 515 } 516 } 517 } else { 518 519 if (FirstDisConnect || bFirstCoverage) { 520 CurrentIGI = dm_dig_min; 521 } else { 522 if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2]) 523 CurrentIGI = CurrentIGI + 4; 524 else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1]) 525 CurrentIGI = CurrentIGI + 2; 526 else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0]) 527 CurrentIGI = CurrentIGI - 2; 528 } 529 } 530 531 /* 1 Check initial gain by upper/lower bound */ 532 if (CurrentIGI < pDM_DigTable->rx_gain_range_min) 533 CurrentIGI = pDM_DigTable->rx_gain_range_min; 534 535 if (CurrentIGI > pDM_DigTable->rx_gain_range_max) 536 CurrentIGI = pDM_DigTable->rx_gain_range_max; 537 538 /* 1 Force upper bound and lower bound for adaptivity */ 539 if ( 540 pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY && 541 pDM_Odm->adaptivity_flag == true 542 ) { 543 if (CurrentIGI > Adap_IGI_Upper) 544 CurrentIGI = Adap_IGI_Upper; 545 546 if (pDM_Odm->IGI_LowerBound != 0) { 547 if (CurrentIGI < pDM_Odm->IGI_LowerBound) 548 CurrentIGI = pDM_Odm->IGI_LowerBound; 549 } 550 } 551 552 553 /* 1 Update status */ 554 if (pDM_Odm->bBtHsOperation) { 555 if (pDM_Odm->bLinked) { 556 if (pDM_DigTable->BT30_CurIGI > (CurrentIGI)) 557 ODM_Write_DIG(pDM_Odm, CurrentIGI); 558 else 559 ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI); 560 561 pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; 562 pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; 563 } else { 564 if (pDM_Odm->bLinkInProcess) 565 ODM_Write_DIG(pDM_Odm, 0x1c); 566 else if (pDM_Odm->bBtConnectProcess) 567 ODM_Write_DIG(pDM_Odm, 0x28); 568 else 569 ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ 570 } 571 } else { /* BT is not using */ 572 ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ 573 pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; 574 pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; 575 } 576 } 577 578 void odm_DIGbyRSSI_LPS(void *pDM_VOID) 579 { 580 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 581 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; 582 583 u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */ 584 u8 CurrentIGI = pDM_Odm->RSSI_Min; 585 586 CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG; 587 588 /* Using FW PS mode to make IGI */ 589 /* Adjust by FA in LPS MODE */ 590 if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS) 591 CurrentIGI = CurrentIGI+4; 592 else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS) 593 CurrentIGI = CurrentIGI+2; 594 else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS) 595 CurrentIGI = CurrentIGI-2; 596 597 598 /* Lower bound checking */ 599 600 /* RSSI Lower bound check */ 601 if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC) 602 RSSI_Lower = pDM_Odm->RSSI_Min-10; 603 else 604 RSSI_Lower = DM_DIG_MIN_NIC; 605 606 /* Upper and Lower Bound checking */ 607 if (CurrentIGI > DM_DIG_MAX_NIC) 608 CurrentIGI = DM_DIG_MAX_NIC; 609 else if (CurrentIGI < RSSI_Lower) 610 CurrentIGI = RSSI_Lower; 611 612 ODM_Write_DIG(pDM_Odm, CurrentIGI); 613 /* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ 614 } 615 616 /* 3 ============================================================ */ 617 /* 3 FASLE ALARM CHECK */ 618 /* 3 ============================================================ */ 619 620 void odm_FalseAlarmCounterStatistics(void *pDM_VOID) 621 { 622 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 623 struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; 624 u32 ret_value; 625 626 if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) 627 return; 628 629 /* hold ofdm counter */ 630 /* hold page C counter */ 631 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1); 632 /* hold page D counter */ 633 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1); 634 635 ret_value = PHY_QueryBBReg( 636 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord 637 ); 638 FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); 639 FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); 640 641 ret_value = PHY_QueryBBReg( 642 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord 643 ); 644 FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); 645 FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); 646 647 ret_value = PHY_QueryBBReg( 648 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord 649 ); 650 FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); 651 FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); 652 653 ret_value = PHY_QueryBBReg( 654 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord 655 ); 656 FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); 657 658 FalseAlmCnt->Cnt_Ofdm_fail = 659 FalseAlmCnt->Cnt_Parity_Fail + 660 FalseAlmCnt->Cnt_Rate_Illegal + 661 FalseAlmCnt->Cnt_Crc8_fail + 662 FalseAlmCnt->Cnt_Mcs_fail + 663 FalseAlmCnt->Cnt_Fast_Fsync + 664 FalseAlmCnt->Cnt_SB_Search_fail; 665 666 { 667 /* hold cck counter */ 668 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1); 669 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1); 670 671 ret_value = PHY_QueryBBReg( 672 pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0 673 ); 674 FalseAlmCnt->Cnt_Cck_fail = ret_value; 675 676 ret_value = PHY_QueryBBReg( 677 pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3 678 ); 679 FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8; 680 681 ret_value = PHY_QueryBBReg( 682 pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord 683 ); 684 FalseAlmCnt->Cnt_CCK_CCA = 685 ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8); 686 } 687 688 FalseAlmCnt->Cnt_all = ( 689 FalseAlmCnt->Cnt_Fast_Fsync + 690 FalseAlmCnt->Cnt_SB_Search_fail + 691 FalseAlmCnt->Cnt_Parity_Fail + 692 FalseAlmCnt->Cnt_Rate_Illegal + 693 FalseAlmCnt->Cnt_Crc8_fail + 694 FalseAlmCnt->Cnt_Mcs_fail + 695 FalseAlmCnt->Cnt_Cck_fail 696 ); 697 698 FalseAlmCnt->Cnt_CCA_all = 699 FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; 700 } 701 702 703 void odm_FAThresholdCheck( 704 void *pDM_VOID, 705 bool bDFSBand, 706 bool bPerformance, 707 u32 RxTp, 708 u32 TxTp, 709 u32 *dm_FA_thres 710 ) 711 { 712 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 713 714 if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) { 715 /* For NIC */ 716 dm_FA_thres[0] = DM_DIG_FA_TH0; 717 dm_FA_thres[1] = DM_DIG_FA_TH1; 718 dm_FA_thres[2] = DM_DIG_FA_TH2; 719 } else { 720 dm_FA_thres[0] = 2000; 721 dm_FA_thres[1] = 4000; 722 dm_FA_thres[2] = 5000; 723 } 724 } 725 726 u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI) 727 { 728 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 729 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 730 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; 731 u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min; 732 733 if (pFalseAlmCnt->Cnt_all > 10000) { 734 if (pDM_DigTable->LargeFAHit != 3) 735 pDM_DigTable->LargeFAHit++; 736 737 /* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */ 738 if (pDM_DigTable->ForbiddenIGI < CurrentIGI) { 739 pDM_DigTable->ForbiddenIGI = CurrentIGI; 740 /* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */ 741 pDM_DigTable->LargeFAHit = 1; 742 } 743 744 if (pDM_DigTable->LargeFAHit >= 3) { 745 if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max) 746 rx_gain_range_min = pDM_DigTable->rx_gain_range_max; 747 else 748 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); 749 pDM_DigTable->Recover_cnt = 1800; 750 } 751 } else { 752 if (pDM_DigTable->Recover_cnt != 0) { 753 pDM_DigTable->Recover_cnt--; 754 } else { 755 if (pDM_DigTable->LargeFAHit < 3) { 756 if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */ 757 pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ 758 rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ 759 } else { 760 pDM_DigTable->ForbiddenIGI -= 2; 761 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); 762 } 763 } else 764 pDM_DigTable->LargeFAHit = 0; 765 } 766 } 767 768 return rx_gain_range_min; 769 770 } 771 772 /* 3 ============================================================ */ 773 /* 3 CCK Packet Detect Threshold */ 774 /* 3 ============================================================ */ 775 776 void odm_CCKPacketDetectionThresh(void *pDM_VOID) 777 { 778 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 779 struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; 780 u8 CurCCK_CCAThres; 781 782 783 if ( 784 !(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) || 785 !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT) 786 ) { 787 return; 788 } 789 790 if (pDM_Odm->ExtLNA) 791 return; 792 793 if (pDM_Odm->bLinked) { 794 if (pDM_Odm->RSSI_Min > 25) 795 CurCCK_CCAThres = 0xcd; 796 else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) 797 CurCCK_CCAThres = 0x83; 798 else { 799 if (FalseAlmCnt->Cnt_Cck_fail > 1000) 800 CurCCK_CCAThres = 0x83; 801 else 802 CurCCK_CCAThres = 0x40; 803 } 804 } else { 805 if (FalseAlmCnt->Cnt_Cck_fail > 1000) 806 CurCCK_CCAThres = 0x83; 807 else 808 CurCCK_CCAThres = 0x40; 809 } 810 811 ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres); 812 } 813 814 void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres) 815 { 816 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 817 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 818 819 /* modify by Guo.Mingzhi 2012-01-03 */ 820 if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) 821 rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres); 822 823 pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; 824 pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; 825 } 826