linux/drivers/staging/r8188eu/core/rtw_pwrctrl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2007 - 2012 Realtek Corporation. */
   3
   4#define _RTW_PWRCTRL_C_
   5
   6#include "../include/osdep_service.h"
   7#include "../include/drv_types.h"
   8#include "../include/osdep_intf.h"
   9#include "../include/linux/usb.h"
  10
  11void ips_enter(struct adapter *padapter)
  12{
  13        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  14        struct xmit_priv *pxmit_priv = &padapter->xmitpriv;
  15
  16        if (padapter->registrypriv.mp_mode == 1)
  17                return;
  18
  19        if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
  20            pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
  21                DBG_88E_LEVEL(_drv_info_, "There are some pkts to transmit\n");
  22                DBG_88E_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n",
  23                              pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);
  24                return;
  25        }
  26
  27        _enter_pwrlock(&pwrpriv->lock);
  28
  29        pwrpriv->bips_processing = true;
  30
  31        /*  syn ips_mode with request */
  32        pwrpriv->ips_mode = pwrpriv->ips_mode_req;
  33
  34        pwrpriv->ips_enter_cnts++;
  35        DBG_88E("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts);
  36        if (rf_off == pwrpriv->change_rfpwrstate) {
  37                pwrpriv->bpower_saving = true;
  38                DBG_88E_LEVEL(_drv_info_, "nolinked power save enter\n");
  39
  40                if (pwrpriv->ips_mode == IPS_LEVEL_2)
  41                        pwrpriv->bkeepfwalive = true;
  42
  43                rtw_ips_pwr_down(padapter);
  44                pwrpriv->rf_pwrstate = rf_off;
  45        }
  46        pwrpriv->bips_processing = false;
  47
  48        _exit_pwrlock(&pwrpriv->lock);
  49}
  50
  51int ips_leave(struct adapter *padapter)
  52{
  53        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  54        struct security_priv *psecuritypriv = &padapter->securitypriv;
  55        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  56        int result = _SUCCESS;
  57        int keyid;
  58
  59        _enter_pwrlock(&pwrpriv->lock);
  60
  61        if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
  62                pwrpriv->bips_processing = true;
  63                pwrpriv->change_rfpwrstate = rf_on;
  64                pwrpriv->ips_leave_cnts++;
  65                DBG_88E("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts);
  66
  67                result = rtw_ips_pwr_up(padapter);
  68                if (result == _SUCCESS) {
  69                        pwrpriv->rf_pwrstate = rf_on;
  70                }
  71                DBG_88E_LEVEL(_drv_info_, "nolinked power save leave\n");
  72
  73                if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) || (_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) {
  74                        DBG_88E("==>%s, channel(%d), processing(%x)\n", __func__, padapter->mlmeextpriv.cur_channel, pwrpriv->bips_processing);
  75                        set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
  76                        for (keyid = 0; keyid < 4; keyid++) {
  77                                if (pmlmepriv->key_mask & BIT(keyid)) {
  78                                        if (keyid == psecuritypriv->dot11PrivacyKeyIndex)
  79                                                result = rtw_set_key(padapter, psecuritypriv, keyid, 1);
  80                                        else
  81                                                result = rtw_set_key(padapter, psecuritypriv, keyid, 0);
  82                                }
  83                        }
  84                }
  85
  86                DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
  87                pwrpriv->bips_processing = false;
  88
  89                pwrpriv->bkeepfwalive = false;
  90                pwrpriv->bpower_saving = false;
  91        }
  92
  93        _exit_pwrlock(&pwrpriv->lock);
  94
  95        return result;
  96}
  97
  98static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
  99{
 100        struct adapter *buddy = adapter->pbuddy_adapter;
 101        struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
 102#ifdef CONFIG_88EU_P2P
 103        struct wifidirect_info  *pwdinfo = &adapter->wdinfo;
 104#endif
 105
 106        bool ret = false;
 107
 108        if (adapter->pwrctrlpriv.ips_deny_time >= jiffies)
 109                goto exit;
 110
 111        if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) ||
 112            check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) ||
 113            check_fwstate(pmlmepriv, WIFI_UNDER_WPS) ||
 114            check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
 115            check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) ||
 116#if defined(CONFIG_88EU_P2P)
 117            !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
 118#else
 119            0)
 120#endif
 121                goto exit;
 122
 123        /* consider buddy, if exist */
 124        if (buddy) {
 125                struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv;
 126                #ifdef CONFIG_88EU_P2P
 127                struct wifidirect_info *b_pwdinfo = &buddy->wdinfo;
 128                #endif
 129
 130                if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) ||
 131                    check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) ||
 132                    check_fwstate(b_pmlmepriv, WIFI_AP_STATE) ||
 133                    check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) ||
 134#if defined(CONFIG_88EU_P2P)
 135                    !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE))
 136#else
 137                    0)
 138#endif
 139                        goto exit;
 140        }
 141        ret = true;
 142
 143exit:
 144        return ret;
 145}
 146
 147void rtw_ps_processor(struct adapter *padapter)
 148{
 149        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 150        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 151        enum rt_rf_power_state rfpwrstate;
 152
 153        pwrpriv->ps_processing = true;
 154
 155        if (pwrpriv->bips_processing)
 156                goto exit;
 157
 158        if (padapter->pwrctrlpriv.bHWPwrPindetect) {
 159                rfpwrstate = RfOnOffDetect(padapter);
 160                DBG_88E("@@@@- #2  %s==> rfstate:%s\n", __func__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off");
 161
 162                if (rfpwrstate != pwrpriv->rf_pwrstate) {
 163                        if (rfpwrstate == rf_off) {
 164                                pwrpriv->change_rfpwrstate = rf_off;
 165                                pwrpriv->brfoffbyhw = true;
 166                                padapter->bCardDisableWOHSM = true;
 167                                rtw_hw_suspend(padapter);
 168                        } else {
 169                                pwrpriv->change_rfpwrstate = rf_on;
 170                                rtw_hw_resume(padapter);
 171                        }
 172                        DBG_88E("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on");
 173                }
 174                pwrpriv->pwr_state_check_cnts++;
 175        }
 176
 177        if (pwrpriv->ips_mode_req == IPS_NONE)
 178                goto exit;
 179
 180        if (!rtw_pwr_unassociated_idle(padapter))
 181                goto exit;
 182
 183        if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts % 4) == 0)) {
 184                DBG_88E("==>%s .fw_state(%x)\n", __func__, get_fwstate(pmlmepriv));
 185                pwrpriv->change_rfpwrstate = rf_off;
 186
 187                ips_enter(padapter);
 188        }
 189exit:
 190        rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
 191        pwrpriv->ps_processing = false;
 192}
 193
 194static void pwr_state_check_handler(struct timer_list *t)
 195{
 196        struct adapter *padapter =
 197                from_timer(padapter, t,
 198                           pwrctrlpriv.pwr_state_check_timer);
 199        rtw_ps_cmd(padapter);
 200}
 201
 202/*
 203 *
 204 * Parameters
 205 *      padapter
 206 *      pslv                    power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
 207 *
 208 */
 209void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
 210{
 211        u8      rpwm;
 212        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 213
 214        pslv = PS_STATE(pslv);
 215
 216        if (pwrpriv->btcoex_rfon) {
 217                if (pslv < PS_STATE_S4)
 218                        pslv = PS_STATE_S3;
 219        }
 220
 221        if (pwrpriv->rpwm == pslv)
 222                return;
 223
 224        if ((padapter->bSurpriseRemoved) ||
 225            (!padapter->hw_init_completed)) {
 226                pwrpriv->cpwm = PS_STATE_S4;
 227
 228                return;
 229        }
 230
 231        if (padapter->bDriverStopped) {
 232                if (pslv < PS_STATE_S2)
 233                        return;
 234        }
 235
 236        rpwm = pslv | pwrpriv->tog;
 237
 238        pwrpriv->rpwm = pslv;
 239
 240        rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
 241
 242        pwrpriv->tog += 0x80;
 243        pwrpriv->cpwm = pslv;
 244
 245}
 246
 247static u8 PS_RDY_CHECK(struct adapter *padapter)
 248{
 249        u32 curr_time, delta_time;
 250        struct pwrctrl_priv     *pwrpriv = &padapter->pwrctrlpriv;
 251        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 252
 253        curr_time = jiffies;
 254        delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
 255
 256        if (delta_time < LPS_DELAY_TIME)
 257                return false;
 258
 259        if (!check_fwstate(pmlmepriv, _FW_LINKED) ||
 260            check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) ||
 261            check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
 262            check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
 263            check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
 264                return false;
 265        if (pwrpriv->bInSuspend)
 266                return false;
 267        if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && !padapter->securitypriv.binstallGrpkey) {
 268                DBG_88E("Group handshake still in progress !!!\n");
 269                return false;
 270        }
 271        return true;
 272}
 273
 274void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
 275{
 276        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 277#ifdef CONFIG_88EU_P2P
 278        struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
 279#endif /* CONFIG_88EU_P2P */
 280
 281        if (ps_mode > PM_Card_Disable)
 282                return;
 283
 284        if (pwrpriv->pwr_mode == ps_mode) {
 285                if (PS_MODE_ACTIVE == ps_mode)
 286                        return;
 287
 288                if ((pwrpriv->smart_ps == smart_ps) &&
 289                    (pwrpriv->bcn_ant_mode == bcn_ant_mode))
 290                        return;
 291        }
 292
 293        /* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
 294        if (ps_mode == PS_MODE_ACTIVE) {
 295#ifdef CONFIG_88EU_P2P
 296                if (pwdinfo->opp_ps == 0) {
 297                        DBG_88E("rtw_set_ps_mode: Leave 802.11 power save\n");
 298                        pwrpriv->pwr_mode = ps_mode;
 299                        rtw_set_rpwm(padapter, PS_STATE_S4);
 300                        rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
 301                        pwrpriv->bFwCurrentInPSMode = false;
 302                }
 303        } else {
 304#endif /* CONFIG_88EU_P2P */
 305                if (PS_RDY_CHECK(padapter)) {
 306                        DBG_88E("%s: Enter 802.11 power save\n", __func__);
 307                        pwrpriv->bFwCurrentInPSMode = true;
 308                        pwrpriv->pwr_mode = ps_mode;
 309                        pwrpriv->smart_ps = smart_ps;
 310                        pwrpriv->bcn_ant_mode = bcn_ant_mode;
 311                        rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
 312
 313#ifdef CONFIG_88EU_P2P
 314                        /*  Set CTWindow after LPS */
 315                        if (pwdinfo->opp_ps == 1)
 316                                p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
 317#endif /* CONFIG_88EU_P2P */
 318
 319                        rtw_set_rpwm(padapter, PS_STATE_S2);
 320                }
 321        }
 322
 323}
 324
 325/*
 326 * Return:
 327 *      0:      Leave OK
 328 *      -1:     Timeout
 329 *      -2:     Other error
 330 */
 331s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
 332{
 333        u32 start_time;
 334        u8 bAwake = false;
 335        s32 err = 0;
 336
 337        start_time = jiffies;
 338        while (1) {
 339                rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
 340                if (bAwake)
 341                        break;
 342
 343                if (padapter->bSurpriseRemoved) {
 344                        err = -2;
 345                        DBG_88E("%s: device surprise removed!!\n", __func__);
 346                        break;
 347                }
 348
 349                if (rtw_get_passing_time_ms(start_time) > delay_ms) {
 350                        err = -1;
 351                        DBG_88E("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms);
 352                        break;
 353                }
 354                rtw_usleep_os(100);
 355        }
 356
 357        return err;
 358}
 359
 360/*  */
 361/*      Description: */
 362/*              Enter the leisure power save mode. */
 363/*  */
 364void LPS_Enter(struct adapter *padapter)
 365{
 366        struct pwrctrl_priv     *pwrpriv = &padapter->pwrctrlpriv;
 367
 368        if (!PS_RDY_CHECK(padapter))
 369                return;
 370
 371        if (pwrpriv->bLeisurePs) {
 372                /*  Idle for a while if we connect to AP a while ago. */
 373                if (pwrpriv->LpsIdleCount >= 2) { /*   4 Sec */
 374                        if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
 375                                pwrpriv->bpower_saving = true;
 376                                DBG_88E("%s smart_ps:%d\n", __func__, pwrpriv->smart_ps);
 377                                /* For Tenda W311R IOT issue */
 378                                rtw_set_ps_mode(padapter, pwrpriv->power_mgnt,
 379                                                pwrpriv->smart_ps, 0x40);
 380                        }
 381                } else {
 382                        pwrpriv->LpsIdleCount++;
 383                }
 384        }
 385
 386}
 387
 388#define LPS_LEAVE_TIMEOUT_MS 100
 389
 390/*      Description: */
 391/*              Leave the leisure power save mode. */
 392void LPS_Leave(struct adapter *padapter)
 393{
 394        struct pwrctrl_priv     *pwrpriv = &padapter->pwrctrlpriv;
 395
 396        if (pwrpriv->bLeisurePs) {
 397                if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
 398                        rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0x40);
 399
 400                        if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
 401                                LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS);
 402                }
 403        }
 404
 405        pwrpriv->bpower_saving = false;
 406
 407}
 408
 409/*  */
 410/*  Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */
 411/*  Move code to function by tynli. 2010.03.26. */
 412/*  */
 413void LeaveAllPowerSaveMode(struct adapter *Adapter)
 414{
 415        struct mlme_priv        *pmlmepriv = &Adapter->mlmepriv;
 416        u8      enqueue = 0;
 417
 418        if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */
 419                p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, enqueue);
 420
 421                rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
 422        }
 423
 424}
 425
 426void rtw_init_pwrctrl_priv(struct adapter *padapter)
 427{
 428        struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
 429
 430        _init_pwrlock(&pwrctrlpriv->lock);
 431        pwrctrlpriv->rf_pwrstate = rf_on;
 432        pwrctrlpriv->ips_enter_cnts = 0;
 433        pwrctrlpriv->ips_leave_cnts = 0;
 434        pwrctrlpriv->bips_processing = false;
 435
 436        pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
 437        pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
 438
 439        pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
 440        pwrctrlpriv->pwr_state_check_cnts = 0;
 441        pwrctrlpriv->bInternalAutoSuspend = false;
 442        pwrctrlpriv->bInSuspend = false;
 443        pwrctrlpriv->bkeepfwalive = false;
 444
 445        pwrctrlpriv->LpsIdleCount = 0;
 446        if (padapter->registrypriv.mp_mode == 1)
 447                pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE;
 448        else
 449                pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/*  PS_MODE_MIN; */
 450        pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false;
 451
 452        pwrctrlpriv->bFwCurrentInPSMode = false;
 453
 454        pwrctrlpriv->rpwm = 0;
 455        pwrctrlpriv->cpwm = PS_STATE_S4;
 456
 457        pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
 458        pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
 459        pwrctrlpriv->bcn_ant_mode = 0;
 460
 461        pwrctrlpriv->tog = 0x80;
 462
 463        pwrctrlpriv->btcoex_rfon = false;
 464
 465        timer_setup(&pwrctrlpriv->pwr_state_check_timer, pwr_state_check_handler, 0);
 466}
 467
 468void rtw_free_pwrctrl_priv(struct adapter *adapter)
 469{
 470        struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv;
 471
 472        _free_pwrlock(&pwrctrlpriv->lock);
 473
 474}
 475
 476u8 rtw_interface_ps_func(struct adapter *padapter, enum hal_intf_ps_func efunc_id, u8 *val)
 477{
 478        u8 bResult = true;
 479        rtw_hal_intf_ps_func(padapter, efunc_id, val);
 480
 481        return bResult;
 482}
 483
 484inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms)
 485{
 486        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 487        pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ms);
 488}
 489
 490/*
 491* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
 492* @adapter: pointer to struct adapter structure
 493* @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup
 494* Return _SUCCESS or _FAIL
 495*/
 496
 497int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller)
 498{
 499        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 500        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 501        int ret = _SUCCESS;
 502        u32 start = jiffies;
 503
 504        if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms))
 505                pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms);
 506
 507        if (pwrpriv->ps_processing) {
 508                DBG_88E("%s wait ps_processing...\n", __func__);
 509                while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000)
 510                        msleep(10);
 511                if (pwrpriv->ps_processing)
 512                        DBG_88E("%s wait ps_processing timeout\n", __func__);
 513                else
 514                        DBG_88E("%s wait ps_processing done\n", __func__);
 515        }
 516
 517        /* System suspend is not allowed to wakeup */
 518        if ((!pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) {
 519                while (pwrpriv->bInSuspend &&
 520                       (rtw_get_passing_time_ms(start) <= 3000 ||
 521                       (rtw_get_passing_time_ms(start) <= 500)))
 522                                msleep(10);
 523                if (pwrpriv->bInSuspend)
 524                        DBG_88E("%s wait bInSuspend timeout\n", __func__);
 525                else
 526                        DBG_88E("%s wait bInSuspend done\n", __func__);
 527        }
 528
 529        /* block??? */
 530        if ((pwrpriv->bInternalAutoSuspend)  && (padapter->net_closed)) {
 531                ret = _FAIL;
 532                goto exit;
 533        }
 534
 535        /* I think this should be check in IPS, LPS, autosuspend functions... */
 536        if (check_fwstate(pmlmepriv, _FW_LINKED)) {
 537                ret = _SUCCESS;
 538                goto exit;
 539        }
 540        if (rf_off == pwrpriv->rf_pwrstate) {
 541                DBG_88E("%s call ips_leave....\n", __func__);
 542                if (_FAIL ==  ips_leave(padapter)) {
 543                        DBG_88E("======> ips_leave fail.............\n");
 544                        ret = _FAIL;
 545                        goto exit;
 546                }
 547        }
 548
 549        /* TODO: the following checking need to be merged... */
 550        if (padapter->bDriverStopped || !padapter->bup ||
 551            !padapter->hw_init_completed) {
 552                DBG_88E("%s: bDriverStopped=%d, bup=%d, hw_init_completed =%u\n"
 553                        , caller
 554                        , padapter->bDriverStopped
 555                        , padapter->bup
 556                        , padapter->hw_init_completed);
 557                ret = false;
 558                goto exit;
 559        }
 560
 561exit:
 562        if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms))
 563                pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms);
 564        return ret;
 565}
 566
 567int rtw_pm_set_lps(struct adapter *padapter, u8 mode)
 568{
 569        int     ret = 0;
 570        struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
 571
 572        if (mode < PS_MODE_NUM) {
 573                if (pwrctrlpriv->power_mgnt != mode) {
 574                        if (PS_MODE_ACTIVE == mode)
 575                                LeaveAllPowerSaveMode(padapter);
 576                        else
 577                                pwrctrlpriv->LpsIdleCount = 2;
 578                        pwrctrlpriv->power_mgnt = mode;
 579                        pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false;
 580                }
 581        } else {
 582                ret = -EINVAL;
 583        }
 584
 585        return ret;
 586}
 587
 588int rtw_pm_set_ips(struct adapter *padapter, u8 mode)
 589{
 590        struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
 591
 592        if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
 593                rtw_ips_mode_req(pwrctrlpriv, mode);
 594                DBG_88E("%s %s\n", __func__, mode == IPS_NORMAL ? "IPS_NORMAL" : "IPS_LEVEL_2");
 595                return 0;
 596        } else if (mode == IPS_NONE) {
 597                rtw_ips_mode_req(pwrctrlpriv, mode);
 598                DBG_88E("%s %s\n", __func__, "IPS_NONE");
 599                if ((padapter->bSurpriseRemoved == 0) && (_FAIL == rtw_pwr_wakeup(padapter)))
 600                        return -EFAULT;
 601        } else {
 602                return -EINVAL;
 603        }
 604        return 0;
 605}
 606