19dab4d62SMichael Baum /* SPDX-License-Identifier: BSD-3-Clause
29dab4d62SMichael Baum * Copyright 2020 Mellanox Technologies, Ltd
39dab4d62SMichael Baum */
49dab4d62SMichael Baum #include <stdint.h>
59dab4d62SMichael Baum
69dab4d62SMichael Baum #include <rte_errno.h>
79dab4d62SMichael Baum #include <rte_common.h>
89dab4d62SMichael Baum #include <rte_eal_paging.h>
99dab4d62SMichael Baum
109dab4d62SMichael Baum #include <mlx5_glue.h>
119dab4d62SMichael Baum #include <mlx5_common_os.h>
129dab4d62SMichael Baum
139dab4d62SMichael Baum #include "mlx5_prm.h"
149dab4d62SMichael Baum #include "mlx5_devx_cmds.h"
1525245d5dSShiri Kuzin #include "mlx5_common_log.h"
169dab4d62SMichael Baum #include "mlx5_malloc.h"
179dab4d62SMichael Baum #include "mlx5_common.h"
189dab4d62SMichael Baum #include "mlx5_common_devx.h"
199dab4d62SMichael Baum
209dab4d62SMichael Baum /**
219dab4d62SMichael Baum * Destroy DevX Completion Queue.
229dab4d62SMichael Baum *
239dab4d62SMichael Baum * @param[in] cq
249dab4d62SMichael Baum * DevX CQ to destroy.
259dab4d62SMichael Baum */
269dab4d62SMichael Baum void
mlx5_devx_cq_destroy(struct mlx5_devx_cq * cq)279dab4d62SMichael Baum mlx5_devx_cq_destroy(struct mlx5_devx_cq *cq)
289dab4d62SMichael Baum {
299dab4d62SMichael Baum if (cq->cq)
309dab4d62SMichael Baum claim_zero(mlx5_devx_cmd_destroy(cq->cq));
319dab4d62SMichael Baum if (cq->umem_obj)
329dab4d62SMichael Baum claim_zero(mlx5_os_umem_dereg(cq->umem_obj));
339dab4d62SMichael Baum if (cq->umem_buf)
349dab4d62SMichael Baum mlx5_free((void *)(uintptr_t)cq->umem_buf);
359dab4d62SMichael Baum }
369dab4d62SMichael Baum
379dab4d62SMichael Baum /* Mark all CQEs initially as invalid. */
389dab4d62SMichael Baum static void
mlx5_cq_init(struct mlx5_devx_cq * cq_obj,uint16_t cq_size)399dab4d62SMichael Baum mlx5_cq_init(struct mlx5_devx_cq *cq_obj, uint16_t cq_size)
409dab4d62SMichael Baum {
419dab4d62SMichael Baum volatile struct mlx5_cqe *cqe = cq_obj->cqes;
429dab4d62SMichael Baum uint16_t i;
439dab4d62SMichael Baum
44*a7da07e5SAlexander Kozyrev for (i = 0; i < cq_size; i++, cqe++) {
459dab4d62SMichael Baum cqe->op_own = (MLX5_CQE_INVALID << 4) | MLX5_CQE_OWNER_MASK;
46*a7da07e5SAlexander Kozyrev cqe->validity_iteration_count = MLX5_CQE_VIC_INIT;
47*a7da07e5SAlexander Kozyrev }
489dab4d62SMichael Baum }
499dab4d62SMichael Baum
509dab4d62SMichael Baum /**
519dab4d62SMichael Baum * Create Completion Queue using DevX API.
529dab4d62SMichael Baum *
539dab4d62SMichael Baum * Get a pointer to partially initialized attributes structure, and updates the
549dab4d62SMichael Baum * following fields:
559dab4d62SMichael Baum * q_umem_valid
569dab4d62SMichael Baum * q_umem_id
579dab4d62SMichael Baum * q_umem_offset
589dab4d62SMichael Baum * db_umem_valid
599dab4d62SMichael Baum * db_umem_id
609dab4d62SMichael Baum * db_umem_offset
619dab4d62SMichael Baum * eqn
629dab4d62SMichael Baum * log_cq_size
639dab4d62SMichael Baum * log_page_size
649dab4d62SMichael Baum * All other fields are updated by caller.
659dab4d62SMichael Baum *
669dab4d62SMichael Baum * @param[in] ctx
679dab4d62SMichael Baum * Context returned from mlx5 open_device() glue function.
689dab4d62SMichael Baum * @param[in/out] cq_obj
699dab4d62SMichael Baum * Pointer to CQ to create.
709dab4d62SMichael Baum * @param[in] log_desc_n
719dab4d62SMichael Baum * Log of number of descriptors in queue.
729dab4d62SMichael Baum * @param[in] attr
739dab4d62SMichael Baum * Pointer to CQ attributes structure.
749dab4d62SMichael Baum * @param[in] socket
759dab4d62SMichael Baum * Socket to use for allocation.
769dab4d62SMichael Baum *
779dab4d62SMichael Baum * @return
789dab4d62SMichael Baum * 0 on success, a negative errno value otherwise and rte_errno is set.
799dab4d62SMichael Baum */
809dab4d62SMichael Baum int
mlx5_devx_cq_create(void * ctx,struct mlx5_devx_cq * cq_obj,uint16_t log_desc_n,struct mlx5_devx_cq_attr * attr,int socket)819dab4d62SMichael Baum mlx5_devx_cq_create(void *ctx, struct mlx5_devx_cq *cq_obj, uint16_t log_desc_n,
829dab4d62SMichael Baum struct mlx5_devx_cq_attr *attr, int socket)
839dab4d62SMichael Baum {
849dab4d62SMichael Baum struct mlx5_devx_obj *cq = NULL;
859dab4d62SMichael Baum struct mlx5dv_devx_umem *umem_obj = NULL;
869dab4d62SMichael Baum void *umem_buf = NULL;
879dab4d62SMichael Baum size_t page_size = rte_mem_page_size();
889dab4d62SMichael Baum size_t alignment = MLX5_CQE_BUF_ALIGNMENT;
899dab4d62SMichael Baum uint32_t umem_size, umem_dbrec;
909dab4d62SMichael Baum uint32_t eqn;
9154feeab1SRaja Zidane uint32_t num_of_cqes = RTE_BIT32(log_desc_n);
929dab4d62SMichael Baum int ret;
939dab4d62SMichael Baum
949dab4d62SMichael Baum if (page_size == (size_t)-1 || alignment == (size_t)-1) {
959dab4d62SMichael Baum DRV_LOG(ERR, "Failed to get page_size.");
969dab4d62SMichael Baum rte_errno = ENOMEM;
979dab4d62SMichael Baum return -rte_errno;
989dab4d62SMichael Baum }
999dab4d62SMichael Baum /* Query first EQN. */
1009dab4d62SMichael Baum ret = mlx5_glue->devx_query_eqn(ctx, 0, &eqn);
1019dab4d62SMichael Baum if (ret) {
1029dab4d62SMichael Baum rte_errno = errno;
1039dab4d62SMichael Baum DRV_LOG(ERR, "Failed to query event queue number.");
1049dab4d62SMichael Baum return -rte_errno;
1059dab4d62SMichael Baum }
1069dab4d62SMichael Baum /* Allocate memory buffer for CQEs and doorbell record. */
10754feeab1SRaja Zidane umem_size = sizeof(struct mlx5_cqe) * num_of_cqes;
1089dab4d62SMichael Baum umem_dbrec = RTE_ALIGN(umem_size, MLX5_DBR_SIZE);
1099dab4d62SMichael Baum umem_size += MLX5_DBR_SIZE;
1109dab4d62SMichael Baum umem_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, umem_size,
1119dab4d62SMichael Baum alignment, socket);
1129dab4d62SMichael Baum if (!umem_buf) {
1139dab4d62SMichael Baum DRV_LOG(ERR, "Failed to allocate memory for CQ.");
1149dab4d62SMichael Baum rte_errno = ENOMEM;
1159dab4d62SMichael Baum return -rte_errno;
1169dab4d62SMichael Baum }
1179dab4d62SMichael Baum /* Register allocated buffer in user space with DevX. */
1189dab4d62SMichael Baum umem_obj = mlx5_os_umem_reg(ctx, (void *)(uintptr_t)umem_buf, umem_size,
1199dab4d62SMichael Baum IBV_ACCESS_LOCAL_WRITE);
1209dab4d62SMichael Baum if (!umem_obj) {
1219dab4d62SMichael Baum DRV_LOG(ERR, "Failed to register umem for CQ.");
1229dab4d62SMichael Baum rte_errno = errno;
1239dab4d62SMichael Baum goto error;
1249dab4d62SMichael Baum }
1259dab4d62SMichael Baum /* Fill attributes for CQ object creation. */
1269dab4d62SMichael Baum attr->q_umem_valid = 1;
1279dab4d62SMichael Baum attr->q_umem_id = mlx5_os_get_umem_id(umem_obj);
1289dab4d62SMichael Baum attr->q_umem_offset = 0;
1299dab4d62SMichael Baum attr->db_umem_valid = 1;
1309dab4d62SMichael Baum attr->db_umem_id = attr->q_umem_id;
1319dab4d62SMichael Baum attr->db_umem_offset = umem_dbrec;
1329dab4d62SMichael Baum attr->eqn = eqn;
1339dab4d62SMichael Baum attr->log_cq_size = log_desc_n;
1349dab4d62SMichael Baum attr->log_page_size = rte_log2_u32(page_size);
1359dab4d62SMichael Baum /* Create completion queue object with DevX. */
1369dab4d62SMichael Baum cq = mlx5_devx_cmd_create_cq(ctx, attr);
1379dab4d62SMichael Baum if (!cq) {
1389dab4d62SMichael Baum DRV_LOG(ERR, "Can't create DevX CQ object.");
1399dab4d62SMichael Baum rte_errno = ENOMEM;
1409dab4d62SMichael Baum goto error;
1419dab4d62SMichael Baum }
1429dab4d62SMichael Baum cq_obj->umem_buf = umem_buf;
1439dab4d62SMichael Baum cq_obj->umem_obj = umem_obj;
1449dab4d62SMichael Baum cq_obj->cq = cq;
1459dab4d62SMichael Baum cq_obj->db_rec = RTE_PTR_ADD(cq_obj->umem_buf, umem_dbrec);
1469dab4d62SMichael Baum /* Mark all CQEs initially as invalid. */
14754feeab1SRaja Zidane mlx5_cq_init(cq_obj, num_of_cqes);
1489dab4d62SMichael Baum return 0;
1499dab4d62SMichael Baum error:
1509dab4d62SMichael Baum ret = rte_errno;
1519dab4d62SMichael Baum if (umem_obj)
1529dab4d62SMichael Baum claim_zero(mlx5_os_umem_dereg(umem_obj));
1539dab4d62SMichael Baum if (umem_buf)
1549dab4d62SMichael Baum mlx5_free((void *)(uintptr_t)umem_buf);
1559dab4d62SMichael Baum rte_errno = ret;
1569dab4d62SMichael Baum return -rte_errno;
1579dab4d62SMichael Baum }
15838f53763SMichael Baum
15938f53763SMichael Baum /**
16038f53763SMichael Baum * Destroy DevX Send Queue.
16138f53763SMichael Baum *
16238f53763SMichael Baum * @param[in] sq
16338f53763SMichael Baum * DevX SQ to destroy.
16438f53763SMichael Baum */
16538f53763SMichael Baum void
mlx5_devx_sq_destroy(struct mlx5_devx_sq * sq)16638f53763SMichael Baum mlx5_devx_sq_destroy(struct mlx5_devx_sq *sq)
16738f53763SMichael Baum {
16838f53763SMichael Baum if (sq->sq)
16938f53763SMichael Baum claim_zero(mlx5_devx_cmd_destroy(sq->sq));
17038f53763SMichael Baum if (sq->umem_obj)
17138f53763SMichael Baum claim_zero(mlx5_os_umem_dereg(sq->umem_obj));
17238f53763SMichael Baum if (sq->umem_buf)
17338f53763SMichael Baum mlx5_free((void *)(uintptr_t)sq->umem_buf);
17438f53763SMichael Baum }
17538f53763SMichael Baum
17638f53763SMichael Baum /**
17738f53763SMichael Baum * Create Send Queue using DevX API.
17838f53763SMichael Baum *
17938f53763SMichael Baum * Get a pointer to partially initialized attributes structure, and updates the
18038f53763SMichael Baum * following fields:
18138f53763SMichael Baum * wq_type
18238f53763SMichael Baum * wq_umem_valid
18338f53763SMichael Baum * wq_umem_id
18438f53763SMichael Baum * wq_umem_offset
18538f53763SMichael Baum * dbr_umem_valid
18638f53763SMichael Baum * dbr_umem_id
18738f53763SMichael Baum * dbr_addr
18838f53763SMichael Baum * log_wq_stride
18938f53763SMichael Baum * log_wq_sz
19038f53763SMichael Baum * log_wq_pg_sz
19138f53763SMichael Baum * All other fields are updated by caller.
19238f53763SMichael Baum *
19338f53763SMichael Baum * @param[in] ctx
19438f53763SMichael Baum * Context returned from mlx5 open_device() glue function.
19538f53763SMichael Baum * @param[in/out] sq_obj
19638f53763SMichael Baum * Pointer to SQ to create.
19738f53763SMichael Baum * @param[in] log_wqbb_n
19838f53763SMichael Baum * Log of number of WQBBs in queue.
19938f53763SMichael Baum * @param[in] attr
20038f53763SMichael Baum * Pointer to SQ attributes structure.
20138f53763SMichael Baum * @param[in] socket
20238f53763SMichael Baum * Socket to use for allocation.
20338f53763SMichael Baum *
20438f53763SMichael Baum * @return
20538f53763SMichael Baum * 0 on success, a negative errno value otherwise and rte_errno is set.
20638f53763SMichael Baum */
20738f53763SMichael Baum int
mlx5_devx_sq_create(void * ctx,struct mlx5_devx_sq * sq_obj,uint16_t log_wqbb_n,struct mlx5_devx_create_sq_attr * attr,int socket)20838f53763SMichael Baum mlx5_devx_sq_create(void *ctx, struct mlx5_devx_sq *sq_obj, uint16_t log_wqbb_n,
20938f53763SMichael Baum struct mlx5_devx_create_sq_attr *attr, int socket)
21038f53763SMichael Baum {
21138f53763SMichael Baum struct mlx5_devx_obj *sq = NULL;
21238f53763SMichael Baum struct mlx5dv_devx_umem *umem_obj = NULL;
21338f53763SMichael Baum void *umem_buf = NULL;
21438f53763SMichael Baum size_t alignment = MLX5_WQE_BUF_ALIGNMENT;
21538f53763SMichael Baum uint32_t umem_size, umem_dbrec;
21654feeab1SRaja Zidane uint32_t num_of_wqbbs = RTE_BIT32(log_wqbb_n);
21738f53763SMichael Baum int ret;
21838f53763SMichael Baum
21938f53763SMichael Baum if (alignment == (size_t)-1) {
22038f53763SMichael Baum DRV_LOG(ERR, "Failed to get WQE buf alignment.");
22138f53763SMichael Baum rte_errno = ENOMEM;
22238f53763SMichael Baum return -rte_errno;
22338f53763SMichael Baum }
22438f53763SMichael Baum /* Allocate memory buffer for WQEs and doorbell record. */
22554feeab1SRaja Zidane umem_size = MLX5_WQE_SIZE * num_of_wqbbs;
22638f53763SMichael Baum umem_dbrec = RTE_ALIGN(umem_size, MLX5_DBR_SIZE);
22738f53763SMichael Baum umem_size += MLX5_DBR_SIZE;
22838f53763SMichael Baum umem_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, umem_size,
22938f53763SMichael Baum alignment, socket);
23038f53763SMichael Baum if (!umem_buf) {
23138f53763SMichael Baum DRV_LOG(ERR, "Failed to allocate memory for SQ.");
23238f53763SMichael Baum rte_errno = ENOMEM;
23338f53763SMichael Baum return -rte_errno;
23438f53763SMichael Baum }
23538f53763SMichael Baum /* Register allocated buffer in user space with DevX. */
23638f53763SMichael Baum umem_obj = mlx5_os_umem_reg(ctx, (void *)(uintptr_t)umem_buf, umem_size,
23738f53763SMichael Baum IBV_ACCESS_LOCAL_WRITE);
23838f53763SMichael Baum if (!umem_obj) {
23938f53763SMichael Baum DRV_LOG(ERR, "Failed to register umem for SQ.");
24038f53763SMichael Baum rte_errno = errno;
24138f53763SMichael Baum goto error;
24238f53763SMichael Baum }
24338f53763SMichael Baum /* Fill attributes for SQ object creation. */
24438f53763SMichael Baum attr->wq_attr.wq_type = MLX5_WQ_TYPE_CYCLIC;
24538f53763SMichael Baum attr->wq_attr.wq_umem_valid = 1;
24638f53763SMichael Baum attr->wq_attr.wq_umem_id = mlx5_os_get_umem_id(umem_obj);
24738f53763SMichael Baum attr->wq_attr.wq_umem_offset = 0;
24838f53763SMichael Baum attr->wq_attr.dbr_umem_valid = 1;
24938f53763SMichael Baum attr->wq_attr.dbr_umem_id = attr->wq_attr.wq_umem_id;
25038f53763SMichael Baum attr->wq_attr.dbr_addr = umem_dbrec;
25138f53763SMichael Baum attr->wq_attr.log_wq_stride = rte_log2_u32(MLX5_WQE_SIZE);
25238f53763SMichael Baum attr->wq_attr.log_wq_sz = log_wqbb_n;
25338f53763SMichael Baum attr->wq_attr.log_wq_pg_sz = MLX5_LOG_PAGE_SIZE;
25438f53763SMichael Baum /* Create send queue object with DevX. */
25538f53763SMichael Baum sq = mlx5_devx_cmd_create_sq(ctx, attr);
25638f53763SMichael Baum if (!sq) {
25738f53763SMichael Baum DRV_LOG(ERR, "Can't create DevX SQ object.");
25838f53763SMichael Baum rte_errno = ENOMEM;
25938f53763SMichael Baum goto error;
26038f53763SMichael Baum }
26138f53763SMichael Baum sq_obj->umem_buf = umem_buf;
26238f53763SMichael Baum sq_obj->umem_obj = umem_obj;
26338f53763SMichael Baum sq_obj->sq = sq;
26438f53763SMichael Baum sq_obj->db_rec = RTE_PTR_ADD(sq_obj->umem_buf, umem_dbrec);
26538f53763SMichael Baum return 0;
26638f53763SMichael Baum error:
26738f53763SMichael Baum ret = rte_errno;
26838f53763SMichael Baum if (umem_obj)
26938f53763SMichael Baum claim_zero(mlx5_os_umem_dereg(umem_obj));
27038f53763SMichael Baum if (umem_buf)
27138f53763SMichael Baum mlx5_free((void *)(uintptr_t)umem_buf);
27238f53763SMichael Baum rte_errno = ret;
27338f53763SMichael Baum return -rte_errno;
27438f53763SMichael Baum }
27538f53763SMichael Baum
276edb704daSMichael Baum /**
277056c87d0SXueming Li * Destroy DevX Receive Queue resources.
278056c87d0SXueming Li *
279056c87d0SXueming Li * @param[in] rq_res
280056c87d0SXueming Li * DevX RQ resource to destroy.
281056c87d0SXueming Li */
282056c87d0SXueming Li static void
mlx5_devx_wq_res_destroy(struct mlx5_devx_wq_res * rq_res)283056c87d0SXueming Li mlx5_devx_wq_res_destroy(struct mlx5_devx_wq_res *rq_res)
284056c87d0SXueming Li {
285056c87d0SXueming Li if (rq_res->umem_obj)
286056c87d0SXueming Li claim_zero(mlx5_os_umem_dereg(rq_res->umem_obj));
287056c87d0SXueming Li if (rq_res->umem_buf)
288056c87d0SXueming Li mlx5_free((void *)(uintptr_t)rq_res->umem_buf);
289056c87d0SXueming Li memset(rq_res, 0, sizeof(*rq_res));
290056c87d0SXueming Li }
291056c87d0SXueming Li
292056c87d0SXueming Li /**
293056c87d0SXueming Li * Destroy DevX Receive Memory Pool.
294056c87d0SXueming Li *
295056c87d0SXueming Li * @param[in] rmp
296056c87d0SXueming Li * DevX RMP to destroy.
297056c87d0SXueming Li */
298056c87d0SXueming Li static void
mlx5_devx_rmp_destroy(struct mlx5_devx_rmp * rmp)299056c87d0SXueming Li mlx5_devx_rmp_destroy(struct mlx5_devx_rmp *rmp)
300056c87d0SXueming Li {
301056c87d0SXueming Li MLX5_ASSERT(rmp->ref_cnt == 0);
302056c87d0SXueming Li if (rmp->rmp) {
303056c87d0SXueming Li claim_zero(mlx5_devx_cmd_destroy(rmp->rmp));
304056c87d0SXueming Li rmp->rmp = NULL;
305056c87d0SXueming Li }
306056c87d0SXueming Li mlx5_devx_wq_res_destroy(&rmp->wq);
307056c87d0SXueming Li }
308056c87d0SXueming Li
309056c87d0SXueming Li /**
310f9213ab1SRaja Zidane * Destroy DevX Queue Pair.
311f9213ab1SRaja Zidane *
312f9213ab1SRaja Zidane * @param[in] qp
313f9213ab1SRaja Zidane * DevX QP to destroy.
314f9213ab1SRaja Zidane */
315f9213ab1SRaja Zidane void
mlx5_devx_qp_destroy(struct mlx5_devx_qp * qp)316f9213ab1SRaja Zidane mlx5_devx_qp_destroy(struct mlx5_devx_qp *qp)
317f9213ab1SRaja Zidane {
318f9213ab1SRaja Zidane if (qp->qp)
319f9213ab1SRaja Zidane claim_zero(mlx5_devx_cmd_destroy(qp->qp));
320f9213ab1SRaja Zidane if (qp->umem_obj)
321f9213ab1SRaja Zidane claim_zero(mlx5_os_umem_dereg(qp->umem_obj));
322f9213ab1SRaja Zidane if (qp->umem_buf)
323f9213ab1SRaja Zidane mlx5_free((void *)(uintptr_t)qp->umem_buf);
324f9213ab1SRaja Zidane }
325f9213ab1SRaja Zidane
326f9213ab1SRaja Zidane /**
327f9213ab1SRaja Zidane * Create Queue Pair using DevX API.
328f9213ab1SRaja Zidane *
329f9213ab1SRaja Zidane * Get a pointer to partially initialized attributes structure, and updates the
330f9213ab1SRaja Zidane * following fields:
331f9213ab1SRaja Zidane * wq_umem_id
332f9213ab1SRaja Zidane * wq_umem_offset
333f9213ab1SRaja Zidane * dbr_umem_valid
334f9213ab1SRaja Zidane * dbr_umem_id
335f9213ab1SRaja Zidane * dbr_address
336f9213ab1SRaja Zidane * log_page_size
337f9213ab1SRaja Zidane * All other fields are updated by caller.
338f9213ab1SRaja Zidane *
339f9213ab1SRaja Zidane * @param[in] ctx
340f9213ab1SRaja Zidane * Context returned from mlx5 open_device() glue function.
341f9213ab1SRaja Zidane * @param[in/out] qp_obj
342f9213ab1SRaja Zidane * Pointer to QP to create.
343bba8281dSRaja Zidane * @param[in] queue_size
344bba8281dSRaja Zidane * Size of queue to create.
345f9213ab1SRaja Zidane * @param[in] attr
346f9213ab1SRaja Zidane * Pointer to QP attributes structure.
347f9213ab1SRaja Zidane * @param[in] socket
348f9213ab1SRaja Zidane * Socket to use for allocation.
349f9213ab1SRaja Zidane *
350f9213ab1SRaja Zidane * @return
351f9213ab1SRaja Zidane * 0 on success, a negative errno value otherwise and rte_errno is set.
352f9213ab1SRaja Zidane */
353f9213ab1SRaja Zidane int
mlx5_devx_qp_create(void * ctx,struct mlx5_devx_qp * qp_obj,uint32_t queue_size,struct mlx5_devx_qp_attr * attr,int socket)354bba8281dSRaja Zidane mlx5_devx_qp_create(void *ctx, struct mlx5_devx_qp *qp_obj, uint32_t queue_size,
355f9213ab1SRaja Zidane struct mlx5_devx_qp_attr *attr, int socket)
356f9213ab1SRaja Zidane {
357f9213ab1SRaja Zidane struct mlx5_devx_obj *qp = NULL;
358f9213ab1SRaja Zidane struct mlx5dv_devx_umem *umem_obj = NULL;
359f9213ab1SRaja Zidane void *umem_buf = NULL;
360f9213ab1SRaja Zidane size_t alignment = MLX5_WQE_BUF_ALIGNMENT;
361f9213ab1SRaja Zidane uint32_t umem_size, umem_dbrec;
362f9213ab1SRaja Zidane int ret;
363f9213ab1SRaja Zidane
364f9213ab1SRaja Zidane if (alignment == (size_t)-1) {
365f9213ab1SRaja Zidane DRV_LOG(ERR, "Failed to get WQE buf alignment.");
366f9213ab1SRaja Zidane rte_errno = ENOMEM;
367f9213ab1SRaja Zidane return -rte_errno;
368f9213ab1SRaja Zidane }
369f9213ab1SRaja Zidane /* Allocate memory buffer for WQEs and doorbell record. */
370bba8281dSRaja Zidane umem_size = queue_size;
371f9213ab1SRaja Zidane umem_dbrec = RTE_ALIGN(umem_size, MLX5_DBR_SIZE);
372f9213ab1SRaja Zidane umem_size += MLX5_DBR_SIZE;
373f9213ab1SRaja Zidane umem_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, umem_size,
374f9213ab1SRaja Zidane alignment, socket);
375f9213ab1SRaja Zidane if (!umem_buf) {
376f9213ab1SRaja Zidane DRV_LOG(ERR, "Failed to allocate memory for QP.");
377f9213ab1SRaja Zidane rte_errno = ENOMEM;
378f9213ab1SRaja Zidane return -rte_errno;
379f9213ab1SRaja Zidane }
380f9213ab1SRaja Zidane /* Register allocated buffer in user space with DevX. */
381f9213ab1SRaja Zidane umem_obj = mlx5_os_umem_reg(ctx, (void *)(uintptr_t)umem_buf, umem_size,
382f9213ab1SRaja Zidane IBV_ACCESS_LOCAL_WRITE);
383f9213ab1SRaja Zidane if (!umem_obj) {
384f9213ab1SRaja Zidane DRV_LOG(ERR, "Failed to register umem for QP.");
385f9213ab1SRaja Zidane rte_errno = errno;
386f9213ab1SRaja Zidane goto error;
387f9213ab1SRaja Zidane }
388f9213ab1SRaja Zidane /* Fill attributes for SQ object creation. */
389f9213ab1SRaja Zidane attr->wq_umem_id = mlx5_os_get_umem_id(umem_obj);
390f9213ab1SRaja Zidane attr->wq_umem_offset = 0;
391f9213ab1SRaja Zidane attr->dbr_umem_valid = 1;
392f9213ab1SRaja Zidane attr->dbr_umem_id = attr->wq_umem_id;
393f9213ab1SRaja Zidane attr->dbr_address = umem_dbrec;
394f9213ab1SRaja Zidane attr->log_page_size = MLX5_LOG_PAGE_SIZE;
395f9213ab1SRaja Zidane /* Create send queue object with DevX. */
396f9213ab1SRaja Zidane qp = mlx5_devx_cmd_create_qp(ctx, attr);
397f9213ab1SRaja Zidane if (!qp) {
398f9213ab1SRaja Zidane DRV_LOG(ERR, "Can't create DevX QP object.");
399f9213ab1SRaja Zidane rte_errno = ENOMEM;
400f9213ab1SRaja Zidane goto error;
401f9213ab1SRaja Zidane }
402f9213ab1SRaja Zidane qp_obj->umem_buf = umem_buf;
403f9213ab1SRaja Zidane qp_obj->umem_obj = umem_obj;
404f9213ab1SRaja Zidane qp_obj->qp = qp;
405f9213ab1SRaja Zidane qp_obj->db_rec = RTE_PTR_ADD(qp_obj->umem_buf, umem_dbrec);
406f9213ab1SRaja Zidane return 0;
407f9213ab1SRaja Zidane error:
408f9213ab1SRaja Zidane ret = rte_errno;
409f9213ab1SRaja Zidane if (umem_obj)
410f9213ab1SRaja Zidane claim_zero(mlx5_os_umem_dereg(umem_obj));
411f9213ab1SRaja Zidane if (umem_buf)
412f9213ab1SRaja Zidane mlx5_free((void *)(uintptr_t)umem_buf);
413f9213ab1SRaja Zidane rte_errno = ret;
414f9213ab1SRaja Zidane return -rte_errno;
415f9213ab1SRaja Zidane }
416f9213ab1SRaja Zidane
417f9213ab1SRaja Zidane /**
418edb704daSMichael Baum * Destroy DevX Receive Queue.
419edb704daSMichael Baum *
420edb704daSMichael Baum * @param[in] rq
421edb704daSMichael Baum * DevX RQ to destroy.
422edb704daSMichael Baum */
423edb704daSMichael Baum void
mlx5_devx_rq_destroy(struct mlx5_devx_rq * rq)424edb704daSMichael Baum mlx5_devx_rq_destroy(struct mlx5_devx_rq *rq)
425edb704daSMichael Baum {
426056c87d0SXueming Li if (rq->rq) {
427edb704daSMichael Baum claim_zero(mlx5_devx_cmd_destroy(rq->rq));
428056c87d0SXueming Li rq->rq = NULL;
429056c87d0SXueming Li if (rq->rmp)
430056c87d0SXueming Li rq->rmp->ref_cnt--;
431056c87d0SXueming Li }
432056c87d0SXueming Li if (rq->rmp == NULL) {
433056c87d0SXueming Li mlx5_devx_wq_res_destroy(&rq->wq);
434056c87d0SXueming Li } else {
435056c87d0SXueming Li if (rq->rmp->ref_cnt == 0)
436056c87d0SXueming Li mlx5_devx_rmp_destroy(rq->rmp);
437056c87d0SXueming Li }
438edb704daSMichael Baum }
439edb704daSMichael Baum
440edb704daSMichael Baum /**
441056c87d0SXueming Li * Create WQ resources using DevX API.
442056c87d0SXueming Li *
443056c87d0SXueming Li * @param[in] ctx
444056c87d0SXueming Li * Context returned from mlx5 open_device() glue function.
445056c87d0SXueming Li * @param[in] wqe_size
446056c87d0SXueming Li * Size of WQE structure.
447056c87d0SXueming Li * @param[in] log_wqbb_n
448056c87d0SXueming Li * Log of number of WQBBs in queue.
449056c87d0SXueming Li * @param[in] socket
450056c87d0SXueming Li * Socket to use for allocation.
451056c87d0SXueming Li * @param[out] wq_attr
452056c87d0SXueming Li * Pointer to WQ attributes structure.
453056c87d0SXueming Li * @param[out] wq_res
454056c87d0SXueming Li * Pointer to WQ resource to create.
455056c87d0SXueming Li *
456056c87d0SXueming Li * @return
457056c87d0SXueming Li * 0 on success, a negative errno value otherwise and rte_errno is set.
458056c87d0SXueming Li */
459056c87d0SXueming Li static int
mlx5_devx_wq_init(void * ctx,uint32_t wqe_size,uint16_t log_wqbb_n,int socket,struct mlx5_devx_wq_attr * wq_attr,struct mlx5_devx_wq_res * wq_res)460056c87d0SXueming Li mlx5_devx_wq_init(void *ctx, uint32_t wqe_size, uint16_t log_wqbb_n, int socket,
461056c87d0SXueming Li struct mlx5_devx_wq_attr *wq_attr,
462056c87d0SXueming Li struct mlx5_devx_wq_res *wq_res)
463056c87d0SXueming Li {
464056c87d0SXueming Li struct mlx5dv_devx_umem *umem_obj = NULL;
465056c87d0SXueming Li void *umem_buf = NULL;
466056c87d0SXueming Li size_t alignment = MLX5_WQE_BUF_ALIGNMENT;
467056c87d0SXueming Li uint32_t umem_size, umem_dbrec;
468056c87d0SXueming Li int ret;
469056c87d0SXueming Li
470056c87d0SXueming Li if (alignment == (size_t)-1) {
471056c87d0SXueming Li DRV_LOG(ERR, "Failed to get WQE buf alignment.");
472056c87d0SXueming Li rte_errno = ENOMEM;
473056c87d0SXueming Li return -rte_errno;
474056c87d0SXueming Li }
475056c87d0SXueming Li /* Allocate memory buffer for WQEs and doorbell record. */
476056c87d0SXueming Li umem_size = wqe_size * (1 << log_wqbb_n);
477056c87d0SXueming Li umem_dbrec = RTE_ALIGN(umem_size, MLX5_DBR_SIZE);
478056c87d0SXueming Li umem_size += MLX5_DBR_SIZE;
479056c87d0SXueming Li umem_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, umem_size,
480056c87d0SXueming Li alignment, socket);
481056c87d0SXueming Li if (!umem_buf) {
482056c87d0SXueming Li DRV_LOG(ERR, "Failed to allocate memory for RQ.");
483056c87d0SXueming Li rte_errno = ENOMEM;
484056c87d0SXueming Li return -rte_errno;
485056c87d0SXueming Li }
486056c87d0SXueming Li /* Register allocated buffer in user space with DevX. */
487056c87d0SXueming Li umem_obj = mlx5_os_umem_reg(ctx, (void *)(uintptr_t)umem_buf,
488056c87d0SXueming Li umem_size, 0);
489056c87d0SXueming Li if (!umem_obj) {
490056c87d0SXueming Li DRV_LOG(ERR, "Failed to register umem for RQ.");
491056c87d0SXueming Li rte_errno = errno;
492056c87d0SXueming Li goto error;
493056c87d0SXueming Li }
494056c87d0SXueming Li /* Fill WQ attributes for RQ/RMP object creation. */
495056c87d0SXueming Li wq_attr->wq_umem_valid = 1;
496056c87d0SXueming Li wq_attr->wq_umem_id = mlx5_os_get_umem_id(umem_obj);
497056c87d0SXueming Li wq_attr->wq_umem_offset = 0;
498056c87d0SXueming Li wq_attr->dbr_umem_valid = 1;
499056c87d0SXueming Li wq_attr->dbr_umem_id = wq_attr->wq_umem_id;
500056c87d0SXueming Li wq_attr->dbr_addr = umem_dbrec;
501056c87d0SXueming Li wq_attr->log_wq_pg_sz = MLX5_LOG_PAGE_SIZE;
502056c87d0SXueming Li /* Fill attributes for RQ object creation. */
503056c87d0SXueming Li wq_res->umem_buf = umem_buf;
504056c87d0SXueming Li wq_res->umem_obj = umem_obj;
505056c87d0SXueming Li wq_res->db_rec = RTE_PTR_ADD(umem_buf, umem_dbrec);
506056c87d0SXueming Li return 0;
507056c87d0SXueming Li error:
508056c87d0SXueming Li ret = rte_errno;
509056c87d0SXueming Li if (umem_obj)
510056c87d0SXueming Li claim_zero(mlx5_os_umem_dereg(umem_obj));
511056c87d0SXueming Li if (umem_buf)
512056c87d0SXueming Li mlx5_free((void *)(uintptr_t)umem_buf);
513056c87d0SXueming Li rte_errno = ret;
514056c87d0SXueming Li return -rte_errno;
515056c87d0SXueming Li }
516056c87d0SXueming Li
517056c87d0SXueming Li /**
518056c87d0SXueming Li * Create standalone Receive Queue using DevX API.
519056c87d0SXueming Li *
520056c87d0SXueming Li * @param[in] ctx
521056c87d0SXueming Li * Context returned from mlx5 open_device() glue function.
522056c87d0SXueming Li * @param[in/out] rq_obj
523056c87d0SXueming Li * Pointer to RQ to create.
524056c87d0SXueming Li * @param[in] wqe_size
525056c87d0SXueming Li * Size of WQE structure.
526056c87d0SXueming Li * @param[in] log_wqbb_n
527056c87d0SXueming Li * Log of number of WQBBs in queue.
528056c87d0SXueming Li * @param[in] attr
529056c87d0SXueming Li * Pointer to RQ attributes structure.
530056c87d0SXueming Li * @param[in] socket
531056c87d0SXueming Li * Socket to use for allocation.
532056c87d0SXueming Li *
533056c87d0SXueming Li * @return
534056c87d0SXueming Li * 0 on success, a negative errno value otherwise and rte_errno is set.
535056c87d0SXueming Li */
536056c87d0SXueming Li static int
mlx5_devx_rq_std_create(void * ctx,struct mlx5_devx_rq * rq_obj,uint32_t wqe_size,uint16_t log_wqbb_n,struct mlx5_devx_create_rq_attr * attr,int socket)537056c87d0SXueming Li mlx5_devx_rq_std_create(void *ctx, struct mlx5_devx_rq *rq_obj,
538056c87d0SXueming Li uint32_t wqe_size, uint16_t log_wqbb_n,
539056c87d0SXueming Li struct mlx5_devx_create_rq_attr *attr, int socket)
540056c87d0SXueming Li {
541056c87d0SXueming Li struct mlx5_devx_obj *rq;
542056c87d0SXueming Li int ret;
543056c87d0SXueming Li
544056c87d0SXueming Li ret = mlx5_devx_wq_init(ctx, wqe_size, log_wqbb_n, socket,
545056c87d0SXueming Li &attr->wq_attr, &rq_obj->wq);
546056c87d0SXueming Li if (ret != 0)
547056c87d0SXueming Li return ret;
548056c87d0SXueming Li /* Create receive queue object with DevX. */
549056c87d0SXueming Li rq = mlx5_devx_cmd_create_rq(ctx, attr, socket);
550056c87d0SXueming Li if (!rq) {
551056c87d0SXueming Li DRV_LOG(ERR, "Can't create DevX RQ object.");
552056c87d0SXueming Li rte_errno = ENOMEM;
553056c87d0SXueming Li goto error;
554056c87d0SXueming Li }
555056c87d0SXueming Li rq_obj->rq = rq;
556056c87d0SXueming Li return 0;
557056c87d0SXueming Li error:
558056c87d0SXueming Li ret = rte_errno;
559056c87d0SXueming Li mlx5_devx_wq_res_destroy(&rq_obj->wq);
560056c87d0SXueming Li rte_errno = ret;
561056c87d0SXueming Li return -rte_errno;
562056c87d0SXueming Li }
563056c87d0SXueming Li
564056c87d0SXueming Li /**
565056c87d0SXueming Li * Create Receive Memory Pool using DevX API.
566056c87d0SXueming Li *
567056c87d0SXueming Li * @param[in] ctx
568056c87d0SXueming Li * Context returned from mlx5 open_device() glue function.
569056c87d0SXueming Li * @param[in/out] rq_obj
570056c87d0SXueming Li * Pointer to RQ to create.
571056c87d0SXueming Li * @param[in] wqe_size
572056c87d0SXueming Li * Size of WQE structure.
573056c87d0SXueming Li * @param[in] log_wqbb_n
574056c87d0SXueming Li * Log of number of WQBBs in queue.
575056c87d0SXueming Li * @param[in] attr
576056c87d0SXueming Li * Pointer to RQ attributes structure.
577056c87d0SXueming Li * @param[in] socket
578056c87d0SXueming Li * Socket to use for allocation.
579056c87d0SXueming Li *
580056c87d0SXueming Li * @return
581056c87d0SXueming Li * 0 on success, a negative errno value otherwise and rte_errno is set.
582056c87d0SXueming Li */
583056c87d0SXueming Li static int
mlx5_devx_rmp_create(void * ctx,struct mlx5_devx_rmp * rmp_obj,uint32_t wqe_size,uint16_t log_wqbb_n,struct mlx5_devx_wq_attr * wq_attr,int socket)584056c87d0SXueming Li mlx5_devx_rmp_create(void *ctx, struct mlx5_devx_rmp *rmp_obj,
585056c87d0SXueming Li uint32_t wqe_size, uint16_t log_wqbb_n,
586056c87d0SXueming Li struct mlx5_devx_wq_attr *wq_attr, int socket)
587056c87d0SXueming Li {
588056c87d0SXueming Li struct mlx5_devx_create_rmp_attr rmp_attr = { 0 };
589056c87d0SXueming Li int ret;
590056c87d0SXueming Li
591056c87d0SXueming Li if (rmp_obj->rmp != NULL)
592056c87d0SXueming Li return 0;
593056c87d0SXueming Li rmp_attr.wq_attr = *wq_attr;
594056c87d0SXueming Li ret = mlx5_devx_wq_init(ctx, wqe_size, log_wqbb_n, socket,
595056c87d0SXueming Li &rmp_attr.wq_attr, &rmp_obj->wq);
596056c87d0SXueming Li if (ret != 0)
597056c87d0SXueming Li return ret;
598056c87d0SXueming Li rmp_attr.state = MLX5_RMPC_STATE_RDY;
599056c87d0SXueming Li rmp_attr.basic_cyclic_rcv_wqe =
600056c87d0SXueming Li wq_attr->wq_type != MLX5_WQ_TYPE_CYCLIC_STRIDING_RQ;
601056c87d0SXueming Li /* Create receive memory pool object with DevX. */
602056c87d0SXueming Li rmp_obj->rmp = mlx5_devx_cmd_create_rmp(ctx, &rmp_attr, socket);
603056c87d0SXueming Li if (rmp_obj->rmp == NULL) {
604056c87d0SXueming Li DRV_LOG(ERR, "Can't create DevX RMP object.");
605056c87d0SXueming Li rte_errno = ENOMEM;
606056c87d0SXueming Li goto error;
607056c87d0SXueming Li }
608056c87d0SXueming Li return 0;
609056c87d0SXueming Li error:
610056c87d0SXueming Li ret = rte_errno;
611056c87d0SXueming Li mlx5_devx_wq_res_destroy(&rmp_obj->wq);
612056c87d0SXueming Li rte_errno = ret;
613056c87d0SXueming Li return -rte_errno;
614056c87d0SXueming Li }
615056c87d0SXueming Li
616056c87d0SXueming Li /**
617056c87d0SXueming Li * Create Shared Receive Queue based on RMP using DevX API.
618056c87d0SXueming Li *
619056c87d0SXueming Li * @param[in] ctx
620056c87d0SXueming Li * Context returned from mlx5 open_device() glue function.
621056c87d0SXueming Li * @param[in/out] rq_obj
622056c87d0SXueming Li * Pointer to RQ to create.
623056c87d0SXueming Li * @param[in] wqe_size
624056c87d0SXueming Li * Size of WQE structure.
625056c87d0SXueming Li * @param[in] log_wqbb_n
626056c87d0SXueming Li * Log of number of WQBBs in queue.
627056c87d0SXueming Li * @param[in] attr
628056c87d0SXueming Li * Pointer to RQ attributes structure.
629056c87d0SXueming Li * @param[in] socket
630056c87d0SXueming Li * Socket to use for allocation.
631056c87d0SXueming Li *
632056c87d0SXueming Li * @return
633056c87d0SXueming Li * 0 on success, a negative errno value otherwise and rte_errno is set.
634056c87d0SXueming Li */
635056c87d0SXueming Li static int
mlx5_devx_rq_shared_create(void * ctx,struct mlx5_devx_rq * rq_obj,uint32_t wqe_size,uint16_t log_wqbb_n,struct mlx5_devx_create_rq_attr * attr,int socket)636056c87d0SXueming Li mlx5_devx_rq_shared_create(void *ctx, struct mlx5_devx_rq *rq_obj,
637056c87d0SXueming Li uint32_t wqe_size, uint16_t log_wqbb_n,
638056c87d0SXueming Li struct mlx5_devx_create_rq_attr *attr, int socket)
639056c87d0SXueming Li {
640056c87d0SXueming Li struct mlx5_devx_obj *rq;
641056c87d0SXueming Li int ret;
642056c87d0SXueming Li
643056c87d0SXueming Li ret = mlx5_devx_rmp_create(ctx, rq_obj->rmp, wqe_size, log_wqbb_n,
644056c87d0SXueming Li &attr->wq_attr, socket);
645056c87d0SXueming Li if (ret != 0)
646056c87d0SXueming Li return ret;
647056c87d0SXueming Li attr->mem_rq_type = MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_RMP;
648056c87d0SXueming Li attr->rmpn = rq_obj->rmp->rmp->id;
649056c87d0SXueming Li attr->flush_in_error_en = 0;
650056c87d0SXueming Li memset(&attr->wq_attr, 0, sizeof(attr->wq_attr));
651056c87d0SXueming Li /* Create receive queue object with DevX. */
652056c87d0SXueming Li rq = mlx5_devx_cmd_create_rq(ctx, attr, socket);
653056c87d0SXueming Li if (!rq) {
654056c87d0SXueming Li DRV_LOG(ERR, "Can't create DevX RMP RQ object.");
655056c87d0SXueming Li rte_errno = ENOMEM;
656056c87d0SXueming Li goto error;
657056c87d0SXueming Li }
658056c87d0SXueming Li rq_obj->rq = rq;
659056c87d0SXueming Li rq_obj->rmp->ref_cnt++;
660056c87d0SXueming Li return 0;
661056c87d0SXueming Li error:
662056c87d0SXueming Li ret = rte_errno;
663056c87d0SXueming Li mlx5_devx_rq_destroy(rq_obj);
664056c87d0SXueming Li rte_errno = ret;
665056c87d0SXueming Li return -rte_errno;
666056c87d0SXueming Li }
667056c87d0SXueming Li
668056c87d0SXueming Li /**
669056c87d0SXueming Li * Create Receive Queue using DevX API. Shared RQ is created only if rmp set.
670edb704daSMichael Baum *
671edb704daSMichael Baum * Get a pointer to partially initialized attributes structure, and updates the
672edb704daSMichael Baum * following fields:
673edb704daSMichael Baum * wq_umem_valid
674edb704daSMichael Baum * wq_umem_id
675edb704daSMichael Baum * wq_umem_offset
676edb704daSMichael Baum * dbr_umem_valid
677edb704daSMichael Baum * dbr_umem_id
678edb704daSMichael Baum * dbr_addr
679edb704daSMichael Baum * log_wq_pg_sz
680edb704daSMichael Baum * All other fields are updated by caller.
681edb704daSMichael Baum *
682edb704daSMichael Baum * @param[in] ctx
683edb704daSMichael Baum * Context returned from mlx5 open_device() glue function.
684edb704daSMichael Baum * @param[in/out] rq_obj
685edb704daSMichael Baum * Pointer to RQ to create.
686edb704daSMichael Baum * @param[in] wqe_size
687edb704daSMichael Baum * Size of WQE structure.
688edb704daSMichael Baum * @param[in] log_wqbb_n
689edb704daSMichael Baum * Log of number of WQBBs in queue.
690edb704daSMichael Baum * @param[in] attr
691edb704daSMichael Baum * Pointer to RQ attributes structure.
692edb704daSMichael Baum * @param[in] socket
693edb704daSMichael Baum * Socket to use for allocation.
694edb704daSMichael Baum *
695edb704daSMichael Baum * @return
696edb704daSMichael Baum * 0 on success, a negative errno value otherwise and rte_errno is set.
697edb704daSMichael Baum */
698edb704daSMichael Baum int
mlx5_devx_rq_create(void * ctx,struct mlx5_devx_rq * rq_obj,uint32_t wqe_size,uint16_t log_wqbb_n,struct mlx5_devx_create_rq_attr * attr,int socket)699056c87d0SXueming Li mlx5_devx_rq_create(void *ctx, struct mlx5_devx_rq *rq_obj,
700056c87d0SXueming Li uint32_t wqe_size, uint16_t log_wqbb_n,
701edb704daSMichael Baum struct mlx5_devx_create_rq_attr *attr, int socket)
702edb704daSMichael Baum {
703056c87d0SXueming Li if (rq_obj->rmp == NULL)
704056c87d0SXueming Li return mlx5_devx_rq_std_create(ctx, rq_obj, wqe_size,
705056c87d0SXueming Li log_wqbb_n, attr, socket);
706056c87d0SXueming Li return mlx5_devx_rq_shared_create(ctx, rq_obj, wqe_size,
707056c87d0SXueming Li log_wqbb_n, attr, socket);
708edb704daSMichael Baum }
709f9213ab1SRaja Zidane
710f9213ab1SRaja Zidane /**
711f9213ab1SRaja Zidane * Change QP state to RTS.
712f9213ab1SRaja Zidane *
713f9213ab1SRaja Zidane * @param[in] qp
714f9213ab1SRaja Zidane * DevX QP to change.
715f9213ab1SRaja Zidane * @param[in] remote_qp_id
716f9213ab1SRaja Zidane * The remote QP ID for MLX5_CMD_OP_INIT2RTR_QP operation.
717f9213ab1SRaja Zidane *
718f9213ab1SRaja Zidane * @return
719f9213ab1SRaja Zidane * 0 on success, a negative errno value otherwise and rte_errno is set.
720f9213ab1SRaja Zidane */
721f9213ab1SRaja Zidane int
mlx5_devx_qp2rts(struct mlx5_devx_qp * qp,uint32_t remote_qp_id)722f9213ab1SRaja Zidane mlx5_devx_qp2rts(struct mlx5_devx_qp *qp, uint32_t remote_qp_id)
723f9213ab1SRaja Zidane {
724f9213ab1SRaja Zidane if (mlx5_devx_cmd_modify_qp_state(qp->qp, MLX5_CMD_OP_RST2INIT_QP,
725f9213ab1SRaja Zidane remote_qp_id)) {
726f9213ab1SRaja Zidane DRV_LOG(ERR, "Failed to modify QP to INIT state(%u).",
727f9213ab1SRaja Zidane rte_errno);
728f9213ab1SRaja Zidane return -1;
729f9213ab1SRaja Zidane }
730f9213ab1SRaja Zidane if (mlx5_devx_cmd_modify_qp_state(qp->qp, MLX5_CMD_OP_INIT2RTR_QP,
731f9213ab1SRaja Zidane remote_qp_id)) {
732f9213ab1SRaja Zidane DRV_LOG(ERR, "Failed to modify QP to RTR state(%u).",
733f9213ab1SRaja Zidane rte_errno);
734f9213ab1SRaja Zidane return -1;
735f9213ab1SRaja Zidane }
736f9213ab1SRaja Zidane if (mlx5_devx_cmd_modify_qp_state(qp->qp, MLX5_CMD_OP_RTR2RTS_QP,
737f9213ab1SRaja Zidane remote_qp_id)) {
738f9213ab1SRaja Zidane DRV_LOG(ERR, "Failed to modify QP to RTS state(%u).",
739f9213ab1SRaja Zidane rte_errno);
740f9213ab1SRaja Zidane return -1;
741f9213ab1SRaja Zidane }
742f9213ab1SRaja Zidane return 0;
743f9213ab1SRaja Zidane }
744