aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-09-08 16:42:54 +0200
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-09-14 12:56:40 +0300
commitb2b7875bfb6c69bb708b61c5f745491d240161a1 (patch)
tree96a4defff20dfee2724407355493b9705f7a5667
parentiwlwifi: define the non shared antenna per hardware (diff)
downloadlinux-dev-b2b7875bfb6c69bb708b61c5f745491d240161a1.tar.xz
linux-dev-b2b7875bfb6c69bb708b61c5f745491d240161a1.zip
iwlwifi: mvm: don't update quota in firmware too often
When updating quota in the firmware, it has to reset quite a bit of internal state, which apparently can have an adverse impact on its operation. Avoid that by only updating the quota command when there are any signification changes, i.e. added/removed bindings or changes in quota that are bigger than 8 TU within a binding. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c33
4 files changed, 33 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index cb48656a8eaf..118108929a87 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -87,5 +87,6 @@
#define IWL_MVM_BT_COEX_CORUNNING 1
#define IWL_MVM_BT_COEX_MPLUT 1
#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
+#define IWL_MVM_QUOTA_THRESHOLD 8
#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 21d606028ca6..23fd711a67e4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -454,6 +454,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
for (i = 0; i < IWL_MVM_STATION_COUNT; i++)
RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
+ /* reset quota debouncing buffer - 0xff will yield invalid data */
+ memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd));
+
/* Add auxiliary station for scanning */
ret = iwl_mvm_add_aux_sta(mvm);
if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index e292de96e09a..f05b7d7bcae3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -709,6 +709,8 @@ struct iwl_mvm {
*/
bool temperature_test; /* Debug test temperature is enabled */
+ struct iwl_time_quota_cmd last_quota_cmd;
+
#ifdef CONFIG_NL80211_TESTMODE
u32 noa_duration;
struct ieee80211_vif *noa_vif;
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 5fd502db03d1..1eab2f2fee5d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -175,12 +175,14 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
struct ieee80211_vif *disabled_vif)
{
struct iwl_time_quota_cmd cmd = {};
- int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat;
+ int i, idx, err, num_active_macs, quota, quota_rem, n_non_lowlat;
struct iwl_mvm_quota_iterator_data data = {
.n_interfaces = {},
.colors = { -1, -1, -1, -1 },
.disabled_vif = disabled_vif,
};
+ struct iwl_time_quota_cmd *last = &mvm->last_quota_cmd;
+ bool send = false;
lockdep_assert_held(&mvm->mutex);
@@ -293,15 +295,34 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
/* check that we have non-zero quota for all valid bindings */
for (i = 0; i < MAX_BINDINGS; i++) {
+ if (cmd.quotas[i].id_and_color != last->quotas[i].id_and_color)
+ send = true;
+ if (cmd.quotas[i].max_duration != last->quotas[i].max_duration)
+ send = true;
+ if (abs((int)le32_to_cpu(cmd.quotas[i].quota) -
+ (int)le32_to_cpu(last->quotas[i].quota))
+ > IWL_MVM_QUOTA_THRESHOLD)
+ send = true;
if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID))
continue;
WARN_ONCE(cmd.quotas[i].quota == 0,
"zero quota on binding %d\n", i);
}
- ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
- sizeof(cmd), &cmd);
- if (ret)
- IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
- return ret;
+ if (send) {
+ err = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
+ sizeof(cmd), &cmd);
+ } else {
+ /* don't send a practically unchanged command, the firmware has
+ * to re-initialize a lot of state and that can have an adverse
+ * impact on it
+ */
+ err = 0;
+ }
+
+ if (err)
+ IWL_ERR(mvm, "Failed to send quota: %d\n", err);
+ else
+ mvm->last_quota_cmd = cmd;
+ return err;
}