crypto/octeontx2: add queue pair functions
[dpdk.git] / drivers / crypto / octeontx2 / otx2_cryptodev_ops.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2019 Marvell International Ltd.
3  */
4
5 #include <unistd.h>
6
7 #include <rte_cryptodev_pmd.h>
8 #include <rte_errno.h>
9
10 #include "otx2_cryptodev.h"
11 #include "otx2_cryptodev_hw_access.h"
12 #include "otx2_cryptodev_mbox.h"
13 #include "otx2_cryptodev_ops.h"
14 #include "otx2_mbox.h"
15
16 #include "cpt_hw_types.h"
17 #include "cpt_pmd_logs.h"
18 #include "cpt_pmd_ops_helper.h"
19
20 #define METABUF_POOL_CACHE_SIZE 512
21
22 /* Forward declarations */
23
24 static int
25 otx2_cpt_queue_pair_release(struct rte_cryptodev *dev, uint16_t qp_id);
26
27 static void
28 qp_memzone_name_get(char *name, int size, int dev_id, int qp_id)
29 {
30         snprintf(name, size, "otx2_cpt_lf_mem_%u:%u", dev_id, qp_id);
31 }
32
33 static int
34 otx2_cpt_metabuf_mempool_create(const struct rte_cryptodev *dev,
35                                 struct otx2_cpt_qp *qp, uint8_t qp_id,
36                                 int nb_elements)
37 {
38         char mempool_name[RTE_MEMPOOL_NAMESIZE];
39         int sg_mlen, lb_mlen, max_mlen, ret;
40         struct cpt_qp_meta_info *meta_info;
41         struct rte_mempool *pool;
42
43         /* Get meta len for scatter gather mode */
44         sg_mlen = cpt_pmd_ops_helper_get_mlen_sg_mode();
45
46         /* Extra 32B saved for future considerations */
47         sg_mlen += 4 * sizeof(uint64_t);
48
49         /* Get meta len for linear buffer (direct) mode */
50         lb_mlen = cpt_pmd_ops_helper_get_mlen_direct_mode();
51
52         /* Extra 32B saved for future considerations */
53         lb_mlen += 4 * sizeof(uint64_t);
54
55         /* Check max requirement for meta buffer */
56         max_mlen = RTE_MAX(lb_mlen, sg_mlen);
57
58         /* Allocate mempool */
59
60         snprintf(mempool_name, RTE_MEMPOOL_NAMESIZE, "otx2_cpt_mb_%u:%u",
61                  dev->data->dev_id, qp_id);
62
63         pool = rte_mempool_create_empty(mempool_name, nb_elements, max_mlen,
64                                         METABUF_POOL_CACHE_SIZE, 0,
65                                         rte_socket_id(), 0);
66
67         if (pool == NULL) {
68                 CPT_LOG_ERR("Could not create mempool for metabuf");
69                 return rte_errno;
70         }
71
72         ret = rte_mempool_set_ops_byname(pool, RTE_MBUF_DEFAULT_MEMPOOL_OPS,
73                                          NULL);
74         if (ret) {
75                 CPT_LOG_ERR("Could not set mempool ops");
76                 goto mempool_free;
77         }
78
79         ret = rte_mempool_populate_default(pool);
80         if (ret <= 0) {
81                 CPT_LOG_ERR("Could not populate metabuf pool");
82                 goto mempool_free;
83         }
84
85         meta_info = &qp->meta_info;
86
87         meta_info->pool = pool;
88         meta_info->lb_mlen = lb_mlen;
89         meta_info->sg_mlen = sg_mlen;
90
91         return 0;
92
93 mempool_free:
94         rte_mempool_free(pool);
95         return ret;
96 }
97
98 static void
99 otx2_cpt_metabuf_mempool_destroy(struct otx2_cpt_qp *qp)
100 {
101         struct cpt_qp_meta_info *meta_info = &qp->meta_info;
102
103         rte_mempool_free(meta_info->pool);
104
105         meta_info->pool = NULL;
106         meta_info->lb_mlen = 0;
107         meta_info->sg_mlen = 0;
108 }
109
110 static struct otx2_cpt_qp *
111 otx2_cpt_qp_create(const struct rte_cryptodev *dev, uint16_t qp_id,
112                    uint8_t group)
113 {
114         struct otx2_cpt_vf *vf = dev->data->dev_private;
115         uint64_t pg_sz = sysconf(_SC_PAGESIZE);
116         const struct rte_memzone *lf_mem;
117         uint32_t len, iq_len, size_div40;
118         char name[RTE_MEMZONE_NAMESIZE];
119         uint64_t used_len, iova;
120         struct otx2_cpt_qp *qp;
121         uint64_t lmtline;
122         uint8_t *va;
123         int ret;
124
125         /* Allocate queue pair */
126         qp = rte_zmalloc_socket("OCTEON TX2 Crypto PMD Queue Pair", sizeof(*qp),
127                                 OTX2_ALIGN, 0);
128         if (qp == NULL) {
129                 CPT_LOG_ERR("Could not allocate queue pair");
130                 return NULL;
131         }
132
133         iq_len = OTX2_CPT_IQ_LEN;
134
135         /*
136          * Queue size must be a multiple of 40 and effective queue size to
137          * software is (size_div40 - 1) * 40
138          */
139         size_div40 = (iq_len + 40 - 1) / 40 + 1;
140
141         /* For pending queue */
142         len = iq_len * RTE_ALIGN(sizeof(struct rid), 8);
143
144         /* Space for instruction group memory */
145         len += size_div40 * 16;
146
147         /* So that instruction queues start as pg size aligned */
148         len = RTE_ALIGN(len, pg_sz);
149
150         /* For instruction queues */
151         len += OTX2_CPT_IQ_LEN * sizeof(union cpt_inst_s);
152
153         /* Wastage after instruction queues */
154         len = RTE_ALIGN(len, pg_sz);
155
156         qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
157                             qp_id);
158
159         lf_mem = rte_memzone_reserve_aligned(name, len, vf->otx2_dev.node,
160                         RTE_MEMZONE_SIZE_HINT_ONLY | RTE_MEMZONE_256MB,
161                         RTE_CACHE_LINE_SIZE);
162         if (lf_mem == NULL) {
163                 CPT_LOG_ERR("Could not allocate reserved memzone");
164                 goto qp_free;
165         }
166
167         va = lf_mem->addr;
168         iova = lf_mem->iova;
169
170         memset(va, 0, len);
171
172         ret = otx2_cpt_metabuf_mempool_create(dev, qp, qp_id, iq_len);
173         if (ret) {
174                 CPT_LOG_ERR("Could not create mempool for metabuf");
175                 goto lf_mem_free;
176         }
177
178         /* Initialize pending queue */
179         qp->pend_q.rid_queue = (struct rid *)va;
180         qp->pend_q.enq_tail = 0;
181         qp->pend_q.deq_head = 0;
182         qp->pend_q.pending_count = 0;
183
184         used_len = iq_len * RTE_ALIGN(sizeof(struct rid), 8);
185         used_len += size_div40 * 16;
186         used_len = RTE_ALIGN(used_len, pg_sz);
187         iova += used_len;
188
189         qp->iq_dma_addr = iova;
190         qp->id = qp_id;
191         qp->base = OTX2_CPT_LF_BAR2(vf, qp_id);
192
193         lmtline = vf->otx2_dev.bar2 +
194                   (RVU_BLOCK_ADDR_LMT << 20 | qp_id << 12) +
195                   OTX2_LMT_LF_LMTLINE(0);
196
197         qp->lmtline = (void *)lmtline;
198
199         qp->lf_nq_reg = qp->base + OTX2_CPT_LF_NQ(0);
200
201         otx2_cpt_iq_disable(qp);
202
203         ret = otx2_cpt_iq_enable(dev, qp, group, OTX2_CPT_QUEUE_HI_PRIO,
204                                  size_div40);
205         if (ret) {
206                 CPT_LOG_ERR("Could not enable instruction queue");
207                 goto mempool_destroy;
208         }
209
210         return qp;
211
212 mempool_destroy:
213         otx2_cpt_metabuf_mempool_destroy(qp);
214 lf_mem_free:
215         rte_memzone_free(lf_mem);
216 qp_free:
217         rte_free(qp);
218         return NULL;
219 }
220
221 static int
222 otx2_cpt_qp_destroy(const struct rte_cryptodev *dev, struct otx2_cpt_qp *qp)
223 {
224         const struct rte_memzone *lf_mem;
225         char name[RTE_MEMZONE_NAMESIZE];
226         int ret;
227
228         otx2_cpt_iq_disable(qp);
229
230         otx2_cpt_metabuf_mempool_destroy(qp);
231
232         qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
233                             qp->id);
234
235         lf_mem = rte_memzone_lookup(name);
236
237         ret = rte_memzone_free(lf_mem);
238         if (ret)
239                 return ret;
240
241         rte_free(qp);
242
243         return 0;
244 }
245
246 /* PMD ops */
247
248 static int
249 otx2_cpt_dev_config(struct rte_cryptodev *dev,
250                     struct rte_cryptodev_config *conf)
251 {
252         struct otx2_cpt_vf *vf = dev->data->dev_private;
253         int ret;
254
255         if (conf->nb_queue_pairs > vf->max_queues) {
256                 CPT_LOG_ERR("Invalid number of queue pairs requested");
257                 return -EINVAL;
258         }
259
260         dev->feature_flags &= ~conf->ff_disable;
261
262         /* Unregister error interrupts */
263         if (vf->err_intr_registered)
264                 otx2_cpt_err_intr_unregister(dev);
265
266         /* Detach queues */
267         if (vf->nb_queues) {
268                 ret = otx2_cpt_queues_detach(dev);
269                 if (ret) {
270                         CPT_LOG_ERR("Could not detach CPT queues");
271                         return ret;
272                 }
273         }
274
275         /* Attach queues */
276         ret = otx2_cpt_queues_attach(dev, conf->nb_queue_pairs);
277         if (ret) {
278                 CPT_LOG_ERR("Could not attach CPT queues");
279                 return -ENODEV;
280         }
281
282         ret = otx2_cpt_msix_offsets_get(dev);
283         if (ret) {
284                 CPT_LOG_ERR("Could not get MSI-X offsets");
285                 goto queues_detach;
286         }
287
288         /* Register error interrupts */
289         ret = otx2_cpt_err_intr_register(dev);
290         if (ret) {
291                 CPT_LOG_ERR("Could not register error interrupts");
292                 goto queues_detach;
293         }
294
295         rte_mb();
296         return 0;
297
298 queues_detach:
299         otx2_cpt_queues_detach(dev);
300         return ret;
301 }
302
303 static int
304 otx2_cpt_dev_start(struct rte_cryptodev *dev)
305 {
306         RTE_SET_USED(dev);
307
308         CPT_PMD_INIT_FUNC_TRACE();
309
310         return 0;
311 }
312
313 static void
314 otx2_cpt_dev_stop(struct rte_cryptodev *dev)
315 {
316         RTE_SET_USED(dev);
317
318         CPT_PMD_INIT_FUNC_TRACE();
319 }
320
321 static int
322 otx2_cpt_dev_close(struct rte_cryptodev *dev)
323 {
324         struct otx2_cpt_vf *vf = dev->data->dev_private;
325         int i, ret = 0;
326
327         for (i = 0; i < dev->data->nb_queue_pairs; i++) {
328                 ret = otx2_cpt_queue_pair_release(dev, i);
329                 if (ret)
330                         return ret;
331         }
332
333         /* Unregister error interrupts */
334         if (vf->err_intr_registered)
335                 otx2_cpt_err_intr_unregister(dev);
336
337         /* Detach queues */
338         if (vf->nb_queues) {
339                 ret = otx2_cpt_queues_detach(dev);
340                 if (ret)
341                         CPT_LOG_ERR("Could not detach CPT queues");
342         }
343
344         return ret;
345 }
346
347 static void
348 otx2_cpt_dev_info_get(struct rte_cryptodev *dev,
349                       struct rte_cryptodev_info *info)
350 {
351         struct otx2_cpt_vf *vf = dev->data->dev_private;
352
353         if (info != NULL) {
354                 info->max_nb_queue_pairs = vf->max_queues;
355                 info->feature_flags = dev->feature_flags;
356                 info->capabilities = NULL;
357                 info->sym.max_nb_sessions = 0;
358                 info->driver_id = otx2_cryptodev_driver_id;
359                 info->min_mbuf_headroom_req = OTX2_CPT_MIN_HEADROOM_REQ;
360                 info->min_mbuf_tailroom_req = OTX2_CPT_MIN_TAILROOM_REQ;
361         }
362 }
363
364 static int
365 otx2_cpt_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
366                           const struct rte_cryptodev_qp_conf *conf,
367                           int socket_id __rte_unused)
368 {
369         uint8_t grp_mask = OTX2_CPT_ENG_GRPS_MASK;
370         struct rte_pci_device *pci_dev;
371         struct otx2_cpt_qp *qp;
372
373         CPT_PMD_INIT_FUNC_TRACE();
374
375         if (dev->data->queue_pairs[qp_id] != NULL)
376                 otx2_cpt_queue_pair_release(dev, qp_id);
377
378         if (conf->nb_descriptors > OTX2_CPT_DEFAULT_CMD_QLEN) {
379                 CPT_LOG_ERR("Could not setup queue pair for %u descriptors",
380                             conf->nb_descriptors);
381                 return -EINVAL;
382         }
383
384         pci_dev = RTE_DEV_TO_PCI(dev->device);
385
386         if (pci_dev->mem_resource[2].addr == NULL) {
387                 CPT_LOG_ERR("Invalid PCI mem address");
388                 return -EIO;
389         }
390
391         qp = otx2_cpt_qp_create(dev, qp_id, grp_mask);
392         if (qp == NULL) {
393                 CPT_LOG_ERR("Could not create queue pair %d", qp_id);
394                 return -ENOMEM;
395         }
396
397         qp->sess_mp = conf->mp_session;
398         qp->sess_mp_priv = conf->mp_session_private;
399         dev->data->queue_pairs[qp_id] = qp;
400
401         return 0;
402 }
403
404 static int
405 otx2_cpt_queue_pair_release(struct rte_cryptodev *dev, uint16_t qp_id)
406 {
407         struct otx2_cpt_qp *qp = dev->data->queue_pairs[qp_id];
408         int ret;
409
410         CPT_PMD_INIT_FUNC_TRACE();
411
412         if (qp == NULL)
413                 return -EINVAL;
414
415         CPT_LOG_INFO("Releasing queue pair %d", qp_id);
416
417         ret = otx2_cpt_qp_destroy(dev, qp);
418         if (ret) {
419                 CPT_LOG_ERR("Could not destroy queue pair %d", qp_id);
420                 return ret;
421         }
422
423         dev->data->queue_pairs[qp_id] = NULL;
424
425         return 0;
426 }
427
428 struct rte_cryptodev_ops otx2_cpt_ops = {
429         /* Device control ops */
430         .dev_configure = otx2_cpt_dev_config,
431         .dev_start = otx2_cpt_dev_start,
432         .dev_stop = otx2_cpt_dev_stop,
433         .dev_close = otx2_cpt_dev_close,
434         .dev_infos_get = otx2_cpt_dev_info_get,
435
436         .stats_get = NULL,
437         .stats_reset = NULL,
438         .queue_pair_setup = otx2_cpt_queue_pair_setup,
439         .queue_pair_release = otx2_cpt_queue_pair_release,
440         .queue_pair_count = NULL,
441
442         /* Symmetric crypto ops */
443         .sym_session_get_size = NULL,
444         .sym_session_configure = NULL,
445         .sym_session_clear = NULL,
446 };