1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
\r
5 * This program is free software; you can redistribute it and/or modify it
\r
6 * under the terms of version 2 of the GNU General Public License as
\r
7 * published by the Free Software Foundation.
\r
9 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
14 * You should have received a copy of the GNU General Public License along with
\r
15 * this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
\r
19 ******************************************************************************/
\r
20 //============================================================
\r
23 // This file is for 92CE/92CU dynamic mechanism only
\r
26 //============================================================
\r
27 #define _RTL8723B_DM_C_
\r
29 //============================================================
\r
31 //============================================================
\r
32 #include <rtl8723b_hal.h>
\r
34 //============================================================
\r
36 //============================================================
\r
45 PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
\r
46 u1Byte CurRate, RateThreshold;
\r
48 if(pMgntInfo->pHTInfo->bCurBW40MHz)
\r
49 RateThreshold = MGN_MCS1;
\r
51 RateThreshold = MGN_MCS3;
\r
53 if(Adapter->TxStats.CurrentInitTxRate <= RateThreshold)
\r
55 pMgntInfo->bDmDisableProtect = TRUE;
\r
56 DbgPrint("Forced disable protect: %x\n", Adapter->TxStats.CurrentInitTxRate);
\r
60 pMgntInfo->bDmDisableProtect = FALSE;
\r
61 DbgPrint("Enable protect: %x\n", Adapter->TxStats.CurrentInitTxRate);
\r
72 if(!Adapter->MgntInfo.bMediaConnect)
\r
75 //2008.12.10 tynli Add for getting Current_Tx_Rate_Reg flexibly.
\r
76 rtw_hal_get_hwreg( Adapter, HW_VAR_INIT_TX_RATE, (pu1Byte)(&Adapter->TxStats.CurrentInitTxRate) );
\r
78 // Calculate current Tx Rate(Successful transmited!!)
\r
80 // Calculate current Rx Rate(Successful received!!)
\r
82 //for tx tx retry count
\r
83 rtw_hal_get_hwreg( Adapter, HW_VAR_RETRY_COUNT, (pu1Byte)(&Adapter->TxStats.NumTxRetryCount) );
\r
86 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
\r
87 static void dm_CheckPbcGPIO(_adapter *padapter)
\r
90 u8 bPbcPressed = _FALSE;
\r
92 if(!padapter->registrypriv.hw_wps_pbc)
\r
95 #ifdef CONFIG_USB_HCI
\r
96 tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
\r
97 tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT);
\r
98 rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); //enable GPIO[2] as output mode
\r
100 tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
\r
101 rtw_write8(padapter, GPIO_IN, tmp1byte); //reset the floating voltage level
\r
103 tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
\r
104 tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
\r
105 rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); //enable GPIO[2] as input mode
\r
107 tmp1byte =rtw_read8(padapter, GPIO_IN);
\r
109 if (tmp1byte == 0xff)
\r
112 if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)
\r
114 bPbcPressed = _TRUE;
\r
117 tmp1byte = rtw_read8(padapter, GPIO_IN);
\r
118 //RT_TRACE(COMP_IO, DBG_TRACE, ("dm_CheckPbcGPIO - %x\n", tmp1byte));
\r
120 if (tmp1byte == 0xff || padapter->init_adpt_in_progress)
\r
123 if((tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)==0)
\r
125 bPbcPressed = _TRUE;
\r
129 if( _TRUE == bPbcPressed)
\r
131 // Here we only set bPbcPressed to true
\r
132 // After trigger PBC, the variable will be set to false
\r
133 DBG_8192C("CheckPbcGPIO - PBC is pressed\n");
\r
134 rtw_request_wps_pbc_event(padapter);
\r
137 #endif //#ifdef CONFIG_SUPPORT_HW_WPS_PBC
\r
140 #ifdef CONFIG_PCI_HCI
\r
143 // Perform interrupt migration dynamically to reduce CPU utilization.
\r
146 // 1. Do not enable migration under WIFI test.
\r
148 // Created by Roger, 2010.03.05.
\r
151 dm_InterruptMigration(
\r
152 IN PADAPTER Adapter
\r
155 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
\r
156 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
\r
157 BOOLEAN bCurrentIntMt, bCurrentACIntDisable;
\r
158 BOOLEAN IntMtToSet = _FALSE;
\r
159 BOOLEAN ACIntToSet = _FALSE;
\r
162 // Retrieve current interrupt migration and Tx four ACs IMR settings first.
\r
163 bCurrentIntMt = pHalData->bInterruptMigration;
\r
164 bCurrentACIntDisable = pHalData->bDisableTxInt;
\r
167 // <Roger_Notes> Currently we use busy traffic for reference instead of RxIntOK counts to prevent non-linear Rx statistics
\r
168 // when interrupt migration is set before. 2010.03.05.
\r
170 if(!Adapter->registrypriv.wifi_spec &&
\r
171 (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) &&
\r
172 pmlmepriv->LinkDetectInfo.bHigherBusyTraffic)
\r
174 IntMtToSet = _TRUE;
\r
176 // To check whether we should disable Tx interrupt or not.
\r
177 if(pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic )
\r
178 ACIntToSet = _TRUE;
\r
181 //Update current settings.
\r
182 if( bCurrentIntMt != IntMtToSet ){
\r
183 DBG_8192C("%s(): Update interrrupt migration(%d)\n",__FUNCTION__,IntMtToSet);
\r
187 // <Roger_Notes> Set interrrupt migration timer and corresponging Tx/Rx counter.
\r
188 // timer 25ns*0xfa0=100us for 0xf packets.
\r
191 rtw_write32(Adapter, REG_INT_MIG, 0xff000fa0);// 0x306:Rx, 0x307:Tx
\r
192 pHalData->bInterruptMigration = IntMtToSet;
\r
196 // Reset all interrupt migration settings.
\r
197 rtw_write32(Adapter, REG_INT_MIG, 0);
\r
198 pHalData->bInterruptMigration = IntMtToSet;
\r
202 /*if( bCurrentACIntDisable != ACIntToSet ){
\r
203 DBG_8192C("%s(): Update AC interrrupt(%d)\n",__FUNCTION__,ACIntToSet);
\r
204 if(ACIntToSet) // Disable four ACs interrupts.
\r
207 // <Roger_Notes> Disable VO, VI, BE and BK four AC interrupts to gain more efficient CPU utilization.
\r
208 // When extremely highly Rx OK occurs, we will disable Tx interrupts.
\r
211 UpdateInterruptMask8192CE( Adapter, 0, RT_AC_INT_MASKS );
\r
212 pHalData->bDisableTxInt = ACIntToSet;
\r
214 else// Enable four ACs interrupts.
\r
216 UpdateInterruptMask8192CE( Adapter, RT_AC_INT_MASKS, 0 );
\r
217 pHalData->bDisableTxInt = ACIntToSet;
\r
226 // Initialize GPIO setting registers
\r
229 dm_InitGPIOSetting(
\r
230 IN PADAPTER Adapter
\r
233 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
237 tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
\r
238 tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
\r
240 rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
\r
242 //============================================================
\r
244 //============================================================
\r
245 static void Init_ODM_ComInfo_8723b(PADAPTER Adapter)
\r
247 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
248 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
\r
249 u32 SupportAbility = 0;
\r
250 u8 cut_ver,fab_ver;
\r
252 Init_ODM_ComInfo(Adapter);
\r
254 ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PACKAGE_TYPE, pHalData->PackageType);
\r
255 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_IC_TYPE, ODM_RTL8723B);
\r
257 fab_ver = ODM_TSMC;
\r
258 cut_ver = ODM_CUT_A;
\r
260 DBG_871X("%s(): fab_ver=%d cut_ver=%d\n", __func__, fab_ver, cut_ver);
\r
261 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_FAB_VER,fab_ver);
\r
262 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_CUT_VER,cut_ver);
\r
264 #ifdef CONFIG_DISABLE_ODM
\r
265 SupportAbility = 0;
\r
267 SupportAbility = ODM_RF_CALIBRATION |
\r
268 ODM_RF_TX_PWR_TRACK
\r
270 /*if(pHalData->AntDivCfg)
\r
271 SupportAbility |= ODM_BB_ANT_DIV;*/
\r
274 ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_ABILITY,SupportAbility);
\r
277 static void Update_ODM_ComInfo_8723b(PADAPTER Adapter)
\r
279 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
280 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
\r
281 u32 SupportAbility = 0;
\r
286 | ODM_BB_DYNAMIC_TXPWR
\r
288 | ODM_BB_RSSI_MONITOR
\r
290 //| ODM_BB_PWR_SAVE
\r
291 | ODM_BB_CFO_TRACKING
\r
292 | ODM_MAC_EDCA_TURBO
\r
293 | ODM_RF_TX_PWR_TRACK
\r
294 | ODM_RF_CALIBRATION
\r
296 // | ODM_BB_PWR_TRAIN
\r
299 if (rtw_odm_adaptivity_needed(Adapter) == _TRUE)
\r
300 SupportAbility |= ODM_BB_ADAPTIVITY;
\r
302 #ifdef CONFIG_ANTENNA_DIVERSITY
\r
303 if(pHalData->AntDivCfg)
\r
304 SupportAbility |= ODM_BB_ANT_DIV;
\r
308 if (Adapter->registrypriv.mp_mode == 1) {
\r
310 | ODM_RF_CALIBRATION
\r
311 | ODM_RF_TX_PWR_TRACK
\r
314 #endif//(MP_DRIVER==1)
\r
316 #ifdef CONFIG_DISABLE_ODM
\r
317 SupportAbility = 0;
\r
318 #endif//CONFIG_DISABLE_ODM
\r
320 ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_ABILITY,SupportAbility);
\r
324 rtl8723b_InitHalDm(
\r
325 IN PADAPTER Adapter
\r
328 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
329 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
\r
333 #ifdef CONFIG_USB_HCI
\r
334 dm_InitGPIOSetting(Adapter);
\r
337 pHalData->DM_Type = DM_Type_ByDriver;
\r
339 Update_ODM_ComInfo_8723b(Adapter);
\r
341 if (Adapter->registrypriv.mp_mode == 0)
\r
342 ODM_DMInit(pDM_Odm);
\r
347 rtl8723b_HalDmWatchDog(
\r
348 IN PADAPTER Adapter
\r
351 BOOLEAN bFwCurrentInPSMode = _FALSE;
\r
352 BOOLEAN bFwPSAwake = _TRUE;
\r
353 u8 hw_init_completed = _FALSE;
\r
354 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
355 #ifdef CONFIG_CONCURRENT_MODE
\r
356 PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
\r
357 #endif //CONFIG_CONCURRENT_MODE
\r
360 if (Adapter->registrypriv.mp_mode == 1 && Adapter->mppriv.mp_dm ==0) // for MP power tracking
\r
364 hw_init_completed = Adapter->hw_init_completed;
\r
366 if (hw_init_completed == _FALSE)
\r
370 bFwCurrentInPSMode = adapter_to_pwrctl(Adapter)->bFwCurrentInPSMode;
\r
371 rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake));
\r
375 // Fw is under p2p powersaving mode, driver should stop dynamic mechanism.
\r
376 // modifed by thomas. 2011.06.11.
\r
377 if(Adapter->wdinfo.p2p_ps_mode)
\r
378 bFwPSAwake = _FALSE;
\r
379 #endif //CONFIG_P2P
\r
382 if( (hw_init_completed == _TRUE)
\r
383 && ((!bFwCurrentInPSMode) && bFwPSAwake))
\r
386 // Calculate Tx/Rx statistics.
\r
388 dm_CheckStatistics(Adapter);
\r
389 rtw_hal_check_rxfifo_full(Adapter);
\r
391 // Dynamically switch RTS/CTS protection.
\r
393 //dm_CheckProtection(Adapter);
\r
395 #ifdef CONFIG_PCI_HCI
\r
396 // 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput.
\r
397 // Tx Migration settings.
\r
398 //dm_InterruptMigration(Adapter);
\r
400 //if(Adapter->HalFunc.TxCheckStuckHandler(Adapter))
\r
401 // PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem));
\r
406 if (hw_init_completed == _TRUE)
\r
409 u8 bsta_state=_FALSE;
\r
410 u8 bBtDisabled = _TRUE;
\r
412 if(rtw_linked_check(Adapter)){
\r
414 if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE))
\r
415 bsta_state = _TRUE;
\r
418 #ifdef CONFIG_CONCURRENT_MODE
\r
419 if(pbuddy_adapter && rtw_linked_check(pbuddy_adapter)){
\r
421 if(pbuddy_adapter && check_fwstate(&pbuddy_adapter->mlmepriv, WIFI_STATION_STATE))
\r
422 bsta_state = _TRUE;
\r
424 #endif //CONFIG_CONCURRENT_MODE
\r
426 ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked);
\r
427 ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_STATION_STATE, bsta_state);
\r
429 //ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM);
\r
431 #ifdef CONFIG_BT_COEXIST
\r
432 bBtDisabled = rtw_btcoex_IsBtDisabled(Adapter);
\r
433 #endif // CONFIG_BT_COEXIST
\r
434 ODM_CmnInfoUpdate(&pHalData->odmpriv, ODM_CMNINFO_BT_ENABLED, ((bBtDisabled == _TRUE)?_FALSE:_TRUE));
\r
436 ODM_DMWatchdog(&pHalData->odmpriv);
\r
441 // Check GPIO to determine current RF on/off and Pbc status.
\r
442 // Check Hardware Radio ON/OFF or not
\r
443 //if(Adapter->MgntInfo.PowerSaveControl.bGpioRfSw)
\r
445 //RTPRINT(FPWR, PWRHW, ("dm_CheckRfCtrlGPIO \n"));
\r
446 // dm_CheckRfCtrlGPIO(Adapter);
\r
448 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
\r
449 dm_CheckPbcGPIO(Adapter);
\r
454 void rtl8723b_hal_dm_in_lps(PADAPTER padapter)
\r
457 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
458 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
\r
459 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
\r
460 pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
\r
461 struct sta_priv *pstapriv = &padapter->stapriv;
\r
462 struct sta_info *psta = NULL;
\r
464 DBG_871X("%s, RSSI_Min=%d\n", __func__, pDM_Odm->RSSI_Min);
\r
467 ODM_Write_DIG(pDM_Odm, pDM_Odm->RSSI_Min);
\r
471 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
472 if(psta && (psta->rssi_stat.UndecoratedSmoothedPWDB > 0))
\r
474 PWDB_rssi = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16) );
\r
476 rtl8723b_set_rssi_cmd(padapter, (u8*)&PWDB_rssi);
\r
481 void rtl8723b_HalDmWatchDog_in_LPS(IN PADAPTER Adapter)
\r
484 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
485 struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
\r
486 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
\r
487 pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
\r
488 struct sta_priv *pstapriv = &Adapter->stapriv;
\r
489 struct sta_info *psta = NULL;
\r
490 #ifdef CONFIG_CONCURRENT_MODE
\r
491 PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
\r
492 #endif //CONFIG_CONCURRENT_MODE
\r
494 if (Adapter->hw_init_completed == _FALSE)
\r
498 if(rtw_linked_check(Adapter))
\r
501 #ifdef CONFIG_CONCURRENT_MODE
\r
502 if (pbuddy_adapter && rtw_linked_check(pbuddy_adapter))
\r
504 #endif //CONFIG_CONCURRENT_MODE
\r
506 ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked);
\r
508 if(bLinked == _FALSE)
\r
511 if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR))
\r
515 //ODM_DMWatchdog(&pHalData->odmpriv);
\r
516 //Do DIG by RSSI In LPS-32K
\r
519 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
523 pHalData->EntryMinUndecoratedSmoothedPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
\r
525 DBG_871X("CurIGValue=%d, EntryMinUndecoratedSmoothedPWDB = %d\n", pDM_DigTable->CurIGValue, pHalData->EntryMinUndecoratedSmoothedPWDB );
\r
527 if(pHalData->EntryMinUndecoratedSmoothedPWDB <=0)
\r
530 pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB;
\r
532 pDM_Odm->RSSI_Min = pHalData->MinUndecoratedPWDBForDM;
\r
534 //if(pDM_DigTable->CurIGValue != pDM_Odm->RSSI_Min)
\r
535 if((pDM_DigTable->CurIGValue > pDM_Odm->RSSI_Min + 5) ||
\r
536 (pDM_DigTable->CurIGValue < pDM_Odm->RSSI_Min - 5))
\r
539 rtw_dm_in_lps_wk_cmd(Adapter);
\r
549 void rtl8723b_init_dm_priv(IN PADAPTER Adapter)
\r
551 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
552 PDM_ODM_T podmpriv = &pHalData->odmpriv;
\r
553 Init_ODM_ComInfo_8723b(Adapter);
\r
554 ODM_InitAllTimers(podmpriv );
\r
557 void rtl8723b_deinit_dm_priv(IN PADAPTER Adapter)
\r
559 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
560 PDM_ODM_T podmpriv = &pHalData->odmpriv;
\r
561 ODM_CancelAllTimers(podmpriv);
\r