+
+/**
+ * Create general object of type FLOW_HIT_ASO using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ * @param [in] pd
+ * PD value to associate the FLOW_HIT_ASO object with.
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_flow_hit_aso_obj(void *ctx, uint32_t pd)
+{
+ uint32_t in[MLX5_ST_SZ_DW(create_flow_hit_aso_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
+ struct mlx5_devx_obj *flow_hit_aso_obj = NULL;
+ void *ptr = NULL;
+
+ flow_hit_aso_obj = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*flow_hit_aso_obj),
+ 0, SOCKET_ID_ANY);
+ if (!flow_hit_aso_obj) {
+ DRV_LOG(ERR, "Failed to allocate FLOW_HIT_ASO object data");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ ptr = MLX5_ADDR_OF(create_flow_hit_aso_in, in, hdr);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
+ MLX5_GENERAL_OBJ_TYPE_FLOW_HIT_ASO);
+ ptr = MLX5_ADDR_OF(create_flow_hit_aso_in, in, flow_hit_aso);
+ MLX5_SET(flow_hit_aso, ptr, access_pd, pd);
+ flow_hit_aso_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
+ out, sizeof(out));
+ if (!flow_hit_aso_obj->obj) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to create FLOW_HIT_ASO obj using DevX.");
+ mlx5_free(flow_hit_aso_obj);
+ return NULL;
+ }
+ flow_hit_aso_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+ return flow_hit_aso_obj;
+}
+
+/*
+ * Create PD using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_alloc_pd(void *ctx)
+{
+ struct mlx5_devx_obj *ppd =
+ mlx5_malloc(MLX5_MEM_ZERO, sizeof(*ppd), 0, SOCKET_ID_ANY);
+ u32 in[MLX5_ST_SZ_DW(alloc_pd_in)] = {0};
+ u32 out[MLX5_ST_SZ_DW(alloc_pd_out)] = {0};
+
+ if (!ppd) {
+ DRV_LOG(ERR, "Failed to allocate PD data.");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ MLX5_SET(alloc_pd_in, in, opcode, MLX5_CMD_OP_ALLOC_PD);
+ ppd->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
+ out, sizeof(out));
+ if (!ppd->obj) {
+ mlx5_free(ppd);
+ DRV_LOG(ERR, "Failed to allocate PD Obj using DevX.");
+ rte_errno = errno;
+ return NULL;
+ }
+ ppd->id = MLX5_GET(alloc_pd_out, out, pd);
+ return ppd;
+}
+
+/**
+ * Create general object of type FLOW_METER_ASO using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ * @param [in] pd
+ * PD value to associate the FLOW_METER_ASO object with.
+ * @param [in] log_obj_size
+ * log_obj_size define to allocate number of 2 * meters
+ * in one FLOW_METER_ASO object.
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_flow_meter_aso_obj(void *ctx, uint32_t pd,
+ uint32_t log_obj_size)
+{
+ uint32_t in[MLX5_ST_SZ_DW(create_flow_meter_aso_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
+ struct mlx5_devx_obj *flow_meter_aso_obj;
+ void *ptr;
+
+ flow_meter_aso_obj = mlx5_malloc(MLX5_MEM_ZERO,
+ sizeof(*flow_meter_aso_obj),
+ 0, SOCKET_ID_ANY);
+ if (!flow_meter_aso_obj) {
+ DRV_LOG(ERR, "Failed to allocate FLOW_METER_ASO object data");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ ptr = MLX5_ADDR_OF(create_flow_meter_aso_in, in, hdr);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
+ MLX5_GENERAL_OBJ_TYPE_FLOW_METER_ASO);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, log_obj_range,
+ log_obj_size);
+ ptr = MLX5_ADDR_OF(create_flow_meter_aso_in, in, flow_meter_aso);
+ MLX5_SET(flow_meter_aso, ptr, access_pd, pd);
+ flow_meter_aso_obj->obj = mlx5_glue->devx_obj_create(
+ ctx, in, sizeof(in),
+ out, sizeof(out));
+ if (!flow_meter_aso_obj->obj) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to create FLOW_METER_ASO obj using DevX.");
+ mlx5_free(flow_meter_aso_obj);
+ return NULL;
+ }
+ flow_meter_aso_obj->id = MLX5_GET(general_obj_out_cmd_hdr,
+ out, obj_id);
+ return flow_meter_aso_obj;
+}
+
+/*
+ * Create general object of type CONN_TRACK_OFFLOAD using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ * @param [in] pd
+ * PD value to associate the CONN_TRACK_OFFLOAD ASO object with.
+ * @param [in] log_obj_size
+ * log_obj_size to allocate its power of 2 * objects
+ * in one CONN_TRACK_OFFLOAD bulk allocation.
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_conn_track_offload_obj(void *ctx, uint32_t pd,
+ uint32_t log_obj_size)
+{
+ uint32_t in[MLX5_ST_SZ_DW(create_conn_track_aso_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
+ struct mlx5_devx_obj *ct_aso_obj;
+ void *ptr;
+
+ ct_aso_obj = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*ct_aso_obj),
+ 0, SOCKET_ID_ANY);
+ if (!ct_aso_obj) {
+ DRV_LOG(ERR, "Failed to allocate CONN_TRACK_OFFLOAD object.");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ ptr = MLX5_ADDR_OF(create_conn_track_aso_in, in, hdr);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
+ MLX5_GENERAL_OBJ_TYPE_CONN_TRACK_OFFLOAD);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, log_obj_range, log_obj_size);
+ ptr = MLX5_ADDR_OF(create_conn_track_aso_in, in, conn_track_offload);
+ MLX5_SET(conn_track_offload, ptr, conn_track_aso_access_pd, pd);
+ ct_aso_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
+ out, sizeof(out));
+ if (!ct_aso_obj->obj) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to create CONN_TRACK_OFFLOAD obj by using DevX.");
+ mlx5_free(ct_aso_obj);
+ return NULL;
+ }
+ ct_aso_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+ return ct_aso_obj;
+}
+
+/**
+ * Create general object of type GENEVE TLV option using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ * @param [in] class
+ * TLV option variable value of class
+ * @param [in] type
+ * TLV option variable value of type
+ * @param [in] len
+ * TLV option variable value of len
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_geneve_tlv_option(void *ctx,
+ uint16_t class, uint8_t type, uint8_t len)
+{
+ uint32_t in[MLX5_ST_SZ_DW(create_geneve_tlv_option_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
+ struct mlx5_devx_obj *geneve_tlv_opt_obj = mlx5_malloc(MLX5_MEM_ZERO,
+ sizeof(*geneve_tlv_opt_obj),
+ 0, SOCKET_ID_ANY);
+
+ if (!geneve_tlv_opt_obj) {
+ DRV_LOG(ERR, "Failed to allocate geneve tlv option object.");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ void *hdr = MLX5_ADDR_OF(create_geneve_tlv_option_in, in, hdr);
+ void *opt = MLX5_ADDR_OF(create_geneve_tlv_option_in, in,
+ geneve_tlv_opt);
+ MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type,
+ MLX5_GENERAL_OBJ_TYPE_GENEVE_TLV_OPT);
+ MLX5_SET(geneve_tlv_option, opt, option_class,
+ rte_be_to_cpu_16(class));
+ MLX5_SET(geneve_tlv_option, opt, option_type, type);
+ MLX5_SET(geneve_tlv_option, opt, option_data_length, len);
+ geneve_tlv_opt_obj->obj = mlx5_glue->devx_obj_create(ctx, in,
+ sizeof(in), out, sizeof(out));
+ if (!geneve_tlv_opt_obj->obj) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to create Geneve tlv option "
+ "Obj using DevX.");
+ mlx5_free(geneve_tlv_opt_obj);
+ return NULL;
+ }
+ geneve_tlv_opt_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+ return geneve_tlv_opt_obj;
+}
+
+int
+mlx5_devx_cmd_wq_query(void *wq, uint32_t *counter_set_id)
+{
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+ uint32_t in[MLX5_ST_SZ_DW(query_rq_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(query_rq_out)] = {0};
+ int rc;
+ void *rq_ctx;
+
+ MLX5_SET(query_rq_in, in, opcode, MLX5_CMD_OP_QUERY_RQ);
+ MLX5_SET(query_rq_in, in, rqn, ((struct ibv_wq *)wq)->wq_num);
+ rc = mlx5_glue->devx_wq_query(wq, in, sizeof(in), out, sizeof(out));
+ if (rc) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to query WQ counter set ID using DevX - "
+ "rc = %d, errno = %d.", rc, errno);
+ return -rc;
+ };
+ rq_ctx = MLX5_ADDR_OF(query_rq_out, out, rq_context);
+ *counter_set_id = MLX5_GET(rqc, rq_ctx, counter_set_id);
+ return 0;
+#else
+ (void)wq;
+ (void)counter_set_id;
+ return -ENOTSUP;
+#endif
+}
+
+/*
+ * Allocate queue counters via devx interface.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ *
+ * @return
+ * Pointer to counter object on success, a NULL value otherwise and
+ * rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_queue_counter_alloc(void *ctx)
+{
+ struct mlx5_devx_obj *dcs = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*dcs), 0,
+ SOCKET_ID_ANY);
+ uint32_t in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {0};
+
+ if (!dcs) {
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
+ dcs->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out,
+ sizeof(out));
+ if (!dcs->obj) {
+ DRV_LOG(DEBUG, "Can't allocate q counter set by DevX - error "
+ "%d.", errno);
+ rte_errno = errno;
+ mlx5_free(dcs);
+ return NULL;
+ }
+ dcs->id = MLX5_GET(alloc_q_counter_out, out, counter_set_id);
+ return dcs;
+}
+
+/**
+ * Query queue counters values.
+ *
+ * @param[in] dcs
+ * devx object of the queue counter set.
+ * @param[in] clear
+ * Whether hardware should clear the counters after the query or not.
+ * @param[out] out_of_buffers
+ * Number of dropped occurred due to lack of WQE for the associated QPs/RQs.
+ *
+ * @return
+ * 0 on success, a negative value otherwise.
+ */
+int
+mlx5_devx_cmd_queue_counter_query(struct mlx5_devx_obj *dcs, int clear,
+ uint32_t *out_of_buffers)
+{
+ uint32_t out[MLX5_ST_SZ_BYTES(query_q_counter_out)] = {0};
+ uint32_t in[MLX5_ST_SZ_DW(query_q_counter_in)] = {0};
+ int rc;
+
+ MLX5_SET(query_q_counter_in, in, opcode,
+ MLX5_CMD_OP_QUERY_Q_COUNTER);
+ MLX5_SET(query_q_counter_in, in, op_mod, 0);
+ MLX5_SET(query_q_counter_in, in, counter_set_id, dcs->id);
+ MLX5_SET(query_q_counter_in, in, clear, !!clear);
+ rc = mlx5_glue->devx_obj_query(dcs->obj, in, sizeof(in), out,
+ sizeof(out));
+ if (rc) {
+ DRV_LOG(ERR, "Failed to query devx q counter set - rc %d", rc);
+ rte_errno = rc;
+ return -rc;
+ }
+ *out_of_buffers = MLX5_GET(query_q_counter_out, out, out_of_buffer);
+ return 0;
+}
+
+/**
+ * Create general object of type DEK using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ * @param [in] attr
+ * Pointer to DEK attributes structure.
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_dek_obj(void *ctx, struct mlx5_devx_dek_attr *attr)
+{
+ uint32_t in[MLX5_ST_SZ_DW(create_dek_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
+ struct mlx5_devx_obj *dek_obj = NULL;
+ void *ptr = NULL, *key_addr = NULL;
+
+ dek_obj = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*dek_obj),
+ 0, SOCKET_ID_ANY);
+ if (dek_obj == NULL) {
+ DRV_LOG(ERR, "Failed to allocate DEK object data");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ ptr = MLX5_ADDR_OF(create_dek_in, in, hdr);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
+ MLX5_GENERAL_OBJ_TYPE_DEK);
+ ptr = MLX5_ADDR_OF(create_dek_in, in, dek);
+ MLX5_SET(dek, ptr, key_size, attr->key_size);
+ MLX5_SET(dek, ptr, has_keytag, attr->has_keytag);
+ MLX5_SET(dek, ptr, key_purpose, attr->key_purpose);
+ MLX5_SET(dek, ptr, pd, attr->pd);
+ MLX5_SET64(dek, ptr, opaque, attr->opaque);
+ key_addr = MLX5_ADDR_OF(dek, ptr, key);
+ memcpy(key_addr, (void *)(attr->key), MLX5_CRYPTO_KEY_MAX_SIZE);
+ dek_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
+ out, sizeof(out));
+ if (dek_obj->obj == NULL) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to create DEK obj using DevX.");
+ mlx5_free(dek_obj);
+ return NULL;
+ }
+ dek_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+ return dek_obj;
+}
+
+/**
+ * Create general object of type IMPORT_KEK using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ * @param [in] attr
+ * Pointer to IMPORT_KEK attributes structure.
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_import_kek_obj(void *ctx,
+ struct mlx5_devx_import_kek_attr *attr)
+{
+ uint32_t in[MLX5_ST_SZ_DW(create_import_kek_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
+ struct mlx5_devx_obj *import_kek_obj = NULL;
+ void *ptr = NULL, *key_addr = NULL;
+
+ import_kek_obj = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*import_kek_obj),
+ 0, SOCKET_ID_ANY);
+ if (import_kek_obj == NULL) {
+ DRV_LOG(ERR, "Failed to allocate IMPORT_KEK object data");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ ptr = MLX5_ADDR_OF(create_import_kek_in, in, hdr);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
+ MLX5_GENERAL_OBJ_TYPE_IMPORT_KEK);
+ ptr = MLX5_ADDR_OF(create_import_kek_in, in, import_kek);
+ MLX5_SET(import_kek, ptr, key_size, attr->key_size);
+ key_addr = MLX5_ADDR_OF(import_kek, ptr, key);
+ memcpy(key_addr, (void *)(attr->key), MLX5_CRYPTO_KEY_MAX_SIZE);
+ import_kek_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
+ out, sizeof(out));
+ if (import_kek_obj->obj == NULL) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to create IMPORT_KEK object using DevX.");
+ mlx5_free(import_kek_obj);
+ return NULL;
+ }
+ import_kek_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+ return import_kek_obj;
+}
+
+/**
+ * Create general object of type CREDENTIAL using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ * @param [in] attr
+ * Pointer to CREDENTIAL attributes structure.
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_credential_obj(void *ctx,
+ struct mlx5_devx_credential_attr *attr)
+{
+ uint32_t in[MLX5_ST_SZ_DW(create_credential_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
+ struct mlx5_devx_obj *credential_obj = NULL;
+ void *ptr = NULL, *credential_addr = NULL;
+
+ credential_obj = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*credential_obj),
+ 0, SOCKET_ID_ANY);
+ if (credential_obj == NULL) {
+ DRV_LOG(ERR, "Failed to allocate CREDENTIAL object data");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ ptr = MLX5_ADDR_OF(create_credential_in, in, hdr);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
+ MLX5_GENERAL_OBJ_TYPE_CREDENTIAL);
+ ptr = MLX5_ADDR_OF(create_credential_in, in, credential);
+ MLX5_SET(credential, ptr, credential_role, attr->credential_role);
+ credential_addr = MLX5_ADDR_OF(credential, ptr, credential);
+ memcpy(credential_addr, (void *)(attr->credential),
+ MLX5_CRYPTO_CREDENTIAL_SIZE);
+ credential_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
+ out, sizeof(out));
+ if (credential_obj->obj == NULL) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to create CREDENTIAL object using DevX.");
+ mlx5_free(credential_obj);
+ return NULL;
+ }
+ credential_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+ return credential_obj;
+}
+
+/**
+ * Create general object of type CRYPTO_LOGIN using DevX API.
+ *
+ * @param[in] ctx
+ * Context returned from mlx5 open_device() glue function.
+ * @param [in] attr
+ * Pointer to CRYPTO_LOGIN attributes structure.
+ *
+ * @return
+ * The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_crypto_login_obj(void *ctx,
+ struct mlx5_devx_crypto_login_attr *attr)
+{
+ uint32_t in[MLX5_ST_SZ_DW(create_crypto_login_in)] = {0};
+ uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
+ struct mlx5_devx_obj *crypto_login_obj = NULL;
+ void *ptr = NULL, *credential_addr = NULL;
+
+ crypto_login_obj = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*crypto_login_obj),
+ 0, SOCKET_ID_ANY);
+ if (crypto_login_obj == NULL) {
+ DRV_LOG(ERR, "Failed to allocate CRYPTO_LOGIN object data");
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ ptr = MLX5_ADDR_OF(create_crypto_login_in, in, hdr);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
+ MLX5_GENERAL_OBJ_TYPE_CRYPTO_LOGIN);
+ ptr = MLX5_ADDR_OF(create_crypto_login_in, in, crypto_login);
+ MLX5_SET(crypto_login, ptr, credential_pointer,
+ attr->credential_pointer);
+ MLX5_SET(crypto_login, ptr, session_import_kek_ptr,
+ attr->session_import_kek_ptr);
+ credential_addr = MLX5_ADDR_OF(crypto_login, ptr, credential);
+ memcpy(credential_addr, (void *)(attr->credential),
+ MLX5_CRYPTO_CREDENTIAL_SIZE);
+ crypto_login_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
+ out, sizeof(out));
+ if (crypto_login_obj->obj == NULL) {
+ rte_errno = errno;
+ DRV_LOG(ERR, "Failed to create CRYPTO_LOGIN obj using DevX.");
+ mlx5_free(crypto_login_obj);
+ return NULL;
+ }
+ crypto_login_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+ return crypto_login_obj;
+}