aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-09-08 10:42:54 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-09-14 05:56:40 -0400
commitb2b7875bfb6c69bb708b61c5f745491d240161a1 (patch)
tree96a4defff20dfee2724407355493b9705f7a5667
parentbbab758279a14556e6ccb17b1f98935634eeb8d5 (diff)
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 @@
87#define IWL_MVM_BT_COEX_CORUNNING 1 87#define IWL_MVM_BT_COEX_CORUNNING 1
88#define IWL_MVM_BT_COEX_MPLUT 1 88#define IWL_MVM_BT_COEX_MPLUT 1
89#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 89#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
90#define IWL_MVM_QUOTA_THRESHOLD 8
90 91
91#endif /* __MVM_CONSTANTS_H */ 92#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)
454 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) 454 for (i = 0; i < IWL_MVM_STATION_COUNT; i++)
455 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL); 455 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
456 456
457 /* reset quota debouncing buffer - 0xff will yield invalid data */
458 memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd));
459
457 /* Add auxiliary station for scanning */ 460 /* Add auxiliary station for scanning */
458 ret = iwl_mvm_add_aux_sta(mvm); 461 ret = iwl_mvm_add_aux_sta(mvm);
459 if (ret) 462 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 {
709 */ 709 */
710 bool temperature_test; /* Debug test temperature is enabled */ 710 bool temperature_test; /* Debug test temperature is enabled */
711 711
712 struct iwl_time_quota_cmd last_quota_cmd;
713
712#ifdef CONFIG_NL80211_TESTMODE 714#ifdef CONFIG_NL80211_TESTMODE
713 u32 noa_duration; 715 u32 noa_duration;
714 struct ieee80211_vif *noa_vif; 716 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,
175 struct ieee80211_vif *disabled_vif) 175 struct ieee80211_vif *disabled_vif)
176{ 176{
177 struct iwl_time_quota_cmd cmd = {}; 177 struct iwl_time_quota_cmd cmd = {};
178 int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat; 178 int i, idx, err, num_active_macs, quota, quota_rem, n_non_lowlat;
179 struct iwl_mvm_quota_iterator_data data = { 179 struct iwl_mvm_quota_iterator_data data = {
180 .n_interfaces = {}, 180 .n_interfaces = {},
181 .colors = { -1, -1, -1, -1 }, 181 .colors = { -1, -1, -1, -1 },
182 .disabled_vif = disabled_vif, 182 .disabled_vif = disabled_vif,
183 }; 183 };
184 struct iwl_time_quota_cmd *last = &mvm->last_quota_cmd;
185 bool send = false;
184 186
185 lockdep_assert_held(&mvm->mutex); 187 lockdep_assert_held(&mvm->mutex);
186 188
@@ -293,15 +295,34 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
293 295
294 /* check that we have non-zero quota for all valid bindings */ 296 /* check that we have non-zero quota for all valid bindings */
295 for (i = 0; i < MAX_BINDINGS; i++) { 297 for (i = 0; i < MAX_BINDINGS; i++) {
298 if (cmd.quotas[i].id_and_color != last->quotas[i].id_and_color)
299 send = true;
300 if (cmd.quotas[i].max_duration != last->quotas[i].max_duration)
301 send = true;
302 if (abs((int)le32_to_cpu(cmd.quotas[i].quota) -
303 (int)le32_to_cpu(last->quotas[i].quota))
304 > IWL_MVM_QUOTA_THRESHOLD)
305 send = true;
296 if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID)) 306 if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID))
297 continue; 307 continue;
298 WARN_ONCE(cmd.quotas[i].quota == 0, 308 WARN_ONCE(cmd.quotas[i].quota == 0,
299 "zero quota on binding %d\n", i); 309 "zero quota on binding %d\n", i);
300 } 310 }
301 311
302 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, 312 if (send) {
303 sizeof(cmd), &cmd); 313 err = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
304 if (ret) 314 sizeof(cmd), &cmd);
305 IWL_ERR(mvm, "Failed to send quota: %d\n", ret); 315 } else {
306 return ret; 316 /* don't send a practically unchanged command, the firmware has
317 * to re-initialize a lot of state and that can have an adverse
318 * impact on it
319 */
320 err = 0;
321 }
322
323 if (err)
324 IWL_ERR(mvm, "Failed to send quota: %d\n", err);
325 else
326 mvm->last_quota_cmd = cmd;
327 return err;
307} 328}