iwlwifi: mvm: add option that allows a vif to disable PS
authorLuciano Coelho <luciano.coelho@intel.com>
Fri, 8 Aug 2014 16:50:46 +0000 (19:50 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 3 Sep 2014 19:48:59 +0000 (22:48 +0300)
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 <luciano.coelho@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/power.c

index 531540c..98e14f9 100644 (file)
@@ -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 */
index 108ef16..ffb5093 100644 (file)
@@ -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;
index 18f887a..b552183 100644 (file)
@@ -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;