X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fiwlwifi%2Fmvm%2Fpower.c;h=def6ec5173b9d8bbabe5e5e4e3a681b41af96f31;hb=995dca4ce9dddf48597bd3e0427447acd4509f1d;hp=d9eab3b7bb9f871a37b818e5a63e1320a12d7189;hpb=f568849edac8611d603e00bd6cbbcfea09395ae6;p=linux-2.6-block.git diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index d9eab3b7bb9f..def6ec5173b9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -74,39 +74,36 @@ #define POWER_KEEP_ALIVE_PERIOD_SEC 25 +static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm, - struct iwl_beacon_filter_cmd *cmd) + struct iwl_beacon_filter_cmd *cmd, + u32 flags) { - int ret; - - ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC, - sizeof(struct iwl_beacon_filter_cmd), cmd); - - if (!ret) { - IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n", - le32_to_cpu(cmd->ba_enable_beacon_abort)); - IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n", - le32_to_cpu(cmd->ba_escape_timer)); - IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n", - le32_to_cpu(cmd->bf_debug_flag)); - IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n", - le32_to_cpu(cmd->bf_enable_beacon_filter)); - IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n", - le32_to_cpu(cmd->bf_energy_delta)); - IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n", - le32_to_cpu(cmd->bf_escape_timer)); - IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n", - le32_to_cpu(cmd->bf_roaming_energy_delta)); - IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n", - le32_to_cpu(cmd->bf_roaming_state)); - IWL_DEBUG_POWER(mvm, "bf_temp_threshold is: %d\n", - le32_to_cpu(cmd->bf_temp_threshold)); - IWL_DEBUG_POWER(mvm, "bf_temp_fast_filter is: %d\n", - le32_to_cpu(cmd->bf_temp_fast_filter)); - IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n", - le32_to_cpu(cmd->bf_temp_slow_filter)); - } - return ret; + IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n", + le32_to_cpu(cmd->ba_enable_beacon_abort)); + IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n", + le32_to_cpu(cmd->ba_escape_timer)); + IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n", + le32_to_cpu(cmd->bf_debug_flag)); + IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n", + le32_to_cpu(cmd->bf_enable_beacon_filter)); + IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n", + le32_to_cpu(cmd->bf_energy_delta)); + IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n", + le32_to_cpu(cmd->bf_escape_timer)); + IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n", + le32_to_cpu(cmd->bf_roaming_energy_delta)); + IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n", + le32_to_cpu(cmd->bf_roaming_state)); + IWL_DEBUG_POWER(mvm, "bf_temp_threshold is: %d\n", + le32_to_cpu(cmd->bf_temp_threshold)); + IWL_DEBUG_POWER(mvm, "bf_temp_fast_filter is: %d\n", + le32_to_cpu(cmd->bf_temp_fast_filter)); + IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n", + le32_to_cpu(cmd->bf_temp_slow_filter)); + + return iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, flags, + sizeof(struct iwl_beacon_filter_cmd), cmd); } static @@ -145,7 +142,7 @@ int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm, mvmvif->bf_data.ba_enabled = enable; iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, &cmd); iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); - return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); + return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd, CMD_SYNC); } static void iwl_mvm_power_log(struct iwl_mvm *mvm, @@ -301,8 +298,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); cmd->keep_alive_seconds = cpu_to_le16(keep_alive); - if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM || - mvm->ps_prevented) + if (mvm->ps_disabled) return; cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); @@ -312,7 +308,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, mvmvif->dbgfs_pm.disable_power_off) cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); #endif - if (!vif->bss_conf.ps || mvmvif->pm_prevented) + if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) || + mvm->pm_disabled) return; cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); @@ -419,72 +416,44 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, #endif /* CONFIG_IWLWIFI_DEBUGFS */ } -static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, +static int iwl_mvm_power_send_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { - int ret; - bool ba_enable; struct iwl_mac_power_cmd cmd = {}; if (vif->type != NL80211_IFTYPE_STATION) return 0; if (vif->p2p && - !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS)) + !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)) return 0; iwl_mvm_power_build_cmd(mvm, vif, &cmd); iwl_mvm_power_log(mvm, &cmd); - - ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC, - sizeof(cmd), &cmd); - if (ret) - return ret; - - ba_enable = !!(cmd.flags & - cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)); - - return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable); -} - -static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) -{ - struct iwl_mac_power_cmd cmd = {}; - struct iwl_mvm_vif *mvmvif __maybe_unused = - iwl_mvm_vif_from_mac80211(vif); - - if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) - return 0; - - cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, - mvmvif->color)); - - if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) - cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); - #ifdef CONFIG_IWLWIFI_DEBUGFS - if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF && - mvmvif->dbgfs_pm.disable_power_off) - cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); + memcpy(&iwl_mvm_vif_from_mac80211(vif)->mac_pwr_cmd, &cmd, sizeof(cmd)); #endif - iwl_mvm_power_log(mvm, &cmd); - return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_ASYNC, + return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC, sizeof(cmd), &cmd); } -static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable) +int iwl_mvm_power_update_device(struct iwl_mvm *mvm) { struct iwl_device_power_cmd cmd = { .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), }; + if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) + return 0; + if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) return 0; - if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM || - force_disable) + if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) + mvm->ps_disabled = true; + + if (mvm->ps_disabled) cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -501,11 +470,6 @@ static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable) &cmd); } -static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) -{ - return _iwl_mvm_power_update_device(mvm, false); -} - void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); @@ -544,44 +508,169 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm, return 0; } -static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac, - struct ieee80211_vif *vif) +struct iwl_power_constraint { + struct ieee80211_vif *bf_vif; + struct ieee80211_vif *bss_vif; + u16 bss_phyctx_id; + u16 p2p_phyctx_id; + bool pm_disabled; + bool ps_disabled; + struct iwl_mvm *mvm; +}; + +static void iwl_mvm_power_iterator(void *_data, u8 *mac, + struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_mvm *mvm = _data; - int ret; + struct iwl_power_constraint *power_iterator = _data; + struct iwl_mvm *mvm = power_iterator->mvm; + + switch (ieee80211_vif_type_p2p(vif)) { + case NL80211_IFTYPE_P2P_DEVICE: + break; + + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_AP: + /* no BSS power mgmt if we have an active AP */ + if (mvmvif->ap_ibss_active) + power_iterator->pm_disabled = true; + break; + + case NL80211_IFTYPE_MONITOR: + /* no BSS power mgmt and no device power save */ + power_iterator->pm_disabled = true; + power_iterator->ps_disabled = true; + break; + + case NL80211_IFTYPE_P2P_CLIENT: + if (mvmvif->phy_ctxt) + power_iterator->p2p_phyctx_id = mvmvif->phy_ctxt->id; + + IWL_DEBUG_POWER(mvm, "p2p: p2p_id=%d, bss_id=%d\n", + power_iterator->p2p_phyctx_id, + power_iterator->bss_phyctx_id); + if (!(mvm->fw->ucode_capa.flags & + IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)) { + /* no BSS power mgmt if we have a P2P client*/ + power_iterator->pm_disabled = true; + } else if (power_iterator->p2p_phyctx_id < MAX_PHYS && + power_iterator->bss_phyctx_id < MAX_PHYS && + power_iterator->p2p_phyctx_id == + power_iterator->bss_phyctx_id) { + power_iterator->pm_disabled = true; + } + break; + + case NL80211_IFTYPE_STATION: + if (mvmvif->phy_ctxt) + power_iterator->bss_phyctx_id = mvmvif->phy_ctxt->id; + + /* we should have only one BSS vif */ + WARN_ON(power_iterator->bss_vif); + power_iterator->bss_vif = vif; + + if (mvmvif->bf_data.bf_enabled && + !WARN_ON(power_iterator->bf_vif)) + power_iterator->bf_vif = vif; + + IWL_DEBUG_POWER(mvm, "bss: p2p_id=%d, bss_id=%d\n", + power_iterator->p2p_phyctx_id, + power_iterator->bss_phyctx_id); + if (mvm->fw->ucode_capa.flags & + IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM && + (power_iterator->p2p_phyctx_id < MAX_PHYS && + power_iterator->bss_phyctx_id < MAX_PHYS && + power_iterator->p2p_phyctx_id == + power_iterator->bss_phyctx_id)) + power_iterator->pm_disabled = true; + break; + + default: + break; + } +} - mvmvif->pm_prevented = (mvm->bound_vif_cnt <= 1) ? false : true; +static void +iwl_mvm_power_get_global_constraint(struct iwl_mvm *mvm, + struct iwl_power_constraint *constraint) +{ + lockdep_assert_held(&mvm->mutex); + + if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) { + constraint->pm_disabled = true; + constraint->ps_disabled = true; + } - ret = iwl_mvm_power_mac_update_mode(mvm, vif); - WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n"); + ieee80211_iterate_active_interfaces_atomic(mvm->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_power_iterator, constraint); } -static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - bool assign) +int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_power_constraint constraint = { + .p2p_phyctx_id = MAX_PHYS, + .bss_phyctx_id = MAX_PHYS, + .mvm = mvm, + }; + bool ba_enable; + int ret; + + lockdep_assert_held(&mvm->mutex); + + if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) + return 0; + + iwl_mvm_power_get_global_constraint(mvm, &constraint); + mvm->ps_disabled = constraint.ps_disabled; + mvm->pm_disabled = constraint.pm_disabled; + + /* don't update device power state unless we add / remove monitor */ if (vif->type == NL80211_IFTYPE_MONITOR) { - int ret = _iwl_mvm_power_update_device(mvm, assign); - mvm->ps_prevented = assign; - WARN_ONCE(ret, "Failed to update power device state\n"); + ret = iwl_mvm_power_update_device(mvm); + if (ret) + return ret; } - ieee80211_iterate_active_interfaces(mvm->hw, - IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_power_binding_iterator, - mvm); + ret = iwl_mvm_power_send_cmd(mvm, vif); + if (ret) + return ret; + + if (constraint.bss_vif && vif != constraint.bss_vif) { + ret = iwl_mvm_power_send_cmd(mvm, constraint.bss_vif); + if (ret) + return ret; + } + + if (!constraint.bf_vif) + return 0; + + vif = constraint.bf_vif; + mvmvif = iwl_mvm_vif_from_mac80211(vif); + + ba_enable = !(constraint.pm_disabled || constraint.ps_disabled || + !vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif)); + + return iwl_mvm_update_beacon_abort(mvm, constraint.bf_vif, ba_enable); } #ifdef CONFIG_IWLWIFI_DEBUGFS -static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, char *buf, - int bufsz) +int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, char *buf, + int bufsz) { + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mac_power_cmd cmd = {}; int pos = 0; - iwl_mvm_power_build_cmd(mvm, vif, &cmd); + if (WARN_ON(!(mvm->fw->ucode_capa.flags & + IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT))) + return 0; + + mutex_lock(&mvm->mutex); + memcpy(&cmd, &mvmvif->mac_pwr_cmd, sizeof(cmd)); + mutex_unlock(&mvm->mutex); if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n", @@ -685,32 +774,46 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, } #endif -int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) +static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct iwl_beacon_filter_cmd *cmd, + u32 cmd_flags, + bool d0i3) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_beacon_filter_cmd cmd = { - IWL_BF_CMD_CONFIG_DEFAULTS, - .bf_enable_beacon_filter = cpu_to_le32(1), - }; int ret; if (mvmvif != mvm->bf_allowed_vif || vif->type != NL80211_IFTYPE_STATION || vif->p2p) return 0; - iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, &cmd); - iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); - ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); + iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd); + if (!d0i3) + iwl_mvm_beacon_filter_debugfs_parameters(vif, cmd); + ret = iwl_mvm_beacon_filter_send_cmd(mvm, cmd, cmd_flags); - if (!ret) + /* don't change bf_enabled in case of temporary d0i3 configuration */ + if (!ret && !d0i3) mvmvif->bf_data.bf_enabled = true; return ret; } +int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + u32 flags) +{ + struct iwl_beacon_filter_cmd cmd = { + IWL_BF_CMD_CONFIG_DEFAULTS, + .bf_enable_beacon_filter = cpu_to_le32(1), + }; + + return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags, false); +} + int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) + struct ieee80211_vif *vif, + u32 flags) { struct iwl_beacon_filter_cmd cmd = {}; struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); @@ -720,7 +823,7 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, vif->type != NL80211_IFTYPE_STATION || vif->p2p) return 0; - ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); + ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd, flags); if (!ret) mvmvif->bf_data.bf_enabled = false; @@ -728,23 +831,89 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, return ret; } -int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) +int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + bool enable, u32 flags) { + int ret; struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mac_power_cmd cmd = {}; - if (!mvmvif->bf_data.bf_enabled) + if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) return 0; - return iwl_mvm_enable_beacon_filter(mvm, vif); -} + if (!vif->bss_conf.assoc) + return 0; -const struct iwl_mvm_power_ops pm_mac_ops = { - .power_update_mode = iwl_mvm_power_mac_update_mode, - .power_update_device_mode = iwl_mvm_power_update_device, - .power_disable = iwl_mvm_power_mac_disable, - .power_update_binding = _iwl_mvm_power_update_binding, + iwl_mvm_power_build_cmd(mvm, vif, &cmd); + if (enable) { + /* configure skip over dtim up to 300 msec */ + int dtimper = mvm->hw->conf.ps_dtim_period ?: 1; + int dtimper_msec = dtimper * vif->bss_conf.beacon_int; + + if (WARN_ON(!dtimper_msec)) + return 0; + + cmd.flags |= + cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); + cmd.skip_dtim_periods = 300 / dtimper_msec; + } + iwl_mvm_power_log(mvm, &cmd); #ifdef CONFIG_IWLWIFI_DEBUGFS - .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, + memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd)); #endif -}; + ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags, + sizeof(cmd), &cmd); + if (ret) + return ret; + + /* configure beacon filtering */ + if (mvmvif != mvm->bf_allowed_vif) + return 0; + + if (enable) { + struct iwl_beacon_filter_cmd cmd_bf = { + IWL_BF_CMD_CONFIG_D0I3, + .bf_enable_beacon_filter = cpu_to_le32(1), + }; + ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf, + flags, true); + } else { + if (mvmvif->bf_data.bf_enabled) + ret = iwl_mvm_enable_beacon_filter(mvm, vif, flags); + else + ret = iwl_mvm_disable_beacon_filter(mvm, vif, flags); + } + + return ret; +} + +int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + bool force, + u32 flags) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + if (mvmvif != mvm->bf_allowed_vif) + return 0; + + if (!mvmvif->bf_data.bf_enabled) { + /* disable beacon filtering explicitly if force is true */ + if (force) + return iwl_mvm_disable_beacon_filter(mvm, vif, flags); + return 0; + } + + return iwl_mvm_enable_beacon_filter(mvm, vif, flags); +} + +int iwl_power_legacy_set_cam_mode(struct iwl_mvm *mvm) +{ + struct iwl_powertable_cmd cmd = { + .keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC, + }; + + return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, + sizeof(cmd), &cmd); +}