1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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 	/*  syn ips_mode with request */
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 	rtw_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req);
47 
48 	down(&pwrpriv->lock);
49 	_ips_enter(padapter);
50 	up(&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 	down(&pwrpriv->lock);
89 	ret = _ips_leave(padapter);
90 	up(&pwrpriv->lock);
91 
92 	if (_SUCCESS == ret)
93 		rtw_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 == true) {
107 		/* DBG_871X("%s: already in LPS or IPS mode\n", __func__); */
108 		goto exit;
109 	}
110 
111 	if (time_before(jiffies, adapter_to_pwrctl(adapter)->ips_deny_time)) {
112 		/* DBG_871X("%s ips_deny_time\n", __func__); */
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 	/* consider buddy, if exist */
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  * ATTENTION:
152  *rtw_ps_processor() doesn't handle LPS.
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 	down(&adapter_to_pwrctl(padapter)->lock);
162 	ps_deny = rtw_ps_deny_get(padapter);
163 	up(&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 == true) {/* system suspend or autosuspend */
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) == false)
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) { /* from 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) { /*  2 sec == watch dog timer */
221 			if (xmit_cnt > 8) {
222 				if ((adapter_to_pwrctl(padapter)->bLeisurePs)
223 					&& (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE)
224 					&& (rtw_btcoex_IsBtControlLps(padapter) == false)
225 					) {
226 					DBG_871X("leave lps via Tx = %d\n", xmit_cnt);
227 					bLeaveLPS = true;
228 				}
229 			}
230 
231 			start_time = jiffies;
232 			xmit_cnt = 0;
233 		}
234 
235 	} else { /*  from rx path */
236 		if (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4/*2*/) {
237 			if ((adapter_to_pwrctl(padapter)->bLeisurePs)
238 				&& (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE)
239 				&& (rtw_btcoex_IsBtControlLps(padapter) == false)
240 				) {
241 				DBG_871X("leave lps via Rx = %d\n", pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod);
242 				bLeaveLPS = true;
243 			}
244 		}
245 	}
246 
247 	if (bLeaveLPS)
248 		/* DBG_871X("leave lps via %s, Tx = %d, Rx = %d\n", tx?"Tx":"Rx", pmlmepriv->LinkDetectInfo.NumTxOkInPeriod, pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); */
249 		/* rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1); */
250 		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, tx?0:1);
251 }
252 
253 /*
254  * Description:
255  *This function MUST be called under power lock protect
256  *
257  * Parameters
258  *padapter
259  *pslv			power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
260  *
261  */
262 void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
263 {
264 	u8 rpwm;
265 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
266 	u8 cpwm_orig;
267 
268 	pslv = PS_STATE(pslv);
269 
270 	if (pwrpriv->brpwmtimeout == true) {
271 		DBG_871X("%s: RPWM timeout, force to set RPWM(0x%02X) again!\n", __func__, pslv);
272 	} else{
273 		if ((pwrpriv->rpwm == pslv)
274 			|| ((pwrpriv->rpwm >= PS_STATE_S2) && (pslv >= PS_STATE_S2))) {
275 			RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
276 				("%s: Already set rpwm[0x%02X], new = 0x%02X!\n", __func__, pwrpriv->rpwm, pslv));
277 			return;
278 		}
279 	}
280 
281 	if ((padapter->bSurpriseRemoved == true) ||
282 		(padapter->hw_init_completed == false)) {
283 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
284 				 ("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n",
285 				  __func__, padapter->bSurpriseRemoved, padapter->hw_init_completed));
286 
287 		pwrpriv->cpwm = PS_STATE_S4;
288 
289 		return;
290 	}
291 
292 	if (padapter->bDriverStopped == true) {
293 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
294 				 ("%s: change power state(0x%02X) when DriverStopped\n", __func__, pslv));
295 
296 		if (pslv < PS_STATE_S2) {
297 			RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
298 					 ("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __func__, pslv));
299 			return;
300 		}
301 	}
302 
303 	rpwm = pslv | pwrpriv->tog;
304 	/*  only when from PS_STATE S0/S1 to S2 and higher needs ACK */
305 	if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2))
306 		rpwm |= PS_ACK;
307 	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
308 			 ("rtw_set_rpwm: rpwm = 0x%02x cpwm = 0x%02x\n", rpwm, pwrpriv->cpwm));
309 
310 	pwrpriv->rpwm = pslv;
311 
312 	cpwm_orig = 0;
313 	if (rpwm & PS_ACK)
314 		rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
315 
316 	if (rpwm & PS_ACK)
317 		_set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS);
318 	rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
319 
320 	pwrpriv->tog += 0x80;
321 
322 	/*  No LPS 32K, No Ack */
323 	if (rpwm & PS_ACK) {
324 		unsigned long start_time;
325 		u8 cpwm_now;
326 		u8 poll_cnt = 0;
327 
328 		start_time = jiffies;
329 
330 		/*  polling cpwm */
331 		do {
332 			mdelay(1);
333 			poll_cnt++;
334 			rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
335 			if ((cpwm_orig ^ cpwm_now) & 0x80) {
336 				pwrpriv->cpwm = PS_STATE_S4;
337 				pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE;
338 				break;
339 			}
340 
341 			if (jiffies_to_msecs(jiffies - start_time) > LPS_RPWM_WAIT_MS) {
342 				DBG_871X("%s: polling cpwm timeout! poll_cnt =%d, cpwm_orig =%02x, cpwm_now =%02x\n", __func__, poll_cnt, cpwm_orig, cpwm_now);
343 				_set_timer(&pwrpriv->pwr_rpwm_timer, 1);
344 				break;
345 			}
346 		} while (1);
347 	} else
348 		pwrpriv->cpwm = pslv;
349 }
350 
351 static u8 PS_RDY_CHECK(struct adapter *padapter)
352 {
353 	unsigned long curr_time, delta_time;
354 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
355 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
356 
357 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
358 	if (true == pwrpriv->bInSuspend && pwrpriv->wowlan_mode)
359 		return true;
360 	else if (true == pwrpriv->bInSuspend && pwrpriv->wowlan_ap_mode)
361 		return true;
362 	else if (true == pwrpriv->bInSuspend)
363 		return false;
364 #else
365 	if (true == pwrpriv->bInSuspend)
366 		return false;
367 #endif
368 
369 	curr_time = jiffies;
370 
371 	delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
372 
373 	if (delta_time < LPS_DELAY_TIME)
374 		return false;
375 
376 	if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)
377 		|| check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
378 		|| check_fwstate(pmlmepriv, WIFI_AP_STATE)
379 		|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
380 		|| rtw_is_scan_deny(padapter)
381 	)
382 		return false;
383 
384 	if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == false)) {
385 		DBG_871X("Group handshake still in progress !!!\n");
386 		return false;
387 	}
388 
389 	if (!rtw_cfg80211_pwr_mgmt(padapter))
390 		return false;
391 
392 	return true;
393 }
394 
395 void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg)
396 {
397 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
398 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
399 	struct debug_priv *pdbgpriv = &padapter->dvobj->drv_dbg;
400 #endif
401 
402 	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
403 			 ("%s: PowerMode =%d Smart_PS =%d\n",
404 			  __func__, ps_mode, smart_ps));
405 
406 	if (ps_mode > PM_Card_Disable) {
407 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("ps_mode:%d error\n", ps_mode));
408 		return;
409 	}
410 
411 	if (pwrpriv->pwr_mode == ps_mode)
412 		if (PS_MODE_ACTIVE == ps_mode)
413 			return;
414 
415 
416 	down(&pwrpriv->lock);
417 
418 	/* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
419 	if (ps_mode == PS_MODE_ACTIVE) {
420 		if (1
421 			&& (((rtw_btcoex_IsBtControlLps(padapter) == false)
422 					)
423 				|| ((rtw_btcoex_IsBtControlLps(padapter) == true)
424 					&& (rtw_btcoex_IsLpsOn(padapter) == false))
425 				)
426 			) {
427 			DBG_871X(FUNC_ADPT_FMT" Leave 802.11 power save - %s\n",
428 				FUNC_ADPT_ARG(padapter), msg);
429 
430 			pwrpriv->pwr_mode = ps_mode;
431 			rtw_set_rpwm(padapter, PS_STATE_S4);
432 
433 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
434 			if (pwrpriv->wowlan_mode == true ||
435 					pwrpriv->wowlan_ap_mode == true) {
436 				unsigned long start_time;
437 				u32 delay_ms;
438 				u8 val8;
439 				delay_ms = 20;
440 				start_time = jiffies;
441 				do {
442 					rtw_hal_get_hwreg(padapter, HW_VAR_SYS_CLKR, &val8);
443 					if (!(val8 & BIT(4))) { /* 0x08 bit4 = 1 --> in 32k, bit4 = 0 --> leave 32k */
444 						pwrpriv->cpwm = PS_STATE_S4;
445 						break;
446 					}
447 					if (jiffies_to_msecs(jiffies - start_time) > delay_ms) {
448 						DBG_871X("%s: Wait for FW 32K leave more than %u ms!!!\n",
449 								__func__, delay_ms);
450 						pdbgpriv->dbg_wow_leave_ps_fail_cnt++;
451 						break;
452 					}
453 					msleep(1);
454 				} while (1);
455 			}
456 #endif
457 			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
458 			pwrpriv->bFwCurrentInPSMode = false;
459 
460 			rtw_btcoex_LpsNotify(padapter, ps_mode);
461 		}
462 	} else{
463 		if ((PS_RDY_CHECK(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE))
464 			|| ((rtw_btcoex_IsBtControlLps(padapter) == true)
465 				&& (rtw_btcoex_IsLpsOn(padapter) == true))
466 			) {
467 			u8 pslv;
468 
469 			DBG_871X(FUNC_ADPT_FMT" Enter 802.11 power save - %s\n",
470 				FUNC_ADPT_ARG(padapter), msg);
471 
472 			rtw_btcoex_LpsNotify(padapter, ps_mode);
473 
474 			pwrpriv->bFwCurrentInPSMode = true;
475 			pwrpriv->pwr_mode = ps_mode;
476 			pwrpriv->smart_ps = smart_ps;
477 			pwrpriv->bcn_ant_mode = bcn_ant_mode;
478 			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
479 
480 			pslv = PS_STATE_S2;
481 			if (pwrpriv->alives == 0)
482 				pslv = PS_STATE_S0;
483 
484 			if ((rtw_btcoex_IsBtDisabled(padapter) == false)
485 				&& (rtw_btcoex_IsBtControlLps(padapter) == true)) {
486 				u8 val8;
487 
488 				val8 = rtw_btcoex_LpsVal(padapter);
489 				if (val8 & BIT(4))
490 					pslv = PS_STATE_S2;
491 			}
492 
493 			rtw_set_rpwm(padapter, pslv);
494 		}
495 	}
496 
497 	up(&pwrpriv->lock);
498 }
499 
500 /*
501  * Return:
502  *0:	Leave OK
503  *-1:	Timeout
504  *-2:	Other error
505  */
506 s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
507 {
508 	unsigned long start_time;
509 	u8 bAwake = false;
510 	s32 err = 0;
511 
512 
513 	start_time = jiffies;
514 	while (1) {
515 		rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
516 		if (true == bAwake)
517 			break;
518 
519 		if (true == padapter->bSurpriseRemoved) {
520 			err = -2;
521 			DBG_871X("%s: device surprise removed!!\n", __func__);
522 			break;
523 		}
524 
525 		if (jiffies_to_msecs(jiffies - start_time) > delay_ms) {
526 			err = -1;
527 			DBG_871X("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms);
528 			break;
529 		}
530 		msleep(1);
531 	}
532 
533 	return err;
534 }
535 
536 /*  */
537 /* 	Description: */
538 /* 		Enter the leisure power save mode. */
539 /*  */
540 void LPS_Enter(struct adapter *padapter, const char *msg)
541 {
542 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
543 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
544 	int n_assoc_iface = 0;
545 	char buf[32] = {0};
546 
547 	if (rtw_btcoex_IsBtControlLps(padapter) == true)
548 		return;
549 
550 	/* Skip lps enter request if number of assocated adapters is not 1 */
551 	if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE))
552 		n_assoc_iface++;
553 	if (n_assoc_iface != 1)
554 		return;
555 
556 	/* Skip lps enter request for adapter not port0 */
557 	if (get_iface_type(padapter) != IFACE_PORT0)
558 		return;
559 
560 	if (PS_RDY_CHECK(dvobj->padapters) == false)
561 			return;
562 
563 	if (pwrpriv->bLeisurePs) {
564 		/*  Idle for a while if we connect to AP a while ago. */
565 		if (pwrpriv->LpsIdleCount >= 2) { /*   4 Sec */
566 			if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
567 				sprintf(buf, "WIFI-%s", msg);
568 				pwrpriv->bpower_saving = true;
569 				rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, padapter->registrypriv.smart_ps, 0, buf);
570 			}
571 		} else
572 			pwrpriv->LpsIdleCount++;
573 	}
574 
575 /* 	DBG_871X("-LeisurePSEnter\n"); */
576 }
577 
578 /*  */
579 /* 	Description: */
580 /* 		Leave the leisure power save mode. */
581 /*  */
582 void LPS_Leave(struct adapter *padapter, const char *msg)
583 {
584 #define LPS_LEAVE_TIMEOUT_MS 100
585 
586 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
587 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
588 	char buf[32] = {0};
589 
590 /* 	DBG_871X("+LeisurePSLeave\n"); */
591 
592 	if (rtw_btcoex_IsBtControlLps(padapter) == true)
593 		return;
594 
595 	if (pwrpriv->bLeisurePs) {
596 		if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
597 			sprintf(buf, "WIFI-%s", msg);
598 			rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, buf);
599 
600 			if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
601 				LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS);
602 		}
603 	}
604 
605 	pwrpriv->bpower_saving = false;
606 /* 	DBG_871X("-LeisurePSLeave\n"); */
607 
608 }
609 
610 void LeaveAllPowerSaveModeDirect(struct adapter *Adapter)
611 {
612 	struct adapter *pri_padapter = GET_PRIMARY_ADAPTER(Adapter);
613 	struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
614 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter);
615 
616 	DBG_871X("%s.....\n", __func__);
617 
618 	if (true == Adapter->bSurpriseRemoved) {
619 		DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved =%d Skip!\n",
620 			FUNC_ADPT_ARG(Adapter), Adapter->bSurpriseRemoved);
621 		return;
622 	}
623 
624 	if ((check_fwstate(pmlmepriv, _FW_LINKED) == true)) { /* connect */
625 
626 		if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
627 			DBG_871X("%s: Driver Already Leave LPS\n", __func__);
628 			return;
629 		}
630 
631 		down(&pwrpriv->lock);
632 
633 		rtw_set_rpwm(Adapter, PS_STATE_S4);
634 
635 		up(&pwrpriv->lock);
636 
637 		rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, 0);
638 	} else{
639 		if (pwrpriv->rf_pwrstate == rf_off)
640 			if (false == ips_leave(pri_padapter))
641 				DBG_871X("======> ips_leave fail.............\n");
642 	}
643 }
644 
645 /*  */
646 /*  Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */
647 /*  Move code to function by tynli. 2010.03.26. */
648 /*  */
649 void LeaveAllPowerSaveMode(struct adapter *Adapter)
650 {
651 	struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
652 	u8 enqueue = 0;
653 	int n_assoc_iface = 0;
654 
655 	if (!Adapter->bup) {
656 		DBG_871X(FUNC_ADPT_FMT ": bup =%d Skip!\n",
657 			FUNC_ADPT_ARG(Adapter), Adapter->bup);
658 		return;
659 	}
660 
661 	if (Adapter->bSurpriseRemoved) {
662 		DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved =%d Skip!\n",
663 			FUNC_ADPT_ARG(Adapter), Adapter->bSurpriseRemoved);
664 		return;
665 	}
666 
667 	if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE))
668 		n_assoc_iface++;
669 
670 	if (n_assoc_iface) { /* connect */
671 		enqueue = 1;
672 
673 		rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
674 
675 		LPS_Leave_check(Adapter);
676 	} else {
677 		if (adapter_to_pwrctl(Adapter)->rf_pwrstate == rf_off) {
678 			if (false == ips_leave(Adapter))
679 				DBG_871X("======> ips_leave fail.............\n");
680 		}
681 	}
682 }
683 
684 void LPS_Leave_check(
685 	struct adapter *padapter)
686 {
687 	struct pwrctrl_priv *pwrpriv;
688 	unsigned long	start_time;
689 	u8 bReady;
690 
691 	pwrpriv = adapter_to_pwrctl(padapter);
692 
693 	bReady = false;
694 	start_time = jiffies;
695 
696 	cond_resched();
697 
698 	while (1) {
699 		down(&pwrpriv->lock);
700 
701 		if ((padapter->bSurpriseRemoved == true)
702 			|| (padapter->hw_init_completed == false)
703 			|| (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
704 			)
705 			bReady = true;
706 
707 		up(&pwrpriv->lock);
708 
709 		if (true == bReady)
710 			break;
711 
712 		if (jiffies_to_msecs(jiffies - start_time) > 100) {
713 			DBG_871X("Wait for cpwm event  than 100 ms!!!\n");
714 			break;
715 		}
716 		msleep(1);
717 	}
718 }
719 
720 /*
721  * Caller:ISR handler...
722  *
723  * This will be called when CPWM interrupt is up.
724  *
725  * using to update cpwn of drv; and drv willl make a decision to up or down pwr level
726  */
727 void cpwm_int_hdl(
728 	struct adapter *padapter,
729 	struct reportpwrstate_parm *preportpwrstate)
730 {
731 	struct pwrctrl_priv *pwrpriv;
732 
733 	pwrpriv = adapter_to_pwrctl(padapter);
734 
735 	down(&pwrpriv->lock);
736 
737 	if (pwrpriv->rpwm < PS_STATE_S2) {
738 		DBG_871X("%s: Redundant CPWM Int. RPWM = 0x%02X CPWM = 0x%02x\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
739 		up(&pwrpriv->lock);
740 		goto exit;
741 	}
742 
743 	pwrpriv->cpwm = PS_STATE(preportpwrstate->state);
744 	pwrpriv->cpwm_tog = preportpwrstate->state & PS_TOGGLE;
745 
746 	if (pwrpriv->cpwm >= PS_STATE_S2) {
747 		if (pwrpriv->alives & CMD_ALIVE)
748 			up(&padapter->cmdpriv.cmd_queue_sema);
749 
750 		if (pwrpriv->alives & XMIT_ALIVE)
751 			up(&padapter->xmitpriv.xmit_sema);
752 	}
753 
754 	up(&pwrpriv->lock);
755 
756 exit:
757 	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
758 			 ("cpwm_int_hdl: cpwm = 0x%02x\n", pwrpriv->cpwm));
759 }
760 
761 static void cpwm_event_callback(struct work_struct *work)
762 {
763 	struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event);
764 	struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
765 	struct adapter *adapter = dvobj->if1;
766 	struct reportpwrstate_parm report;
767 
768 	/* DBG_871X("%s\n", __func__); */
769 
770 	report.state = PS_STATE_S2;
771 	cpwm_int_hdl(adapter, &report);
772 }
773 
774 static void rpwmtimeout_workitem_callback(struct work_struct *work)
775 {
776 	struct adapter *padapter;
777 	struct dvobj_priv *dvobj;
778 	struct pwrctrl_priv *pwrpriv;
779 
780 
781 	pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi);
782 	dvobj = pwrctl_to_dvobj(pwrpriv);
783 	padapter = dvobj->if1;
784 /* 	DBG_871X("+%s: rpwm = 0x%02X cpwm = 0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); */
785 
786 	down(&pwrpriv->lock);
787 	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
788 		DBG_871X("%s: rpwm = 0x%02X cpwm = 0x%02X CPWM done!\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
789 		goto exit;
790 	}
791 	up(&pwrpriv->lock);
792 
793 	if (rtw_read8(padapter, 0x100) != 0xEA) {
794 		struct reportpwrstate_parm report;
795 
796 		report.state = PS_STATE_S2;
797 		DBG_871X("\n%s: FW already leave 32K!\n\n", __func__);
798 		cpwm_int_hdl(padapter, &report);
799 
800 		return;
801 	}
802 
803 	down(&pwrpriv->lock);
804 
805 	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
806 		DBG_871X("%s: cpwm =%d, nothing to do!\n", __func__, pwrpriv->cpwm);
807 		goto exit;
808 	}
809 	pwrpriv->brpwmtimeout = true;
810 	rtw_set_rpwm(padapter, pwrpriv->rpwm);
811 	pwrpriv->brpwmtimeout = false;
812 
813 exit:
814 	up(&pwrpriv->lock);
815 }
816 
817 /*
818  * This function is a timer handler, can't do any IO in it.
819  */
820 static void pwr_rpwm_timeout_handler(struct timer_list *t)
821 {
822 	struct pwrctrl_priv *pwrpriv = from_timer(pwrpriv, t, pwr_rpwm_timer);
823 
824 	DBG_871X("+%s: rpwm = 0x%02X cpwm = 0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
825 
826 	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
827 		DBG_871X("+%s: cpwm =%d, nothing to do!\n", __func__, pwrpriv->cpwm);
828 		return;
829 	}
830 
831 	_set_workitem(&pwrpriv->rpwmtimeoutwi);
832 }
833 
834 static __inline void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
835 {
836 	pwrctrl->alives |= tag;
837 }
838 
839 static __inline void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
840 {
841 	pwrctrl->alives &= ~tag;
842 }
843 
844 
845 /*
846  * Description:
847  *Check if the fw_pwrstate is okay for I/O.
848  *If not (cpwm is less than S2), then the sub-routine
849  *will raise the cpwm to be greater than or equal to S2.
850  *
851  *Calling Context: Passive
852  *
853  *Constraint:
854  *	1. this function will request pwrctrl->lock
855  *
856  * Return Value:
857  *_SUCCESS	hardware is ready for I/O
858  *_FAIL		can't I/O right now
859  */
860 s32 rtw_register_task_alive(struct adapter *padapter, u32 task)
861 {
862 	s32 res;
863 	struct pwrctrl_priv *pwrctrl;
864 	u8 pslv;
865 
866 	res = _SUCCESS;
867 	pwrctrl = adapter_to_pwrctl(padapter);
868 	pslv = PS_STATE_S2;
869 
870 	down(&pwrctrl->lock);
871 
872 	register_task_alive(pwrctrl, task);
873 
874 	if (pwrctrl->bFwCurrentInPSMode == true) {
875 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
876 				 ("%s: task = 0x%x cpwm = 0x%02x alives = 0x%08x\n",
877 				  __func__, task, pwrctrl->cpwm, pwrctrl->alives));
878 
879 		if (pwrctrl->cpwm < pslv) {
880 			if (pwrctrl->cpwm < PS_STATE_S2)
881 				res = _FAIL;
882 			if (pwrctrl->rpwm < pslv)
883 				rtw_set_rpwm(padapter, pslv);
884 		}
885 	}
886 
887 	up(&pwrctrl->lock);
888 
889 	if (_FAIL == res)
890 		if (pwrctrl->cpwm >= PS_STATE_S2)
891 			res = _SUCCESS;
892 
893 	return res;
894 }
895 
896 /*
897  * Description:
898  *If task is done, call this func. to power down firmware again.
899  *
900  *Constraint:
901  *	1. this function will request pwrctrl->lock
902  *
903  * Return Value:
904  *none
905  */
906 void rtw_unregister_task_alive(struct adapter *padapter, u32 task)
907 {
908 	struct pwrctrl_priv *pwrctrl;
909 	u8 pslv;
910 
911 	pwrctrl = adapter_to_pwrctl(padapter);
912 	pslv = PS_STATE_S0;
913 
914 	if ((rtw_btcoex_IsBtDisabled(padapter) == false)
915 		&& (rtw_btcoex_IsBtControlLps(padapter) == true)) {
916 		u8 val8;
917 
918 		val8 = rtw_btcoex_LpsVal(padapter);
919 		if (val8 & BIT(4))
920 			pslv = PS_STATE_S2;
921 	}
922 
923 	down(&pwrctrl->lock);
924 
925 	unregister_task_alive(pwrctrl, task);
926 
927 	if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
928 		&& (pwrctrl->bFwCurrentInPSMode == true)) {
929 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
930 				 ("%s: cpwm = 0x%02x alives = 0x%08x\n",
931 				  __func__, pwrctrl->cpwm, pwrctrl->alives));
932 
933 		if (pwrctrl->cpwm > pslv)
934 			if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
935 				rtw_set_rpwm(padapter, pslv);
936 
937 	}
938 
939 	up(&pwrctrl->lock);
940 }
941 
942 /*
943  * Caller: rtw_xmit_thread
944  *
945  * Check if the fw_pwrstate is okay for xmit.
946  * If not (cpwm is less than S3), then the sub-routine
947  * will raise the cpwm to be greater than or equal to S3.
948  *
949  * Calling Context: Passive
950  *
951  * Return Value:
952  * _SUCCESS	rtw_xmit_thread can write fifo/txcmd afterwards.
953  * _FAIL		rtw_xmit_thread can not do anything.
954  */
955 s32 rtw_register_tx_alive(struct adapter *padapter)
956 {
957 	s32 res;
958 	struct pwrctrl_priv *pwrctrl;
959 	u8 pslv;
960 
961 	res = _SUCCESS;
962 	pwrctrl = adapter_to_pwrctl(padapter);
963 	pslv = PS_STATE_S2;
964 
965 	down(&pwrctrl->lock);
966 
967 	register_task_alive(pwrctrl, XMIT_ALIVE);
968 
969 	if (pwrctrl->bFwCurrentInPSMode == true) {
970 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
971 				 ("rtw_register_tx_alive: cpwm = 0x%02x alives = 0x%08x\n",
972 				  pwrctrl->cpwm, pwrctrl->alives));
973 
974 		if (pwrctrl->cpwm < pslv) {
975 			if (pwrctrl->cpwm < PS_STATE_S2)
976 				res = _FAIL;
977 			if (pwrctrl->rpwm < pslv)
978 				rtw_set_rpwm(padapter, pslv);
979 		}
980 	}
981 
982 	up(&pwrctrl->lock);
983 
984 	if (_FAIL == res)
985 		if (pwrctrl->cpwm >= PS_STATE_S2)
986 			res = _SUCCESS;
987 
988 	return res;
989 }
990 
991 /*
992  * Caller: rtw_cmd_thread
993  *
994  * Check if the fw_pwrstate is okay for issuing cmd.
995  * If not (cpwm should be is less than S2), then the sub-routine
996  * will raise the cpwm to be greater than or equal to S2.
997  *
998  * Calling Context: Passive
999  *
1000  * Return Value:
1001  *_SUCCESS	rtw_cmd_thread can issue cmds to firmware afterwards.
1002  *_FAIL		rtw_cmd_thread can not do anything.
1003  */
1004 s32 rtw_register_cmd_alive(struct adapter *padapter)
1005 {
1006 	s32 res;
1007 	struct pwrctrl_priv *pwrctrl;
1008 	u8 pslv;
1009 
1010 	res = _SUCCESS;
1011 	pwrctrl = adapter_to_pwrctl(padapter);
1012 	pslv = PS_STATE_S2;
1013 
1014 	down(&pwrctrl->lock);
1015 
1016 	register_task_alive(pwrctrl, CMD_ALIVE);
1017 
1018 	if (pwrctrl->bFwCurrentInPSMode == true) {
1019 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_info_,
1020 				 ("rtw_register_cmd_alive: cpwm = 0x%02x alives = 0x%08x\n",
1021 				  pwrctrl->cpwm, pwrctrl->alives));
1022 
1023 		if (pwrctrl->cpwm < pslv) {
1024 			if (pwrctrl->cpwm < PS_STATE_S2)
1025 				res = _FAIL;
1026 			if (pwrctrl->rpwm < pslv)
1027 				rtw_set_rpwm(padapter, pslv);
1028 		}
1029 	}
1030 
1031 	up(&pwrctrl->lock);
1032 
1033 	if (_FAIL == res)
1034 		if (pwrctrl->cpwm >= PS_STATE_S2)
1035 			res = _SUCCESS;
1036 
1037 	return res;
1038 }
1039 
1040 /*
1041  * Caller: ISR
1042  *
1043  * If ISR's txdone,
1044  * No more pkts for TX,
1045  * Then driver shall call this fun. to power down firmware again.
1046  */
1047 void rtw_unregister_tx_alive(struct adapter *padapter)
1048 {
1049 	struct pwrctrl_priv *pwrctrl;
1050 	u8 pslv;
1051 
1052 	pwrctrl = adapter_to_pwrctl(padapter);
1053 	pslv = PS_STATE_S0;
1054 
1055 	if ((rtw_btcoex_IsBtDisabled(padapter) == false)
1056 		&& (rtw_btcoex_IsBtControlLps(padapter) == true)) {
1057 		u8 val8;
1058 
1059 		val8 = rtw_btcoex_LpsVal(padapter);
1060 		if (val8 & BIT(4))
1061 			pslv = PS_STATE_S2;
1062 	}
1063 
1064 	down(&pwrctrl->lock);
1065 
1066 	unregister_task_alive(pwrctrl, XMIT_ALIVE);
1067 
1068 	if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
1069 		&& (pwrctrl->bFwCurrentInPSMode == true)) {
1070 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
1071 				 ("%s: cpwm = 0x%02x alives = 0x%08x\n",
1072 				  __func__, pwrctrl->cpwm, pwrctrl->alives));
1073 
1074 		if (pwrctrl->cpwm > pslv)
1075 			if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
1076 				rtw_set_rpwm(padapter, pslv);
1077 	}
1078 
1079 	up(&pwrctrl->lock);
1080 }
1081 
1082 /*
1083  * Caller: ISR
1084  *
1085  * If all commands have been done,
1086  * and no more command to do,
1087  * then driver shall call this fun. to power down firmware again.
1088  */
1089 void rtw_unregister_cmd_alive(struct adapter *padapter)
1090 {
1091 	struct pwrctrl_priv *pwrctrl;
1092 	u8 pslv;
1093 
1094 	pwrctrl = adapter_to_pwrctl(padapter);
1095 	pslv = PS_STATE_S0;
1096 
1097 	if ((rtw_btcoex_IsBtDisabled(padapter) == false)
1098 		&& (rtw_btcoex_IsBtControlLps(padapter) == true)) {
1099 		u8 val8;
1100 
1101 		val8 = rtw_btcoex_LpsVal(padapter);
1102 		if (val8 & BIT(4))
1103 			pslv = PS_STATE_S2;
1104 	}
1105 
1106 	down(&pwrctrl->lock);
1107 
1108 	unregister_task_alive(pwrctrl, CMD_ALIVE);
1109 
1110 	if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
1111 		&& (pwrctrl->bFwCurrentInPSMode == true)) {
1112 		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_info_,
1113 				 ("%s: cpwm = 0x%02x alives = 0x%08x\n",
1114 				  __func__, pwrctrl->cpwm, pwrctrl->alives));
1115 
1116 		if (pwrctrl->cpwm > pslv) {
1117 			if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
1118 				rtw_set_rpwm(padapter, pslv);
1119 		}
1120 	}
1121 
1122 	up(&pwrctrl->lock);
1123 }
1124 
1125 void rtw_init_pwrctrl_priv(struct adapter *padapter)
1126 {
1127 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1128 
1129 	sema_init(&pwrctrlpriv->lock, 1);
1130 	sema_init(&pwrctrlpriv->check_32k_lock, 1);
1131 	pwrctrlpriv->rf_pwrstate = rf_on;
1132 	pwrctrlpriv->ips_enter_cnts = 0;
1133 	pwrctrlpriv->ips_leave_cnts = 0;
1134 	pwrctrlpriv->bips_processing = false;
1135 
1136 	pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
1137 	pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
1138 
1139 	pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
1140 	pwrctrlpriv->pwr_state_check_cnts = 0;
1141 	pwrctrlpriv->bInternalAutoSuspend = false;
1142 	pwrctrlpriv->bInSuspend = false;
1143 	pwrctrlpriv->bkeepfwalive = false;
1144 
1145 	pwrctrlpriv->LpsIdleCount = 0;
1146 	pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/*  PS_MODE_MIN; */
1147 	pwrctrlpriv->bLeisurePs = pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE;
1148 
1149 	pwrctrlpriv->bFwCurrentInPSMode = false;
1150 
1151 	pwrctrlpriv->rpwm = 0;
1152 	pwrctrlpriv->cpwm = PS_STATE_S4;
1153 
1154 	pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
1155 	pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
1156 	pwrctrlpriv->bcn_ant_mode = 0;
1157 	pwrctrlpriv->dtim = 0;
1158 
1159 	pwrctrlpriv->tog = 0x80;
1160 
1161 	rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&pwrctrlpriv->rpwm));
1162 
1163 	_init_workitem(&pwrctrlpriv->cpwm_event, cpwm_event_callback, NULL);
1164 
1165 	pwrctrlpriv->brpwmtimeout = false;
1166 	pwrctrlpriv->adapter = padapter;
1167 	_init_workitem(&pwrctrlpriv->rpwmtimeoutwi, rpwmtimeout_workitem_callback, NULL);
1168 	timer_setup(&pwrctrlpriv->pwr_rpwm_timer, pwr_rpwm_timeout_handler, 0);
1169 	timer_setup(&pwrctrlpriv->pwr_state_check_timer,
1170 		    pwr_state_check_handler, 0);
1171 
1172 	pwrctrlpriv->wowlan_mode = false;
1173 	pwrctrlpriv->wowlan_ap_mode = false;
1174 
1175 #ifdef CONFIG_PNO_SUPPORT
1176 	pwrctrlpriv->pno_inited = false;
1177 	pwrctrlpriv->pnlo_info = NULL;
1178 	pwrctrlpriv->pscan_info = NULL;
1179 	pwrctrlpriv->pno_ssid_list = NULL;
1180 	pwrctrlpriv->pno_in_resume = true;
1181 #endif
1182 }
1183 
1184 
1185 void rtw_free_pwrctrl_priv(struct adapter *adapter)
1186 {
1187 #ifdef CONFIG_PNO_SUPPORT
1188 	if (pwrctrlpriv->pnlo_info != NULL)
1189 		printk("****** pnlo_info memory leak********\n");
1190 
1191 	if (pwrctrlpriv->pscan_info != NULL)
1192 		printk("****** pscan_info memory leak********\n");
1193 
1194 	if (pwrctrlpriv->pno_ssid_list != NULL)
1195 		printk("****** pno_ssid_list memory leak********\n");
1196 #endif
1197 }
1198 
1199 inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms)
1200 {
1201 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1202 	pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms);
1203 }
1204 
1205 /*
1206 * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
1207 * @adapter: pointer to struct adapter structure
1208 * @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup
1209 * Return _SUCCESS or _FAIL
1210 */
1211 
1212 int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller)
1213 {
1214 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1215 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
1216 	struct mlme_priv *pmlmepriv;
1217 	int ret = _SUCCESS;
1218 	unsigned long start = jiffies;
1219 	unsigned long deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
1220 
1221 	/* for LPS */
1222 	LeaveAllPowerSaveMode(padapter);
1223 
1224 	/* IPS still bound with primary adapter */
1225 	padapter = GET_PRIMARY_ADAPTER(padapter);
1226 	pmlmepriv = &padapter->mlmepriv;
1227 
1228 	if (time_before(pwrpriv->ips_deny_time, deny_time))
1229 		pwrpriv->ips_deny_time = deny_time;
1230 
1231 
1232 	if (pwrpriv->ps_processing) {
1233 		DBG_871X("%s wait ps_processing...\n", __func__);
1234 		while (pwrpriv->ps_processing && jiffies_to_msecs(jiffies - start) <= 3000)
1235 			msleep(10);
1236 		if (pwrpriv->ps_processing)
1237 			DBG_871X("%s wait ps_processing timeout\n", __func__);
1238 		else
1239 			DBG_871X("%s wait ps_processing done\n", __func__);
1240 	}
1241 
1242 	if (pwrpriv->bInternalAutoSuspend == false && pwrpriv->bInSuspend) {
1243 		DBG_871X("%s wait bInSuspend...\n", __func__);
1244 		while (pwrpriv->bInSuspend
1245 			&& jiffies_to_msecs(jiffies - start) <= 3000
1246 		) {
1247 			msleep(10);
1248 		}
1249 		if (pwrpriv->bInSuspend)
1250 			DBG_871X("%s wait bInSuspend timeout\n", __func__);
1251 		else
1252 			DBG_871X("%s wait bInSuspend done\n", __func__);
1253 	}
1254 
1255 	/* System suspend is not allowed to wakeup */
1256 	if ((pwrpriv->bInternalAutoSuspend == false) && (true == pwrpriv->bInSuspend)) {
1257 		ret = _FAIL;
1258 		goto exit;
1259 	}
1260 
1261 	/* block??? */
1262 	if ((pwrpriv->bInternalAutoSuspend == true)  && (padapter->net_closed == true)) {
1263 		ret = _FAIL;
1264 		goto exit;
1265 	}
1266 
1267 	/* I think this should be check in IPS, LPS, autosuspend functions... */
1268 	if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
1269 		ret = _SUCCESS;
1270 		goto exit;
1271 	}
1272 
1273 	if (rf_off == pwrpriv->rf_pwrstate) {
1274 		{
1275 			DBG_8192C("%s call ips_leave....\n", __func__);
1276 			if (_FAIL ==  ips_leave(padapter)) {
1277 				DBG_8192C("======> ips_leave fail.............\n");
1278 				ret = _FAIL;
1279 				goto exit;
1280 			}
1281 		}
1282 	}
1283 
1284 	/* TODO: the following checking need to be merged... */
1285 	if (padapter->bDriverStopped
1286 		|| !padapter->bup
1287 		|| !padapter->hw_init_completed
1288 	) {
1289 		DBG_8192C("%s: bDriverStopped =%d, bup =%d, hw_init_completed =%u\n"
1290 			, caller
1291 			, padapter->bDriverStopped
1292 			, padapter->bup
1293 			, padapter->hw_init_completed);
1294 		ret = false;
1295 		goto exit;
1296 	}
1297 
1298 exit:
1299 	deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
1300 	if (time_before(pwrpriv->ips_deny_time, deny_time))
1301 		pwrpriv->ips_deny_time = deny_time;
1302 	return ret;
1303 
1304 }
1305 
1306 int rtw_pm_set_lps(struct adapter *padapter, u8 mode)
1307 {
1308 	int	ret = 0;
1309 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1310 
1311 	if (mode < PS_MODE_NUM) {
1312 		if (pwrctrlpriv->power_mgnt != mode) {
1313 			if (PS_MODE_ACTIVE == mode)
1314 				LeaveAllPowerSaveMode(padapter);
1315 			else
1316 				pwrctrlpriv->LpsIdleCount = 2;
1317 
1318 			pwrctrlpriv->power_mgnt = mode;
1319 			pwrctrlpriv->bLeisurePs =
1320 				pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE;
1321 		}
1322 	} else
1323 		ret = -EINVAL;
1324 
1325 	return ret;
1326 }
1327 
1328 int rtw_pm_set_ips(struct adapter *padapter, u8 mode)
1329 {
1330 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1331 
1332 	if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
1333 		rtw_ips_mode_req(pwrctrlpriv, mode);
1334 		DBG_871X("%s %s\n", __func__, mode == IPS_NORMAL?"IPS_NORMAL":"IPS_LEVEL_2");
1335 		return 0;
1336 	} else if (mode == IPS_NONE) {
1337 		rtw_ips_mode_req(pwrctrlpriv, mode);
1338 		DBG_871X("%s %s\n", __func__, "IPS_NONE");
1339 		if ((padapter->bSurpriseRemoved == 0) && (_FAIL == rtw_pwr_wakeup(padapter)))
1340 			return -EFAULT;
1341 	} else
1342 		return -EINVAL;
1343 
1344 	return 0;
1345 }
1346 
1347 /*
1348  * ATTENTION:
1349  *This function will request pwrctrl LOCK!
1350  */
1351 void rtw_ps_deny(struct adapter *padapter, enum PS_DENY_REASON reason)
1352 {
1353 	struct pwrctrl_priv *pwrpriv;
1354 
1355 /* 	DBG_871X("+" FUNC_ADPT_FMT ": Request PS deny for %d (0x%08X)\n", */
1356 /* 		FUNC_ADPT_ARG(padapter), reason, BIT(reason)); */
1357 
1358 	pwrpriv = adapter_to_pwrctl(padapter);
1359 
1360 	down(&pwrpriv->lock);
1361 	if (pwrpriv->ps_deny & BIT(reason)) {
1362 		DBG_871X(FUNC_ADPT_FMT ": [WARNING] Reason %d had been set before!!\n",
1363 			FUNC_ADPT_ARG(padapter), reason);
1364 	}
1365 	pwrpriv->ps_deny |= BIT(reason);
1366 	up(&pwrpriv->lock);
1367 
1368 /* 	DBG_871X("-" FUNC_ADPT_FMT ": Now PS deny for 0x%08X\n", */
1369 /* 		FUNC_ADPT_ARG(padapter), pwrpriv->ps_deny); */
1370 }
1371 
1372 /*
1373  * ATTENTION:
1374  *This function will request pwrctrl LOCK!
1375  */
1376 void rtw_ps_deny_cancel(struct adapter *padapter, enum PS_DENY_REASON reason)
1377 {
1378 	struct pwrctrl_priv *pwrpriv;
1379 
1380 
1381 /* 	DBG_871X("+" FUNC_ADPT_FMT ": Cancel PS deny for %d(0x%08X)\n", */
1382 /* 		FUNC_ADPT_ARG(padapter), reason, BIT(reason)); */
1383 
1384 	pwrpriv = adapter_to_pwrctl(padapter);
1385 
1386 	down(&pwrpriv->lock);
1387 	if ((pwrpriv->ps_deny & BIT(reason)) == 0) {
1388 		DBG_871X(FUNC_ADPT_FMT ": [ERROR] Reason %d had been canceled before!!\n",
1389 			FUNC_ADPT_ARG(padapter), reason);
1390 	}
1391 	pwrpriv->ps_deny &= ~BIT(reason);
1392 	up(&pwrpriv->lock);
1393 
1394 /* 	DBG_871X("-" FUNC_ADPT_FMT ": Now PS deny for 0x%08X\n", */
1395 /* 		FUNC_ADPT_ARG(padapter), pwrpriv->ps_deny); */
1396 }
1397 
1398 /*
1399  * ATTENTION:
1400  *Before calling this function pwrctrl lock should be occupied already,
1401  *otherwise it may return incorrect value.
1402  */
1403 u32 rtw_ps_deny_get(struct adapter *padapter)
1404 {
1405 	u32 deny;
1406 
1407 
1408 	deny = adapter_to_pwrctl(padapter)->ps_deny;
1409 
1410 	return deny;
1411 }
1412