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