int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
{
struct iwl_time_quota_cmd cmd;
- int i, idx, ret;
+ int i, idx, ret, num_active_bindings, quota, quota_rem;
struct iwl_mvm_quota_iterator_data data = {
.n_interfaces = {},
.colors = { -1, -1, -1, -1 },
iwl_mvm_quota_iterator(&data, newvif->addr, newvif);
}
+ /*
+ * The FW's scheduling session consists of
+ * IWL_MVM_MAX_QUOTA fragments. Divide these fragments
+ * equally between all the bindings that require quota
+ */
+ num_active_bindings = 0;
+ for (i = 0; i < MAX_BINDINGS; i++) {
+ cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
+ if (data.n_interfaces[i] > 0)
+ num_active_bindings++;
+ }
+
+ if (!num_active_bindings)
+ goto send_cmd;
+
+ quota = IWL_MVM_MAX_QUOTA / num_active_bindings;
+ quota_rem = IWL_MVM_MAX_QUOTA % num_active_bindings;
+
for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
if (data.n_interfaces[i] <= 0)
continue;
cmd.quotas[idx].id_and_color =
cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
- cmd.quotas[idx].quota = cpu_to_le32(100);
- cmd.quotas[idx].max_duration = cpu_to_le32(1000);
+ cmd.quotas[idx].quota = cpu_to_le32(quota);
+ cmd.quotas[idx].max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
idx++;
}
- for (i = idx; i < MAX_BINDINGS; i++)
- cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
+ /* Give the remainder of the session to the first binding */
+ le32_add_cpu(&cmd.quotas[0].quota, quota_rem);
+send_cmd:
ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
sizeof(cmd), &cmd);
if (ret)