1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
20 //============================================================
23 // This file is for 92CE/92CU dynamic mechanism only
26 //============================================================
27 #define _RTL8723A_DM_C_
29 //============================================================
31 //============================================================
33 #include <osdep_service.h>
34 #include <drv_types.h>
36 #include <rtl8723a_hal.h>
38 //============================================================
40 //============================================================
49 PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
50 u1Byte CurRate, RateThreshold;
52 if(pMgntInfo->pHTInfo->bCurBW40MHz)
53 RateThreshold = MGN_MCS1;
55 RateThreshold = MGN_MCS3;
57 if(Adapter->TxStats.CurrentInitTxRate <= RateThreshold)
59 pMgntInfo->bDmDisableProtect = TRUE;
60 DbgPrint("Forced disable protect: %x\n", Adapter->TxStats.CurrentInitTxRate);
64 pMgntInfo->bDmDisableProtect = FALSE;
65 DbgPrint("Enable protect: %x\n", Adapter->TxStats.CurrentInitTxRate);
76 if(!Adapter->MgntInfo.bMediaConnect)
79 //2008.12.10 tynli Add for getting Current_Tx_Rate_Reg flexibly.
80 rtw_hal_get_hwreg( Adapter, HW_VAR_INIT_TX_RATE, (pu1Byte)(&Adapter->TxStats.CurrentInitTxRate) );
82 // Calculate current Tx Rate(Successful transmited!!)
84 // Calculate current Rx Rate(Successful received!!)
86 //for tx tx retry count
87 rtw_hal_get_hwreg( Adapter, HW_VAR_RETRY_COUNT, (pu1Byte)(&Adapter->TxStats.NumTxRetryCount) );
91 static void dm_CheckPbcGPIO(_adapter *padapter)
94 u8 bPbcPressed = _FALSE;
96 if(!padapter->registrypriv.hw_wps_pbc)
100 tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
101 tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT);
102 rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); //enable GPIO[2] as output mode
104 tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
105 rtw_write8(padapter, GPIO_IN, tmp1byte); //reset the floating voltage level
107 tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
108 tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
109 rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); //enable GPIO[2] as input mode
111 tmp1byte =rtw_read8(padapter, GPIO_IN);
113 if (tmp1byte == 0xff)
116 if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)
121 tmp1byte = rtw_read8(padapter, GPIO_IN);
122 //RT_TRACE(COMP_IO, DBG_TRACE, ("dm_CheckPbcGPIO - %x\n", tmp1byte));
124 if (tmp1byte == 0xff || padapter->init_adpt_in_progress)
127 if((tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)==0)
133 if( _TRUE == bPbcPressed)
135 // Here we only set bPbcPressed to true
136 // After trigger PBC, the variable will be set to false
137 DBG_8723A("CheckPbcGPIO - PBC is pressed\n");
139 if ( padapter->pid[0] == 0 )
140 { // 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver.
144 rtw_signal_process(padapter->pid[0], SIGUSR1);
148 #ifdef CONFIG_PCI_HCI
151 // Perform interrupt migration dynamically to reduce CPU utilization.
154 // 1. Do not enable migration under WIFI test.
156 // Created by Roger, 2010.03.05.
159 dm_InterruptMigration(
163 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
164 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
165 bool bCurrentIntMt, bCurrentACIntDisable;
166 bool IntMtToSet = _FALSE;
167 bool ACIntToSet = _FALSE;
170 // Retrieve current interrupt migration and Tx four ACs IMR settings first.
171 bCurrentIntMt = pHalData->bInterruptMigration;
172 bCurrentACIntDisable = pHalData->bDisableTxInt;
175 // <Roger_Notes> Currently we use busy traffic for reference instead of RxIntOK counts to prevent non-linear Rx statistics
176 // when interrupt migration is set before. 2010.03.05.
178 if(!Adapter->registrypriv.wifi_spec &&
179 (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) &&
180 pmlmepriv->LinkDetectInfo.bHigherBusyTraffic)
184 // To check whether we should disable Tx interrupt or not.
185 if(pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic )
189 //Update current settings.
190 if( bCurrentIntMt != IntMtToSet ){
191 DBG_8723A("%s(): Update interrrupt migration(%d)\n",__FUNCTION__,IntMtToSet);
195 // <Roger_Notes> Set interrrupt migration timer and corresponging Tx/Rx counter.
196 // timer 25ns*0xfa0=100us for 0xf packets.
199 rtw_write32(Adapter, REG_INT_MIG, 0xff000fa0);// 0x306:Rx, 0x307:Tx
200 pHalData->bInterruptMigration = IntMtToSet;
204 // Reset all interrupt migration settings.
205 rtw_write32(Adapter, REG_INT_MIG, 0);
206 pHalData->bInterruptMigration = IntMtToSet;
210 /*if( bCurrentACIntDisable != ACIntToSet ){
211 DBG_8723A("%s(): Update AC interrrupt(%d)\n",__FUNCTION__,ACIntToSet);
212 if(ACIntToSet) // Disable four ACs interrupts.
215 // <Roger_Notes> Disable VO, VI, BE and BK four AC interrupts to gain more efficient CPU utilization.
216 // When extremely highly Rx OK occurs, we will disable Tx interrupts.
219 UpdateInterruptMask8192CE( Adapter, 0, RT_AC_INT_MASKS );
220 pHalData->bDisableTxInt = ACIntToSet;
222 else// Enable four ACs interrupts.
224 UpdateInterruptMask8192CE( Adapter, RT_AC_INT_MASKS, 0 );
225 pHalData->bDisableTxInt = ACIntToSet;
234 // Initialize GPIO setting registers
241 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
245 tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
246 tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
248 rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
250 //============================================================
252 //============================================================
253 static void Init_ODM_ComInfo_8723a(PADAPTER Adapter)
256 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
257 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
263 memset(pDM_Odm, 0, sizeof(*pDM_Odm));
265 pDM_Odm->Adapter = Adapter;
266 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_PLATFORM,ODM_CE);
267 if(Adapter->interface_type == RTW_GSPI )
268 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_INTERFACE,ODM_ITRF_SDIO);
270 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_INTERFACE,Adapter->interface_type);//RTL871X_HCI_TYPE
272 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_IC_TYPE,ODM_RTL8723A);
275 if(IS_8723A_A_CUT(pHalData->VersionID))
280 else if(IS_8723A_B_CUT(pHalData->VersionID))
290 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_FAB_VER,fab_ver);
291 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_CUT_VER,cut_ver);
292 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_MP_TEST_CHIP,IS_NORMAL_CHIP(pHalData->VersionID));
294 #ifdef CONFIG_USB_HCI
295 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_BOARD_TYPE,pHalData->BoardType);
297 if(pHalData->BoardType == BOARD_USB_High_PA){
298 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_EXT_LNA,_TRUE);
299 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_EXT_PA,_TRUE);
302 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_PATCH_ID,pHalData->CustomerID);
303 // ODM_CMNINFO_BINHCT_TEST only for MP Team
304 ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_BWIFI_TEST,Adapter->registrypriv.wifi_spec);
307 if(pHalData->rf_type == RF_1T1R){
308 ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_RF_TYPE,ODM_1T1R);
310 else if(pHalData->rf_type == RF_2T2R){
311 ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_RF_TYPE,ODM_2T2R);
313 else if(pHalData->rf_type == RF_1T2R){
314 ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_RF_TYPE,ODM_1T2R);
317 static void Update_ODM_ComInfo_8723a(PADAPTER Adapter)
319 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
320 struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
321 struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
322 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
323 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
324 struct dm_priv *pdmpriv = &pHalData->dmpriv;
326 pdmpriv->InitODMFlag = ODM_BB_DIG |
327 #ifdef CONFIG_ODM_REFRESH_RAMASK
330 ODM_BB_DYNAMIC_TXPWR |
332 ODM_BB_RSSI_MONITOR |
336 ODM_RF_TX_PWR_TRACK |
341 //ODM_CMNINFO_MAC_PHY_MODE pHalData->MacPhyMode92D
342 // ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_MAC_PHY_MODE,&(pDM_Odm->u1Byte_temp));
345 #ifdef CONFIG_ANTENNA_DIVERSITY
346 if(pHalData->AntDivCfg)
347 pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV;
350 ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_ABILITY,pdmpriv->InitODMFlag);
352 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_TX_UNI,&(Adapter->xmitpriv.tx_bytes));
353 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_RX_UNI,&(Adapter->recvpriv.rx_bytes));
354 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_WM_MODE,&(pmlmeext->cur_wireless_mode));
355 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_SEC_CHNL_OFFSET,&(pHalData->nCur40MhzPrimeSC));
356 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_SEC_MODE,&(Adapter->securitypriv.dot11PrivacyAlgrthm));
357 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BW,&(pHalData->CurrentChannelBW ));
358 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_CHNL,&( pHalData->CurrentChannel));
359 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_NET_CLOSED,&( Adapter->net_closed));
361 //================= only for 8192D =================
363 //pHalData->CurrentBandType92D
364 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BAND,&(pDM_Odm->u1Byte_temp));
365 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_DMSP_GET_VALUE,&(pDM_Odm->u1Byte_temp));
366 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BUDDY_ADAPTOR,&(pDM_Odm->PADAPTER_temp));
367 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_DMSP_IS_MASTER,&(pDM_Odm->u1Byte_temp));
368 //================= only for 8192D =================
369 // driver havn't those variable now
370 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BT_OPERATION,&(pDM_Odm->u1Byte_temp));
371 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BT_DISABLE_EDCA,&(pDM_Odm->u1Byte_temp));
374 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_SCAN,&(pmlmepriv->bScanInProcess));
375 ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_POWER_SAVING,&(pwrctrlpriv->bpower_saving));
378 for(i=0; i< NUM_STA; i++)
380 //pDM_Odm->pODM_StaInfo[i] = NULL;
381 ODM_CmnInfoPtrArrayHook(pDM_Odm, ODM_CMNINFO_STA_STATUS,i,NULL);
390 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
391 struct dm_priv *pdmpriv = &pHalData->dmpriv;
392 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
396 pdmpriv->DM_Type = DM_Type_ByDriver;
397 pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE;
399 #ifdef CONFIG_BT_COEXIST
400 pdmpriv->DMFlag |= DYNAMIC_FUNC_BT;
401 // btdm_InitBtCoexistDM(Adapter); // Move to BT_CoexistMechanism()
403 pdmpriv->InitDMFlag = pdmpriv->DMFlag;
405 Update_ODM_ComInfo_8723a(Adapter);
407 // Save REG_INIDATA_RATE_SEL value for TXDESC.
408 for(i = 0 ; i<32 ; i++)
410 pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL+i) & 0x3f;
416 rtl8723a_HalDmWatchDog(
420 bool bFwCurrentInPSMode = _FALSE;
421 bool bFwPSAwake = _TRUE;
422 u8 hw_init_completed = _FALSE;
423 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
424 struct dm_priv *pdmpriv = &pHalData->dmpriv;
425 #ifdef CONFIG_CONCURRENT_MODE
426 PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
427 #endif //CONFIG_CONCURRENT_MODE
429 hw_init_completed = Adapter->hw_init_completed;
431 if (hw_init_completed == _FALSE)
435 #ifdef CONFIG_CONCURRENT_MODE
436 if (Adapter->iface_type != IFACE_PORT0 && pbuddy_adapter) {
437 bFwCurrentInPSMode = pbuddy_adapter->pwrctrlpriv.bFwCurrentInPSMode;
438 rtw_hal_get_hwreg(pbuddy_adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake));
440 #endif //CONFIG_CONCURRENT_MODE
442 bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode;
443 rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake));
448 // Fw is under p2p powersaving mode, driver should stop dynamic mechanism.
449 // modifed by thomas. 2011.06.11.
450 if(Adapter->wdinfo.p2p_ps_mode)
452 #endif //CONFIG_P2P_PS
454 if( (hw_init_completed == _TRUE)
455 && ((!bFwCurrentInPSMode) && bFwPSAwake))
458 // Calculate Tx/Rx statistics.
460 dm_CheckStatistics(Adapter);
463 #ifdef CONFIG_CONCURRENT_MODE
464 if(Adapter->adapter_type > PRIMARY_ADAPTER)
465 goto _record_initrate;
469 // Dynamically switch RTS/CTS protection.
471 //dm_CheckProtection(Adapter);
473 #ifdef CONFIG_PCI_HCI
474 // 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput.
475 // Tx Migration settings.
476 //dm_InterruptMigration(Adapter);
478 //if(Adapter->HalFunc.TxCheckStuckHandler(Adapter))
479 // PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem));
483 // Read REG_INIDATA_RATE_SEL value for TXDESC.
484 if(check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
486 pdmpriv->INIDATA_RATE[0] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL) & 0x3f;
491 for(i=1 ; i < (Adapter->stapriv.asoc_sta_count + 1); i++)
493 pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, (REG_INIDATA_RATE_SEL+i)) & 0x3f;
500 if (hw_init_completed == _TRUE)
504 #ifdef CONFIG_DISABLE_ODM
505 pHalData->odmpriv.SupportAbility = 0;
508 if(rtw_linked_check(Adapter))
511 #ifdef CONFIG_CONCURRENT_MODE
512 if(pbuddy_adapter && rtw_linked_check(pbuddy_adapter))
514 #endif //CONFIG_CONCURRENT_MODE
516 ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked);
517 ODM_DMWatchdog(&pHalData->odmpriv);
523 // Check GPIO to determine current RF on/off and Pbc status.
524 // Check Hardware Radio ON/OFF or not
525 #ifdef CONFIG_PCI_HCI
526 if(pHalData->bGpioHwWpsPbc)
529 dm_CheckPbcGPIO(Adapter); // Add by hpfan 2008-03-11
534 void rtl8723a_init_dm_priv(IN PADAPTER Adapter)
536 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
537 struct dm_priv *pdmpriv = &pHalData->dmpriv;
538 PDM_ODM_T podmpriv = &pHalData->odmpriv;
539 memset(pdmpriv, 0, sizeof(struct dm_priv));
540 Init_ODM_ComInfo_8723a(Adapter);
541 #ifdef CONFIG_SW_ANTENNA_DIVERSITY
542 //_init_timer(&(pdmpriv->SwAntennaSwitchTimer), Adapter->pnetdev , odm_SW_AntennaSwitchCallback, Adapter);
543 ODM_InitAllTimers(podmpriv );
547 void rtl8723a_deinit_dm_priv(IN PADAPTER Adapter)
549 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
550 struct dm_priv *pdmpriv = &pHalData->dmpriv;
551 PDM_ODM_T podmpriv = &pHalData->odmpriv;
552 #ifdef CONFIG_SW_ANTENNA_DIVERSITY
553 //_cancel_timer_ex(&pdmpriv->SwAntennaSwitchTimer);
554 ODM_CancelAllTimers(podmpriv);