File Index
Files and directories
Sign in
FILE

odm_DIG.c

File preview with syntax highlighting.

linux-6.19.14/drivers/staging/rtl8723bs/hal/odm_DIG.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/******************************************************************************
  3 *
  4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
  5 *
  6 ******************************************************************************/
  7
  8#include "odm_precomp.h"
  9
 10void odm_NHMCounterStatisticsInit(void *pDM_VOID)
 11{
 12	struct dm_odm_t	*pDM_Odm = (struct dm_odm_t *)pDM_VOID;
 13
 14	/* PHY parameters initialize for n series */
 15	rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x2710);	/* 0x894[31:16]= 0x2710	Time duration for NHM unit: 4us, 0x2710 =40ms */
 16	/* rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x4e20);	0x894[31:16]= 0x4e20	Time duration for NHM unit: 4us, 0x4e20 =80ms */
 17	rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff);	/* 0x890[31:16]= 0xffff	th_9, th_10 */
 18	/* rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff5c);	0x898 = 0xffffff5c		th_3, th_2, th_1, th_0 */
 19	rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff52);	/* 0x898 = 0xffffff52		th_3, th_2, th_1, th_0 */
 20	rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff);	/* 0x89c = 0xffffffff		th_7, th_6, th_5, th_4 */
 21	PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff);		/* 0xe28[7:0]= 0xff		th_8 */
 22	PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x7);	/* 0x890[9:8]=3			enable CCX */
 23	PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1);		/* 0xc0c[7]= 1			max power among all RX ants */
 24}
 25
 26void odm_NHMCounterStatistics(void *pDM_VOID)
 27{
 28	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
 29
 30	/*  Get NHM report */
 31	odm_GetNHMCounterStatistics(pDM_Odm);
 32
 33	/*  Reset NHM counter */
 34	odm_NHMCounterStatisticsReset(pDM_Odm);
 35}
 36
 37void odm_GetNHMCounterStatistics(void *pDM_VOID)
 38{
 39	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
 40	u32 value32 = 0;
 41
 42	value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_NHM_CNT_11N, bMaskDWord);
 43
 44	pDM_Odm->NHM_cnt_0 = (u8)(value32 & bMaskByte0);
 45}
 46
 47void odm_NHMCounterStatisticsReset(void *pDM_VOID)
 48{
 49	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
 50
 51	PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 0);
 52	PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 1);
 53}
 54
 55void odm_NHMBBInit(void *pDM_VOID)
 56{
 57	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
 58
 59	pDM_Odm->adaptivity_flag = false;
 60	pDM_Odm->tolerance_cnt = 3;
 61	pDM_Odm->NHMLastTxOkcnt = 0;
 62	pDM_Odm->NHMLastRxOkcnt = 0;
 63	pDM_Odm->NHMCurTxOkcnt = 0;
 64	pDM_Odm->NHMCurRxOkcnt = 0;
 65}
 66
 67/*  */
 68void odm_NHMBB(void *pDM_VOID)
 69{
 70	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
 71	/* u8 test_status; */
 72	/* struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; */
 73
 74	pDM_Odm->NHMCurTxOkcnt =
 75		*(pDM_Odm->pNumTxBytesUnicast)-pDM_Odm->NHMLastTxOkcnt;
 76	pDM_Odm->NHMCurRxOkcnt =
 77		*(pDM_Odm->pNumRxBytesUnicast)-pDM_Odm->NHMLastRxOkcnt;
 78	pDM_Odm->NHMLastTxOkcnt =
 79		*(pDM_Odm->pNumTxBytesUnicast);
 80	pDM_Odm->NHMLastRxOkcnt =
 81		*(pDM_Odm->pNumRxBytesUnicast);
 82
 83
 84	if ((pDM_Odm->NHMCurTxOkcnt) + 1 > (u64)(pDM_Odm->NHMCurRxOkcnt<<2) + 1) { /* Tx > 4*Rx possible for adaptivity test */
 85		if (pDM_Odm->NHM_cnt_0 >= 190 || pDM_Odm->adaptivity_flag == true) {
 86			/* Enable EDCCA since it is possible running Adaptivity testing */
 87			/* test_status = 1; */
 88			pDM_Odm->adaptivity_flag = true;
 89			pDM_Odm->tolerance_cnt = 0;
 90		} else {
 91			if (pDM_Odm->tolerance_cnt < 3)
 92				pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
 93			else
 94				pDM_Odm->tolerance_cnt = 4;
 95			/* test_status = 5; */
 96			if (pDM_Odm->tolerance_cnt > 3) {
 97				/* test_status = 3; */
 98				pDM_Odm->adaptivity_flag = false;
 99			}
100		}
101	} else { /*  TX<RX */
102		if (pDM_Odm->adaptivity_flag == true && pDM_Odm->NHM_cnt_0 <= 200) {
103			/* test_status = 2; */
104			pDM_Odm->tolerance_cnt = 0;
105		} else {
106			if (pDM_Odm->tolerance_cnt < 3)
107				pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
108			else
109				pDM_Odm->tolerance_cnt = 4;
110			/* test_status = 5; */
111			if (pDM_Odm->tolerance_cnt > 3) {
112				/* test_status = 4; */
113				pDM_Odm->adaptivity_flag = false;
114			}
115		}
116	}
117}
118
119void odm_SearchPwdBLowerBound(void *pDM_VOID, u8 IGI_target)
120{
121	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
122	u32 value32 = 0;
123	u8 cnt, IGI;
124	bool bAdjust = true;
125	s8 TH_L2H_dmc, TH_H2L_dmc;
126	s8 Diff;
127
128	IGI = 0x50; /*  find H2L, L2H lower bound */
129	ODM_Write_DIG(pDM_Odm, IGI);
130
131
132	Diff = IGI_target-(s8)IGI;
133	TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
134	if (TH_L2H_dmc > 10)
135		TH_L2H_dmc = 10;
136	TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
137	PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
138	PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
139
140	mdelay(5);
141
142	while (bAdjust) {
143		for (cnt = 0; cnt < 20; cnt++) {
144			value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_RPT_11N, bMaskDWord);
145
146			if (value32 & BIT30)
147				pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
148			else if (value32 & BIT29)
149				pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
150			else
151				pDM_Odm->txEdcca0 = pDM_Odm->txEdcca0 + 1;
152		}
153
154		if (pDM_Odm->txEdcca1 > 5) {
155			IGI = IGI-1;
156			TH_L2H_dmc = TH_L2H_dmc + 1;
157			if (TH_L2H_dmc > 10)
158				TH_L2H_dmc = 10;
159			TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
160			PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
161			PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
162
163			pDM_Odm->TxHangFlg = true;
164			pDM_Odm->txEdcca1 = 0;
165			pDM_Odm->txEdcca0 = 0;
166
167			if (TH_L2H_dmc == 10) {
168				bAdjust = false;
169				pDM_Odm->TxHangFlg = false;
170				pDM_Odm->txEdcca1 = 0;
171				pDM_Odm->txEdcca0 = 0;
172				pDM_Odm->H2L_lb = TH_H2L_dmc;
173				pDM_Odm->L2H_lb = TH_L2H_dmc;
174				pDM_Odm->Adaptivity_IGI_upper = IGI;
175			}
176		} else {
177			bAdjust = false;
178			pDM_Odm->TxHangFlg = false;
179			pDM_Odm->txEdcca1 = 0;
180			pDM_Odm->txEdcca0 = 0;
181			pDM_Odm->H2L_lb = TH_H2L_dmc;
182			pDM_Odm->L2H_lb = TH_L2H_dmc;
183			pDM_Odm->Adaptivity_IGI_upper = IGI;
184		}
185	}
186}
187
188void odm_AdaptivityInit(void *pDM_VOID)
189{
190	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
191
192	if (pDM_Odm->Carrier_Sense_enable == false)
193		pDM_Odm->TH_L2H_ini = 0xf7; /*  -7 */
194	else
195		pDM_Odm->TH_L2H_ini = 0xa;
196
197	pDM_Odm->AdapEn_RSSI = 20;
198	pDM_Odm->TH_EDCCA_HL_diff = 7;
199
200	pDM_Odm->IGI_Base = 0x32;
201	pDM_Odm->IGI_target = 0x1c;
202	pDM_Odm->ForceEDCCA = 0;
203	pDM_Odm->NHM_disable = false;
204	pDM_Odm->TxHangFlg = true;
205	pDM_Odm->txEdcca0 = 0;
206	pDM_Odm->txEdcca1 = 0;
207	pDM_Odm->H2L_lb = 0;
208	pDM_Odm->L2H_lb = 0;
209	pDM_Odm->Adaptivity_IGI_upper = 0;
210	odm_NHMBBInit(pDM_Odm);
211
212	PHY_SetBBReg(pDM_Odm->Adapter, REG_RD_CTRL, BIT11, 1); /*  stop counting if EDCCA is asserted */
213}
214
215
216void odm_Adaptivity(void *pDM_VOID, u8 IGI)
217{
218	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
219	s8 TH_L2H_dmc, TH_H2L_dmc;
220	s8 Diff, IGI_target;
221	bool EDCCA_State = false;
222
223	if (!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) {
224		return;
225	}
226
227	if (*pDM_Odm->pBandWidth == ODM_BW20M) /* CHANNEL_WIDTH_20 */
228		IGI_target = pDM_Odm->IGI_Base;
229	else if (*pDM_Odm->pBandWidth == ODM_BW40M)
230		IGI_target = pDM_Odm->IGI_Base + 2;
231	else
232		IGI_target = pDM_Odm->IGI_Base;
233	pDM_Odm->IGI_target = (u8) IGI_target;
234
235	/* Search pwdB lower bound */
236	if (pDM_Odm->TxHangFlg == true) {
237		PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208);
238		odm_SearchPwdBLowerBound(pDM_Odm, pDM_Odm->IGI_target);
239	}
240
241	if ((!pDM_Odm->bLinked) || (*pDM_Odm->pChannel > 149)) { /*  Band4 doesn't need adaptivity */
242		PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, 0x7f);
243		PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, 0x7f);
244		return;
245	}
246
247	if (!pDM_Odm->ForceEDCCA) {
248		if (pDM_Odm->RSSI_Min > pDM_Odm->AdapEn_RSSI)
249			EDCCA_State = true;
250		else if (pDM_Odm->RSSI_Min < (pDM_Odm->AdapEn_RSSI - 5))
251			EDCCA_State = false;
252	} else
253		EDCCA_State = true;
254
255	if (
256		pDM_Odm->bLinked &&
257		pDM_Odm->Carrier_Sense_enable == false &&
258		pDM_Odm->NHM_disable == false &&
259		pDM_Odm->TxHangFlg == false
260	)
261		odm_NHMBB(pDM_Odm);
262
263	if (EDCCA_State) {
264		Diff = IGI_target-(s8)IGI;
265		TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
266		if (TH_L2H_dmc > 10)
267			TH_L2H_dmc = 10;
268
269		TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
270
271		/* replace lower bound to prevent EDCCA always equal  */
272		if (TH_H2L_dmc < pDM_Odm->H2L_lb)
273			TH_H2L_dmc = pDM_Odm->H2L_lb;
274		if (TH_L2H_dmc < pDM_Odm->L2H_lb)
275			TH_L2H_dmc = pDM_Odm->L2H_lb;
276	} else {
277		TH_L2H_dmc = 0x7f;
278		TH_H2L_dmc = 0x7f;
279	}
280	PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
281	PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
282}
283
284void ODM_Write_DIG(void *pDM_VOID, u8 CurrentIGI)
285{
286	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
287	struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
288
289	if (pDM_DigTable->bStopDIG) {
290		return;
291	}
292
293	if (pDM_DigTable->CurIGValue != CurrentIGI) {
294		/* 1 Check initial gain by upper bound */
295		if (!pDM_DigTable->bPSDInProgress) {
296			if (CurrentIGI > pDM_DigTable->rx_gain_range_max) {
297				CurrentIGI = pDM_DigTable->rx_gain_range_max;
298			}
299
300		}
301
302		/* 1 Set IGI value */
303		PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
304
305		PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
306
307		pDM_DigTable->CurIGValue = CurrentIGI;
308	}
309
310}
311
312bool odm_DigAbort(void *pDM_VOID)
313{
314	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
315
316	/* SupportAbility */
317	if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) {
318		return	true;
319	}
320
321	/* SupportAbility */
322	if (!(pDM_Odm->SupportAbility & ODM_BB_DIG)) {
323		return	true;
324	}
325
326	/* ScanInProcess */
327	if (*(pDM_Odm->pbScanInProcess)) {
328		return	true;
329	}
330
331	/* add by Neil Chen to avoid PSD is processing */
332	if (pDM_Odm->bDMInitialGainEnable == false) {
333		return	true;
334	}
335
336	return	false;
337}
338
339void odm_DIGInit(void *pDM_VOID)
340{
341	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
342	struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
343
344	pDM_DigTable->bStopDIG = false;
345	pDM_DigTable->bPSDInProgress = false;
346	pDM_DigTable->CurIGValue = (u8) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm));
347	pDM_DigTable->RssiLowThresh	= DM_DIG_THRESH_LOW;
348	pDM_DigTable->RssiHighThresh	= DM_DIG_THRESH_HIGH;
349	pDM_DigTable->FALowThresh	= DMfalseALARM_THRESH_LOW;
350	pDM_DigTable->FAHighThresh	= DMfalseALARM_THRESH_HIGH;
351	pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT;
352	pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
353	pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
354	pDM_DigTable->PreCCK_CCAThres = 0xFF;
355	pDM_DigTable->CurCCK_CCAThres = 0x83;
356	pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC;
357	pDM_DigTable->LargeFAHit = 0;
358	pDM_DigTable->Recover_cnt = 0;
359	pDM_DigTable->bMediaConnect_0 = false;
360	pDM_DigTable->bMediaConnect_1 = false;
361
362	/* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */
363	pDM_Odm->bDMInitialGainEnable = true;
364
365	pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC;
366	pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC;
367
368	/* To Initi BT30 IGI */
369	pDM_DigTable->BT30_CurIGI = 0x32;
370
371	pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
372	pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
373}
374
375
376void odm_DIG(void *pDM_VOID)
377{
378	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
379
380	/*  Common parameters */
381	struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
382	struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
383	bool FirstConnect, FirstDisConnect;
384	u8 DIG_MaxOfMin, DIG_Dynamic_MIN;
385	u8 dm_dig_max, dm_dig_min;
386	u8 CurrentIGI = pDM_DigTable->CurIGValue;
387	u8 offset;
388	u32 dm_FA_thres[3];
389	u8 Adap_IGI_Upper = 0;
390	u32 TxTp = 0, RxTp = 0;
391	bool bDFSBand = false;
392	bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false;
393
394	if (odm_DigAbort(pDM_Odm))
395		return;
396
397	if (pDM_Odm->adaptivity_flag == true)
398		Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper;
399
400
401	/* 1 Update status */
402	DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
403	FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == false);
404	FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == true);
405
406	/* 1 Boundary Decision */
407	/* 2 For WIN\CE */
408	dm_dig_max = 0x5A;
409	dm_dig_min = DM_DIG_MIN_NIC;
410	DIG_MaxOfMin = DM_DIG_MAX_AP;
411
412	/* 1 Adjust boundary by RSSI */
413	if (pDM_Odm->bLinked && bPerformance) {
414		/* 2 Modify DIG upper bound */
415		/* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
416		if (pDM_Odm->bBtLimitedDig == 1) {
417			offset = 10;
418		} else
419			offset = 15;
420
421		if ((pDM_Odm->RSSI_Min + offset) > dm_dig_max)
422			pDM_DigTable->rx_gain_range_max = dm_dig_max;
423		else if ((pDM_Odm->RSSI_Min + offset) < dm_dig_min)
424			pDM_DigTable->rx_gain_range_max = dm_dig_min;
425		else
426			pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset;
427
428		/* 2 Modify DIG lower bound */
429		/* if (pDM_Odm->bOneEntryOnly) */
430		{
431			if (pDM_Odm->RSSI_Min < dm_dig_min)
432				DIG_Dynamic_MIN = dm_dig_min;
433			else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
434				DIG_Dynamic_MIN = DIG_MaxOfMin;
435			else
436				DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
437		}
438	} else {
439		pDM_DigTable->rx_gain_range_max = dm_dig_max;
440		DIG_Dynamic_MIN = dm_dig_min;
441	}
442
443	/* 1 Force Lower Bound for AntDiv */
444	if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) {
445		if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
446			if (
447				pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV ||
448				pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV ||
449				pDM_Odm->AntDivType == S0S1_SW_ANTDIV
450			) {
451				if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin)
452					DIG_Dynamic_MIN = DIG_MaxOfMin;
453				else
454					DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max;
455			}
456		}
457	}
458
459	/* 1 Modify DIG lower bound, deal with abnormal case */
460	/* 2 Abnormal false alarm case */
461	if (FirstDisConnect) {
462		pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN;
463		pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN;
464	} else
465		pDM_DigTable->rx_gain_range_min =
466			odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI);
467
468	if (pDM_Odm->bLinked && !FirstConnect) {
469		if (
470			(pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
471			pDM_Odm->bsta_state
472		) {
473			pDM_DigTable->rx_gain_range_min = dm_dig_min;
474		}
475	}
476
477	/* 2 Abnormal lower bound case */
478	if (pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) {
479		pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
480	}
481
482
483	/* 1 False alarm threshold decision */
484	odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres);
485
486	/* 1 Adjust initial gain by false alarm */
487	if (pDM_Odm->bLinked && bPerformance) {
488
489		if (bFirstTpTarget || FirstConnect) {
490			pDM_DigTable->LargeFAHit = 0;
491
492			if (pDM_Odm->RSSI_Min < DIG_MaxOfMin) {
493				if (CurrentIGI < pDM_Odm->RSSI_Min)
494					CurrentIGI = pDM_Odm->RSSI_Min;
495			} else {
496				if (CurrentIGI < DIG_MaxOfMin)
497					CurrentIGI = DIG_MaxOfMin;
498			}
499
500		} else {
501			if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
502				CurrentIGI = CurrentIGI + 4;
503			else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
504				CurrentIGI = CurrentIGI + 2;
505			else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
506				CurrentIGI = CurrentIGI - 2;
507
508			if (
509				(pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
510				(pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) &&
511				(pDM_Odm->bsta_state)
512			) {
513				CurrentIGI = pDM_DigTable->rx_gain_range_min;
514			}
515		}
516	} else {
517
518		if (FirstDisConnect || bFirstCoverage) {
519			CurrentIGI = dm_dig_min;
520		} else {
521			if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
522				CurrentIGI = CurrentIGI + 4;
523			else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
524				CurrentIGI = CurrentIGI + 2;
525			else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
526				CurrentIGI = CurrentIGI - 2;
527		}
528	}
529
530	/* 1 Check initial gain by upper/lower bound */
531	if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
532		CurrentIGI = pDM_DigTable->rx_gain_range_min;
533
534	if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
535		CurrentIGI = pDM_DigTable->rx_gain_range_max;
536
537	/* 1 Force upper bound and lower bound for adaptivity */
538	if (
539		pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY &&
540		pDM_Odm->adaptivity_flag == true
541	) {
542		if (CurrentIGI > Adap_IGI_Upper)
543			CurrentIGI = Adap_IGI_Upper;
544
545		if (pDM_Odm->IGI_LowerBound != 0) {
546			if (CurrentIGI < pDM_Odm->IGI_LowerBound)
547				CurrentIGI = pDM_Odm->IGI_LowerBound;
548		}
549	}
550
551
552	/* 1 Update status */
553	if (pDM_Odm->bBtHsOperation) {
554		if (pDM_Odm->bLinked) {
555			if (pDM_DigTable->BT30_CurIGI > (CurrentIGI))
556				ODM_Write_DIG(pDM_Odm, CurrentIGI);
557			else
558				ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);
559
560			pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
561			pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
562		} else {
563			if (pDM_Odm->bLinkInProcess)
564				ODM_Write_DIG(pDM_Odm, 0x1c);
565			else if (pDM_Odm->bBtConnectProcess)
566				ODM_Write_DIG(pDM_Odm, 0x28);
567			else
568				ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
569		}
570	} else { /*  BT is not using */
571		ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
572		pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
573		pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
574	}
575}
576
577void odm_DIGbyRSSI_LPS(void *pDM_VOID)
578{
579	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
580	struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
581
582	u8 RSSI_Lower = DM_DIG_MIN_NIC;   /* 0x1E or 0x1C */
583	u8 CurrentIGI = pDM_Odm->RSSI_Min;
584
585	CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
586
587	/*  Using FW PS mode to make IGI */
588	/* Adjust by  FA in LPS MODE */
589	if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS)
590		CurrentIGI = CurrentIGI+4;
591	else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS)
592		CurrentIGI = CurrentIGI+2;
593	else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS)
594		CurrentIGI = CurrentIGI-2;
595
596
597	/* Lower bound checking */
598
599	/* RSSI Lower bound check */
600	RSSI_Lower = max(pDM_Odm->RSSI_Min - 10, DM_DIG_MIN_NIC);
601
602	/* Upper and Lower Bound checking */
603	if (CurrentIGI > DM_DIG_MAX_NIC)
604		CurrentIGI = DM_DIG_MAX_NIC;
605	else if (CurrentIGI < RSSI_Lower)
606		CurrentIGI = RSSI_Lower;
607
608	ODM_Write_DIG(pDM_Odm, CurrentIGI);
609	/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
610}
611
612/* 3 ============================================================ */
613/* 3 FASLE ALARM CHECK */
614/* 3 ============================================================ */
615
616void odm_FalseAlarmCounterStatistics(void *pDM_VOID)
617{
618	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
619	struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
620	u32 ret_value;
621
622	if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
623		return;
624
625	/* hold ofdm counter */
626	/* hold page C counter */
627	PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1);
628	/* hold page D counter */
629	PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1);
630
631	ret_value = PHY_QueryBBReg(
632		pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord
633	);
634	FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
635	FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16);
636
637	ret_value = PHY_QueryBBReg(
638		pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord
639	);
640	FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
641	FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
642
643	ret_value = PHY_QueryBBReg(
644		pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord
645	);
646	FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
647	FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
648
649	ret_value = PHY_QueryBBReg(
650		pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord
651	);
652	FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
653
654	FalseAlmCnt->Cnt_Ofdm_fail =
655		FalseAlmCnt->Cnt_Parity_Fail +
656		FalseAlmCnt->Cnt_Rate_Illegal +
657		FalseAlmCnt->Cnt_Crc8_fail +
658		FalseAlmCnt->Cnt_Mcs_fail +
659		FalseAlmCnt->Cnt_Fast_Fsync +
660		FalseAlmCnt->Cnt_SB_Search_fail;
661
662	{
663		/* hold cck counter */
664		PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1);
665		PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1);
666
667		ret_value = PHY_QueryBBReg(
668			pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0
669		);
670		FalseAlmCnt->Cnt_Cck_fail = ret_value;
671
672		ret_value = PHY_QueryBBReg(
673			pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3
674		);
675		FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8;
676
677		ret_value = PHY_QueryBBReg(
678			pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord
679		);
680		FalseAlmCnt->Cnt_CCK_CCA =
681			((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
682	}
683
684	FalseAlmCnt->Cnt_all = (
685		FalseAlmCnt->Cnt_Fast_Fsync +
686		FalseAlmCnt->Cnt_SB_Search_fail +
687		FalseAlmCnt->Cnt_Parity_Fail +
688		FalseAlmCnt->Cnt_Rate_Illegal +
689		FalseAlmCnt->Cnt_Crc8_fail +
690		FalseAlmCnt->Cnt_Mcs_fail +
691		FalseAlmCnt->Cnt_Cck_fail
692	);
693
694	FalseAlmCnt->Cnt_CCA_all =
695		FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
696}
697
698
699void odm_FAThresholdCheck(
700	void *pDM_VOID,
701	bool bDFSBand,
702	bool bPerformance,
703	u32 RxTp,
704	u32 TxTp,
705	u32 *dm_FA_thres
706)
707{
708	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
709
710	if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) {
711		/*  For NIC */
712		dm_FA_thres[0] = DM_DIG_FA_TH0;
713		dm_FA_thres[1] = DM_DIG_FA_TH1;
714		dm_FA_thres[2] = DM_DIG_FA_TH2;
715	} else {
716		dm_FA_thres[0] = 2000;
717		dm_FA_thres[1] = 4000;
718		dm_FA_thres[2] = 5000;
719	}
720}
721
722u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI)
723{
724	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
725	struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
726	struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
727	u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min;
728
729	if (pFalseAlmCnt->Cnt_all > 10000) {
730		if (pDM_DigTable->LargeFAHit != 3)
731			pDM_DigTable->LargeFAHit++;
732
733		/* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */
734		if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
735			pDM_DigTable->ForbiddenIGI = CurrentIGI;
736			/* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */
737			pDM_DigTable->LargeFAHit = 1;
738		}
739
740		if (pDM_DigTable->LargeFAHit >= 3) {
741			if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max)
742				rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
743			else
744				rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
745			pDM_DigTable->Recover_cnt = 1800;
746		}
747	} else {
748		if (pDM_DigTable->Recover_cnt != 0) {
749			pDM_DigTable->Recover_cnt--;
750		} else {
751			if (pDM_DigTable->LargeFAHit < 3) {
752				if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */
753					pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
754					rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
755				} else {
756					pDM_DigTable->ForbiddenIGI -= 2;
757					rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
758				}
759			} else
760				pDM_DigTable->LargeFAHit = 0;
761		}
762	}
763
764	return rx_gain_range_min;
765
766}
767
768/* 3 ============================================================ */
769/* 3 CCK Packet Detect Threshold */
770/* 3 ============================================================ */
771
772void odm_CCKPacketDetectionThresh(void *pDM_VOID)
773{
774	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
775	struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
776	u8 CurCCK_CCAThres;
777
778
779	if (
780		!(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) ||
781		!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)
782	) {
783		return;
784	}
785
786	if (pDM_Odm->ExtLNA)
787		return;
788
789	if (pDM_Odm->bLinked) {
790		if (pDM_Odm->RSSI_Min > 25)
791			CurCCK_CCAThres = 0xcd;
792		else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10))
793			CurCCK_CCAThres = 0x83;
794		else {
795			if (FalseAlmCnt->Cnt_Cck_fail > 1000)
796				CurCCK_CCAThres = 0x83;
797			else
798				CurCCK_CCAThres = 0x40;
799		}
800	} else {
801		if (FalseAlmCnt->Cnt_Cck_fail > 1000)
802			CurCCK_CCAThres = 0x83;
803		else
804			CurCCK_CCAThres = 0x40;
805	}
806
807	ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres);
808}
809
810void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres)
811{
812	struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
813	struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
814
815	/* modify by Guo.Mingzhi 2012-01-03 */
816	if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
817		rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres);
818
819	pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
820	pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
821}
~/ Read-only file preview.