X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fmlx5%2Fmlx5_devx_cmds.c;h=63ae95832d8f4f4f97be5baaaf554e62211aa490;hb=9a4c36880704438a8801cf4c58a434b04007a91c;hp=6c6f4391a1abc8f1aa6a040821f20469f129b622;hpb=894711d3fea4cdee130c5e282beef8f00239c8b2;p=dpdk.git diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 6c6f4391a1..63ae95832d 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -1,5 +1,6 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2018 Mellanox Technologies, Ltd */ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 Mellanox Technologies, Ltd + */ #include @@ -9,10 +10,9 @@ #include "mlx5_prm.h" #include "mlx5_devx_cmds.h" -#include "mlx5_common_utils.h" +#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 +61,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 +74,70 @@ error: 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. * @@ -263,6 +327,10 @@ mlx5_devx_cmd_mkey_create(void *ctx, MLX5_SET(create_mkey_in, in, pg_access, attr->pg_access); MLX5_SET(mkc, mkc, lw, 0x1); MLX5_SET(mkc, mkc, lr, 0x1); + if (attr->set_remote_rw) { + MLX5_SET(mkc, mkc, rw, 0x1); + MLX5_SET(mkc, mkc, rr, 0x1); + } MLX5_SET(mkc, mkc, qpn, 0xffffff); MLX5_SET(mkc, mkc, pd, attr->pd); MLX5_SET(mkc, mkc, mkey_7_0, attr->umem_id & 0xFF); @@ -273,6 +341,11 @@ mlx5_devx_cmd_mkey_create(void *ctx, MLX5_SET(mkc, mkc, relaxed_ordering_read, attr->relaxed_ordering_read); MLX5_SET64(mkc, mkc, start_addr, attr->addr); MLX5_SET64(mkc, mkc, len, attr->size); + MLX5_SET(mkc, mkc, crypto_en, attr->crypto_en); + if (attr->crypto_en) { + MLX5_SET(mkc, mkc, bsf_en, attr->crypto_en); + MLX5_SET(mkc, mkc, bsf_octword_size, 4); + } mkey->obj = mlx5_glue->devx_obj_create(ctx, in, in_size_dw * 4, out, sizeof(out)); if (!mkey->obj) { @@ -626,6 +699,29 @@ mlx5_devx_cmd_create_flex_parser(void *ctx, return parse_flex_obj; } +static int +mlx5_devx_query_pkt_integrity_match(void *hcattr) +{ + return MLX5_GET(flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive.inner_l3_ok) && + MLX5_GET(flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive.inner_l4_ok) && + MLX5_GET(flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive.outer_l3_ok) && + MLX5_GET(flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive.outer_l4_ok) && + MLX5_GET(flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive + .inner_ipv4_checksum_ok) && + MLX5_GET(flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive.inner_l4_checksum_ok) && + MLX5_GET(flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive + .outer_ipv4_checksum_ok) && + MLX5_GET(flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive.outer_l4_checksum_ok); +} + /** * Query HCA attributes. * Using those attributes we can check on run time if the device @@ -647,6 +743,7 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0}; void *hcattr; int status, syndrome, rc, i; + uint64_t general_obj_types_supported = 0; MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); MLX5_SET(query_hca_cap_in, in, op_mod, @@ -725,12 +822,30 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, attr->regex = MLX5_GET(cmd_hca_cap, hcattr, regexp); attr->regexp_num_of_engines = MLX5_GET(cmd_hca_cap, hcattr, regexp_num_of_engines); - attr->flow_hit_aso = !!(MLX5_GET64(cmd_hca_cap, hcattr, - general_obj_types) & + /* Read the general_obj_types bitmap and extract the relevant bits. */ + general_obj_types_supported = MLX5_GET64(cmd_hca_cap, hcattr, + general_obj_types); + attr->vdpa.valid = !!(general_obj_types_supported & + MLX5_GENERAL_OBJ_TYPES_CAP_VIRTQ_NET_Q); + attr->vdpa.queue_counters_valid = + !!(general_obj_types_supported & + MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_Q_COUNTERS); + attr->parse_graph_flex_node = + !!(general_obj_types_supported & + MLX5_GENERAL_OBJ_TYPES_CAP_PARSE_GRAPH_FLEX_NODE); + attr->flow_hit_aso = !!(general_obj_types_supported & MLX5_GENERAL_OBJ_TYPES_CAP_FLOW_HIT_ASO); - attr->geneve_tlv_opt = !!(MLX5_GET64(cmd_hca_cap, hcattr, - general_obj_types) & - MLX5_GENERAL_OBJ_TYPES_CAP_GENEVE_TLV_OPT); + attr->geneve_tlv_opt = !!(general_obj_types_supported & + MLX5_GENERAL_OBJ_TYPES_CAP_GENEVE_TLV_OPT); + attr->dek = !!(general_obj_types_supported & + MLX5_GENERAL_OBJ_TYPES_CAP_DEK); + attr->import_kek = !!(general_obj_types_supported & + MLX5_GENERAL_OBJ_TYPES_CAP_IMPORT_KEK); + attr->credential = !!(general_obj_types_supported & + MLX5_GENERAL_OBJ_TYPES_CAP_CREDENTIAL); + attr->crypto_login = !!(general_obj_types_supported & + MLX5_GENERAL_OBJ_TYPES_CAP_CRYPTO_LOGIN); + /* Add reading of other GENERAL_OBJ_TYPES_CAP bits above this line. */ attr->log_max_cq = MLX5_GET(cmd_hca_cap, hcattr, log_max_cq); attr->log_max_qp = MLX5_GET(cmd_hca_cap, hcattr, log_max_qp); attr->log_max_cq_sz = MLX5_GET(cmd_hca_cap, hcattr, log_max_cq_sz); @@ -760,6 +875,12 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, MLX5_GET(cmd_hca_cap, hcattr, umr_indirect_mkey_disabled); attr->umr_modify_entity_size_disabled = MLX5_GET(cmd_hca_cap, hcattr, umr_modify_entity_size_disabled); + attr->crypto = MLX5_GET(cmd_hca_cap, hcattr, crypto); + if (attr->crypto) + attr->aes_xts = MLX5_GET(cmd_hca_cap, hcattr, aes_xts); + attr->ct_offload = !!(MLX5_GET64(cmd_hca_cap, hcattr, + general_obj_types) & + MLX5_GENERAL_OBJ_TYPES_CAP_CONN_TRACK_OFFLOAD); if (attr->qos.sup) { MLX5_SET(query_hca_cap_in, in, op_mod, MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | @@ -823,10 +944,13 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, return -1; } hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); - attr->log_max_ft_sampler_num = - MLX5_GET(flow_table_nic_cap, - hcattr, flow_table_properties.log_max_ft_sampler_num); - + attr->log_max_ft_sampler_num = MLX5_GET + (flow_table_nic_cap, hcattr, + flow_table_properties_nic_receive.log_max_ft_sampler_num); + attr->flow.tunnel_header_0_1 = MLX5_GET + (flow_table_nic_cap, hcattr, + ft_field_support_2_nic_receive.tunnel_header_0_1); + attr->pkt_integrity_match = mlx5_devx_query_pkt_integrity_match(hcattr); /* Query HCA offloads for Ethernet protocol. */ memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); @@ -851,6 +975,8 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); attr->wqe_vlan_insert = MLX5_GET(per_protocol_networking_offload_caps, hcattr, wqe_vlan_insert); + attr->csum_cap = MLX5_GET(per_protocol_networking_offload_caps, + hcattr, csum_cap); attr->lro_cap = MLX5_GET(per_protocol_networking_offload_caps, hcattr, lro_cap); attr->tunnel_lro_gre = MLX5_GET(per_protocol_networking_offload_caps, @@ -2227,6 +2353,56 @@ mlx5_devx_cmd_create_flow_meter_aso_obj(void *ctx, uint32_t pd, 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. * @@ -2263,7 +2439,7 @@ mlx5_devx_cmd_create_geneve_tlv_option(void *ctx, 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_OBJ_TYPE_GENEVE_TLV_OPT); + 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); @@ -2381,3 +2557,203 @@ mlx5_devx_cmd_queue_counter_query(struct mlx5_devx_obj *dcs, int clear, *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; +}