diff options
Diffstat (limited to 'drivers/staging/rtl8192e/rtl_ps.c')
-rw-r--r-- | drivers/staging/rtl8192e/rtl_ps.c | 649 |
1 files changed, 649 insertions, 0 deletions
diff --git a/drivers/staging/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl_ps.c new file mode 100644 index 000000000000..cf401352c627 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_ps.c @@ -0,0 +1,649 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + *****************************************************************************/ +#include "rtl_ps.h" +#include "rtl_core.h" +#include "r8192E_phy.h" +#include "r8192E_phyreg.h" +#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ +#include "r8192E_cmdpkt.h" + +void rtl8192_hw_sleep_down(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + unsigned long flags = 0; +#ifdef CONFIG_ASPM_OR_D3 + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); +#endif + spin_lock_irqsave(&priv->rf_ps_lock,flags); + if (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + RT_TRACE(COMP_DBG, "rtl8192_hw_sleep_down(): RF Change in progress! \n"); + return; + } + spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + RT_TRACE(COMP_DBG, "%s()============>come to sleep down\n", __func__); + +#ifdef CONFIG_RTLWIFI_DEBUGFS + if (priv->debug->hw_holding) { + return; + } +#endif + MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS,false); +#ifdef CONFIG_ASPM_OR_D3 + if (pPSC->RegRfPsLevel & RT_RF_LPS_LEVEL_ASPM) + { + RT_ENABLE_ASPM(dev); + RT_SET_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM); + } +#endif +} + +void rtl8192_hw_sleep_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data,struct rtllib_device,hw_sleep_wq); + struct net_device *dev = ieee->dev; + rtl8192_hw_sleep_down(dev); +} + +void rtl8192_hw_wakeup(struct net_device* dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + unsigned long flags = 0; +#ifdef CONFIG_ASPM_OR_D3 + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); +#endif + spin_lock_irqsave(&priv->rf_ps_lock,flags); + if (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + RT_TRACE(COMP_DBG, "rtl8192_hw_wakeup(): RF Change in progress! \n"); + queue_delayed_work_rsl(priv->rtllib->wq,&priv->rtllib->hw_wakeup_wq,MSECS(10)); + return; + } + spin_unlock_irqrestore(&priv->rf_ps_lock,flags); +#ifdef CONFIG_ASPM_OR_D3 + if (pPSC->RegRfPsLevel & RT_RF_LPS_LEVEL_ASPM) { + RT_DISABLE_ASPM(dev); + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM); + } +#endif + RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __func__); + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS,false); +} + +void rtl8192_hw_wakeup_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data,struct rtllib_device,hw_wakeup_wq); + struct net_device *dev = ieee->dev; + rtl8192_hw_wakeup(dev); + +} + +#define MIN_SLEEP_TIME 50 +#define MAX_SLEEP_TIME 10000 +void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + u32 rb = jiffies; + unsigned long flags; + + spin_lock_irqsave(&priv->ps_lock,flags); + + tl -= MSECS(8+16+7); + + if (((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME)) + ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { + spin_unlock_irqrestore(&priv->ps_lock,flags); + printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME)); + return; + } + + if (((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))|| + ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))|| + ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) { + printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME)); + spin_unlock_irqrestore(&priv->ps_lock,flags); + return; + } + { + u32 tmp = (tl>rb)?(tl-rb):(rb-tl); + queue_delayed_work_rsl(priv->rtllib->wq, + &priv->rtllib->hw_wakeup_wq,tmp); + } + queue_delayed_work_rsl(priv->rtllib->wq, + (void *)&priv->rtllib->hw_sleep_wq,0); + spin_unlock_irqrestore(&priv->ps_lock,flags); +} + +void InactivePsWorkItemCallback(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); + + RT_TRACE(COMP_PS, "InactivePsWorkItemCallback() ---------> \n"); + pPSC->bSwRfProcessing = true; + + RT_TRACE(COMP_PS, "InactivePsWorkItemCallback(): Set RF to %s.\n", \ + pPSC->eInactivePowerState == eRfOff?"OFF":"ON"); +#ifdef CONFIG_ASPM_OR_D3 + if (pPSC->eInactivePowerState == eRfOn) + { + + if ((pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_ASPM) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_ASPM)) + { + RT_DISABLE_ASPM(dev); + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_ASPM); + } +#ifdef TODO + else if ((pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_PCI_D3) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_PCI_D3)) + { + RT_LEAVE_D3(dev, false); + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_PCI_D3); + } +#endif + } +#endif + MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS,false); + +#ifdef CONFIG_ASPM_OR_D3 + if (pPSC->eInactivePowerState == eRfOff) + { + if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_ASPM) + { + RT_ENABLE_ASPM(dev); + RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_ASPM); + } +#ifdef TODO + else if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_PCI_D3) + { + RT_ENTER_D3(dev, false); + RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_PCI_D3); + } +#endif + } +#endif + + pPSC->bSwRfProcessing = false; + RT_TRACE(COMP_PS, "InactivePsWorkItemCallback() <--------- \n"); +} + +void +IPSEnter(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); + RT_RF_POWER_STATE rtState; + + if (pPSC->bInactivePs) + { + rtState = priv->rtllib->eRFPowerState; + if (rtState == eRfOn && !pPSC->bSwRfProcessing &&\ + (priv->rtllib->state != RTLLIB_LINKED)&&\ + (priv->rtllib->iw_mode != IW_MODE_MASTER)) + { + RT_TRACE(COMP_PS,"IPSEnter(): Turn off RF.\n"); + pPSC->eInactivePowerState = eRfOff; + priv->isRFOff = true; + priv->bInPowerSaveMode = true; + InactivePsWorkItemCallback(dev); + } + } +} + +void +IPSLeave(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); + RT_RF_POWER_STATE rtState; + + if (pPSC->bInactivePs) + { + rtState = priv->rtllib->eRFPowerState; + if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->rtllib->RfOffReason <= RF_CHANGE_BY_IPS) + { + RT_TRACE(COMP_PS, "IPSLeave(): Turn on RF.\n"); + pPSC->eInactivePowerState = eRfOn; + priv->bInPowerSaveMode = false; + InactivePsWorkItemCallback(dev); + } + } +} +void IPSLeave_wq(void *data) +{ + struct rtllib_device *ieee = container_of_work_rsl(data,struct rtllib_device,ips_leave_wq); + struct net_device *dev = ieee->dev; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); +} + +void rtllib_ips_leave_wq(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + RT_RF_POWER_STATE rtState; + rtState = priv->rtllib->eRFPowerState; + + if (priv->rtllib->PowerSaveControl.bInactivePs){ + if (rtState == eRfOff){ + if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) + { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__func__); + return; + } + else{ + printk("=========>%s(): IPSLeave\n",__func__); + queue_work_rsl(priv->rtllib->wq,&priv->rtllib->ips_leave_wq); + } + } + } +} +void rtllib_ips_leave(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); +} + +bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) + return false; + + RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__func__,rtPsMode); + if (!priv->ps_force) { + priv->rtllib->ps = rtPsMode; + } + if (priv->rtllib->sta_sleep != LPS_IS_WAKE && rtPsMode == RTLLIB_PS_DISABLED) { + unsigned long flags; + + rtl8192_hw_wakeup(dev); + priv->rtllib->sta_sleep = LPS_IS_WAKE; + + spin_lock_irqsave(&(priv->rtllib->mgmt_tx_lock), flags); + RT_TRACE(COMP_DBG, "LPS leave: notify AP we are awaked" + " ++++++++++ SendNullFunctionData\n"); + rtllib_sta_ps_send_null_frame(priv->rtllib, 0); + spin_unlock_irqrestore(&(priv->rtllib->mgmt_tx_lock), flags); + } + + return true; +} + + +void LeisurePSEnter(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); + + RT_TRACE(COMP_PS, "LeisurePSEnter()...\n"); + RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n", + pPSC->bLeisurePs, priv->rtllib->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD); + + if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) && (priv->rtllib->state == RTLLIB_LINKED)) + || (priv->rtllib->iw_mode == IW_MODE_ADHOC) || (priv->rtllib->iw_mode == IW_MODE_MASTER)) + return; + + if (pPSC->bLeisurePs) { + if (pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) { + + if (priv->rtllib->ps == RTLLIB_PS_DISABLED) { + + RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n"); + + if (!pPSC->bFwCtrlLPS) { + if (priv->rtllib->SetFwCmdHandler) + priv->rtllib->SetFwCmdHandler(dev, FW_CMD_LPS_ENTER); + } + MgntActSet_802_11_PowerSaveMode(dev, RTLLIB_PS_MBCAST|RTLLIB_PS_UNICAST); + } + } else + pPSC->LpsIdleCount++; + } +} + + +void LeisurePSLeave(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); + + + RT_TRACE(COMP_PS, "LeisurePSLeave()...\n"); + RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n", + pPSC->bLeisurePs, priv->rtllib->ps); + + if (pPSC->bLeisurePs) + { + if (priv->rtllib->ps != RTLLIB_PS_DISABLED) + { +#ifdef CONFIG_ASPM_OR_D3 + if (pPSC->RegRfPsLevel & RT_RF_LPS_LEVEL_ASPM && RT_IN_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM)) + { + RT_DISABLE_ASPM(dev); + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM); + } +#endif + RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n"); + MgntActSet_802_11_PowerSaveMode(dev, RTLLIB_PS_DISABLED); + + if (!pPSC->bFwCtrlLPS) + { + if (priv->rtllib->SetFwCmdHandler) + { + priv->rtllib->SetFwCmdHandler(dev, FW_CMD_LPS_LEAVE); + } + } + } + } +} + +#ifdef CONFIG_ASPM_OR_D3 + +void +PlatformDisableHostL0s(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + u32 PciCfgAddrPort=0; + u8 Num4Bytes; + u8 uPciBridgeASPMSetting = 0; + + + if ( (priv->NdisAdapter.BusNumber == 0xff && priv->NdisAdapter.DevNumber == 0xff && priv->NdisAdapter.FuncNumber == 0xff) || + (priv->NdisAdapter.PciBridgeBusNum == 0xff && priv->NdisAdapter.PciBridgeDevNum == 0xff && priv->NdisAdapter.PciBridgeFuncNum == 0xff) ) + { + printk("PlatformDisableHostL0s(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n"); + return; + } + + PciCfgAddrPort= (priv->NdisAdapter.PciBridgeBusNum << 16)|(priv->NdisAdapter.PciBridgeDevNum<< 11)|(priv->NdisAdapter.PciBridgeFuncNum << 8)|(1 << 31); + Num4Bytes = (priv->NdisAdapter.PciBridgePCIeHdrOffset+0x10)/4; + + + NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+(Num4Bytes << 2)); + + NdisRawReadPortUchar(PCI_CONF_DATA, &uPciBridgeASPMSetting); + + if (uPciBridgeASPMSetting & BIT0) + uPciBridgeASPMSetting &= ~(BIT0); + + NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+(Num4Bytes << 2)); + NdisRawWritePortUchar(PCI_CONF_DATA, uPciBridgeASPMSetting); + + udelay(50); + + printk("PlatformDisableHostL0s():PciBridge BusNumber[%x], DevNumbe[%x], FuncNumber[%x], Write reg[%x] = %x\n", + priv->NdisAdapter.PciBridgeBusNum, priv->NdisAdapter.PciBridgeDevNum, priv->NdisAdapter.PciBridgeFuncNum, + (priv->NdisAdapter.PciBridgePCIeHdrOffset+0x10), (priv->NdisAdapter.PciBridgeLinkCtrlReg | (priv->RegDevicePciASPMSetting&~BIT0))); +} + +bool +PlatformEnable92CEBackDoor(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + bool bResult = true; + u8 value; + + if ( (priv->NdisAdapter.BusNumber == 0xff && priv->NdisAdapter.DevNumber == 0xff && priv->NdisAdapter.FuncNumber == 0xff) || + (priv->NdisAdapter.PciBridgeBusNum == 0xff && priv->NdisAdapter.PciBridgeDevNum == 0xff && priv->NdisAdapter.PciBridgeFuncNum == 0xff) ) + { + RT_TRACE(COMP_INIT, "PlatformEnableASPM(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n"); + return false; + } + + pci_read_config_byte(priv->pdev, 0x70f, &value); + + if (priv->NdisAdapter.PciBridgeVendor == PCI_BRIDGE_VENDOR_INTEL) + { + value |= BIT7; + } + else + { + value = 0x23; + } + + pci_write_config_byte(priv->pdev, 0x70f, value); + + + pci_read_config_byte(priv->pdev, 0x719, &value); + value |= (BIT3|BIT4); + pci_write_config_byte(priv->pdev, 0x719, value); + + + return bResult; +} + +bool PlatformSwitchDevicePciASPM(struct net_device *dev, u8 value) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + bool bResult = false; + + pci_write_config_byte(priv->pdev, 0x80, value); + + return bResult; +} + +bool PlatformSwitchClkReq(struct net_device *dev, u8 value) +{ + bool bResult = false; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + u8 Buffer; + + Buffer= value; + +#ifdef MERGE_TO_DO + if (Adapter->bDriverIsGoingToPnpSetPowerSleep && pDevice->RegSupportLowPowerState + && value == 0x0) + return false; +#endif + + pci_write_config_byte(priv->pdev,0x81,value); + bResult = true; + +#ifdef TODO + if (Buffer) { + priv->ClkReqState = true; + } else { + priv->ClkReqState = false; + } +#endif + +#ifdef RTL8192SE + udelay(100); +#endif + + return bResult; +} + +void +PlatformDisableASPM(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); +#if 1 + u32 PciCfgAddrPort=0; + u8 Num4Bytes; +#endif + u8 LinkCtrlReg; + u16 PciBridgeLinkCtrlReg, ASPMLevel=0; + + if (priv->NdisAdapter.PciBridgeVendor == PCI_BRIDGE_VENDOR_UNKNOWN) + { + RT_TRACE(COMP_POWER, "%s(): Disable ASPM. Recognize the Bus of PCI(Bridge) as UNKNOWN.\n",__func__); + } + + + LinkCtrlReg = priv->NdisAdapter.LinkCtrlReg; + PciBridgeLinkCtrlReg = priv->NdisAdapter.PciBridgeLinkCtrlReg; + + ASPMLevel |= BIT0|BIT1; + LinkCtrlReg &=~ASPMLevel; + PciBridgeLinkCtrlReg &=~(BIT0|BIT1); + + if ( (priv->NdisAdapter.BusNumber == 0xff && priv->NdisAdapter.DevNumber == 0xff && priv->NdisAdapter.FuncNumber == 0xff) || + (priv->NdisAdapter.PciBridgeBusNum == 0xff && priv->NdisAdapter.PciBridgeDevNum == 0xff && priv->NdisAdapter.PciBridgeFuncNum == 0xff) ) + { + } else { + PciCfgAddrPort= (priv->NdisAdapter.PciBridgeBusNum << 16)|(priv->NdisAdapter.PciBridgeDevNum<< 11)|(priv->NdisAdapter.PciBridgeFuncNum << 8)|(1 << 31); + Num4Bytes = (priv->NdisAdapter.PciBridgePCIeHdrOffset+0x10)/4; + + NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+(Num4Bytes << 2)); + + NdisRawWritePortUchar(PCI_CONF_DATA, PciBridgeLinkCtrlReg); + RT_TRACE(COMP_POWER, "PlatformDisableASPM():PciBridge BusNumber[%x], DevNumbe[%x], FuncNumber[%x], Write reg[%x] = %x\n", + priv->NdisAdapter.PciBridgeBusNum, priv->NdisAdapter.PciBridgeDevNum, priv->NdisAdapter.PciBridgeFuncNum, + (priv->NdisAdapter.PciBridgePCIeHdrOffset+0x10), PciBridgeLinkCtrlReg); + + udelay(50); + } +} + +void PlatformEnableASPM(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl)); + u16 ASPMLevel = 0; + u32 PciCfgAddrPort=0; + u8 Num4Bytes; + u8 uPciBridgeASPMSetting = 0; + u8 uDeviceASPMSetting = 0; + + + if ( (priv->NdisAdapter.BusNumber == 0xff && priv->NdisAdapter.DevNumber == 0xff && priv->NdisAdapter.FuncNumber == 0xff) || + (priv->NdisAdapter.PciBridgeBusNum == 0xff && priv->NdisAdapter.PciBridgeDevNum == 0xff && priv->NdisAdapter.PciBridgeFuncNum == 0xff) ) + { + RT_TRACE(COMP_INIT, "PlatformEnableASPM(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n"); + return; + } + +#ifdef RTL8192SE + if (priv->NdisAdapter.PciBridgeVendor != PCI_BRIDGE_VENDOR_INTEL ) + { + RT_TRACE(COMP_POWER, "%s(): Dont modify ASPM for non intel chipset. For Bridge Vendor %d.\n" + ,__func__,priv->NdisAdapter.PciBridgeVendor); + return; + } +#endif + + ASPMLevel |= priv->RegDevicePciASPMSetting; + uDeviceASPMSetting = priv->NdisAdapter.LinkCtrlReg; + + uDeviceASPMSetting |= ASPMLevel; + + PlatformSwitchDevicePciASPM(dev, uDeviceASPMSetting); + + if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_CLK_REQ) { + PlatformSwitchClkReq(dev,(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); + RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_CLK_REQ); + } + udelay(100); + + udelay(100); +} + +u32 PlatformResetPciSpace(struct net_device *dev,u8 Value) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + pci_write_config_byte(priv->pdev,0x04,Value); + + return 1; + +} +bool PlatformSetPMCSR(struct net_device *dev,u8 value,bool bTempSetting) +{ + bool bResult = false; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + u8 Buffer; + bool bActuallySet=false, bSetFunc=false; + unsigned long flag; + + Buffer= value; + spin_lock_irqsave(&priv->D3_lock,flag); +#ifdef TODO + if (bTempSetting) + { + if (Buffer==0x00) + { + priv->LeaveD3Cnt++; + + { + bActuallySet =true; + } + } + else + { + priv->LeaveD3Cnt--; + + if (priv->LeaveD3Cnt == 0) + { + bActuallySet=true; + } + } + } + else + { + priv->LeaveD3Cnt=0; + bActuallySet=true; + bSetFunc=true; + } +#endif + if (bActuallySet) { + if (Buffer) { + PlatformSwitchClkReq(dev, 0x01); + } else { + PlatformSwitchClkReq(dev, 0x00); + } + + pci_write_config_byte(priv->pdev,0x44,Buffer); + RT_TRACE(COMP_POWER, "PlatformSetPMCSR(): D3(value: %d)\n", Buffer); + + bResult = true; + if (!Buffer) { + PlatformResetPciSpace(dev, 0x06); + PlatformResetPciSpace(dev, 0x07); + } + + if (bSetFunc) { + if (Buffer) { +#ifdef TO_DO_LIST + RT_DISABLE_FUNC(Adapter, DF_IO_D3_BIT); +#endif + } else { +#ifdef TO_DO_LIST + RT_ENABLE_FUNC(Adapter, DF_IO_D3_BIT); +#endif + } + } + + } + spin_unlock_irqrestore(&priv->D3_lock,flag); + return bResult; +} +#endif |