]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
staging: rtl8188eu: rtw_io.h: Remove unused structures and macros
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / rtl8188eu / core / rtw_pwrctrl.c
CommitLineData
1cc18a22
LF
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20#define _RTW_PWRCTRL_C_
21
22#include <osdep_service.h>
23#include <drv_types.h>
24#include <osdep_intf.h>
25#include <linux/usb.h>
95311b47 26#include <usb_osintf.h>
27
28static int rtw_hw_suspend(struct adapter *padapter)
29{
30 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
31 struct net_device *pnetdev = padapter->pnetdev;
32
33
34 if ((!padapter->bup) || (padapter->bDriverStopped) ||
35 (padapter->bSurpriseRemoved)) {
36 DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n",
37 padapter->bup, padapter->bDriverStopped,
38 padapter->bSurpriseRemoved);
39 goto error_exit;
40 }
41
42 /* system suspend */
43 LeaveAllPowerSaveMode(padapter);
44
45 DBG_88E("==> rtw_hw_suspend\n");
46 _enter_pwrlock(&pwrpriv->lock);
47 pwrpriv->bips_processing = true;
48 /* s1. */
49 if (pnetdev) {
50 netif_carrier_off(pnetdev);
51 netif_tx_stop_all_queues(pnetdev);
52 }
53
54 /* s2. */
55 rtw_disassoc_cmd(padapter, 500, false);
56
57 /* s2-2. indicate disconnect to os */
58 {
59 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
60
61 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
62 _clr_fwstate_(pmlmepriv, _FW_LINKED);
63
64 rtw_led_control(padapter, LED_CTL_NO_LINK);
65
66 rtw_os_indicate_disconnect(padapter);
67
68 /* donnot enqueue cmd */
69 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0);
70 }
71 }
72 /* s2-3. */
73 rtw_free_assoc_resources(padapter, 1);
74
75 /* s2-4. */
76 rtw_free_network_queue(padapter, true);
77 rtw_ips_dev_unload(padapter);
78 pwrpriv->rf_pwrstate = rf_off;
79 pwrpriv->bips_processing = false;
80
81 _exit_pwrlock(&pwrpriv->lock);
82
83 return 0;
84
85error_exit:
86 DBG_88E("%s, failed\n", __func__);
87 return -1;
88}
89
90static int rtw_hw_resume(struct adapter *padapter)
91{
92 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
93 struct net_device *pnetdev = padapter->pnetdev;
94
95
96 /* system resume */
97 DBG_88E("==> rtw_hw_resume\n");
98 _enter_pwrlock(&pwrpriv->lock);
99 pwrpriv->bips_processing = true;
100 rtw_reset_drv_sw(padapter);
101
102 if (pm_netdev_open(pnetdev, false) != 0) {
103 _exit_pwrlock(&pwrpriv->lock);
104 goto error_exit;
105 }
106
107 netif_device_attach(pnetdev);
108 netif_carrier_on(pnetdev);
109
110 if (!netif_queue_stopped(pnetdev))
111 netif_start_queue(pnetdev);
112 else
113 netif_wake_queue(pnetdev);
114
115 pwrpriv->bkeepfwalive = false;
116 pwrpriv->brfoffbyhw = false;
117
118 pwrpriv->rf_pwrstate = rf_on;
119 pwrpriv->bips_processing = false;
120
121 _exit_pwrlock(&pwrpriv->lock);
122
123
124 return 0;
125error_exit:
126 DBG_88E("%s, Open net dev failed\n", __func__);
127 return -1;
128}
1cc18a22
LF
129
130void ips_enter(struct adapter *padapter)
131{
132 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
133 struct xmit_priv *pxmit_priv = &padapter->xmitpriv;
134
135 if (padapter->registrypriv.mp_mode == 1)
136 return;
137
138 if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
139 pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
140 DBG_88E_LEVEL(_drv_info_, "There are some pkts to transmit\n");
141 DBG_88E_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n",
142 pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);
143 return;
144 }
145
146 _enter_pwrlock(&pwrpriv->lock);
147
148 pwrpriv->bips_processing = true;
149
150 /* syn ips_mode with request */
151 pwrpriv->ips_mode = pwrpriv->ips_mode_req;
152
153 pwrpriv->ips_enter_cnts++;
154 DBG_88E("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts);
155 if (rf_off == pwrpriv->change_rfpwrstate) {
156 pwrpriv->bpower_saving = true;
157 DBG_88E_LEVEL(_drv_info_, "nolinked power save enter\n");
158
159 if (pwrpriv->ips_mode == IPS_LEVEL_2)
160 pwrpriv->bkeepfwalive = true;
161
162 rtw_ips_pwr_down(padapter);
163 pwrpriv->rf_pwrstate = rf_off;
164 }
165 pwrpriv->bips_processing = false;
166
167 _exit_pwrlock(&pwrpriv->lock);
168}
169
170int ips_leave(struct adapter *padapter)
171{
172 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
173 struct security_priv *psecuritypriv = &(padapter->securitypriv);
174 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
175 int result = _SUCCESS;
176 int keyid;
177
178
179 _enter_pwrlock(&pwrpriv->lock);
180
181 if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
182 pwrpriv->bips_processing = true;
183 pwrpriv->change_rfpwrstate = rf_on;
184 pwrpriv->ips_leave_cnts++;
185 DBG_88E("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts);
186
187 result = rtw_ips_pwr_up(padapter);
188 if (result == _SUCCESS) {
189 pwrpriv->rf_pwrstate = rf_on;
190 }
191 DBG_88E_LEVEL(_drv_info_, "nolinked power save leave\n");
192
193 if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) || (_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) {
194 DBG_88E("==>%s, channel(%d), processing(%x)\n", __func__, padapter->mlmeextpriv.cur_channel, pwrpriv->bips_processing);
195 set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
196 for (keyid = 0; keyid < 4; keyid++) {
197 if (pmlmepriv->key_mask & BIT(keyid)) {
198 if (keyid == psecuritypriv->dot11PrivacyKeyIndex)
199 result = rtw_set_key(padapter, psecuritypriv, keyid, 1);
200 else
201 result = rtw_set_key(padapter, psecuritypriv, keyid, 0);
202 }
203 }
204 }
205
99ecfb06 206 DBG_88E("==> ips_leave.....LED(0x%08x)...\n", usb_read32(padapter, 0x4c));
1cc18a22
LF
207 pwrpriv->bips_processing = false;
208
209 pwrpriv->bkeepfwalive = false;
210 pwrpriv->bpower_saving = false;
211 }
212
213 _exit_pwrlock(&pwrpriv->lock);
214
215 return result;
216}
217
218static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
219{
1cc18a22
LF
220 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
221#ifdef CONFIG_88EU_P2P
222 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
223#endif
224
225 bool ret = false;
226
e017a92b 227 if (time_after_eq(adapter->pwrctrlpriv.ips_deny_time, jiffies))
1cc18a22
LF
228 goto exit;
229
230 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
231 check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
232 check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
233 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) ||
234#if defined(CONFIG_88EU_P2P)
235 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
236#else
237 0)
238#endif
239 goto exit;
240
1cc18a22
LF
241 ret = true;
242
243exit:
244 return ret;
245}
246
247void rtw_ps_processor(struct adapter *padapter)
248{
249 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
250 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
251 enum rt_rf_power_state rfpwrstate;
252
253 pwrpriv->ps_processing = true;
254
255 if (pwrpriv->bips_processing)
256 goto exit;
257
258 if (padapter->pwrctrlpriv.bHWPwrPindetect) {
259 rfpwrstate = RfOnOffDetect(padapter);
260 DBG_88E("@@@@- #2 %s==> rfstate:%s\n", __func__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off");
261
262 if (rfpwrstate != pwrpriv->rf_pwrstate) {
263 if (rfpwrstate == rf_off) {
264 pwrpriv->change_rfpwrstate = rf_off;
265 pwrpriv->brfoffbyhw = true;
1cc18a22
LF
266 rtw_hw_suspend(padapter);
267 } else {
268 pwrpriv->change_rfpwrstate = rf_on;
269 rtw_hw_resume(padapter);
270 }
271 DBG_88E("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on");
272 }
273 pwrpriv->pwr_state_check_cnts++;
274 }
275
276 if (pwrpriv->ips_mode_req == IPS_NONE)
277 goto exit;
278
5b66fb7d 279 if (!rtw_pwr_unassociated_idle(padapter))
1cc18a22
LF
280 goto exit;
281
282 if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4) == 0)) {
283 DBG_88E("==>%s .fw_state(%x)\n", __func__, get_fwstate(pmlmepriv));
284 pwrpriv->change_rfpwrstate = rf_off;
285
286 ips_enter(padapter);
287 }
288exit:
289 rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
290 pwrpriv->ps_processing = false;
291 return;
292}
293
294static void pwr_state_check_handler(void *FunctionContext)
295{
296 struct adapter *padapter = (struct adapter *)FunctionContext;
297 rtw_ps_cmd(padapter);
298}
299
300/*
301 *
302 * Parameters
303 * padapter
304 * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
305 *
306 */
307void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
308{
309 u8 rpwm;
310 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
311
1cc18a22
LF
312 pslv = PS_STATE(pslv);
313
1cc18a22
LF
314 if (pwrpriv->btcoex_rfon) {
315 if (pslv < PS_STATE_S4)
316 pslv = PS_STATE_S3;
317 }
318
319 if ((pwrpriv->rpwm == pslv)) {
320 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
321 ("%s: Already set rpwm[0x%02X], new=0x%02X!\n", __func__, pwrpriv->rpwm, pslv));
322 return;
323 }
324
325 if ((padapter->bSurpriseRemoved) ||
326 (!padapter->hw_init_completed)) {
327 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
328 ("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n",
329 __func__, padapter->bSurpriseRemoved, padapter->hw_init_completed));
330
331 pwrpriv->cpwm = PS_STATE_S4;
332
333 return;
334 }
335
336 if (padapter->bDriverStopped) {
337 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
338 ("%s: change power state(0x%02X) when DriverStopped\n", __func__, pslv));
339
340 if (pslv < PS_STATE_S2) {
341 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
342 ("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __func__, pslv));
343 return;
344 }
345 }
346
347 rpwm = pslv | pwrpriv->tog;
348 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
349 ("rtw_set_rpwm: rpwm=0x%02x cpwm=0x%02x\n", rpwm, pwrpriv->cpwm));
350
351 pwrpriv->rpwm = pslv;
352
353 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
354
355 pwrpriv->tog += 0x80;
356 pwrpriv->cpwm = pslv;
1cc18a22
LF
357}
358
359static u8 PS_RDY_CHECK(struct adapter *padapter)
360{
361 u32 curr_time, delta_time;
362 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
363 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
364
365
c01fb496 366 curr_time = jiffies;
1cc18a22
LF
367 delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
368
369 if (delta_time < LPS_DELAY_TIME)
370 return false;
371
372 if ((check_fwstate(pmlmepriv, _FW_LINKED) == false) ||
373 (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ||
374 (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ||
375 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
376 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
377 return false;
378 if (pwrpriv->bInSuspend)
379 return false;
380 if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == false)) {
381 DBG_88E("Group handshake still in progress !!!\n");
382 return false;
383 }
384 return true;
385}
386
387void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
388{
389 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
390#ifdef CONFIG_88EU_P2P
391 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
392#endif /* CONFIG_88EU_P2P */
393
1cc18a22
LF
394 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
395 ("%s: PowerMode=%d Smart_PS=%d\n",
396 __func__, ps_mode, smart_ps));
397
398 if (ps_mode > PM_Card_Disable) {
399 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("ps_mode:%d error\n", ps_mode));
400 return;
401 }
402
403 if (pwrpriv->pwr_mode == ps_mode) {
404 if (PS_MODE_ACTIVE == ps_mode)
405 return;
406
407 if ((pwrpriv->smart_ps == smart_ps) &&
408 (pwrpriv->bcn_ant_mode == bcn_ant_mode))
409 return;
410 }
411
412 /* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
413 if (ps_mode == PS_MODE_ACTIVE) {
414#ifdef CONFIG_88EU_P2P
415 if (pwdinfo->opp_ps == 0) {
416 DBG_88E("rtw_set_ps_mode: Leave 802.11 power save\n");
417 pwrpriv->pwr_mode = ps_mode;
418 rtw_set_rpwm(padapter, PS_STATE_S4);
419 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
420 pwrpriv->bFwCurrentInPSMode = false;
421 }
422 } else {
423#endif /* CONFIG_88EU_P2P */
424 if (PS_RDY_CHECK(padapter)) {
425 DBG_88E("%s: Enter 802.11 power save\n", __func__);
426 pwrpriv->bFwCurrentInPSMode = true;
427 pwrpriv->pwr_mode = ps_mode;
428 pwrpriv->smart_ps = smart_ps;
429 pwrpriv->bcn_ant_mode = bcn_ant_mode;
430 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
431
432#ifdef CONFIG_88EU_P2P
433 /* Set CTWindow after LPS */
434 if (pwdinfo->opp_ps == 1)
435 p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
436#endif /* CONFIG_88EU_P2P */
437
438 rtw_set_rpwm(padapter, PS_STATE_S2);
439 }
440 }
1cc18a22
LF
441}
442
443/*
444 * Return:
445 * 0: Leave OK
446 * -1: Timeout
447 * -2: Other error
448 */
449s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
450{
451 u32 start_time;
452 u8 bAwake = false;
453 s32 err = 0;
454
455
c01fb496 456 start_time = jiffies;
1cc18a22
LF
457 while (1) {
458 rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
459 if (bAwake)
460 break;
461
462 if (padapter->bSurpriseRemoved) {
463 err = -2;
464 DBG_88E("%s: device surprise removed!!\n", __func__);
465 break;
466 }
467
468 if (rtw_get_passing_time_ms(start_time) > delay_ms) {
469 err = -1;
470 DBG_88E("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms);
471 break;
472 }
b2dcff2a 473 msleep(1);
1cc18a22
LF
474 }
475
476 return err;
477}
478
479/* */
480/* Description: */
481/* Enter the leisure power save mode. */
482/* */
483void LPS_Enter(struct adapter *padapter)
484{
485 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
486
1cc18a22
LF
487 if (PS_RDY_CHECK(padapter) == false)
488 return;
489
490 if (pwrpriv->bLeisurePs) {
491 /* Idle for a while if we connect to AP a while ago. */
492 if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */
493 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
494 pwrpriv->bpower_saving = true;
495 DBG_88E("%s smart_ps:%d\n", __func__, pwrpriv->smart_ps);
496 /* For Tenda W311R IOT issue */
497 rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, pwrpriv->smart_ps, 0);
498 }
499 } else {
500 pwrpriv->LpsIdleCount++;
501 }
502 }
1cc18a22
LF
503}
504
505#define LPS_LEAVE_TIMEOUT_MS 100
506
507/* Description: */
508/* Leave the leisure power save mode. */
509void LPS_Leave(struct adapter *padapter)
510{
511 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
512
1cc18a22
LF
513 if (pwrpriv->bLeisurePs) {
514 if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
515 rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0);
516
517 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
518 LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS);
519 }
520 }
521
522 pwrpriv->bpower_saving = false;
1cc18a22
LF
523}
524
525/* */
526/* Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */
527/* Move code to function by tynli. 2010.03.26. */
528/* */
529void LeaveAllPowerSaveMode(struct adapter *Adapter)
530{
531 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
532 u8 enqueue = 0;
533
1cc18a22
LF
534 if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */
535 p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, enqueue);
536
537 rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
538 }
1cc18a22
LF
539}
540
541void rtw_init_pwrctrl_priv(struct adapter *padapter)
542{
543 struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
544
1cc18a22
LF
545 _init_pwrlock(&pwrctrlpriv->lock);
546 pwrctrlpriv->rf_pwrstate = rf_on;
547 pwrctrlpriv->ips_enter_cnts = 0;
548 pwrctrlpriv->ips_leave_cnts = 0;
549 pwrctrlpriv->bips_processing = false;
550
551 pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
552 pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
553
554 pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
555 pwrctrlpriv->pwr_state_check_cnts = 0;
556 pwrctrlpriv->bInternalAutoSuspend = false;
557 pwrctrlpriv->bInSuspend = false;
558 pwrctrlpriv->bkeepfwalive = false;
559
560 pwrctrlpriv->LpsIdleCount = 0;
561 if (padapter->registrypriv.mp_mode == 1)
562 pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE ;
563 else
564 pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */
565 pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false;
566
567 pwrctrlpriv->bFwCurrentInPSMode = false;
568
569 pwrctrlpriv->rpwm = 0;
570 pwrctrlpriv->cpwm = PS_STATE_S4;
571
572 pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
573 pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
574 pwrctrlpriv->bcn_ant_mode = 0;
575
576 pwrctrlpriv->tog = 0x80;
577
578 pwrctrlpriv->btcoex_rfon = false;
579
580 _init_timer(&(pwrctrlpriv->pwr_state_check_timer), padapter->pnetdev, pwr_state_check_handler, (u8 *)padapter);
1cc18a22
LF
581}
582
1cc18a22
LF
583inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms)
584{
585 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
c01fb496 586 pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ms);
1cc18a22
LF
587}
588
589/*
590* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
591* @adapter: pointer to struct adapter structure
40a46d8b 592* @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup
1cc18a22
LF
593* Return _SUCCESS or _FAIL
594*/
595
596int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller)
597{
598 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
599 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
e017a92b 600 unsigned long expires;
1cc18a22
LF
601 int ret = _SUCCESS;
602
e017a92b
MS
603 expires = jiffies + rtw_ms_to_systime(ips_deffer_ms);
604 if (time_before(pwrpriv->ips_deny_time, expires))
c01fb496 605 pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms);
1cc18a22
LF
606
607{
c01fb496 608 u32 start = jiffies;
1cc18a22
LF
609 if (pwrpriv->ps_processing) {
610 DBG_88E("%s wait ps_processing...\n", __func__);
611 while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000)
0da46e6b 612 msleep(10);
1cc18a22
LF
613 if (pwrpriv->ps_processing)
614 DBG_88E("%s wait ps_processing timeout\n", __func__);
615 else
616 DBG_88E("%s wait ps_processing done\n", __func__);
617 }
618}
619
620 /* System suspend is not allowed to wakeup */
621 if ((!pwrpriv->bInternalAutoSuspend) && (pwrpriv->bInSuspend)) {
622 ret = _FAIL;
623 goto exit;
624 }
625
626 /* block??? */
627 if ((pwrpriv->bInternalAutoSuspend) && (padapter->net_closed)) {
628 ret = _FAIL;
629 goto exit;
630 }
631
632 /* I think this should be check in IPS, LPS, autosuspend functions... */
633 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
634 ret = _SUCCESS;
635 goto exit;
636 }
637 if (rf_off == pwrpriv->rf_pwrstate) {
638 DBG_88E("%s call ips_leave....\n", __func__);
639 if (_FAIL == ips_leave(padapter)) {
640 DBG_88E("======> ips_leave fail.............\n");
641 ret = _FAIL;
642 goto exit;
643 }
644 }
645
646 /* TODO: the following checking need to be merged... */
647 if (padapter->bDriverStopped || !padapter->bup ||
648 !padapter->hw_init_completed) {
649 DBG_88E("%s: bDriverStopped=%d, bup=%d, hw_init_completed =%u\n"
650 , caller
651 , padapter->bDriverStopped
652 , padapter->bup
653 , padapter->hw_init_completed);
654 ret = false;
655 goto exit;
656 }
657
658exit:
e017a92b
MS
659 expires = jiffies + rtw_ms_to_systime(ips_deffer_ms);
660 if (time_before(pwrpriv->ips_deny_time, expires))
c01fb496 661 pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms);
1cc18a22
LF
662 return ret;
663}
664
665int rtw_pm_set_lps(struct adapter *padapter, u8 mode)
666{
667 int ret = 0;
668 struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
669
670 if (mode < PS_MODE_NUM) {
671 if (pwrctrlpriv->power_mgnt != mode) {
672 if (PS_MODE_ACTIVE == mode)
673 LeaveAllPowerSaveMode(padapter);
674 else
675 pwrctrlpriv->LpsIdleCount = 2;
676 pwrctrlpriv->power_mgnt = mode;
677 pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false;
678 }
679 } else {
680 ret = -EINVAL;
681 }
682
683 return ret;
684}
685
686int rtw_pm_set_ips(struct adapter *padapter, u8 mode)
687{
688 struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
689
690 if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
691 rtw_ips_mode_req(pwrctrlpriv, mode);
692 DBG_88E("%s %s\n", __func__, mode == IPS_NORMAL ? "IPS_NORMAL" : "IPS_LEVEL_2");
693 return 0;
694 } else if (mode == IPS_NONE) {
695 rtw_ips_mode_req(pwrctrlpriv, mode);
696 DBG_88E("%s %s\n", __func__, "IPS_NONE");
697 if ((padapter->bSurpriseRemoved == 0) && (_FAIL == rtw_pwr_wakeup(padapter)))
698 return -EFAULT;
699 } else {
700 return -EINVAL;
701 }
702 return 0;
703}