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
odm_NHMCounterStatisticsInit(void * pDM_VOID)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
odm_NHMCounterStatistics(void * pDM_VOID)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
odm_GetNHMCounterStatistics(void * pDM_VOID)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
odm_NHMCounterStatisticsReset(void * pDM_VOID)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
odm_NHMBBInit(void * pDM_VOID)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 = false;
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 /* */
odm_NHMBB(void * pDM_VOID)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
odm_SearchPwdBLowerBound(void * pDM_VOID,u8 IGI_target)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
odm_AdaptivityInit(void * pDM_VOID)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
odm_Adaptivity(void * pDM_VOID,u8 IGI)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
ODM_Write_DIG(void * pDM_VOID,u8 CurrentIGI)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
odm_DigAbort(void * pDM_VOID)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
odm_DIGInit(void * pDM_VOID)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
odm_DIG(void * pDM_VOID)376 void odm_DIG(void *pDM_VOID)
377 {
378 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
379
380 /* Common parameters */
381 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
382 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
383 bool FirstConnect, FirstDisConnect;
384 u8 DIG_MaxOfMin, DIG_Dynamic_MIN;
385 u8 dm_dig_max, dm_dig_min;
386 u8 CurrentIGI = pDM_DigTable->CurIGValue;
387 u8 offset;
388 u32 dm_FA_thres[3];
389 u8 Adap_IGI_Upper = 0;
390 u32 TxTp = 0, RxTp = 0;
391 bool bDFSBand = false;
392 bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false;
393
394 if (odm_DigAbort(pDM_Odm))
395 return;
396
397 if (pDM_Odm->adaptivity_flag == true)
398 Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper;
399
400
401 /* 1 Update status */
402 DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
403 FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == false);
404 FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == true);
405
406 /* 1 Boundary Decision */
407 /* 2 For WIN\CE */
408 dm_dig_max = 0x5A;
409 dm_dig_min = DM_DIG_MIN_NIC;
410 DIG_MaxOfMin = DM_DIG_MAX_AP;
411
412 /* 1 Adjust boundary by RSSI */
413 if (pDM_Odm->bLinked && bPerformance) {
414 /* 2 Modify DIG upper bound */
415 /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
416 if (pDM_Odm->bBtLimitedDig == 1) {
417 offset = 10;
418 } else
419 offset = 15;
420
421 if ((pDM_Odm->RSSI_Min + offset) > dm_dig_max)
422 pDM_DigTable->rx_gain_range_max = dm_dig_max;
423 else if ((pDM_Odm->RSSI_Min + offset) < dm_dig_min)
424 pDM_DigTable->rx_gain_range_max = dm_dig_min;
425 else
426 pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset;
427
428 /* 2 Modify DIG lower bound */
429 /* if (pDM_Odm->bOneEntryOnly) */
430 {
431 if (pDM_Odm->RSSI_Min < dm_dig_min)
432 DIG_Dynamic_MIN = dm_dig_min;
433 else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
434 DIG_Dynamic_MIN = DIG_MaxOfMin;
435 else
436 DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
437 }
438 } else {
439 pDM_DigTable->rx_gain_range_max = dm_dig_max;
440 DIG_Dynamic_MIN = dm_dig_min;
441 }
442
443 /* 1 Force Lower Bound for AntDiv */
444 if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) {
445 if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
446 if (
447 pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV ||
448 pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV ||
449 pDM_Odm->AntDivType == S0S1_SW_ANTDIV
450 ) {
451 if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin)
452 DIG_Dynamic_MIN = DIG_MaxOfMin;
453 else
454 DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max;
455 }
456 }
457 }
458
459 /* 1 Modify DIG lower bound, deal with abnormal case */
460 /* 2 Abnormal false alarm case */
461 if (FirstDisConnect) {
462 pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN;
463 pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN;
464 } else
465 pDM_DigTable->rx_gain_range_min =
466 odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI);
467
468 if (pDM_Odm->bLinked && !FirstConnect) {
469 if (
470 (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
471 pDM_Odm->bsta_state
472 ) {
473 pDM_DigTable->rx_gain_range_min = dm_dig_min;
474 }
475 }
476
477 /* 2 Abnormal lower bound case */
478 if (pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) {
479 pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
480 }
481
482
483 /* 1 False alarm threshold decision */
484 odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres);
485
486 /* 1 Adjust initial gain by false alarm */
487 if (pDM_Odm->bLinked && bPerformance) {
488
489 if (bFirstTpTarget || FirstConnect) {
490 pDM_DigTable->LargeFAHit = 0;
491
492 if (pDM_Odm->RSSI_Min < DIG_MaxOfMin) {
493 if (CurrentIGI < pDM_Odm->RSSI_Min)
494 CurrentIGI = pDM_Odm->RSSI_Min;
495 } else {
496 if (CurrentIGI < DIG_MaxOfMin)
497 CurrentIGI = DIG_MaxOfMin;
498 }
499
500 } else {
501 if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
502 CurrentIGI = CurrentIGI + 4;
503 else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
504 CurrentIGI = CurrentIGI + 2;
505 else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
506 CurrentIGI = CurrentIGI - 2;
507
508 if (
509 (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
510 (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) &&
511 (pDM_Odm->bsta_state)
512 ) {
513 CurrentIGI = pDM_DigTable->rx_gain_range_min;
514 }
515 }
516 } else {
517
518 if (FirstDisConnect || bFirstCoverage) {
519 CurrentIGI = dm_dig_min;
520 } else {
521 if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
522 CurrentIGI = CurrentIGI + 4;
523 else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
524 CurrentIGI = CurrentIGI + 2;
525 else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
526 CurrentIGI = CurrentIGI - 2;
527 }
528 }
529
530 /* 1 Check initial gain by upper/lower bound */
531 if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
532 CurrentIGI = pDM_DigTable->rx_gain_range_min;
533
534 if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
535 CurrentIGI = pDM_DigTable->rx_gain_range_max;
536
537 /* 1 Force upper bound and lower bound for adaptivity */
538 if (
539 pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY &&
540 pDM_Odm->adaptivity_flag == true
541 ) {
542 if (CurrentIGI > Adap_IGI_Upper)
543 CurrentIGI = Adap_IGI_Upper;
544
545 if (pDM_Odm->IGI_LowerBound != 0) {
546 if (CurrentIGI < pDM_Odm->IGI_LowerBound)
547 CurrentIGI = pDM_Odm->IGI_LowerBound;
548 }
549 }
550
551
552 /* 1 Update status */
553 if (pDM_Odm->bBtHsOperation) {
554 if (pDM_Odm->bLinked) {
555 if (pDM_DigTable->BT30_CurIGI > (CurrentIGI))
556 ODM_Write_DIG(pDM_Odm, CurrentIGI);
557 else
558 ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);
559
560 pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
561 pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
562 } else {
563 if (pDM_Odm->bLinkInProcess)
564 ODM_Write_DIG(pDM_Odm, 0x1c);
565 else if (pDM_Odm->bBtConnectProcess)
566 ODM_Write_DIG(pDM_Odm, 0x28);
567 else
568 ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
569 }
570 } else { /* BT is not using */
571 ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
572 pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
573 pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
574 }
575 }
576
odm_DIGbyRSSI_LPS(void * pDM_VOID)577 void odm_DIGbyRSSI_LPS(void *pDM_VOID)
578 {
579 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
580 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
581
582 u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
583 u8 CurrentIGI = pDM_Odm->RSSI_Min;
584
585 CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
586
587 /* Using FW PS mode to make IGI */
588 /* Adjust by FA in LPS MODE */
589 if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS)
590 CurrentIGI = CurrentIGI+4;
591 else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS)
592 CurrentIGI = CurrentIGI+2;
593 else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS)
594 CurrentIGI = CurrentIGI-2;
595
596
597 /* Lower bound checking */
598
599 /* RSSI Lower bound check */
600 RSSI_Lower = max(pDM_Odm->RSSI_Min - 10, DM_DIG_MIN_NIC);
601
602 /* Upper and Lower Bound checking */
603 if (CurrentIGI > DM_DIG_MAX_NIC)
604 CurrentIGI = DM_DIG_MAX_NIC;
605 else if (CurrentIGI < RSSI_Lower)
606 CurrentIGI = RSSI_Lower;
607
608 ODM_Write_DIG(pDM_Odm, CurrentIGI);
609 /* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
610 }
611
612 /* 3 ============================================================ */
613 /* 3 FASLE ALARM CHECK */
614 /* 3 ============================================================ */
615
odm_FalseAlarmCounterStatistics(void * pDM_VOID)616 void odm_FalseAlarmCounterStatistics(void *pDM_VOID)
617 {
618 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
619 struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
620 u32 ret_value;
621
622 if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
623 return;
624
625 /* hold ofdm counter */
626 /* hold page C counter */
627 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1);
628 /* hold page D counter */
629 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1);
630
631 ret_value = PHY_QueryBBReg(
632 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord
633 );
634 FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
635 FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16);
636
637 ret_value = PHY_QueryBBReg(
638 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord
639 );
640 FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
641 FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
642
643 ret_value = PHY_QueryBBReg(
644 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord
645 );
646 FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
647 FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
648
649 ret_value = PHY_QueryBBReg(
650 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord
651 );
652 FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
653
654 FalseAlmCnt->Cnt_Ofdm_fail =
655 FalseAlmCnt->Cnt_Parity_Fail +
656 FalseAlmCnt->Cnt_Rate_Illegal +
657 FalseAlmCnt->Cnt_Crc8_fail +
658 FalseAlmCnt->Cnt_Mcs_fail +
659 FalseAlmCnt->Cnt_Fast_Fsync +
660 FalseAlmCnt->Cnt_SB_Search_fail;
661
662 {
663 /* hold cck counter */
664 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1);
665 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1);
666
667 ret_value = PHY_QueryBBReg(
668 pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0
669 );
670 FalseAlmCnt->Cnt_Cck_fail = ret_value;
671
672 ret_value = PHY_QueryBBReg(
673 pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3
674 );
675 FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8;
676
677 ret_value = PHY_QueryBBReg(
678 pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord
679 );
680 FalseAlmCnt->Cnt_CCK_CCA =
681 ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
682 }
683
684 FalseAlmCnt->Cnt_all = (
685 FalseAlmCnt->Cnt_Fast_Fsync +
686 FalseAlmCnt->Cnt_SB_Search_fail +
687 FalseAlmCnt->Cnt_Parity_Fail +
688 FalseAlmCnt->Cnt_Rate_Illegal +
689 FalseAlmCnt->Cnt_Crc8_fail +
690 FalseAlmCnt->Cnt_Mcs_fail +
691 FalseAlmCnt->Cnt_Cck_fail
692 );
693
694 FalseAlmCnt->Cnt_CCA_all =
695 FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
696 }
697
698
odm_FAThresholdCheck(void * pDM_VOID,bool bDFSBand,bool bPerformance,u32 RxTp,u32 TxTp,u32 * dm_FA_thres)699 void odm_FAThresholdCheck(
700 void *pDM_VOID,
701 bool bDFSBand,
702 bool bPerformance,
703 u32 RxTp,
704 u32 TxTp,
705 u32 *dm_FA_thres
706 )
707 {
708 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
709
710 if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) {
711 /* For NIC */
712 dm_FA_thres[0] = DM_DIG_FA_TH0;
713 dm_FA_thres[1] = DM_DIG_FA_TH1;
714 dm_FA_thres[2] = DM_DIG_FA_TH2;
715 } else {
716 dm_FA_thres[0] = 2000;
717 dm_FA_thres[1] = 4000;
718 dm_FA_thres[2] = 5000;
719 }
720 }
721
odm_ForbiddenIGICheck(void * pDM_VOID,u8 DIG_Dynamic_MIN,u8 CurrentIGI)722 u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI)
723 {
724 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
725 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
726 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
727 u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min;
728
729 if (pFalseAlmCnt->Cnt_all > 10000) {
730 if (pDM_DigTable->LargeFAHit != 3)
731 pDM_DigTable->LargeFAHit++;
732
733 /* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */
734 if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
735 pDM_DigTable->ForbiddenIGI = CurrentIGI;
736 /* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */
737 pDM_DigTable->LargeFAHit = 1;
738 }
739
740 if (pDM_DigTable->LargeFAHit >= 3) {
741 if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max)
742 rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
743 else
744 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
745 pDM_DigTable->Recover_cnt = 1800;
746 }
747 } else {
748 if (pDM_DigTable->Recover_cnt != 0) {
749 pDM_DigTable->Recover_cnt--;
750 } else {
751 if (pDM_DigTable->LargeFAHit < 3) {
752 if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */
753 pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
754 rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
755 } else {
756 pDM_DigTable->ForbiddenIGI -= 2;
757 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
758 }
759 } else
760 pDM_DigTable->LargeFAHit = 0;
761 }
762 }
763
764 return rx_gain_range_min;
765
766 }
767
768 /* 3 ============================================================ */
769 /* 3 CCK Packet Detect Threshold */
770 /* 3 ============================================================ */
771
odm_CCKPacketDetectionThresh(void * pDM_VOID)772 void odm_CCKPacketDetectionThresh(void *pDM_VOID)
773 {
774 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
775 struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
776 u8 CurCCK_CCAThres;
777
778
779 if (
780 !(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) ||
781 !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)
782 ) {
783 return;
784 }
785
786 if (pDM_Odm->ExtLNA)
787 return;
788
789 if (pDM_Odm->bLinked) {
790 if (pDM_Odm->RSSI_Min > 25)
791 CurCCK_CCAThres = 0xcd;
792 else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10))
793 CurCCK_CCAThres = 0x83;
794 else {
795 if (FalseAlmCnt->Cnt_Cck_fail > 1000)
796 CurCCK_CCAThres = 0x83;
797 else
798 CurCCK_CCAThres = 0x40;
799 }
800 } else {
801 if (FalseAlmCnt->Cnt_Cck_fail > 1000)
802 CurCCK_CCAThres = 0x83;
803 else
804 CurCCK_CCAThres = 0x40;
805 }
806
807 ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres);
808 }
809
ODM_Write_CCK_CCA_Thres(void * pDM_VOID,u8 CurCCK_CCAThres)810 void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres)
811 {
812 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
813 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
814
815 /* modify by Guo.Mingzhi 2012-01-03 */
816 if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
817 rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres);
818
819 pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
820 pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
821 }
822