+static uint64_t
+sfc_sw_stat_get_val(struct sfc_adapter *sa,
+ unsigned int sw_stat_idx, uint16_t qid)
+{
+ struct sfc_sw_stats *sw_stats = &sa->sw_stats;
+ uint64_t *res = &sw_stats->supp[sw_stat_idx].cache[qid];
+ uint64_t values[SFC_SW_STATS_GROUP_SIZE_MAX];
+ unsigned int group_start_idx;
+ unsigned int group_size;
+ unsigned int i;
+
+ if (*res != SFC_SW_STAT_INVALID)
+ return *res;
+
+ /*
+ * Search for the group start, i.e. the stat that implements
+ * get value callback.
+ */
+ group_start_idx = sw_stat_idx;
+ while (sw_stats->supp[group_start_idx].descr->get_val == NULL)
+ group_start_idx--;
+
+ /*
+ * Calculate number of elements in the group with loop till the next
+ * group start or the list end.
+ */
+ group_size = 1;
+ for (i = sw_stat_idx + 1; i < sw_stats->supp_count; i++) {
+ if (sw_stats->supp[i].descr->get_val != NULL)
+ break;
+ group_size++;
+ }
+ group_size += sw_stat_idx - group_start_idx;
+
+ SFC_ASSERT(group_size <= SFC_SW_STATS_GROUP_SIZE_MAX);
+ sw_stats->supp[group_start_idx].descr->get_val(sa, qid, values,
+ group_size);
+ for (i = group_start_idx; i < (group_start_idx + group_size); i++)
+ sw_stats->supp[i].cache[qid] = values[i - group_start_idx];
+
+ return *res;
+}
+