rtw_pwrctrl.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. ******************************************************************************/
  15. #define _RTW_PWRCTRL_C_
  16. #include <osdep_service.h>
  17. #include <drv_types.h>
  18. #include <osdep_intf.h>
  19. #include <rtl8723a_cmd.h>
  20. #include <rtw_sreset.h>
  21. #include <rtl8723a_bt_intf.h>
  22. #include <usb_ops_linux.h>
  23. void ips_enter23a(struct rtw_adapter *padapter)
  24. {
  25. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  26. down(&pwrpriv->lock);
  27. pwrpriv->bips_processing = true;
  28. /* syn ips_mode with request */
  29. pwrpriv->ips_mode = pwrpriv->ips_mode_req;
  30. pwrpriv->ips_enter23a_cnts++;
  31. DBG_8723A("==>ips_enter23a cnts:%d\n", pwrpriv->ips_enter23a_cnts);
  32. rtl8723a_BT_disable_coexist(padapter);
  33. if (pwrpriv->change_rfpwrstate == rf_off) {
  34. pwrpriv->bpower_saving = true;
  35. DBG_8723A_LEVEL(_drv_always_, "nolinked power save enter\n");
  36. if (pwrpriv->ips_mode == IPS_LEVEL_2)
  37. pwrpriv->bkeepfwalive = true;
  38. rtw_ips_pwr_down23a(padapter);
  39. pwrpriv->rf_pwrstate = rf_off;
  40. }
  41. pwrpriv->bips_processing = false;
  42. up(&pwrpriv->lock);
  43. }
  44. int ips_leave23a(struct rtw_adapter *padapter)
  45. {
  46. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  47. struct security_priv *psecuritypriv = &padapter->securitypriv;
  48. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  49. int result = _SUCCESS;
  50. int keyid;
  51. down(&pwrpriv->lock);
  52. if (pwrpriv->rf_pwrstate == rf_off && !pwrpriv->bips_processing) {
  53. pwrpriv->bips_processing = true;
  54. pwrpriv->change_rfpwrstate = rf_on;
  55. pwrpriv->ips_leave23a_cnts++;
  56. DBG_8723A("==>ips_leave23a cnts:%d\n",
  57. pwrpriv->ips_leave23a_cnts);
  58. result = rtw_ips_pwr_up23a(padapter);
  59. if (result == _SUCCESS)
  60. pwrpriv->rf_pwrstate = rf_on;
  61. DBG_8723A_LEVEL(_drv_always_, "nolinked power save leave\n");
  62. if (psecuritypriv->dot11PrivacyAlgrthm ==
  63. WLAN_CIPHER_SUITE_WEP40 ||
  64. psecuritypriv->dot11PrivacyAlgrthm ==
  65. WLAN_CIPHER_SUITE_WEP104) {
  66. DBG_8723A("==>%s, channel(%d), processing(%x)\n",
  67. __func__, padapter->mlmeextpriv.cur_channel,
  68. pwrpriv->bips_processing);
  69. set_channel_bwmode23a(padapter,
  70. padapter->mlmeextpriv.cur_channel,
  71. HAL_PRIME_CHNL_OFFSET_DONT_CARE,
  72. HT_CHANNEL_WIDTH_20);
  73. for (keyid = 0; keyid < 4; keyid++) {
  74. if (pmlmepriv->key_mask & BIT(keyid)) {
  75. if (keyid ==
  76. psecuritypriv->dot11PrivacyKeyIndex)
  77. result = rtw_set_key23a(padapter, psecuritypriv, keyid, 1);
  78. else
  79. result = rtw_set_key23a(padapter, psecuritypriv, keyid, 0);
  80. }
  81. }
  82. }
  83. DBG_8723A("==> ips_leave23a.....LED(0x%08x)...\n",
  84. rtl8723au_read32(padapter, 0x4c));
  85. pwrpriv->bips_processing = false;
  86. pwrpriv->bkeepfwalive = false;
  87. pwrpriv->bpower_saving = false;
  88. }
  89. up(&pwrpriv->lock);
  90. return result;
  91. }
  92. static bool rtw_pwr_unassociated_idle(struct rtw_adapter *adapter)
  93. {
  94. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  95. struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
  96. bool ret = false;
  97. if (time_after_eq(adapter->pwrctrlpriv.ips_deny_time, jiffies))
  98. goto exit;
  99. if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
  100. check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
  101. check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
  102. check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)){
  103. goto exit;
  104. }
  105. if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
  106. pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
  107. DBG_8723A_LEVEL(_drv_always_,
  108. "There are some pkts to transmit\n");
  109. DBG_8723A_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, "
  110. "free_xmit_extbuf_cnt: %d\n",
  111. pxmit_priv->free_xmitbuf_cnt,
  112. pxmit_priv->free_xmit_extbuf_cnt);
  113. goto exit;
  114. }
  115. ret = true;
  116. exit:
  117. return ret;
  118. }
  119. void rtw_ps_processor23a(struct rtw_adapter *padapter)
  120. {
  121. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  122. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  123. pwrpriv->ps_processing = true;
  124. if (pwrpriv->bips_processing == true)
  125. goto exit;
  126. if (pwrpriv->ips_mode_req == IPS_NONE)
  127. goto exit;
  128. if (!rtw_pwr_unassociated_idle(padapter))
  129. goto exit;
  130. if (pwrpriv->rf_pwrstate == rf_on &&
  131. (pwrpriv->pwr_state_check_cnts % 4) == 0) {
  132. DBG_8723A("==>%s .fw_state(%x)\n", __func__,
  133. get_fwstate(pmlmepriv));
  134. pwrpriv->change_rfpwrstate = rf_off;
  135. ips_enter23a(padapter);
  136. }
  137. exit:
  138. rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
  139. pwrpriv->ps_processing = false;
  140. }
  141. static void pwr_state_check_handler(unsigned long data)
  142. {
  143. struct rtw_adapter *padapter = (struct rtw_adapter *)data;
  144. rtw_ps_cmd23a(padapter);
  145. }
  146. /*
  147. *
  148. * Parameters
  149. * padapter
  150. * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
  151. *
  152. */
  153. void rtw_set_rpwm23a(struct rtw_adapter *padapter, u8 pslv)
  154. {
  155. u8 rpwm;
  156. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  157. pslv = PS_STATE(pslv);
  158. if (pwrpriv->btcoex_rfon) {
  159. if (pslv < PS_STATE_S4)
  160. pslv = PS_STATE_S3;
  161. }
  162. if (pwrpriv->rpwm == pslv) {
  163. RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
  164. "%s: Already set rpwm[0x%02X], new = 0x%02X!\n",
  165. __func__, pwrpriv->rpwm, pslv);
  166. return;
  167. }
  168. if (padapter->bSurpriseRemoved == true ||
  169. padapter->hw_init_completed == false) {
  170. RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
  171. "%s: SurpriseRemoved(%d) hw_init_completed(%d)\n",
  172. __func__, padapter->bSurpriseRemoved,
  173. padapter->hw_init_completed);
  174. pwrpriv->cpwm = PS_STATE_S4;
  175. return;
  176. }
  177. if (padapter->bDriverStopped == true) {
  178. RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
  179. "%s: change power state(0x%02X) when DriverStopped\n",
  180. __func__, pslv);
  181. if (pslv < PS_STATE_S2) {
  182. RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
  183. "%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n",
  184. __func__, pslv);
  185. return;
  186. }
  187. }
  188. rpwm = pslv | pwrpriv->tog;
  189. RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
  190. "rtw_set_rpwm23a: rpwm = 0x%02x cpwm = 0x%02x\n",
  191. rpwm, pwrpriv->cpwm);
  192. pwrpriv->rpwm = pslv;
  193. rtl8723a_set_rpwm(padapter, rpwm);
  194. pwrpriv->tog += 0x80;
  195. pwrpriv->cpwm = pslv;
  196. }
  197. static bool PS_RDY_CHECK(struct rtw_adapter *padapter)
  198. {
  199. unsigned long delta_time;
  200. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  201. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  202. delta_time = jiffies - pwrpriv->DelayLPSLastTimeStamp;
  203. if (delta_time < LPS_DELAY_TIME)
  204. return false;
  205. if (!check_fwstate(pmlmepriv, _FW_LINKED) ||
  206. check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) ||
  207. check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
  208. check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
  209. check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
  210. return false;
  211. if (pwrpriv->bInSuspend)
  212. return false;
  213. if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X &&
  214. !padapter->securitypriv.binstallGrpkey) {
  215. DBG_8723A("Group handshake still in progress !!!\n");
  216. return false;
  217. }
  218. if (!rtw_cfg80211_pwr_mgmt(padapter))
  219. return false;
  220. return true;
  221. }
  222. void rtw_set_ps_mode23a(struct rtw_adapter *padapter, u8 ps_mode,
  223. u8 smart_ps, u8 bcn_ant_mode)
  224. {
  225. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  226. RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
  227. "%s: PowerMode =%d Smart_PS =%d\n",
  228. __func__, ps_mode, smart_ps);
  229. if (ps_mode > PM_Card_Disable) {
  230. RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
  231. "ps_mode:%d error\n", ps_mode);
  232. return;
  233. }
  234. if (pwrpriv->pwr_mode == ps_mode) {
  235. if (PS_MODE_ACTIVE == ps_mode)
  236. return;
  237. if (pwrpriv->smart_ps == smart_ps &&
  238. pwrpriv->bcn_ant_mode == bcn_ant_mode)
  239. return;
  240. }
  241. if (ps_mode == PS_MODE_ACTIVE) {
  242. DBG_8723A("rtw_set_ps_mode23a: Leave 802.11 power save\n");
  243. pwrpriv->pwr_mode = ps_mode;
  244. rtw_set_rpwm23a(padapter, PS_STATE_S4);
  245. rtl8723a_set_FwPwrMode_cmd(padapter, ps_mode);
  246. pwrpriv->bFwCurrentInPSMode = false;
  247. } else {
  248. if (PS_RDY_CHECK(padapter) ||
  249. rtl8723a_BT_using_antenna_1(padapter)) {
  250. DBG_8723A("%s: Enter 802.11 power save\n", __func__);
  251. pwrpriv->bFwCurrentInPSMode = true;
  252. pwrpriv->pwr_mode = ps_mode;
  253. pwrpriv->smart_ps = smart_ps;
  254. pwrpriv->bcn_ant_mode = bcn_ant_mode;
  255. rtl8723a_set_FwPwrMode_cmd(padapter, ps_mode);
  256. rtw_set_rpwm23a(padapter, PS_STATE_S2);
  257. }
  258. }
  259. }
  260. /*
  261. * Return:
  262. * 0: Leave OK
  263. * -1: Timeout
  264. * -2: Other error
  265. */
  266. s32 LPS_RF_ON_check23a(struct rtw_adapter *padapter, u32 delay_ms)
  267. {
  268. unsigned long start_time, end_time;
  269. u8 bAwake = false;
  270. s32 err = 0;
  271. start_time = jiffies;
  272. end_time = start_time + msecs_to_jiffies(delay_ms);
  273. while (1) {
  274. bAwake = rtl8723a_get_fwlps_rf_on(padapter);
  275. if (bAwake == true)
  276. break;
  277. if (padapter->bSurpriseRemoved == true) {
  278. err = -2;
  279. DBG_8723A("%s: device surprise removed!!\n", __func__);
  280. break;
  281. }
  282. if (time_after(jiffies, end_time)) {
  283. err = -1;
  284. DBG_8723A("%s: Wait for FW LPS leave more than %u "
  285. "ms!\n", __func__, delay_ms);
  286. break;
  287. }
  288. udelay(100);
  289. }
  290. return err;
  291. }
  292. /* Description: */
  293. /* Enter the leisure power save mode. */
  294. void LPS_Enter23a(struct rtw_adapter *padapter)
  295. {
  296. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  297. if (!PS_RDY_CHECK(padapter))
  298. return;
  299. if (pwrpriv->bLeisurePs) {
  300. /* Idle for a while if we connect to AP a while ago. */
  301. if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */
  302. if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
  303. pwrpriv->bpower_saving = true;
  304. DBG_8723A("%s smart_ps:%d\n", __func__,
  305. pwrpriv->smart_ps);
  306. /* For Tenda W311R IOT issue */
  307. rtw_set_ps_mode23a(padapter,
  308. pwrpriv->power_mgnt,
  309. pwrpriv->smart_ps, 0);
  310. }
  311. } else
  312. pwrpriv->LpsIdleCount++;
  313. }
  314. }
  315. /* Description: */
  316. /* Leave the leisure power save mode. */
  317. void LPS_Leave23a(struct rtw_adapter *padapter)
  318. {
  319. #define LPS_LEAVE_TIMEOUT_MS 100
  320. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  321. if (pwrpriv->bLeisurePs) {
  322. if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
  323. rtw_set_ps_mode23a(padapter, PS_MODE_ACTIVE, 0, 0);
  324. if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
  325. LPS_RF_ON_check23a(padapter,
  326. LPS_LEAVE_TIMEOUT_MS);
  327. }
  328. }
  329. pwrpriv->bpower_saving = false;
  330. }
  331. /* Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */
  332. /* Move code to function by tynli. 2010.03.26. */
  333. void LeaveAllPowerSaveMode23a(struct rtw_adapter *Adapter)
  334. {
  335. struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
  336. u8 enqueue = 0;
  337. /* DBG_8723A("%s.....\n", __func__); */
  338. if (check_fwstate(pmlmepriv, _FW_LINKED))
  339. rtw_lps_ctrl_wk_cmd23a(Adapter, LPS_CTRL_LEAVE, enqueue);
  340. }
  341. void rtw_init_pwrctrl_priv23a(struct rtw_adapter *padapter)
  342. {
  343. struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
  344. sema_init(&pwrctrlpriv->lock, 1);
  345. pwrctrlpriv->rf_pwrstate = rf_on;
  346. pwrctrlpriv->ips_enter23a_cnts = 0;
  347. pwrctrlpriv->ips_leave23a_cnts = 0;
  348. pwrctrlpriv->bips_processing = false;
  349. pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
  350. pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
  351. pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
  352. pwrctrlpriv->pwr_state_check_cnts = 0;
  353. pwrctrlpriv->bInSuspend = false;
  354. pwrctrlpriv->bkeepfwalive = false;
  355. pwrctrlpriv->LpsIdleCount = 0;
  356. /* PS_MODE_MIN; */
  357. pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;
  358. pwrctrlpriv->bLeisurePs =
  359. (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt)?true:false;
  360. pwrctrlpriv->bFwCurrentInPSMode = false;
  361. pwrctrlpriv->rpwm = 0;
  362. pwrctrlpriv->cpwm = PS_STATE_S4;
  363. pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
  364. pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
  365. pwrctrlpriv->bcn_ant_mode = 0;
  366. pwrctrlpriv->tog = 0x80;
  367. pwrctrlpriv->btcoex_rfon = false;
  368. setup_timer(&pwrctrlpriv->pwr_state_check_timer,
  369. pwr_state_check_handler, (unsigned long)padapter);
  370. }
  371. void rtw_free_pwrctrl_priv(struct rtw_adapter *adapter)
  372. {
  373. }
  374. inline void rtw_set_ips_deny23a(struct rtw_adapter *padapter, u32 ms)
  375. {
  376. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  377. pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms);
  378. }
  379. /*
  380. * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
  381. * @adapter: pointer to _adapter structure
  382. * @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup
  383. * Return _SUCCESS or _FAIL
  384. */
  385. int _rtw_pwr_wakeup23a(struct rtw_adapter *padapter, u32 ips_deffer_ms, const char *caller)
  386. {
  387. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  388. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  389. int ret = _SUCCESS;
  390. unsigned long start = jiffies;
  391. unsigned long new_deny_time;
  392. new_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
  393. if (time_before(pwrpriv->ips_deny_time, new_deny_time))
  394. pwrpriv->ips_deny_time = new_deny_time;
  395. if (pwrpriv->ps_processing) {
  396. DBG_8723A("%s wait ps_processing...\n", __func__);
  397. while (pwrpriv->ps_processing &&
  398. jiffies_to_msecs(jiffies - start) <= 3000)
  399. msleep(10);
  400. if (pwrpriv->ps_processing)
  401. DBG_8723A("%s wait ps_processing timeout\n", __func__);
  402. else
  403. DBG_8723A("%s wait ps_processing done\n", __func__);
  404. }
  405. if (rtw_sreset_inprogress(padapter)) {
  406. DBG_8723A("%s wait sreset_inprogress...\n", __func__);
  407. while (rtw_sreset_inprogress(padapter) &&
  408. jiffies_to_msecs(jiffies - start) <= 4000)
  409. msleep(10);
  410. if (rtw_sreset_inprogress(padapter))
  411. DBG_8723A("%s wait sreset_inprogress timeout\n",
  412. __func__);
  413. else
  414. DBG_8723A("%s wait sreset_inprogress done\n", __func__);
  415. }
  416. if (pwrpriv->bInSuspend) {
  417. DBG_8723A("%s wait bInSuspend...\n", __func__);
  418. while (pwrpriv->bInSuspend &&
  419. (jiffies_to_msecs(jiffies - start) <= 3000)) {
  420. msleep(10);
  421. }
  422. if (pwrpriv->bInSuspend)
  423. DBG_8723A("%s wait bInSuspend timeout\n", __func__);
  424. else
  425. DBG_8723A("%s wait bInSuspend done\n", __func__);
  426. }
  427. /* System suspend is not allowed to wakeup */
  428. if (pwrpriv->bInSuspend) {
  429. ret = _FAIL;
  430. goto exit;
  431. }
  432. /* I think this should be check in IPS, LPS, autosuspend functions... */
  433. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  434. ret = _SUCCESS;
  435. goto exit;
  436. }
  437. if (rf_off == pwrpriv->rf_pwrstate) {
  438. DBG_8723A("%s call ips_leave23a....\n", __func__);
  439. if (ips_leave23a(padapter)== _FAIL) {
  440. DBG_8723A("======> ips_leave23a fail.............\n");
  441. ret = _FAIL;
  442. goto exit;
  443. }
  444. }
  445. /* TODO: the following checking need to be merged... */
  446. if (padapter->bDriverStopped || !padapter->bup ||
  447. !padapter->hw_init_completed) {
  448. DBG_8723A("%s: bDriverStopped =%d, bup =%d, hw_init_completed "
  449. "=%u\n", caller, padapter->bDriverStopped,
  450. padapter->bup, padapter->hw_init_completed);
  451. ret = _FAIL;
  452. goto exit;
  453. }
  454. exit:
  455. new_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
  456. if (time_before(pwrpriv->ips_deny_time, new_deny_time))
  457. pwrpriv->ips_deny_time = new_deny_time;
  458. return ret;
  459. }
  460. int rtw_pm_set_lps23a(struct rtw_adapter *padapter, u8 mode)
  461. {
  462. int ret = 0;
  463. struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
  464. if (mode < PS_MODE_NUM) {
  465. if (pwrctrlpriv->power_mgnt != mode) {
  466. if (PS_MODE_ACTIVE == mode)
  467. LeaveAllPowerSaveMode23a(padapter);
  468. else
  469. pwrctrlpriv->LpsIdleCount = 2;
  470. pwrctrlpriv->power_mgnt = mode;
  471. pwrctrlpriv->bLeisurePs =
  472. (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ?
  473. true:false;
  474. }
  475. } else
  476. ret = -EINVAL;
  477. return ret;
  478. }
  479. int rtw_pm_set_ips23a(struct rtw_adapter *padapter, u8 mode)
  480. {
  481. struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
  482. if (mode != IPS_NORMAL && mode != IPS_LEVEL_2 && mode != IPS_NONE)
  483. return -EINVAL;
  484. pwrctrlpriv->ips_mode_req = mode;
  485. if (mode == IPS_NONE) {
  486. DBG_8723A("%s %s\n", __func__, "IPS_NONE");
  487. if (padapter->bSurpriseRemoved == 0 &&
  488. rtw_pwr_wakeup(padapter) == _FAIL)
  489. return -EFAULT;
  490. }
  491. return 0;
  492. }