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