iwlwifi: mvm: limit non-low-latency binding scheduling duration
authorJohannes Berg <johannes.berg@intel.com>
Tue, 12 Nov 2013 21:18:45 +0000 (22:18 +0100)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 3 Feb 2014 20:23:35 +0000 (22:23 +0200)
Limit the scheduling duration of bindings without a low-latency
interface in the firmware, this prevents those bindings from
occupying the medium for a period of time longer than what we
want for the other interfaces in low-latency mode.

As older firmware doesn't do anything with the max_duration field
and ignores it completely, there's no need for a firmware flag.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/constants.h
drivers/net/wireless/iwlwifi/mvm/quota.c

index ffa3346..f3b96e4 100644 (file)
@@ -79,5 +79,7 @@
 #define IWL_MVM_PS_SNOOZE_WINDOW               50
 #define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW                25
 #define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT       64
+#define IWL_MVM_LOWLAT_SINGLE_BINDING_MAXDUR   24 /* TU */
+#define IWL_MVM_LOWLAT_DUAL_BINDING_MAXDUR     24 /* TU */
 
 #endif /* __MVM_CONSTANTS_H */
index 0d2185b..5691a85 100644 (file)
@@ -180,6 +180,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
                .colors = { -1, -1, -1, -1 },
                .new_vif = newvif,
        };
+       u32 ll_max_duration;
 
        lockdep_assert_held(&mvm->mutex);
 
@@ -198,6 +199,21 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
                iwl_mvm_quota_iterator(&data, newvif->addr, newvif);
        }
 
+       switch (data.n_low_latency_bindings) {
+       case 0: /* no low latency - use default */
+               ll_max_duration = 0;
+               break;
+       case 1: /* SingleBindingLowLatencyMode */
+               ll_max_duration = IWL_MVM_LOWLAT_SINGLE_BINDING_MAXDUR;
+               break;
+       case 2: /* DualBindingLowLatencyMode */
+               ll_max_duration = IWL_MVM_LOWLAT_DUAL_BINDING_MAXDUR;
+               break;
+       default: /* MultiBindingLowLatencyMode */
+               ll_max_duration = 0;
+               break;
+       }
+
        /*
         * The FW's scheduling session consists of
         * IWL_MVM_MAX_QUOTA fragments. Divide these fragments
@@ -242,18 +258,21 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
                cmd.quotas[idx].id_and_color =
                        cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
 
-               if (data.n_interfaces[i] <= 0) {
+               if (data.n_interfaces[i] <= 0)
                        cmd.quotas[idx].quota = cpu_to_le32(0);
-                       cmd.quotas[idx].max_duration = cpu_to_le32(0);
-               } else if (data.n_low_latency_bindings == 1 && n_non_lowlat &&
-                          data.low_latency[i]) {
+               else if (data.n_low_latency_bindings == 1 && n_non_lowlat &&
+                        data.low_latency[i])
                        cmd.quotas[idx].quota = cpu_to_le32(QUOTA_LOWLAT_MIN);
-                       cmd.quotas[idx].max_duration = cpu_to_le32(0);
-               } else {
+               else
                        cmd.quotas[idx].quota =
                                cpu_to_le32(quota * data.n_interfaces[i]);
+
+               if (data.n_interfaces[i] && !data.low_latency[i])
+                       cmd.quotas[idx].max_duration =
+                               cpu_to_le32(ll_max_duration);
+               else
                        cmd.quotas[idx].max_duration = cpu_to_le32(0);
-               }
+
                idx++;
        }