GNU Linux-libre 4.19.211-gnu1
[releases.git] / drivers / staging / rtl8723bs / hal / odm_DIG.c
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
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
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
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
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
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 /*  */
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
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
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
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
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
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
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
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         if (pDM_Odm->BoardType & (ODM_BOARD_EXT_PA|ODM_BOARD_EXT_LNA)) {
500                 pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
501                 pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
502         } else {
503                 pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
504                 pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
505         }
506
507 }
508
509
510 void odm_DIG(void *pDM_VOID)
511 {
512         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
513
514         /*  Common parameters */
515         pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
516         Pfalse_ALARM_STATISTICS pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
517         bool FirstConnect, FirstDisConnect;
518         u8 DIG_MaxOfMin, DIG_Dynamic_MIN;
519         u8 dm_dig_max, dm_dig_min;
520         u8 CurrentIGI = pDM_DigTable->CurIGValue;
521         u8 offset;
522         u32 dm_FA_thres[3];
523         u8 Adap_IGI_Upper = 0;
524         u32 TxTp = 0, RxTp = 0;
525         bool bDFSBand = false;
526         bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false;
527
528         if (odm_DigAbort(pDM_Odm) == true)
529                 return;
530
531         ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG() ===========================>\n\n"));
532
533         if (pDM_Odm->adaptivity_flag == true)
534                 Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper;
535
536
537         /* 1 Update status */
538         DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
539         FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == false);
540         FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == true);
541
542         /* 1 Boundary Decision */
543         /* 2 For WIN\CE */
544         dm_dig_max = 0x5A;
545         dm_dig_min = DM_DIG_MIN_NIC;
546         DIG_MaxOfMin = DM_DIG_MAX_AP;
547
548         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));
549
550         /* 1 Adjust boundary by RSSI */
551         if (pDM_Odm->bLinked && bPerformance) {
552                 /* 2 Modify DIG upper bound */
553                 /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
554                 if (pDM_Odm->bBtLimitedDig == 1) {
555                         offset = 10;
556                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Coex. case: Force upper bound to RSSI + %d !!!!!!\n", offset));
557                 } else
558                         offset = 15;
559
560                 if ((pDM_Odm->RSSI_Min + offset) > dm_dig_max)
561                         pDM_DigTable->rx_gain_range_max = dm_dig_max;
562                 else if ((pDM_Odm->RSSI_Min + offset) < dm_dig_min)
563                         pDM_DigTable->rx_gain_range_max = dm_dig_min;
564                 else
565                         pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset;
566
567                 /* 2 Modify DIG lower bound */
568                 /* if (pDM_Odm->bOneEntryOnly) */
569                 {
570                         if (pDM_Odm->RSSI_Min < dm_dig_min)
571                                 DIG_Dynamic_MIN = dm_dig_min;
572                         else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
573                                 DIG_Dynamic_MIN = DIG_MaxOfMin;
574                         else
575                                 DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
576                 }
577         } else {
578                 pDM_DigTable->rx_gain_range_max = dm_dig_max;
579                 DIG_Dynamic_MIN = dm_dig_min;
580         }
581
582         /* 1 Force Lower Bound for AntDiv */
583         if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) {
584                 if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
585                         if (
586                                 pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV ||
587                                 pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV ||
588                                 pDM_Odm->AntDivType == S0S1_SW_ANTDIV
589                         ) {
590                                 if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin)
591                                         DIG_Dynamic_MIN = DIG_MaxOfMin;
592                                 else
593                                         DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max;
594                                 ODM_RT_TRACE(
595                                         pDM_Odm,
596                                         ODM_COMP_ANT_DIV,
597                                         ODM_DBG_LOUD,
598                                         (
599                                                 "odm_DIG(): Antenna diversity case: Force lower bound to 0x%x !!!!!!\n",
600                                                 DIG_Dynamic_MIN
601                                         )
602                                 );
603                                 ODM_RT_TRACE(
604                                         pDM_Odm,
605                                         ODM_COMP_ANT_DIV,
606                                         ODM_DBG_LOUD,
607                                         (
608                                                 "odm_DIG(): Antenna diversity case: RSSI_max = 0x%x !!!!!!\n",
609                                                 pDM_DigTable->AntDiv_RSSI_max
610                                         )
611                                 );
612                         }
613                 }
614         }
615         ODM_RT_TRACE(
616                 pDM_Odm,
617                 ODM_COMP_DIG,
618                 ODM_DBG_LOUD,
619                 (
620                         "odm_DIG(): Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n",
621                         pDM_DigTable->rx_gain_range_max,
622                         DIG_Dynamic_MIN
623                 )
624         );
625         ODM_RT_TRACE(
626                 pDM_Odm,
627                 ODM_COMP_DIG,
628                 ODM_DBG_LOUD,
629                 (
630                         "odm_DIG(): Link status: bLinked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n\n",
631                         pDM_Odm->bLinked,
632                         pDM_Odm->RSSI_Min,
633                         FirstConnect,
634                         FirstDisConnect
635                 )
636         );
637
638         /* 1 Modify DIG lower bound, deal with abnormal case */
639         /* 2 Abnormal false alarm case */
640         if (FirstDisConnect) {
641                 pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN;
642                 pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN;
643         } else
644                 pDM_DigTable->rx_gain_range_min =
645                         odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI);
646
647         if (pDM_Odm->bLinked && !FirstConnect) {
648                 if (
649                         (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
650                         pDM_Odm->bsta_state
651                 ) {
652                         pDM_DigTable->rx_gain_range_min = dm_dig_min;
653                         ODM_RT_TRACE(
654                                 pDM_Odm,
655                                 ODM_COMP_DIG,
656                                 ODM_DBG_LOUD,
657                                 (
658                                         "odm_DIG(): Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x !!!!!!\n\n",
659                                         pDM_Odm->PhyDbgInfo.NumQryBeaconPkt,
660                                         pDM_DigTable->rx_gain_range_min
661                                 )
662                         );
663                 }
664         }
665
666         /* 2 Abnormal lower bound case */
667         if (pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) {
668                 pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
669                 ODM_RT_TRACE(
670                         pDM_Odm,
671                         ODM_COMP_DIG,
672                         ODM_DBG_LOUD,
673                         (
674                                 "odm_DIG(): Abnrormal lower bound case: Force lower bound to 0x%x !!!!!!\n\n",
675                                 pDM_DigTable->rx_gain_range_min
676                         )
677                 );
678         }
679
680
681         /* 1 False alarm threshold decision */
682         odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres);
683         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]));
684
685         /* 1 Adjust initial gain by false alarm */
686         if (pDM_Odm->bLinked && bPerformance) {
687                 /* 2 After link */
688                 ODM_RT_TRACE(
689                         pDM_Odm,
690                         ODM_COMP_DIG,
691                         ODM_DBG_LOUD,
692                         ("odm_DIG(): Adjust IGI after link\n")
693                 );
694
695                 if (bFirstTpTarget || (FirstConnect && bPerformance)) {
696                         pDM_DigTable->LargeFAHit = 0;
697
698                         if (pDM_Odm->RSSI_Min < DIG_MaxOfMin) {
699                                 if (CurrentIGI < pDM_Odm->RSSI_Min)
700                                         CurrentIGI = pDM_Odm->RSSI_Min;
701                         } else {
702                                 if (CurrentIGI < DIG_MaxOfMin)
703                                         CurrentIGI = DIG_MaxOfMin;
704                         }
705
706                         ODM_RT_TRACE(
707                                 pDM_Odm,
708                                 ODM_COMP_DIG,
709                                 ODM_DBG_LOUD,
710                                 (
711                                         "odm_DIG(): First connect case: IGI does on-shot to 0x%x\n",
712                                         CurrentIGI
713                                 )
714                         );
715
716                 } else {
717                         if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
718                                 CurrentIGI = CurrentIGI + 4;
719                         else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
720                                 CurrentIGI = CurrentIGI + 2;
721                         else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
722                                 CurrentIGI = CurrentIGI - 2;
723
724                         if (
725                                 (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
726                                 (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) &&
727                                 (pDM_Odm->bsta_state)
728                         ) {
729                                 CurrentIGI = pDM_DigTable->rx_gain_range_min;
730                                 ODM_RT_TRACE(
731                                         pDM_Odm,
732                                         ODM_COMP_DIG,
733                                         ODM_DBG_LOUD,
734                                         (
735                                                 "odm_DIG(): Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n",
736                                                 pDM_Odm->PhyDbgInfo.NumQryBeaconPkt,
737                                                 CurrentIGI
738                                         )
739                                 );
740                         }
741                 }
742         } else {
743                 /* 2 Before link */
744                 ODM_RT_TRACE(
745                         pDM_Odm,
746                         ODM_COMP_DIG,
747                         ODM_DBG_LOUD,
748                         ("odm_DIG(): Adjust IGI before link\n")
749                 );
750
751                 if (FirstDisConnect || bFirstCoverage) {
752                         CurrentIGI = dm_dig_min;
753                         ODM_RT_TRACE(
754                                 pDM_Odm,
755                                 ODM_COMP_DIG,
756                                 ODM_DBG_LOUD,
757                                 ("odm_DIG(): First disconnect case: IGI does on-shot to lower bound\n")
758                         );
759                 } else {
760                         if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
761                                 CurrentIGI = CurrentIGI + 4;
762                         else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
763                                 CurrentIGI = CurrentIGI + 2;
764                         else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
765                                 CurrentIGI = CurrentIGI - 2;
766                 }
767         }
768
769         /* 1 Check initial gain by upper/lower bound */
770         if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
771                 CurrentIGI = pDM_DigTable->rx_gain_range_min;
772
773         if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
774                 CurrentIGI = pDM_DigTable->rx_gain_range_max;
775
776         ODM_RT_TRACE(
777                 pDM_Odm,
778                 ODM_COMP_DIG,
779                 ODM_DBG_LOUD,
780                 (
781                         "odm_DIG(): CurIGValue = 0x%x, TotalFA = %d\n\n",
782                         CurrentIGI,
783                         pFalseAlmCnt->Cnt_all
784                 )
785         );
786
787         /* 1 Force upper bound and lower bound for adaptivity */
788         if (
789                 pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY &&
790                 pDM_Odm->adaptivity_flag == true
791         ) {
792                 if (CurrentIGI > Adap_IGI_Upper)
793                         CurrentIGI = Adap_IGI_Upper;
794
795                 if (pDM_Odm->IGI_LowerBound != 0) {
796                         if (CurrentIGI < pDM_Odm->IGI_LowerBound)
797                                 CurrentIGI = pDM_Odm->IGI_LowerBound;
798                 }
799                 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));
800                 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));
801         }
802
803
804         /* 1 Update status */
805         if (pDM_Odm->bBtHsOperation) {
806                 if (pDM_Odm->bLinked) {
807                         if (pDM_DigTable->BT30_CurIGI > (CurrentIGI))
808                                 ODM_Write_DIG(pDM_Odm, CurrentIGI);
809                         else
810                                 ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);
811
812                         pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
813                         pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
814                 } else {
815                         if (pDM_Odm->bLinkInProcess)
816                                 ODM_Write_DIG(pDM_Odm, 0x1c);
817                         else if (pDM_Odm->bBtConnectProcess)
818                                 ODM_Write_DIG(pDM_Odm, 0x28);
819                         else
820                                 ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
821                 }
822         } else { /*  BT is not using */
823                 ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
824                 pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
825                 pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
826         }
827 }
828
829 void odm_DIGbyRSSI_LPS(void *pDM_VOID)
830 {
831         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
832         Pfalse_ALARM_STATISTICS pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
833
834         u8 RSSI_Lower = DM_DIG_MIN_NIC;   /* 0x1E or 0x1C */
835         u8 CurrentIGI = pDM_Odm->RSSI_Min;
836
837         CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
838
839         ODM_RT_TRACE(
840                 pDM_Odm,
841                 ODM_COMP_DIG,
842                 ODM_DBG_LOUD,
843                 ("odm_DIGbyRSSI_LPS() ==>\n")
844         );
845
846         /*  Using FW PS mode to make IGI */
847         /* Adjust by  FA in LPS MODE */
848         if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS)
849                 CurrentIGI = CurrentIGI+4;
850         else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS)
851                 CurrentIGI = CurrentIGI+2;
852         else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS)
853                 CurrentIGI = CurrentIGI-2;
854
855
856         /* Lower bound checking */
857
858         /* RSSI Lower bound check */
859         if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC)
860                 RSSI_Lower = pDM_Odm->RSSI_Min-10;
861         else
862                 RSSI_Lower = DM_DIG_MIN_NIC;
863
864         /* Upper and Lower Bound checking */
865         if (CurrentIGI > DM_DIG_MAX_NIC)
866                 CurrentIGI = DM_DIG_MAX_NIC;
867         else if (CurrentIGI < RSSI_Lower)
868                 CurrentIGI = RSSI_Lower;
869
870
871         ODM_RT_TRACE(
872                 pDM_Odm,
873                 ODM_COMP_DIG,
874                 ODM_DBG_LOUD,
875                 ("odm_DIGbyRSSI_LPS(): pFalseAlmCnt->Cnt_all = %d\n", pFalseAlmCnt->Cnt_all)
876         );
877         ODM_RT_TRACE(
878                 pDM_Odm,
879                 ODM_COMP_DIG,
880                 ODM_DBG_LOUD,
881                 ("odm_DIGbyRSSI_LPS(): pDM_Odm->RSSI_Min = %d\n", pDM_Odm->RSSI_Min)
882         );
883         ODM_RT_TRACE(
884                 pDM_Odm,
885                 ODM_COMP_DIG,
886                 ODM_DBG_LOUD,
887                 ("odm_DIGbyRSSI_LPS(): CurrentIGI = 0x%x\n", CurrentIGI)
888         );
889
890         ODM_Write_DIG(pDM_Odm, CurrentIGI);
891         /* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
892 }
893
894 /* 3 ============================================================ */
895 /* 3 FASLE ALARM CHECK */
896 /* 3 ============================================================ */
897
898 void odm_FalseAlarmCounterStatistics(void *pDM_VOID)
899 {
900         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
901         Pfalse_ALARM_STATISTICS FalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
902         u32 ret_value;
903
904         if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
905                 return;
906
907         /* hold ofdm counter */
908         /* hold page C counter */
909         PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1);
910         /* hold page D counter */
911         PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1);
912
913         ret_value = PHY_QueryBBReg(
914                 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord
915         );
916         FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
917         FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16);
918
919         ret_value = PHY_QueryBBReg(
920                 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord
921         );
922         FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
923         FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
924
925         ret_value = PHY_QueryBBReg(
926                 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord
927         );
928         FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
929         FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
930
931         ret_value = PHY_QueryBBReg(
932                 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord
933         );
934         FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
935
936         FalseAlmCnt->Cnt_Ofdm_fail =
937                 FalseAlmCnt->Cnt_Parity_Fail +
938                 FalseAlmCnt->Cnt_Rate_Illegal +
939                 FalseAlmCnt->Cnt_Crc8_fail +
940                 FalseAlmCnt->Cnt_Mcs_fail +
941                 FalseAlmCnt->Cnt_Fast_Fsync +
942                 FalseAlmCnt->Cnt_SB_Search_fail;
943
944         {
945                 /* hold cck counter */
946                 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1);
947                 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1);
948
949                 ret_value = PHY_QueryBBReg(
950                         pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0
951                 );
952                 FalseAlmCnt->Cnt_Cck_fail = ret_value;
953
954                 ret_value = PHY_QueryBBReg(
955                         pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3
956                 );
957                 FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8;
958
959                 ret_value = PHY_QueryBBReg(
960                         pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord
961                 );
962                 FalseAlmCnt->Cnt_CCK_CCA =
963                         ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
964         }
965
966         FalseAlmCnt->Cnt_all = (
967                 FalseAlmCnt->Cnt_Fast_Fsync +
968                 FalseAlmCnt->Cnt_SB_Search_fail +
969                 FalseAlmCnt->Cnt_Parity_Fail +
970                 FalseAlmCnt->Cnt_Rate_Illegal +
971                 FalseAlmCnt->Cnt_Crc8_fail +
972                 FalseAlmCnt->Cnt_Mcs_fail +
973                 FalseAlmCnt->Cnt_Cck_fail
974         );
975
976         FalseAlmCnt->Cnt_CCA_all =
977                 FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
978
979         ODM_RT_TRACE(
980                 pDM_Odm,
981                 ODM_COMP_FA_CNT,
982                 ODM_DBG_LOUD,
983                 ("Enter odm_FalseAlarmCounterStatistics\n")
984         );
985         ODM_RT_TRACE(
986                 pDM_Odm,
987                 ODM_COMP_FA_CNT,
988                 ODM_DBG_LOUD,
989                 (
990                         "Cnt_Fast_Fsync =%d, Cnt_SB_Search_fail =%d\n",
991                         FalseAlmCnt->Cnt_Fast_Fsync,
992                         FalseAlmCnt->Cnt_SB_Search_fail
993                 )
994         );
995         ODM_RT_TRACE(
996                 pDM_Odm,
997                 ODM_COMP_FA_CNT,
998                 ODM_DBG_LOUD,
999                 (
1000                         "Cnt_Parity_Fail =%d, Cnt_Rate_Illegal =%d\n",
1001                         FalseAlmCnt->Cnt_Parity_Fail,
1002                         FalseAlmCnt->Cnt_Rate_Illegal
1003                 )
1004         );
1005         ODM_RT_TRACE(
1006                 pDM_Odm,
1007                 ODM_COMP_FA_CNT,
1008                 ODM_DBG_LOUD,
1009                 (
1010                         "Cnt_Crc8_fail =%d, Cnt_Mcs_fail =%d\n",
1011                         FalseAlmCnt->Cnt_Crc8_fail,
1012                         FalseAlmCnt->Cnt_Mcs_fail
1013                 )
1014         );
1015
1016         ODM_RT_TRACE(
1017                 pDM_Odm,
1018                 ODM_COMP_FA_CNT,
1019                 ODM_DBG_LOUD,
1020                 ("Cnt_OFDM_CCA =%d\n", FalseAlmCnt->Cnt_OFDM_CCA)
1021         );
1022         ODM_RT_TRACE(
1023                 pDM_Odm,
1024                 ODM_COMP_FA_CNT,
1025                 ODM_DBG_LOUD,
1026                 ("Cnt_CCK_CCA =%d\n", FalseAlmCnt->Cnt_CCK_CCA)
1027         );
1028         ODM_RT_TRACE(
1029                 pDM_Odm,
1030                 ODM_COMP_FA_CNT,
1031                 ODM_DBG_LOUD,
1032                 ("Cnt_CCA_all =%d\n", FalseAlmCnt->Cnt_CCA_all)
1033         );
1034         ODM_RT_TRACE(
1035                 pDM_Odm,
1036                 ODM_COMP_FA_CNT,
1037                 ODM_DBG_LOUD,
1038                 ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail)
1039         );
1040         ODM_RT_TRACE(
1041                 pDM_Odm,
1042                 ODM_COMP_FA_CNT,
1043                 ODM_DBG_LOUD,
1044                 ("Cnt_Cck_fail =%d\n",  FalseAlmCnt->Cnt_Cck_fail)
1045         );
1046         ODM_RT_TRACE(
1047                 pDM_Odm,
1048                 ODM_COMP_FA_CNT,
1049                 ODM_DBG_LOUD,
1050                 ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail)
1051         );
1052         ODM_RT_TRACE(
1053                 pDM_Odm,
1054                 ODM_COMP_FA_CNT,
1055                 ODM_DBG_LOUD,
1056                 ("Total False Alarm =%d\n",     FalseAlmCnt->Cnt_all)
1057         );
1058 }
1059
1060
1061 void odm_FAThresholdCheck(
1062         void *pDM_VOID,
1063         bool bDFSBand,
1064         bool bPerformance,
1065         u32 RxTp,
1066         u32 TxTp,
1067         u32 *dm_FA_thres
1068 )
1069 {
1070         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
1071
1072         if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) {
1073                 /*  For NIC */
1074                 dm_FA_thres[0] = DM_DIG_FA_TH0;
1075                 dm_FA_thres[1] = DM_DIG_FA_TH1;
1076                 dm_FA_thres[2] = DM_DIG_FA_TH2;
1077         } else {
1078                 dm_FA_thres[0] = 2000;
1079                 dm_FA_thres[1] = 4000;
1080                 dm_FA_thres[2] = 5000;
1081         }
1082         return;
1083 }
1084
1085 u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI)
1086 {
1087         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
1088         pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
1089         Pfalse_ALARM_STATISTICS pFalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
1090         u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min;
1091
1092         if (pFalseAlmCnt->Cnt_all > 10000) {
1093                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case.\n"));
1094
1095                 if (pDM_DigTable->LargeFAHit != 3)
1096                         pDM_DigTable->LargeFAHit++;
1097
1098                 /* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */
1099                 if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
1100                         pDM_DigTable->ForbiddenIGI = CurrentIGI;
1101                         /* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */
1102                         pDM_DigTable->LargeFAHit = 1;
1103                 }
1104
1105                 if (pDM_DigTable->LargeFAHit >= 3) {
1106                         if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max)
1107                                 rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
1108                         else
1109                                 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
1110                         pDM_DigTable->Recover_cnt = 1800;
1111                         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));
1112                 }
1113         } else {
1114                 if (pDM_DigTable->Recover_cnt != 0) {
1115                         pDM_DigTable->Recover_cnt--;
1116                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Recover_cnt = %d\n", pDM_DigTable->Recover_cnt));
1117                 } else {
1118                         if (pDM_DigTable->LargeFAHit < 3) {
1119                                 if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */
1120                                         pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
1121                                         rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
1122                                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: At Lower Bound\n"));
1123                                 } else {
1124                                         pDM_DigTable->ForbiddenIGI -= 2;
1125                                         rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
1126                                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Approach Lower Bound\n"));
1127                                 }
1128                         } else
1129                                 pDM_DigTable->LargeFAHit = 0;
1130                 }
1131         }
1132
1133         return rx_gain_range_min;
1134
1135 }
1136
1137 /* 3 ============================================================ */
1138 /* 3 CCK Packet Detect Threshold */
1139 /* 3 ============================================================ */
1140
1141 void odm_CCKPacketDetectionThresh(void *pDM_VOID)
1142 {
1143         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
1144         Pfalse_ALARM_STATISTICS FalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
1145         u8 CurCCK_CCAThres;
1146
1147
1148         if (
1149                 !(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) ||
1150                 !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)
1151         ) {
1152                 ODM_RT_TRACE(
1153                         pDM_Odm,
1154                         ODM_COMP_CCK_PD,
1155                         ODM_DBG_LOUD,
1156                         ("odm_CCKPacketDetectionThresh()  return ==========\n")
1157                 );
1158                 return;
1159         }
1160
1161         if (pDM_Odm->ExtLNA)
1162                 return;
1163
1164         ODM_RT_TRACE(
1165                 pDM_Odm,
1166                 ODM_COMP_CCK_PD,
1167                 ODM_DBG_LOUD,
1168                 ("odm_CCKPacketDetectionThresh()  ==========>\n")
1169         );
1170
1171         if (pDM_Odm->bLinked) {
1172                 if (pDM_Odm->RSSI_Min > 25)
1173                         CurCCK_CCAThres = 0xcd;
1174                 else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10))
1175                         CurCCK_CCAThres = 0x83;
1176                 else {
1177                         if (FalseAlmCnt->Cnt_Cck_fail > 1000)
1178                                 CurCCK_CCAThres = 0x83;
1179                         else
1180                                 CurCCK_CCAThres = 0x40;
1181                 }
1182         } else {
1183                 if (FalseAlmCnt->Cnt_Cck_fail > 1000)
1184                         CurCCK_CCAThres = 0x83;
1185                 else
1186                         CurCCK_CCAThres = 0x40;
1187         }
1188
1189         ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres);
1190
1191         ODM_RT_TRACE(
1192                 pDM_Odm,
1193                 ODM_COMP_CCK_PD,
1194                 ODM_DBG_LOUD,
1195                 (
1196                         "odm_CCKPacketDetectionThresh()  CurCCK_CCAThres = 0x%x\n",
1197                         CurCCK_CCAThres
1198                 )
1199         );
1200 }
1201
1202 void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres)
1203 {
1204         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
1205         pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
1206
1207         /* modify by Guo.Mingzhi 2012-01-03 */
1208         if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
1209                 rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres);
1210
1211         pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
1212         pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
1213 }