158391efdSNathan Chancellor // SPDX-License-Identifier: GPL-2.0
2554c0a3aSHans de Goede /******************************************************************************
3554c0a3aSHans de Goede *
4554c0a3aSHans de Goede * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5554c0a3aSHans de Goede *
6554c0a3aSHans de Goede ******************************************************************************/
7554c0a3aSHans de Goede
8554c0a3aSHans de Goede #include "odm_precomp.h"
9554c0a3aSHans de Goede
odm_NHMCounterStatisticsInit(void * pDM_VOID)10554c0a3aSHans de Goede void odm_NHMCounterStatisticsInit(void *pDM_VOID)
11554c0a3aSHans de Goede {
12f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
13554c0a3aSHans de Goede
14554c0a3aSHans de Goede /* PHY parameters initialize for n series */
15554c0a3aSHans de Goede rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x2710); /* 0x894[31:16]= 0x2710 Time duration for NHM unit: 4us, 0x2710 =40ms */
16554c0a3aSHans de Goede /* rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x4e20); 0x894[31:16]= 0x4e20 Time duration for NHM unit: 4us, 0x4e20 =80ms */
17554c0a3aSHans de Goede rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff); /* 0x890[31:16]= 0xffff th_9, th_10 */
18554c0a3aSHans de Goede /* rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff5c); 0x898 = 0xffffff5c th_3, th_2, th_1, th_0 */
19554c0a3aSHans de Goede rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff52); /* 0x898 = 0xffffff52 th_3, th_2, th_1, th_0 */
20554c0a3aSHans de Goede rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff); /* 0x89c = 0xffffffff th_7, th_6, th_5, th_4 */
21554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff); /* 0xe28[7:0]= 0xff th_8 */
22554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x7); /* 0x890[9:8]=3 enable CCX */
23554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1); /* 0xc0c[7]= 1 max power among all RX ants */
24554c0a3aSHans de Goede }
25554c0a3aSHans de Goede
odm_NHMCounterStatistics(void * pDM_VOID)26554c0a3aSHans de Goede void odm_NHMCounterStatistics(void *pDM_VOID)
27554c0a3aSHans de Goede {
28f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
29554c0a3aSHans de Goede
30554c0a3aSHans de Goede /* Get NHM report */
31554c0a3aSHans de Goede odm_GetNHMCounterStatistics(pDM_Odm);
32554c0a3aSHans de Goede
33554c0a3aSHans de Goede /* Reset NHM counter */
34554c0a3aSHans de Goede odm_NHMCounterStatisticsReset(pDM_Odm);
35554c0a3aSHans de Goede }
36554c0a3aSHans de Goede
odm_GetNHMCounterStatistics(void * pDM_VOID)37554c0a3aSHans de Goede void odm_GetNHMCounterStatistics(void *pDM_VOID)
38554c0a3aSHans de Goede {
39f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
40554c0a3aSHans de Goede u32 value32 = 0;
41554c0a3aSHans de Goede
42554c0a3aSHans de Goede value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_NHM_CNT_11N, bMaskDWord);
43554c0a3aSHans de Goede
44554c0a3aSHans de Goede pDM_Odm->NHM_cnt_0 = (u8)(value32 & bMaskByte0);
45554c0a3aSHans de Goede }
46554c0a3aSHans de Goede
odm_NHMCounterStatisticsReset(void * pDM_VOID)47554c0a3aSHans de Goede void odm_NHMCounterStatisticsReset(void *pDM_VOID)
48554c0a3aSHans de Goede {
49f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
50554c0a3aSHans de Goede
51554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 0);
52554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 1);
53554c0a3aSHans de Goede }
54554c0a3aSHans de Goede
odm_NHMBBInit(void * pDM_VOID)55554c0a3aSHans de Goede void odm_NHMBBInit(void *pDM_VOID)
56554c0a3aSHans de Goede {
57f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
58554c0a3aSHans de Goede
59554c0a3aSHans de Goede pDM_Odm->adaptivity_flag = 0;
60554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 3;
61554c0a3aSHans de Goede pDM_Odm->NHMLastTxOkcnt = 0;
62554c0a3aSHans de Goede pDM_Odm->NHMLastRxOkcnt = 0;
63554c0a3aSHans de Goede pDM_Odm->NHMCurTxOkcnt = 0;
64554c0a3aSHans de Goede pDM_Odm->NHMCurRxOkcnt = 0;
65554c0a3aSHans de Goede }
66554c0a3aSHans de Goede
67554c0a3aSHans de Goede /* */
odm_NHMBB(void * pDM_VOID)68554c0a3aSHans de Goede void odm_NHMBB(void *pDM_VOID)
69554c0a3aSHans de Goede {
70f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
71554c0a3aSHans de Goede /* u8 test_status; */
72db07a1caSMarco Cesati /* struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; */
73554c0a3aSHans de Goede
74554c0a3aSHans de Goede pDM_Odm->NHMCurTxOkcnt =
75554c0a3aSHans de Goede *(pDM_Odm->pNumTxBytesUnicast)-pDM_Odm->NHMLastTxOkcnt;
76554c0a3aSHans de Goede pDM_Odm->NHMCurRxOkcnt =
77554c0a3aSHans de Goede *(pDM_Odm->pNumRxBytesUnicast)-pDM_Odm->NHMLastRxOkcnt;
78554c0a3aSHans de Goede pDM_Odm->NHMLastTxOkcnt =
79554c0a3aSHans de Goede *(pDM_Odm->pNumTxBytesUnicast);
80554c0a3aSHans de Goede pDM_Odm->NHMLastRxOkcnt =
81554c0a3aSHans de Goede *(pDM_Odm->pNumRxBytesUnicast);
82554c0a3aSHans de Goede
83554c0a3aSHans de Goede
84554c0a3aSHans de Goede if ((pDM_Odm->NHMCurTxOkcnt) + 1 > (u64)(pDM_Odm->NHMCurRxOkcnt<<2) + 1) { /* Tx > 4*Rx possible for adaptivity test */
85554c0a3aSHans de Goede if (pDM_Odm->NHM_cnt_0 >= 190 || pDM_Odm->adaptivity_flag == true) {
86554c0a3aSHans de Goede /* Enable EDCCA since it is possible running Adaptivity testing */
87554c0a3aSHans de Goede /* test_status = 1; */
88554c0a3aSHans de Goede pDM_Odm->adaptivity_flag = true;
89554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 0;
90554c0a3aSHans de Goede } else {
91554c0a3aSHans de Goede if (pDM_Odm->tolerance_cnt < 3)
92554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
93554c0a3aSHans de Goede else
94554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 4;
95554c0a3aSHans de Goede /* test_status = 5; */
96554c0a3aSHans de Goede if (pDM_Odm->tolerance_cnt > 3) {
97554c0a3aSHans de Goede /* test_status = 3; */
98554c0a3aSHans de Goede pDM_Odm->adaptivity_flag = false;
99554c0a3aSHans de Goede }
100554c0a3aSHans de Goede }
101554c0a3aSHans de Goede } else { /* TX<RX */
102554c0a3aSHans de Goede if (pDM_Odm->adaptivity_flag == true && pDM_Odm->NHM_cnt_0 <= 200) {
103554c0a3aSHans de Goede /* test_status = 2; */
104554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 0;
105554c0a3aSHans de Goede } else {
106554c0a3aSHans de Goede if (pDM_Odm->tolerance_cnt < 3)
107554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
108554c0a3aSHans de Goede else
109554c0a3aSHans de Goede pDM_Odm->tolerance_cnt = 4;
110554c0a3aSHans de Goede /* test_status = 5; */
111554c0a3aSHans de Goede if (pDM_Odm->tolerance_cnt > 3) {
112554c0a3aSHans de Goede /* test_status = 4; */
113554c0a3aSHans de Goede pDM_Odm->adaptivity_flag = false;
114554c0a3aSHans de Goede }
115554c0a3aSHans de Goede }
116554c0a3aSHans de Goede }
117554c0a3aSHans de Goede }
118554c0a3aSHans de Goede
odm_SearchPwdBLowerBound(void * pDM_VOID,u8 IGI_target)119554c0a3aSHans de Goede void odm_SearchPwdBLowerBound(void *pDM_VOID, u8 IGI_target)
120554c0a3aSHans de Goede {
121f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
122554c0a3aSHans de Goede u32 value32 = 0;
123554c0a3aSHans de Goede u8 cnt, IGI;
124554c0a3aSHans de Goede bool bAdjust = true;
125554c0a3aSHans de Goede s8 TH_L2H_dmc, TH_H2L_dmc;
126554c0a3aSHans de Goede s8 Diff;
127554c0a3aSHans de Goede
128554c0a3aSHans de Goede IGI = 0x50; /* find H2L, L2H lower bound */
129554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, IGI);
130554c0a3aSHans de Goede
131554c0a3aSHans de Goede
132554c0a3aSHans de Goede Diff = IGI_target-(s8)IGI;
133554c0a3aSHans de Goede TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
134554c0a3aSHans de Goede if (TH_L2H_dmc > 10)
135554c0a3aSHans de Goede TH_L2H_dmc = 10;
136554c0a3aSHans de Goede TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
137554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
138554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
139554c0a3aSHans de Goede
140554c0a3aSHans de Goede mdelay(5);
141554c0a3aSHans de Goede
142554c0a3aSHans de Goede while (bAdjust) {
143554c0a3aSHans de Goede for (cnt = 0; cnt < 20; cnt++) {
144554c0a3aSHans de Goede value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_RPT_11N, bMaskDWord);
145554c0a3aSHans de Goede
146554c0a3aSHans de Goede if (value32 & BIT30)
147554c0a3aSHans de Goede pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
148554c0a3aSHans de Goede else if (value32 & BIT29)
149554c0a3aSHans de Goede pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
150554c0a3aSHans de Goede else
151554c0a3aSHans de Goede pDM_Odm->txEdcca0 = pDM_Odm->txEdcca0 + 1;
152554c0a3aSHans de Goede }
153554c0a3aSHans de Goede
154554c0a3aSHans de Goede if (pDM_Odm->txEdcca1 > 5) {
155554c0a3aSHans de Goede IGI = IGI-1;
156554c0a3aSHans de Goede TH_L2H_dmc = TH_L2H_dmc + 1;
157554c0a3aSHans de Goede if (TH_L2H_dmc > 10)
158554c0a3aSHans de Goede TH_L2H_dmc = 10;
159554c0a3aSHans de Goede TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
160554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
161554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
162554c0a3aSHans de Goede
163554c0a3aSHans de Goede pDM_Odm->TxHangFlg = true;
164554c0a3aSHans de Goede pDM_Odm->txEdcca1 = 0;
165554c0a3aSHans de Goede pDM_Odm->txEdcca0 = 0;
166554c0a3aSHans de Goede
167554c0a3aSHans de Goede if (TH_L2H_dmc == 10) {
168554c0a3aSHans de Goede bAdjust = false;
169554c0a3aSHans de Goede pDM_Odm->TxHangFlg = false;
170554c0a3aSHans de Goede pDM_Odm->txEdcca1 = 0;
171554c0a3aSHans de Goede pDM_Odm->txEdcca0 = 0;
172554c0a3aSHans de Goede pDM_Odm->H2L_lb = TH_H2L_dmc;
173554c0a3aSHans de Goede pDM_Odm->L2H_lb = TH_L2H_dmc;
174554c0a3aSHans de Goede pDM_Odm->Adaptivity_IGI_upper = IGI;
175554c0a3aSHans de Goede }
176554c0a3aSHans de Goede } else {
177554c0a3aSHans de Goede bAdjust = false;
178554c0a3aSHans de Goede pDM_Odm->TxHangFlg = false;
179554c0a3aSHans de Goede pDM_Odm->txEdcca1 = 0;
180554c0a3aSHans de Goede pDM_Odm->txEdcca0 = 0;
181554c0a3aSHans de Goede pDM_Odm->H2L_lb = TH_H2L_dmc;
182554c0a3aSHans de Goede pDM_Odm->L2H_lb = TH_L2H_dmc;
183554c0a3aSHans de Goede pDM_Odm->Adaptivity_IGI_upper = IGI;
184554c0a3aSHans de Goede }
185554c0a3aSHans de Goede }
186554c0a3aSHans de Goede }
187554c0a3aSHans de Goede
odm_AdaptivityInit(void * pDM_VOID)188554c0a3aSHans de Goede void odm_AdaptivityInit(void *pDM_VOID)
189554c0a3aSHans de Goede {
190f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
191554c0a3aSHans de Goede
192554c0a3aSHans de Goede if (pDM_Odm->Carrier_Sense_enable == false)
193554c0a3aSHans de Goede pDM_Odm->TH_L2H_ini = 0xf7; /* -7 */
194554c0a3aSHans de Goede else
195554c0a3aSHans de Goede pDM_Odm->TH_L2H_ini = 0xa;
196554c0a3aSHans de Goede
197554c0a3aSHans de Goede pDM_Odm->AdapEn_RSSI = 20;
198554c0a3aSHans de Goede pDM_Odm->TH_EDCCA_HL_diff = 7;
199554c0a3aSHans de Goede
200554c0a3aSHans de Goede pDM_Odm->IGI_Base = 0x32;
201554c0a3aSHans de Goede pDM_Odm->IGI_target = 0x1c;
202554c0a3aSHans de Goede pDM_Odm->ForceEDCCA = 0;
203554c0a3aSHans de Goede pDM_Odm->NHM_disable = false;
204554c0a3aSHans de Goede pDM_Odm->TxHangFlg = true;
205554c0a3aSHans de Goede pDM_Odm->txEdcca0 = 0;
206554c0a3aSHans de Goede pDM_Odm->txEdcca1 = 0;
207554c0a3aSHans de Goede pDM_Odm->H2L_lb = 0;
208554c0a3aSHans de Goede pDM_Odm->L2H_lb = 0;
209554c0a3aSHans de Goede pDM_Odm->Adaptivity_IGI_upper = 0;
210554c0a3aSHans de Goede odm_NHMBBInit(pDM_Odm);
211554c0a3aSHans de Goede
212554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, REG_RD_CTRL, BIT11, 1); /* stop counting if EDCCA is asserted */
213554c0a3aSHans de Goede }
214554c0a3aSHans de Goede
215554c0a3aSHans de Goede
odm_Adaptivity(void * pDM_VOID,u8 IGI)216554c0a3aSHans de Goede void odm_Adaptivity(void *pDM_VOID, u8 IGI)
217554c0a3aSHans de Goede {
218f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
219554c0a3aSHans de Goede s8 TH_L2H_dmc, TH_H2L_dmc;
220554c0a3aSHans de Goede s8 Diff, IGI_target;
221554c0a3aSHans de Goede bool EDCCA_State = false;
222554c0a3aSHans de Goede
223554c0a3aSHans de Goede if (!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) {
224554c0a3aSHans de Goede return;
225554c0a3aSHans de Goede }
226554c0a3aSHans de Goede
227554c0a3aSHans de Goede if (*pDM_Odm->pBandWidth == ODM_BW20M) /* CHANNEL_WIDTH_20 */
228554c0a3aSHans de Goede IGI_target = pDM_Odm->IGI_Base;
229554c0a3aSHans de Goede else if (*pDM_Odm->pBandWidth == ODM_BW40M)
230554c0a3aSHans de Goede IGI_target = pDM_Odm->IGI_Base + 2;
231554c0a3aSHans de Goede else
232554c0a3aSHans de Goede IGI_target = pDM_Odm->IGI_Base;
233554c0a3aSHans de Goede pDM_Odm->IGI_target = (u8) IGI_target;
234554c0a3aSHans de Goede
235554c0a3aSHans de Goede /* Search pwdB lower bound */
236554c0a3aSHans de Goede if (pDM_Odm->TxHangFlg == true) {
237554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208);
238554c0a3aSHans de Goede odm_SearchPwdBLowerBound(pDM_Odm, pDM_Odm->IGI_target);
239554c0a3aSHans de Goede }
240554c0a3aSHans de Goede
241554c0a3aSHans de Goede if ((!pDM_Odm->bLinked) || (*pDM_Odm->pChannel > 149)) { /* Band4 doesn't need adaptivity */
242554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, 0x7f);
243554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, 0x7f);
244554c0a3aSHans de Goede return;
245554c0a3aSHans de Goede }
246554c0a3aSHans de Goede
247554c0a3aSHans de Goede if (!pDM_Odm->ForceEDCCA) {
248554c0a3aSHans de Goede if (pDM_Odm->RSSI_Min > pDM_Odm->AdapEn_RSSI)
2497bb0dffdSsimran singhal EDCCA_State = true;
250554c0a3aSHans de Goede else if (pDM_Odm->RSSI_Min < (pDM_Odm->AdapEn_RSSI - 5))
2517bb0dffdSsimran singhal EDCCA_State = false;
252554c0a3aSHans de Goede } else
2537bb0dffdSsimran singhal EDCCA_State = true;
254554c0a3aSHans de Goede
255554c0a3aSHans de Goede if (
256554c0a3aSHans de Goede pDM_Odm->bLinked &&
257554c0a3aSHans de Goede pDM_Odm->Carrier_Sense_enable == false &&
258554c0a3aSHans de Goede pDM_Odm->NHM_disable == false &&
259554c0a3aSHans de Goede pDM_Odm->TxHangFlg == false
260554c0a3aSHans de Goede )
261554c0a3aSHans de Goede odm_NHMBB(pDM_Odm);
262554c0a3aSHans de Goede
2637bb0dffdSsimran singhal if (EDCCA_State) {
264554c0a3aSHans de Goede Diff = IGI_target-(s8)IGI;
265554c0a3aSHans de Goede TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
266554c0a3aSHans de Goede if (TH_L2H_dmc > 10)
267554c0a3aSHans de Goede TH_L2H_dmc = 10;
268554c0a3aSHans de Goede
269554c0a3aSHans de Goede TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
270554c0a3aSHans de Goede
271554c0a3aSHans de Goede /* replace lower bound to prevent EDCCA always equal */
272554c0a3aSHans de Goede if (TH_H2L_dmc < pDM_Odm->H2L_lb)
273554c0a3aSHans de Goede TH_H2L_dmc = pDM_Odm->H2L_lb;
274554c0a3aSHans de Goede if (TH_L2H_dmc < pDM_Odm->L2H_lb)
275554c0a3aSHans de Goede TH_L2H_dmc = pDM_Odm->L2H_lb;
276554c0a3aSHans de Goede } else {
277554c0a3aSHans de Goede TH_L2H_dmc = 0x7f;
278554c0a3aSHans de Goede TH_H2L_dmc = 0x7f;
279554c0a3aSHans de Goede }
280554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
281554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
282554c0a3aSHans de Goede }
283554c0a3aSHans de Goede
ODM_Write_DIG(void * pDM_VOID,u8 CurrentIGI)284554c0a3aSHans de Goede void ODM_Write_DIG(void *pDM_VOID, u8 CurrentIGI)
285554c0a3aSHans de Goede {
286f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
28786d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
288554c0a3aSHans de Goede
289554c0a3aSHans de Goede if (pDM_DigTable->bStopDIG) {
290554c0a3aSHans de Goede return;
291554c0a3aSHans de Goede }
292554c0a3aSHans de Goede
293554c0a3aSHans de Goede if (pDM_DigTable->CurIGValue != CurrentIGI) {
294554c0a3aSHans de Goede /* 1 Check initial gain by upper bound */
295554c0a3aSHans de Goede if (!pDM_DigTable->bPSDInProgress) {
296554c0a3aSHans de Goede if (CurrentIGI > pDM_DigTable->rx_gain_range_max) {
297554c0a3aSHans de Goede CurrentIGI = pDM_DigTable->rx_gain_range_max;
298554c0a3aSHans de Goede }
299554c0a3aSHans de Goede
300554c0a3aSHans de Goede }
301554c0a3aSHans de Goede
302554c0a3aSHans de Goede /* 1 Set IGI value */
303554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
304554c0a3aSHans de Goede
305554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
306554c0a3aSHans de Goede
307554c0a3aSHans de Goede pDM_DigTable->CurIGValue = CurrentIGI;
308554c0a3aSHans de Goede }
309554c0a3aSHans de Goede
310554c0a3aSHans de Goede }
311554c0a3aSHans de Goede
odm_DigAbort(void * pDM_VOID)312554c0a3aSHans de Goede bool odm_DigAbort(void *pDM_VOID)
313554c0a3aSHans de Goede {
314f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
315554c0a3aSHans de Goede
316554c0a3aSHans de Goede /* SupportAbility */
317554c0a3aSHans de Goede if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) {
318554c0a3aSHans de Goede return true;
319554c0a3aSHans de Goede }
320554c0a3aSHans de Goede
321554c0a3aSHans de Goede /* SupportAbility */
322554c0a3aSHans de Goede if (!(pDM_Odm->SupportAbility & ODM_BB_DIG)) {
323554c0a3aSHans de Goede return true;
324554c0a3aSHans de Goede }
325554c0a3aSHans de Goede
326554c0a3aSHans de Goede /* ScanInProcess */
327554c0a3aSHans de Goede if (*(pDM_Odm->pbScanInProcess)) {
328554c0a3aSHans de Goede return true;
329554c0a3aSHans de Goede }
330554c0a3aSHans de Goede
331554c0a3aSHans de Goede /* add by Neil Chen to avoid PSD is processing */
332554c0a3aSHans de Goede if (pDM_Odm->bDMInitialGainEnable == false) {
333554c0a3aSHans de Goede return true;
334554c0a3aSHans de Goede }
335554c0a3aSHans de Goede
336554c0a3aSHans de Goede return false;
337554c0a3aSHans de Goede }
338554c0a3aSHans de Goede
odm_DIGInit(void * pDM_VOID)339554c0a3aSHans de Goede void odm_DIGInit(void *pDM_VOID)
340554c0a3aSHans de Goede {
341f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
34286d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
343554c0a3aSHans de Goede
344554c0a3aSHans de Goede pDM_DigTable->bStopDIG = false;
345554c0a3aSHans de Goede pDM_DigTable->bPSDInProgress = false;
346554c0a3aSHans de Goede pDM_DigTable->CurIGValue = (u8) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm));
347554c0a3aSHans de Goede pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW;
348554c0a3aSHans de Goede pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH;
349554c0a3aSHans de Goede pDM_DigTable->FALowThresh = DMfalseALARM_THRESH_LOW;
350554c0a3aSHans de Goede pDM_DigTable->FAHighThresh = DMfalseALARM_THRESH_HIGH;
351554c0a3aSHans de Goede pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT;
352554c0a3aSHans de Goede pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
353554c0a3aSHans de Goede pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
354554c0a3aSHans de Goede pDM_DigTable->PreCCK_CCAThres = 0xFF;
355554c0a3aSHans de Goede pDM_DigTable->CurCCK_CCAThres = 0x83;
356554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC;
357554c0a3aSHans de Goede pDM_DigTable->LargeFAHit = 0;
358554c0a3aSHans de Goede pDM_DigTable->Recover_cnt = 0;
359554c0a3aSHans de Goede pDM_DigTable->bMediaConnect_0 = false;
360554c0a3aSHans de Goede pDM_DigTable->bMediaConnect_1 = false;
361554c0a3aSHans de Goede
362554c0a3aSHans de Goede /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */
363554c0a3aSHans de Goede pDM_Odm->bDMInitialGainEnable = true;
364554c0a3aSHans de Goede
365554c0a3aSHans de Goede pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC;
366554c0a3aSHans de Goede pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC;
367554c0a3aSHans de Goede
368554c0a3aSHans de Goede /* To Initi BT30 IGI */
369554c0a3aSHans de Goede pDM_DigTable->BT30_CurIGI = 0x32;
370554c0a3aSHans de Goede
371554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
372554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
373554c0a3aSHans de Goede
374554c0a3aSHans de Goede }
375554c0a3aSHans de Goede
376554c0a3aSHans de Goede
odm_DIG(void * pDM_VOID)377554c0a3aSHans de Goede void odm_DIG(void *pDM_VOID)
378554c0a3aSHans de Goede {
379f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
380554c0a3aSHans de Goede
381554c0a3aSHans de Goede /* Common parameters */
38286d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
383d7c2b41fSMarco Cesati struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
384554c0a3aSHans de Goede bool FirstConnect, FirstDisConnect;
385554c0a3aSHans de Goede u8 DIG_MaxOfMin, DIG_Dynamic_MIN;
386554c0a3aSHans de Goede u8 dm_dig_max, dm_dig_min;
387554c0a3aSHans de Goede u8 CurrentIGI = pDM_DigTable->CurIGValue;
388554c0a3aSHans de Goede u8 offset;
389554c0a3aSHans de Goede u32 dm_FA_thres[3];
390554c0a3aSHans de Goede u8 Adap_IGI_Upper = 0;
391554c0a3aSHans de Goede u32 TxTp = 0, RxTp = 0;
392554c0a3aSHans de Goede bool bDFSBand = false;
393554c0a3aSHans de Goede bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false;
394554c0a3aSHans de Goede
395941add8eSPuranjay Mohan if (odm_DigAbort(pDM_Odm))
396554c0a3aSHans de Goede return;
397554c0a3aSHans de Goede
398554c0a3aSHans de Goede if (pDM_Odm->adaptivity_flag == true)
399554c0a3aSHans de Goede Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper;
400554c0a3aSHans de Goede
401554c0a3aSHans de Goede
402554c0a3aSHans de Goede /* 1 Update status */
403554c0a3aSHans de Goede DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
404554c0a3aSHans de Goede FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == false);
405554c0a3aSHans de Goede FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == true);
406554c0a3aSHans de Goede
407554c0a3aSHans de Goede /* 1 Boundary Decision */
408554c0a3aSHans de Goede /* 2 For WIN\CE */
409554c0a3aSHans de Goede dm_dig_max = 0x5A;
410554c0a3aSHans de Goede dm_dig_min = DM_DIG_MIN_NIC;
411554c0a3aSHans de Goede DIG_MaxOfMin = DM_DIG_MAX_AP;
412554c0a3aSHans de Goede
413554c0a3aSHans de Goede /* 1 Adjust boundary by RSSI */
414554c0a3aSHans de Goede if (pDM_Odm->bLinked && bPerformance) {
415554c0a3aSHans de Goede /* 2 Modify DIG upper bound */
416554c0a3aSHans de Goede /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
417554c0a3aSHans de Goede if (pDM_Odm->bBtLimitedDig == 1) {
418554c0a3aSHans de Goede offset = 10;
419554c0a3aSHans de Goede } else
420554c0a3aSHans de Goede offset = 15;
421554c0a3aSHans de Goede
422554c0a3aSHans de Goede if ((pDM_Odm->RSSI_Min + offset) > dm_dig_max)
423554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = dm_dig_max;
424554c0a3aSHans de Goede else if ((pDM_Odm->RSSI_Min + offset) < dm_dig_min)
425554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = dm_dig_min;
426554c0a3aSHans de Goede else
427554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset;
428554c0a3aSHans de Goede
429554c0a3aSHans de Goede /* 2 Modify DIG lower bound */
430554c0a3aSHans de Goede /* if (pDM_Odm->bOneEntryOnly) */
431554c0a3aSHans de Goede {
432554c0a3aSHans de Goede if (pDM_Odm->RSSI_Min < dm_dig_min)
433554c0a3aSHans de Goede DIG_Dynamic_MIN = dm_dig_min;
434554c0a3aSHans de Goede else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
435554c0a3aSHans de Goede DIG_Dynamic_MIN = DIG_MaxOfMin;
436554c0a3aSHans de Goede else
437554c0a3aSHans de Goede DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
438554c0a3aSHans de Goede }
439554c0a3aSHans de Goede } else {
440554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_max = dm_dig_max;
441554c0a3aSHans de Goede DIG_Dynamic_MIN = dm_dig_min;
442554c0a3aSHans de Goede }
443554c0a3aSHans de Goede
444554c0a3aSHans de Goede /* 1 Force Lower Bound for AntDiv */
445554c0a3aSHans de Goede if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) {
446554c0a3aSHans de Goede if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
447554c0a3aSHans de Goede if (
448554c0a3aSHans de Goede pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV ||
449554c0a3aSHans de Goede pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV ||
450554c0a3aSHans de Goede pDM_Odm->AntDivType == S0S1_SW_ANTDIV
451554c0a3aSHans de Goede ) {
452554c0a3aSHans de Goede if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin)
453554c0a3aSHans de Goede DIG_Dynamic_MIN = DIG_MaxOfMin;
454554c0a3aSHans de Goede else
455554c0a3aSHans de Goede DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max;
456554c0a3aSHans de Goede }
457554c0a3aSHans de Goede }
458554c0a3aSHans de Goede }
459554c0a3aSHans de Goede
460554c0a3aSHans de Goede /* 1 Modify DIG lower bound, deal with abnormal case */
461554c0a3aSHans de Goede /* 2 Abnormal false alarm case */
462554c0a3aSHans de Goede if (FirstDisConnect) {
463554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN;
464554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN;
465554c0a3aSHans de Goede } else
466554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min =
467554c0a3aSHans de Goede odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI);
468554c0a3aSHans de Goede
469554c0a3aSHans de Goede if (pDM_Odm->bLinked && !FirstConnect) {
470554c0a3aSHans de Goede if (
471554c0a3aSHans de Goede (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
472554c0a3aSHans de Goede pDM_Odm->bsta_state
473554c0a3aSHans de Goede ) {
474554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = dm_dig_min;
475554c0a3aSHans de Goede }
476554c0a3aSHans de Goede }
477554c0a3aSHans de Goede
478554c0a3aSHans de Goede /* 2 Abnormal lower bound case */
479554c0a3aSHans de Goede if (pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) {
480554c0a3aSHans de Goede pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
481554c0a3aSHans de Goede }
482554c0a3aSHans de Goede
483554c0a3aSHans de Goede
484554c0a3aSHans de Goede /* 1 False alarm threshold decision */
485554c0a3aSHans de Goede odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres);
486554c0a3aSHans de Goede
487554c0a3aSHans de Goede /* 1 Adjust initial gain by false alarm */
488554c0a3aSHans de Goede if (pDM_Odm->bLinked && bPerformance) {
489554c0a3aSHans de Goede
49098f668b3SSaurav Girepunje if (bFirstTpTarget || FirstConnect) {
491554c0a3aSHans de Goede pDM_DigTable->LargeFAHit = 0;
492554c0a3aSHans de Goede
493554c0a3aSHans de Goede if (pDM_Odm->RSSI_Min < DIG_MaxOfMin) {
494554c0a3aSHans de Goede if (CurrentIGI < pDM_Odm->RSSI_Min)
495554c0a3aSHans de Goede CurrentIGI = pDM_Odm->RSSI_Min;
496554c0a3aSHans de Goede } else {
497554c0a3aSHans de Goede if (CurrentIGI < DIG_MaxOfMin)
498554c0a3aSHans de Goede CurrentIGI = DIG_MaxOfMin;
499554c0a3aSHans de Goede }
500554c0a3aSHans de Goede
501554c0a3aSHans de Goede } else {
502554c0a3aSHans de Goede if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
503554c0a3aSHans de Goede CurrentIGI = CurrentIGI + 4;
504554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
505554c0a3aSHans de Goede CurrentIGI = CurrentIGI + 2;
506554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
507554c0a3aSHans de Goede CurrentIGI = CurrentIGI - 2;
508554c0a3aSHans de Goede
509554c0a3aSHans de Goede if (
510554c0a3aSHans de Goede (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
511554c0a3aSHans de Goede (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) &&
512554c0a3aSHans de Goede (pDM_Odm->bsta_state)
513554c0a3aSHans de Goede ) {
514554c0a3aSHans de Goede CurrentIGI = pDM_DigTable->rx_gain_range_min;
515554c0a3aSHans de Goede }
516554c0a3aSHans de Goede }
517554c0a3aSHans de Goede } else {
518554c0a3aSHans de Goede
519554c0a3aSHans de Goede if (FirstDisConnect || bFirstCoverage) {
520554c0a3aSHans de Goede CurrentIGI = dm_dig_min;
521554c0a3aSHans de Goede } else {
522554c0a3aSHans de Goede if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
523554c0a3aSHans de Goede CurrentIGI = CurrentIGI + 4;
524554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
525554c0a3aSHans de Goede CurrentIGI = CurrentIGI + 2;
526554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
527554c0a3aSHans de Goede CurrentIGI = CurrentIGI - 2;
528554c0a3aSHans de Goede }
529554c0a3aSHans de Goede }
530554c0a3aSHans de Goede
531554c0a3aSHans de Goede /* 1 Check initial gain by upper/lower bound */
532554c0a3aSHans de Goede if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
533554c0a3aSHans de Goede CurrentIGI = pDM_DigTable->rx_gain_range_min;
534554c0a3aSHans de Goede
535554c0a3aSHans de Goede if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
536554c0a3aSHans de Goede CurrentIGI = pDM_DigTable->rx_gain_range_max;
537554c0a3aSHans de Goede
538554c0a3aSHans de Goede /* 1 Force upper bound and lower bound for adaptivity */
539554c0a3aSHans de Goede if (
540554c0a3aSHans de Goede pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY &&
541554c0a3aSHans de Goede pDM_Odm->adaptivity_flag == true
542554c0a3aSHans de Goede ) {
543554c0a3aSHans de Goede if (CurrentIGI > Adap_IGI_Upper)
544554c0a3aSHans de Goede CurrentIGI = Adap_IGI_Upper;
545554c0a3aSHans de Goede
546554c0a3aSHans de Goede if (pDM_Odm->IGI_LowerBound != 0) {
547554c0a3aSHans de Goede if (CurrentIGI < pDM_Odm->IGI_LowerBound)
548554c0a3aSHans de Goede CurrentIGI = pDM_Odm->IGI_LowerBound;
549554c0a3aSHans de Goede }
550554c0a3aSHans de Goede }
551554c0a3aSHans de Goede
552554c0a3aSHans de Goede
553554c0a3aSHans de Goede /* 1 Update status */
554554c0a3aSHans de Goede if (pDM_Odm->bBtHsOperation) {
555554c0a3aSHans de Goede if (pDM_Odm->bLinked) {
556554c0a3aSHans de Goede if (pDM_DigTable->BT30_CurIGI > (CurrentIGI))
557554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, CurrentIGI);
558554c0a3aSHans de Goede else
559554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);
560554c0a3aSHans de Goede
561554c0a3aSHans de Goede pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
562554c0a3aSHans de Goede pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
563554c0a3aSHans de Goede } else {
564554c0a3aSHans de Goede if (pDM_Odm->bLinkInProcess)
565554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, 0x1c);
566554c0a3aSHans de Goede else if (pDM_Odm->bBtConnectProcess)
567554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, 0x28);
568554c0a3aSHans de Goede else
569554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
570554c0a3aSHans de Goede }
571554c0a3aSHans de Goede } else { /* BT is not using */
572554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
573554c0a3aSHans de Goede pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
574554c0a3aSHans de Goede pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
575554c0a3aSHans de Goede }
576554c0a3aSHans de Goede }
577554c0a3aSHans de Goede
odm_DIGbyRSSI_LPS(void * pDM_VOID)578554c0a3aSHans de Goede void odm_DIGbyRSSI_LPS(void *pDM_VOID)
579554c0a3aSHans de Goede {
580f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
581d7c2b41fSMarco Cesati struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
582554c0a3aSHans de Goede
583554c0a3aSHans de Goede u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
584554c0a3aSHans de Goede u8 CurrentIGI = pDM_Odm->RSSI_Min;
585554c0a3aSHans de Goede
586554c0a3aSHans de Goede CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
587554c0a3aSHans de Goede
588554c0a3aSHans de Goede /* Using FW PS mode to make IGI */
589554c0a3aSHans de Goede /* Adjust by FA in LPS MODE */
590554c0a3aSHans de Goede if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS)
591554c0a3aSHans de Goede CurrentIGI = CurrentIGI+4;
592554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS)
593554c0a3aSHans de Goede CurrentIGI = CurrentIGI+2;
594554c0a3aSHans de Goede else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS)
595554c0a3aSHans de Goede CurrentIGI = CurrentIGI-2;
596554c0a3aSHans de Goede
597554c0a3aSHans de Goede
598554c0a3aSHans de Goede /* Lower bound checking */
599554c0a3aSHans de Goede
600554c0a3aSHans de Goede /* RSSI Lower bound check */
601*6c6ff293SDeepak R Varma RSSI_Lower = max(pDM_Odm->RSSI_Min - 10, DM_DIG_MIN_NIC);
602554c0a3aSHans de Goede
603554c0a3aSHans de Goede /* Upper and Lower Bound checking */
604554c0a3aSHans de Goede if (CurrentIGI > DM_DIG_MAX_NIC)
605554c0a3aSHans de Goede CurrentIGI = DM_DIG_MAX_NIC;
606554c0a3aSHans de Goede else if (CurrentIGI < RSSI_Lower)
607554c0a3aSHans de Goede CurrentIGI = RSSI_Lower;
608554c0a3aSHans de Goede
609554c0a3aSHans de Goede ODM_Write_DIG(pDM_Odm, CurrentIGI);
610554c0a3aSHans de Goede /* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
611554c0a3aSHans de Goede }
612554c0a3aSHans de Goede
613554c0a3aSHans de Goede /* 3 ============================================================ */
614554c0a3aSHans de Goede /* 3 FASLE ALARM CHECK */
615554c0a3aSHans de Goede /* 3 ============================================================ */
616554c0a3aSHans de Goede
odm_FalseAlarmCounterStatistics(void * pDM_VOID)617554c0a3aSHans de Goede void odm_FalseAlarmCounterStatistics(void *pDM_VOID)
618554c0a3aSHans de Goede {
619f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
620db07a1caSMarco Cesati struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
621554c0a3aSHans de Goede u32 ret_value;
622554c0a3aSHans de Goede
623554c0a3aSHans de Goede if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
624554c0a3aSHans de Goede return;
625554c0a3aSHans de Goede
626554c0a3aSHans de Goede /* hold ofdm counter */
627554c0a3aSHans de Goede /* hold page C counter */
628554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1);
629554c0a3aSHans de Goede /* hold page D counter */
630554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1);
631554c0a3aSHans de Goede
632554c0a3aSHans de Goede ret_value = PHY_QueryBBReg(
633554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord
634554c0a3aSHans de Goede );
635554c0a3aSHans de Goede FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
636554c0a3aSHans de Goede FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16);
637554c0a3aSHans de Goede
638554c0a3aSHans de Goede ret_value = PHY_QueryBBReg(
639554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord
640554c0a3aSHans de Goede );
641554c0a3aSHans de Goede FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
642554c0a3aSHans de Goede FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
643554c0a3aSHans de Goede
644554c0a3aSHans de Goede ret_value = PHY_QueryBBReg(
645554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord
646554c0a3aSHans de Goede );
647554c0a3aSHans de Goede FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
648554c0a3aSHans de Goede FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
649554c0a3aSHans de Goede
650554c0a3aSHans de Goede ret_value = PHY_QueryBBReg(
651554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord
652554c0a3aSHans de Goede );
653554c0a3aSHans de Goede FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
654554c0a3aSHans de Goede
655554c0a3aSHans de Goede FalseAlmCnt->Cnt_Ofdm_fail =
656554c0a3aSHans de Goede FalseAlmCnt->Cnt_Parity_Fail +
657554c0a3aSHans de Goede FalseAlmCnt->Cnt_Rate_Illegal +
658554c0a3aSHans de Goede FalseAlmCnt->Cnt_Crc8_fail +
659554c0a3aSHans de Goede FalseAlmCnt->Cnt_Mcs_fail +
660554c0a3aSHans de Goede FalseAlmCnt->Cnt_Fast_Fsync +
661554c0a3aSHans de Goede FalseAlmCnt->Cnt_SB_Search_fail;
662554c0a3aSHans de Goede
663554c0a3aSHans de Goede {
664554c0a3aSHans de Goede /* hold cck counter */
665554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1);
666554c0a3aSHans de Goede PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1);
667554c0a3aSHans de Goede
668554c0a3aSHans de Goede ret_value = PHY_QueryBBReg(
669554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0
670554c0a3aSHans de Goede );
671554c0a3aSHans de Goede FalseAlmCnt->Cnt_Cck_fail = ret_value;
672554c0a3aSHans de Goede
673554c0a3aSHans de Goede ret_value = PHY_QueryBBReg(
674554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3
675554c0a3aSHans de Goede );
676554c0a3aSHans de Goede FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8;
677554c0a3aSHans de Goede
678554c0a3aSHans de Goede ret_value = PHY_QueryBBReg(
679554c0a3aSHans de Goede pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord
680554c0a3aSHans de Goede );
681554c0a3aSHans de Goede FalseAlmCnt->Cnt_CCK_CCA =
682554c0a3aSHans de Goede ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
683554c0a3aSHans de Goede }
684554c0a3aSHans de Goede
685554c0a3aSHans de Goede FalseAlmCnt->Cnt_all = (
686554c0a3aSHans de Goede FalseAlmCnt->Cnt_Fast_Fsync +
687554c0a3aSHans de Goede FalseAlmCnt->Cnt_SB_Search_fail +
688554c0a3aSHans de Goede FalseAlmCnt->Cnt_Parity_Fail +
689554c0a3aSHans de Goede FalseAlmCnt->Cnt_Rate_Illegal +
690554c0a3aSHans de Goede FalseAlmCnt->Cnt_Crc8_fail +
691554c0a3aSHans de Goede FalseAlmCnt->Cnt_Mcs_fail +
692554c0a3aSHans de Goede FalseAlmCnt->Cnt_Cck_fail
693554c0a3aSHans de Goede );
694554c0a3aSHans de Goede
695554c0a3aSHans de Goede FalseAlmCnt->Cnt_CCA_all =
696554c0a3aSHans de Goede FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
697554c0a3aSHans de Goede }
698554c0a3aSHans de Goede
699554c0a3aSHans de Goede
odm_FAThresholdCheck(void * pDM_VOID,bool bDFSBand,bool bPerformance,u32 RxTp,u32 TxTp,u32 * dm_FA_thres)700554c0a3aSHans de Goede void odm_FAThresholdCheck(
701554c0a3aSHans de Goede void *pDM_VOID,
702554c0a3aSHans de Goede bool bDFSBand,
703554c0a3aSHans de Goede bool bPerformance,
704554c0a3aSHans de Goede u32 RxTp,
705554c0a3aSHans de Goede u32 TxTp,
706554c0a3aSHans de Goede u32 *dm_FA_thres
707554c0a3aSHans de Goede )
708554c0a3aSHans de Goede {
709f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
710554c0a3aSHans de Goede
711554c0a3aSHans de Goede if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) {
712554c0a3aSHans de Goede /* For NIC */
713554c0a3aSHans de Goede dm_FA_thres[0] = DM_DIG_FA_TH0;
714554c0a3aSHans de Goede dm_FA_thres[1] = DM_DIG_FA_TH1;
715554c0a3aSHans de Goede dm_FA_thres[2] = DM_DIG_FA_TH2;
716554c0a3aSHans de Goede } else {
717554c0a3aSHans de Goede dm_FA_thres[0] = 2000;
718554c0a3aSHans de Goede dm_FA_thres[1] = 4000;
719554c0a3aSHans de Goede dm_FA_thres[2] = 5000;
720554c0a3aSHans de Goede }
721554c0a3aSHans de Goede }
722554c0a3aSHans de Goede
odm_ForbiddenIGICheck(void * pDM_VOID,u8 DIG_Dynamic_MIN,u8 CurrentIGI)723554c0a3aSHans de Goede u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI)
724554c0a3aSHans de Goede {
725f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
72686d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
727db07a1caSMarco Cesati struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
728554c0a3aSHans de Goede u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min;
729554c0a3aSHans de Goede
730554c0a3aSHans de Goede if (pFalseAlmCnt->Cnt_all > 10000) {
731554c0a3aSHans de Goede if (pDM_DigTable->LargeFAHit != 3)
732554c0a3aSHans de Goede pDM_DigTable->LargeFAHit++;
733554c0a3aSHans de Goede
734554c0a3aSHans de Goede /* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */
735554c0a3aSHans de Goede if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
736554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI = CurrentIGI;
737554c0a3aSHans de Goede /* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */
738554c0a3aSHans de Goede pDM_DigTable->LargeFAHit = 1;
739554c0a3aSHans de Goede }
740554c0a3aSHans de Goede
741554c0a3aSHans de Goede if (pDM_DigTable->LargeFAHit >= 3) {
742554c0a3aSHans de Goede if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max)
743554c0a3aSHans de Goede rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
744554c0a3aSHans de Goede else
745554c0a3aSHans de Goede rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
746554c0a3aSHans de Goede pDM_DigTable->Recover_cnt = 1800;
747554c0a3aSHans de Goede }
748554c0a3aSHans de Goede } else {
749554c0a3aSHans de Goede if (pDM_DigTable->Recover_cnt != 0) {
750554c0a3aSHans de Goede pDM_DigTable->Recover_cnt--;
751554c0a3aSHans de Goede } else {
752554c0a3aSHans de Goede if (pDM_DigTable->LargeFAHit < 3) {
753554c0a3aSHans de Goede if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */
754554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
755554c0a3aSHans de Goede rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
756554c0a3aSHans de Goede } else {
757554c0a3aSHans de Goede pDM_DigTable->ForbiddenIGI -= 2;
758554c0a3aSHans de Goede rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
759554c0a3aSHans de Goede }
760554c0a3aSHans de Goede } else
761554c0a3aSHans de Goede pDM_DigTable->LargeFAHit = 0;
762554c0a3aSHans de Goede }
763554c0a3aSHans de Goede }
764554c0a3aSHans de Goede
765554c0a3aSHans de Goede return rx_gain_range_min;
766554c0a3aSHans de Goede
767554c0a3aSHans de Goede }
768554c0a3aSHans de Goede
769554c0a3aSHans de Goede /* 3 ============================================================ */
770554c0a3aSHans de Goede /* 3 CCK Packet Detect Threshold */
771554c0a3aSHans de Goede /* 3 ============================================================ */
772554c0a3aSHans de Goede
odm_CCKPacketDetectionThresh(void * pDM_VOID)773554c0a3aSHans de Goede void odm_CCKPacketDetectionThresh(void *pDM_VOID)
774554c0a3aSHans de Goede {
775f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
776db07a1caSMarco Cesati struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
777554c0a3aSHans de Goede u8 CurCCK_CCAThres;
778554c0a3aSHans de Goede
779554c0a3aSHans de Goede
780554c0a3aSHans de Goede if (
781554c0a3aSHans de Goede !(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) ||
782554c0a3aSHans de Goede !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)
783554c0a3aSHans de Goede ) {
784554c0a3aSHans de Goede return;
785554c0a3aSHans de Goede }
786554c0a3aSHans de Goede
787554c0a3aSHans de Goede if (pDM_Odm->ExtLNA)
788554c0a3aSHans de Goede return;
789554c0a3aSHans de Goede
790554c0a3aSHans de Goede if (pDM_Odm->bLinked) {
791554c0a3aSHans de Goede if (pDM_Odm->RSSI_Min > 25)
792554c0a3aSHans de Goede CurCCK_CCAThres = 0xcd;
793554c0a3aSHans de Goede else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10))
794554c0a3aSHans de Goede CurCCK_CCAThres = 0x83;
795554c0a3aSHans de Goede else {
796554c0a3aSHans de Goede if (FalseAlmCnt->Cnt_Cck_fail > 1000)
797554c0a3aSHans de Goede CurCCK_CCAThres = 0x83;
798554c0a3aSHans de Goede else
799554c0a3aSHans de Goede CurCCK_CCAThres = 0x40;
800554c0a3aSHans de Goede }
801554c0a3aSHans de Goede } else {
802554c0a3aSHans de Goede if (FalseAlmCnt->Cnt_Cck_fail > 1000)
803554c0a3aSHans de Goede CurCCK_CCAThres = 0x83;
804554c0a3aSHans de Goede else
805554c0a3aSHans de Goede CurCCK_CCAThres = 0x40;
806554c0a3aSHans de Goede }
807554c0a3aSHans de Goede
808554c0a3aSHans de Goede ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres);
809554c0a3aSHans de Goede }
810554c0a3aSHans de Goede
ODM_Write_CCK_CCA_Thres(void * pDM_VOID,u8 CurCCK_CCAThres)811554c0a3aSHans de Goede void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres)
812554c0a3aSHans de Goede {
813f8010da6SMarco Cesati struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
81486d6c0aeSMarco Cesati struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
815554c0a3aSHans de Goede
816554c0a3aSHans de Goede /* modify by Guo.Mingzhi 2012-01-03 */
817554c0a3aSHans de Goede if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
818554c0a3aSHans de Goede rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres);
819554c0a3aSHans de Goede
820554c0a3aSHans de Goede pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
821554c0a3aSHans de Goede pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
822554c0a3aSHans de Goede }
823