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