Commit 92d85562 authored by Alexander Bondar's avatar Alexander Bondar Committed by Emmanuel Grumbach

iwlwifi: mvm: Disable power save for monitor interface

When monitor interface is activated device power save needs
to be disabled.
Re-consider power management status on other active
interfaces when monitor interface is bound or unbound.
Signed-off-by: default avatarAlexander Bondar <alexander.bondar@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 1c2abf72
...@@ -1610,7 +1610,13 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw, ...@@ -1610,7 +1610,13 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
goto out_unlock; goto out_unlock;
/* /*
* Setting the quota at this stage is only required for monitor * Power state must be updated before quotas,
* otherwise fw will complain.
*/
mvm->bound_vif_cnt++;
iwl_mvm_power_update_binding(mvm, vif, true);
/* Setting the quota at this stage is only required for monitor
* interfaces. For the other types, the bss_info changed flow * interfaces. For the other types, the bss_info changed flow
* will handle quota settings. * will handle quota settings.
*/ */
...@@ -1621,13 +1627,12 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw, ...@@ -1621,13 +1627,12 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
goto out_remove_binding; goto out_remove_binding;
} }
mvm->bound_vif_cnt++;
iwl_mvm_power_update_binding(mvm, vif);
goto out_unlock; goto out_unlock;
out_remove_binding: out_remove_binding:
iwl_mvm_binding_remove_vif(mvm, vif); iwl_mvm_binding_remove_vif(mvm, vif);
mvm->bound_vif_cnt--;
iwl_mvm_power_update_binding(mvm, vif, false);
out_unlock: out_unlock:
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
if (ret) if (ret)
...@@ -1662,7 +1667,7 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw, ...@@ -1662,7 +1667,7 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
out_unlock: out_unlock:
mvmvif->phy_ctxt = NULL; mvmvif->phy_ctxt = NULL;
mvm->bound_vif_cnt--; mvm->bound_vif_cnt--;
iwl_mvm_power_update_binding(mvm, vif); iwl_mvm_power_update_binding(mvm, vif, false);
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
} }
......
...@@ -164,7 +164,7 @@ struct iwl_mvm_power_ops { ...@@ -164,7 +164,7 @@ struct iwl_mvm_power_ops {
int (*power_update_device_mode)(struct iwl_mvm *mvm); int (*power_update_device_mode)(struct iwl_mvm *mvm);
int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
void (*power_update_binding)(struct iwl_mvm *mvm, void (*power_update_binding)(struct iwl_mvm *mvm,
struct ieee80211_vif *vif); struct ieee80211_vif *vif, bool assign);
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
char *buf, int bufsz); char *buf, int bufsz);
...@@ -568,6 +568,9 @@ struct iwl_mvm { ...@@ -568,6 +568,9 @@ struct iwl_mvm {
u8 last_agg_queue; u8 last_agg_queue;
u8 bound_vif_cnt; u8 bound_vif_cnt;
/* Indicate if device power save is allowed */
bool ps_prevented;
}; };
/* Extract MVM priv from op_mode and _hw */ /* Extract MVM priv from op_mode and _hw */
...@@ -787,10 +790,11 @@ static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm) ...@@ -787,10 +790,11 @@ static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm)
} }
static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm, static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
struct ieee80211_vif *vif) struct ieee80211_vif *vif,
bool assign)
{ {
if (mvm->pm_ops->power_update_binding) if (mvm->pm_ops->power_update_binding)
mvm->pm_ops->power_update_binding(mvm, vif); mvm->pm_ops->power_update_binding(mvm, vif, assign);
} }
void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
......
...@@ -301,7 +301,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, ...@@ -301,7 +301,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
cmd->keep_alive_seconds = cpu_to_le16(keep_alive); cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
mvm->ps_prevented)
return; return;
cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
...@@ -447,7 +448,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, ...@@ -447,7 +448,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
sizeof(cmd), &cmd); sizeof(cmd), &cmd);
} }
static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable)
{ {
struct iwl_device_power_cmd cmd = { struct iwl_device_power_cmd cmd = {
.flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
...@@ -456,7 +457,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) ...@@ -456,7 +457,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
return 0; return 0;
if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
force_disable)
cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
...@@ -473,6 +475,11 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) ...@@ -473,6 +475,11 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
&cmd); &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) 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); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
...@@ -525,8 +532,15 @@ static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac, ...@@ -525,8 +532,15 @@ static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac,
} }
static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
struct ieee80211_vif *vif) struct ieee80211_vif *vif,
bool assign)
{ {
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");
}
ieee80211_iterate_active_interfaces(mvm->hw, ieee80211_iterate_active_interfaces(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_power_binding_iterator, iwl_mvm_power_binding_iterator,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment