xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/core/rtw_pwrctrl.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _RTW_PWRCTRL_C_
16 
17 #include <drv_types.h>
18 #ifdef CONFIG_RTW_IPS
rtw_core_set_ips_state(void * drv_priv,enum rtw_rf_state state)19 bool rtw_core_set_ips_state(void *drv_priv, enum rtw_rf_state state)
20 {
21         struct dvobj_priv *dvobj = (struct dvobj_priv *)drv_priv;
22         enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
23 
24         if (state == RTW_RF_ON) {
25                 pstatus = rtw_phl_rf_on(dvobj->phl);
26         } else if (state == RTW_RF_OFF) {
27                 pstatus = rtw_phl_rf_off(dvobj->phl);
28         }
29 
30         if (RTW_PHL_STATUS_SUCCESS == pstatus)
31                 return true;
32         else
33                 return false;
34 }
35 #endif
36 #ifdef DBG_CHECK_FW_PS_STATE
rtw_fw_ps_state(_adapter * padapter)37 int rtw_fw_ps_state(_adapter *padapter)
38 {
39 	struct dvobj_priv *psdpriv = padapter->dvobj;
40 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
41 	int ret = _FAIL, dont_care = 0;
42 	u8 ps_state = 0;
43 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
44 	struct registry_priv  *registry_par = &padapter->registrypriv;
45 
46 	if (registry_par->check_fw_ps != 1)
47 		return _SUCCESS;
48 
49 	_enter_pwrlock(&pwrpriv->check_32k_lock);
50 
51 	if (RTW_CANNOT_RUN(psdpriv)) {
52 		RTW_INFO("%s: bSurpriseRemoved=%s , hw_init_completed=%d, bDriverStopped=%s\n", __func__
53 			 , dev_is_surprise_removed(adapter_to_dvobj(padapter)) ? "True" : "False"
54 			 , rtw_hw_get_init_completed(adapter_to_dvobj(padapter))
55 			 , dev_is_drv_stopped(adapter_to_dvobj(padapter)) ? "True" : "False");
56 		goto exit_fw_ps_state;
57 	}
58 	rtw_hal_get_hwreg(padapter, HW_VAR_FW_PS_STATE, (u8 *)&ps_state);
59 	if (ps_state == PS_ACTIVE) {
60 		ret = _SUCCESS;
61 	} else {
62 		pdbgpriv->dbg_poll_fail_cnt++;
63 		RTW_INFO("%s: fw_ps_state=%04x\n", __func__, ps_state);
64 	}
65 
66 exit_fw_ps_state:
67 	_exit_pwrlock(&pwrpriv->check_32k_lock);
68 	return ret;
69 }
70 #endif /*DBG_CHECK_FW_PS_STATE*/
71 #ifdef CONFIG_IPS
_ips_enter(_adapter * padapter)72 void _ips_enter(_adapter *padapter)
73 {
74 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
75 
76 	pwrpriv->bips_processing = _TRUE;
77 
78 	/* syn ips_mode with request */
79 	pwrpriv->ips_mode = pwrpriv->ips_mode_req;
80 
81 	pwrpriv->ips_enter_cnts++;
82 	RTW_INFO("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts);
83 
84 	if (rf_off == pwrpriv->change_rfpwrstate) {
85 		pwrpriv->bpower_saving = _TRUE;
86 		RTW_PRINT("nolinked power save enter\n");
87 
88 		if (pwrpriv->ips_mode == IPS_LEVEL_2)
89 			pwrpriv->bkeepfwalive = _TRUE;
90 
91 #ifdef CONFIG_RTW_CFGVENDOR_LLSTATS
92 		pwrpriv->pwr_saving_start_time = rtw_get_current_time();
93 #endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */
94 
95 		rtw_ips_pwr_down(padapter);
96 		pwrpriv->rf_pwrstate = rf_off;
97 	}
98 	pwrpriv->bips_processing = _FALSE;
99 
100 }
101 
ips_enter(_adapter * padapter)102 void ips_enter(_adapter *padapter)
103 {
104 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
105 
106 	_enter_pwrlock(&pwrpriv->lock);
107 	_ips_enter(padapter);
108 	_exit_pwrlock(&pwrpriv->lock);
109 
110 #ifdef CONFIG_PCI_DYNAMIC_ASPM
111 	rtw_pci_dynamic_aspm_set_mode(padapter, ASPM_MODE_PS);
112 #endif
113 }
114 
_ips_leave(_adapter * padapter)115 int _ips_leave(_adapter *padapter)
116 {
117 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
118 	int result = _SUCCESS;
119 
120 	if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
121 		pwrpriv->bips_processing = _TRUE;
122 		pwrpriv->change_rfpwrstate = rf_on;
123 		pwrpriv->ips_leave_cnts++;
124 		RTW_INFO("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts);
125 
126 		result = rtw_ips_pwr_up(padapter);
127 		if (result == _SUCCESS)
128 			pwrpriv->rf_pwrstate = rf_on;
129 
130 #ifdef CONFIG_RTW_CFGVENDOR_LLSTATS
131 		pwrpriv->pwr_saving_time += rtw_get_passing_time_ms(pwrpriv->pwr_saving_start_time);
132 #endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */
133 
134 		RTW_PRINT("nolinked power save leave\n");
135 #if 0 /*GEORGIA_TODO_REDEFINE_IO*/
136 		RTW_INFO("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
137 #endif
138 		pwrpriv->bips_processing = _FALSE;
139 
140 		pwrpriv->bkeepfwalive = _FALSE;
141 		pwrpriv->bpower_saving = _FALSE;
142 	}
143 
144 	return result;
145 }
146 
ips_leave(_adapter * padapter)147 int ips_leave(_adapter *padapter)
148 {
149 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
150 #ifdef DBG_CHECK_FW_PS_STATE
151 	struct dvobj_priv *psdpriv = padapter->dvobj;
152 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
153 #endif
154 	int ret;
155 
156 	if (!is_primary_adapter(padapter))
157 		return _SUCCESS;
158 
159 	_enter_pwrlock(&pwrpriv->lock);
160 	ret = _ips_leave(padapter);
161 #ifdef DBG_CHECK_FW_PS_STATE
162 	if (rtw_fw_ps_state(padapter) == _FAIL) {
163 		RTW_INFO("ips leave doesn't leave 32k\n");
164 		pdbgpriv->dbg_leave_ips_fail_cnt++;
165 	}
166 #endif /* DBG_CHECK_FW_PS_STATE */
167 	_exit_pwrlock(&pwrpriv->lock);
168 
169 #ifdef CONFIG_PCI_DYNAMIC_ASPM
170 	rtw_pci_dynamic_aspm_set_mode(padapter, ASPM_MODE_PERF);
171 #endif
172 	return ret;
173 }
174 #endif /* CONFIG_IPS */
175 
176 #ifdef CONFIG_POWER_SAVING
rtw_pwr_unassociated_idle(_adapter * adapter)177 bool rtw_pwr_unassociated_idle(_adapter *adapter)
178 {
179 	u8 i;
180 	_adapter *iface;
181 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
182 	struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
183 	struct mlme_priv *pmlmepriv;
184 #ifdef CONFIG_P2P
185 	struct wifidirect_info	*pwdinfo;
186 #endif
187 	u8 xmitbuf_nr = GET_HAL_XMITBUF_NR(dvobj);
188 	u8 xmitbuf_ext_nr = GET_HAL_XMITBUF_EXT_NR(dvobj);
189 
190 	bool ret = _FALSE;
191 
192 	if (adapter_to_pwrctl(adapter)->bpower_saving == _TRUE) {
193 		/* RTW_INFO("%s: already in LPS or IPS mode\n", __func__); */
194 		goto exit;
195 	}
196 
197 	if (rtw_time_after(adapter_to_pwrctl(adapter)->ips_deny_time, rtw_get_current_time())) {
198 		/* RTW_INFO("%s ips_deny_time\n", __func__); */
199 		goto exit;
200 	}
201 
202 	for (i = 0; i < dvobj->iface_nums; i++) {
203 		iface = dvobj->padapters[i];
204 		if ((iface) && rtw_is_adapter_up(iface)) {
205 			pmlmepriv = &(iface->mlmepriv);
206 #ifdef CONFIG_P2P
207 			pwdinfo = &(iface->wdinfo);
208 #endif
209 			if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_SURVEY)
210 				|| check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)
211 				|| MLME_IS_AP(iface)
212 				|| MLME_IS_MESH(iface)
213 				|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)
214 				#if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
215 				|| rtw_cfg80211_get_is_roch(iface) == _TRUE
216 				|| (rtw_cfg80211_is_ro_ch_once(adapter)
217 					&& rtw_cfg80211_get_last_ro_ch_passing_ms(adapter) < 3000)
218 				#endif
219 			)
220 				goto exit;
221 
222 		}
223 	}
224 
225 #if (MP_DRIVER == 1)
226 	if (adapter->registrypriv.mp_mode == 1)
227 		goto exit;
228 #endif
229 
230 	if (pxmit_priv->free_xmitbuf_cnt != xmitbuf_nr ||
231 	    pxmit_priv->free_xmit_extbuf_cnt != xmitbuf_ext_nr) {
232 		RTW_PRINT("There are some pkts to transmit\n");
233 		RTW_PRINT("free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n",
234 			pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);
235 		goto exit;
236 	}
237 
238 	ret = _TRUE;
239 
240 exit:
241 	return ret;
242 }
243 
244 
245 /*
246  * ATTENTION:
247  *	rtw_ps_processor() doesn't handle LPS.
248  */
249 
rtw_ps_processor(_adapter * padapter)250 void rtw_ps_processor(_adapter *padapter)
251 {
252 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
253 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
254 	struct dvobj_priv *psdpriv = padapter->dvobj;
255 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
256 	u32 ps_deny = 0;
257 
258 	_enter_pwrlock(&adapter_to_pwrctl(padapter)->lock);
259 	ps_deny = rtw_ps_deny_get(padapter);
260 	_exit_pwrlock(&adapter_to_pwrctl(padapter)->lock);
261 	if (ps_deny != 0) {
262 		if (!MLME_IS_MONITOR(padapter)) {
263 			RTW_INFO(FUNC_ADPT_FMT ": ps_deny=0x%08X, skip power save!\n",
264 				 FUNC_ADPT_ARG(padapter), ps_deny);
265 		}
266 		goto exit;
267 	}
268 
269 	if (pwrpriv->bInSuspend == _TRUE) { /* system suspend or autosuspend */
270 		pdbgpriv->dbg_ps_insuspend_cnt++;
271 		RTW_INFO("%s, pwrpriv->bInSuspend == _TRUE ignore this process\n", __FUNCTION__);
272 		return;
273 	}
274 
275 	pwrpriv->ps_processing = _TRUE;
276 
277 	if (pwrpriv->ips_mode_req == IPS_NONE)
278 		goto exit;
279 
280 	if (rtw_pwr_unassociated_idle(padapter) == _FALSE)
281 		goto exit;
282 
283 	if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts % 4) == 0)) {
284 		RTW_INFO("==>%s .fw_state(%x)\n", __FUNCTION__, get_fwstate(pmlmepriv));
285 		pwrpriv->change_rfpwrstate = rf_off;
286 
287 #ifdef CONFIG_IPS
288 			ips_enter(padapter);
289 #endif
290 
291 	}
292 exit:
293 #ifndef CONFIG_IPS_CHECK_IN_WD
294 	rtw_set_pwr_state_check_timer(pwrpriv);
295 #endif
296 	pwrpriv->ps_processing = _FALSE;
297 	return;
298 }
299 #endif
300 #ifdef CONFIG_POWER_SAVING
pwr_state_check_handler(void * ctx)301 void pwr_state_check_handler(void *ctx)
302 {
303 	_adapter *padapter = (_adapter *)ctx;
304 	rtw_ps_cmd(padapter);
305 }
306 #endif
307 #ifdef CONFIG_LPS
308 #ifdef CONFIG_CHECK_LEAVE_LPS
309 #ifdef CONFIG_LPS_CHK_BY_TP
traffic_check_for_leave_lps_by_tp(_adapter * padapter,u8 tx,struct sta_info * sta)310 void traffic_check_for_leave_lps_by_tp(_adapter *padapter, u8 tx, struct sta_info *sta)
311 {
312 	struct stainfo_stats *pstats = &sta->sta_stats;
313 	u64 cur_acc_tx_bytes = 0, cur_acc_rx_bytes = 0;
314 	u32 tx_tp_kbyte = 0, rx_tp_kbyte = 0;
315 	u32 tx_tp_th = 0, rx_tp_th = 0;
316 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
317 	u8	leave_lps = _FALSE;
318 
319 	if (tx) { /* from tx */
320 		cur_acc_tx_bytes = pstats->tx_bytes - pstats->acc_tx_bytes;
321 		tx_tp_kbyte = cur_acc_tx_bytes >> 10;
322 		tx_tp_th = pwrpriv->lps_tx_tp_th * 1024 / 8 * 2; /*KBytes @2s*/
323 
324 		if (tx_tp_kbyte >= tx_tp_th ||
325 			padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod >= pwrpriv->lps_tx_pkts){
326 			if (pwrpriv->bLeisurePs
327 				&& (pwrpriv->pwr_mode != PM_PS_MODE_ACTIVE)
328 			) {
329 				leave_lps = _TRUE;
330 			}
331 		}
332 
333 	} else { /* from rx path */
334 		cur_acc_rx_bytes = pstats->rx_bytes - pstats->acc_rx_bytes;
335 		rx_tp_kbyte = cur_acc_rx_bytes >> 10;
336 		rx_tp_th = pwrpriv->lps_rx_tp_th * 1024 / 8 * 2;
337 
338 		if (rx_tp_kbyte>= rx_tp_th ||
339 			padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod >= pwrpriv->lps_rx_pkts) {
340 			if (pwrpriv->bLeisurePs
341 				&& (pwrpriv->pwr_mode != PM_PS_MODE_ACTIVE)
342 			) {
343 				leave_lps = _TRUE;
344 			}
345 		}
346 	}
347 
348 	if (leave_lps) {
349 		#ifdef DBG_LPS_CHK_BY_TP
350 		RTW_INFO("leave lps via %s, ", tx ? "Tx" : "Rx");
351 		if (tx)
352 			RTW_INFO("Tx = %d [%d] (KB)\n", tx_tp_kbyte, tx_tp_th);
353 		else
354 			RTW_INFO("Rx = %d [%d] (KB)\n", rx_tp_kbyte, rx_tp_th);
355 		#endif
356 		pwrpriv->lps_chk_cnt = pwrpriv->lps_chk_cnt_th;
357 		/* rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 0); */
358 		rtw_lps_ctrl_wk_cmd(padapter, tx ? LPS_CTRL_TX_TRAFFIC_LEAVE : LPS_CTRL_RX_TRAFFIC_LEAVE, 0);
359 	}
360 }
361 #endif /*CONFIG_LPS_CHK_BY_TP*/
362 
traffic_check_for_leave_lps(_adapter * padapter,u8 tx,u32 tx_packets)363 void	traffic_check_for_leave_lps(_adapter *padapter, u8 tx, u32 tx_packets)
364 {
365 	static systime start_time = 0;
366 	static u32 xmit_cnt = 0;
367 	u8	bLeaveLPS = _FALSE;
368 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
369 
370 
371 
372 	if (tx) { /* from tx */
373 		xmit_cnt += tx_packets;
374 
375 		if (start_time == 0)
376 			start_time = rtw_get_current_time();
377 
378 		if (rtw_get_passing_time_ms(start_time) > 2000) { /* 2 sec == watch dog timer */
379 			if (xmit_cnt > 8) {
380 				if ((adapter_to_pwrctl(padapter)->bLeisurePs)
381 				    && (adapter_to_pwrctl(padapter)->pwr_mode != PM_PS_MODE_ACTIVE)
382 				   ) {
383 					/* RTW_INFO("leave lps via Tx = %d\n", xmit_cnt);			 */
384 					bLeaveLPS = _TRUE;
385 				}
386 			}
387 
388 			start_time = rtw_get_current_time();
389 			xmit_cnt = 0;
390 		}
391 
392 	} else { /* from rx path */
393 		if (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4/*2*/) {
394 			if ((adapter_to_pwrctl(padapter)->bLeisurePs)
395 			    && (adapter_to_pwrctl(padapter)->pwr_mode != PM_PS_MODE_ACTIVE)
396 			   ) {
397 				/* RTW_INFO("leave lps via Rx = %d\n", pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod);	 */
398 				bLeaveLPS = _TRUE;
399 			}
400 		}
401 	}
402 
403 	if (bLeaveLPS) {
404 		/* RTW_INFO("leave lps via %s, Tx = %d, Rx = %d\n", tx?"Tx":"Rx", pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod);	 */
405 		/* rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 0); */
406 		rtw_lps_ctrl_wk_cmd(padapter, tx ? LPS_CTRL_TX_TRAFFIC_LEAVE : LPS_CTRL_RX_TRAFFIC_LEAVE, tx ? RTW_CMDF_DIRECTLY : 0);
407 	}
408 }
409 #endif /* CONFIG_CHECK_LEAVE_LPS */
410 
411 #ifdef CONFIG_LPS_LCLK
412 #define LPS_CPWM_TIMEOUT_MS	10 /*ms*/
413 #define LPS_RPWM_RETRY_CNT		3
414 
rtw_cpwm_polling(_adapter * adapter,u8 rpwm,u8 cpwm_orig)415 u8 rtw_cpwm_polling(_adapter *adapter, u8 rpwm, u8 cpwm_orig)
416 {
417 	u8 rst = _FAIL;
418 	u8 cpwm_now = 0;
419 	systime start_time;
420 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
421 	#ifdef DBG_CHECK_FW_PS_STATE
422 	struct debug_priv *pdbgpriv = &(adapter_to_dvobj(adapter)->drv_dbg);
423 	#endif
424 
425 	pwrpriv->rpwm_retry = 0;
426 
427 	do {
428 		start_time = rtw_get_current_time();
429 		do {
430 			rtw_msleep_os(1);
431 			rtw_hal_get_hwreg(adapter, HW_VAR_CPWM, &cpwm_now);
432 
433 			if ((cpwm_orig ^ cpwm_now) & 0x80) {
434 				pwrpriv->cpwm = PS_STATE_S4;
435 				pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE;
436 				rst = _SUCCESS;
437 				break;
438 			}
439 		} while (rtw_get_passing_time_ms(start_time) < LPS_CPWM_TIMEOUT_MS && !RTW_CANNOT_RUN(adapter_to_dvobj(adapter)));
440 
441 		if (rst == _SUCCESS)
442 			break;
443 		else {
444 			/* rpwm retry */
445 			cpwm_orig = cpwm_now;
446 			rpwm &= ~PS_TOGGLE;
447 			rpwm |= pwrpriv->tog;
448 			rtw_hal_set_hwreg(adapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
449 			pwrpriv->tog += 0x80;
450 		}
451 	} while (pwrpriv->rpwm_retry++ < LPS_RPWM_RETRY_CNT && !RTW_CANNOT_RUN(adapter_to_dvobj(adapter)));
452 
453 	if (rst == _SUCCESS) {
454 		#ifdef DBG_CHECK_FW_PS_STATE
455 		RTW_INFO("%s: polling cpwm OK! rpwm_retry=%d, cpwm_orig=%02x, cpwm_now=%02x , 0x100=0x%x\n"
456 			, __func__, pwrpriv->rpwm_retry, cpwm_orig, cpwm_now, rtw_read8(adapter, REG_CR));
457 		if (rtw_fw_ps_state(adapter) == _FAIL) {
458 			RTW_INFO("leave 32k but fw state in 32k\n");
459 			pdbgpriv->dbg_rpwm_toogle_cnt++;
460 		}
461 		#endif /* DBG_CHECK_FW_PS_STATE */
462 	} else {
463 		RTW_ERR("%s: polling cpwm timeout! rpwm_retry=%d, cpwm_orig=%02x, cpwm_now=%02x\n"
464 				, __func__, pwrpriv->rpwm_retry, cpwm_orig, cpwm_now);
465 		#ifdef DBG_CHECK_FW_PS_STATE
466 		if (rtw_fw_ps_state(adapter) == _FAIL) {
467 			RTW_INFO("rpwm timeout and fw ps state in 32k\n");
468 			pdbgpriv->dbg_rpwm_timeout_fail_cnt++;
469 		}
470 		#endif /* DBG_CHECK_FW_PS_STATE */
471 
472 		#ifdef CONFIG_LPS_RPWM_TIMER
473 		_set_timer(&pwrpriv->pwr_rpwm_timer, 1);
474 		#endif /* CONFIG_LPS_RPWM_TIMER */
475 	}
476 
477 	return rst;
478 }
479 #endif
480 /*
481  * Description:
482  *	This function MUST be called under power lock protect
483  *
484  * Parameters
485  *	padapter
486  *	pslv			power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
487  *
488  */
rtw_set_rpwm(_adapter * padapter,u8 pslv)489 u8 rtw_set_rpwm(_adapter *padapter, u8 pslv)
490 {
491 	u8	rpwm = 0xFF;
492 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
493 #ifdef CONFIG_LPS_LCLK
494 	u8 cpwm_orig;
495 #endif
496 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
497 
498 	pslv = PS_STATE(pslv);
499 
500 #ifdef CONFIG_LPS_RPWM_TIMER
501 	if (pwrpriv->brpwmtimeout == _TRUE)
502 		RTW_INFO("%s: RPWM timeout, force to set RPWM(0x%02X) again!\n", __FUNCTION__, pslv);
503 	else
504 #endif /* CONFIG_LPS_RPWM_TIMER */
505 	{
506 		if ((pwrpriv->rpwm == pslv)
507 #ifdef CONFIG_LPS_LCLK
508 		    || ((pwrpriv->rpwm >= PS_STATE_S2) && (pslv >= PS_STATE_S2))
509 #endif
510 			|| (pwrpriv->lps_level == LPS_NORMAL)
511 		   ) {
512 			return rpwm;
513 		}
514 	}
515 
516 	if (dev_is_surprise_removed(dvobj) ||
517 	    (!rtw_hw_is_init_completed(dvobj))) {
518 
519 		pwrpriv->cpwm = PS_STATE_S4;
520 
521 		return rpwm;
522 	}
523 
524 	if (dev_is_drv_stopped(dvobj))
525 		if (pslv < PS_STATE_S2)
526 			return rpwm;
527 
528 	rpwm = pslv | pwrpriv->tog;
529 #ifdef CONFIG_LPS_LCLK
530 	/* only when from PS_STATE S0/S1 to S2 and higher needs ACK */
531 	if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2))
532 		rpwm |= PS_ACK;
533 #endif
534 
535 	pwrpriv->rpwm = pslv;
536 
537 #ifdef CONFIG_LPS_LCLK
538 	cpwm_orig = 0;
539 	if (rpwm & PS_ACK)
540 		rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
541 #endif
542 
543 #if defined(CONFIG_LPS_RPWM_TIMER) && !defined(CONFIG_DETECT_CPWM_BY_POLLING)
544 	if (rpwm & PS_ACK) {
545 		#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN)
546 		if (pwrpriv->wowlan_mode != _TRUE &&
547 			pwrpriv->wowlan_ap_mode != _TRUE &&
548 			pwrpriv->wowlan_p2p_mode != _TRUE)
549 		#endif
550 		_set_timer(&pwrpriv->pwr_rpwm_timer, LPS_CPWM_TIMEOUT_MS);
551 	}
552 #endif /* CONFIG_LPS_RPWM_TIMER & !CONFIG_DETECT_CPWM_BY_POLLING */
553 
554 	rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
555 
556 	pwrpriv->tog += 0x80;
557 
558 #ifdef CONFIG_LPS_LCLK
559 	/* No LPS 32K, No Ack */
560 	if (rpwm & PS_ACK) {
561 		#ifdef CONFIG_DETECT_CPWM_BY_POLLING
562 		rtw_cpwm_polling(padapter, rpwm, cpwm_orig);
563 		#else
564 		#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN)
565 		if (pwrpriv->wowlan_mode == _TRUE ||
566 			pwrpriv->wowlan_ap_mode == _TRUE ||
567 			pwrpriv->wowlan_p2p_mode == _TRUE)
568 				rtw_cpwm_polling(padapter, rpwm, cpwm_orig);
569 		#endif /*#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN)*/
570 		#endif /*#ifdef CONFIG_DETECT_CPWM_BY_POLLING*/
571 	} else
572 #endif /* CONFIG_LPS_LCLK */
573 	{
574 		pwrpriv->cpwm = pslv;
575 	}
576 
577 	return rpwm;
578 }
579 
PS_RDY_CHECK(_adapter * padapter)580 u8 PS_RDY_CHECK(_adapter *padapter)
581 {
582 	struct pwrctrl_priv	*pwrpriv = adapter_to_pwrctl(padapter);
583 	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
584 
585 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
586 	if (_TRUE == pwrpriv->bInSuspend && pwrpriv->wowlan_mode)
587 		return _TRUE;
588 	else if (_TRUE == pwrpriv->bInSuspend && pwrpriv->wowlan_ap_mode)
589 		return _TRUE;
590 	else if (_TRUE == pwrpriv->bInSuspend)
591 		return _FALSE;
592 #else
593 	if (_TRUE == pwrpriv->bInSuspend)
594 		return _FALSE;
595 #endif
596 
597 	if (rtw_time_after(pwrpriv->lps_deny_time, rtw_get_current_time()))
598 		return _FALSE;
599 
600 	if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)
601 		|| check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)
602 		|| MLME_IS_AP(padapter)
603 		|| MLME_IS_MESH(padapter)
604 		|| MLME_IS_MONITOR(padapter)
605 		|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)
606 		#if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
607 		|| rtw_cfg80211_get_is_roch(padapter) == _TRUE
608 		#endif
609 		|| rtw_is_scan_deny(padapter)
610 		#ifdef CONFIG_TDLS
611 		/* TDLS link is established. */
612 		|| (padapter->tdlsinfo.link_established == _TRUE)
613 		#endif /* CONFIG_TDLS		 */
614 		#ifdef CONFIG_DFS_MASTER
615 		|| adapter_to_rfctl(padapter)->radar_detect_enabled
616 		#endif
617 	)
618 		return _FALSE;
619 
620 	if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == _FALSE)) {
621 		RTW_INFO("Group handshake still in progress !!!\n");
622 		return _FALSE;
623 	}
624 
625 #ifdef CONFIG_IOCTL_CFG80211
626 	if (!rtw_cfg80211_pwr_mgmt(padapter))
627 		return _FALSE;
628 #endif
629 
630 	return _TRUE;
631 }
632 
rtw_leave_lps_and_chk(_adapter * padapter,u8 ps_mode)633 void rtw_leave_lps_and_chk(_adapter *padapter, u8 ps_mode)
634 {
635 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
636 
637 #ifdef CONFIG_LPS_ACK
638 			_rtw_mutex_lock_interruptible(&pwrpriv->lps_ack_mutex);
639 			rtw_sctx_init(&pwrpriv->lps_ack_sctx, 100);
640 #endif /* CONFIG_LPS_ACK */
641 			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
642 			rtw_hal_set_hwreg(padapter, HW_VAR_LPS_STATE_CHK, (u8 *)(&ps_mode));
643 
644 #ifdef CONFIG_LPS_ACK
645 			_rtw_mutex_unlock(&pwrpriv->lps_ack_mutex);
646 #endif /* CONFIG_LPS_ACK */
647 
648 }
649 
rtw_set_ps_mode(_adapter * padapter,u8 ps_mode,u8 smart_ps,u8 bcn_ant_mode,const char * msg)650 void rtw_set_ps_mode(_adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg)
651 {
652 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
653 	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
654 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN)
655 	struct dvobj_priv *psdpriv = padapter->dvobj;
656 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
657 #endif
658 #ifdef CONFIG_WMMPS_STA
659 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
660 #endif
661 #ifdef CONFIG_P2P
662 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
663 #endif /* CONFIG_P2P */
664 #ifdef CONFIG_TDLS
665 	struct sta_priv *pstapriv = &padapter->stapriv;
666 	int i, j;
667 	_list	*plist, *phead;
668 	struct sta_info *ptdls_sta;
669 #endif /* CONFIG_TDLS */
670 #ifdef CONFIG_LPS_PG
671 	u8 lps_pg_hdl_id = 0;
672 #endif
673 
674 
675 
676 	if (ps_mode > PM_CARD_DISABLE) {
677 		return;
678 	}
679 
680 	if (pwrpriv->pwr_mode == ps_mode) {
681 		if (PM_PS_MODE_ACTIVE == ps_mode)
682 			return;
683 
684 #ifndef CONFIG_BTC
685 #ifdef CONFIG_WMMPS_STA
686 		if (!rtw_is_wmmps_mode(padapter))
687 #endif /* CONFIG_WMMPS_STA */
688 			if ((pwrpriv->smart_ps == smart_ps) &&
689 			    (pwrpriv->bcn_ant_mode == bcn_ant_mode))
690 				return;
691 #endif /* !CONFIG_BTC */
692 	}
693 
694 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
695 	if (PM_PS_MODE_ACTIVE != ps_mode) {
696 		rtw_set_ps_rsvd_page(padapter);
697 		rtw_set_default_port_id(padapter);
698 	}
699 #endif
700 
701 #ifdef CONFIG_LPS_PG
702 	if ((PM_PS_MODE_ACTIVE != ps_mode) && (pwrpriv->lps_level == LPS_PG)) {
703 		if (pwrpriv->wowlan_mode != _TRUE) {
704 				/*rtw_hal_set_lps_pg_info(padapter);*/
705 				lps_pg_hdl_id = LPS_PG_INFO_CFG;
706 				rtw_hal_set_hwreg(padapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
707 		}
708 	}
709 #endif
710 
711 #ifdef CONFIG_LPS_LCLK
712 	_enter_pwrlock(&pwrpriv->lock);
713 #endif
714 
715 	/* if(pwrpriv->pwr_mode == PM_PS_MODE_ACTIVE) */
716 	if (ps_mode == PM_PS_MODE_ACTIVE) {
717 		if (1
718 #ifdef CONFIG_P2P_PS
719 			 && (pwdinfo->opp_ps == 0)
720 #endif /* CONFIG_P2P_PS */
721 		   ) {
722 			RTW_INFO(FUNC_ADPT_FMT" Leave 802.11 power save - %s\n",
723 				 FUNC_ADPT_ARG(padapter), msg);
724 
725 			if (pwrpriv->lps_leave_cnts < UINT_MAX)
726 				pwrpriv->lps_leave_cnts++;
727 			else
728 				pwrpriv->lps_leave_cnts = 0;
729 #ifdef CONFIG_TDLS
730 			for (i = 0; i < NUM_STA; i++) {
731 				phead = &(pstapriv->sta_hash[i]);
732 				plist = get_next(phead);
733 
734 				while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
735 					ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
736 
737 					if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)
738 						issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->phl_sta->mac_addr, 0, 0, 0);
739 					plist = get_next(plist);
740 				}
741 			}
742 #endif /* CONFIG_TDLS */
743 
744 			pwrpriv->pwr_mode = ps_mode;
745 			rtw_set_rpwm(padapter, PS_STATE_S4);
746 
747 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN)
748 			if (pwrpriv->wowlan_mode == _TRUE ||
749 			    pwrpriv->wowlan_ap_mode == _TRUE ||
750 			    pwrpriv->wowlan_p2p_mode == _TRUE) {
751 				systime start_time;
752 				u32 delay_ms;
753 				u8 val8;
754 				delay_ms = 20;
755 				start_time = rtw_get_current_time();
756 				do {
757 					rtw_hal_get_hwreg(padapter, HW_VAR_SYS_CLKR, &val8);
758 					if (!(val8 & BIT(4))) { /* 0x08 bit4 =1 --> in 32k, bit4 = 0 --> leave 32k */
759 						pwrpriv->cpwm = PS_STATE_S4;
760 						break;
761 					}
762 					if (rtw_get_passing_time_ms(start_time) > delay_ms) {
763 						RTW_INFO("%s: Wait for FW 32K leave more than %u ms!!!\n",
764 							__FUNCTION__, delay_ms);
765 						pdbgpriv->dbg_wow_leave_ps_fail_cnt++;
766 						break;
767 					}
768 					rtw_usleep_os(100);
769 				} while (1);
770 			}
771 #endif
772 #ifdef CONFIG_LPS_PG
773 			if (pwrpriv->lps_level == LPS_PG) {
774 				lps_pg_hdl_id = LPS_PG_REDLEMEM;
775 				rtw_hal_set_hwreg(padapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
776 			}
777 #endif
778 #ifdef CONFIG_WOWLAN
779 			if (pwrpriv->wowlan_mode == _TRUE)
780 				rtw_hal_set_hwreg(padapter, HW_VAR_H2C_INACTIVE_IPS, (u8 *)(&ps_mode));
781 #endif /* CONFIG_WOWLAN */
782 
783 			rtw_leave_lps_and_chk(padapter, ps_mode);
784 
785 #ifdef CONFIG_LPS_PG
786 			if (pwrpriv->lps_level == LPS_PG) {
787 				lps_pg_hdl_id = LPS_PG_PHYDM_EN;
788 				rtw_hal_set_hwreg(padapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
789 			}
790 #endif
791 
792 			pwrpriv->bFwCurrentInPSMode = _FALSE;
793 		}
794 	} else {
795 		if ((PS_RDY_CHECK(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE))
796 #ifdef CONFIG_P2P_WOWLAN
797 		    || (_TRUE == pwrpriv->wowlan_p2p_mode)
798 #endif /* CONFIG_P2P_WOWLAN */
799 #ifdef CONFIG_WOWLAN
800 			|| WOWLAN_IS_STA_MIX_MODE(padapter)
801 #endif /* CONFIG_WOWLAN */
802 		   ) {
803 			u8 pslv;
804 
805 			RTW_INFO(FUNC_ADPT_FMT" Enter 802.11 power save - %s\n",
806 				 FUNC_ADPT_ARG(padapter), msg);
807 
808 			if (pwrpriv->lps_enter_cnts < UINT_MAX)
809 				pwrpriv->lps_enter_cnts++;
810 			else
811 				pwrpriv->lps_enter_cnts = 0;
812 #ifdef CONFIG_TDLS
813 			for (i = 0; i < NUM_STA; i++) {
814 				phead = &(pstapriv->sta_hash[i]);
815 				plist = get_next(phead);
816 
817 				while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
818 					ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
819 
820 					if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)
821 						issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->phl_sta->mac_addr, 1, 0, 0);
822 					plist = get_next(plist);
823 				}
824 			}
825 #endif /* CONFIG_TDLS */
826 
827 			pwrpriv->bFwCurrentInPSMode = _TRUE;
828 			pwrpriv->pwr_mode = ps_mode;
829 			pwrpriv->smart_ps = smart_ps;
830 			pwrpriv->bcn_ant_mode = bcn_ant_mode;
831 #ifdef CONFIG_LPS_PG
832 			if (pwrpriv->lps_level == LPS_PG) {
833 				lps_pg_hdl_id = LPS_PG_PHYDM_DIS;
834 				rtw_hal_set_hwreg(padapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
835 			}
836 #endif
837 
838 #ifdef CONFIG_WMMPS_STA
839 			pwrpriv->wmm_smart_ps = pregistrypriv->wmm_smart_ps;
840 #endif /* CONFIG_WMMPS_STA */
841 
842 
843 			if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
844 				rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
845 #ifdef CONFIG_WOWLAN
846 			if (pwrpriv->wowlan_mode == _TRUE)
847 				rtw_hal_set_hwreg(padapter, HW_VAR_H2C_INACTIVE_IPS, (u8 *)(&ps_mode));
848 #endif /* CONFIG_WOWLAN */
849 
850 #ifdef CONFIG_P2P_PS
851 			/* Set CTWindow after LPS */
852 			if (pwdinfo->opp_ps == 1)
853 				p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
854 #endif /* CONFIG_P2P_PS */
855 
856 			pslv = PS_STATE_S2;
857 #ifdef CONFIG_LPS_LCLK
858 			if (pwrpriv->alives == 0)
859 				pslv = PS_STATE_S0;
860 #endif /* CONFIG_LPS_LCLK */
861 
862 			rtw_set_rpwm(padapter, pslv);
863 		}
864 	}
865 
866 #ifdef CONFIG_LPS_LCLK
867 	_exit_pwrlock(&pwrpriv->lock);
868 #endif
869 
870 }
871 
872 const char * const LPS_CTRL_PHYDM = "LPS_CTRL_PHYDM";
873 
874 /*
875  *	Description:
876  *		Enter the leisure power save mode.
877  *   */
LPS_Enter(_adapter * padapter,const char * msg)878 void LPS_Enter(_adapter *padapter, const char *msg)
879 {
880 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
881 	struct pwrctrl_priv	*pwrpriv = dvobj_to_pwrctl(dvobj);
882 	int i;
883 	char buf[32] = {0};
884 #ifdef DBG_LA_MODE
885 	struct registry_priv *registry_par = &(padapter->registrypriv);
886 #endif
887 
888 	/*	RTW_INFO("+LeisurePSEnter\n"); */
889 #if 0 /*GEORGIA_TODO_FIXIT*/
890 	if (GET_PHL_COM(dvobj)->fw_ready == _FALSE)
891 		return;
892 #endif
893 
894 #ifdef DBG_LA_MODE
895 	if(registry_par->la_mode_en == 1) {
896 		RTW_INFO("%s LA debug mode lps_leave \n", __func__);
897 		return;
898 	}
899 #endif
900 	/* Skip lps enter request if number of assocated adapters is not 1 */
901 	if (rtw_mi_get_assoc_if_num(padapter) != 1)
902 		return;
903 
904 #ifndef CONFIG_FW_MULTI_PORT_SUPPORT
905 	/* Skip lps enter request for adapter not port0 */
906 	if (get_hw_port(padapter) != HW_PORT0)
907 		return;
908 #endif
909 
910 	for (i = 0; i < dvobj->iface_nums; i++) {
911 		if (PS_RDY_CHECK(dvobj->padapters[i]) == _FALSE)
912 			return;
913 	}
914 
915 
916 #ifdef CONFIG_P2P_PS
917 	if (padapter->wdinfo.p2p_ps_mode == P2P_PS_NOA) {
918 		return;/* supporting p2p client ps NOA via H2C_8723B_P2P_PS_OFFLOAD */
919 	}
920 #endif /* CONFIG_P2P_PS */
921 
922 	if (pwrpriv->bLeisurePs) {
923 		/* Idle for a while if we connect to AP a while ago. */
924 		if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */
925 			if (pwrpriv->pwr_mode == PM_PS_MODE_ACTIVE) {
926 
927 #ifdef CONFIG_WMMPS_STA
928 				if (rtw_is_wmmps_mode(padapter))
929 					msg = "WMMPS_IDLE";
930 #endif /* CONFIG_WMMPS_STA */
931 
932 				sprintf(buf, "WIFI-%s", msg);
933 				pwrpriv->bpower_saving = _TRUE;
934 
935 #ifdef CONFIG_RTW_CFGVENDOR_LLSTATS
936 				pwrpriv->pwr_saving_start_time = rtw_get_current_time();
937 #endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */
938 
939 				rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, padapter->registrypriv.smart_ps, 0, buf);
940 
941 #ifdef CONFIG_PCI_DYNAMIC_ASPM
942 				if (msg != LPS_CTRL_PHYDM)
943 					rtw_pci_dynamic_aspm_set_mode(padapter, ASPM_MODE_PS);
944 #endif
945 			}
946 		} else
947 			pwrpriv->LpsIdleCount++;
948 	}
949 
950 	/*	RTW_INFO("-LeisurePSEnter\n"); */
951 
952 }
953 
954 /*
955  *	Description:
956  *		Leave the leisure power save mode.
957  *   */
LPS_Leave(_adapter * padapter,const char * msg)958 void LPS_Leave(_adapter *padapter, const char *msg)
959 {
960 #define LPS_LEAVE_TIMEOUT_MS 100
961 
962 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
963 	struct pwrctrl_priv	*pwrpriv = dvobj_to_pwrctl(dvobj);
964 	char buf[32] = {0};
965 #ifdef DBG_CHECK_FW_PS_STATE
966 	struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
967 #endif
968 
969 
970 	/*	RTW_INFO("+LeisurePSLeave\n"); */
971 
972 	if (pwrpriv->bLeisurePs) {
973 		if (pwrpriv->pwr_mode != PM_PS_MODE_ACTIVE) {
974 #ifdef CONFIG_PCI_DYNAMIC_ASPM
975 			if (msg != LPS_CTRL_PHYDM)
976 				rtw_pci_dynamic_aspm_set_mode(padapter, ASPM_MODE_PERF);
977 #endif
978 #ifdef CONFIG_WMMPS_STA
979 			if (rtw_is_wmmps_mode(padapter))
980 				msg = "WMMPS_BUSY";
981 #endif /* CONFIG_WMMPS_STA */
982 
983 			sprintf(buf, "WIFI-%s", msg);
984 			rtw_set_ps_mode(padapter, PM_PS_MODE_ACTIVE, 0, 0, buf);
985 
986 #ifdef CONFIG_RTW_CFGVENDOR_LLSTATS
987 			pwrpriv->pwr_saving_time += rtw_get_passing_time_ms(pwrpriv->pwr_saving_start_time);
988 #endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */
989 		}
990 	}
991 
992 	pwrpriv->bpower_saving = _FALSE;
993 #ifdef DBG_CHECK_FW_PS_STATE
994 	if (rtw_fw_ps_state(padapter) == _FAIL) {
995 		RTW_INFO("leave lps, fw in 32k\n");
996 		pdbgpriv->dbg_leave_lps_fail_cnt++;
997 	}
998 #endif /* DBG_CHECK_FW_PS_STATE
999  * 	RTW_INFO("-LeisurePSLeave\n"); */
1000 
1001 }
1002 
1003 #endif /* CONFIG_LPS */
1004 
LeaveAllPowerSaveModeDirect(_adapter * adapter)1005 void LeaveAllPowerSaveModeDirect(_adapter *adapter)
1006 {
1007 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1008 	_adapter *pri_padapter = GET_PRIMARY_ADAPTER(adapter);
1009 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
1010 
1011 #ifdef CONFIG_LPS_LCLK
1012 #ifndef CONFIG_DETECT_CPWM_BY_POLLING
1013 	u8 cpwm_orig;
1014 #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
1015 	u8 rpwm;
1016 #endif
1017 	int i;
1018 
1019 	RTW_INFO("%s.....\n", __FUNCTION__);
1020 
1021 	if (dev_is_surprise_removed(adapter_to_dvobj(adapter))) {
1022 		RTW_INFO(FUNC_ADPT_FMT ": bSurpriseRemoved=_TRUE Skip!\n", FUNC_ADPT_ARG(adapter));
1023 		return;
1024 	}
1025 
1026 	if (rtw_mi_check_status(adapter, MI_LINKED)) { /*connect*/
1027 
1028 		if (pwrpriv->pwr_mode == PM_PS_MODE_ACTIVE) {
1029 			RTW_INFO("%s: Driver Already Leave LPS\n", __FUNCTION__);
1030 			return;
1031 		}
1032 
1033 #ifdef CONFIG_LPS_LCLK
1034 		_enter_pwrlock(&pwrpriv->lock);
1035 
1036 #ifndef CONFIG_DETECT_CPWM_BY_POLLING
1037 		cpwm_orig = 0;
1038 		rtw_hal_get_hwreg(adapter, HW_VAR_CPWM, &cpwm_orig);
1039 #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
1040 		rpwm = rtw_set_rpwm(adapter, PS_STATE_S4);
1041 
1042 #ifndef CONFIG_DETECT_CPWM_BY_POLLING
1043 		if (rpwm != 0xFF && rpwm & PS_ACK)
1044 			rtw_cpwm_polling(adapter, rpwm, cpwm_orig);
1045 #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
1046 
1047 		_exit_pwrlock(&pwrpriv->lock);
1048 #endif/*CONFIG_LPS_LCLK*/
1049 
1050 #ifdef CONFIG_P2P_PS
1051 		for (i = 0; i < dvobj->iface_nums; i++) {
1052 			_adapter *iface = dvobj->padapters[i];
1053 			struct wifidirect_info *pwdinfo = &(iface->wdinfo);
1054 
1055 			if (pwdinfo->p2p_ps_mode > P2P_PS_NONE)
1056 				p2p_ps_wk_cmd(iface, P2P_PS_DISABLE, 0);
1057 		}
1058 #endif /* CONFIG_P2P_PS */
1059 
1060 #ifdef CONFIG_LPS
1061 		rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, RTW_CMDF_DIRECTLY);
1062 #endif
1063 	} else {
1064 		if (pwrpriv->rf_pwrstate == rf_off) {
1065 
1066 #if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS)
1067 #ifdef CONFIG_IPS
1068 			if (_FALSE == ips_leave(pri_padapter))
1069 				RTW_INFO("======> ips_leave fail.............\n");
1070 #endif
1071 #endif /* defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) */
1072 
1073 		}
1074 	}
1075 
1076 }
1077 
1078 /*
1079  * Description: Leave all power save mode: LPS, FwLPS, IPS if needed.
1080  * Move code to function by tynli. 2010.03.26.
1081  *   */
LeaveAllPowerSaveMode(_adapter * adapter)1082 void LeaveAllPowerSaveMode(_adapter *adapter)
1083 {
1084 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1085 	u8	enqueue = 0;
1086 	int i;
1087 
1088 
1089 /*	RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));*/
1090 
1091 	if (dev_is_surprise_removed(adapter_to_dvobj(adapter))) {
1092 		RTW_INFO(FUNC_ADPT_FMT ": bSurpriseRemoved=_TRUE Skip!\n", FUNC_ADPT_ARG(adapter));
1093 		return;
1094 	}
1095 
1096 	if (rtw_mi_get_assoc_if_num(adapter)) {
1097 		/* connect */
1098 #ifdef CONFIG_LPS_LCLK
1099 		enqueue = 1;
1100 #endif
1101 
1102 #ifdef CONFIG_P2P_PS
1103 		for (i = 0; i < dvobj->iface_nums; i++) {
1104 			_adapter *iface = dvobj->padapters[i];
1105 			struct wifidirect_info *pwdinfo = &(iface->wdinfo);
1106 
1107 			if (pwdinfo->p2p_ps_mode > P2P_PS_NONE)
1108 				p2p_ps_wk_cmd(iface, P2P_PS_DISABLE, enqueue);
1109 		}
1110 #endif /* CONFIG_P2P_PS */
1111 
1112 #ifdef CONFIG_LPS
1113 		rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_LEAVE, enqueue ? 0 : RTW_CMDF_DIRECTLY);
1114 #endif
1115 
1116 #ifdef CONFIG_LPS_LCLK
1117 		LPS_Leave_check(adapter);
1118 #endif
1119 	} else {
1120 		if (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off) {
1121 
1122 #if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS)
1123 #ifdef CONFIG_IPS
1124 			if (_FALSE == ips_leave(adapter))
1125 				RTW_INFO("======> ips_leave fail.............\n");
1126 #endif
1127 #endif /* defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) */
1128 
1129 		}
1130 	}
1131 
1132 }
1133 
1134 #ifdef CONFIG_LPS_LCLK
LPS_Leave_check(_adapter * padapter)1135 void LPS_Leave_check(
1136 	_adapter *padapter)
1137 {
1138 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1139 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1140 	systime	start_time;
1141 	u8	bReady;
1142 
1143 	bReady = _FALSE;
1144 	start_time = rtw_get_current_time();
1145 
1146 	rtw_yield_os();
1147 
1148 	while (1) {
1149 		_enter_pwrlock(&pwrpriv->lock);
1150 
1151 		if (dev_is_surprise_removed(dvobj)
1152 		    || (!rtw_hw_is_init_completed(dvobj))
1153 #ifdef CONFIG_USB_HCI
1154 		    || dev_is_drv_stopped(dvobj)
1155 #endif
1156 		    || (pwrpriv->pwr_mode == PM_PS_MODE_ACTIVE)
1157 		   )
1158 			bReady = _TRUE;
1159 
1160 		_exit_pwrlock(&pwrpriv->lock);
1161 
1162 		if (_TRUE == bReady)
1163 			break;
1164 
1165 		if (rtw_get_passing_time_ms(start_time) > 100) {
1166 			RTW_ERR("Wait for cpwm event  than 100 ms!!!\n");
1167 			break;
1168 		}
1169 		rtw_msleep_os(1);
1170 	}
1171 
1172 }
1173 
1174 /*
1175  * Caller:ISR handler...
1176  *
1177  * This will be called when CPWM interrupt is up.
1178  *
1179  * using to update cpwn of drv; and drv willl make a decision to up or down pwr level
1180  */
cpwm_int_hdl(_adapter * padapter,struct reportpwrstate_parm * preportpwrstate)1181 void cpwm_int_hdl(
1182 	_adapter *padapter,
1183 	struct reportpwrstate_parm *preportpwrstate)
1184 {
1185 	struct pwrctrl_priv *pwrpriv;
1186 
1187 	if (!padapter)
1188 		goto exit;
1189 
1190 	if (RTW_CANNOT_RUN(adapter_to_dvobj(padapter)))
1191 		goto exit;
1192 
1193 	pwrpriv = adapter_to_pwrctl(padapter);
1194 #if 0
1195 	if (pwrpriv->cpwm_tog == (preportpwrstate->state & PS_TOGGLE)) {
1196 		goto exit;
1197 	}
1198 #endif
1199 
1200 	_enter_pwrlock(&pwrpriv->lock);
1201 
1202 #ifdef CONFIG_LPS_RPWM_TIMER
1203 	if (pwrpriv->rpwm < PS_STATE_S2) {
1204 		RTW_INFO("%s: Redundant CPWM Int. RPWM=0x%02X CPWM=0x%02x\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
1205 		_exit_pwrlock(&pwrpriv->lock);
1206 		goto exit;
1207 	}
1208 #endif /* CONFIG_LPS_RPWM_TIMER */
1209 
1210 	pwrpriv->cpwm = PS_STATE(preportpwrstate->state);
1211 	pwrpriv->cpwm_tog = preportpwrstate->state & PS_TOGGLE;
1212 
1213 	if (pwrpriv->cpwm >= PS_STATE_S2) {
1214 		#if 0 /*#ifdef CONFIG_CORE_CMD_THREAD*/
1215 		if (pwrpriv->alives & CMD_ALIVE)
1216 			_rtw_up_sema(&padapter->cmdpriv.cmd_queue_sema);
1217 		#endif
1218 		#if 0 /*def CONFIG_XMIT_THREAD_MODE*/
1219 		if (pwrpriv->alives & XMIT_ALIVE)
1220 			_rtw_up_sema(&padapter->xmitpriv.xmit_sema);
1221 		#endif
1222 	}
1223 
1224 	_exit_pwrlock(&pwrpriv->lock);
1225 
1226 exit:
1227 	return;
1228 }
1229 
cpwm_event_callback(struct work_struct * work)1230 static void cpwm_event_callback(struct work_struct *work)
1231 {
1232 	struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event);
1233 	struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
1234 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
1235 	struct reportpwrstate_parm report;
1236 
1237 	/* RTW_INFO("%s\n",__FUNCTION__); */
1238 
1239 	report.state = PS_STATE_S2;
1240 	cpwm_int_hdl(adapter, &report);
1241 }
1242 
dma_event_callback(struct work_struct * work)1243 static void dma_event_callback(struct work_struct *work)
1244 {
1245 	struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, dma_event);
1246 	struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
1247 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
1248 
1249 	rtw_unregister_tx_alive(adapter);
1250 }
1251 
1252 #ifdef CONFIG_LPS_RPWM_TIMER
1253 
1254 #if defined(DBG_CPWM_CHK_FAIL)
1255 extern void rtw_cpwm_chk_fail_debug(_adapter *padapter, struct pwrctrl_priv *pwrpriv);
1256 #endif
1257 
rpwmtimeout_workitem_callback(struct work_struct * work)1258 static void rpwmtimeout_workitem_callback(struct work_struct *work)
1259 {
1260 	_adapter *padapter;
1261 	struct dvobj_priv *dvobj;
1262 	struct pwrctrl_priv *pwrpriv;
1263 
1264 
1265 	pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi);
1266 	dvobj = pwrctl_to_dvobj(pwrpriv);
1267 	padapter = dvobj_get_primary_adapter(dvobj);
1268 
1269 	if (!padapter)
1270 		return;
1271 
1272 	if (RTW_CANNOT_RUN(dvobj))
1273 		return;
1274 
1275 	_enter_pwrlock(&pwrpriv->lock);
1276 	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
1277 		RTW_INFO("%s: rpwm=0x%02X cpwm=0x%02X CPWM done!\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
1278 		goto exit;
1279 	}
1280 
1281 	if (pwrpriv->rpwm_retry++ < LPS_RPWM_RETRY_CNT) {
1282 		u8 rpwm = (pwrpriv->rpwm | pwrpriv->tog | PS_ACK);
1283 
1284 		rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
1285 
1286 		pwrpriv->tog += 0x80;
1287 		_set_timer(&pwrpriv->pwr_rpwm_timer, LPS_CPWM_TIMEOUT_MS);
1288 		goto exit;
1289 	}
1290 
1291 	pwrpriv->rpwm_retry = 0;
1292 	_exit_pwrlock(&pwrpriv->lock);
1293 
1294 #if defined(DBG_CPWM_CHK_FAIL)
1295 	rtw_cpwm_chk_fail_debug(padapter, pwrpriv);
1296 #endif
1297 
1298 #if 0 /*GEORGIA_TODO_REDEFINE_IO*/
1299 	if (rtw_read8(padapter, 0x100) != 0xEA)
1300 #else
1301 	if (!rtw_hal_is_leave_ps(padapter))
1302 #endif
1303 
1304 	{
1305 #if 1
1306 		struct reportpwrstate_parm report;
1307 
1308 		report.state = PS_STATE_S2;
1309 		RTW_INFO("\n%s: FW already leave 32K!\n\n", __func__);
1310 		cpwm_int_hdl(padapter, &report);
1311 #else
1312 		RTW_INFO("\n%s: FW already leave 32K!\n\n", __func__);
1313 		cpwm_event_callback(&pwrpriv->cpwm_event);
1314 #endif
1315 		return;
1316 	}
1317 
1318 	_enter_pwrlock(&pwrpriv->lock);
1319 
1320 	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
1321 		RTW_INFO("%s: cpwm=%d, nothing to do!\n", __func__, pwrpriv->cpwm);
1322 		goto exit;
1323 	}
1324 	pwrpriv->brpwmtimeout = _TRUE;
1325 	rtw_set_rpwm(padapter, pwrpriv->rpwm);
1326 	pwrpriv->brpwmtimeout = _FALSE;
1327 
1328 exit:
1329 	_exit_pwrlock(&pwrpriv->lock);
1330 }
1331 
1332 /*
1333  * This function is a timer handler, can't do any IO in it.
1334  */
pwr_rpwm_timeout_handler(void * FunctionContext)1335 static void pwr_rpwm_timeout_handler(void *FunctionContext)
1336 {
1337 	_adapter *padapter;
1338 	struct pwrctrl_priv *pwrpriv;
1339 
1340 	padapter = (_adapter *)FunctionContext;
1341 	if (!padapter)
1342 		return;
1343 
1344 	pwrpriv = adapter_to_pwrctl(padapter);
1345 
1346 	if (RTW_CANNOT_RUN(adapter_to_dvobj(padapter)))
1347 		return;
1348 
1349 	RTW_INFO("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
1350 
1351 	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
1352 		RTW_INFO("+%s: cpwm=%d, nothing to do!\n", __func__, pwrpriv->cpwm);
1353 		return;
1354 	}
1355 
1356 	_set_workitem(&pwrpriv->rpwmtimeoutwi);
1357 }
1358 #endif /* CONFIG_LPS_RPWM_TIMER */
1359 
register_task_alive(struct pwrctrl_priv * pwrctrl,u32 tag)1360 __inline static void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
1361 {
1362 	pwrctrl->alives |= tag;
1363 }
1364 
unregister_task_alive(struct pwrctrl_priv * pwrctrl,u32 tag)1365 __inline static void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
1366 {
1367 	pwrctrl->alives &= ~tag;
1368 }
1369 
1370 
1371 /*
1372  * Description:
1373  *	Check if the fw_pwrstate is okay for I/O.
1374  *	If not (cpwm is less than S2), then the sub-routine
1375  *	will raise the cpwm to be greater than or equal to S2.
1376  *
1377  *	Calling Context: Passive
1378  *
1379  *	Constraint:
1380  *		1. this function will request pwrctrl->lock
1381  *
1382  * Return Value:
1383  *	_SUCCESS	hardware is ready for I/O
1384  *	_FAIL		can't I/O right now
1385  */
rtw_register_task_alive(_adapter * padapter,u32 task)1386 s32 rtw_register_task_alive(_adapter *padapter, u32 task)
1387 {
1388 	s32 res;
1389 	struct pwrctrl_priv *pwrctrl;
1390 	u8 pslv;
1391 
1392 
1393 	res = _SUCCESS;
1394 	pwrctrl = adapter_to_pwrctl(padapter);
1395 	pslv = PS_STATE_S2;
1396 
1397 	_enter_pwrlock(&pwrctrl->lock);
1398 
1399 	register_task_alive(pwrctrl, task);
1400 
1401 	if (pwrctrl->bFwCurrentInPSMode == _TRUE) {
1402 
1403 		if (pwrctrl->cpwm < pslv) {
1404 			if (pwrctrl->cpwm < PS_STATE_S2)
1405 				res = _FAIL;
1406 			if (pwrctrl->rpwm < pslv)
1407 				rtw_set_rpwm(padapter, pslv);
1408 		}
1409 	}
1410 
1411 	_exit_pwrlock(&pwrctrl->lock);
1412 
1413 #ifdef CONFIG_DETECT_CPWM_BY_POLLING
1414 	if (_FAIL == res) {
1415 		if (pwrctrl->cpwm >= PS_STATE_S2)
1416 			res = _SUCCESS;
1417 	}
1418 #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
1419 
1420 
1421 	return res;
1422 }
1423 
1424 /*
1425  * Description:
1426  *	If task is done, call this func. to power down firmware again.
1427  *
1428  *	Constraint:
1429  *		1. this function will request pwrctrl->lock
1430  *
1431  * Return Value:
1432  *	none
1433  */
rtw_unregister_task_alive(_adapter * padapter,u32 task)1434 void rtw_unregister_task_alive(_adapter *padapter, u32 task)
1435 {
1436 	struct pwrctrl_priv *pwrctrl;
1437 	u8 pslv;
1438 
1439 
1440 	pwrctrl = adapter_to_pwrctl(padapter);
1441 	pslv = PS_STATE_S0;
1442 
1443 	_enter_pwrlock(&pwrctrl->lock);
1444 
1445 	unregister_task_alive(pwrctrl, task);
1446 
1447 	if ((pwrctrl->pwr_mode != PM_PS_MODE_ACTIVE)
1448 	    && (pwrctrl->bFwCurrentInPSMode == _TRUE)) {
1449 
1450 		if (pwrctrl->cpwm > pslv) {
1451 			if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
1452 				rtw_set_rpwm(padapter, pslv);
1453 		}
1454 	}
1455 
1456 	_exit_pwrlock(&pwrctrl->lock);
1457 
1458 }
1459 
1460 /*
1461  * Caller: rtw_xmit_thread
1462  *
1463  * Check if the fw_pwrstate is okay for xmit.
1464  * If not (cpwm is less than S3), then the sub-routine
1465  * will raise the cpwm to be greater than or equal to S3.
1466  *
1467  * Calling Context: Passive
1468  *
1469  * Return Value:
1470  *	 _SUCCESS	rtw_xmit_thread can write fifo/txcmd afterwards.
1471  *	 _FAIL		rtw_xmit_thread can not do anything.
1472  */
rtw_register_tx_alive(_adapter * padapter)1473 s32 rtw_register_tx_alive(_adapter *padapter)
1474 {
1475 	s32 res;
1476 	struct pwrctrl_priv *pwrctrl;
1477 	u8 pslv;
1478 
1479 
1480 	res = _SUCCESS;
1481 	pwrctrl = adapter_to_pwrctl(padapter);
1482 	pslv = PS_STATE_S2;
1483 
1484 	_enter_pwrlock(&pwrctrl->lock);
1485 
1486 	register_task_alive(pwrctrl, XMIT_ALIVE);
1487 
1488 	if (pwrctrl->bFwCurrentInPSMode == _TRUE) {
1489 
1490 		if (pwrctrl->cpwm < pslv) {
1491 			if (pwrctrl->cpwm < PS_STATE_S2)
1492 				res = _FAIL;
1493 			if (pwrctrl->rpwm < pslv)
1494 				rtw_set_rpwm(padapter, pslv);
1495 		}
1496 	}
1497 
1498 	_exit_pwrlock(&pwrctrl->lock);
1499 
1500 #ifdef CONFIG_DETECT_CPWM_BY_POLLING
1501 	if (_FAIL == res) {
1502 		if (pwrctrl->cpwm >= PS_STATE_S2)
1503 			res = _SUCCESS;
1504 	}
1505 #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
1506 
1507 
1508 	return res;
1509 }
1510 
1511 /*
1512  * Caller: rtw_cmd_thread
1513  *
1514  * Check if the fw_pwrstate is okay for issuing cmd.
1515  * If not (cpwm should be is less than S2), then the sub-routine
1516  * will raise the cpwm to be greater than or equal to S2.
1517  *
1518  * Calling Context: Passive
1519  *
1520  * Return Value:
1521  *	_SUCCESS	rtw_cmd_thread can issue cmds to firmware afterwards.
1522  *	_FAIL		rtw_cmd_thread can not do anything.
1523  */
1524 #if 0 /*#ifdef CONFIG_CORE_CMD_THREAD*/
1525 s32 rtw_register_cmd_alive(_adapter *padapter)
1526 {
1527 	s32 res;
1528 	struct pwrctrl_priv *pwrctrl;
1529 	u8 pslv;
1530 
1531 
1532 	res = _SUCCESS;
1533 	pwrctrl = adapter_to_pwrctl(padapter);
1534 	pslv = PS_STATE_S2;
1535 
1536 	_enter_pwrlock(&pwrctrl->lock);
1537 
1538 	register_task_alive(pwrctrl, CMD_ALIVE);
1539 
1540 	if (pwrctrl->bFwCurrentInPSMode == _TRUE) {
1541 
1542 		if (pwrctrl->cpwm < pslv) {
1543 			if (pwrctrl->cpwm < PS_STATE_S2)
1544 				res = _FAIL;
1545 			if (pwrctrl->rpwm < pslv)
1546 				rtw_set_rpwm(padapter, pslv);
1547 		}
1548 	}
1549 
1550 	_exit_pwrlock(&pwrctrl->lock);
1551 
1552 #ifdef CONFIG_DETECT_CPWM_BY_POLLING
1553 	if (_FAIL == res) {
1554 		if (pwrctrl->cpwm >= PS_STATE_S2)
1555 			res = _SUCCESS;
1556 	}
1557 #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
1558 
1559 
1560 	return res;
1561 }
1562 #endif
1563 /*
1564  * Caller: rx_isr
1565  *
1566  * Calling Context: Dispatch/ISR
1567  *
1568  * Return Value:
1569  *	_SUCCESS
1570  *	_FAIL
1571  */
rtw_register_rx_alive(_adapter * padapter)1572 s32 rtw_register_rx_alive(_adapter *padapter)
1573 {
1574 	struct pwrctrl_priv *pwrctrl;
1575 
1576 
1577 	pwrctrl = adapter_to_pwrctl(padapter);
1578 
1579 	_enter_pwrlock(&pwrctrl->lock);
1580 
1581 	register_task_alive(pwrctrl, RECV_ALIVE);
1582 
1583 	_exit_pwrlock(&pwrctrl->lock);
1584 
1585 
1586 	return _SUCCESS;
1587 }
1588 
1589 /*
1590  * Caller: ISR
1591  *
1592  * If ISR's txdone,
1593  * No more pkts for TX,
1594  * Then driver shall call this fun. to power down firmware again.
1595  */
rtw_unregister_tx_alive(_adapter * padapter)1596 void rtw_unregister_tx_alive(_adapter *padapter)
1597 {
1598 	struct pwrctrl_priv *pwrctrl;
1599 	_adapter *iface;
1600 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1601 	u8 pslv, i;
1602 
1603 
1604 	pwrctrl = adapter_to_pwrctl(padapter);
1605 	pslv = PS_STATE_S0;
1606 
1607 #ifdef CONFIG_P2P_PS
1608 	for (i = 0; i < dvobj->iface_nums; i++) {
1609 		iface = dvobj->padapters[i];
1610 		if ((iface) && rtw_is_adapter_up(iface)) {
1611 			if (iface->wdinfo.p2p_ps_mode > P2P_PS_NONE) {
1612 				pslv = PS_STATE_S2;
1613 				break;
1614 			}
1615 		}
1616 	}
1617 #endif
1618 	_enter_pwrlock(&pwrctrl->lock);
1619 
1620 	unregister_task_alive(pwrctrl, XMIT_ALIVE);
1621 
1622 	if ((pwrctrl->pwr_mode != PM_PS_MODE_ACTIVE)
1623 	    && (pwrctrl->bFwCurrentInPSMode == _TRUE)) {
1624 
1625 		if (pwrctrl->cpwm > pslv) {
1626 			if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
1627 				rtw_set_rpwm(padapter, pslv);
1628 		}
1629 	}
1630 
1631 	_exit_pwrlock(&pwrctrl->lock);
1632 
1633 }
1634 
1635 /*
1636  * Caller: ISR
1637  *
1638  * If all commands have been done,
1639  * and no more command to do,
1640  * then driver shall call this fun. to power down firmware again.
1641  */
1642 #if 0 /*#ifdef CONFIG_CORE_CMD_THREAD*/
1643 void rtw_unregister_cmd_alive(_adapter *padapter)
1644 {
1645 	_adapter *iface;
1646 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1647 	struct pwrctrl_priv *pwrctrl;
1648 	u8 pslv, i;
1649 
1650 
1651 	pwrctrl = adapter_to_pwrctl(padapter);
1652 	pslv = PS_STATE_S0;
1653 
1654 #ifdef CONFIG_P2P_PS
1655 	for (i = 0; i < dvobj->iface_nums; i++) {
1656 		iface = dvobj->padapters[i];
1657 		if ((iface) && rtw_is_adapter_up(iface)) {
1658 			if (iface->wdinfo.p2p_ps_mode > P2P_PS_NONE) {
1659 				pslv = PS_STATE_S2;
1660 				break;
1661 			}
1662 		}
1663 	}
1664 #endif
1665 
1666 	_enter_pwrlock(&pwrctrl->lock);
1667 
1668 	unregister_task_alive(pwrctrl, CMD_ALIVE);
1669 
1670 	if ((pwrctrl->pwr_mode != PM_PS_MODE_ACTIVE)
1671 	    && (pwrctrl->bFwCurrentInPSMode == _TRUE)) {
1672 
1673 		if (pwrctrl->cpwm > pslv) {
1674 			if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
1675 				rtw_set_rpwm(padapter, pslv);
1676 		}
1677 	}
1678 
1679 	_exit_pwrlock(&pwrctrl->lock);
1680 
1681 }
1682 #endif
1683 /*
1684  * Caller: ISR
1685  */
rtw_unregister_rx_alive(_adapter * padapter)1686 void rtw_unregister_rx_alive(_adapter *padapter)
1687 {
1688 	struct pwrctrl_priv *pwrctrl;
1689 
1690 
1691 	pwrctrl = adapter_to_pwrctl(padapter);
1692 
1693 	_enter_pwrlock(&pwrctrl->lock);
1694 
1695 	unregister_task_alive(pwrctrl, RECV_ALIVE);
1696 
1697 
1698 	_exit_pwrlock(&pwrctrl->lock);
1699 
1700 }
1701 #endif	/* CONFIG_LPS_LCLK */
1702 
1703 #ifdef CONFIG_RESUME_IN_WORKQUEUE
1704 	static void resume_workitem_callback(struct work_struct *work);
1705 #endif /* CONFIG_RESUME_IN_WORKQUEUE */
1706 
rtw_init_pwrctrl_priv(_adapter * padapter)1707 void rtw_init_pwrctrl_priv(_adapter *padapter)
1708 {
1709 #ifdef CONFIG_LPS_1T1R
1710 #define LPS_1T1R_FMT ", LPS_1T1R=%d"
1711 #define LPS_1T1R_ARG , pwrctrlpriv->lps_1t1r
1712 #else
1713 #define LPS_1T1R_FMT ""
1714 #define LPS_1T1R_ARG
1715 #endif
1716 
1717 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1718 
1719 #if defined(CONFIG_CONCURRENT_MODE)
1720 	if (!is_primary_adapter(padapter))
1721 		return;
1722 #endif
1723 
1724 	_init_pwrlock(&pwrctrlpriv->lock);
1725 	_init_pwrlock(&pwrctrlpriv->check_32k_lock);
1726 	pwrctrlpriv->rf_pwrstate = rf_on;
1727 	pwrctrlpriv->ips_enter_cnts = 0;
1728 	pwrctrlpriv->ips_leave_cnts = 0;
1729 	pwrctrlpriv->lps_enter_cnts = 0;
1730 	pwrctrlpriv->lps_leave_cnts = 0;
1731 	pwrctrlpriv->bips_processing = _FALSE;
1732 #ifdef CONFIG_LPS_CHK_BY_TP
1733 	pwrctrlpriv->lps_chk_by_tp = padapter->registrypriv.lps_chk_by_tp;
1734 	pwrctrlpriv->lps_tx_tp_th = LPS_TX_TP_TH;
1735 	pwrctrlpriv->lps_rx_tp_th = LPS_RX_TP_TH;
1736 	pwrctrlpriv->lps_bi_tp_th = LPS_BI_TP_TH;
1737 	pwrctrlpriv->lps_chk_cnt = pwrctrlpriv->lps_chk_cnt_th = LPS_TP_CHK_CNT;
1738 	pwrctrlpriv->lps_tx_pkts = LPS_CHK_PKTS_TX;
1739 	pwrctrlpriv->lps_rx_pkts = LPS_CHK_PKTS_RX;
1740 #endif
1741 
1742 	pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
1743 	pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
1744 	pwrctrlpriv->ips_deny_time = rtw_get_current_time();
1745 	pwrctrlpriv->lps_level = padapter->registrypriv.lps_level;
1746 #ifdef CONFIG_LPS_1T1R
1747 	pwrctrlpriv->lps_1t1r = padapter->registrypriv.lps_1t1r;
1748 #endif
1749 
1750 	pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
1751 	pwrctrlpriv->pwr_state_check_cnts = 0;
1752 	pwrctrlpriv->bInSuspend = _FALSE;
1753 	pwrctrlpriv->bkeepfwalive = _FALSE;
1754 	pwrctrlpriv->LpsIdleCount = 0;
1755 
1756 	/* pwrctrlpriv->FWCtrlPSMode =padapter->registrypriv.power_mgnt; */ /* PM_PS_MODE_MIN; */
1757 	if (padapter->registrypriv.mp_mode == 1)
1758 		pwrctrlpriv->power_mgnt = PM_PS_MODE_ACTIVE ;
1759 	else
1760 		pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt; /* PM_PS_MODE_MIN; */
1761 	pwrctrlpriv->bLeisurePs = (PM_PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? _TRUE : _FALSE;
1762 
1763 	pwrctrlpriv->bFwCurrentInPSMode = _FALSE;
1764 	pwrctrlpriv->lps_deny_time = rtw_get_current_time();
1765 
1766 	pwrctrlpriv->rpwm = 0;
1767 	pwrctrlpriv->cpwm = PS_STATE_S4;
1768 
1769 	pwrctrlpriv->pwr_mode = PM_PS_MODE_ACTIVE;
1770 	pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
1771 	pwrctrlpriv->bcn_ant_mode = 0;
1772 	pwrctrlpriv->dtim = 0;
1773 
1774 	pwrctrlpriv->tog = 0x80;
1775 	pwrctrlpriv->rpwm_retry = 0;
1776 
1777 	RTW_INFO("%s: IPS_mode=%d, LPS_mode=%d, LPS_level=%d"LPS_1T1R_FMT"\n",
1778 		__func__, pwrctrlpriv->ips_mode, pwrctrlpriv->power_mgnt, pwrctrlpriv->lps_level
1779 		LPS_1T1R_ARG
1780 	);
1781 
1782 #ifdef CONFIG_LPS_LCLK
1783 	rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&pwrctrlpriv->rpwm));
1784 
1785 	_init_workitem(&pwrctrlpriv->cpwm_event, cpwm_event_callback, NULL);
1786 
1787 	_init_workitem(&pwrctrlpriv->dma_event, dma_event_callback, NULL);
1788 
1789 #ifdef CONFIG_LPS_RPWM_TIMER
1790 	pwrctrlpriv->brpwmtimeout = _FALSE;
1791 	_init_workitem(&pwrctrlpriv->rpwmtimeoutwi, rpwmtimeout_workitem_callback, NULL);
1792 	rtw_init_timer(&pwrctrlpriv->pwr_rpwm_timer, pwr_rpwm_timeout_handler, padapter);
1793 #endif /* CONFIG_LPS_RPWM_TIMER */
1794 #endif /* CONFIG_LPS_LCLK */
1795 
1796 #ifdef CONFIG_LPS_PG
1797 	pwrctrlpriv->lpspg_info.name = "LPSPG_INFO";
1798 	#ifdef CONFIG_RTL8822C
1799 	pwrctrlpriv->lpspg_dpk_info.name = "LPSPG_DPK_INFO";
1800 	pwrctrlpriv->lpspg_iqk_info.name = "LPSPG_IQK_INFO";
1801 	#endif
1802 #endif
1803 #ifdef CONFIG_POWER_SAVING
1804 	rtw_init_timer(&pwrctrlpriv->pwr_state_check_timer, pwr_state_check_handler, padapter);
1805 #endif
1806 
1807 #ifdef CONFIG_RESUME_IN_WORKQUEUE
1808 	_init_workitem(&pwrctrlpriv->resume_work, resume_workitem_callback, NULL);
1809 	pwrctrlpriv->rtw_workqueue = create_singlethread_workqueue("rtw_workqueue");
1810 #endif /* CONFIG_RESUME_IN_WORKQUEUE */
1811 
1812 #ifdef CONFIG_LPS_ACK
1813 	_rtw_mutex_init(&pwrctrlpriv->lps_ack_mutex);
1814 	pwrctrlpriv->lps_ack_status = -1;
1815 #endif /* CONFIG_LPS_ACK */
1816 }
1817 
1818 
rtw_free_pwrctrl_priv(_adapter * adapter)1819 void rtw_free_pwrctrl_priv(_adapter *adapter)
1820 {
1821 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(adapter);
1822 
1823 #if defined(CONFIG_CONCURRENT_MODE)
1824 	if (!is_primary_adapter(adapter))
1825 		return;
1826 #endif
1827 
1828 
1829 	/* _rtw_memset((unsigned char *)pwrctrlpriv, 0, sizeof(struct pwrctrl_priv)); */
1830 
1831 
1832 #ifdef CONFIG_RESUME_IN_WORKQUEUE
1833 	if (pwrctrlpriv->rtw_workqueue) {
1834 		flush_workqueue(pwrctrlpriv->rtw_workqueue);
1835 		destroy_workqueue(pwrctrlpriv->rtw_workqueue);
1836 	}
1837 #endif
1838 
1839 #ifdef CONFIG_LPS_LCLK
1840 	_cancel_workitem_sync(&pwrctrlpriv->cpwm_event);
1841 	_cancel_workitem_sync(&pwrctrlpriv->dma_event);
1842 	#ifdef CONFIG_LPS_RPWM_TIMER
1843 	_cancel_workitem_sync(&pwrctrlpriv->rpwmtimeoutwi);
1844 	#endif
1845 #endif /* CONFIG_LPS_LCLK */
1846 
1847 #ifdef CONFIG_LPS_PG
1848 	rsvd_page_cache_free(&pwrctrlpriv->lpspg_info);
1849 	#ifdef CONFIG_RTL8822C
1850 	rsvd_page_cache_free(&pwrctrlpriv->lpspg_dpk_info);
1851 	rsvd_page_cache_free(&pwrctrlpriv->lpspg_iqk_info);
1852 	#endif
1853 #endif
1854 
1855 	_free_pwrlock(&pwrctrlpriv->lock);
1856 	_free_pwrlock(&pwrctrlpriv->check_32k_lock);
1857 
1858 #ifdef CONFIG_LPS_ACK
1859 	_rtw_mutex_free(&pwrctrlpriv->lps_ack_mutex);
1860 #endif /* CONFIG_LPS_ACK */
1861 }
1862 
1863 #ifdef CONFIG_RESUME_IN_WORKQUEUE
1864 extern int rtw_resume_process(_adapter *padapter);
1865 
resume_workitem_callback(struct work_struct * work)1866 static void resume_workitem_callback(struct work_struct *work)
1867 {
1868 	struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, resume_work);
1869 	struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
1870 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
1871 
1872 	RTW_INFO("%s\n", __FUNCTION__);
1873 
1874 	rtw_resume_process(adapter);
1875 
1876 	rtw_resume_unlock_suspend();
1877 }
1878 
rtw_resume_in_workqueue(struct pwrctrl_priv * pwrpriv)1879 void rtw_resume_in_workqueue(struct pwrctrl_priv *pwrpriv)
1880 {
1881 	/* accquire system's suspend lock preventing from falliing asleep while resume in workqueue */
1882 	/* rtw_lock_suspend(); */
1883 
1884 	rtw_resume_lock_suspend();
1885 
1886 #if 1
1887 	queue_work(pwrpriv->rtw_workqueue, &pwrpriv->resume_work);
1888 #else
1889 	_set_workitem(&pwrpriv->resume_work);
1890 #endif
1891 }
1892 #endif /* CONFIG_RESUME_IN_WORKQUEUE */
1893 
1894 #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
rtw_is_earlysuspend_registered(struct pwrctrl_priv * pwrpriv)1895 inline bool rtw_is_earlysuspend_registered(struct pwrctrl_priv *pwrpriv)
1896 {
1897 	return (pwrpriv->early_suspend.suspend) ? _TRUE : _FALSE;
1898 }
1899 
rtw_is_do_late_resume(struct pwrctrl_priv * pwrpriv)1900 inline bool rtw_is_do_late_resume(struct pwrctrl_priv *pwrpriv)
1901 {
1902 	return (pwrpriv->do_late_resume) ? _TRUE : _FALSE;
1903 }
1904 
rtw_set_do_late_resume(struct pwrctrl_priv * pwrpriv,bool enable)1905 inline void rtw_set_do_late_resume(struct pwrctrl_priv *pwrpriv, bool enable)
1906 {
1907 	pwrpriv->do_late_resume = enable;
1908 }
1909 #endif
1910 
1911 #ifdef CONFIG_HAS_EARLYSUSPEND
1912 extern int rtw_resume_process(_adapter *padapter);
rtw_early_suspend(struct early_suspend * h)1913 static void rtw_early_suspend(struct early_suspend *h)
1914 {
1915 	struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
1916 	RTW_INFO("%s\n", __FUNCTION__);
1917 
1918 	rtw_set_do_late_resume(pwrpriv, _FALSE);
1919 }
1920 
rtw_late_resume(struct early_suspend * h)1921 static void rtw_late_resume(struct early_suspend *h)
1922 {
1923 	struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
1924 	struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
1925 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
1926 
1927 	RTW_INFO("%s\n", __FUNCTION__);
1928 
1929 	if (pwrpriv->do_late_resume) {
1930 		rtw_set_do_late_resume(pwrpriv, _FALSE);
1931 		rtw_resume_process(adapter);
1932 	}
1933 }
1934 
rtw_register_early_suspend(struct pwrctrl_priv * pwrpriv)1935 void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv)
1936 {
1937 	RTW_INFO("%s\n", __FUNCTION__);
1938 
1939 	/* jeff: set the early suspend level before blank screen, so we wll do late resume after scree is lit */
1940 	pwrpriv->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
1941 	pwrpriv->early_suspend.suspend = rtw_early_suspend;
1942 	pwrpriv->early_suspend.resume = rtw_late_resume;
1943 	register_early_suspend(&pwrpriv->early_suspend);
1944 
1945 
1946 }
1947 
rtw_unregister_early_suspend(struct pwrctrl_priv * pwrpriv)1948 void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv)
1949 {
1950 	RTW_INFO("%s\n", __FUNCTION__);
1951 
1952 	rtw_set_do_late_resume(pwrpriv, _FALSE);
1953 
1954 	if (pwrpriv->early_suspend.suspend)
1955 		unregister_early_suspend(&pwrpriv->early_suspend);
1956 
1957 	pwrpriv->early_suspend.suspend = NULL;
1958 	pwrpriv->early_suspend.resume = NULL;
1959 }
1960 #endif /* CONFIG_HAS_EARLYSUSPEND */
1961 
1962 #ifdef CONFIG_ANDROID_POWER
1963 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
1964 	extern int rtw_resume_process(_adapter *padapter);
1965 #endif
rtw_early_suspend(android_early_suspend_t * h)1966 static void rtw_early_suspend(android_early_suspend_t *h)
1967 {
1968 	struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
1969 	RTW_INFO("%s\n", __FUNCTION__);
1970 
1971 	rtw_set_do_late_resume(pwrpriv, _FALSE);
1972 }
1973 
rtw_late_resume(android_early_suspend_t * h)1974 static void rtw_late_resume(android_early_suspend_t *h)
1975 {
1976 	struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
1977 	struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
1978 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
1979 
1980 	RTW_INFO("%s\n", __FUNCTION__);
1981 	if (pwrpriv->do_late_resume) {
1982 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
1983 		rtw_set_do_late_resume(pwrpriv, _FALSE);
1984 		rtw_resume_process(adapter);
1985 #endif
1986 	}
1987 }
1988 
rtw_register_early_suspend(struct pwrctrl_priv * pwrpriv)1989 void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv)
1990 {
1991 	RTW_INFO("%s\n", __FUNCTION__);
1992 
1993 	/* jeff: set the early suspend level before blank screen, so we wll do late resume after scree is lit */
1994 	pwrpriv->early_suspend.level = ANDROID_EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
1995 	pwrpriv->early_suspend.suspend = rtw_early_suspend;
1996 	pwrpriv->early_suspend.resume = rtw_late_resume;
1997 	android_register_early_suspend(&pwrpriv->early_suspend);
1998 }
1999 
rtw_unregister_early_suspend(struct pwrctrl_priv * pwrpriv)2000 void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv)
2001 {
2002 	RTW_INFO("%s\n", __FUNCTION__);
2003 
2004 	rtw_set_do_late_resume(pwrpriv, _FALSE);
2005 
2006 	if (pwrpriv->early_suspend.suspend)
2007 		android_unregister_early_suspend(&pwrpriv->early_suspend);
2008 
2009 	pwrpriv->early_suspend.suspend = NULL;
2010 	pwrpriv->early_suspend.resume = NULL;
2011 }
2012 #endif /* CONFIG_ANDROID_POWER */
2013 
2014 
rtw_set_ips_deny(_adapter * padapter,u32 ms)2015 inline void rtw_set_ips_deny(_adapter *padapter, u32 ms)
2016 {
2017 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2018 	pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
2019 }
2020 
2021 /*
2022 * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
2023 * @adapter: pointer to _adapter structure
2024 * @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup
2025 * Return _SUCCESS or _FAIL
2026 */
2027 
_rtw_pwr_wakeup(_adapter * padapter,u32 ips_deffer_ms,const char * caller)2028 int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller)
2029 {
2030 	int ret = _SUCCESS;
2031 
2032 #ifdef CONFIG_POWER_SAVING
2033 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2034 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
2035 	struct mlme_priv *pmlmepriv;
2036 
2037 	systime start = rtw_get_current_time();
2038 
2039 	/*RTW_INFO(FUNC_ADPT_FMT "===>\n", FUNC_ADPT_ARG(padapter));*/
2040 	/* for LPS */
2041 	LeaveAllPowerSaveMode(padapter);
2042 
2043 	/* IPS still bound with primary adapter */
2044 	padapter = GET_PRIMARY_ADAPTER(padapter);
2045 	pmlmepriv = &padapter->mlmepriv;
2046 
2047 	if (rtw_time_after(rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms), pwrpriv->ips_deny_time))
2048 		pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms);
2049 
2050 
2051 	if (pwrpriv->ps_processing) {
2052 		RTW_INFO("%s wait ps_processing...\n", __func__);
2053 		while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000)
2054 			rtw_msleep_os(10);
2055 		if (pwrpriv->ps_processing)
2056 			RTW_INFO("%s wait ps_processing timeout\n", __func__);
2057 		else
2058 			RTW_INFO("%s wait ps_processing done\n", __func__);
2059 	}
2060 
2061 #ifdef DBG_CONFIG_ERROR_DETECT
2062 	if (rtw_hal_sreset_inprogress(padapter)) {
2063 		RTW_INFO("%s wait sreset_inprogress...\n", __func__);
2064 		while (rtw_hal_sreset_inprogress(padapter) && rtw_get_passing_time_ms(start) <= 4000)
2065 			rtw_msleep_os(10);
2066 		if (rtw_hal_sreset_inprogress(padapter))
2067 			RTW_INFO("%s wait sreset_inprogress timeout\n", __func__);
2068 		else
2069 			RTW_INFO("%s wait sreset_inprogress done\n", __func__);
2070 	}
2071 #endif
2072 
2073 	if (pwrpriv->bInSuspend) {
2074 		RTW_INFO("%s wait bInSuspend...\n", __func__);
2075 		while (pwrpriv->bInSuspend
2076 		       && ((rtw_get_passing_time_ms(start) <= 3000 && !rtw_is_do_late_resume(pwrpriv))
2077 			|| (rtw_get_passing_time_ms(start) <= 500 && rtw_is_do_late_resume(pwrpriv)))
2078 		      )
2079 			rtw_msleep_os(10);
2080 		if (pwrpriv->bInSuspend)
2081 			RTW_INFO("%s wait bInSuspend timeout\n", __func__);
2082 		else
2083 			RTW_INFO("%s wait bInSuspend done\n", __func__);
2084 	}
2085 
2086 	/* System suspend is not allowed to wakeup */
2087 	if (_TRUE == pwrpriv->bInSuspend) {
2088 		ret = _FAIL;
2089 		goto exit;
2090 	}
2091 	/* I think this should be check in IPS, LPS, autosuspend functions... */
2092 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
2093 		ret = _SUCCESS;
2094 		goto exit;
2095 	}
2096 
2097 	if (rf_off == pwrpriv->rf_pwrstate) {
2098 
2099 #ifdef CONFIG_IPS
2100 		RTW_INFO("%s call ips_leave....\n", __FUNCTION__);
2101 		if (_FAIL ==  ips_leave(padapter)) {
2102 			RTW_INFO("======> ips_leave fail.............\n");
2103 			ret = _FAIL;
2104 			goto exit;
2105 		}
2106 #endif
2107 
2108 	}
2109 
2110 	/* TODO: the following checking need to be merged... */
2111 	if (dev_is_drv_stopped(dvobj)
2112 	    || !padapter->netif_up
2113 	    || !rtw_hw_is_init_completed(dvobj)
2114 	   ) {
2115 		RTW_INFO("%s: bDriverStopped=%s, netif_up=%d, hw_init_completed=%u\n"
2116 			 , caller
2117 			 , dev_is_drv_stopped(dvobj) ? "True" : "False"
2118 			 , padapter->netif_up
2119 			 , rtw_hw_get_init_completed(dvobj));
2120 		ret = _FALSE;
2121 		goto exit;
2122 	}
2123 
2124 exit:
2125 	if (rtw_time_after(rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms), pwrpriv->ips_deny_time))
2126 		pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms);
2127 	/*RTW_INFO(FUNC_ADPT_FMT "<===\n", FUNC_ADPT_ARG(padapter));*/
2128 #endif
2129 	return ret;
2130 }
2131 
rtw_pm_set_lps(_adapter * padapter,u8 mode)2132 int rtw_pm_set_lps(_adapter *padapter, u8 mode)
2133 {
2134 	int	ret = 0;
2135 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
2136 
2137 	if (mode < PM_PS_MODE_NUM) {
2138 		if (pwrctrlpriv->power_mgnt != mode) {
2139 			if (PM_PS_MODE_ACTIVE == mode)
2140 				LeaveAllPowerSaveMode(padapter);
2141 			else
2142 				pwrctrlpriv->LpsIdleCount = 2;
2143 			pwrctrlpriv->power_mgnt = mode;
2144 			pwrctrlpriv->bLeisurePs = (PM_PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? _TRUE : _FALSE;
2145 		}
2146 	} else
2147 		ret = -EINVAL;
2148 
2149 	return ret;
2150 }
2151 
rtw_pm_set_lps_level(_adapter * padapter,u8 level)2152 int rtw_pm_set_lps_level(_adapter *padapter, u8 level)
2153 {
2154 	int	ret = 0;
2155 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
2156 
2157 	if (level < LPS_LEVEL_MAX) {
2158 		if (pwrctrlpriv->lps_level != level) {
2159 			#ifdef CONFIG_LPS
2160 			if (rtw_lps_ctrl_leave_set_level_cmd(padapter, level, RTW_CMDF_WAIT_ACK) != _SUCCESS)
2161 			#endif
2162 				pwrctrlpriv->lps_level = level;
2163 		}
2164 	} else
2165 		ret = -EINVAL;
2166 
2167 	return ret;
2168 }
2169 
2170 #ifdef CONFIG_LPS_1T1R
rtw_pm_set_lps_1t1r(_adapter * padapter,u8 en)2171 int rtw_pm_set_lps_1t1r(_adapter *padapter, u8 en)
2172 {
2173 	int	ret = 0;
2174 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
2175 
2176 	en = en ? 1 : 0;
2177 	if (pwrctrlpriv->lps_1t1r != en) {
2178 		if (rtw_lps_ctrl_leave_set_1t1r_cmd(padapter, en, RTW_CMDF_WAIT_ACK) != _SUCCESS)
2179 			pwrctrlpriv->lps_1t1r = en;
2180 	}
2181 
2182 	return ret;
2183 }
2184 #endif
2185 
rtw_set_lps_deny(_adapter * adapter,u32 ms)2186 inline void rtw_set_lps_deny(_adapter *adapter, u32 ms)
2187 {
2188 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2189 	pwrpriv->lps_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
2190 }
2191 
rtw_pm_set_ips(_adapter * padapter,u8 mode)2192 int rtw_pm_set_ips(_adapter *padapter, u8 mode)
2193 {
2194 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
2195 
2196 	if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
2197 		rtw_ips_mode_req(pwrctrlpriv, mode);
2198 		RTW_INFO("%s %s\n", __FUNCTION__, mode == IPS_NORMAL ? "IPS_NORMAL" : "IPS_LEVEL_2");
2199 		return 0;
2200 	} else if (mode == IPS_NONE) {
2201 		rtw_ips_mode_req(pwrctrlpriv, mode);
2202 		RTW_INFO("%s %s\n", __FUNCTION__, "IPS_NONE");
2203 		if (!dev_is_surprise_removed(adapter_to_dvobj(padapter)) && (_FAIL == rtw_pwr_wakeup(padapter)))
2204 			return -EFAULT;
2205 	} else
2206 		return -EINVAL;
2207 	return 0;
2208 }
2209 
2210 /*
2211  * ATTENTION:
2212  *	This function will request pwrctrl LOCK!
2213  */
rtw_ps_deny(_adapter * padapter,PS_DENY_REASON reason)2214 void rtw_ps_deny(_adapter *padapter, PS_DENY_REASON reason)
2215 {
2216 	struct pwrctrl_priv *pwrpriv;
2217 
2218 	/* 	RTW_INFO("+" FUNC_ADPT_FMT ": Request PS deny for %d (0x%08X)\n",
2219 	 *		FUNC_ADPT_ARG(padapter), reason, BIT(reason)); */
2220 
2221 	pwrpriv = adapter_to_pwrctl(padapter);
2222 
2223 	_enter_pwrlock(&pwrpriv->lock);
2224 	if (pwrpriv->ps_deny & BIT(reason)) {
2225 		RTW_INFO(FUNC_ADPT_FMT ": [WARNING] Reason %d had been set before!!\n",
2226 			 FUNC_ADPT_ARG(padapter), reason);
2227 	}
2228 	pwrpriv->ps_deny |= BIT(reason);
2229 	_exit_pwrlock(&pwrpriv->lock);
2230 
2231 	/* 	RTW_INFO("-" FUNC_ADPT_FMT ": Now PS deny for 0x%08X\n",
2232 	 *		FUNC_ADPT_ARG(padapter), pwrpriv->ps_deny); */
2233 }
2234 
2235 /*
2236  * ATTENTION:
2237  *	This function will request pwrctrl LOCK!
2238  */
rtw_ps_deny_cancel(_adapter * padapter,PS_DENY_REASON reason)2239 void rtw_ps_deny_cancel(_adapter *padapter, PS_DENY_REASON reason)
2240 {
2241 	struct pwrctrl_priv *pwrpriv;
2242 
2243 
2244 	/* 	RTW_INFO("+" FUNC_ADPT_FMT ": Cancel PS deny for %d(0x%08X)\n",
2245 	 *		FUNC_ADPT_ARG(padapter), reason, BIT(reason)); */
2246 
2247 	pwrpriv = adapter_to_pwrctl(padapter);
2248 
2249 	_enter_pwrlock(&pwrpriv->lock);
2250 	if ((pwrpriv->ps_deny & BIT(reason)) == 0) {
2251 		RTW_INFO(FUNC_ADPT_FMT ": [ERROR] Reason %d had been canceled before!!\n",
2252 			 FUNC_ADPT_ARG(padapter), reason);
2253 	}
2254 	pwrpriv->ps_deny &= ~BIT(reason);
2255 	_exit_pwrlock(&pwrpriv->lock);
2256 
2257 	/* 	RTW_INFO("-" FUNC_ADPT_FMT ": Now PS deny for 0x%08X\n",
2258 	 *		FUNC_ADPT_ARG(padapter), pwrpriv->ps_deny); */
2259 }
2260 
2261 /*
2262  * ATTENTION:
2263  *	Before calling this function pwrctrl lock should be occupied already,
2264  *	otherwise it may return incorrect value.
2265  */
rtw_ps_deny_get(_adapter * padapter)2266 u32 rtw_ps_deny_get(_adapter *padapter)
2267 {
2268 	u32 deny;
2269 
2270 
2271 	deny = adapter_to_pwrctl(padapter)->ps_deny;
2272 
2273 	return deny;
2274 }
2275 
_rtw_ssmps(_adapter * adapter,struct sta_info * sta)2276 static void _rtw_ssmps(_adapter *adapter, struct sta_info *sta)
2277 {
2278 	struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
2279 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2280 
2281 	issue_action_SM_PS_wait_ack(adapter , get_my_bssid(&(pmlmeinfo->network)),
2282 			sta->phl_sta->asoc_cap.sm_ps, 3 , 1);
2283 
2284 	if (sta->phl_sta->asoc_cap.sm_ps == SM_PS_STATIC) {
2285 		pmlmeext->txss_bk = sta->phl_sta->asoc_cap.nss_rx;
2286 		sta->phl_sta->asoc_cap.nss_rx = 1;
2287 	} else {
2288 		sta->phl_sta->asoc_cap.nss_rx = pmlmeext->txss_bk;
2289 	}
2290 
2291 	rtw_phl_cmd_change_stainfo(adapter_to_dvobj(adapter)->phl,
2292 				   sta->phl_sta,
2293 				   STA_CHG_RAMASK,
2294 				   NULL,
2295 				   0,
2296 				   PHL_CMD_DIRECTLY,
2297 				   0);
2298 }
rtw_ssmps_enter(_adapter * adapter,struct sta_info * sta)2299 void rtw_ssmps_enter(_adapter *adapter, struct sta_info *sta)
2300 {
2301 	if (MLME_IS_AP(adapter))
2302 		return;
2303 
2304 	if (sta->phl_sta->asoc_cap.sm_ps == SM_PS_STATIC)
2305 		return;
2306 
2307 	RTW_INFO(ADPT_FMT" STA [" MAC_FMT "]\n", ADPT_ARG(adapter), MAC_ARG(sta->phl_sta->mac_addr));
2308 
2309 	sta->phl_sta->asoc_cap.sm_ps = SM_PS_STATIC;
2310 	_rtw_ssmps(adapter, sta);
2311 }
rtw_ssmps_leave(_adapter * adapter,struct sta_info * sta)2312 void rtw_ssmps_leave(_adapter *adapter, struct sta_info *sta)
2313 {
2314 	if (MLME_IS_AP(adapter))
2315 		return;
2316 
2317 	if (sta->phl_sta->asoc_cap.sm_ps == SM_PS_DISABLE)
2318 		return;
2319 
2320 	RTW_INFO(ADPT_FMT" STA [" MAC_FMT "] \n", ADPT_ARG(adapter), MAC_ARG(sta->phl_sta->mac_addr));
2321 	sta->phl_sta->asoc_cap.sm_ps = SM_PS_DISABLE;
2322 	_rtw_ssmps(adapter, sta);
2323 }
2324 
2325