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