xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8189es/hal/rtl8188e/rtl8188e_dm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 //============================================================
21 // Description:
22 //
23 // This file is for 92CE/92CU dynamic mechanism only
24 //
25 //
26 //============================================================
27 #define _RTL8188E_DM_C_
28 
29 //============================================================
30 // include files
31 //============================================================
32 #include <drv_types.h>
33 #include <rtl8188e_hal.h>
34 
35 //============================================================
36 // Global var
37 //============================================================
38 
39 
40 static VOID
dm_CheckProtection(IN PADAPTER Adapter)41 dm_CheckProtection(
42 	IN	PADAPTER	Adapter
43 	)
44 {
45 #if 0
46 	PMGNT_INFO		pMgntInfo = &(Adapter->MgntInfo);
47 	u1Byte			CurRate, RateThreshold;
48 
49 	if(pMgntInfo->pHTInfo->bCurBW40MHz)
50 		RateThreshold = MGN_MCS1;
51 	else
52 		RateThreshold = MGN_MCS3;
53 
54 	if(Adapter->TxStats.CurrentInitTxRate <= RateThreshold)
55 	{
56 		pMgntInfo->bDmDisableProtect = TRUE;
57 		DbgPrint("Forced disable protect: %x\n", Adapter->TxStats.CurrentInitTxRate);
58 	}
59 	else
60 	{
61 		pMgntInfo->bDmDisableProtect = FALSE;
62 		DbgPrint("Enable protect: %x\n", Adapter->TxStats.CurrentInitTxRate);
63 	}
64 #endif
65 }
66 
67 static VOID
dm_CheckStatistics(IN PADAPTER Adapter)68 dm_CheckStatistics(
69 	IN	PADAPTER	Adapter
70 	)
71 {
72 #if 0
73 	if(!Adapter->MgntInfo.bMediaConnect)
74 		return;
75 
76 	//2008.12.10 tynli Add for getting Current_Tx_Rate_Reg flexibly.
77 	rtw_hal_get_hwreg( Adapter, HW_VAR_INIT_TX_RATE, (pu1Byte)(&Adapter->TxStats.CurrentInitTxRate) );
78 
79 	// Calculate current Tx Rate(Successful transmited!!)
80 
81 	// Calculate current Rx Rate(Successful received!!)
82 
83 	//for tx tx retry count
84 	rtw_hal_get_hwreg( Adapter, HW_VAR_RETRY_COUNT, (pu1Byte)(&Adapter->TxStats.NumTxRetryCount) );
85 #endif
86 }
87 
88 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
dm_CheckPbcGPIO(_adapter * padapter)89 static void dm_CheckPbcGPIO(_adapter *padapter)
90 {
91 	u8	tmp1byte;
92 	u8	bPbcPressed = _FALSE;
93 
94 	if(!padapter->registrypriv.hw_wps_pbc)
95 		return;
96 
97 #ifdef CONFIG_USB_HCI
98 	tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
99 	tmp1byte |= (HAL_8188E_HW_GPIO_WPS_BIT);
100 	rtw_write8(padapter, GPIO_IO_SEL, tmp1byte);	//enable GPIO[2] as output mode
101 
102 	tmp1byte &= ~(HAL_8188E_HW_GPIO_WPS_BIT);
103 	rtw_write8(padapter,  GPIO_IN, tmp1byte);		//reset the floating voltage level
104 
105 	tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
106 	tmp1byte &= ~(HAL_8188E_HW_GPIO_WPS_BIT);
107 	rtw_write8(padapter, GPIO_IO_SEL, tmp1byte);	//enable GPIO[2] as input mode
108 
109 	tmp1byte =rtw_read8(padapter, GPIO_IN);
110 
111 	if (tmp1byte == 0xff)
112 		return ;
113 
114 	if (tmp1byte&HAL_8188E_HW_GPIO_WPS_BIT)
115 	{
116 		bPbcPressed = _TRUE;
117 	}
118 #else
119 	tmp1byte = rtw_read8(padapter, GPIO_IN);
120 	//RT_TRACE(COMP_IO, DBG_TRACE, ("dm_CheckPbcGPIO - %x\n", tmp1byte));
121 
122 	if (tmp1byte == 0xff || padapter->init_adpt_in_progress)
123 		return ;
124 
125 	if((tmp1byte&HAL_8188E_HW_GPIO_WPS_BIT)==0)
126 	{
127 		bPbcPressed = _TRUE;
128 	}
129 #endif
130 
131 	if( _TRUE == bPbcPressed)
132 	{
133 		// Here we only set bPbcPressed to true
134 		// After trigger PBC, the variable will be set to false
135 		DBG_8192C("CheckPbcGPIO - PBC is pressed\n");
136 		rtw_request_wps_pbc_event(padapter);
137 	}
138 }
139 #endif//#ifdef CONFIG_SUPPORT_HW_WPS_PBC
140 
141 #ifdef CONFIG_PCI_HCI
142 //
143 //	Description:
144 //		Perform interrupt migration dynamically to reduce CPU utilization.
145 //
146 //	Assumption:
147 //		1. Do not enable migration under WIFI test.
148 //
149 //	Created by Roger, 2010.03.05.
150 //
151 VOID
dm_InterruptMigration(IN PADAPTER Adapter)152 dm_InterruptMigration(
153 	IN	PADAPTER	Adapter
154 	)
155 {
156 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
157 	struct mlme_priv	*pmlmepriv = &(Adapter->mlmepriv);
158 	BOOLEAN			bCurrentIntMt, bCurrentACIntDisable;
159 	BOOLEAN			IntMtToSet = _FALSE;
160 	BOOLEAN			ACIntToSet = _FALSE;
161 
162 
163 	// Retrieve current interrupt migration and Tx four ACs IMR settings first.
164 	bCurrentIntMt = pHalData->bInterruptMigration;
165 	bCurrentACIntDisable = pHalData->bDisableTxInt;
166 
167 	//
168 	// <Roger_Notes> Currently we use busy traffic for reference instead of RxIntOK counts to prevent non-linear Rx statistics
169 	// when interrupt migration is set before. 2010.03.05.
170 	//
171 	if(!Adapter->registrypriv.wifi_spec &&
172 		(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) &&
173 		pmlmepriv->LinkDetectInfo.bHigherBusyTraffic)
174 	{
175 		IntMtToSet = _TRUE;
176 
177 		// To check whether we should disable Tx interrupt or not.
178 		if(pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic )
179 			ACIntToSet = _TRUE;
180 	}
181 
182 	//Update current settings.
183 	if( bCurrentIntMt != IntMtToSet ){
184 		DBG_8192C("%s(): Update interrrupt migration(%d)\n",__FUNCTION__,IntMtToSet);
185 		if(IntMtToSet)
186 		{
187 			//
188 			// <Roger_Notes> Set interrrupt migration timer and corresponging Tx/Rx counter.
189 			// timer 25ns*0xfa0=100us for 0xf packets.
190 			// 2010.03.05.
191 			//
192 			rtw_write32(Adapter, REG_INT_MIG, 0xff000fa0);// 0x306:Rx, 0x307:Tx
193 			pHalData->bInterruptMigration = IntMtToSet;
194 		}
195 		else
196 		{
197 			// Reset all interrupt migration settings.
198 			rtw_write32(Adapter, REG_INT_MIG, 0);
199 			pHalData->bInterruptMigration = IntMtToSet;
200 		}
201 	}
202 
203 	/*if( bCurrentACIntDisable != ACIntToSet ){
204 		DBG_8192C("%s(): Update AC interrrupt(%d)\n",__FUNCTION__,ACIntToSet);
205 		if(ACIntToSet) // Disable four ACs interrupts.
206 		{
207 			//
208 			// <Roger_Notes> Disable VO, VI, BE and BK four AC interrupts to gain more efficient CPU utilization.
209 			// When extremely highly Rx OK occurs, we will disable Tx interrupts.
210 			// 2010.03.05.
211 			//
212 			UpdateInterruptMask8192CE( Adapter, 0, RT_AC_INT_MASKS );
213 			pHalData->bDisableTxInt = ACIntToSet;
214 		}
215 		else// Enable four ACs interrupts.
216 		{
217 			UpdateInterruptMask8192CE( Adapter, RT_AC_INT_MASKS, 0 );
218 			pHalData->bDisableTxInt = ACIntToSet;
219 		}
220 	}*/
221 
222 }
223 
224 #endif
225 
226 //
227 // Initialize GPIO setting registers
228 //
229 static void
dm_InitGPIOSetting(IN PADAPTER Adapter)230 dm_InitGPIOSetting(
231 	IN	PADAPTER	Adapter
232 	)
233 {
234 	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(Adapter);
235 
236 	u8	tmp1byte;
237 
238 	tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
239 	tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
240 
241 	rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
242 
243 }
244 
245 //============================================================
246 // functions
247 //============================================================
Init_ODM_ComInfo_88E(PADAPTER Adapter)248 static void Init_ODM_ComInfo_88E(PADAPTER	Adapter)
249 {
250 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
251 	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
252 	u32  SupportAbility = 0;
253 	u8	cut_ver,fab_ver;
254 
255 	Init_ODM_ComInfo(Adapter);
256 
257 	ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_IC_TYPE,ODM_RTL8188E);
258 
259 	fab_ver = ODM_TSMC;
260 	cut_ver = ODM_CUT_A;
261 
262 	if(IS_VENDOR_8188E_I_CUT_SERIES(Adapter))
263 		cut_ver = ODM_CUT_I;
264 
265 	ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_FAB_VER,fab_ver);
266 	ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_CUT_VER,cut_ver);
267 
268  	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_ANTENNA_TYPE, pHalData->TRxAntDivType);
269 
270 	#ifdef CONFIG_DISABLE_ODM
271 	SupportAbility = 0;
272 	#else
273 	SupportAbility = 	ODM_RF_CALIBRATION |
274 					ODM_RF_TX_PWR_TRACK
275 					;
276 	/* if(pHalData->AntDivCfg)
277 		SupportAbility |= ODM_BB_ANT_DIV; */
278 	#endif
279 
280 	ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_ABILITY,SupportAbility);
281 
282 }
Update_ODM_ComInfo_88E(PADAPTER Adapter)283 static void Update_ODM_ComInfo_88E(PADAPTER	Adapter)
284 {
285 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
286 	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
287 	u32  SupportAbility = 0;
288 	int i;
289 
290 	SupportAbility = 0
291 		| ODM_BB_DIG
292 		| ODM_BB_RA_MASK
293 		| ODM_BB_DYNAMIC_TXPWR
294 		| ODM_BB_FA_CNT
295 		| ODM_BB_RSSI_MONITOR
296 		| ODM_BB_CCK_PD
297 		//| ODM_BB_PWR_SAVE
298 		| ODM_BB_CFO_TRACKING
299 		| ODM_RF_CALIBRATION
300 		| ODM_RF_TX_PWR_TRACK
301 		| ODM_BB_NHM_CNT
302 		| ODM_BB_PRIMARY_CCA
303 //		| ODM_BB_PWR_TRAIN
304 		;
305 
306 	if (rtw_odm_adaptivity_needed(Adapter) == _TRUE) {
307 		rtw_odm_adaptivity_config_msg(RTW_DBGDUMP, Adapter);
308 		SupportAbility |= ODM_BB_ADAPTIVITY;
309 	}
310 
311 	if (!Adapter->registrypriv.qos_opt_enable) {
312 		SupportAbility |= ODM_MAC_EDCA_TURBO;
313 	}
314 
315 	if(pHalData->AntDivCfg)
316 		SupportAbility |= ODM_BB_ANT_DIV;
317 
318 #if (MP_DRIVER==1)
319 	if (Adapter->registrypriv.mp_mode == 1) {
320 		SupportAbility = 0
321 			| ODM_RF_CALIBRATION
322 			| ODM_RF_TX_PWR_TRACK
323 			;
324 	}
325 #endif//(MP_DRIVER==1)
326 
327 #ifdef CONFIG_DISABLE_ODM
328 	SupportAbility = 0;
329 #endif//CONFIG_DISABLE_ODM
330 
331 	ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_ABILITY,SupportAbility);
332 
333 	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_ANTENNA_TYPE, pHalData->TRxAntDivType);
334 }
335 
336 void
rtl8188e_InitHalDm(IN PADAPTER Adapter)337 rtl8188e_InitHalDm(
338 	IN	PADAPTER	Adapter
339 	)
340 {
341 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
342 	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
343 	u8	i;
344 
345 #ifdef CONFIG_USB_HCI
346 	dm_InitGPIOSetting(Adapter);
347 #endif
348 
349 	pHalData->DM_Type = DM_Type_ByDriver;
350 
351 	Update_ODM_ComInfo_88E(Adapter);
352 	ODM_DMInit(pDM_Odm);
353 }
354 
355 
356 VOID
rtl8188e_HalDmWatchDog(IN PADAPTER Adapter)357 rtl8188e_HalDmWatchDog(
358 	IN	PADAPTER	Adapter
359 	)
360 {
361 	BOOLEAN		bFwCurrentInPSMode = _FALSE;
362 	BOOLEAN		bFwPSAwake = _TRUE;
363 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
364 	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
365 #ifdef CONFIG_CONCURRENT_MODE
366 	PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
367 #endif //CONFIG_CONCURRENT_MODE
368 
369 	_func_enter_;
370 
371 	if (!rtw_is_hw_init_completed(Adapter))
372 		goto skip_dm;
373 
374 #ifdef CONFIG_LPS
375 	bFwCurrentInPSMode = adapter_to_pwrctl(Adapter)->bFwCurrentInPSMode;
376 	rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake));
377 #endif
378 
379 #ifdef CONFIG_P2P_PS
380 	// Fw is under p2p powersaving mode, driver should stop dynamic mechanism.
381 	// modifed by thomas. 2011.06.11.
382 	if(Adapter->wdinfo.p2p_ps_mode)
383 		bFwPSAwake = _FALSE;
384 #endif //CONFIG_P2P_PS
385 
386 	if ((rtw_is_hw_init_completed(Adapter))
387 		&& ((!bFwCurrentInPSMode) && bFwPSAwake)) {
388 		//
389 		// Calculate Tx/Rx statistics.
390 		//
391 		dm_CheckStatistics(Adapter);
392 
393 		rtw_hal_check_rxfifo_full(Adapter);
394 		//
395 		// Dynamically switch RTS/CTS protection.
396 		//
397 		//dm_CheckProtection(Adapter);
398 
399 #ifdef CONFIG_PCI_HCI
400 		// 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput.
401 		// Tx Migration settings.
402 		//dm_InterruptMigration(Adapter);
403 
404 		//if(Adapter->HalFunc.TxCheckStuckHandler(Adapter))
405 		//	PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem));
406 #endif
407 
408 	}
409 
410 
411 	//ODM
412 	if (rtw_is_hw_init_completed(Adapter)) {
413 		u8	bLinked=_FALSE;
414 		u8	bsta_state=_FALSE;
415 		#ifdef CONFIG_DISABLE_ODM
416 		pHalData->odmpriv.SupportAbility = 0;
417 		#endif
418 
419 		if(rtw_linked_check(Adapter)){
420 			bLinked = _TRUE;
421 			if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE))
422 				bsta_state = _TRUE;
423 		}
424 
425 #ifdef CONFIG_CONCURRENT_MODE
426 		if(pbuddy_adapter && rtw_linked_check(pbuddy_adapter)){
427 			bLinked = _TRUE;
428 			if(pbuddy_adapter && check_fwstate(&pbuddy_adapter->mlmepriv, WIFI_STATION_STATE))
429 				bsta_state = _TRUE;
430 		}
431 #endif //CONFIG_CONCURRENT_MODE
432 
433 		ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked);
434 		ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_STATION_STATE, bsta_state);
435 
436 
437 		ODM_DMWatchdog(&pHalData->odmpriv);
438 
439 	}
440 
441 skip_dm:
442 
443 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
444 	// Check GPIO to determine current Pbc status.
445 	dm_CheckPbcGPIO(Adapter);
446 #endif
447 	return;
448 }
449 
rtl8188e_init_dm_priv(IN PADAPTER Adapter)450 void rtl8188e_init_dm_priv(IN PADAPTER Adapter)
451 {
452 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
453 	PDM_ODM_T 		podmpriv = &pHalData->odmpriv;
454 
455 	//_rtw_spinlock_init(&(pHalData->odm_stainfo_lock));
456 	Init_ODM_ComInfo_88E(Adapter);
457 	ODM_InitAllTimers(podmpriv );
458 	PHYDM_InitDebugSetting(podmpriv);
459 }
460 
rtl8188e_deinit_dm_priv(IN PADAPTER Adapter)461 void rtl8188e_deinit_dm_priv(IN PADAPTER Adapter)
462 {
463 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
464 	PDM_ODM_T 		podmpriv = &pHalData->odmpriv;
465 	//_rtw_spinlock_free(&pHalData->odm_stainfo_lock);
466 	ODM_CancelAllTimers(podmpriv);
467 }
468 
469 
470 #ifdef CONFIG_ANTENNA_DIVERSITY
471 // Add new function to reset the state of antenna diversity before link.
472 //
473 // Compare RSSI for deciding antenna
AntDivCompare8188E(PADAPTER Adapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)474 void	AntDivCompare8188E(PADAPTER Adapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
475 {
476 	//PADAPTER Adapter = pDM_Odm->Adapter ;
477 
478 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
479 	if(0 != pHalData->AntDivCfg )
480 	{
481 		//DBG_8192C("update_network=> orgRSSI(%d)(%d),newRSSI(%d)(%d)\n",dst->Rssi,query_rx_pwr_percentage(dst->Rssi),
482 		//	src->Rssi,query_rx_pwr_percentage(src->Rssi));
483 		//select optimum_antenna for before linked =>For antenna diversity
484 		if(dst->Rssi >=  src->Rssi )//keep org parameter
485 		{
486 			src->Rssi = dst->Rssi;
487 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
488 		}
489 	}
490 }
491 
492 // Add new function to reset the state of antenna diversity before link.
AntDivBeforeLink8188E(PADAPTER Adapter)493 u8 AntDivBeforeLink8188E(PADAPTER Adapter )
494 {
495 
496 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
497 	PDM_ODM_T 	pDM_Odm =&pHalData->odmpriv;
498 	SWAT_T		*pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
499 	struct mlme_priv	*pmlmepriv = &(Adapter->mlmepriv);
500 
501 	// Condition that does not need to use antenna diversity.
502 	if(pHalData->AntDivCfg==0)
503 	{
504 		//DBG_8192C("odm_AntDivBeforeLink8192C(): No AntDiv Mechanism.\n");
505 		return _FALSE;
506 	}
507 
508 	if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
509 	{
510 		return _FALSE;
511 	}
512 
513 
514 	if(pDM_SWAT_Table->SWAS_NoLink_State == 0){
515 		//switch channel
516 		pDM_SWAT_Table->SWAS_NoLink_State = 1;
517 		pDM_SWAT_Table->CurAntenna = (pDM_SWAT_Table->CurAntenna==MAIN_ANT)?AUX_ANT:MAIN_ANT;
518 
519 		//PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, pDM_SWAT_Table->CurAntenna);
520 		rtw_antenna_select_cmd(Adapter, pDM_SWAT_Table->CurAntenna, _FALSE);
521 		//DBG_8192C("%s change antenna to ANT_( %s ).....\n",__FUNCTION__, (pDM_SWAT_Table->CurAntenna==MAIN_ANT)?"MAIN":"AUX");
522 		return _TRUE;
523 	}
524 	else
525 	{
526 		pDM_SWAT_Table->SWAS_NoLink_State = 0;
527 		return _FALSE;
528 	}
529 
530 }
531 #endif
532 
533