예제 #1
0
void rtw_set_ps_mode(struct rtl_priv *rtlpriv, uint8_t ps_mode, uint8_t smart_ps, uint8_t bcn_ant_mode)
{
	struct pwrctrl_priv *pwrpriv = &rtlpriv->pwrctrlpriv;



	if (ps_mode > PM_Card_Disable) {
		return;
	}

	if (pwrpriv->pwr_mode == ps_mode) {
		if (PS_MODE_ACTIVE == ps_mode)
			return;

		if ((pwrpriv->smart_ps == smart_ps)
		   && (pwrpriv->bcn_ant_mode == bcn_ant_mode)) {
			return;
		}
	}

	//if(pwrpriv->pwr_mode == PS_MODE_ACTIVE)
	if(ps_mode == PS_MODE_ACTIVE)
	{
		{
			DBG_871X("rtw_set_ps_mode: Leave 802.11 power save\n");


			pwrpriv->pwr_mode = ps_mode;
			rtw_set_rpwm(rtlpriv, PS_STATE_S4);
			rtw_hal_set_hwreg(rtlpriv, HW_VAR_H2C_FW_PWRMODE, (uint8_t *)(&ps_mode));
			pwrpriv->fw_current_inpsmode = false;
		}
	} else 	{
		if (PS_RDY_CHECK(rtlpriv)) {
			DBG_871X("%s: Enter 802.11 power save\n", __FUNCTION__);


			pwrpriv->fw_current_inpsmode = true;
			pwrpriv->pwr_mode = ps_mode;
			pwrpriv->smart_ps = smart_ps;
			pwrpriv->bcn_ant_mode = bcn_ant_mode;
			rtw_hal_set_hwreg(rtlpriv, HW_VAR_H2C_FW_PWRMODE, (uint8_t *)(&ps_mode));

			rtw_set_rpwm(rtlpriv, PS_STATE_S2);
		}
	}


}
예제 #2
0
파일: rtw_pwrctrl.c 프로젝트: Lyude/linux
/*
 * Caller: rtw_xmit_thread
 *
 * Check if the fw_pwrstate is okay for xmit.
 * If not (cpwm is less than S3), then the sub-routine
 * will raise the cpwm to be greater than or equal to S3.
 *
 * Calling Context: Passive
 *
 * Return Value:
 * _SUCCESS	rtw_xmit_thread can write fifo/txcmd afterwards.
 * _FAIL		rtw_xmit_thread can not do anything.
 */
s32 rtw_register_tx_alive(struct adapter *padapter)
{
	s32 res;
	struct pwrctrl_priv *pwrctrl;
	u8 pslv;

	res = _SUCCESS;
	pwrctrl = adapter_to_pwrctl(padapter);
	pslv = PS_STATE_S2;

	down(&pwrctrl->lock);

	register_task_alive(pwrctrl, XMIT_ALIVE);

	if (pwrctrl->bFwCurrentInPSMode == true) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
				 ("rtw_register_tx_alive: cpwm = 0x%02x alives = 0x%08x\n",
				  pwrctrl->cpwm, pwrctrl->alives));

		if (pwrctrl->cpwm < pslv) {
			if (pwrctrl->cpwm < PS_STATE_S2)
				res = _FAIL;
			if (pwrctrl->rpwm < pslv)
				rtw_set_rpwm(padapter, pslv);
		}
	}

	up(&pwrctrl->lock);

	if (_FAIL == res)
		if (pwrctrl->cpwm >= PS_STATE_S2)
			res = _SUCCESS;

	return res;
}
예제 #3
0
파일: rtw_pwrctrl.c 프로젝트: 020gzh/linux
void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;

	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
		 ("%s: PowerMode=%d Smart_PS=%d\n",
		  __func__, ps_mode, smart_ps));

	if (ps_mode > PM_Card_Disable) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("ps_mode:%d error\n", ps_mode));
		return;
	}

	if (pwrpriv->pwr_mode == ps_mode) {
		if (PS_MODE_ACTIVE == ps_mode)
			return;

		if ((pwrpriv->smart_ps == smart_ps) &&
		    (pwrpriv->bcn_ant_mode == bcn_ant_mode))
			return;
	}

	/* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
	if (ps_mode == PS_MODE_ACTIVE) {
		if (PS_RDY_CHECK(padapter)) {
			DBG_88E("%s: Enter 802.11 power save\n", __func__);
			pwrpriv->bFwCurrentInPSMode = true;
			pwrpriv->pwr_mode = ps_mode;
			pwrpriv->smart_ps = smart_ps;
			pwrpriv->bcn_ant_mode = bcn_ant_mode;
			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
			rtw_set_rpwm(padapter, PS_STATE_S2);
		}
	}
}
예제 #4
0
파일: rtw_pwrctrl.c 프로젝트: Lyude/linux
void LeaveAllPowerSaveModeDirect(struct adapter *Adapter)
{
	struct adapter *pri_padapter = GET_PRIMARY_ADAPTER(Adapter);
	struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter);

	DBG_871X("%s.....\n", __func__);

	if (true == Adapter->bSurpriseRemoved) {
		DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved =%d Skip!\n",
			FUNC_ADPT_ARG(Adapter), Adapter->bSurpriseRemoved);
		return;
	}

	if ((check_fwstate(pmlmepriv, _FW_LINKED) == true)) { /* connect */

		if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
			DBG_871X("%s: Driver Already Leave LPS\n", __func__);
			return;
		}

		down(&pwrpriv->lock);

		rtw_set_rpwm(Adapter, PS_STATE_S4);

		up(&pwrpriv->lock);

		rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, 0);
	} else{
		if (pwrpriv->rf_pwrstate == rf_off)
			if (false == ips_leave(pri_padapter))
				DBG_871X("======> ips_leave fail.............\n");
	}
}
예제 #5
0
void rtw_unregister_cmd_alive(_adapter *padapter)
{
#ifdef CONFIG_PWRCTRL

	struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv;

_func_enter_;

	_enter_pwrlock(&pwrctrl->lock);

	unregister_task_alive(pwrctrl, CMD_ALIVE);

	if((pwrctrl->cpwm > PS_STATE_S2) && (pwrctrl->pwr_mode > PS_MODE_ACTIVE)){
		if((pwrctrl->alives == 0)&&(check_fwstate(&padapter->mlmepriv, _FW_UNDER_LINKING)!=_TRUE)){
			rtw_set_rpwm(padapter, PS_STATE_S0);
		}
	}

	RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("rtw_unregister_cmd_alive: cpwm:%d alives:%x\n", pwrctrl->cpwm, pwrctrl->alives));

	_exit_pwrlock(&pwrctrl->lock);

_func_exit_;

#endif /*CONFIG_PWRCTRL*/
}
예제 #6
0
파일: rtw_pwrctrl.c 프로젝트: Lyude/linux
/*
 * Description:
 *If task is done, call this func. to power down firmware again.
 *
 *Constraint:
 *	1. this function will request pwrctrl->lock
 *
 * Return Value:
 *none
 */
void rtw_unregister_task_alive(struct adapter *padapter, u32 task)
{
	struct pwrctrl_priv *pwrctrl;
	u8 pslv;

	pwrctrl = adapter_to_pwrctl(padapter);
	pslv = PS_STATE_S0;

	if ((rtw_btcoex_IsBtDisabled(padapter) == false)
		&& (rtw_btcoex_IsBtControlLps(padapter) == true)) {
		u8 val8;

		val8 = rtw_btcoex_LpsVal(padapter);
		if (val8 & BIT(4))
			pslv = PS_STATE_S2;
	}

	down(&pwrctrl->lock);

	unregister_task_alive(pwrctrl, task);

	if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
		&& (pwrctrl->bFwCurrentInPSMode == true)) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
				 ("%s: cpwm = 0x%02x alives = 0x%08x\n",
				  __func__, pwrctrl->cpwm, pwrctrl->alives));

		if (pwrctrl->cpwm > pslv)
			if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
				rtw_set_rpwm(padapter, pslv);

	}

	up(&pwrctrl->lock);
}
예제 #7
0
/*
Caller: rtw_cmd_thread

Check if the fw_pwrstate is okay for issuing cmd.
If not (cpwm should be is less than P2 state), then the sub-routine
will raise the cpwm to be greater than or equal to P2. 

Calling Context: Passive

Return Value:

_SUCCESS: rtw_cmd_thread can issue cmds to firmware afterwards.
_FAIL: rtw_cmd_thread can not do anything.
*/
sint rtw_register_cmd_alive(_adapter *padapter)
{
	uint res = _SUCCESS;
	
#ifdef CONFIG_PWRCTRL

	struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv;

_func_enter_;

	_enter_pwrlock(&pwrctrl->lock);

	register_task_alive(pwrctrl, CMD_ALIVE);
	RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("rtw_register_cmd_alive: cpwm:%d alives:%x\n", pwrctrl->cpwm, pwrctrl->alives));

	if(pwrctrl->cpwm < PS_STATE_S2){
		rtw_set_rpwm(padapter, PS_STATE_S3);
		res = _FAIL;
	}

	_exit_pwrlock(&pwrctrl->lock);
_func_exit_;
#endif

	return res;
}
예제 #8
0
/*
 * Caller: rtw_cmd_thread
 *
 * Check if the fw_pwrstate is okay for issuing cmd.
 * If not (cpwm should be is less than S2), then the sub-routine
 * will raise the cpwm to be greater than or equal to S2.
 *
 * Calling Context: Passive
 *
 * Return Value:
 *	_SUCCESS	rtw_cmd_thread can issue cmds to firmware afterwards.
 *	_FAIL		rtw_cmd_thread can not do anything.
 */
s32 rtw_register_cmd_alive(struct rtw_adapter *padapter)
{
	s32 res;
	struct pwrctrl_priv *pwrctrl;

	res = _SUCCESS;
	pwrctrl = &padapter->pwrctrlpriv;

	_enter_pwrlock(&pwrctrl->lock);

	register_task_alive(pwrctrl, CMD_ALIVE);

	if (pwrctrl->bFwCurrentInPSMode == true) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
			 ("rtw_register_cmd_alive: cpwm=0x%02x alives=0x%08x\n",
			  pwrctrl->cpwm, pwrctrl->alives));

		if (pwrctrl->cpwm < PS_STATE_S2) {
			if (pwrctrl->rpwm < PS_STATE_S2)
				rtw_set_rpwm(padapter, PS_STATE_S2);
			res = _FAIL;
		}
	}

	_exit_pwrlock(&pwrctrl->lock);

	return res;
}
예제 #9
0
static void rpwmtimeout_workitem_callback(struct work_struct *work)
{
	PADAPTER padapter;
	struct dvobj_priv *dvobj;
	struct pwrctrl_priv *pwrpriv;


	pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi);
	dvobj = pwrctl_to_dvobj(pwrpriv);
	padapter = dvobj->if1;
/* 	DBG_871X("+%s: rpwm =0x%02X cpwm =0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); */

	down(&pwrpriv->lock);
	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2))
	{
		DBG_871X("%s: rpwm =0x%02X cpwm =0x%02X CPWM done!\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
		goto exit;
	}
	up(&pwrpriv->lock);

	if (rtw_read8(padapter, 0x100) != 0xEA)
	{
		struct reportpwrstate_parm report;

		report.state = PS_STATE_S2;
		DBG_871X("\n%s: FW already leave 32K!\n\n", __func__);
		cpwm_int_hdl(padapter, &report);

		return;
	}

	down(&pwrpriv->lock);

	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2))
	{
		DBG_871X("%s: cpwm =%d, nothing to do!\n", __func__, pwrpriv->cpwm);
		goto exit;
	}
	pwrpriv->brpwmtimeout = true;
	rtw_set_rpwm(padapter, pwrpriv->rpwm);
	pwrpriv->brpwmtimeout = false;

exit:
	up(&pwrpriv->lock);
}
예제 #10
0
/*
 * Description:
 *	Check if the fw_pwrstate is okay for I/O.
 *	If not (cpwm is less than S2), then the sub-routine
 *	will raise the cpwm to be greater than or equal to S2.
 *
 *	Calling Context: Passive
 *
 *	Constraint:
 *		1. this function will request pwrctrl->lock
 *
 * Return Value:
 *	_SUCCESS	hardware is ready for I/O
 *	_FAIL		can't I/O right now
 */
s32 rtw_register_task_alive(PADAPTER padapter, u32 task)
{
	s32 res;
	struct pwrctrl_priv *pwrctrl;
	u8 pslv;

	res = _SUCCESS;
	pwrctrl = adapter_to_pwrctl(padapter);
	pslv = PS_STATE_S2;

	down(&pwrctrl->lock);

	register_task_alive(pwrctrl, task);

	if (pwrctrl->bFwCurrentInPSMode == true)
	{
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
				 ("%s: task =0x%x cpwm =0x%02x alives =0x%08x\n",
				  __FUNCTION__, task, pwrctrl->cpwm, pwrctrl->alives));

		if (pwrctrl->cpwm < pslv)
		{
			if (pwrctrl->cpwm < PS_STATE_S2)
				res = _FAIL;
			if (pwrctrl->rpwm < pslv)
				rtw_set_rpwm(padapter, pslv);
		}
	}

	up(&pwrctrl->lock);

	if (_FAIL == res)
	{
		if (pwrctrl->cpwm >= PS_STATE_S2)
			res = _SUCCESS;
	}
	return res;
}
예제 #11
0
/*
 * Caller: ISR
 *
 * If all commands have been done,
 * and no more command to do,
 * then driver shall call this fun. to power down firmware again.
 */
void rtw_unregister_cmd_alive(struct rtw_adapter *padapter)
{
	struct pwrctrl_priv *pwrctrl;

	pwrctrl = &padapter->pwrctrlpriv;

	_enter_pwrlock(&pwrctrl->lock);

	unregister_task_alive(pwrctrl, CMD_ALIVE);

	if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) &&
	    (pwrctrl->bFwCurrentInPSMode == true)) {
		if ((pwrctrl->alives == 0) && (pwrctrl->cpwm > PS_STATE_S0))
			rtw_set_rpwm(padapter, PS_STATE_S0);

		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
			 ("rtw_unregister_cmd_alive: cpwm=0x%02x alives=0x%08x\n",
			  pwrctrl->cpwm, pwrctrl->alives));
	}

	_exit_pwrlock(&pwrctrl->lock);

}
예제 #12
0
void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
#ifdef CONFIG_P2P
	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo );
#endif //CONFIG_P2P
#ifdef CONFIG_TDLS
	struct sta_priv *pstapriv = &padapter->stapriv;
	_irqL irqL;
	int i, j;
	_list	*plist, *phead;
	struct sta_info *ptdls_sta;
#endif //CONFIG_TDLS

_func_enter_;

	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
			 ("%s: PowerMode=%d Smart_PS=%d\n",
			  __FUNCTION__, ps_mode, smart_ps));

	if(ps_mode > PM_Card_Disable) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("ps_mode:%d error\n", ps_mode));
		return;
	}

	if (pwrpriv->pwr_mode == ps_mode)
	{
		if (PS_MODE_ACTIVE == ps_mode) return;

		if ((pwrpriv->smart_ps == smart_ps) &&
			(pwrpriv->bcn_ant_mode == bcn_ant_mode))
		{
			return;
		}
	}

#ifdef CONFIG_LPS_LCLK
	_enter_pwrlock(&pwrpriv->lock);
#endif

	//if(pwrpriv->pwr_mode == PS_MODE_ACTIVE)
	if(ps_mode == PS_MODE_ACTIVE)
	{
#ifdef CONFIG_P2P_PS
		if(pwdinfo->opp_ps == 0)
#endif //CONFIG_P2P_PS
		{
			DBG_871X("rtw_set_ps_mode: Leave 802.11 power save\n");

#ifdef CONFIG_TDLS
			_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);

			for(i=0; i< NUM_STA; i++)
			{
				phead = &(pstapriv->sta_hash[i]);
				plist = get_next(phead);

				while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
				{
					ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list);

					if( ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE )
						issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0);
					plist = get_next(plist);
				}
			}

			_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
#endif //CONFIG_TDLS

			pwrpriv->pwr_mode = ps_mode;
			rtw_set_rpwm(padapter, PS_STATE_S4);
#ifdef CONFIG_WOWLAN
			if (padapter->pwrctrlpriv.wowlan_mode == _TRUE)
			{
				u32 start_time, delay_ms;
				u8 val8;
				delay_ms = 20;
				start_time = rtw_get_current_time();
				do {
					val8 = rtw_read8(padapter, 0x90);
					if (!(val8 & BIT(0))) break;
					if (rtw_get_passing_time_ms(start_time) > delay_ms)
					{
						DBG_871X("%s: Wait for FW 32K leave more than %u ms!!!\n", __FUNCTION__, delay_ms);
						break;
					}
						rtw_usleep_os(100);
				} while (1);
				pwrpriv->cpwm = PS_STATE_S4;
			}
#endif
			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
			pwrpriv->bFwCurrentInPSMode = _FALSE;
		}
	}
예제 #13
0
void rtw_set_ps_mode(_adapter * padapter, u8 ps_mode, u8 smart_ps)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
#ifdef CONFIG_P2P
	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo );
#endif //CONFIG_P2P

_func_enter_;

	RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("========= Power Mode is :%d, Smart_PS = %d\n", ps_mode,smart_ps));
	//DBG_8192C("========= Power Mode is :%d, Smart_PS = %d\n", ps_mode,smart_ps);

	if(ps_mode > PM_Card_Disable) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("ps_mode:%d error\n", ps_mode));
		return;
	}

	if((pwrpriv->pwr_mode == ps_mode) &&
		(pwrpriv->smart_ps == smart_ps)){
		return;
	}

	//if(pwrpriv->pwr_mode == PS_MODE_ACTIVE)
	if(ps_mode == PS_MODE_ACTIVE)
	{
#ifdef CONFIG_P2P
		if(pwdinfo->opp_ps == 0)
#endif //CONFIG_P2P
		{
			DBG_8192C("rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..\n");
			pwrpriv->smart_ps = smart_ps;
			pwrpriv->pwr_mode = ps_mode;
			rtw_set_rpwm(padapter, PS_STATE_S4);
			padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
			pwrpriv->bFwCurrentInPSMode = _FALSE;
		}
	}
	else
	{
		if(PS_RDY_CHECK(padapter))
		{
			DBG_8192C("rtw_set_ps_mode(): Enter 802.11 power save mode...\n");
			pwrpriv->smart_ps = smart_ps;
			pwrpriv->pwr_mode = ps_mode;
			pwrpriv->bFwCurrentInPSMode = _TRUE;
			padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
#ifdef CONFIG_P2P
			// Set CTWindow after LPS
			if(pwdinfo->opp_ps == 1)
			//if(pwdinfo->p2p_ps_enable == _TRUE)
				p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
#endif //CONFIG_P2P
			rtw_set_rpwm(padapter, PS_STATE_S2);
		}
		//else
		//{
		//	pwrpriv->pwr_mode = PS_MODE_ACTIVE;
		//}
	}

_func_exit_;
}
예제 #14
0
void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg)
{
	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);

	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
			 ("%s: PowerMode =%d Smart_PS =%d\n",
			  __FUNCTION__, ps_mode, smart_ps));

	if (ps_mode > PM_Card_Disable) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("ps_mode:%d error\n", ps_mode));
		return;
	}

	if (pwrpriv->pwr_mode == ps_mode)
	{
		if (PS_MODE_ACTIVE == ps_mode) return;
	}

	down(&pwrpriv->lock);

	/* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
	if (ps_mode == PS_MODE_ACTIVE)
	{
		if (1
			&& (((rtw_btcoex_IsBtControlLps(padapter) == false)
					)
				|| ((rtw_btcoex_IsBtControlLps(padapter) == true)
					&& (rtw_btcoex_IsLpsOn(padapter) == false))
				)
			)
		{
			DBG_871X(FUNC_ADPT_FMT" Leave 802.11 power save - %s\n",
				FUNC_ADPT_ARG(padapter), msg);

			pwrpriv->pwr_mode = ps_mode;
			rtw_set_rpwm(padapter, PS_STATE_S4);

#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
			if (pwrpriv->wowlan_mode == true ||
					pwrpriv->wowlan_ap_mode == true)
			{
				unsigned long start_time;
				u32 delay_ms;
				u8 val8;
				delay_ms = 20;
				start_time = jiffies;
				do {
					rtw_hal_get_hwreg(padapter, HW_VAR_SYS_CLKR, &val8);
					if (!(val8 & BIT(4))){ /* 0x08 bit4 =1 --> in 32k, bit4 = 0 --> leave 32k */
						pwrpriv->cpwm = PS_STATE_S4;
						break;
					}
					if (jiffies_to_msecs(jiffies - start_time) > delay_ms)
					{
						DBG_871X("%s: Wait for FW 32K leave more than %u ms!!!\n",
								__FUNCTION__, delay_ms);
						pdbgpriv->dbg_wow_leave_ps_fail_cnt++;
						break;
					}
					msleep(1);
				} while (1);
			}
#endif
			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
			pwrpriv->bFwCurrentInPSMode = false;

			rtw_btcoex_LpsNotify(padapter, ps_mode);
		}
	}
	else
	{
		if ((PS_RDY_CHECK(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE))
			|| ((rtw_btcoex_IsBtControlLps(padapter) == true)
				&& (rtw_btcoex_IsLpsOn(padapter) == true))
			)
		{
			u8 pslv;

			DBG_871X(FUNC_ADPT_FMT" Enter 802.11 power save - %s\n",
				FUNC_ADPT_ARG(padapter), msg);

			rtw_btcoex_LpsNotify(padapter, ps_mode);

			pwrpriv->bFwCurrentInPSMode = true;
			pwrpriv->pwr_mode = ps_mode;
			pwrpriv->smart_ps = smart_ps;
			pwrpriv->bcn_ant_mode = bcn_ant_mode;
			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));

			pslv = PS_STATE_S2;
			if (pwrpriv->alives == 0)
				pslv = PS_STATE_S0;

			if ((rtw_btcoex_IsBtDisabled(padapter) == false)
				&& (rtw_btcoex_IsBtControlLps(padapter) == true))
			{
				u8 val8;

				val8 = rtw_btcoex_LpsVal(padapter);
				if (val8 & BIT(4))
					pslv = PS_STATE_S2;
			}

			rtw_set_rpwm(padapter, pslv);
		}
	}

	up(&pwrpriv->lock);
}
예제 #15
0
void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
#ifdef CONFIG_P2P
	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo );
#endif //CONFIG_P2P
#ifdef CONFIG_TDLS
	struct sta_priv *pstapriv = &padapter->stapriv;
	_irqL irqL;
	int i, j;
	_list	*plist, *phead;
	struct sta_info *ptdls_sta;
#endif //CONFIG_TDLS

_func_enter_;

	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
			 ("%s: PowerMode=%d Smart_PS=%d\n",
			  __FUNCTION__, ps_mode, smart_ps));

	if(ps_mode > PM_Card_Disable) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("ps_mode:%d error\n", ps_mode));
		return;
	}

	if((pwrpriv->pwr_mode == ps_mode) &&
		(pwrpriv->smart_ps == smart_ps)){
		return;
	}

	//if(pwrpriv->pwr_mode == PS_MODE_ACTIVE)
	if(ps_mode == PS_MODE_ACTIVE)
	{
#ifdef CONFIG_P2P_PS
		if(pwdinfo->opp_ps == 0)
#endif // CONFIG_P2P_PS
		{
#ifdef CONFIG_LPS_LCLK
			_enter_pwrlock(&pwrpriv->lock);
#endif
			DBG_871X("rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..\n");

#ifdef CONFIG_TDLS
			_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);

			for(i=0; i< NUM_STA; i++)
			{
				phead = &(pstapriv->sta_hash[i]);
				plist = get_next(phead);

				while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
				{
					ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list);

					if( ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE )
						issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0);
					plist = get_next(plist);
				}
			}

			_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
#endif //CONFIG_TDLS

			pwrpriv->smart_ps = smart_ps;
			pwrpriv->pwr_mode = ps_mode;

			rtw_set_rpwm(padapter, PS_STATE_S4);
#ifdef CONFIG_LPS_LCLK
{
			u32 n = 0;
			while (pwrpriv->cpwm != PS_STATE_S4) {
				n++;
				if (n == 10000) break;
				if (padapter->bSurpriseRemoved == _TRUE) break;
				rtw_msleep_os(1);
			}
			if (n == 10000)
				printk(KERN_ERR "%s: wait CPWM to S4 too long! cpwm=0x%02x\n", __func__, pwrpriv->cpwm);
}
#endif
			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
			pwrpriv->bFwCurrentInPSMode = _FALSE;
#ifdef CONFIG_LPS_LCLK
			_exit_pwrlock(&pwrpriv->lock);
#endif
		}
	}
예제 #16
0
void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
#ifdef CONFIG_P2P
	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo );
#endif //CONFIG_P2P
#ifdef CONFIG_TDLS
	struct sta_priv *pstapriv = &padapter->stapriv;
	_irqL irqL;
	int i, j;
	_list	*plist, *phead;
	struct sta_info *ptdls_sta;
#endif //CONFIG_TDLS

_func_enter_;

	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
			 ("%s: PowerMode=%d Smart_PS=%d\n",
			  __FUNCTION__, ps_mode, smart_ps));

	if(ps_mode > PM_Card_Disable) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("ps_mode:%d error\n", ps_mode));
		return;
	}

	if (pwrpriv->pwr_mode == ps_mode)
	{
		if (PS_MODE_ACTIVE == ps_mode) return;

		if ((pwrpriv->smart_ps == smart_ps) &&
			(pwrpriv->bcn_ant_mode == bcn_ant_mode))
		{
			return;
		}
	}

#ifdef CONFIG_LPS_LCLK
	_enter_pwrlock(&pwrpriv->lock);
#endif

	//if(pwrpriv->pwr_mode == PS_MODE_ACTIVE)
	if(ps_mode == PS_MODE_ACTIVE)
	{
#ifdef CONFIG_P2P
		if(pwdinfo->opp_ps == 0)
#endif //CONFIG_P2P
		{
			DBG_871X("rtw_set_ps_mode: Leave 802.11 power save\n");

#ifdef CONFIG_TDLS
			_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);

			for(i=0; i< NUM_STA; i++)
			{
				phead = &(pstapriv->sta_hash[i]);
				plist = get_next(phead);

				while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
				{
					ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list);

					if( ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE )
						issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0);
					plist = get_next(plist);
				}
			}

			_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
#endif //CONFIG_TDLS

			pwrpriv->pwr_mode = ps_mode;
			rtw_set_rpwm(padapter, PS_STATE_S4);
			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
			pwrpriv->bFwCurrentInPSMode = _FALSE;
		}
	}
예제 #17
0
void rtw_set_ps_mode(struct rtw_adapter *padapter, u8 ps_mode, u8 smart_ps)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;

	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
		 ("%s: PowerMode=%d Smart_PS=%d\n",
		  __func__, ps_mode, smart_ps));

	if (ps_mode > PM_Card_Disable) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
			 ("ps_mode:%d error\n", ps_mode));
		return;
	}

	if ((pwrpriv->pwr_mode == ps_mode) && (pwrpriv->smart_ps == smart_ps)) {
		return;
	}

	/* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
	if (ps_mode == PS_MODE_ACTIVE) {
		{
#ifdef CONFIG_LPS_LCLK
			_enter_pwrlock(&pwrpriv->lock);
#endif
			DBG_8192D
			    ("rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..\n");

			pwrpriv->smart_ps = smart_ps;
			pwrpriv->pwr_mode = ps_mode;

			rtw_set_rpwm(padapter, PS_STATE_S4);
#ifdef CONFIG_LPS_LCLK
			{
				u32 n = 0;
				while (pwrpriv->cpwm != PS_STATE_S4) {
					n++;
					if (n == 10000)
						break;
					if (padapter->bSurpriseRemoved == true)
						break;
					rtw_msleep_os(1);
				}
				if (n == 10000)
					printk(KERN_ERR
					       "%s: wait CPWM to S4 too long! cpwm=0x%02x\n",
					       __func__, pwrpriv->cpwm);
			}
#endif
			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE,
					  (u8 *)(&ps_mode));
			pwrpriv->bFwCurrentInPSMode = false;
#ifdef CONFIG_LPS_LCLK
			_exit_pwrlock(&pwrpriv->lock);
#endif
		}
	} else {
		if (ps_rdy_check(padapter)) {
#ifdef CONFIG_LPS_LCLK
			_enter_pwrlock(&pwrpriv->lock);
#endif
			DBG_8192D
			    ("rtw_set_ps_mode(): Enter 802.11 power save mode...\n");

			pwrpriv->smart_ps = smart_ps;
			pwrpriv->pwr_mode = ps_mode;
			pwrpriv->bFwCurrentInPSMode = true;
			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
#ifdef CONFIG_LPS_LCLK
			if (pwrpriv->alives == 0)
				rtw_set_rpwm(padapter, PS_STATE_S0);
#else
			rtw_set_rpwm(padapter, PS_STATE_S2);
#endif
#ifdef CONFIG_LPS_LCLK
			_exit_pwrlock(&pwrpriv->lock);
#endif
		}
		/* else */
		/*  */
		/*      pwrpriv->pwr_mode = PS_MODE_ACTIVE; */
		/*  */
	}

}