f2d781a9658858637516b5303c1080feeb3bd312
[dpdk.git] / drivers / common / mlx5 / windows / mlx5_common_os.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Mellanox Technologies, Ltd
3  */
4
5 #include <unistd.h>
6 #include <string.h>
7 #include <stdio.h>
8
9 #include <rte_mempool.h>
10 #include <rte_malloc.h>
11 #include <rte_errno.h>
12
13 #include "mlx5_devx_cmds.h"
14 #include "mlx5_common_utils.h"
15 #include "mlx5_common.h"
16 #include "mlx5_common_os.h"
17 #include "mlx5_malloc.h"
18
19 /**
20  * Initialization routine for run-time dependency on external lib
21  */
22 void
23 mlx5_glue_constructor(void)
24 {
25 }
26
27 /**
28  * Allocate PD. Given a devx context object
29  * return an mlx5-pd object.
30  *
31  * @param[in] ctx
32  *   Pointer to context.
33  *
34  * @return
35  *    The mlx5_pd if pd is valid, NULL and errno otherwise.
36  */
37 void *
38 mlx5_os_alloc_pd(void *ctx)
39 {
40         struct mlx5_pd *ppd =  mlx5_malloc(MLX5_MEM_ZERO,
41                 sizeof(struct mlx5_pd), 0, SOCKET_ID_ANY);
42         if (!ppd)
43                 return NULL;
44
45         struct mlx5_devx_obj *obj = mlx5_devx_cmd_alloc_pd(ctx);
46         if (!obj) {
47                 mlx5_free(ppd);
48                 return NULL;
49         }
50         ppd->obj = obj;
51         ppd->pdn = obj->id;
52         ppd->devx_ctx = ctx;
53         return ppd;
54 }
55
56 /**
57  * Release PD. Releases a given mlx5_pd object
58  *
59  * @param[in] pd
60  *   Pointer to mlx5_pd.
61  *
62  * @return
63  *    Zero if pd is released successfully, negative number otherwise.
64  */
65 int
66 mlx5_os_dealloc_pd(void *pd)
67 {
68         if (!pd)
69                 return -EINVAL;
70         mlx5_devx_cmd_destroy(((struct mlx5_pd *)pd)->obj);
71         mlx5_free(pd);
72         return 0;
73 }
74
75 /**
76  * Register umem.
77  *
78  * @param[in] ctx
79  *   Pointer to context.
80  * @param[in] addr
81  *   Pointer to memory start address.
82  * @param[in] size
83  *   Size of the memory to register.
84  * @param[out] access
85  *   UMEM access type
86  *
87  * @return
88  *   umem on successful registration, NULL and errno otherwise
89  */
90 void *
91 mlx5_os_umem_reg(void *ctx, void *addr, size_t size, uint32_t access)
92 {
93         struct mlx5_devx_umem *umem;
94
95         umem = mlx5_malloc(MLX5_MEM_ZERO,
96                 (sizeof(*umem)), 0, SOCKET_ID_ANY);
97         if (!umem) {
98                 errno = ENOMEM;
99                 return NULL;
100         }
101         umem->umem_hdl = mlx5_glue->devx_umem_reg(ctx, addr, size, access,
102                 &umem->umem_id);
103         if (!umem->umem_hdl) {
104                 mlx5_free(umem);
105                 return NULL;
106         }
107         umem->addr = addr;
108         return umem;
109 }
110
111 /**
112  * Deregister umem.
113  *
114  * @param[in] pumem
115  *   Pointer to umem.
116  *
117  * @return
118  *   0 on successful release, negative number otherwise
119  */
120 int
121 mlx5_os_umem_dereg(void *pumem)
122 {
123         struct mlx5_devx_umem *umem;
124         int err = 0;
125
126         if (!pumem)
127                 return err;
128         umem = pumem;
129         if (umem->umem_hdl)
130                 err = mlx5_glue->devx_umem_dereg(umem->umem_hdl);
131         mlx5_free(umem);
132         return err;
133 }
134
135 /**
136  * Register mr. Given protection doamin pointer, pointer to addr and length
137  * register the memory region.
138  *
139  * @param[in] pd
140  *   Pointer to protection domain context (type mlx5_pd).
141  * @param[in] addr
142  *   Pointer to memory start address (type devx_device_ctx).
143  * @param[in] length
144  *   Lengtoh of the memory to register.
145  * @param[out] pmd_mr
146  *   pmd_mr struct set with lkey, address, length, pointer to mr object, mkey
147  *
148  * @return
149  *   0 on successful registration, -1 otherwise
150  */
151 int
152 mlx5_os_reg_mr(void *pd,
153                void *addr, size_t length, struct mlx5_pmd_mr *pmd_mr)
154 {
155         struct mlx5_devx_mkey_attr mkey_attr;
156         struct mlx5_pd *mlx5_pd = (struct mlx5_pd *)pd;
157         struct mlx5_hca_attr attr;
158
159         if (!pd || !addr) {
160                 rte_errno = EINVAL;
161                 return -1;
162         }
163         memset(pmd_mr, 0, sizeof(*pmd_mr));
164         if (mlx5_devx_cmd_query_hca_attr(mlx5_pd->devx_ctx, &attr))
165                 return -1;
166         pmd_mr->addr = addr;
167         pmd_mr->len = length;
168         pmd_mr->obj = mlx5_os_umem_reg(mlx5_pd->devx_ctx, pmd_mr->addr,
169                                        pmd_mr->len, IBV_ACCESS_LOCAL_WRITE);
170         if (!pmd_mr->obj)
171                 return -1;
172         mkey_attr.addr = (uintptr_t)addr;
173         mkey_attr.size = length;
174         mkey_attr.umem_id = ((struct mlx5_devx_umem *)(pmd_mr->obj))->umem_id;
175         mkey_attr.pd = mlx5_pd->pdn;
176         mkey_attr.log_entity_size = 0;
177         mkey_attr.pg_access = 0;
178         mkey_attr.klm_array = NULL;
179         mkey_attr.klm_num = 0;
180         mkey_attr.relaxed_ordering_read = 0;
181         mkey_attr.relaxed_ordering_write = 0;
182         if (!haswell_broadwell_cpu) {
183                 mkey_attr.relaxed_ordering_write = attr.relaxed_ordering_write;
184                 mkey_attr.relaxed_ordering_read = attr.relaxed_ordering_read;
185         }
186         pmd_mr->mkey = mlx5_devx_cmd_mkey_create(mlx5_pd->devx_ctx, &mkey_attr);
187         if (!pmd_mr->mkey) {
188                 claim_zero(mlx5_os_umem_dereg(pmd_mr->obj));
189                 return -1;
190         }
191         pmd_mr->lkey = pmd_mr->mkey->id;
192         return 0;
193 }
194
195 /**
196  * De-register mr.
197  *
198  * @param[in] pmd_mr
199  *  Pointer to PMD mr object
200  */
201 void
202 mlx5_os_dereg_mr(struct mlx5_pmd_mr *pmd_mr)
203 {
204         if (pmd_mr && pmd_mr->mkey)
205                 claim_zero(mlx5_glue->devx_obj_destroy(pmd_mr->mkey->obj));
206         if (pmd_mr && pmd_mr->obj)
207                 claim_zero(mlx5_os_umem_dereg(pmd_mr->obj));
208         memset(pmd_mr, 0, sizeof(*pmd_mr));
209 }