diff mbox series

[v3,14/15] common/mlx5: support register write access

Message ID 20210504175500.3385811-15-matan@nvidia.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers show
Series mlx5 common part for crypto driver | expand

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Matan Azrad May 4, 2021, 5:54 p.m. UTC
From: Dekel Peled <dekelp@nvidia.com>

This patch adds support of write operation to NIC registers.

Signed-off-by: Dekel Peled <dekelp@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c | 67 +++++++++++++++++++++++++++-
 drivers/common/mlx5/mlx5_devx_cmds.h |  4 ++
 drivers/common/mlx5/version.map      |  1 +
 3 files changed, 70 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index c0a0853c3a..0b421933ce 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -12,7 +12,6 @@ 
 #include "mlx5_common_log.h"
 #include "mlx5_malloc.h"
 
-
 /**
  * Perform read access to the registers. Reads data from register
  * and writes ones to the specified buffer.
@@ -61,7 +60,7 @@  mlx5_devx_cmd_register_read(void *ctx, uint16_t reg_id, uint32_t arg,
 	if (status) {
 		int syndrome = MLX5_GET(access_register_out, out, syndrome);
 
-		DRV_LOG(DEBUG, "Failed to access NIC register 0x%X, "
+		DRV_LOG(DEBUG, "Failed to read access NIC register 0x%X, "
 			       "status %x, syndrome = %x",
 			       reg_id, status, syndrome);
 		return -1;
@@ -74,6 +73,70 @@  mlx5_devx_cmd_register_read(void *ctx, uint16_t reg_id, uint32_t arg,
 	return rc;
 }
 
+/**
+ * Perform write access to the registers.
+ *
+ * @param[in] ctx
+ *   Context returned from mlx5 open_device() glue function.
+ * @param[in] reg_id
+ *   Register identifier according to the PRM.
+ * @param[in] arg
+ *   Register access auxiliary parameter according to the PRM.
+ * @param[out] data
+ *   Pointer to the buffer containing data to write.
+ * @param[in] dw_cnt
+ *   Buffer size in double words (32bit units).
+ *
+ * @return
+ *   0 on success, a negative value otherwise.
+ */
+int
+mlx5_devx_cmd_register_write(void *ctx, uint16_t reg_id, uint32_t arg,
+			     uint32_t *data, uint32_t dw_cnt)
+{
+	uint32_t in[MLX5_ST_SZ_DW(access_register_in) +
+		    MLX5_ACCESS_REGISTER_DATA_DWORD_MAX] = {0};
+	uint32_t out[MLX5_ST_SZ_DW(access_register_out)] = {0};
+	int status, rc;
+	void *ptr;
+
+	MLX5_ASSERT(data && dw_cnt);
+	MLX5_ASSERT(dw_cnt <= MLX5_ACCESS_REGISTER_DATA_DWORD_MAX);
+	if (dw_cnt > MLX5_ACCESS_REGISTER_DATA_DWORD_MAX) {
+		DRV_LOG(ERR, "Data to write exceeds max size");
+		return -1;
+	}
+	MLX5_SET(access_register_in, in, opcode,
+		 MLX5_CMD_OP_ACCESS_REGISTER_USER);
+	MLX5_SET(access_register_in, in, op_mod,
+		 MLX5_ACCESS_REGISTER_IN_OP_MOD_WRITE);
+	MLX5_SET(access_register_in, in, register_id, reg_id);
+	MLX5_SET(access_register_in, in, argument, arg);
+	ptr = MLX5_ADDR_OF(access_register_in, in, register_data);
+	memcpy(ptr, data, dw_cnt * sizeof(uint32_t));
+	rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
+
+	rc = mlx5_glue->devx_general_cmd(ctx, in,
+					 MLX5_ST_SZ_BYTES(access_register_in) +
+					 dw_cnt * sizeof(uint32_t),
+					 out, sizeof(out));
+	if (rc)
+		goto error;
+	status = MLX5_GET(access_register_out, out, status);
+	if (status) {
+		int syndrome = MLX5_GET(access_register_out, out, syndrome);
+
+		DRV_LOG(DEBUG, "Failed to write access NIC register 0x%X, "
+			       "status %x, syndrome = %x",
+			       reg_id, status, syndrome);
+		return -1;
+	}
+	return 0;
+error:
+	rc = (rc > 0) ? -rc : rc;
+	return rc;
+}
+
 /**
  * Allocate flow counters via devx interface.
  *
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index 811e7a1462..ce570ad28a 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -566,6 +566,10 @@  __rte_internal
 int mlx5_devx_cmd_register_read(void *ctx, uint16_t reg_id,
 				uint32_t arg, uint32_t *data, uint32_t dw_cnt);
 
+__rte_internal
+int mlx5_devx_cmd_register_write(void *ctx, uint16_t reg_id,
+				 uint32_t arg, uint32_t *data, uint32_t dw_cnt);
+
 __rte_internal
 struct mlx5_devx_obj *
 mlx5_devx_cmd_create_geneve_tlv_option(void *ctx,
diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map
index 04b2179b2c..c630696213 100644
--- a/drivers/common/mlx5/version.map
+++ b/drivers/common/mlx5/version.map
@@ -53,6 +53,7 @@  INTERNAL {
 	mlx5_devx_cmd_queue_counter_alloc; # WINDOWS_NO_EXPORT
 	mlx5_devx_cmd_queue_counter_query; # WINDOWS_NO_EXPORT
 	mlx5_devx_cmd_register_read;
+	mlx5_devx_cmd_register_write;
 	mlx5_devx_cmd_wq_query; # WINDOWS_NO_EXPORT
 
 	mlx5_devx_cq_create;