+
+static int
+sfc_mae_query_counter(struct sfc_adapter *sa,
+ struct sfc_flow_spec_mae *spec,
+ const struct rte_flow_action *action,
+ struct rte_flow_query_count *data,
+ struct rte_flow_error *error)
+{
+ struct sfc_mae_action_set *action_set = spec->action_set;
+ const struct rte_flow_action_count *conf = action->conf;
+ unsigned int i;
+ int rc;
+
+ if (action_set->n_counters == 0) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "Queried flow rule does not have count actions");
+ }
+
+ for (i = 0; i < action_set->n_counters; i++) {
+ /*
+ * Get the first available counter of the flow rule if
+ * counter ID is not specified.
+ */
+ if (conf != NULL && action_set->counters[i].rte_id != conf->id)
+ continue;
+
+ rc = sfc_mae_counter_get(&sa->mae.counter_registry.counters,
+ &action_set->counters[i], data);
+ if (rc != 0) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "Queried flow rule counter action is invalid");
+ }
+
+ return 0;
+ }
+
+ return rte_flow_error_set(error, ENOENT,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "No such flow rule action count ID");
+}
+
+int
+sfc_mae_flow_query(struct rte_eth_dev *dev,
+ struct rte_flow *flow,
+ const struct rte_flow_action *action,
+ void *data,
+ struct rte_flow_error *error)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ struct sfc_flow_spec *spec = &flow->spec;
+ struct sfc_flow_spec_mae *spec_mae = &spec->mae;
+
+ switch (action->type) {
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ return sfc_mae_query_counter(sa, spec_mae, action,
+ data, error);
+ default:
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "Query for action of this type is not supported");
+ }
+}