diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-12-18 09:56:28 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-02-03 15:23:35 -0500 |
commit | 6ca40d6eae3e36068157412ceb9ddf1f2d53d1c8 (patch) | |
tree | 8d77da577f6345963e23f738d3337f019f03f81f /drivers/net/wireless/iwlwifi/mvm/quota.c | |
parent | e03f9bef2f9de4295df91a235c6b521dd64ef655 (diff) |
iwlwifi: mvm: reserve bandwidth for low-latency interface
If there is/are interface(s) in low-latency mode, reserve a
percentage (currently 64%) of the quota for that binding to
improve the quality of service for those interfaces. However,
if there's more than one binding that has low-latency, then
give up and don't reserve, we can't allocate more than 100%.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/quota.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/quota.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index ce5db6c4ef7e..0d2185b89d95 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c | |||
@@ -65,9 +65,14 @@ | |||
65 | #include "fw-api.h" | 65 | #include "fw-api.h" |
66 | #include "mvm.h" | 66 | #include "mvm.h" |
67 | 67 | ||
68 | #define QUOTA_100 IWL_MVM_MAX_QUOTA | ||
69 | #define QUOTA_LOWLAT_MIN ((QUOTA_100 * IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT) / 100) | ||
70 | |||
68 | struct iwl_mvm_quota_iterator_data { | 71 | struct iwl_mvm_quota_iterator_data { |
69 | int n_interfaces[MAX_BINDINGS]; | 72 | int n_interfaces[MAX_BINDINGS]; |
70 | int colors[MAX_BINDINGS]; | 73 | int colors[MAX_BINDINGS]; |
74 | int low_latency[MAX_BINDINGS]; | ||
75 | int n_low_latency_bindings; | ||
71 | struct ieee80211_vif *new_vif; | 76 | struct ieee80211_vif *new_vif; |
72 | }; | 77 | }; |
73 | 78 | ||
@@ -107,22 +112,29 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac, | |||
107 | switch (vif->type) { | 112 | switch (vif->type) { |
108 | case NL80211_IFTYPE_STATION: | 113 | case NL80211_IFTYPE_STATION: |
109 | if (vif->bss_conf.assoc) | 114 | if (vif->bss_conf.assoc) |
110 | data->n_interfaces[id]++; | 115 | break; |
111 | break; | 116 | return; |
112 | case NL80211_IFTYPE_AP: | 117 | case NL80211_IFTYPE_AP: |
113 | case NL80211_IFTYPE_ADHOC: | 118 | case NL80211_IFTYPE_ADHOC: |
114 | if (mvmvif->ap_ibss_active) | 119 | if (mvmvif->ap_ibss_active) |
115 | data->n_interfaces[id]++; | 120 | break; |
116 | break; | 121 | return; |
117 | case NL80211_IFTYPE_MONITOR: | 122 | case NL80211_IFTYPE_MONITOR: |
118 | if (mvmvif->monitor_active) | 123 | if (mvmvif->monitor_active) |
119 | data->n_interfaces[id]++; | 124 | break; |
120 | break; | 125 | return; |
121 | case NL80211_IFTYPE_P2P_DEVICE: | 126 | case NL80211_IFTYPE_P2P_DEVICE: |
122 | break; | 127 | return; |
123 | default: | 128 | default: |
124 | WARN_ON_ONCE(1); | 129 | WARN_ON_ONCE(1); |
125 | break; | 130 | return; |
131 | } | ||
132 | |||
133 | data->n_interfaces[id]++; | ||
134 | |||
135 | if (iwl_mvm_vif_low_latency(mvmvif) && !data->low_latency[id]) { | ||
136 | data->n_low_latency_bindings++; | ||
137 | data->low_latency[id] = true; | ||
126 | } | 138 | } |
127 | } | 139 | } |
128 | 140 | ||
@@ -162,7 +174,7 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm, | |||
162 | int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) | 174 | int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) |
163 | { | 175 | { |
164 | struct iwl_time_quota_cmd cmd = {}; | 176 | struct iwl_time_quota_cmd cmd = {}; |
165 | int i, idx, ret, num_active_macs, quota, quota_rem; | 177 | int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat; |
166 | struct iwl_mvm_quota_iterator_data data = { | 178 | struct iwl_mvm_quota_iterator_data data = { |
167 | .n_interfaces = {}, | 179 | .n_interfaces = {}, |
168 | .colors = { -1, -1, -1, -1 }, | 180 | .colors = { -1, -1, -1, -1 }, |
@@ -197,11 +209,30 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) | |||
197 | num_active_macs += data.n_interfaces[i]; | 209 | num_active_macs += data.n_interfaces[i]; |
198 | } | 210 | } |
199 | 211 | ||
200 | quota = 0; | 212 | n_non_lowlat = num_active_macs; |
201 | quota_rem = 0; | 213 | |
202 | if (num_active_macs) { | 214 | if (data.n_low_latency_bindings == 1) { |
203 | quota = IWL_MVM_MAX_QUOTA / num_active_macs; | 215 | for (i = 0; i < MAX_BINDINGS; i++) { |
204 | quota_rem = IWL_MVM_MAX_QUOTA % num_active_macs; | 216 | if (data.low_latency[i]) { |
217 | n_non_lowlat -= data.n_interfaces[i]; | ||
218 | break; | ||
219 | } | ||
220 | } | ||
221 | if (n_non_lowlat) { | ||
222 | quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat; | ||
223 | quota_rem = QUOTA_100 - n_non_lowlat * quota - | ||
224 | QUOTA_LOWLAT_MIN; | ||
225 | } else { | ||
226 | quota = QUOTA_100; | ||
227 | quota_rem = 0; | ||
228 | } | ||
229 | } else if (num_active_macs) { | ||
230 | quota = QUOTA_100 / num_active_macs; | ||
231 | quota_rem = QUOTA_100 % num_active_macs; | ||
232 | } else { | ||
233 | /* values don't really matter - won't be used */ | ||
234 | quota = 0; | ||
235 | quota_rem = 0; | ||
205 | } | 236 | } |
206 | 237 | ||
207 | for (idx = 0, i = 0; i < MAX_BINDINGS; i++) { | 238 | for (idx = 0, i = 0; i < MAX_BINDINGS; i++) { |
@@ -214,6 +245,10 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) | |||
214 | if (data.n_interfaces[i] <= 0) { | 245 | if (data.n_interfaces[i] <= 0) { |
215 | cmd.quotas[idx].quota = cpu_to_le32(0); | 246 | cmd.quotas[idx].quota = cpu_to_le32(0); |
216 | cmd.quotas[idx].max_duration = cpu_to_le32(0); | 247 | cmd.quotas[idx].max_duration = cpu_to_le32(0); |
248 | } else if (data.n_low_latency_bindings == 1 && n_non_lowlat && | ||
249 | data.low_latency[i]) { | ||
250 | cmd.quotas[idx].quota = cpu_to_le32(QUOTA_LOWLAT_MIN); | ||
251 | cmd.quotas[idx].max_duration = cpu_to_le32(0); | ||
217 | } else { | 252 | } else { |
218 | cmd.quotas[idx].quota = | 253 | cmd.quotas[idx].quota = |
219 | cpu_to_le32(quota * data.n_interfaces[i]); | 254 | cpu_to_le32(quota * data.n_interfaces[i]); |