11cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/****************************************************************************** 21cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 31cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 41cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 51cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * This program is free software; you can redistribute it and/or modify it 61cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * under the terms of version 2 of the GNU General Public License as 71cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * published by the Free Software Foundation. 81cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 91cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * This program is distributed in the hope that it will be useful, but WITHOUT 101cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 121cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * more details. 131cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 141cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * You should have received a copy of the GNU General Public License along with 151cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * this program; if not, write to the Free Software Foundation, Inc., 161cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 171cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 181cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 191cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ******************************************************************************/ 201cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger#define _RTW_PWRCTRL_C_ 211cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 221cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger#include <osdep_service.h> 231cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger#include <drv_types.h> 241cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger#include <osdep_intf.h> 25e73fd15ea84a8b2411a70b62473a7bfcba74c207navin patidar#include <usb_ops_linux.h> 261cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger#include <linux/usb.h> 2795311b478fea4c489603258549c16e5819c4c153navin patidar 2895311b478fea4c489603258549c16e5819c4c153navin patidarstatic int rtw_hw_suspend(struct adapter *padapter) 2995311b478fea4c489603258549c16e5819c4c153navin patidar{ 3095311b478fea4c489603258549c16e5819c4c153navin patidar struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 3195311b478fea4c489603258549c16e5819c4c153navin patidar struct net_device *pnetdev = padapter->pnetdev; 3295311b478fea4c489603258549c16e5819c4c153navin patidar 3395311b478fea4c489603258549c16e5819c4c153navin patidar 3495311b478fea4c489603258549c16e5819c4c153navin patidar if ((!padapter->bup) || (padapter->bDriverStopped) || 3595311b478fea4c489603258549c16e5819c4c153navin patidar (padapter->bSurpriseRemoved)) { 3695311b478fea4c489603258549c16e5819c4c153navin patidar DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", 3795311b478fea4c489603258549c16e5819c4c153navin patidar padapter->bup, padapter->bDriverStopped, 3895311b478fea4c489603258549c16e5819c4c153navin patidar padapter->bSurpriseRemoved); 3995311b478fea4c489603258549c16e5819c4c153navin patidar goto error_exit; 4095311b478fea4c489603258549c16e5819c4c153navin patidar } 4195311b478fea4c489603258549c16e5819c4c153navin patidar 4295311b478fea4c489603258549c16e5819c4c153navin patidar /* system suspend */ 4395311b478fea4c489603258549c16e5819c4c153navin patidar LeaveAllPowerSaveMode(padapter); 4495311b478fea4c489603258549c16e5819c4c153navin patidar 4595311b478fea4c489603258549c16e5819c4c153navin patidar DBG_88E("==> rtw_hw_suspend\n"); 4695311b478fea4c489603258549c16e5819c4c153navin patidar _enter_pwrlock(&pwrpriv->lock); 4795311b478fea4c489603258549c16e5819c4c153navin patidar pwrpriv->bips_processing = true; 4895311b478fea4c489603258549c16e5819c4c153navin patidar /* s1. */ 4995311b478fea4c489603258549c16e5819c4c153navin patidar if (pnetdev) { 5095311b478fea4c489603258549c16e5819c4c153navin patidar netif_carrier_off(pnetdev); 5195311b478fea4c489603258549c16e5819c4c153navin patidar netif_tx_stop_all_queues(pnetdev); 5295311b478fea4c489603258549c16e5819c4c153navin patidar } 5395311b478fea4c489603258549c16e5819c4c153navin patidar 5495311b478fea4c489603258549c16e5819c4c153navin patidar /* s2. */ 5595311b478fea4c489603258549c16e5819c4c153navin patidar rtw_disassoc_cmd(padapter, 500, false); 5695311b478fea4c489603258549c16e5819c4c153navin patidar 5795311b478fea4c489603258549c16e5819c4c153navin patidar /* s2-2. indicate disconnect to os */ 5895311b478fea4c489603258549c16e5819c4c153navin patidar { 5995311b478fea4c489603258549c16e5819c4c153navin patidar struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 6095311b478fea4c489603258549c16e5819c4c153navin patidar 6195311b478fea4c489603258549c16e5819c4c153navin patidar if (check_fwstate(pmlmepriv, _FW_LINKED)) { 6295311b478fea4c489603258549c16e5819c4c153navin patidar _clr_fwstate_(pmlmepriv, _FW_LINKED); 6395311b478fea4c489603258549c16e5819c4c153navin patidar 6495311b478fea4c489603258549c16e5819c4c153navin patidar rtw_led_control(padapter, LED_CTL_NO_LINK); 6595311b478fea4c489603258549c16e5819c4c153navin patidar 6695311b478fea4c489603258549c16e5819c4c153navin patidar rtw_os_indicate_disconnect(padapter); 6795311b478fea4c489603258549c16e5819c4c153navin patidar 6895311b478fea4c489603258549c16e5819c4c153navin patidar /* donnot enqueue cmd */ 6995311b478fea4c489603258549c16e5819c4c153navin patidar rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0); 7095311b478fea4c489603258549c16e5819c4c153navin patidar } 7195311b478fea4c489603258549c16e5819c4c153navin patidar } 7295311b478fea4c489603258549c16e5819c4c153navin patidar /* s2-3. */ 7395311b478fea4c489603258549c16e5819c4c153navin patidar rtw_free_assoc_resources(padapter, 1); 7495311b478fea4c489603258549c16e5819c4c153navin patidar 7595311b478fea4c489603258549c16e5819c4c153navin patidar /* s2-4. */ 7695311b478fea4c489603258549c16e5819c4c153navin patidar rtw_free_network_queue(padapter, true); 7795311b478fea4c489603258549c16e5819c4c153navin patidar rtw_ips_dev_unload(padapter); 7895311b478fea4c489603258549c16e5819c4c153navin patidar pwrpriv->rf_pwrstate = rf_off; 7995311b478fea4c489603258549c16e5819c4c153navin patidar pwrpriv->bips_processing = false; 8095311b478fea4c489603258549c16e5819c4c153navin patidar 8195311b478fea4c489603258549c16e5819c4c153navin patidar _exit_pwrlock(&pwrpriv->lock); 8295311b478fea4c489603258549c16e5819c4c153navin patidar 8395311b478fea4c489603258549c16e5819c4c153navin patidar return 0; 8495311b478fea4c489603258549c16e5819c4c153navin patidar 8595311b478fea4c489603258549c16e5819c4c153navin patidarerror_exit: 8695311b478fea4c489603258549c16e5819c4c153navin patidar DBG_88E("%s, failed\n", __func__); 8795311b478fea4c489603258549c16e5819c4c153navin patidar return -1; 8895311b478fea4c489603258549c16e5819c4c153navin patidar} 8995311b478fea4c489603258549c16e5819c4c153navin patidar 9095311b478fea4c489603258549c16e5819c4c153navin patidarstatic int rtw_hw_resume(struct adapter *padapter) 9195311b478fea4c489603258549c16e5819c4c153navin patidar{ 9295311b478fea4c489603258549c16e5819c4c153navin patidar struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 9395311b478fea4c489603258549c16e5819c4c153navin patidar struct net_device *pnetdev = padapter->pnetdev; 9495311b478fea4c489603258549c16e5819c4c153navin patidar 9595311b478fea4c489603258549c16e5819c4c153navin patidar 9695311b478fea4c489603258549c16e5819c4c153navin patidar /* system resume */ 9795311b478fea4c489603258549c16e5819c4c153navin patidar DBG_88E("==> rtw_hw_resume\n"); 9895311b478fea4c489603258549c16e5819c4c153navin patidar _enter_pwrlock(&pwrpriv->lock); 9995311b478fea4c489603258549c16e5819c4c153navin patidar pwrpriv->bips_processing = true; 10095311b478fea4c489603258549c16e5819c4c153navin patidar rtw_reset_drv_sw(padapter); 10195311b478fea4c489603258549c16e5819c4c153navin patidar 10295311b478fea4c489603258549c16e5819c4c153navin patidar if (pm_netdev_open(pnetdev, false) != 0) { 10395311b478fea4c489603258549c16e5819c4c153navin patidar _exit_pwrlock(&pwrpriv->lock); 10495311b478fea4c489603258549c16e5819c4c153navin patidar goto error_exit; 10595311b478fea4c489603258549c16e5819c4c153navin patidar } 10695311b478fea4c489603258549c16e5819c4c153navin patidar 10795311b478fea4c489603258549c16e5819c4c153navin patidar netif_device_attach(pnetdev); 10895311b478fea4c489603258549c16e5819c4c153navin patidar netif_carrier_on(pnetdev); 10995311b478fea4c489603258549c16e5819c4c153navin patidar 11095311b478fea4c489603258549c16e5819c4c153navin patidar if (!netif_queue_stopped(pnetdev)) 11195311b478fea4c489603258549c16e5819c4c153navin patidar netif_start_queue(pnetdev); 11295311b478fea4c489603258549c16e5819c4c153navin patidar else 11395311b478fea4c489603258549c16e5819c4c153navin patidar netif_wake_queue(pnetdev); 11495311b478fea4c489603258549c16e5819c4c153navin patidar 11595311b478fea4c489603258549c16e5819c4c153navin patidar pwrpriv->bkeepfwalive = false; 11695311b478fea4c489603258549c16e5819c4c153navin patidar pwrpriv->brfoffbyhw = false; 11795311b478fea4c489603258549c16e5819c4c153navin patidar 11895311b478fea4c489603258549c16e5819c4c153navin patidar pwrpriv->rf_pwrstate = rf_on; 11995311b478fea4c489603258549c16e5819c4c153navin patidar pwrpriv->bips_processing = false; 12095311b478fea4c489603258549c16e5819c4c153navin patidar 12195311b478fea4c489603258549c16e5819c4c153navin patidar _exit_pwrlock(&pwrpriv->lock); 12295311b478fea4c489603258549c16e5819c4c153navin patidar 12395311b478fea4c489603258549c16e5819c4c153navin patidar 12495311b478fea4c489603258549c16e5819c4c153navin patidar return 0; 12595311b478fea4c489603258549c16e5819c4c153navin patidarerror_exit: 12695311b478fea4c489603258549c16e5819c4c153navin patidar DBG_88E("%s, Open net dev failed\n", __func__); 12795311b478fea4c489603258549c16e5819c4c153navin patidar return -1; 12895311b478fea4c489603258549c16e5819c4c153navin patidar} 1291cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1301cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingervoid ips_enter(struct adapter *padapter) 1311cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 1321cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 1331cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct xmit_priv *pxmit_priv = &padapter->xmitpriv; 1341cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1351cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (padapter->registrypriv.mp_mode == 1) 1361cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 1371cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1381cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF || 1391cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) { 1401cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E_LEVEL(_drv_info_, "There are some pkts to transmit\n"); 1411cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n", 1421cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt); 1431cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 1441cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 1451cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1461cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger _enter_pwrlock(&pwrpriv->lock); 1471cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1481cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bips_processing = true; 1491cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1501cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger /* syn ips_mode with request */ 1511cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->ips_mode = pwrpriv->ips_mode_req; 1521cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1531cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->ips_enter_cnts++; 1541cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts); 1551cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (rf_off == pwrpriv->change_rfpwrstate) { 1561cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bpower_saving = true; 1571cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E_LEVEL(_drv_info_, "nolinked power save enter\n"); 1581cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1591cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->ips_mode == IPS_LEVEL_2) 1601cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bkeepfwalive = true; 1611cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1621cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_ips_pwr_down(padapter); 1631cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->rf_pwrstate = rf_off; 1641cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 1651cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bips_processing = false; 1661cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1671cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger _exit_pwrlock(&pwrpriv->lock); 1681cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 1691cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1701cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerint ips_leave(struct adapter *padapter) 1711cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 1721cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 1731cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct security_priv *psecuritypriv = &(padapter->securitypriv); 1741cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1751cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger int result = _SUCCESS; 1761cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger int keyid; 1771cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1781cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1791cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger _enter_pwrlock(&pwrpriv->lock); 1801cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1811cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) { 1821cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bips_processing = true; 1831cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->change_rfpwrstate = rf_on; 1841cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->ips_leave_cnts++; 1851cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts); 1861cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1871cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger result = rtw_ips_pwr_up(padapter); 1881cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (result == _SUCCESS) { 1891cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->rf_pwrstate = rf_on; 1901cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 1911cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E_LEVEL(_drv_info_, "nolinked power save leave\n"); 1921cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 1931cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) || (_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) { 1941cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("==>%s, channel(%d), processing(%x)\n", __func__, padapter->mlmeextpriv.cur_channel, pwrpriv->bips_processing); 1951cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); 1961cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger for (keyid = 0; keyid < 4; keyid++) { 1971cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pmlmepriv->key_mask & BIT(keyid)) { 1981cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (keyid == psecuritypriv->dot11PrivacyKeyIndex) 1991cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger result = rtw_set_key(padapter, psecuritypriv, keyid, 1); 2001cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger else 2011cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger result = rtw_set_key(padapter, psecuritypriv, keyid, 0); 2021cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 2031cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 2041cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 2051cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 20699ecfb06f83ec7eaa9110fa887cef3f55d031bf4navin patidar DBG_88E("==> ips_leave.....LED(0x%08x)...\n", usb_read32(padapter, 0x4c)); 2071cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bips_processing = false; 2081cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2091cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bkeepfwalive = false; 2101cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bpower_saving = false; 2111cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 2121cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2131cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger _exit_pwrlock(&pwrpriv->lock); 2141cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2151cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return result; 2161cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 2171cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2181cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerstatic bool rtw_pwr_unassociated_idle(struct adapter *adapter) 2191cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 2201cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); 2211cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger bool ret = false; 2221cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 223e017a92b2e768c13503765e1eabfa566bf791807Manuel Schölling if (time_after_eq(adapter->pwrctrlpriv.ips_deny_time, jiffies)) 2241cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 2251cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2261cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) || 2271cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) || 2281cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger check_fwstate(pmlmepriv, WIFI_AP_STATE) || 2292454e79ac22da26c5ef42a0db0aef8d968d55d0fnavin patidar check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)) 2301cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 2311cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2321cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ret = true; 2331cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2341cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerexit: 2351cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return ret; 2361cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 2371cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2381cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingervoid rtw_ps_processor(struct adapter *padapter) 2391cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 2401cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 2411cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2421cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger enum rt_rf_power_state rfpwrstate; 2431cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2441cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->ps_processing = true; 2451cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2461cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->bips_processing) 2471cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 2481cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2491cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (padapter->pwrctrlpriv.bHWPwrPindetect) { 2501cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rfpwrstate = RfOnOffDetect(padapter); 2511cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("@@@@- #2 %s==> rfstate:%s\n", __func__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off"); 2521cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2531cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (rfpwrstate != pwrpriv->rf_pwrstate) { 2541cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (rfpwrstate == rf_off) { 2551cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->change_rfpwrstate = rf_off; 2561cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->brfoffbyhw = true; 2571cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_hw_suspend(padapter); 2581cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } else { 2591cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->change_rfpwrstate = rf_on; 2601cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_hw_resume(padapter); 2611cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 2621cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on"); 2631cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 2641cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->pwr_state_check_cnts++; 2651cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 2661cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2671cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->ips_mode_req == IPS_NONE) 2681cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 2691cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2705b66fb7d57462f5c0683f7d64625652ffb9f5f87Valentina Manea if (!rtw_pwr_unassociated_idle(padapter)) 2711cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 2721cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2731cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4) == 0)) { 2741cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("==>%s .fw_state(%x)\n", __func__, get_fwstate(pmlmepriv)); 2751cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->change_rfpwrstate = rf_off; 2761cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2771cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ips_enter(padapter); 2781cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 2791cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerexit: 2801cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); 2811cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->ps_processing = false; 2821cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 2831cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 2841cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2851cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerstatic void pwr_state_check_handler(void *FunctionContext) 2861cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 2871cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct adapter *padapter = (struct adapter *)FunctionContext; 2881cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_ps_cmd(padapter); 2891cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 2901cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 2911cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* 2921cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 2931cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * Parameters 2941cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * padapter 2951cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4 2961cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 2971cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger */ 2981cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingervoid rtw_set_rpwm(struct adapter *padapter, u8 pslv) 2991cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 3001cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger u8 rpwm; 3011cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 3021cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3031cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pslv = PS_STATE(pslv); 3041cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3051cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->btcoex_rfon) { 3061cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pslv < PS_STATE_S4) 3071cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pslv = PS_STATE_S3; 3081cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 3091cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3101cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((pwrpriv->rpwm == pslv)) { 3111cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, 3121cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ("%s: Already set rpwm[0x%02X], new=0x%02X!\n", __func__, pwrpriv->rpwm, pslv)); 3131cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 3141cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 3151cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3161cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((padapter->bSurpriseRemoved) || 3171cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger (!padapter->hw_init_completed)) { 3181cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, 3191cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n", 3201cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger __func__, padapter->bSurpriseRemoved, padapter->hw_init_completed)); 3211cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3221cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->cpwm = PS_STATE_S4; 3231cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3241cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 3251cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 3261cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3271cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (padapter->bDriverStopped) { 3281cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, 3291cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ("%s: change power state(0x%02X) when DriverStopped\n", __func__, pslv)); 3301cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3311cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pslv < PS_STATE_S2) { 3321cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, 3331cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __func__, pslv)); 3341cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 3351cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 3361cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 3371cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3381cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rpwm = pslv | pwrpriv->tog; 3391cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, 3401cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ("rtw_set_rpwm: rpwm=0x%02x cpwm=0x%02x\n", rpwm, pwrpriv->cpwm)); 3411cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3421cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->rpwm = pslv; 3431cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3441cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm)); 3451cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3461cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->tog += 0x80; 3471cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->cpwm = pslv; 3481cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 3491cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3501cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerstatic u8 PS_RDY_CHECK(struct adapter *padapter) 3511cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 3521cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger u32 curr_time, delta_time; 3531cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 3541cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3551cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3561cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 357c01fb49636b65ceea513c00966c58b8bdb095c8fLarry Finger curr_time = jiffies; 3581cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp; 3591cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3601cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (delta_time < LPS_DELAY_TIME) 3611cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return false; 3621cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3631cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((check_fwstate(pmlmepriv, _FW_LINKED) == false) || 3641cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) || 3651cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger (check_fwstate(pmlmepriv, WIFI_AP_STATE)) || 3661cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) || 3671cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) 3681cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return false; 3691cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->bInSuspend) 3701cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return false; 3711cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == false)) { 3721cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("Group handshake still in progress !!!\n"); 3731cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return false; 3741cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 3751cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return true; 3761cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 3771cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3781cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingervoid rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode) 3791cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 3801cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 3811cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3821cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, 3831cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ("%s: PowerMode=%d Smart_PS=%d\n", 3841cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger __func__, ps_mode, smart_ps)); 3851cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3861cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (ps_mode > PM_Card_Disable) { 3871cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("ps_mode:%d error\n", ps_mode)); 3881cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 3891cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 3901cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3911cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->pwr_mode == ps_mode) { 3921cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (PS_MODE_ACTIVE == ps_mode) 3931cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 3941cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 3951cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((pwrpriv->smart_ps == smart_ps) && 3961cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger (pwrpriv->bcn_ant_mode == bcn_ant_mode)) 3971cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 3981cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 3991cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4001cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger /* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */ 4011cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (ps_mode == PS_MODE_ACTIVE) { 4021cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (PS_RDY_CHECK(padapter)) { 4031cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s: Enter 802.11 power save\n", __func__); 4041cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bFwCurrentInPSMode = true; 4051cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->pwr_mode = ps_mode; 4061cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->smart_ps = smart_ps; 4071cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bcn_ant_mode = bcn_ant_mode; 4081cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); 4091cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_set_rpwm(padapter, PS_STATE_S2); 4101cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4111cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4121cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 4131cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4141cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* 4151cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * Return: 4161cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * 0: Leave OK 4171cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * -1: Timeout 4181cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger * -2: Other error 4191cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger */ 4201cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingers32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) 4211cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 4221cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger u32 start_time; 4231cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger u8 bAwake = false; 4241cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger s32 err = 0; 4251cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4261cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 427c01fb49636b65ceea513c00966c58b8bdb095c8fLarry Finger start_time = jiffies; 4281cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger while (1) { 4291cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake); 4301cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (bAwake) 4311cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger break; 4321cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4331cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (padapter->bSurpriseRemoved) { 4341cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger err = -2; 4351cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s: device surprise removed!!\n", __func__); 4361cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger break; 4371cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4381cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4391cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (rtw_get_passing_time_ms(start_time) > delay_ms) { 4401cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger err = -1; 4411cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms); 4421cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger break; 4431cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 444b2dcff2a91d67e2a3c35be54c731343148d19292Larry Finger msleep(1); 4451cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4461cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4471cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return err; 4481cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 4491cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4501cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* */ 4511cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* Description: */ 4521cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* Enter the leisure power save mode. */ 4531cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* */ 4541cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingervoid LPS_Enter(struct adapter *padapter) 4551cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 4561cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 4571cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4581cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (PS_RDY_CHECK(padapter) == false) 4591cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return; 4601cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4611cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->bLeisurePs) { 4621cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger /* Idle for a while if we connect to AP a while ago. */ 4631cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */ 4641cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) { 4651cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bpower_saving = true; 4661cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s smart_ps:%d\n", __func__, pwrpriv->smart_ps); 4671cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger /* For Tenda W311R IOT issue */ 4681cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, pwrpriv->smart_ps, 0); 4691cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4701cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } else { 4711cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->LpsIdleCount++; 4721cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4731cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4741cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 4751cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4761cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger#define LPS_LEAVE_TIMEOUT_MS 100 4771cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4781cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* Description: */ 4791cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* Leave the leisure power save mode. */ 4801cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingervoid LPS_Leave(struct adapter *padapter) 4811cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 4821cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 4831cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4841cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->bLeisurePs) { 4851cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) { 4861cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0); 4871cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4881cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) 4891cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS); 4901cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4911cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 4921cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4931cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrpriv->bpower_saving = false; 4941cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 4951cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 4961cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* */ 4971cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */ 4981cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* Move code to function by tynli. 2010.03.26. */ 4991cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* */ 5001cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingervoid LeaveAllPowerSaveMode(struct adapter *Adapter) 5011cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 5021cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); 5031cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger u8 enqueue = 0; 5041cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5052454e79ac22da26c5ef42a0db0aef8d968d55d0fnavin patidar if (check_fwstate(pmlmepriv, _FW_LINKED)) 5061cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue); 5071cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 5081cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5091cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingervoid rtw_init_pwrctrl_priv(struct adapter *padapter) 5101cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 5111cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; 5121cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5131cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger _init_pwrlock(&pwrctrlpriv->lock); 5141cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->rf_pwrstate = rf_on; 5151cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->ips_enter_cnts = 0; 5161cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->ips_leave_cnts = 0; 5171cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->bips_processing = false; 5181cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5191cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode; 5201cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode; 5211cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5221cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL; 5231cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->pwr_state_check_cnts = 0; 5241cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->bInternalAutoSuspend = false; 5251cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->bInSuspend = false; 5261cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->bkeepfwalive = false; 5271cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5281cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->LpsIdleCount = 0; 5291cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (padapter->registrypriv.mp_mode == 1) 5301cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE ; 5311cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger else 5321cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */ 5331cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false; 5341cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5351cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->bFwCurrentInPSMode = false; 5361cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5371cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->rpwm = 0; 5381cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->cpwm = PS_STATE_S4; 5391cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5401cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE; 5411cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps; 5421cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->bcn_ant_mode = 0; 5431cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5441cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->tog = 0x80; 5451cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5461cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->btcoex_rfon = false; 5471cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5481cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger _init_timer(&(pwrctrlpriv->pwr_state_check_timer), padapter->pnetdev, pwr_state_check_handler, (u8 *)padapter); 5491cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 5501cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5511cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerinline void rtw_set_ips_deny(struct adapter *padapter, u32 ms) 5521cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 5531cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 554ace050139cee44d06b06b4c78074b4eb80fb7c0anavin patidar pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms); 5551cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 5561cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5571cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger/* 5581cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend 5591cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger* @adapter: pointer to struct adapter structure 56040a46d8b40e326ba77e0858f3a45206ebc201660Masanari Iida* @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup 5611cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger* Return _SUCCESS or _FAIL 5621cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger*/ 5631cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5641cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerint _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller) 5651cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 5661cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 5671cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 568e017a92b2e768c13503765e1eabfa566bf791807Manuel Schölling unsigned long expires; 5691cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger int ret = _SUCCESS; 5701cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 571ace050139cee44d06b06b4c78074b4eb80fb7c0anavin patidar expires = jiffies + msecs_to_jiffies(ips_deffer_ms); 572e017a92b2e768c13503765e1eabfa566bf791807Manuel Schölling if (time_before(pwrpriv->ips_deny_time, expires)) 573ace050139cee44d06b06b4c78074b4eb80fb7c0anavin patidar pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms); 5741cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5751cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 576c01fb49636b65ceea513c00966c58b8bdb095c8fLarry Finger u32 start = jiffies; 5771cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->ps_processing) { 5781cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s wait ps_processing...\n", __func__); 5791cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) 5800da46e6bb1ac0b311d0ef47e5f723f330e144d37Larry Finger msleep(10); 5811cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrpriv->ps_processing) 5821cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s wait ps_processing timeout\n", __func__); 5831cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger else 5841cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s wait ps_processing done\n", __func__); 5851cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 5861cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 5871cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5881cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger /* System suspend is not allowed to wakeup */ 5891cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((!pwrpriv->bInternalAutoSuspend) && (pwrpriv->bInSuspend)) { 5901cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ret = _FAIL; 5911cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 5921cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 5931cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 5941cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger /* block??? */ 5951cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((pwrpriv->bInternalAutoSuspend) && (padapter->net_closed)) { 5961cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ret = _FAIL; 5971cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 5981cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 5991cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 6001cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger /* I think this should be check in IPS, LPS, autosuspend functions... */ 6011cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (check_fwstate(pmlmepriv, _FW_LINKED)) { 6021cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ret = _SUCCESS; 6031cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 6041cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 6051cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (rf_off == pwrpriv->rf_pwrstate) { 6061cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s call ips_leave....\n", __func__); 6071cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (_FAIL == ips_leave(padapter)) { 6081cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("======> ips_leave fail.............\n"); 6091cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ret = _FAIL; 6101cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 6111cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 6121cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 6131cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 6141cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger /* TODO: the following checking need to be merged... */ 6151cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (padapter->bDriverStopped || !padapter->bup || 6161cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger !padapter->hw_init_completed) { 6171cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s: bDriverStopped=%d, bup=%d, hw_init_completed =%u\n" 6181cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger , caller 6191cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger , padapter->bDriverStopped 6201cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger , padapter->bup 6211cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger , padapter->hw_init_completed); 6221cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ret = false; 6231cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger goto exit; 6241cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 6251cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 6261cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerexit: 627ace050139cee44d06b06b4c78074b4eb80fb7c0anavin patidar expires = jiffies + msecs_to_jiffies(ips_deffer_ms); 628e017a92b2e768c13503765e1eabfa566bf791807Manuel Schölling if (time_before(pwrpriv->ips_deny_time, expires)) 629ace050139cee44d06b06b4c78074b4eb80fb7c0anavin patidar pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms); 6301cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return ret; 6311cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 6321cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 6331cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerint rtw_pm_set_lps(struct adapter *padapter, u8 mode) 6341cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 6351cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger int ret = 0; 6361cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; 6371cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 6381cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (mode < PS_MODE_NUM) { 6391cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (pwrctrlpriv->power_mgnt != mode) { 6401cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (PS_MODE_ACTIVE == mode) 6411cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger LeaveAllPowerSaveMode(padapter); 6421cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger else 6431cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->LpsIdleCount = 2; 6441cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->power_mgnt = mode; 6451cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false; 6461cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 6471cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } else { 6481cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger ret = -EINVAL; 6491cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 6501cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 6511cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return ret; 6521cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 6531cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 6541cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Fingerint rtw_pm_set_ips(struct adapter *padapter, u8 mode) 6551cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger{ 6561cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; 6571cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger 6581cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) { 6591cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_ips_mode_req(pwrctrlpriv, mode); 6601cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s %s\n", __func__, mode == IPS_NORMAL ? "IPS_NORMAL" : "IPS_LEVEL_2"); 6611cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return 0; 6621cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } else if (mode == IPS_NONE) { 6631cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger rtw_ips_mode_req(pwrctrlpriv, mode); 6641cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger DBG_88E("%s %s\n", __func__, "IPS_NONE"); 6651cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger if ((padapter->bSurpriseRemoved == 0) && (_FAIL == rtw_pwr_wakeup(padapter))) 6661cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return -EFAULT; 6671cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } else { 6681cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return -EINVAL; 6691cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger } 6701cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger return 0; 6711cc18a22b96b33119f457cac3ce5fcbbcbab1badLarry Finger} 672