+static int
+enic_flow_query_count(struct rte_eth_dev *dev,
+ struct rte_flow *flow, void *data,
+ struct rte_flow_error *error)
+{
+ struct enic *enic = pmd_priv(dev);
+ struct rte_flow_query_count *query;
+ uint64_t packets, bytes;
+
+ FLOW_TRACE();
+
+ if (flow->counter_idx == -1) {
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL,
+ "flow does not have counter");
+ }
+ query = (struct rte_flow_query_count *)data;
+ if (!vnic_dev_counter_query(enic->vdev, flow->counter_idx,
+ !!query->reset, &packets, &bytes)) {
+ return rte_flow_error_set
+ (error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL,
+ "cannot read counter");
+ }
+ query->hits_set = 1;
+ query->bytes_set = 1;
+ query->hits = packets;
+ query->bytes = bytes;
+ return 0;
+}
+
+static int
+enic_flow_query(struct rte_eth_dev *dev,
+ struct rte_flow *flow,
+ const struct rte_flow_action *actions,
+ void *data,
+ struct rte_flow_error *error)
+{
+ int ret = 0;
+
+ FLOW_TRACE();
+
+ for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
+ switch (actions->type) {
+ case RTE_FLOW_ACTION_TYPE_VOID:
+ break;
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ ret = enic_flow_query_count(dev, flow, data, error);
+ break;
+ default:
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ actions,
+ "action not supported");
+ }
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+