From: Luciano Coelho Date: Fri, 8 Aug 2014 16:50:46 +0000 (+0300) Subject: iwlwifi: mvm: add option that allows a vif to disable PS X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=2533edcee8aa311a24e5c0a7da955893ad65dc24;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git iwlwifi: mvm: add option that allows a vif to disable PS We need to disable PS when a monitor vif is active or, in the future, when a channel switch is happening. Add a boolean to mvmvif that allows PS to be disabled generically. Additionally, make the monitor interface use this new flag when it gets activated. Signed-off-by: Luciano Coelho Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 531540c54efb..98e14f9c6fbe 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2708,7 +2708,10 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, ret = 0; goto out; case NL80211_IFTYPE_STATION: + break; case NL80211_IFTYPE_MONITOR: + /* always disable PS when a monitor interface is active */ + mvmvif->ps_disabled = true; break; default: ret = -EINVAL; @@ -2784,6 +2787,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, goto out; case NL80211_IFTYPE_MONITOR: mvmvif->monitor_active = false; + mvmvif->ps_disabled = false; break; case NL80211_IFTYPE_AP: /* This part is triggered only during CSA */ diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 108ef161ee11..ffb509362828 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -326,6 +326,7 @@ struct iwl_mvm_vif_bf_data { * interface should get quota etc. * @low_latency: indicates that this interface is in low-latency mode * (VMACLowLatencyMode) + * @ps_disabled: indicates that this interface requires PS to be disabled * @queue_params: QoS params for this MAC * @bcast_sta: station used for broadcast packets. Used by the following * vifs: P2P_DEVICE, GO and AP. @@ -343,6 +344,7 @@ struct iwl_mvm_vif { bool pm_enabled; bool monitor_active; bool low_latency; + bool ps_disabled; struct iwl_mvm_vif_bf_data bf_data; u32 ap_beacon_time; diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 18f887aa32ae..b552183d0a31 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -512,6 +512,17 @@ static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac, mvmvif->pm_enabled = false; } +static void iwl_mvm_power_ps_disabled_iterator(void *_data, u8* mac, + struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + bool *disable_ps = _data; + + if (mvmvif->phy_ctxt) + if (mvmvif->phy_ctxt->id < MAX_PHYS) + *disable_ps |= mvmvif->ps_disabled; +} + static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif) { @@ -831,16 +842,18 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, return ret; } -static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm, - struct iwl_power_vifs *vifs) +static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm) { bool disable_ps; int ret; /* disable PS if CAM */ disable_ps = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM); - /* ...or if there is an active monitor vif */ - disable_ps |= (vifs->monitor_vif && vifs->monitor_active); + /* ...or if any of the vifs require PS to be off */ + ieee80211_iterate_active_interfaces_atomic(mvm->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_power_ps_disabled_iterator, + &disable_ps); /* update device power state if it has changed */ if (mvm->ps_disabled != disable_ps) { @@ -889,7 +902,7 @@ int iwl_mvm_power_update_ps(struct iwl_mvm *mvm) IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_power_get_vifs_iterator, &vifs); - ret = iwl_mvm_power_set_ps(mvm, &vifs); + ret = iwl_mvm_power_set_ps(mvm); if (ret) return ret; @@ -912,7 +925,7 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) iwl_mvm_power_set_pm(mvm, &vifs); - ret = iwl_mvm_power_set_ps(mvm, &vifs); + ret = iwl_mvm_power_set_ps(mvm); if (ret) return ret;