diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 99 | 
1 files changed, 98 insertions, 1 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 883f23ae951..04a41628cee 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -552,7 +552,9 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)  	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);  	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); -	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); +	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, +					 (rtlpriv->mac80211.p2p) ? +					 ppsc->smart_ps : 1);  	SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,  					      ppsc->reg_max_lps_awakeintvl); @@ -808,3 +810,98 @@ void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)  	rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);  }  EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd); + +static void rtl92c_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow) +{ +	u8 u1_ctwindow_period[1] = {ctwindow}; + +	rtl92c_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period); +} + +void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info); +	struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; +	u8	i; +	u16	ctwindow; +	u32	start_time, tsf_low; + +	switch (p2p_ps_state) { +	case P2P_PS_DISABLE: +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); +		memset(p2p_ps_offload, 0, sizeof(struct p2p_ps_offload_t)); +		break; +	case P2P_PS_ENABLE: +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); +		/* update CTWindow value. */ +		if (p2pinfo->ctwindow > 0) { +			p2p_ps_offload->ctwindow_en = 1; +			ctwindow = p2pinfo->ctwindow; +			rtl92c_set_p2p_ctw_period_cmd(hw, ctwindow); +		} +		/* hw only support 2 set of NoA */ +		for (i = 0; i < p2pinfo->noa_num; i++) { +			/* To control the register setting for which NOA*/ +			rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); +			if (i == 0) +				p2p_ps_offload->noa0_en = 1; +			else +				p2p_ps_offload->noa1_en = 1; + +			/* config P2P NoA Descriptor Register */ +			rtl_write_dword(rtlpriv, 0x5E0, +					p2pinfo->noa_duration[i]); +			rtl_write_dword(rtlpriv, 0x5E4, +					p2pinfo->noa_interval[i]); + +			/*Get Current TSF value */ +			tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + +			start_time = p2pinfo->noa_start_time[i]; +			if (p2pinfo->noa_count_type[i] != 1) { +				while (start_time <= (tsf_low+(50*1024))) { +					start_time += p2pinfo->noa_interval[i]; +					if (p2pinfo->noa_count_type[i] != 255) +						p2pinfo->noa_count_type[i]--; +				} +			} +			rtl_write_dword(rtlpriv, 0x5E8, start_time); +			rtl_write_dword(rtlpriv, 0x5EC, +					p2pinfo->noa_count_type[i]); +		} + +		if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { +			/* rst p2p circuit */ +			rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); + +			p2p_ps_offload->offload_en = 1; + +			if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { +				p2p_ps_offload->role = 1; +				p2p_ps_offload->allstasleep = 0; +			} else { +				p2p_ps_offload->role = 0; +			} + +			p2p_ps_offload->discovery = 0; +		} +		break; +	case P2P_PS_SCAN: +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); +		p2p_ps_offload->discovery = 1; +		break; +	case P2P_PS_SCAN_DONE: +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); +		p2p_ps_offload->discovery = 0; +		p2pinfo->p2p_ps_state = P2P_PS_ENABLE; +		break; +	default: +		break; +	} + +	rtl92c_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); +} +EXPORT_SYMBOL_GPL(rtl92c_set_p2p_ps_offload_cmd);  |