summaryrefslogtreecommitdiff
path: root/drivers/net/mlx5/mlx5_devx_cmds.c
diff options
context:
space:
mode:
authorMoti Haimovsky <motih@mellanox.com>2019-01-03 15:06:37 +0000
committerFerruh Yigit <ferruh.yigit@intel.com>2019-01-14 17:44:29 +0100
commitf5bf91de738a3eeebb262c5cccc2eb6e7f4245a5 (patch)
tree96560afe3d43b66c8e8fd96884c045c6fbe9c6e5 /drivers/net/mlx5/mlx5_devx_cmds.c
parent6de1ffaa41128ba81ee7f4c062e8d6932b9ac4f5 (diff)
downloaddpdk-next-eventdev-f5bf91de738a3eeebb262c5cccc2eb6e7f4245a5.zip
dpdk-next-eventdev-f5bf91de738a3eeebb262c5cccc2eb6e7f4245a5.tar.gz
dpdk-next-eventdev-f5bf91de738a3eeebb262c5cccc2eb6e7f4245a5.tar.xz
net/mlx5: support flow counters using devx
This commit adds counters support when creating flows via direct verbs. The implementation uses devx interface in order to create query and delete the counters. This support requires MLNX_OFED_LINUX-4.5-0.1.0.1 installation. Signed-off-by: Moti Haimovsky <motih@mellanox.com> Acked-by: Shahaf Shuler <shahafs@mellanox.com>
Diffstat (limited to 'drivers/net/mlx5/mlx5_devx_cmds.c')
-rw-r--r--drivers/net/mlx5/mlx5_devx_cmds.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/drivers/net/mlx5/mlx5_devx_cmds.c b/drivers/net/mlx5/mlx5_devx_cmds.c
new file mode 100644
index 0000000..a9dff58
--- /dev/null
+++ b/drivers/net/mlx5/mlx5_devx_cmds.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Copyright 2018 Mellanox Technologies, Ltd */
+
+#include <rte_flow_driver.h>
+
+#include "mlx5.h"
+#include "mlx5_glue.h"
+#include "mlx5_prm.h"
+
+/**
+ * Allocate flow counters via devx interface.
+ *
+ * @param[in] ctx
+ * ibv contexts returned from mlx5dv_open_device.
+ * @param dcs
+ * Pointer to counters properties structure to be filled by the routine.
+ *
+ * @return
+ * 0 on success, a negative value otherwise.
+ */
+int mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx,
+ struct mlx5_devx_counter_set *dcs)
+{
+ uint32_t in[MLX5_ST_SZ_DW(alloc_flow_counter_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {0};
+ int status, syndrome;
+
+ MLX5_SET(alloc_flow_counter_in, in, opcode,
+ MLX5_CMD_OP_ALLOC_FLOW_COUNTER);
+ dcs->obj = mlx5_glue->devx_obj_create(ctx, in,
+ sizeof(in), out, sizeof(out));
+ if (!dcs->obj)
+ return -errno;
+ status = MLX5_GET(query_flow_counter_out, out, status);
+ syndrome = MLX5_GET(query_flow_counter_out, out, syndrome);
+ if (status) {
+ DRV_LOG(DEBUG, "Failed to create devx counters, "
+ "status %x, syndrome %x", status, syndrome);
+ return -1;
+ }
+ dcs->id = MLX5_GET(alloc_flow_counter_out,
+ out, flow_counter_id);
+ return 0;
+}
+
+/**
+ * Free flow counters obtained via devx interface.
+ *
+ * @param[in] obj
+ * devx object that was obtained from mlx5_devx_cmd_fc_alloc.
+ *
+ * @return
+ * 0 on success, a negative value otherwise.
+ */
+int mlx5_devx_cmd_flow_counter_free(struct mlx5dv_devx_obj *obj)
+{
+ return mlx5_glue->devx_obj_destroy(obj);
+}
+
+/**
+ * Query flow counters values.
+ *
+ * @param[in] dcs
+ * devx object that was obtained from mlx5_devx_cmd_fc_alloc.
+ * @param[in] clear
+ * Whether hardware should clear the counters after the query or not.
+ * @param pkts
+ * The number of packets that matched the flow.
+ * @param bytes
+ * The number of bytes that matched the flow.
+ *
+ * @return
+ * 0 on success, a negative value otherwise.
+ */
+int
+mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_counter_set *dcs,
+ int clear __rte_unused,
+ uint64_t *pkts, uint64_t *bytes)
+{
+ uint32_t out[MLX5_ST_SZ_BYTES(query_flow_counter_out) +
+ MLX5_ST_SZ_BYTES(traffic_counter)] = {0};
+ uint32_t in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0};
+ void *stats;
+ int status, syndrome, rc;
+
+ MLX5_SET(query_flow_counter_in, in, opcode,
+ MLX5_CMD_OP_QUERY_FLOW_COUNTER);
+ MLX5_SET(query_flow_counter_in, in, op_mod, 0);
+ MLX5_SET(query_flow_counter_in, in, flow_counter_id, dcs->id);
+ rc = mlx5_glue->devx_obj_query(dcs->obj,
+ in, sizeof(in), out, sizeof(out));
+ if (rc)
+ return rc;
+ status = MLX5_GET(query_flow_counter_out, out, status);
+ syndrome = MLX5_GET(query_flow_counter_out, out, syndrome);
+ if (status) {
+ DRV_LOG(DEBUG, "Failed to query devx counters, "
+ "id %d, status %x, syndrome = %x",
+ status, syndrome, dcs->id);
+ return -1;
+ }
+ stats = MLX5_ADDR_OF(query_flow_counter_out,
+ out, flow_statistics);
+ *pkts = MLX5_GET64(traffic_counter, stats, packets);
+ *bytes = MLX5_GET64(traffic_counter, stats, octets);
+ return 0;
+}