This source file includes following definitions.
- _ips_enter
- ips_enter
- _ips_leave
- ips_leave
- rtw_pwr_unassociated_idle
- rtw_ps_processor
- pwr_state_check_handler
- traffic_check_for_leave_lps
- rtw_set_rpwm
- PS_RDY_CHECK
- rtw_set_ps_mode
- LPS_RF_ON_check
- LPS_Enter
- LPS_Leave
- LeaveAllPowerSaveModeDirect
- LeaveAllPowerSaveMode
- LPS_Leave_check
- cpwm_int_hdl
- cpwm_event_callback
- rpwmtimeout_workitem_callback
- pwr_rpwm_timeout_handler
- register_task_alive
- unregister_task_alive
- rtw_register_task_alive
- rtw_unregister_task_alive
- rtw_register_tx_alive
- rtw_register_cmd_alive
- rtw_unregister_tx_alive
- rtw_unregister_cmd_alive
- rtw_init_pwrctrl_priv
- rtw_free_pwrctrl_priv
- rtw_set_ips_deny
- _rtw_pwr_wakeup
- rtw_pm_set_lps
- rtw_pm_set_ips
- rtw_ps_deny
- rtw_ps_deny_cancel
- rtw_ps_deny_get
1
2
3
4
5
6
7 #define _RTW_PWRCTRL_C_
8
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include <hal_data.h>
12 #include <linux/jiffies.h>
13
14
15 void _ips_enter(struct adapter *padapter)
16 {
17 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
18
19 pwrpriv->bips_processing = true;
20
21
22 pwrpriv->ips_mode = pwrpriv->ips_mode_req;
23
24 pwrpriv->ips_enter_cnts++;
25 DBG_871X("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts);
26
27 if (rf_off == pwrpriv->change_rfpwrstate) {
28 pwrpriv->bpower_saving = true;
29 DBG_871X("nolinked power save enter\n");
30
31 if (pwrpriv->ips_mode == IPS_LEVEL_2)
32 pwrpriv->bkeepfwalive = true;
33
34 rtw_ips_pwr_down(padapter);
35 pwrpriv->rf_pwrstate = rf_off;
36 }
37 pwrpriv->bips_processing = false;
38
39 }
40
41 void ips_enter(struct adapter *padapter)
42 {
43 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
44
45
46 hal_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req);
47
48 mutex_lock(&pwrpriv->lock);
49 _ips_enter(padapter);
50 mutex_unlock(&pwrpriv->lock);
51 }
52
53 int _ips_leave(struct adapter *padapter)
54 {
55 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
56 int result = _SUCCESS;
57
58 if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
59 pwrpriv->bips_processing = true;
60 pwrpriv->change_rfpwrstate = rf_on;
61 pwrpriv->ips_leave_cnts++;
62 DBG_871X("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts);
63
64 result = rtw_ips_pwr_up(padapter);
65 if (result == _SUCCESS) {
66 pwrpriv->rf_pwrstate = rf_on;
67 }
68 DBG_871X("nolinked power save leave\n");
69
70 DBG_871X("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
71 pwrpriv->bips_processing = false;
72
73 pwrpriv->bkeepfwalive = false;
74 pwrpriv->bpower_saving = false;
75 }
76
77 return result;
78 }
79
80 int ips_leave(struct adapter *padapter)
81 {
82 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
83 int ret;
84
85 if (!is_primary_adapter(padapter))
86 return _SUCCESS;
87
88 mutex_lock(&pwrpriv->lock);
89 ret = _ips_leave(padapter);
90 mutex_unlock(&pwrpriv->lock);
91
92 if (_SUCCESS == ret)
93 hal_btcoex_IpsNotify(padapter, IPS_NONE);
94
95 return ret;
96 }
97
98 static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
99 {
100 struct adapter *buddy = adapter->pbuddy_adapter;
101 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
102 struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
103
104 bool ret = false;
105
106 if (adapter_to_pwrctl(adapter)->bpower_saving) {
107
108 goto exit;
109 }
110
111 if (time_before(jiffies, adapter_to_pwrctl(adapter)->ips_deny_time)) {
112
113 goto exit;
114 }
115
116 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
117 || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
118 || check_fwstate(pmlmepriv, WIFI_AP_STATE)
119 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
120 )
121 goto exit;
122
123
124 if (buddy) {
125 struct mlme_priv *b_pmlmepriv = &(buddy->mlmepriv);
126
127 if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
128 || check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
129 || check_fwstate(b_pmlmepriv, WIFI_AP_STATE)
130 || check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
131 )
132 goto exit;
133 }
134
135 if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
136 pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
137 DBG_871X_LEVEL(_drv_always_, "There are some pkts to transmit\n");
138 DBG_871X_LEVEL(_drv_always_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n",
139 pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);
140 goto exit;
141 }
142
143 ret = true;
144
145 exit:
146 return ret;
147 }
148
149
150
151
152
153
154 void rtw_ps_processor(struct adapter *padapter)
155 {
156 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
157 struct dvobj_priv *psdpriv = padapter->dvobj;
158 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
159 u32 ps_deny = 0;
160
161 mutex_lock(&adapter_to_pwrctl(padapter)->lock);
162 ps_deny = rtw_ps_deny_get(padapter);
163 mutex_unlock(&adapter_to_pwrctl(padapter)->lock);
164 if (ps_deny != 0) {
165 DBG_871X(FUNC_ADPT_FMT ": ps_deny = 0x%08X, skip power save!\n",
166 FUNC_ADPT_ARG(padapter), ps_deny);
167 goto exit;
168 }
169
170 if (pwrpriv->bInSuspend) {
171 pdbgpriv->dbg_ps_insuspend_cnt++;
172 DBG_871X("%s, pwrpriv->bInSuspend == true ignore this process\n", __func__);
173 return;
174 }
175
176 pwrpriv->ps_processing = true;
177
178 if (pwrpriv->ips_mode_req == IPS_NONE)
179 goto exit;
180
181 if (!rtw_pwr_unassociated_idle(padapter))
182 goto exit;
183
184 if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4) == 0)) {
185 DBG_871X("==>%s\n", __func__);
186 pwrpriv->change_rfpwrstate = rf_off;
187 {
188 ips_enter(padapter);
189 }
190 }
191 exit:
192 pwrpriv->ps_processing = false;
193 return;
194 }
195
196 static void pwr_state_check_handler(struct timer_list *t)
197 {
198 struct pwrctrl_priv *pwrctrlpriv =
199 from_timer(pwrctrlpriv, t, pwr_state_check_timer);
200 struct adapter *padapter = pwrctrlpriv->adapter;
201
202 rtw_ps_cmd(padapter);
203 }
204
205 void traffic_check_for_leave_lps(struct adapter *padapter, u8 tx, u32 tx_packets)
206 {
207 static unsigned long start_time;
208 static u32 xmit_cnt;
209 u8 bLeaveLPS = false;
210 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
211
212
213
214 if (tx) {
215 xmit_cnt += tx_packets;
216
217 if (start_time == 0)
218 start_time = jiffies;
219
220 if (jiffies_to_msecs(jiffies - start_time) > 2000) {
221 if (xmit_cnt > 8) {
222 if (adapter_to_pwrctl(padapter)->bLeisurePs
223 && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE)
224 && !(hal_btcoex_IsBtControlLps(padapter))) {
225 DBG_871X("leave lps via Tx = %d\n", xmit_cnt);
226 bLeaveLPS = true;
227 }
228 }
229
230 start_time = jiffies;
231 xmit_cnt = 0;
232 }
233
234 } else {
235 if (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4) {
236 if (adapter_to_pwrctl(padapter)->bLeisurePs
237 && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE)
238 && !(hal_btcoex_IsBtControlLps(padapter))) {
239 DBG_871X("leave lps via Rx = %d\n", pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod);
240 bLeaveLPS = true;
241 }
242 }
243 }
244
245 if (bLeaveLPS)
246
247
248 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, tx?0:1);
249 }
250
251
252
253
254
255
256
257
258
259
260 void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
261 {
262 u8 rpwm;
263 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
264 u8 cpwm_orig;
265
266 pslv = PS_STATE(pslv);
267
268 if (pwrpriv->brpwmtimeout) {
269 DBG_871X("%s: RPWM timeout, force to set RPWM(0x%02X) again!\n", __func__, pslv);
270 } else {
271 if ((pwrpriv->rpwm == pslv)
272 || ((pwrpriv->rpwm >= PS_STATE_S2) && (pslv >= PS_STATE_S2))) {
273 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
274 ("%s: Already set rpwm[0x%02X], new = 0x%02X!\n", __func__, pwrpriv->rpwm, pslv));
275 return;
276 }
277 }
278
279 if ((padapter->bSurpriseRemoved) || !(padapter->hw_init_completed)) {
280 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
281 ("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n",
282 __func__, padapter->bSurpriseRemoved, padapter->hw_init_completed));
283
284 pwrpriv->cpwm = PS_STATE_S4;
285
286 return;
287 }
288
289 if (padapter->bDriverStopped) {
290 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
291 ("%s: change power state(0x%02X) when DriverStopped\n", __func__, pslv));
292
293 if (pslv < PS_STATE_S2) {
294 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
295 ("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __func__, pslv));
296 return;
297 }
298 }
299
300 rpwm = pslv | pwrpriv->tog;
301
302 if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2))
303 rpwm |= PS_ACK;
304 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
305 ("rtw_set_rpwm: rpwm = 0x%02x cpwm = 0x%02x\n", rpwm, pwrpriv->cpwm));
306
307 pwrpriv->rpwm = pslv;
308
309 cpwm_orig = 0;
310 if (rpwm & PS_ACK)
311 rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
312
313 if (rpwm & PS_ACK)
314 _set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS);
315 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
316
317 pwrpriv->tog += 0x80;
318
319
320 if (rpwm & PS_ACK) {
321 unsigned long start_time;
322 u8 cpwm_now;
323 u8 poll_cnt = 0;
324
325 start_time = jiffies;
326
327
328 do {
329 mdelay(1);
330 poll_cnt++;
331 rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
332 if ((cpwm_orig ^ cpwm_now) & 0x80) {
333 pwrpriv->cpwm = PS_STATE_S4;
334 pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE;
335 break;
336 }
337
338 if (jiffies_to_msecs(jiffies - start_time) > LPS_RPWM_WAIT_MS) {
339 DBG_871X("%s: polling cpwm timeout! poll_cnt =%d, cpwm_orig =%02x, cpwm_now =%02x\n", __func__, poll_cnt, cpwm_orig, cpwm_now);
340 _set_timer(&pwrpriv->pwr_rpwm_timer, 1);
341 break;
342 }
343 } while (1);
344 } else
345 pwrpriv->cpwm = pslv;
346 }
347
348 static u8 PS_RDY_CHECK(struct adapter *padapter)
349 {
350 unsigned long curr_time, delta_time;
351 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
352 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
353
354 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
355 if (pwrpriv->bInSuspend && pwrpriv->wowlan_mode)
356 return true;
357 else if (pwrpriv->bInSuspend && pwrpriv->wowlan_ap_mode)
358 return true;
359 else if (pwrpriv->bInSuspend)
360 return false;
361 #else
362 if (pwrpriv->bInSuspend)
363 return false;
364 #endif
365
366 curr_time = jiffies;
367
368 delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
369
370 if (delta_time < LPS_DELAY_TIME)
371 return false;
372
373 if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)
374 || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
375 || check_fwstate(pmlmepriv, WIFI_AP_STATE)
376 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
377 || rtw_is_scan_deny(padapter)
378 )
379 return false;
380
381 if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && !(padapter->securitypriv.binstallGrpkey)) {
382 DBG_871X("Group handshake still in progress !!!\n");
383 return false;
384 }
385
386 if (!rtw_cfg80211_pwr_mgmt(padapter))
387 return false;
388
389 return true;
390 }
391
392 void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg)
393 {
394 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
395 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
396 struct debug_priv *pdbgpriv = &padapter->dvobj->drv_dbg;
397 #endif
398
399 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
400 ("%s: PowerMode =%d Smart_PS =%d\n",
401 __func__, ps_mode, smart_ps));
402
403 if (ps_mode > PM_Card_Disable) {
404 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("ps_mode:%d error\n", ps_mode));
405 return;
406 }
407
408 if (pwrpriv->pwr_mode == ps_mode)
409 if (PS_MODE_ACTIVE == ps_mode)
410 return;
411
412
413 mutex_lock(&pwrpriv->lock);
414
415
416 if (ps_mode == PS_MODE_ACTIVE) {
417 if (!(hal_btcoex_IsBtControlLps(padapter))
418 || (hal_btcoex_IsBtControlLps(padapter)
419 && !(hal_btcoex_IsLpsOn(padapter)))) {
420 DBG_871X(FUNC_ADPT_FMT" Leave 802.11 power save - %s\n",
421 FUNC_ADPT_ARG(padapter), msg);
422
423 pwrpriv->pwr_mode = ps_mode;
424 rtw_set_rpwm(padapter, PS_STATE_S4);
425
426 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
427 if (pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode) {
428 unsigned long start_time;
429 u32 delay_ms;
430 u8 val8;
431 delay_ms = 20;
432 start_time = jiffies;
433 do {
434 rtw_hal_get_hwreg(padapter, HW_VAR_SYS_CLKR, &val8);
435 if (!(val8 & BIT(4))) {
436 pwrpriv->cpwm = PS_STATE_S4;
437 break;
438 }
439 if (jiffies_to_msecs(jiffies - start_time) > delay_ms) {
440 DBG_871X("%s: Wait for FW 32K leave more than %u ms!!!\n",
441 __func__, delay_ms);
442 pdbgpriv->dbg_wow_leave_ps_fail_cnt++;
443 break;
444 }
445 msleep(1);
446 } while (1);
447 }
448 #endif
449 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
450 pwrpriv->bFwCurrentInPSMode = false;
451
452 hal_btcoex_LpsNotify(padapter, ps_mode);
453 }
454 } else {
455 if ((PS_RDY_CHECK(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE))
456 || ((hal_btcoex_IsBtControlLps(padapter))
457 && (hal_btcoex_IsLpsOn(padapter)))
458 ) {
459 u8 pslv;
460
461 DBG_871X(FUNC_ADPT_FMT" Enter 802.11 power save - %s\n",
462 FUNC_ADPT_ARG(padapter), msg);
463
464 hal_btcoex_LpsNotify(padapter, ps_mode);
465
466 pwrpriv->bFwCurrentInPSMode = true;
467 pwrpriv->pwr_mode = ps_mode;
468 pwrpriv->smart_ps = smart_ps;
469 pwrpriv->bcn_ant_mode = bcn_ant_mode;
470 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
471
472 pslv = PS_STATE_S2;
473 if (pwrpriv->alives == 0)
474 pslv = PS_STATE_S0;
475
476 if (!(hal_btcoex_IsBtDisabled(padapter))
477 && (hal_btcoex_IsBtControlLps(padapter))) {
478 u8 val8;
479
480 val8 = hal_btcoex_LpsVal(padapter);
481 if (val8 & BIT(4))
482 pslv = PS_STATE_S2;
483 }
484
485 rtw_set_rpwm(padapter, pslv);
486 }
487 }
488
489 mutex_unlock(&pwrpriv->lock);
490 }
491
492
493
494
495
496
497
498 s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
499 {
500 unsigned long start_time;
501 u8 bAwake = false;
502 s32 err = 0;
503
504
505 start_time = jiffies;
506 while (1) {
507 rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
508 if (bAwake)
509 break;
510
511 if (padapter->bSurpriseRemoved) {
512 err = -2;
513 DBG_871X("%s: device surprise removed!!\n", __func__);
514 break;
515 }
516
517 if (jiffies_to_msecs(jiffies - start_time) > delay_ms) {
518 err = -1;
519 DBG_871X("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms);
520 break;
521 }
522 msleep(1);
523 }
524
525 return err;
526 }
527
528
529
530
531
532 void LPS_Enter(struct adapter *padapter, const char *msg)
533 {
534 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
535 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
536 int n_assoc_iface = 0;
537 char buf[32] = {0};
538
539 if (hal_btcoex_IsBtControlLps(padapter))
540 return;
541
542
543 if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE))
544 n_assoc_iface++;
545 if (n_assoc_iface != 1)
546 return;
547
548
549 if (get_iface_type(padapter) != IFACE_PORT0)
550 return;
551
552 if (!PS_RDY_CHECK(dvobj->padapters))
553 return;
554
555 if (pwrpriv->bLeisurePs) {
556
557 if (pwrpriv->LpsIdleCount >= 2) {
558 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
559 sprintf(buf, "WIFI-%s", msg);
560 pwrpriv->bpower_saving = true;
561 rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, padapter->registrypriv.smart_ps, 0, buf);
562 }
563 } else
564 pwrpriv->LpsIdleCount++;
565 }
566
567
568 }
569
570
571
572
573
574 void LPS_Leave(struct adapter *padapter, const char *msg)
575 {
576 #define LPS_LEAVE_TIMEOUT_MS 100
577
578 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
579 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
580 char buf[32] = {0};
581
582
583
584 if (hal_btcoex_IsBtControlLps(padapter))
585 return;
586
587 if (pwrpriv->bLeisurePs) {
588 if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
589 sprintf(buf, "WIFI-%s", msg);
590 rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, buf);
591
592 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
593 LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS);
594 }
595 }
596
597 pwrpriv->bpower_saving = false;
598
599
600 }
601
602 void LeaveAllPowerSaveModeDirect(struct adapter *Adapter)
603 {
604 struct adapter *pri_padapter = GET_PRIMARY_ADAPTER(Adapter);
605 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
606 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter);
607
608 DBG_871X("%s.....\n", __func__);
609
610 if (Adapter->bSurpriseRemoved) {
611 DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved =%d Skip!\n",
612 FUNC_ADPT_ARG(Adapter), Adapter->bSurpriseRemoved);
613 return;
614 }
615
616 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
617
618 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
619 DBG_871X("%s: Driver Already Leave LPS\n", __func__);
620 return;
621 }
622
623 mutex_lock(&pwrpriv->lock);
624
625 rtw_set_rpwm(Adapter, PS_STATE_S4);
626
627 mutex_unlock(&pwrpriv->lock);
628
629 rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, 0);
630 } else {
631 if (pwrpriv->rf_pwrstate == rf_off)
632 if (!ips_leave(pri_padapter))
633 DBG_871X("======> ips_leave fail.............\n");
634 }
635 }
636
637
638
639
640
641 void LeaveAllPowerSaveMode(struct adapter *Adapter)
642 {
643 struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
644 u8 enqueue = 0;
645 int n_assoc_iface = 0;
646
647 if (!Adapter->bup) {
648 DBG_871X(FUNC_ADPT_FMT ": bup =%d Skip!\n",
649 FUNC_ADPT_ARG(Adapter), Adapter->bup);
650 return;
651 }
652
653 if (Adapter->bSurpriseRemoved) {
654 DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved =%d Skip!\n",
655 FUNC_ADPT_ARG(Adapter), Adapter->bSurpriseRemoved);
656 return;
657 }
658
659 if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE))
660 n_assoc_iface++;
661
662 if (n_assoc_iface) {
663 enqueue = 1;
664
665 rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
666
667 LPS_Leave_check(Adapter);
668 } else {
669 if (adapter_to_pwrctl(Adapter)->rf_pwrstate == rf_off) {
670 if (!ips_leave(Adapter))
671 DBG_871X("======> ips_leave fail.............\n");
672 }
673 }
674 }
675
676 void LPS_Leave_check(
677 struct adapter *padapter)
678 {
679 struct pwrctrl_priv *pwrpriv;
680 unsigned long start_time;
681 u8 bReady;
682
683 pwrpriv = adapter_to_pwrctl(padapter);
684
685 bReady = false;
686 start_time = jiffies;
687
688 cond_resched();
689
690 while (1) {
691 mutex_lock(&pwrpriv->lock);
692
693 if (padapter->bSurpriseRemoved
694 || !(padapter->hw_init_completed)
695 || (pwrpriv->pwr_mode == PS_MODE_ACTIVE))
696 bReady = true;
697
698 mutex_unlock(&pwrpriv->lock);
699
700 if (bReady)
701 break;
702
703 if (jiffies_to_msecs(jiffies - start_time) > 100) {
704 DBG_871X("Wait for cpwm event than 100 ms!!!\n");
705 break;
706 }
707 msleep(1);
708 }
709 }
710
711
712
713
714
715
716
717
718 void cpwm_int_hdl(
719 struct adapter *padapter,
720 struct reportpwrstate_parm *preportpwrstate)
721 {
722 struct pwrctrl_priv *pwrpriv;
723
724 pwrpriv = adapter_to_pwrctl(padapter);
725
726 mutex_lock(&pwrpriv->lock);
727
728 if (pwrpriv->rpwm < PS_STATE_S2) {
729 DBG_871X("%s: Redundant CPWM Int. RPWM = 0x%02X CPWM = 0x%02x\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
730 goto exit;
731 }
732
733 pwrpriv->cpwm = PS_STATE(preportpwrstate->state);
734 pwrpriv->cpwm_tog = preportpwrstate->state & PS_TOGGLE;
735
736 if (pwrpriv->cpwm >= PS_STATE_S2) {
737 if (pwrpriv->alives & CMD_ALIVE)
738 complete(&padapter->cmdpriv.cmd_queue_comp);
739
740 if (pwrpriv->alives & XMIT_ALIVE)
741 complete(&padapter->xmitpriv.xmit_comp);
742 }
743
744 exit:
745 mutex_unlock(&pwrpriv->lock);
746
747 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
748 ("cpwm_int_hdl: cpwm = 0x%02x\n", pwrpriv->cpwm));
749 }
750
751 static void cpwm_event_callback(struct work_struct *work)
752 {
753 struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event);
754 struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
755 struct adapter *adapter = dvobj->if1;
756 struct reportpwrstate_parm report;
757
758
759
760 report.state = PS_STATE_S2;
761 cpwm_int_hdl(adapter, &report);
762 }
763
764 static void rpwmtimeout_workitem_callback(struct work_struct *work)
765 {
766 struct adapter *padapter;
767 struct dvobj_priv *dvobj;
768 struct pwrctrl_priv *pwrpriv;
769
770
771 pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi);
772 dvobj = pwrctl_to_dvobj(pwrpriv);
773 padapter = dvobj->if1;
774
775
776 mutex_lock(&pwrpriv->lock);
777 if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
778 DBG_871X("%s: rpwm = 0x%02X cpwm = 0x%02X CPWM done!\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
779 goto exit;
780 }
781 mutex_unlock(&pwrpriv->lock);
782
783 if (rtw_read8(padapter, 0x100) != 0xEA) {
784 struct reportpwrstate_parm report;
785
786 report.state = PS_STATE_S2;
787 DBG_871X("\n%s: FW already leave 32K!\n\n", __func__);
788 cpwm_int_hdl(padapter, &report);
789
790 return;
791 }
792
793 mutex_lock(&pwrpriv->lock);
794
795 if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
796 DBG_871X("%s: cpwm =%d, nothing to do!\n", __func__, pwrpriv->cpwm);
797 goto exit;
798 }
799 pwrpriv->brpwmtimeout = true;
800 rtw_set_rpwm(padapter, pwrpriv->rpwm);
801 pwrpriv->brpwmtimeout = false;
802
803 exit:
804 mutex_unlock(&pwrpriv->lock);
805 }
806
807
808
809
810 static void pwr_rpwm_timeout_handler(struct timer_list *t)
811 {
812 struct pwrctrl_priv *pwrpriv = from_timer(pwrpriv, t, pwr_rpwm_timer);
813
814 DBG_871X("+%s: rpwm = 0x%02X cpwm = 0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
815
816 if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
817 DBG_871X("+%s: cpwm =%d, nothing to do!\n", __func__, pwrpriv->cpwm);
818 return;
819 }
820
821 _set_workitem(&pwrpriv->rpwmtimeoutwi);
822 }
823
824 static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
825 {
826 pwrctrl->alives |= tag;
827 }
828
829 static inline void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
830 {
831 pwrctrl->alives &= ~tag;
832 }
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850 s32 rtw_register_task_alive(struct adapter *padapter, u32 task)
851 {
852 s32 res;
853 struct pwrctrl_priv *pwrctrl;
854 u8 pslv;
855
856 res = _SUCCESS;
857 pwrctrl = adapter_to_pwrctl(padapter);
858 pslv = PS_STATE_S2;
859
860 mutex_lock(&pwrctrl->lock);
861
862 register_task_alive(pwrctrl, task);
863
864 if (pwrctrl->bFwCurrentInPSMode) {
865 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
866 ("%s: task = 0x%x cpwm = 0x%02x alives = 0x%08x\n",
867 __func__, task, pwrctrl->cpwm, pwrctrl->alives));
868
869 if (pwrctrl->cpwm < pslv) {
870 if (pwrctrl->cpwm < PS_STATE_S2)
871 res = _FAIL;
872 if (pwrctrl->rpwm < pslv)
873 rtw_set_rpwm(padapter, pslv);
874 }
875 }
876
877 mutex_unlock(&pwrctrl->lock);
878
879 if (_FAIL == res)
880 if (pwrctrl->cpwm >= PS_STATE_S2)
881 res = _SUCCESS;
882
883 return res;
884 }
885
886
887
888
889
890
891
892
893
894
895
896 void rtw_unregister_task_alive(struct adapter *padapter, u32 task)
897 {
898 struct pwrctrl_priv *pwrctrl;
899 u8 pslv;
900
901 pwrctrl = adapter_to_pwrctl(padapter);
902 pslv = PS_STATE_S0;
903
904 if (!(hal_btcoex_IsBtDisabled(padapter))
905 && hal_btcoex_IsBtControlLps(padapter)) {
906 u8 val8;
907
908 val8 = hal_btcoex_LpsVal(padapter);
909 if (val8 & BIT(4))
910 pslv = PS_STATE_S2;
911 }
912
913 mutex_lock(&pwrctrl->lock);
914
915 unregister_task_alive(pwrctrl, task);
916
917 if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
918 && pwrctrl->bFwCurrentInPSMode) {
919 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
920 ("%s: cpwm = 0x%02x alives = 0x%08x\n",
921 __func__, pwrctrl->cpwm, pwrctrl->alives));
922
923 if (pwrctrl->cpwm > pslv)
924 if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
925 rtw_set_rpwm(padapter, pslv);
926
927 }
928
929 mutex_unlock(&pwrctrl->lock);
930 }
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945 s32 rtw_register_tx_alive(struct adapter *padapter)
946 {
947 s32 res;
948 struct pwrctrl_priv *pwrctrl;
949 u8 pslv;
950
951 res = _SUCCESS;
952 pwrctrl = adapter_to_pwrctl(padapter);
953 pslv = PS_STATE_S2;
954
955 mutex_lock(&pwrctrl->lock);
956
957 register_task_alive(pwrctrl, XMIT_ALIVE);
958
959 if (pwrctrl->bFwCurrentInPSMode) {
960 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
961 ("rtw_register_tx_alive: cpwm = 0x%02x alives = 0x%08x\n",
962 pwrctrl->cpwm, pwrctrl->alives));
963
964 if (pwrctrl->cpwm < pslv) {
965 if (pwrctrl->cpwm < PS_STATE_S2)
966 res = _FAIL;
967 if (pwrctrl->rpwm < pslv)
968 rtw_set_rpwm(padapter, pslv);
969 }
970 }
971
972 mutex_unlock(&pwrctrl->lock);
973
974 if (_FAIL == res)
975 if (pwrctrl->cpwm >= PS_STATE_S2)
976 res = _SUCCESS;
977
978 return res;
979 }
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994 s32 rtw_register_cmd_alive(struct adapter *padapter)
995 {
996 s32 res;
997 struct pwrctrl_priv *pwrctrl;
998 u8 pslv;
999
1000 res = _SUCCESS;
1001 pwrctrl = adapter_to_pwrctl(padapter);
1002 pslv = PS_STATE_S2;
1003
1004 mutex_lock(&pwrctrl->lock);
1005
1006 register_task_alive(pwrctrl, CMD_ALIVE);
1007
1008 if (pwrctrl->bFwCurrentInPSMode) {
1009 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_info_,
1010 ("rtw_register_cmd_alive: cpwm = 0x%02x alives = 0x%08x\n",
1011 pwrctrl->cpwm, pwrctrl->alives));
1012
1013 if (pwrctrl->cpwm < pslv) {
1014 if (pwrctrl->cpwm < PS_STATE_S2)
1015 res = _FAIL;
1016 if (pwrctrl->rpwm < pslv)
1017 rtw_set_rpwm(padapter, pslv);
1018 }
1019 }
1020
1021 mutex_unlock(&pwrctrl->lock);
1022
1023 if (_FAIL == res)
1024 if (pwrctrl->cpwm >= PS_STATE_S2)
1025 res = _SUCCESS;
1026
1027 return res;
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037 void rtw_unregister_tx_alive(struct adapter *padapter)
1038 {
1039 struct pwrctrl_priv *pwrctrl;
1040 u8 pslv;
1041
1042 pwrctrl = adapter_to_pwrctl(padapter);
1043 pslv = PS_STATE_S0;
1044
1045 if (!(hal_btcoex_IsBtDisabled(padapter))
1046 && hal_btcoex_IsBtControlLps(padapter)) {
1047 u8 val8;
1048
1049 val8 = hal_btcoex_LpsVal(padapter);
1050 if (val8 & BIT(4))
1051 pslv = PS_STATE_S2;
1052 }
1053
1054 mutex_lock(&pwrctrl->lock);
1055
1056 unregister_task_alive(pwrctrl, XMIT_ALIVE);
1057
1058 if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
1059 && pwrctrl->bFwCurrentInPSMode) {
1060 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
1061 ("%s: cpwm = 0x%02x alives = 0x%08x\n",
1062 __func__, pwrctrl->cpwm, pwrctrl->alives));
1063
1064 if (pwrctrl->cpwm > pslv)
1065 if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
1066 rtw_set_rpwm(padapter, pslv);
1067 }
1068
1069 mutex_unlock(&pwrctrl->lock);
1070 }
1071
1072
1073
1074
1075
1076
1077
1078
1079 void rtw_unregister_cmd_alive(struct adapter *padapter)
1080 {
1081 struct pwrctrl_priv *pwrctrl;
1082 u8 pslv;
1083
1084 pwrctrl = adapter_to_pwrctl(padapter);
1085 pslv = PS_STATE_S0;
1086
1087 if (!(hal_btcoex_IsBtDisabled(padapter))
1088 && hal_btcoex_IsBtControlLps(padapter)) {
1089 u8 val8;
1090
1091 val8 = hal_btcoex_LpsVal(padapter);
1092 if (val8 & BIT(4))
1093 pslv = PS_STATE_S2;
1094 }
1095
1096 mutex_lock(&pwrctrl->lock);
1097
1098 unregister_task_alive(pwrctrl, CMD_ALIVE);
1099
1100 if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
1101 && pwrctrl->bFwCurrentInPSMode) {
1102 RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_info_,
1103 ("%s: cpwm = 0x%02x alives = 0x%08x\n",
1104 __func__, pwrctrl->cpwm, pwrctrl->alives));
1105
1106 if (pwrctrl->cpwm > pslv) {
1107 if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
1108 rtw_set_rpwm(padapter, pslv);
1109 }
1110 }
1111
1112 mutex_unlock(&pwrctrl->lock);
1113 }
1114
1115 void rtw_init_pwrctrl_priv(struct adapter *padapter)
1116 {
1117 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1118
1119 mutex_init(&pwrctrlpriv->lock);
1120 pwrctrlpriv->rf_pwrstate = rf_on;
1121 pwrctrlpriv->ips_enter_cnts = 0;
1122 pwrctrlpriv->ips_leave_cnts = 0;
1123 pwrctrlpriv->bips_processing = false;
1124
1125 pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
1126 pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
1127
1128 pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
1129 pwrctrlpriv->pwr_state_check_cnts = 0;
1130 pwrctrlpriv->bInternalAutoSuspend = false;
1131 pwrctrlpriv->bInSuspend = false;
1132 pwrctrlpriv->bkeepfwalive = false;
1133
1134 pwrctrlpriv->LpsIdleCount = 0;
1135 pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;
1136 pwrctrlpriv->bLeisurePs = pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE;
1137
1138 pwrctrlpriv->bFwCurrentInPSMode = false;
1139
1140 pwrctrlpriv->rpwm = 0;
1141 pwrctrlpriv->cpwm = PS_STATE_S4;
1142
1143 pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
1144 pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
1145 pwrctrlpriv->bcn_ant_mode = 0;
1146 pwrctrlpriv->dtim = 0;
1147
1148 pwrctrlpriv->tog = 0x80;
1149
1150 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&pwrctrlpriv->rpwm));
1151
1152 _init_workitem(&pwrctrlpriv->cpwm_event, cpwm_event_callback, NULL);
1153
1154 pwrctrlpriv->brpwmtimeout = false;
1155 pwrctrlpriv->adapter = padapter;
1156 _init_workitem(&pwrctrlpriv->rpwmtimeoutwi, rpwmtimeout_workitem_callback, NULL);
1157 timer_setup(&pwrctrlpriv->pwr_rpwm_timer, pwr_rpwm_timeout_handler, 0);
1158 timer_setup(&pwrctrlpriv->pwr_state_check_timer,
1159 pwr_state_check_handler, 0);
1160
1161 pwrctrlpriv->wowlan_mode = false;
1162 pwrctrlpriv->wowlan_ap_mode = false;
1163
1164 #ifdef CONFIG_PNO_SUPPORT
1165 pwrctrlpriv->pno_inited = false;
1166 pwrctrlpriv->pnlo_info = NULL;
1167 pwrctrlpriv->pscan_info = NULL;
1168 pwrctrlpriv->pno_ssid_list = NULL;
1169 pwrctrlpriv->pno_in_resume = true;
1170 #endif
1171 }
1172
1173
1174 void rtw_free_pwrctrl_priv(struct adapter *adapter)
1175 {
1176 #ifdef CONFIG_PNO_SUPPORT
1177 if (pwrctrlpriv->pnlo_info != NULL)
1178 printk("****** pnlo_info memory leak********\n");
1179
1180 if (pwrctrlpriv->pscan_info != NULL)
1181 printk("****** pscan_info memory leak********\n");
1182
1183 if (pwrctrlpriv->pno_ssid_list != NULL)
1184 printk("****** pno_ssid_list memory leak********\n");
1185 #endif
1186 }
1187
1188 inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms)
1189 {
1190 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1191 pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms);
1192 }
1193
1194
1195
1196
1197
1198
1199
1200
1201 int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller)
1202 {
1203 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1204 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
1205 struct mlme_priv *pmlmepriv;
1206 int ret = _SUCCESS;
1207 unsigned long start = jiffies;
1208 unsigned long deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
1209
1210
1211 LeaveAllPowerSaveMode(padapter);
1212
1213
1214 padapter = GET_PRIMARY_ADAPTER(padapter);
1215 pmlmepriv = &padapter->mlmepriv;
1216
1217 if (time_before(pwrpriv->ips_deny_time, deny_time))
1218 pwrpriv->ips_deny_time = deny_time;
1219
1220
1221 if (pwrpriv->ps_processing) {
1222 DBG_871X("%s wait ps_processing...\n", __func__);
1223 while (pwrpriv->ps_processing && jiffies_to_msecs(jiffies - start) <= 3000)
1224 mdelay(10);
1225 if (pwrpriv->ps_processing)
1226 DBG_871X("%s wait ps_processing timeout\n", __func__);
1227 else
1228 DBG_871X("%s wait ps_processing done\n", __func__);
1229 }
1230
1231 if (!(pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) {
1232 DBG_871X("%s wait bInSuspend...\n", __func__);
1233 while (pwrpriv->bInSuspend
1234 && jiffies_to_msecs(jiffies - start) <= 3000
1235 ) {
1236 mdelay(10);
1237 }
1238 if (pwrpriv->bInSuspend)
1239 DBG_871X("%s wait bInSuspend timeout\n", __func__);
1240 else
1241 DBG_871X("%s wait bInSuspend done\n", __func__);
1242 }
1243
1244
1245 if (!(pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) {
1246 ret = _FAIL;
1247 goto exit;
1248 }
1249
1250
1251 if (pwrpriv->bInternalAutoSuspend && padapter->net_closed) {
1252 ret = _FAIL;
1253 goto exit;
1254 }
1255
1256
1257 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1258 ret = _SUCCESS;
1259 goto exit;
1260 }
1261
1262 if (rf_off == pwrpriv->rf_pwrstate) {
1263 {
1264 DBG_8192C("%s call ips_leave....\n", __func__);
1265 if (_FAIL == ips_leave(padapter)) {
1266 DBG_8192C("======> ips_leave fail.............\n");
1267 ret = _FAIL;
1268 goto exit;
1269 }
1270 }
1271 }
1272
1273
1274 if (padapter->bDriverStopped
1275 || !padapter->bup
1276 || !padapter->hw_init_completed
1277 ) {
1278 DBG_8192C("%s: bDriverStopped =%d, bup =%d, hw_init_completed =%u\n"
1279 , caller
1280 , padapter->bDriverStopped
1281 , padapter->bup
1282 , padapter->hw_init_completed);
1283 ret = false;
1284 goto exit;
1285 }
1286
1287 exit:
1288 deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
1289 if (time_before(pwrpriv->ips_deny_time, deny_time))
1290 pwrpriv->ips_deny_time = deny_time;
1291 return ret;
1292
1293 }
1294
1295 int rtw_pm_set_lps(struct adapter *padapter, u8 mode)
1296 {
1297 int ret = 0;
1298 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1299
1300 if (mode < PS_MODE_NUM) {
1301 if (pwrctrlpriv->power_mgnt != mode) {
1302 if (PS_MODE_ACTIVE == mode)
1303 LeaveAllPowerSaveMode(padapter);
1304 else
1305 pwrctrlpriv->LpsIdleCount = 2;
1306
1307 pwrctrlpriv->power_mgnt = mode;
1308 pwrctrlpriv->bLeisurePs =
1309 pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE;
1310 }
1311 } else
1312 ret = -EINVAL;
1313
1314 return ret;
1315 }
1316
1317 int rtw_pm_set_ips(struct adapter *padapter, u8 mode)
1318 {
1319 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1320
1321 if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
1322 rtw_ips_mode_req(pwrctrlpriv, mode);
1323 DBG_871X("%s %s\n", __func__, mode == IPS_NORMAL?"IPS_NORMAL":"IPS_LEVEL_2");
1324 return 0;
1325 } else if (mode == IPS_NONE) {
1326 rtw_ips_mode_req(pwrctrlpriv, mode);
1327 DBG_871X("%s %s\n", __func__, "IPS_NONE");
1328 if ((padapter->bSurpriseRemoved == 0) && (_FAIL == rtw_pwr_wakeup(padapter)))
1329 return -EFAULT;
1330 } else
1331 return -EINVAL;
1332
1333 return 0;
1334 }
1335
1336
1337
1338
1339
1340 void rtw_ps_deny(struct adapter *padapter, enum PS_DENY_REASON reason)
1341 {
1342 struct pwrctrl_priv *pwrpriv;
1343
1344
1345
1346
1347 pwrpriv = adapter_to_pwrctl(padapter);
1348
1349 mutex_lock(&pwrpriv->lock);
1350 if (pwrpriv->ps_deny & BIT(reason)) {
1351 DBG_871X(FUNC_ADPT_FMT ": [WARNING] Reason %d had been set before!!\n",
1352 FUNC_ADPT_ARG(padapter), reason);
1353 }
1354 pwrpriv->ps_deny |= BIT(reason);
1355 mutex_unlock(&pwrpriv->lock);
1356
1357
1358
1359 }
1360
1361
1362
1363
1364
1365 void rtw_ps_deny_cancel(struct adapter *padapter, enum PS_DENY_REASON reason)
1366 {
1367 struct pwrctrl_priv *pwrpriv;
1368
1369
1370
1371
1372
1373 pwrpriv = adapter_to_pwrctl(padapter);
1374
1375 mutex_lock(&pwrpriv->lock);
1376 if ((pwrpriv->ps_deny & BIT(reason)) == 0) {
1377 DBG_871X(FUNC_ADPT_FMT ": [ERROR] Reason %d had been canceled before!!\n",
1378 FUNC_ADPT_ARG(padapter), reason);
1379 }
1380 pwrpriv->ps_deny &= ~BIT(reason);
1381 mutex_unlock(&pwrpriv->lock);
1382
1383
1384
1385 }
1386
1387
1388
1389
1390
1391
1392 u32 rtw_ps_deny_get(struct adapter *padapter)
1393 {
1394 u32 deny;
1395
1396
1397 deny = adapter_to_pwrctl(padapter)->ps_deny;
1398
1399 return deny;
1400 }