1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2021-2024 Advanced Micro Devices, Inc.
3 */
4
5 #include <inttypes.h>
6
7 #include <rte_common.h>
8 #include <rte_malloc.h>
9 #include <rte_bitops.h>
10
11 #include "ionic_crypto.h"
12
13 static int
iocpt_cq_init(struct iocpt_cq * cq,uint16_t num_descs)14 iocpt_cq_init(struct iocpt_cq *cq, uint16_t num_descs)
15 {
16 if (!rte_is_power_of_2(num_descs) ||
17 num_descs < IOCPT_MIN_RING_DESC ||
18 num_descs > IOCPT_MAX_RING_DESC) {
19 IOCPT_PRINT(ERR, "%u descriptors (min: %u max: %u)",
20 num_descs, IOCPT_MIN_RING_DESC, IOCPT_MAX_RING_DESC);
21 return -EINVAL;
22 }
23
24 cq->num_descs = num_descs;
25 cq->size_mask = num_descs - 1;
26 cq->tail_idx = 0;
27 cq->done_color = 1;
28
29 return 0;
30 }
31
32 static void
iocpt_cq_reset(struct iocpt_cq * cq)33 iocpt_cq_reset(struct iocpt_cq *cq)
34 {
35 cq->tail_idx = 0;
36 cq->done_color = 1;
37
38 memset(cq->base, 0, sizeof(struct iocpt_nop_comp) * cq->num_descs);
39 }
40
41 static void
iocpt_cq_map(struct iocpt_cq * cq,void * base,rte_iova_t base_pa)42 iocpt_cq_map(struct iocpt_cq *cq, void *base, rte_iova_t base_pa)
43 {
44 cq->base = base;
45 cq->base_pa = base_pa;
46 }
47
48 uint32_t
iocpt_cq_service(struct iocpt_cq * cq,uint32_t work_to_do,iocpt_cq_cb cb,void * cb_arg)49 iocpt_cq_service(struct iocpt_cq *cq, uint32_t work_to_do,
50 iocpt_cq_cb cb, void *cb_arg)
51 {
52 uint32_t work_done = 0;
53
54 if (work_to_do == 0)
55 return 0;
56
57 while (cb(cq, cq->tail_idx, cb_arg)) {
58 cq->tail_idx = Q_NEXT_TO_SRVC(cq, 1);
59 if (cq->tail_idx == 0)
60 cq->done_color = !cq->done_color;
61
62 if (++work_done == work_to_do)
63 break;
64 }
65
66 return work_done;
67 }
68
69 static int
iocpt_q_init(struct iocpt_queue * q,uint8_t type,uint32_t index,uint16_t num_descs,uint16_t num_segs,uint32_t socket_id)70 iocpt_q_init(struct iocpt_queue *q, uint8_t type, uint32_t index,
71 uint16_t num_descs, uint16_t num_segs, uint32_t socket_id)
72 {
73 uint32_t ring_size;
74
75 if (!rte_is_power_of_2(num_descs))
76 return -EINVAL;
77
78 ring_size = rte_log2_u32(num_descs);
79 if (ring_size < 2 || ring_size > 16)
80 return -EINVAL;
81
82 q->type = type;
83 q->index = index;
84 q->num_descs = num_descs;
85 q->num_segs = num_segs;
86 q->size_mask = num_descs - 1;
87 q->head_idx = 0;
88 q->tail_idx = 0;
89
90 q->info = rte_calloc_socket("iocpt",
91 (uint64_t)num_descs * num_segs, sizeof(void *),
92 rte_mem_page_size(), socket_id);
93 if (q->info == NULL) {
94 IOCPT_PRINT(ERR, "Cannot allocate queue info");
95 return -ENOMEM;
96 }
97
98 return 0;
99 }
100
101 static void
iocpt_q_reset(struct iocpt_queue * q)102 iocpt_q_reset(struct iocpt_queue *q)
103 {
104 q->head_idx = 0;
105 q->tail_idx = 0;
106 }
107
108 static void
iocpt_q_map(struct iocpt_queue * q,void * base,rte_iova_t base_pa)109 iocpt_q_map(struct iocpt_queue *q, void *base, rte_iova_t base_pa)
110 {
111 q->base = base;
112 q->base_pa = base_pa;
113 }
114
115 static void
iocpt_q_sg_map(struct iocpt_queue * q,void * base,rte_iova_t base_pa)116 iocpt_q_sg_map(struct iocpt_queue *q, void *base, rte_iova_t base_pa)
117 {
118 q->sg_base = base;
119 q->sg_base_pa = base_pa;
120 }
121
122 static void
iocpt_q_free(struct iocpt_queue * q)123 iocpt_q_free(struct iocpt_queue *q)
124 {
125 if (q->info != NULL) {
126 rte_free(q->info);
127 q->info = NULL;
128 }
129 }
130
131 static void
iocpt_get_abs_stats(const struct iocpt_dev * dev,struct rte_cryptodev_stats * stats)132 iocpt_get_abs_stats(const struct iocpt_dev *dev,
133 struct rte_cryptodev_stats *stats)
134 {
135 uint32_t i;
136
137 memset(stats, 0, sizeof(*stats));
138
139 /* Sum up the per-queue stats counters */
140 for (i = 0; i < dev->crypto_dev->data->nb_queue_pairs; i++) {
141 struct rte_cryptodev_stats *q_stats = &dev->cryptoqs[i]->stats;
142
143 stats->enqueued_count += q_stats->enqueued_count;
144 stats->dequeued_count += q_stats->dequeued_count;
145 stats->enqueue_err_count += q_stats->enqueue_err_count;
146 stats->dequeue_err_count += q_stats->dequeue_err_count;
147 }
148 }
149
150 void
iocpt_get_stats(const struct iocpt_dev * dev,struct rte_cryptodev_stats * stats)151 iocpt_get_stats(const struct iocpt_dev *dev, struct rte_cryptodev_stats *stats)
152 {
153 /* Retrieve the new absolute stats values */
154 iocpt_get_abs_stats(dev, stats);
155
156 /* Subtract the base stats values to get relative values */
157 stats->enqueued_count -= dev->stats_base.enqueued_count;
158 stats->dequeued_count -= dev->stats_base.dequeued_count;
159 stats->enqueue_err_count -= dev->stats_base.enqueue_err_count;
160 stats->dequeue_err_count -= dev->stats_base.dequeue_err_count;
161 }
162
163 void
iocpt_reset_stats(struct iocpt_dev * dev)164 iocpt_reset_stats(struct iocpt_dev *dev)
165 {
166 uint32_t i;
167
168 /* Erase the per-queue stats counters */
169 for (i = 0; i < dev->crypto_dev->data->nb_queue_pairs; i++)
170 memset(&dev->cryptoqs[i]->stats, 0,
171 sizeof(dev->cryptoqs[i]->stats));
172
173 /* Update the base stats values */
174 iocpt_get_abs_stats(dev, &dev->stats_base);
175 }
176
177 static int
iocpt_session_write(struct iocpt_session_priv * priv,enum iocpt_sess_control_oper oper)178 iocpt_session_write(struct iocpt_session_priv *priv,
179 enum iocpt_sess_control_oper oper)
180 {
181 struct iocpt_dev *dev = priv->dev;
182 struct iocpt_admin_ctx ctx = {
183 .pending_work = true,
184 .cmd.sess_control = {
185 .opcode = IOCPT_CMD_SESS_CONTROL,
186 .type = priv->type,
187 .oper = oper,
188 .index = rte_cpu_to_le_32(priv->index),
189 .key_len = rte_cpu_to_le_16(priv->key_len),
190 .key_seg_len = (uint8_t)RTE_MIN(priv->key_len,
191 IOCPT_SESS_KEY_SEG_LEN),
192 },
193 };
194 struct iocpt_sess_control_cmd *cmd = &ctx.cmd.sess_control;
195 uint16_t key_offset;
196 uint8_t key_segs, seg, seg_len;
197 int err;
198
199 key_segs = ((priv->key_len - 1) >> IOCPT_SESS_KEY_SEG_SHFT) + 1;
200
201 for (seg = 0; seg < key_segs; seg++) {
202 ctx.pending_work = true;
203
204 key_offset = seg * cmd->key_seg_len;
205 seg_len = (uint8_t)RTE_MIN(priv->key_len - key_offset,
206 IOCPT_SESS_KEY_SEG_LEN);
207 memcpy(cmd->key, &priv->key[key_offset], seg_len);
208 cmd->key_seg_idx = seg;
209
210 /* Mark final segment */
211 if (seg + 1 == key_segs)
212 cmd->flags |= rte_cpu_to_le_16(IOCPT_SCTL_F_END);
213
214 err = iocpt_adminq_post_wait(dev, &ctx);
215 if (err != 0)
216 return err;
217 }
218
219 return 0;
220 }
221
222 static int
iocpt_session_wdog(struct iocpt_dev * dev)223 iocpt_session_wdog(struct iocpt_dev *dev)
224 {
225 struct iocpt_session_priv priv = {
226 .dev = dev,
227 .index = IOCPT_Q_WDOG_SESS_IDX,
228 .type = IOCPT_SESS_AEAD_AES_GCM,
229 .key_len = IOCPT_Q_WDOG_KEY_LEN,
230 };
231
232 /* Reserve session 0 for queue watchdog */
233 rte_bitmap_clear(dev->sess_bm, IOCPT_Q_WDOG_SESS_IDX);
234
235 return iocpt_session_write(&priv, IOCPT_SESS_INIT);
236 }
237
238 int
iocpt_session_init(struct iocpt_session_priv * priv)239 iocpt_session_init(struct iocpt_session_priv *priv)
240 {
241 struct iocpt_dev *dev = priv->dev;
242 uint64_t bm_slab = 0;
243 uint32_t bm_pos = 0;
244 int err = 0;
245
246 rte_spinlock_lock(&dev->adminq_lock);
247
248 if (rte_bitmap_scan(dev->sess_bm, &bm_pos, &bm_slab) > 0) {
249 priv->index = bm_pos + rte_ctz64(bm_slab);
250 rte_bitmap_clear(dev->sess_bm, priv->index);
251 } else
252 err = -ENOSPC;
253
254 rte_spinlock_unlock(&dev->adminq_lock);
255
256 if (err != 0) {
257 IOCPT_PRINT(ERR, "session index space exhausted");
258 return err;
259 }
260
261 err = iocpt_session_write(priv, IOCPT_SESS_INIT);
262 if (err != 0) {
263 rte_spinlock_lock(&dev->adminq_lock);
264 rte_bitmap_set(dev->sess_bm, priv->index);
265 rte_spinlock_unlock(&dev->adminq_lock);
266 return err;
267 }
268
269 priv->flags |= IOCPT_S_F_INITED;
270
271 return 0;
272 }
273
274 int
iocpt_session_update(struct iocpt_session_priv * priv)275 iocpt_session_update(struct iocpt_session_priv *priv)
276 {
277 return iocpt_session_write(priv, IOCPT_SESS_UPDATE_KEY);
278 }
279
280 void
iocpt_session_deinit(struct iocpt_session_priv * priv)281 iocpt_session_deinit(struct iocpt_session_priv *priv)
282 {
283 struct iocpt_dev *dev = priv->dev;
284 struct iocpt_admin_ctx ctx = {
285 .pending_work = true,
286 .cmd.sess_control = {
287 .opcode = IOCPT_CMD_SESS_CONTROL,
288 .type = priv->type,
289 .oper = IOCPT_SESS_DISABLE,
290 .index = rte_cpu_to_le_32(priv->index),
291 .key_len = rte_cpu_to_le_16(priv->key_len),
292 },
293 };
294
295 (void)iocpt_adminq_post_wait(dev, &ctx);
296
297 rte_spinlock_lock(&dev->adminq_lock);
298 rte_bitmap_set(dev->sess_bm, priv->index);
299 rte_spinlock_unlock(&dev->adminq_lock);
300
301 priv->flags &= ~IOCPT_S_F_INITED;
302 }
303
304 static const struct rte_memzone *
iocpt_dma_zone_reserve(const char * type_name,uint16_t qid,size_t size,unsigned int align,int socket_id)305 iocpt_dma_zone_reserve(const char *type_name, uint16_t qid, size_t size,
306 unsigned int align, int socket_id)
307 {
308 char zone_name[RTE_MEMZONE_NAMESIZE];
309 const struct rte_memzone *mz;
310 int err;
311
312 err = snprintf(zone_name, sizeof(zone_name),
313 "iocpt_%s_%u", type_name, qid);
314 if (err >= RTE_MEMZONE_NAMESIZE) {
315 IOCPT_PRINT(ERR, "Name %s too long", type_name);
316 return NULL;
317 }
318
319 mz = rte_memzone_lookup(zone_name);
320 if (mz != NULL)
321 return mz;
322
323 return rte_memzone_reserve_aligned(zone_name, size, socket_id,
324 RTE_MEMZONE_IOVA_CONTIG, align);
325 }
326
327 static int
iocpt_commonq_alloc(struct iocpt_dev * dev,uint8_t type,size_t struct_size,uint32_t socket_id,uint32_t index,const char * type_name,uint16_t flags,uint16_t num_descs,uint16_t num_segs,uint16_t desc_size,uint16_t cq_desc_size,uint16_t sg_desc_size,struct iocpt_common_q ** comq)328 iocpt_commonq_alloc(struct iocpt_dev *dev,
329 uint8_t type,
330 size_t struct_size,
331 uint32_t socket_id,
332 uint32_t index,
333 const char *type_name,
334 uint16_t flags,
335 uint16_t num_descs,
336 uint16_t num_segs,
337 uint16_t desc_size,
338 uint16_t cq_desc_size,
339 uint16_t sg_desc_size,
340 struct iocpt_common_q **comq)
341 {
342 struct iocpt_common_q *new;
343 uint32_t q_size, cq_size, sg_size, total_size;
344 void *q_base, *cq_base, *sg_base;
345 rte_iova_t q_base_pa = 0;
346 rte_iova_t cq_base_pa = 0;
347 rte_iova_t sg_base_pa = 0;
348 size_t page_size = rte_mem_page_size();
349 int err;
350
351 *comq = NULL;
352
353 q_size = num_descs * desc_size;
354 cq_size = num_descs * cq_desc_size;
355 sg_size = num_descs * sg_desc_size;
356
357 /*
358 * Note: aligning q_size/cq_size is not enough due to cq_base address
359 * aligning as q_base could be not aligned to the page.
360 * Adding page_size.
361 */
362 total_size = RTE_ALIGN(q_size, page_size) +
363 RTE_ALIGN(cq_size, page_size) + page_size;
364 if (flags & IOCPT_Q_F_SG)
365 total_size += RTE_ALIGN(sg_size, page_size) + page_size;
366
367 new = rte_zmalloc_socket("iocpt", struct_size,
368 RTE_CACHE_LINE_SIZE, socket_id);
369 if (new == NULL) {
370 IOCPT_PRINT(ERR, "Cannot allocate queue structure");
371 return -ENOMEM;
372 }
373
374 new->dev = dev;
375
376 err = iocpt_q_init(&new->q, type, index, num_descs, num_segs,
377 socket_id);
378 if (err != 0) {
379 IOCPT_PRINT(ERR, "Queue initialization failed");
380 goto err_free_q;
381 }
382
383 err = iocpt_cq_init(&new->cq, num_descs);
384 if (err != 0) {
385 IOCPT_PRINT(ERR, "Completion queue initialization failed");
386 goto err_deinit_q;
387 }
388
389 new->base_z = iocpt_dma_zone_reserve(type_name, index, total_size,
390 IONIC_ALIGN, socket_id);
391 if (new->base_z == NULL) {
392 IOCPT_PRINT(ERR, "Cannot reserve queue DMA memory");
393 err = -ENOMEM;
394 goto err_deinit_cq;
395 }
396
397 new->base = new->base_z->addr;
398 new->base_pa = new->base_z->iova;
399
400 q_base = new->base;
401 q_base_pa = new->base_pa;
402 iocpt_q_map(&new->q, q_base, q_base_pa);
403
404 cq_base = (void *)RTE_ALIGN((uintptr_t)q_base + q_size, page_size);
405 cq_base_pa = RTE_ALIGN(q_base_pa + q_size, page_size);
406 iocpt_cq_map(&new->cq, cq_base, cq_base_pa);
407
408 if (flags & IOCPT_Q_F_SG) {
409 sg_base = (void *)RTE_ALIGN((uintptr_t)cq_base + cq_size,
410 page_size);
411 sg_base_pa = RTE_ALIGN(cq_base_pa + cq_size, page_size);
412 iocpt_q_sg_map(&new->q, sg_base, sg_base_pa);
413 }
414
415 IOCPT_PRINT(DEBUG, "q_base_pa %#jx cq_base_pa %#jx sg_base_pa %#jx",
416 q_base_pa, cq_base_pa, sg_base_pa);
417
418 *comq = new;
419
420 return 0;
421
422 err_deinit_cq:
423 err_deinit_q:
424 iocpt_q_free(&new->q);
425 err_free_q:
426 rte_free(new);
427 return err;
428 }
429
430 int
iocpt_cryptoq_alloc(struct iocpt_dev * dev,uint32_t socket_id,uint32_t index,uint16_t num_descs)431 iocpt_cryptoq_alloc(struct iocpt_dev *dev, uint32_t socket_id, uint32_t index,
432 uint16_t num_descs)
433 {
434 struct iocpt_crypto_q *cptq;
435 uint16_t flags = 0;
436 int err;
437
438 /* CryptoQ always supports scatter-gather */
439 flags |= IOCPT_Q_F_SG;
440
441 IOCPT_PRINT(DEBUG, "cptq %u num_descs %u num_segs %u",
442 index, num_descs, 1);
443
444 err = iocpt_commonq_alloc(dev,
445 IOCPT_QTYPE_CRYPTOQ,
446 sizeof(struct iocpt_crypto_q),
447 socket_id,
448 index,
449 "crypto",
450 flags,
451 num_descs,
452 1,
453 sizeof(struct iocpt_crypto_desc),
454 sizeof(struct iocpt_crypto_comp),
455 sizeof(struct iocpt_crypto_sg_desc),
456 (struct iocpt_common_q **)&cptq);
457 if (err != 0)
458 return err;
459
460 cptq->flags = flags;
461
462 dev->cryptoqs[index] = cptq;
463
464 return 0;
465 }
466
467 struct ionic_doorbell *
iocpt_db_map(struct iocpt_dev * dev,struct iocpt_queue * q)468 iocpt_db_map(struct iocpt_dev *dev, struct iocpt_queue *q)
469 {
470 return dev->db_pages + q->hw_type;
471 }
472
473 static int
iocpt_cryptoq_init(struct iocpt_crypto_q * cptq)474 iocpt_cryptoq_init(struct iocpt_crypto_q *cptq)
475 {
476 struct iocpt_queue *q = &cptq->q;
477 struct iocpt_dev *dev = cptq->dev;
478 struct iocpt_cq *cq = &cptq->cq;
479 struct iocpt_admin_ctx ctx = {
480 .pending_work = true,
481 .cmd.q_init = {
482 .opcode = IOCPT_CMD_Q_INIT,
483 .type = IOCPT_QTYPE_CRYPTOQ,
484 .ver = dev->qtype_info[IOCPT_QTYPE_CRYPTOQ].version,
485 .index = rte_cpu_to_le_32(q->index),
486 .flags = rte_cpu_to_le_16(IOCPT_QINIT_F_ENA |
487 IOCPT_QINIT_F_SG),
488 .intr_index = rte_cpu_to_le_16(IONIC_INTR_NONE),
489 .ring_size = rte_log2_u32(q->num_descs),
490 .ring_base = rte_cpu_to_le_64(q->base_pa),
491 .cq_ring_base = rte_cpu_to_le_64(cq->base_pa),
492 .sg_ring_base = rte_cpu_to_le_64(q->sg_base_pa),
493 },
494 };
495 int err;
496
497 IOCPT_PRINT(DEBUG, "cptq_init.index %d", q->index);
498 IOCPT_PRINT(DEBUG, "cptq_init.ring_base %#jx", q->base_pa);
499 IOCPT_PRINT(DEBUG, "cptq_init.ring_size %d",
500 ctx.cmd.q_init.ring_size);
501 IOCPT_PRINT(DEBUG, "cptq_init.ver %u", ctx.cmd.q_init.ver);
502
503 iocpt_q_reset(q);
504 iocpt_cq_reset(cq);
505
506 err = iocpt_adminq_post_wait(dev, &ctx);
507 if (err != 0)
508 return err;
509
510 q->hw_type = ctx.comp.q_init.hw_type;
511 q->hw_index = rte_le_to_cpu_32(ctx.comp.q_init.hw_index);
512 q->db = iocpt_db_map(dev, q);
513
514 IOCPT_PRINT(DEBUG, "cptq->hw_type %d", q->hw_type);
515 IOCPT_PRINT(DEBUG, "cptq->hw_index %d", q->hw_index);
516 IOCPT_PRINT(DEBUG, "cptq->db %p", q->db);
517
518 cptq->flags |= IOCPT_Q_F_INITED;
519
520 return 0;
521 }
522
523 static void
iocpt_cryptoq_deinit(struct iocpt_crypto_q * cptq)524 iocpt_cryptoq_deinit(struct iocpt_crypto_q *cptq)
525 {
526 struct iocpt_dev *dev = cptq->dev;
527 struct iocpt_admin_ctx ctx = {
528 .pending_work = true,
529 .cmd.q_control = {
530 .opcode = IOCPT_CMD_Q_CONTROL,
531 .type = IOCPT_QTYPE_CRYPTOQ,
532 .index = rte_cpu_to_le_32(cptq->q.index),
533 .oper = IOCPT_Q_DISABLE,
534 },
535 };
536 unsigned long sleep_usec = 100UL * 1000;
537 uint32_t sleep_cnt, sleep_max = IOCPT_CRYPTOQ_WAIT;
538 int err;
539
540 for (sleep_cnt = 0; sleep_cnt < sleep_max; sleep_cnt++) {
541 ctx.pending_work = true;
542
543 err = iocpt_adminq_post_wait(dev, &ctx);
544 if (err != -EAGAIN)
545 break;
546
547 rte_delay_us_block(sleep_usec);
548 }
549
550 if (err != 0)
551 IOCPT_PRINT(ERR, "Deinit queue %u returned %d after %u ms",
552 cptq->q.index, err, sleep_cnt * 100);
553 else
554 IOCPT_PRINT(DEBUG, "Deinit queue %u returned %d after %u ms",
555 cptq->q.index, err, sleep_cnt * 100);
556
557 IOCPT_PRINT(DEBUG, "Queue %u watchdog: enq %"PRIu64" deq %"PRIu64,
558 cptq->q.index, cptq->enqueued_wdogs, cptq->dequeued_wdogs);
559
560 cptq->flags &= ~IOCPT_Q_F_INITED;
561 }
562
563 void
iocpt_cryptoq_free(struct iocpt_crypto_q * cptq)564 iocpt_cryptoq_free(struct iocpt_crypto_q *cptq)
565 {
566 if (cptq == NULL)
567 return;
568
569 if (cptq->base_z != NULL) {
570 rte_memzone_free(cptq->base_z);
571 cptq->base_z = NULL;
572 cptq->base = NULL;
573 cptq->base_pa = 0;
574 }
575
576 iocpt_q_free(&cptq->q);
577
578 rte_free(cptq);
579 }
580
581 static int
iocpt_adminq_alloc(struct iocpt_dev * dev)582 iocpt_adminq_alloc(struct iocpt_dev *dev)
583 {
584 struct iocpt_admin_q *aq;
585 uint16_t num_descs = IOCPT_ADMINQ_LENGTH;
586 uint16_t flags = 0;
587 int err;
588
589 err = iocpt_commonq_alloc(dev,
590 IOCPT_QTYPE_ADMINQ,
591 sizeof(struct iocpt_admin_q),
592 rte_socket_id(),
593 0,
594 "admin",
595 flags,
596 num_descs,
597 1,
598 sizeof(struct iocpt_admin_cmd),
599 sizeof(struct iocpt_admin_comp),
600 0,
601 (struct iocpt_common_q **)&aq);
602 if (err != 0)
603 return err;
604
605 aq->flags = flags;
606
607 dev->adminq = aq;
608
609 return 0;
610 }
611
612 static int
iocpt_adminq_init(struct iocpt_dev * dev)613 iocpt_adminq_init(struct iocpt_dev *dev)
614 {
615 return iocpt_dev_adminq_init(dev);
616 }
617
618 static void
iocpt_adminq_deinit(struct iocpt_dev * dev)619 iocpt_adminq_deinit(struct iocpt_dev *dev)
620 {
621 dev->adminq->flags &= ~IOCPT_Q_F_INITED;
622 }
623
624 static void
iocpt_adminq_free(struct iocpt_admin_q * aq)625 iocpt_adminq_free(struct iocpt_admin_q *aq)
626 {
627 if (aq->base_z != NULL) {
628 rte_memzone_free(aq->base_z);
629 aq->base_z = NULL;
630 aq->base = NULL;
631 aq->base_pa = 0;
632 }
633
634 iocpt_q_free(&aq->q);
635
636 rte_free(aq);
637 }
638
639 static int
iocpt_alloc_objs(struct iocpt_dev * dev)640 iocpt_alloc_objs(struct iocpt_dev *dev)
641 {
642 uint32_t bmsize, i;
643 uint8_t *bm;
644 int err;
645
646 IOCPT_PRINT(DEBUG, "Crypto: %s", dev->name);
647
648 dev->cryptoqs = rte_calloc_socket("iocpt",
649 dev->max_qps, sizeof(*dev->cryptoqs),
650 RTE_CACHE_LINE_SIZE, dev->socket_id);
651 if (dev->cryptoqs == NULL) {
652 IOCPT_PRINT(ERR, "Cannot allocate tx queues array");
653 return -ENOMEM;
654 }
655
656 rte_spinlock_init(&dev->adminq_lock);
657 rte_spinlock_init(&dev->adminq_service_lock);
658
659 err = iocpt_adminq_alloc(dev);
660 if (err != 0) {
661 IOCPT_PRINT(ERR, "Cannot allocate admin queue");
662 err = -ENOMEM;
663 goto err_free_cryptoqs;
664 }
665
666 dev->info_sz = RTE_ALIGN(sizeof(*dev->info), rte_mem_page_size());
667 dev->info_z = iocpt_dma_zone_reserve("info", 0, dev->info_sz,
668 IONIC_ALIGN, dev->socket_id);
669 if (dev->info_z == NULL) {
670 IOCPT_PRINT(ERR, "Cannot allocate dev info memory");
671 err = -ENOMEM;
672 goto err_free_adminq;
673 }
674
675 dev->info = dev->info_z->addr;
676 dev->info_pa = dev->info_z->iova;
677
678 bmsize = rte_bitmap_get_memory_footprint(dev->max_sessions);
679 bm = rte_malloc_socket("iocpt", bmsize,
680 RTE_CACHE_LINE_SIZE, dev->socket_id);
681 if (bm == NULL) {
682 IOCPT_PRINT(ERR, "Cannot allocate %uB bitmap memory", bmsize);
683 err = -ENOMEM;
684 goto err_free_dmazone;
685 }
686
687 dev->sess_bm = rte_bitmap_init(dev->max_sessions, bm, bmsize);
688 if (dev->sess_bm == NULL) {
689 IOCPT_PRINT(ERR, "Cannot initialize bitmap");
690 err = -EFAULT;
691 goto err_free_bm;
692 }
693 for (i = 0; i < dev->max_sessions; i++)
694 rte_bitmap_set(dev->sess_bm, i);
695
696 return 0;
697
698 err_free_bm:
699 rte_free(bm);
700 err_free_dmazone:
701 rte_memzone_free(dev->info_z);
702 dev->info_z = NULL;
703 dev->info = NULL;
704 dev->info_pa = 0;
705 err_free_adminq:
706 iocpt_adminq_free(dev->adminq);
707 dev->adminq = NULL;
708 err_free_cryptoqs:
709 rte_free(dev->cryptoqs);
710 dev->cryptoqs = NULL;
711 return err;
712 }
713
714 static int
iocpt_init(struct iocpt_dev * dev)715 iocpt_init(struct iocpt_dev *dev)
716 {
717 int err;
718
719 memset(&dev->stats_base, 0, sizeof(dev->stats_base));
720
721 /* Uses dev_cmds */
722 err = iocpt_dev_init(dev, dev->info_pa);
723 if (err != 0)
724 return err;
725
726 err = iocpt_adminq_init(dev);
727 if (err != 0)
728 return err;
729
730 /* Write the queue watchdog key */
731 err = iocpt_session_wdog(dev);
732 if (err != 0) {
733 IOCPT_PRINT(ERR, "Cannot setup watchdog session");
734 goto err_out_adminq_deinit;
735 }
736
737 dev->state |= IOCPT_DEV_F_INITED;
738
739 return 0;
740
741 err_out_adminq_deinit:
742 iocpt_adminq_deinit(dev);
743
744 return err;
745 }
746
747 void
iocpt_configure(struct iocpt_dev * dev)748 iocpt_configure(struct iocpt_dev *dev)
749 {
750 RTE_SET_USED(dev);
751 }
752
753 int
iocpt_start(struct iocpt_dev * dev)754 iocpt_start(struct iocpt_dev *dev)
755 {
756 uint32_t i;
757 int err;
758
759 IOCPT_PRINT(DEBUG, "Starting %u queues",
760 dev->crypto_dev->data->nb_queue_pairs);
761
762 for (i = 0; i < dev->crypto_dev->data->nb_queue_pairs; i++) {
763 err = iocpt_cryptoq_init(dev->cryptoqs[i]);
764 if (err != 0)
765 return err;
766 }
767
768 dev->state |= IOCPT_DEV_F_UP;
769
770 return 0;
771 }
772
773 void
iocpt_stop(struct iocpt_dev * dev)774 iocpt_stop(struct iocpt_dev *dev)
775 {
776 uint32_t i;
777
778 IOCPT_PRINT_CALL();
779
780 dev->state &= ~IOCPT_DEV_F_UP;
781
782 for (i = 0; i < dev->crypto_dev->data->nb_queue_pairs; i++) {
783 struct iocpt_crypto_q *cptq = dev->cryptoqs[i];
784
785 if (cptq->flags & IOCPT_Q_F_INITED)
786 (void)iocpt_cryptoq_deinit(cptq);
787 }
788 }
789
790 void
iocpt_deinit(struct iocpt_dev * dev)791 iocpt_deinit(struct iocpt_dev *dev)
792 {
793 IOCPT_PRINT_CALL();
794
795 if (!(dev->state & IOCPT_DEV_F_INITED))
796 return;
797
798 iocpt_adminq_deinit(dev);
799
800 dev->state &= ~IOCPT_DEV_F_INITED;
801 }
802
803 static void
iocpt_free_objs(struct iocpt_dev * dev)804 iocpt_free_objs(struct iocpt_dev *dev)
805 {
806 void **queue_pairs = dev->crypto_dev->data->queue_pairs;
807 uint32_t i;
808
809 IOCPT_PRINT_CALL();
810
811 for (i = 0; i < dev->crypto_dev->data->nb_queue_pairs; i++) {
812 iocpt_cryptoq_free(queue_pairs[i]);
813 queue_pairs[i] = NULL;
814 }
815
816 if (dev->sess_bm != NULL) {
817 rte_bitmap_free(dev->sess_bm);
818 rte_free(dev->sess_bm);
819 dev->sess_bm = NULL;
820 }
821
822 if (dev->adminq != NULL) {
823 iocpt_adminq_free(dev->adminq);
824 dev->adminq = NULL;
825 }
826
827 if (dev->cryptoqs != NULL) {
828 rte_free(dev->cryptoqs);
829 dev->cryptoqs = NULL;
830 }
831
832 if (dev->info != NULL) {
833 rte_memzone_free(dev->info_z);
834 dev->info_z = NULL;
835 dev->info = NULL;
836 dev->info_pa = 0;
837 }
838 }
839
840 static int
iocpt_devargs(struct rte_devargs * devargs,struct iocpt_dev * dev)841 iocpt_devargs(struct rte_devargs *devargs, struct iocpt_dev *dev)
842 {
843 RTE_SET_USED(devargs);
844 RTE_SET_USED(dev);
845
846 return 0;
847 }
848
849 int
iocpt_probe(void * bus_dev,struct rte_device * rte_dev,struct iocpt_dev_bars * bars,const struct iocpt_dev_intf * intf,uint8_t driver_id,uint8_t socket_id)850 iocpt_probe(void *bus_dev, struct rte_device *rte_dev,
851 struct iocpt_dev_bars *bars, const struct iocpt_dev_intf *intf,
852 uint8_t driver_id, uint8_t socket_id)
853 {
854 struct rte_cryptodev_pmd_init_params init_params = {
855 "iocpt",
856 sizeof(struct iocpt_dev),
857 socket_id,
858 RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
859 };
860 struct rte_cryptodev *cdev;
861 struct iocpt_dev *dev;
862 uint32_t i, sig;
863 int err;
864
865 /* Check structs (trigger error at compilation time) */
866 iocpt_struct_size_checks();
867
868 if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
869 IOCPT_PRINT(ERR, "Multi-process not supported");
870 err = -EPERM;
871 goto err;
872 }
873
874 cdev = rte_cryptodev_pmd_create(rte_dev->name, rte_dev, &init_params);
875 if (cdev == NULL) {
876 IOCPT_PRINT(ERR, "Out of memory");
877 err = -ENOMEM;
878 goto err;
879 }
880
881 dev = cdev->data->dev_private;
882 dev->crypto_dev = cdev;
883 dev->bus_dev = bus_dev;
884 dev->intf = intf;
885 dev->driver_id = driver_id;
886 dev->socket_id = socket_id;
887
888 for (i = 0; i < bars->num_bars; i++) {
889 struct ionic_dev_bar *bar = &bars->bar[i];
890
891 IOCPT_PRINT(DEBUG,
892 "bar[%u] = { .va = %p, .pa = %#jx, .len = %lu }",
893 i, bar->vaddr, bar->bus_addr, bar->len);
894 if (bar->vaddr == NULL) {
895 IOCPT_PRINT(ERR, "Null bar found, aborting");
896 err = -EFAULT;
897 goto err_destroy_crypto_dev;
898 }
899
900 dev->bars.bar[i].vaddr = bar->vaddr;
901 dev->bars.bar[i].bus_addr = bar->bus_addr;
902 dev->bars.bar[i].len = bar->len;
903 }
904 dev->bars.num_bars = bars->num_bars;
905
906 err = iocpt_devargs(rte_dev->devargs, dev);
907 if (err != 0) {
908 IOCPT_PRINT(ERR, "Cannot parse device arguments");
909 goto err_destroy_crypto_dev;
910 }
911
912 err = iocpt_setup_bars(dev);
913 if (err != 0) {
914 IOCPT_PRINT(ERR, "Cannot setup BARs: %d, aborting", err);
915 goto err_destroy_crypto_dev;
916 }
917
918 sig = ioread32(&dev->dev_info->signature);
919 if (sig != IOCPT_DEV_INFO_SIGNATURE) {
920 IOCPT_PRINT(ERR, "Incompatible firmware signature %#x", sig);
921 err = -EFAULT;
922 goto err_destroy_crypto_dev;
923 }
924
925 for (i = 0; i < IOCPT_FWVERS_BUFLEN; i++)
926 dev->fw_version[i] = ioread8(&dev->dev_info->fw_version[i]);
927 dev->fw_version[IOCPT_FWVERS_BUFLEN - 1] = '\0';
928 IOCPT_PRINT(DEBUG, "%s firmware: %s", dev->name, dev->fw_version);
929
930 err = iocpt_dev_identify(dev);
931 if (err != 0) {
932 IOCPT_PRINT(ERR, "Cannot identify device: %d, aborting",
933 err);
934 goto err_destroy_crypto_dev;
935 }
936
937 err = iocpt_alloc_objs(dev);
938 if (err != 0) {
939 IOCPT_PRINT(ERR, "Cannot alloc device objects: %d", err);
940 goto err_destroy_crypto_dev;
941 }
942
943 err = iocpt_init(dev);
944 if (err != 0) {
945 IOCPT_PRINT(ERR, "Cannot init device: %d, aborting", err);
946 goto err_free_objs;
947 }
948
949 err = iocpt_assign_ops(cdev);
950 if (err != 0) {
951 IOCPT_PRINT(ERR, "Failed to configure opts");
952 goto err_deinit_dev;
953 }
954
955 return 0;
956
957 err_deinit_dev:
958 iocpt_deinit(dev);
959 err_free_objs:
960 iocpt_free_objs(dev);
961 err_destroy_crypto_dev:
962 rte_cryptodev_pmd_destroy(cdev);
963 err:
964 return err;
965 }
966
967 int
iocpt_remove(struct rte_device * rte_dev)968 iocpt_remove(struct rte_device *rte_dev)
969 {
970 struct rte_cryptodev *cdev;
971 struct iocpt_dev *dev;
972
973 cdev = rte_cryptodev_pmd_get_named_dev(rte_dev->name);
974 if (cdev == NULL) {
975 IOCPT_PRINT(DEBUG, "Cannot find device %s", rte_dev->name);
976 return -ENODEV;
977 }
978
979 dev = cdev->data->dev_private;
980
981 iocpt_deinit(dev);
982
983 iocpt_dev_reset(dev);
984
985 iocpt_free_objs(dev);
986
987 rte_cryptodev_pmd_destroy(cdev);
988
989 return 0;
990 }
991
992 RTE_LOG_REGISTER_DEFAULT(iocpt_logtype, NOTICE);
993