|
@@ -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);
|
|
|
+}
|