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 RSSI_Lower = max(pDM_Odm->RSSI_Min - 10, DM_DIG_MIN_NIC); 602 603 /* Upper and Lower Bound checking */ 604 if (CurrentIGI > DM_DIG_MAX_NIC) 605 CurrentIGI = DM_DIG_MAX_NIC; 606 else if (CurrentIGI < RSSI_Lower) 607 CurrentIGI = RSSI_Lower; 608 609 ODM_Write_DIG(pDM_Odm, CurrentIGI); 610 /* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ 611 } 612 613 /* 3 ============================================================ */ 614 /* 3 FASLE ALARM CHECK */ 615 /* 3 ============================================================ */ 616 617 void odm_FalseAlarmCounterStatistics(void *pDM_VOID) 618 { 619 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 620 struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; 621 u32 ret_value; 622 623 if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) 624 return; 625 626 /* hold ofdm counter */ 627 /* hold page C counter */ 628 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1); 629 /* hold page D counter */ 630 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1); 631 632 ret_value = PHY_QueryBBReg( 633 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord 634 ); 635 FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); 636 FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); 637 638 ret_value = PHY_QueryBBReg( 639 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord 640 ); 641 FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); 642 FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); 643 644 ret_value = PHY_QueryBBReg( 645 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord 646 ); 647 FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); 648 FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); 649 650 ret_value = PHY_QueryBBReg( 651 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord 652 ); 653 FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); 654 655 FalseAlmCnt->Cnt_Ofdm_fail = 656 FalseAlmCnt->Cnt_Parity_Fail + 657 FalseAlmCnt->Cnt_Rate_Illegal + 658 FalseAlmCnt->Cnt_Crc8_fail + 659 FalseAlmCnt->Cnt_Mcs_fail + 660 FalseAlmCnt->Cnt_Fast_Fsync + 661 FalseAlmCnt->Cnt_SB_Search_fail; 662 663 { 664 /* hold cck counter */ 665 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1); 666 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1); 667 668 ret_value = PHY_QueryBBReg( 669 pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0 670 ); 671 FalseAlmCnt->Cnt_Cck_fail = ret_value; 672 673 ret_value = PHY_QueryBBReg( 674 pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3 675 ); 676 FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8; 677 678 ret_value = PHY_QueryBBReg( 679 pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord 680 ); 681 FalseAlmCnt->Cnt_CCK_CCA = 682 ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8); 683 } 684 685 FalseAlmCnt->Cnt_all = ( 686 FalseAlmCnt->Cnt_Fast_Fsync + 687 FalseAlmCnt->Cnt_SB_Search_fail + 688 FalseAlmCnt->Cnt_Parity_Fail + 689 FalseAlmCnt->Cnt_Rate_Illegal + 690 FalseAlmCnt->Cnt_Crc8_fail + 691 FalseAlmCnt->Cnt_Mcs_fail + 692 FalseAlmCnt->Cnt_Cck_fail 693 ); 694 695 FalseAlmCnt->Cnt_CCA_all = 696 FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; 697 } 698 699 700 void odm_FAThresholdCheck( 701 void *pDM_VOID, 702 bool bDFSBand, 703 bool bPerformance, 704 u32 RxTp, 705 u32 TxTp, 706 u32 *dm_FA_thres 707 ) 708 { 709 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 710 711 if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) { 712 /* For NIC */ 713 dm_FA_thres[0] = DM_DIG_FA_TH0; 714 dm_FA_thres[1] = DM_DIG_FA_TH1; 715 dm_FA_thres[2] = DM_DIG_FA_TH2; 716 } else { 717 dm_FA_thres[0] = 2000; 718 dm_FA_thres[1] = 4000; 719 dm_FA_thres[2] = 5000; 720 } 721 } 722 723 u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI) 724 { 725 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 726 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 727 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; 728 u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min; 729 730 if (pFalseAlmCnt->Cnt_all > 10000) { 731 if (pDM_DigTable->LargeFAHit != 3) 732 pDM_DigTable->LargeFAHit++; 733 734 /* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */ 735 if (pDM_DigTable->ForbiddenIGI < CurrentIGI) { 736 pDM_DigTable->ForbiddenIGI = CurrentIGI; 737 /* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */ 738 pDM_DigTable->LargeFAHit = 1; 739 } 740 741 if (pDM_DigTable->LargeFAHit >= 3) { 742 if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max) 743 rx_gain_range_min = pDM_DigTable->rx_gain_range_max; 744 else 745 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); 746 pDM_DigTable->Recover_cnt = 1800; 747 } 748 } else { 749 if (pDM_DigTable->Recover_cnt != 0) { 750 pDM_DigTable->Recover_cnt--; 751 } else { 752 if (pDM_DigTable->LargeFAHit < 3) { 753 if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */ 754 pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ 755 rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ 756 } else { 757 pDM_DigTable->ForbiddenIGI -= 2; 758 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); 759 } 760 } else 761 pDM_DigTable->LargeFAHit = 0; 762 } 763 } 764 765 return rx_gain_range_min; 766 767 } 768 769 /* 3 ============================================================ */ 770 /* 3 CCK Packet Detect Threshold */ 771 /* 3 ============================================================ */ 772 773 void odm_CCKPacketDetectionThresh(void *pDM_VOID) 774 { 775 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 776 struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; 777 u8 CurCCK_CCAThres; 778 779 780 if ( 781 !(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) || 782 !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT) 783 ) { 784 return; 785 } 786 787 if (pDM_Odm->ExtLNA) 788 return; 789 790 if (pDM_Odm->bLinked) { 791 if (pDM_Odm->RSSI_Min > 25) 792 CurCCK_CCAThres = 0xcd; 793 else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) 794 CurCCK_CCAThres = 0x83; 795 else { 796 if (FalseAlmCnt->Cnt_Cck_fail > 1000) 797 CurCCK_CCAThres = 0x83; 798 else 799 CurCCK_CCAThres = 0x40; 800 } 801 } else { 802 if (FalseAlmCnt->Cnt_Cck_fail > 1000) 803 CurCCK_CCAThres = 0x83; 804 else 805 CurCCK_CCAThres = 0x40; 806 } 807 808 ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres); 809 } 810 811 void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres) 812 { 813 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 814 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; 815 816 /* modify by Guo.Mingzhi 2012-01-03 */ 817 if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) 818 rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres); 819 820 pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; 821 pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; 822 } 823