1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7 #include <drv_types.h>
8 #include <hal_data.h>
9 #include <linux/jiffies.h>
10
_ips_enter(struct adapter * padapter)11 void _ips_enter(struct adapter *padapter)
12 {
13 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
14
15 pwrpriv->bips_processing = true;
16
17 /* syn ips_mode with request */
18 pwrpriv->ips_mode = pwrpriv->ips_mode_req;
19
20 pwrpriv->ips_enter_cnts++;
21
22 if (rf_off == pwrpriv->change_rfpwrstate) {
23 pwrpriv->bpower_saving = true;
24
25 if (pwrpriv->ips_mode == IPS_LEVEL_2)
26 pwrpriv->bkeepfwalive = true;
27
28 rtw_ips_pwr_down(padapter);
29 pwrpriv->rf_pwrstate = rf_off;
30 }
31 pwrpriv->bips_processing = false;
32
33 }
34
ips_enter(struct adapter * padapter)35 void ips_enter(struct adapter *padapter)
36 {
37 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
38
39
40 hal_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req);
41
42 mutex_lock(&pwrpriv->lock);
43 _ips_enter(padapter);
44 mutex_unlock(&pwrpriv->lock);
45 }
46
_ips_leave(struct adapter * padapter)47 int _ips_leave(struct adapter *padapter)
48 {
49 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
50 int result = _SUCCESS;
51
52 if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
53 pwrpriv->bips_processing = true;
54 pwrpriv->change_rfpwrstate = rf_on;
55 pwrpriv->ips_leave_cnts++;
56
57 result = rtw_ips_pwr_up(padapter);
58 if (result == _SUCCESS)
59 pwrpriv->rf_pwrstate = rf_on;
60 pwrpriv->bips_processing = false;
61
62 pwrpriv->bkeepfwalive = false;
63 pwrpriv->bpower_saving = false;
64 }
65
66 return result;
67 }
68
ips_leave(struct adapter * padapter)69 int ips_leave(struct adapter *padapter)
70 {
71 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
72 int ret;
73
74 mutex_lock(&pwrpriv->lock);
75 ret = _ips_leave(padapter);
76 mutex_unlock(&pwrpriv->lock);
77
78 if (ret == _SUCCESS)
79 hal_btcoex_IpsNotify(padapter, IPS_NONE);
80
81 return ret;
82 }
83
rtw_pwr_unassociated_idle(struct adapter * adapter)84 static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
85 {
86 struct adapter *buddy = adapter->pbuddy_adapter;
87 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
88 struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
89
90 bool ret = false;
91
92 if (adapter_to_pwrctl(adapter)->bpower_saving)
93 goto exit;
94
95 if (time_before(jiffies, adapter_to_pwrctl(adapter)->ips_deny_time))
96 goto exit;
97
98 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
99 || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
100 || check_fwstate(pmlmepriv, WIFI_AP_STATE)
101 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
102 )
103 goto exit;
104
105 /* consider buddy, if exist */
106 if (buddy) {
107 struct mlme_priv *b_pmlmepriv = &(buddy->mlmepriv);
108
109 if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
110 || check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
111 || check_fwstate(b_pmlmepriv, WIFI_AP_STATE)
112 || check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
113 )
114 goto exit;
115 }
116
117 if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
118 pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
119 netdev_dbg(adapter->pnetdev,
120 "There are some pkts to transmit\n");
121 netdev_dbg(adapter->pnetdev,
122 "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n",
123 pxmit_priv->free_xmitbuf_cnt,
124 pxmit_priv->free_xmit_extbuf_cnt);
125 goto exit;
126 }
127
128 ret = true;
129
130 exit:
131 return ret;
132 }
133
134
135 /*
136 * ATTENTION:
137 *rtw_ps_processor() doesn't handle LPS.
138 */
rtw_ps_processor(struct adapter * padapter)139 void rtw_ps_processor(struct adapter *padapter)
140 {
141 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
142 u32 ps_deny = 0;
143
144 mutex_lock(&adapter_to_pwrctl(padapter)->lock);
145 ps_deny = rtw_ps_deny_get(padapter);
146 mutex_unlock(&adapter_to_pwrctl(padapter)->lock);
147 if (ps_deny != 0)
148 goto exit;
149
150 if (pwrpriv->bInSuspend) /* system suspend or autosuspend */
151 return;
152
153 pwrpriv->ps_processing = true;
154
155 if (pwrpriv->ips_mode_req == IPS_NONE)
156 goto exit;
157
158 if (!rtw_pwr_unassociated_idle(padapter))
159 goto exit;
160
161 if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4) == 0)) {
162 pwrpriv->change_rfpwrstate = rf_off;
163 {
164 ips_enter(padapter);
165 }
166 }
167 exit:
168 pwrpriv->ps_processing = false;
169 }
170
pwr_state_check_handler(struct timer_list * t)171 static void pwr_state_check_handler(struct timer_list *t)
172 {
173 struct pwrctrl_priv *pwrctrlpriv =
174 timer_container_of(pwrctrlpriv, t, pwr_state_check_timer);
175 struct adapter *padapter = pwrctrlpriv->adapter;
176
177 rtw_ps_cmd(padapter);
178 }
179
traffic_check_for_leave_lps(struct adapter * padapter,u8 tx,u32 tx_packets)180 void traffic_check_for_leave_lps(struct adapter *padapter, u8 tx, u32 tx_packets)
181 {
182 static unsigned long start_time;
183 static u32 xmit_cnt;
184 u8 bLeaveLPS = false;
185 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
186
187
188
189 if (tx) { /* from tx */
190 xmit_cnt += tx_packets;
191
192 if (start_time == 0)
193 start_time = jiffies;
194
195 if (jiffies_to_msecs(jiffies - start_time) > 2000) { /* 2 sec == watch dog timer */
196 if (xmit_cnt > 8) {
197 if (adapter_to_pwrctl(padapter)->bLeisurePs
198 && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE)
199 && !(hal_btcoex_IsBtControlLps(padapter))) {
200 bLeaveLPS = true;
201 }
202 }
203
204 start_time = jiffies;
205 xmit_cnt = 0;
206 }
207
208 } else { /* from rx path */
209 if (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4/*2*/) {
210 if (adapter_to_pwrctl(padapter)->bLeisurePs
211 && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE)
212 && !(hal_btcoex_IsBtControlLps(padapter)))
213 bLeaveLPS = true;
214 }
215 }
216
217 if (bLeaveLPS)
218 /* rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1); */
219 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, tx?0:1);
220 }
221
222 /*
223 * Description:
224 *This function MUST be called under power lock protect
225 *
226 * Parameters
227 *padapter
228 *pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
229 *
230 */
rtw_set_rpwm(struct adapter * padapter,u8 pslv)231 void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
232 {
233 u8 rpwm;
234 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
235 u8 cpwm_orig;
236
237 pslv = PS_STATE(pslv);
238
239 if (!pwrpriv->brpwmtimeout) {
240 if (pwrpriv->rpwm == pslv ||
241 (pwrpriv->rpwm >= PS_STATE_S2 && pslv >= PS_STATE_S2))
242 return;
243
244 }
245
246 if ((padapter->bSurpriseRemoved) || !(padapter->hw_init_completed)) {
247 pwrpriv->cpwm = PS_STATE_S4;
248
249 return;
250 }
251
252 if (padapter->bDriverStopped) {
253 if (pslv < PS_STATE_S2)
254 return;
255 }
256
257 rpwm = pslv | pwrpriv->tog;
258 /* only when from PS_STATE S0/S1 to S2 and higher needs ACK */
259 if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2))
260 rpwm |= PS_ACK;
261
262 pwrpriv->rpwm = pslv;
263
264 cpwm_orig = 0;
265 if (rpwm & PS_ACK)
266 rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
267
268 if (rpwm & PS_ACK)
269 _set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS);
270 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
271
272 pwrpriv->tog += 0x80;
273
274 /* No LPS 32K, No Ack */
275 if (rpwm & PS_ACK) {
276 unsigned long start_time;
277 u8 cpwm_now;
278
279 start_time = jiffies;
280
281 /* polling cpwm */
282 do {
283 mdelay(1);
284 rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
285 if ((cpwm_orig ^ cpwm_now) & 0x80) {
286 pwrpriv->cpwm = PS_STATE_S4;
287 pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE;
288 break;
289 }
290
291 if (jiffies_to_msecs(jiffies - start_time) > LPS_RPWM_WAIT_MS) {
292 _set_timer(&pwrpriv->pwr_rpwm_timer, 1);
293 break;
294 }
295 } while (1);
296 } else
297 pwrpriv->cpwm = pslv;
298 }
299
PS_RDY_CHECK(struct adapter * padapter)300 static u8 PS_RDY_CHECK(struct adapter *padapter)
301 {
302 unsigned long curr_time, delta_time;
303 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
304 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
305
306 if (pwrpriv->bInSuspend)
307 return false;
308
309 curr_time = jiffies;
310
311 delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
312
313 if (delta_time < LPS_DELAY_TIME)
314 return false;
315
316 if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)
317 || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
318 || check_fwstate(pmlmepriv, WIFI_AP_STATE)
319 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
320 || rtw_is_scan_deny(padapter)
321 )
322 return false;
323
324 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X &&
325 !padapter->securitypriv.binstallGrpkey)
326 return false;
327
328 if (!rtw_cfg80211_pwr_mgmt(padapter))
329 return false;
330
331 return true;
332 }
333
rtw_set_ps_mode(struct adapter * padapter,u8 ps_mode,u8 smart_ps,u8 bcn_ant_mode,const char * msg)334 void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg)
335 {
336 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
337
338 if (ps_mode > PM_Card_Disable)
339 return;
340
341 if (pwrpriv->pwr_mode == ps_mode)
342 if (ps_mode == PS_MODE_ACTIVE)
343 return;
344
345
346 mutex_lock(&pwrpriv->lock);
347
348 /* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
349 if (ps_mode == PS_MODE_ACTIVE) {
350 if (!(hal_btcoex_IsBtControlLps(padapter))
351 || (hal_btcoex_IsBtControlLps(padapter)
352 && !(hal_btcoex_IsLpsOn(padapter)))) {
353 pwrpriv->pwr_mode = ps_mode;
354 rtw_set_rpwm(padapter, PS_STATE_S4);
355
356 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
357 pwrpriv->fw_current_in_ps_mode = false;
358
359 hal_btcoex_LpsNotify(padapter, ps_mode);
360 }
361 } else {
362 if ((PS_RDY_CHECK(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) ||
363 ((hal_btcoex_IsBtControlLps(padapter)) && (hal_btcoex_IsLpsOn(padapter)))
364 ) {
365 u8 pslv;
366
367 hal_btcoex_LpsNotify(padapter, ps_mode);
368
369 pwrpriv->fw_current_in_ps_mode = true;
370 pwrpriv->pwr_mode = ps_mode;
371 pwrpriv->smart_ps = smart_ps;
372 pwrpriv->bcn_ant_mode = bcn_ant_mode;
373 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
374
375 pslv = PS_STATE_S2;
376 if (pwrpriv->alives == 0)
377 pslv = PS_STATE_S0;
378
379 if (!(hal_btcoex_IsBtDisabled(padapter)) &&
380 (hal_btcoex_IsBtControlLps(padapter))) {
381 u8 val8;
382
383 val8 = hal_btcoex_LpsVal(padapter);
384 if (val8 & BIT(4))
385 pslv = PS_STATE_S2;
386 }
387
388 rtw_set_rpwm(padapter, pslv);
389 }
390 }
391
392 mutex_unlock(&pwrpriv->lock);
393 }
394
395 /*
396 * Return:
397 *0: Leave OK
398 *-1: Timeout
399 *-2: Other error
400 */
LPS_RF_ON_check(struct adapter * padapter,u32 delay_ms)401 s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
402 {
403 unsigned long start_time;
404 u8 bAwake = false;
405 s32 err = 0;
406
407
408 start_time = jiffies;
409 while (1) {
410 rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
411 if (bAwake)
412 break;
413
414 if (padapter->bSurpriseRemoved) {
415 err = -2;
416 break;
417 }
418
419 if (jiffies_to_msecs(jiffies - start_time) > delay_ms) {
420 err = -1;
421 break;
422 }
423 msleep(1);
424 }
425
426 return err;
427 }
428
429 /* Description: Enter the leisure power save mode. */
LPS_Enter(struct adapter * padapter,const char * msg)430 void LPS_Enter(struct adapter *padapter, const char *msg)
431 {
432 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
433 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
434 int n_assoc_iface = 0;
435 char buf[32] = {0};
436
437 if (hal_btcoex_IsBtControlLps(padapter))
438 return;
439
440 /* Skip lps enter request if number of associated adapters is not 1 */
441 if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE))
442 n_assoc_iface++;
443 if (n_assoc_iface != 1)
444 return;
445
446 if (!PS_RDY_CHECK(dvobj->padapters))
447 return;
448
449 if (pwrpriv->bLeisurePs) {
450 /* Idle for a while if we connect to AP a while ago. */
451 if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */
452 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
453 scnprintf(buf, sizeof(buf), "WIFI-%s", msg);
454 pwrpriv->bpower_saving = true;
455 rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, padapter->registrypriv.smart_ps, 0, buf);
456 }
457 } else
458 pwrpriv->LpsIdleCount++;
459 }
460 }
461
462 /* Description: Leave the leisure power save mode. */
LPS_Leave(struct adapter * padapter,const char * msg)463 void LPS_Leave(struct adapter *padapter, const char *msg)
464 {
465 #define LPS_LEAVE_TIMEOUT_MS 100
466
467 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
468 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
469 char buf[32] = {0};
470
471 if (hal_btcoex_IsBtControlLps(padapter))
472 return;
473
474 if (pwrpriv->bLeisurePs) {
475 if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
476 scnprintf(buf, sizeof(buf), "WIFI-%s", msg);
477 rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, buf);
478
479 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
480 LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS);
481 }
482 }
483
484 pwrpriv->bpower_saving = false;
485 }
486
LeaveAllPowerSaveModeDirect(struct adapter * Adapter)487 void LeaveAllPowerSaveModeDirect(struct adapter *Adapter)
488 {
489 struct adapter *pri_padapter = GET_PRIMARY_ADAPTER(Adapter);
490 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
491 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter);
492
493 if (Adapter->bSurpriseRemoved)
494 return;
495
496 if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */
497
498 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
499 return;
500
501 mutex_lock(&pwrpriv->lock);
502
503 rtw_set_rpwm(Adapter, PS_STATE_S4);
504
505 mutex_unlock(&pwrpriv->lock);
506
507 rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, 0);
508 } else {
509 if (pwrpriv->rf_pwrstate == rf_off)
510 ips_leave(pri_padapter);
511 }
512 }
513
514 /* */
515 /* Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */
516 /* Move code to function by tynli. 2010.03.26. */
517 /* */
LeaveAllPowerSaveMode(struct adapter * Adapter)518 void LeaveAllPowerSaveMode(struct adapter *Adapter)
519 {
520 struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
521 u8 enqueue = 0;
522 int n_assoc_iface = 0;
523
524 if (!Adapter->bup)
525 return;
526
527 if (Adapter->bSurpriseRemoved)
528 return;
529
530 if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE))
531 n_assoc_iface++;
532
533 if (n_assoc_iface) { /* connect */
534 enqueue = 1;
535
536 rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
537
538 LPS_Leave_check(Adapter);
539 } else {
540 if (adapter_to_pwrctl(Adapter)->rf_pwrstate == rf_off)
541 ips_leave(Adapter);
542 }
543 }
544
LPS_Leave_check(struct adapter * padapter)545 void LPS_Leave_check(struct adapter *padapter)
546 {
547 struct pwrctrl_priv *pwrpriv;
548 unsigned long start_time;
549 u8 bReady;
550
551 pwrpriv = adapter_to_pwrctl(padapter);
552
553 bReady = false;
554 start_time = jiffies;
555
556 cond_resched();
557
558 while (1) {
559 mutex_lock(&pwrpriv->lock);
560
561 if (padapter->bSurpriseRemoved ||
562 !(padapter->hw_init_completed) ||
563 (pwrpriv->pwr_mode == PS_MODE_ACTIVE))
564 bReady = true;
565
566 mutex_unlock(&pwrpriv->lock);
567
568 if (bReady)
569 break;
570
571 if (jiffies_to_msecs(jiffies - start_time) > 100)
572 break;
573
574 msleep(1);
575 }
576 }
577
578 /*
579 * Caller:ISR handler...
580 *
581 * This will be called when CPWM interrupt is up.
582 *
583 * using to update cpwn of drv; and drv willl make a decision to up or down pwr level
584 */
cpwm_int_hdl(struct adapter * padapter,struct reportpwrstate_parm * preportpwrstate)585 void cpwm_int_hdl(struct adapter *padapter, struct reportpwrstate_parm *preportpwrstate)
586 {
587 struct pwrctrl_priv *pwrpriv;
588
589 pwrpriv = adapter_to_pwrctl(padapter);
590
591 mutex_lock(&pwrpriv->lock);
592
593 if (pwrpriv->rpwm < PS_STATE_S2)
594 goto exit;
595
596 pwrpriv->cpwm = PS_STATE(preportpwrstate->state);
597 pwrpriv->cpwm_tog = preportpwrstate->state & PS_TOGGLE;
598
599 if (pwrpriv->cpwm >= PS_STATE_S2) {
600 if (pwrpriv->alives & CMD_ALIVE)
601 complete(&padapter->cmdpriv.cmd_queue_comp);
602
603 if (pwrpriv->alives & XMIT_ALIVE)
604 complete(&padapter->xmitpriv.xmit_comp);
605 }
606
607 exit:
608 mutex_unlock(&pwrpriv->lock);
609
610 }
611
cpwm_event_callback(struct work_struct * work)612 static void cpwm_event_callback(struct work_struct *work)
613 {
614 struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event);
615 struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
616 struct adapter *adapter = dvobj->if1;
617 struct reportpwrstate_parm report;
618
619 report.state = PS_STATE_S2;
620 cpwm_int_hdl(adapter, &report);
621 }
622
rpwmtimeout_workitem_callback(struct work_struct * work)623 static void rpwmtimeout_workitem_callback(struct work_struct *work)
624 {
625 struct adapter *padapter;
626 struct dvobj_priv *dvobj;
627 struct pwrctrl_priv *pwrpriv;
628
629
630 pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi);
631 dvobj = pwrctl_to_dvobj(pwrpriv);
632 padapter = dvobj->if1;
633
634 mutex_lock(&pwrpriv->lock);
635 if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2))
636 goto exit;
637
638 mutex_unlock(&pwrpriv->lock);
639
640 if (rtw_read8(padapter, 0x100) != 0xEA) {
641 struct reportpwrstate_parm report;
642
643 report.state = PS_STATE_S2;
644 cpwm_int_hdl(padapter, &report);
645
646 return;
647 }
648
649 mutex_lock(&pwrpriv->lock);
650
651 if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2))
652 goto exit;
653
654 pwrpriv->brpwmtimeout = true;
655 rtw_set_rpwm(padapter, pwrpriv->rpwm);
656 pwrpriv->brpwmtimeout = false;
657
658 exit:
659 mutex_unlock(&pwrpriv->lock);
660 }
661
662 /*
663 * This function is a timer handler, can't do any IO in it.
664 */
pwr_rpwm_timeout_handler(struct timer_list * t)665 static void pwr_rpwm_timeout_handler(struct timer_list *t)
666 {
667 struct pwrctrl_priv *pwrpriv = timer_container_of(pwrpriv, t,
668 pwr_rpwm_timer);
669
670 if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2))
671 return;
672
673 _set_workitem(&pwrpriv->rpwmtimeoutwi);
674 }
675
register_task_alive(struct pwrctrl_priv * pwrctrl,u32 tag)676 static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
677 {
678 pwrctrl->alives |= tag;
679 }
680
unregister_task_alive(struct pwrctrl_priv * pwrctrl,u32 tag)681 static inline void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
682 {
683 pwrctrl->alives &= ~tag;
684 }
685
686
687 /*
688 * Description:
689 *Check if the fw_pwrstate is okay for I/O.
690 *If not (cpwm is less than S2), then the sub-routine
691 *will raise the cpwm to be greater than or equal to S2.
692 *
693 *Calling Context: Passive
694 *
695 *Constraint:
696 * 1. this function will request pwrctrl->lock
697 *
698 * Return Value:
699 *_SUCCESS hardware is ready for I/O
700 *_FAIL can't I/O right now
701 */
rtw_register_task_alive(struct adapter * padapter,u32 task)702 s32 rtw_register_task_alive(struct adapter *padapter, u32 task)
703 {
704 s32 res;
705 struct pwrctrl_priv *pwrctrl;
706 u8 pslv;
707
708 res = _SUCCESS;
709 pwrctrl = adapter_to_pwrctl(padapter);
710 pslv = PS_STATE_S2;
711
712 mutex_lock(&pwrctrl->lock);
713
714 register_task_alive(pwrctrl, task);
715
716 if (pwrctrl->fw_current_in_ps_mode) {
717 if (pwrctrl->cpwm < pslv) {
718 if (pwrctrl->cpwm < PS_STATE_S2)
719 res = _FAIL;
720 if (pwrctrl->rpwm < pslv)
721 rtw_set_rpwm(padapter, pslv);
722 }
723 }
724
725 mutex_unlock(&pwrctrl->lock);
726
727 if (res == _FAIL)
728 if (pwrctrl->cpwm >= PS_STATE_S2)
729 res = _SUCCESS;
730
731 return res;
732 }
733
734 /*
735 * Description:
736 *If task is done, call this func. to power down firmware again.
737 *
738 *Constraint:
739 * 1. this function will request pwrctrl->lock
740 *
741 * Return Value:
742 *none
743 */
rtw_unregister_task_alive(struct adapter * padapter,u32 task)744 void rtw_unregister_task_alive(struct adapter *padapter, u32 task)
745 {
746 struct pwrctrl_priv *pwrctrl;
747 u8 pslv;
748
749 pwrctrl = adapter_to_pwrctl(padapter);
750 pslv = PS_STATE_S0;
751
752 if (!(hal_btcoex_IsBtDisabled(padapter)) && hal_btcoex_IsBtControlLps(padapter)) {
753 u8 val8;
754
755 val8 = hal_btcoex_LpsVal(padapter);
756 if (val8 & BIT(4))
757 pslv = PS_STATE_S2;
758 }
759
760 mutex_lock(&pwrctrl->lock);
761
762 unregister_task_alive(pwrctrl, task);
763
764 if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) && pwrctrl->fw_current_in_ps_mode) {
765 if (pwrctrl->cpwm > pslv)
766 if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
767 rtw_set_rpwm(padapter, pslv);
768
769 }
770
771 mutex_unlock(&pwrctrl->lock);
772 }
773
774 /*
775 * Caller: rtw_xmit_thread
776 *
777 * Check if the fw_pwrstate is okay for xmit.
778 * If not (cpwm is less than S3), then the sub-routine
779 * will raise the cpwm to be greater than or equal to S3.
780 *
781 * Calling Context: Passive
782 *
783 * Return Value:
784 * _SUCCESS rtw_xmit_thread can write fifo/txcmd afterwards.
785 * _FAIL rtw_xmit_thread can not do anything.
786 */
rtw_register_tx_alive(struct adapter * padapter)787 s32 rtw_register_tx_alive(struct adapter *padapter)
788 {
789 s32 res;
790 struct pwrctrl_priv *pwrctrl;
791 u8 pslv;
792
793 res = _SUCCESS;
794 pwrctrl = adapter_to_pwrctl(padapter);
795 pslv = PS_STATE_S2;
796
797 mutex_lock(&pwrctrl->lock);
798
799 register_task_alive(pwrctrl, XMIT_ALIVE);
800
801 if (pwrctrl->fw_current_in_ps_mode) {
802 if (pwrctrl->cpwm < pslv) {
803 if (pwrctrl->cpwm < PS_STATE_S2)
804 res = _FAIL;
805 if (pwrctrl->rpwm < pslv)
806 rtw_set_rpwm(padapter, pslv);
807 }
808 }
809
810 mutex_unlock(&pwrctrl->lock);
811
812 if (res == _FAIL)
813 if (pwrctrl->cpwm >= PS_STATE_S2)
814 res = _SUCCESS;
815
816 return res;
817 }
818
819 /*
820 * Caller: rtw_cmd_thread
821 *
822 * Check if the fw_pwrstate is okay for issuing cmd.
823 * If not (cpwm should be is less than S2), then the sub-routine
824 * will raise the cpwm to be greater than or equal to S2.
825 *
826 * Calling Context: Passive
827 *
828 * Return Value:
829 *_SUCCESS rtw_cmd_thread can issue cmds to firmware afterwards.
830 *_FAIL rtw_cmd_thread can not do anything.
831 */
rtw_register_cmd_alive(struct adapter * padapter)832 s32 rtw_register_cmd_alive(struct adapter *padapter)
833 {
834 s32 res;
835 struct pwrctrl_priv *pwrctrl;
836 u8 pslv;
837
838 res = _SUCCESS;
839 pwrctrl = adapter_to_pwrctl(padapter);
840 pslv = PS_STATE_S2;
841
842 mutex_lock(&pwrctrl->lock);
843
844 register_task_alive(pwrctrl, CMD_ALIVE);
845
846 if (pwrctrl->fw_current_in_ps_mode) {
847 if (pwrctrl->cpwm < pslv) {
848 if (pwrctrl->cpwm < PS_STATE_S2)
849 res = _FAIL;
850 if (pwrctrl->rpwm < pslv)
851 rtw_set_rpwm(padapter, pslv);
852 }
853 }
854
855 mutex_unlock(&pwrctrl->lock);
856
857 if (res == _FAIL)
858 if (pwrctrl->cpwm >= PS_STATE_S2)
859 res = _SUCCESS;
860
861 return res;
862 }
863
864 /*
865 * Caller: ISR
866 *
867 * If ISR's txdone,
868 * No more pkts for TX,
869 * Then driver shall call this fun. to power down firmware again.
870 */
rtw_unregister_tx_alive(struct adapter * padapter)871 void rtw_unregister_tx_alive(struct adapter *padapter)
872 {
873 struct pwrctrl_priv *pwrctrl;
874 u8 pslv;
875
876 pwrctrl = adapter_to_pwrctl(padapter);
877 pslv = PS_STATE_S0;
878
879 if (!(hal_btcoex_IsBtDisabled(padapter)) && hal_btcoex_IsBtControlLps(padapter)) {
880 u8 val8;
881
882 val8 = hal_btcoex_LpsVal(padapter);
883 if (val8 & BIT(4))
884 pslv = PS_STATE_S2;
885 }
886
887 mutex_lock(&pwrctrl->lock);
888
889 unregister_task_alive(pwrctrl, XMIT_ALIVE);
890
891 if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) && pwrctrl->fw_current_in_ps_mode) {
892 if (pwrctrl->cpwm > pslv)
893 if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
894 rtw_set_rpwm(padapter, pslv);
895 }
896
897 mutex_unlock(&pwrctrl->lock);
898 }
899
900 /*
901 * Caller: ISR
902 *
903 * If all commands have been done,
904 * and no more command to do,
905 * then driver shall call this fun. to power down firmware again.
906 */
rtw_unregister_cmd_alive(struct adapter * padapter)907 void rtw_unregister_cmd_alive(struct adapter *padapter)
908 {
909 struct pwrctrl_priv *pwrctrl;
910 u8 pslv;
911
912 pwrctrl = adapter_to_pwrctl(padapter);
913 pslv = PS_STATE_S0;
914
915 if (!(hal_btcoex_IsBtDisabled(padapter)) && hal_btcoex_IsBtControlLps(padapter)) {
916 u8 val8;
917
918 val8 = hal_btcoex_LpsVal(padapter);
919 if (val8 & BIT(4))
920 pslv = PS_STATE_S2;
921 }
922
923 mutex_lock(&pwrctrl->lock);
924
925 unregister_task_alive(pwrctrl, CMD_ALIVE);
926
927 if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) && pwrctrl->fw_current_in_ps_mode) {
928 if (pwrctrl->cpwm > pslv) {
929 if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
930 rtw_set_rpwm(padapter, pslv);
931 }
932 }
933
934 mutex_unlock(&pwrctrl->lock);
935 }
936
rtw_init_pwrctrl_priv(struct adapter * padapter)937 void rtw_init_pwrctrl_priv(struct adapter *padapter)
938 {
939 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
940
941 mutex_init(&pwrctrlpriv->lock);
942 pwrctrlpriv->rf_pwrstate = rf_on;
943 pwrctrlpriv->ips_enter_cnts = 0;
944 pwrctrlpriv->ips_leave_cnts = 0;
945 pwrctrlpriv->bips_processing = false;
946
947 pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
948 pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
949
950 pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
951 pwrctrlpriv->pwr_state_check_cnts = 0;
952 pwrctrlpriv->bInternalAutoSuspend = false;
953 pwrctrlpriv->bInSuspend = false;
954 pwrctrlpriv->bkeepfwalive = false;
955
956 pwrctrlpriv->LpsIdleCount = 0;
957 pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */
958 pwrctrlpriv->bLeisurePs = pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE;
959
960 pwrctrlpriv->fw_current_in_ps_mode = false;
961
962 pwrctrlpriv->rpwm = 0;
963 pwrctrlpriv->cpwm = PS_STATE_S4;
964
965 pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
966 pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
967 pwrctrlpriv->bcn_ant_mode = 0;
968 pwrctrlpriv->dtim = 0;
969
970 pwrctrlpriv->tog = 0x80;
971
972 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&pwrctrlpriv->rpwm));
973
974 _init_workitem(&pwrctrlpriv->cpwm_event, cpwm_event_callback, NULL);
975
976 pwrctrlpriv->brpwmtimeout = false;
977 pwrctrlpriv->adapter = padapter;
978 _init_workitem(&pwrctrlpriv->rpwmtimeoutwi, rpwmtimeout_workitem_callback, NULL);
979 timer_setup(&pwrctrlpriv->pwr_rpwm_timer, pwr_rpwm_timeout_handler, 0);
980 timer_setup(&pwrctrlpriv->pwr_state_check_timer,
981 pwr_state_check_handler, 0);
982
983 pwrctrlpriv->wowlan_mode = false;
984 pwrctrlpriv->wowlan_ap_mode = false;
985 }
986
rtw_free_pwrctrl_priv(struct adapter * adapter)987 void rtw_free_pwrctrl_priv(struct adapter *adapter)
988 {
989 }
990
rtw_set_ips_deny(struct adapter * padapter,u32 ms)991 inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms)
992 {
993 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
994 pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms);
995 }
996
997 /*
998 * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
999 * @adapter: pointer to struct adapter structure
1000 * @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup
1001 * Return _SUCCESS or _FAIL
1002 */
1003
_rtw_pwr_wakeup(struct adapter * padapter,u32 ips_deffer_ms,const char * caller)1004 int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller)
1005 {
1006 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1007 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
1008 struct mlme_priv *pmlmepriv;
1009 int ret = _SUCCESS;
1010 unsigned long start = jiffies;
1011 unsigned long deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
1012
1013 /* for LPS */
1014 LeaveAllPowerSaveMode(padapter);
1015
1016 /* IPS still bound with primary adapter */
1017 padapter = GET_PRIMARY_ADAPTER(padapter);
1018 pmlmepriv = &padapter->mlmepriv;
1019
1020 if (time_before(pwrpriv->ips_deny_time, deny_time))
1021 pwrpriv->ips_deny_time = deny_time;
1022
1023
1024 if (pwrpriv->ps_processing)
1025 while (pwrpriv->ps_processing && jiffies_to_msecs(jiffies - start) <= 3000)
1026 mdelay(10);
1027
1028 if (!(pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend)
1029 while (pwrpriv->bInSuspend && jiffies_to_msecs(jiffies - start) <= 3000
1030 )
1031 mdelay(10);
1032
1033 /* System suspend is not allowed to wakeup */
1034 if (!(pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) {
1035 ret = _FAIL;
1036 goto exit;
1037 }
1038
1039 /* block??? */
1040 if (pwrpriv->bInternalAutoSuspend && padapter->net_closed) {
1041 ret = _FAIL;
1042 goto exit;
1043 }
1044
1045 /* I think this should be check in IPS, LPS, autosuspend functions... */
1046 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1047 ret = _SUCCESS;
1048 goto exit;
1049 }
1050
1051 if (rf_off == pwrpriv->rf_pwrstate) {
1052 {
1053 if (ips_leave(padapter) == _FAIL) {
1054 ret = _FAIL;
1055 goto exit;
1056 }
1057 }
1058 }
1059
1060 /* TODO: the following checking need to be merged... */
1061 if (padapter->bDriverStopped || !padapter->bup || !padapter->hw_init_completed) {
1062 ret = false;
1063 goto exit;
1064 }
1065
1066 exit:
1067 deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
1068 if (time_before(pwrpriv->ips_deny_time, deny_time))
1069 pwrpriv->ips_deny_time = deny_time;
1070 return ret;
1071
1072 }
1073
rtw_pm_set_lps(struct adapter * padapter,u8 mode)1074 int rtw_pm_set_lps(struct adapter *padapter, u8 mode)
1075 {
1076 int ret = 0;
1077 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1078
1079 if (mode < PS_MODE_NUM) {
1080 if (pwrctrlpriv->power_mgnt != mode) {
1081 if (mode == PS_MODE_ACTIVE)
1082 LeaveAllPowerSaveMode(padapter);
1083 else
1084 pwrctrlpriv->LpsIdleCount = 2;
1085
1086 pwrctrlpriv->power_mgnt = mode;
1087 pwrctrlpriv->bLeisurePs =
1088 pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE;
1089 }
1090 } else
1091 ret = -EINVAL;
1092
1093 return ret;
1094 }
1095
rtw_pm_set_ips(struct adapter * padapter,u8 mode)1096 int rtw_pm_set_ips(struct adapter *padapter, u8 mode)
1097 {
1098 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1099
1100 if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
1101 rtw_ips_mode_req(pwrctrlpriv, mode);
1102 return 0;
1103 } else if (mode == IPS_NONE) {
1104 rtw_ips_mode_req(pwrctrlpriv, mode);
1105 if ((padapter->bSurpriseRemoved == 0) && (rtw_pwr_wakeup(padapter) == _FAIL))
1106 return -EFAULT;
1107 } else
1108 return -EINVAL;
1109
1110 return 0;
1111 }
1112
1113 /*
1114 * ATTENTION:
1115 *This function will request pwrctrl LOCK!
1116 */
rtw_ps_deny(struct adapter * padapter,enum ps_deny_reason reason)1117 void rtw_ps_deny(struct adapter *padapter, enum ps_deny_reason reason)
1118 {
1119 struct pwrctrl_priv *pwrpriv;
1120
1121 pwrpriv = adapter_to_pwrctl(padapter);
1122
1123 mutex_lock(&pwrpriv->lock);
1124 pwrpriv->ps_deny |= BIT(reason);
1125 mutex_unlock(&pwrpriv->lock);
1126 }
1127
1128 /*
1129 * ATTENTION:
1130 *This function will request pwrctrl LOCK!
1131 */
rtw_ps_deny_cancel(struct adapter * padapter,enum ps_deny_reason reason)1132 void rtw_ps_deny_cancel(struct adapter *padapter, enum ps_deny_reason reason)
1133 {
1134 struct pwrctrl_priv *pwrpriv;
1135
1136 pwrpriv = adapter_to_pwrctl(padapter);
1137
1138 mutex_lock(&pwrpriv->lock);
1139 pwrpriv->ps_deny &= ~BIT(reason);
1140 mutex_unlock(&pwrpriv->lock);
1141 }
1142
1143 /*
1144 * ATTENTION:
1145 *Before calling this function pwrctrl lock should be occupied already,
1146 *otherwise it may return incorrect value.
1147 */
rtw_ps_deny_get(struct adapter * padapter)1148 u32 rtw_ps_deny_get(struct adapter *padapter)
1149 {
1150 return adapter_to_pwrctl(padapter)->ps_deny;
1151 }
1152