diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8723ae/fw.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723ae/fw.c | 97 |
1 files changed, 96 insertions, 1 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c index 35cb8f83eed4..dedfa1ed3e02 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c @@ -494,7 +494,9 @@ void rtl8723ae_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); @@ -741,3 +743,96 @@ void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); } + +static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, + u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = {ctwindow}; + + rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period); +} + +void rtl8723ae_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; + rtl8723e_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; + } + rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); +} |