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: Alexander Bondar <alexander.bondar@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This commit is contained in:
parent
1c2abf724b
commit
92d8556250
3 changed files with 35 additions and 12 deletions
|
@ -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,
|
||||||
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,
|
||||||
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 {
|
||||||
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 {
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
&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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue