1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2017-2019 NXP
10 #include <rte_byteorder.h>
11 #include <rte_common.h>
12 #include <rte_cryptodev_pmd.h>
13 #include <rte_crypto.h>
14 #include <rte_cryptodev.h>
15 #include <rte_bus_vdev.h>
16 #include <rte_malloc.h>
17 #include <rte_security_driver.h>
18 #include <rte_hexdump.h>
20 #include <caam_jr_capabilities.h>
21 #include <caam_jr_config.h>
22 #include <caam_jr_hw_specific.h>
23 #include <caam_jr_pvt.h>
24 #include <caam_jr_desc.h>
25 #include <caam_jr_log.h>
27 /* RTA header files */
28 #include <desc/common.h>
29 #include <desc/algo.h>
31 #ifdef RTE_LIBRTE_PMD_CAAM_JR_DEBUG
36 #define CRYPTODEV_NAME_CAAM_JR_PMD crypto_caam_jr
37 static uint8_t cryptodev_driver_id
;
40 /* Lists the states possible for the SEC user space driver. */
41 enum sec_driver_state_e
{
42 SEC_DRIVER_STATE_IDLE
, /* Driver not initialized */
43 SEC_DRIVER_STATE_STARTED
, /* Driver initialized and can be used*/
44 SEC_DRIVER_STATE_RELEASE
, /* Driver release is in progress */
47 /* Job rings used for communication with SEC HW */
48 static struct sec_job_ring_t g_job_rings
[MAX_SEC_JOB_RINGS
];
50 /* The current state of SEC user space driver */
51 static enum sec_driver_state_e g_driver_state
= SEC_DRIVER_STATE_IDLE
;
53 /* The number of job rings used by SEC user space driver */
54 static int g_job_rings_no
;
55 static int g_job_rings_max
;
57 struct sec_outring_entry
{
58 phys_addr_t desc
; /* Pointer to completed descriptor */
59 uint32_t status
; /* Status for completed descriptor */
62 /* virtual address conversin when mempool support is available for ctx */
63 static inline phys_addr_t
64 caam_jr_vtop_ctx(struct caam_jr_op_ctx
*ctx
, void *vaddr
)
66 return (size_t)vaddr
- ctx
->vtop_offset
;
70 caam_jr_op_ending(struct caam_jr_op_ctx
*ctx
)
72 /* report op status to sym->op and then free the ctx memory */
73 rte_mempool_put(ctx
->ctx_pool
, (void *)ctx
);
76 static inline struct caam_jr_op_ctx
*
77 caam_jr_alloc_ctx(struct caam_jr_session
*ses
)
79 struct caam_jr_op_ctx
*ctx
;
82 ret
= rte_mempool_get(ses
->ctx_pool
, (void **)(&ctx
));
84 CAAM_JR_DP_WARN("Alloc sec descriptor failed!");
88 * Clear SG memory. There are 16 SG entries of 16 Bytes each.
89 * one call to dcbz_64() clear 64 bytes, hence calling it 4 times
90 * to clear all the SG entries. caam_jr_alloc_ctx() is called for
91 * each packet, memset is costlier than dcbz_64().
93 dcbz_64(&ctx
->sg
[SG_CACHELINE_0
]);
94 dcbz_64(&ctx
->sg
[SG_CACHELINE_1
]);
95 dcbz_64(&ctx
->sg
[SG_CACHELINE_2
]);
96 dcbz_64(&ctx
->sg
[SG_CACHELINE_3
]);
98 ctx
->ctx_pool
= ses
->ctx_pool
;
99 ctx
->vtop_offset
= (size_t) ctx
- rte_mempool_virt2iova(ctx
);
105 void caam_jr_stats_get(struct rte_cryptodev
*dev
,
106 struct rte_cryptodev_stats
*stats
)
108 struct caam_jr_qp
**qp
= (struct caam_jr_qp
**)
109 dev
->data
->queue_pairs
;
112 PMD_INIT_FUNC_TRACE();
114 CAAM_JR_ERR("Invalid stats ptr NULL");
117 for (i
= 0; i
< dev
->data
->nb_queue_pairs
; i
++) {
119 CAAM_JR_WARN("Uninitialised queue pair");
123 stats
->enqueued_count
+= qp
[i
]->tx_pkts
;
124 stats
->dequeued_count
+= qp
[i
]->rx_pkts
;
125 stats
->enqueue_err_count
+= qp
[i
]->tx_errs
;
126 stats
->dequeue_err_count
+= qp
[i
]->rx_errs
;
127 CAAM_JR_INFO("extra stats:\n\tRX Poll ERR = %" PRIu64
128 "\n\tTX Ring Full = %" PRIu64
,
130 qp
[i
]->tx_ring_full
);
135 void caam_jr_stats_reset(struct rte_cryptodev
*dev
)
138 struct caam_jr_qp
**qp
= (struct caam_jr_qp
**)
139 (dev
->data
->queue_pairs
);
141 PMD_INIT_FUNC_TRACE();
142 for (i
= 0; i
< dev
->data
->nb_queue_pairs
; i
++) {
144 CAAM_JR_WARN("Uninitialised queue pair");
149 qp
[i
]->rx_poll_err
= 0;
152 qp
[i
]->tx_ring_full
= 0;
157 is_cipher_only(struct caam_jr_session
*ses
)
159 return ((ses
->cipher_alg
!= RTE_CRYPTO_CIPHER_NULL
) &&
160 (ses
->auth_alg
== RTE_CRYPTO_AUTH_NULL
));
164 is_auth_only(struct caam_jr_session
*ses
)
166 return ((ses
->cipher_alg
== RTE_CRYPTO_CIPHER_NULL
) &&
167 (ses
->auth_alg
!= RTE_CRYPTO_AUTH_NULL
));
171 is_aead(struct caam_jr_session
*ses
)
173 return ((ses
->cipher_alg
== 0) &&
174 (ses
->auth_alg
== 0) &&
175 (ses
->aead_alg
!= 0));
179 is_auth_cipher(struct caam_jr_session
*ses
)
181 return ((ses
->cipher_alg
!= RTE_CRYPTO_CIPHER_NULL
) &&
182 (ses
->auth_alg
!= RTE_CRYPTO_AUTH_NULL
) &&
183 (ses
->proto_alg
!= RTE_SECURITY_PROTOCOL_IPSEC
));
187 is_proto_ipsec(struct caam_jr_session
*ses
)
189 return (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
);
193 is_encode(struct caam_jr_session
*ses
)
195 return ses
->dir
== DIR_ENC
;
199 is_decode(struct caam_jr_session
*ses
)
201 return ses
->dir
== DIR_DEC
;
205 caam_auth_alg(struct caam_jr_session
*ses
, struct alginfo
*alginfo_a
)
207 switch (ses
->auth_alg
) {
208 case RTE_CRYPTO_AUTH_NULL
:
209 ses
->digest_length
= 0;
211 case RTE_CRYPTO_AUTH_MD5_HMAC
:
213 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
214 OP_PCL_IPSEC_HMAC_MD5_96
: OP_ALG_ALGSEL_MD5
;
215 alginfo_a
->algmode
= OP_ALG_AAI_HMAC
;
217 case RTE_CRYPTO_AUTH_SHA1_HMAC
:
219 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
220 OP_PCL_IPSEC_HMAC_SHA1_96
: OP_ALG_ALGSEL_SHA1
;
221 alginfo_a
->algmode
= OP_ALG_AAI_HMAC
;
223 case RTE_CRYPTO_AUTH_SHA224_HMAC
:
225 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
226 OP_PCL_IPSEC_HMAC_SHA1_160
: OP_ALG_ALGSEL_SHA224
;
227 alginfo_a
->algmode
= OP_ALG_AAI_HMAC
;
229 case RTE_CRYPTO_AUTH_SHA256_HMAC
:
231 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
232 OP_PCL_IPSEC_HMAC_SHA2_256_128
: OP_ALG_ALGSEL_SHA256
;
233 alginfo_a
->algmode
= OP_ALG_AAI_HMAC
;
235 case RTE_CRYPTO_AUTH_SHA384_HMAC
:
237 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
238 OP_PCL_IPSEC_HMAC_SHA2_384_192
: OP_ALG_ALGSEL_SHA384
;
239 alginfo_a
->algmode
= OP_ALG_AAI_HMAC
;
241 case RTE_CRYPTO_AUTH_SHA512_HMAC
:
243 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
244 OP_PCL_IPSEC_HMAC_SHA2_512_256
: OP_ALG_ALGSEL_SHA512
;
245 alginfo_a
->algmode
= OP_ALG_AAI_HMAC
;
248 CAAM_JR_DEBUG("unsupported auth alg %u", ses
->auth_alg
);
253 caam_cipher_alg(struct caam_jr_session
*ses
, struct alginfo
*alginfo_c
)
255 switch (ses
->cipher_alg
) {
256 case RTE_CRYPTO_CIPHER_NULL
:
258 case RTE_CRYPTO_CIPHER_AES_CBC
:
260 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
261 OP_PCL_IPSEC_AES_CBC
: OP_ALG_ALGSEL_AES
;
262 alginfo_c
->algmode
= OP_ALG_AAI_CBC
;
264 case RTE_CRYPTO_CIPHER_3DES_CBC
:
266 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
267 OP_PCL_IPSEC_3DES
: OP_ALG_ALGSEL_3DES
;
268 alginfo_c
->algmode
= OP_ALG_AAI_CBC
;
270 case RTE_CRYPTO_CIPHER_AES_CTR
:
272 (ses
->proto_alg
== RTE_SECURITY_PROTOCOL_IPSEC
) ?
273 OP_PCL_IPSEC_AES_CTR
: OP_ALG_ALGSEL_AES
;
274 alginfo_c
->algmode
= OP_ALG_AAI_CTR
;
277 CAAM_JR_DEBUG("unsupported cipher alg %d", ses
->cipher_alg
);
282 caam_aead_alg(struct caam_jr_session
*ses
, struct alginfo
*alginfo
)
284 switch (ses
->aead_alg
) {
285 case RTE_CRYPTO_AEAD_AES_GCM
:
286 alginfo
->algtype
= OP_ALG_ALGSEL_AES
;
287 alginfo
->algmode
= OP_ALG_AAI_GCM
;
290 CAAM_JR_DEBUG("unsupported AEAD alg %d", ses
->aead_alg
);
294 /* prepare command block of the session */
296 caam_jr_prep_cdb(struct caam_jr_session
*ses
)
298 struct alginfo alginfo_c
= {0}, alginfo_a
= {0}, alginfo
= {0};
299 int32_t shared_desc_len
= 0;
302 #if CAAM_BYTE_ORDER == CORE_BYTE_ORDER
309 caam_jr_dma_free(ses
->cdb
);
311 cdb
= caam_jr_dma_mem_alloc(L1_CACHE_BYTES
, sizeof(struct sec_cdb
));
313 CAAM_JR_ERR("failed to allocate memory for cdb\n");
319 memset(cdb
, 0, sizeof(struct sec_cdb
));
321 if (is_cipher_only(ses
)) {
322 caam_cipher_alg(ses
, &alginfo_c
);
323 if (alginfo_c
.algtype
== (unsigned int)CAAM_JR_ALG_UNSUPPORT
) {
324 CAAM_JR_ERR("not supported cipher alg");
329 alginfo_c
.key
= (size_t)ses
->cipher_key
.data
;
330 alginfo_c
.keylen
= ses
->cipher_key
.length
;
331 alginfo_c
.key_enc_flags
= 0;
332 alginfo_c
.key_type
= RTA_DATA_IMM
;
334 shared_desc_len
= cnstr_shdsc_blkcipher(
336 swap
, SHR_NEVER
, &alginfo_c
,
339 } else if (is_auth_only(ses
)) {
340 caam_auth_alg(ses
, &alginfo_a
);
341 if (alginfo_a
.algtype
== (unsigned int)CAAM_JR_ALG_UNSUPPORT
) {
342 CAAM_JR_ERR("not supported auth alg");
347 alginfo_a
.key
= (size_t)ses
->auth_key
.data
;
348 alginfo_a
.keylen
= ses
->auth_key
.length
;
349 alginfo_a
.key_enc_flags
= 0;
350 alginfo_a
.key_type
= RTA_DATA_IMM
;
352 shared_desc_len
= cnstr_shdsc_hmac(cdb
->sh_desc
, true,
353 swap
, SHR_NEVER
, &alginfo_a
,
356 } else if (is_aead(ses
)) {
357 caam_aead_alg(ses
, &alginfo
);
358 if (alginfo
.algtype
== (unsigned int)CAAM_JR_ALG_UNSUPPORT
) {
359 CAAM_JR_ERR("not supported aead alg");
363 alginfo
.key
= (size_t)ses
->aead_key
.data
;
364 alginfo
.keylen
= ses
->aead_key
.length
;
365 alginfo
.key_enc_flags
= 0;
366 alginfo
.key_type
= RTA_DATA_IMM
;
368 if (ses
->dir
== DIR_ENC
)
369 shared_desc_len
= cnstr_shdsc_gcm_encap(
370 cdb
->sh_desc
, true, swap
,
375 shared_desc_len
= cnstr_shdsc_gcm_decap(
376 cdb
->sh_desc
, true, swap
,
381 caam_cipher_alg(ses
, &alginfo_c
);
382 if (alginfo_c
.algtype
== (unsigned int)CAAM_JR_ALG_UNSUPPORT
) {
383 CAAM_JR_ERR("not supported cipher alg");
388 alginfo_c
.key
= (size_t)ses
->cipher_key
.data
;
389 alginfo_c
.keylen
= ses
->cipher_key
.length
;
390 alginfo_c
.key_enc_flags
= 0;
391 alginfo_c
.key_type
= RTA_DATA_IMM
;
393 caam_auth_alg(ses
, &alginfo_a
);
394 if (alginfo_a
.algtype
== (unsigned int)CAAM_JR_ALG_UNSUPPORT
) {
395 CAAM_JR_ERR("not supported auth alg");
400 alginfo_a
.key
= (size_t)ses
->auth_key
.data
;
401 alginfo_a
.keylen
= ses
->auth_key
.length
;
402 alginfo_a
.key_enc_flags
= 0;
403 alginfo_a
.key_type
= RTA_DATA_IMM
;
405 cdb
->sh_desc
[0] = alginfo_c
.keylen
;
406 cdb
->sh_desc
[1] = alginfo_a
.keylen
;
407 err
= rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN
,
409 (unsigned int *)cdb
->sh_desc
,
410 &cdb
->sh_desc
[2], 2);
413 CAAM_JR_ERR("Crypto: Incorrect key lengths");
417 if (cdb
->sh_desc
[2] & 1)
418 alginfo_c
.key_type
= RTA_DATA_IMM
;
420 alginfo_c
.key
= (size_t)caam_jr_mem_vtop(
421 (void *)(size_t)alginfo_c
.key
);
422 alginfo_c
.key_type
= RTA_DATA_PTR
;
424 if (cdb
->sh_desc
[2] & (1<<1))
425 alginfo_a
.key_type
= RTA_DATA_IMM
;
427 alginfo_a
.key
= (size_t)caam_jr_mem_vtop(
428 (void *)(size_t)alginfo_a
.key
);
429 alginfo_a
.key_type
= RTA_DATA_PTR
;
434 if (is_proto_ipsec(ses
)) {
435 if (ses
->dir
== DIR_ENC
) {
436 shared_desc_len
= cnstr_shdsc_ipsec_new_encap(
438 true, swap
, SHR_SERIAL
,
440 (uint8_t *)&ses
->ip4_hdr
,
441 &alginfo_c
, &alginfo_a
);
442 } else if (ses
->dir
== DIR_DEC
) {
443 shared_desc_len
= cnstr_shdsc_ipsec_new_decap(
445 true, swap
, SHR_SERIAL
,
447 &alginfo_c
, &alginfo_a
);
450 /* Auth_only_len is overwritten in fd for each job */
451 shared_desc_len
= cnstr_shdsc_authenc(cdb
->sh_desc
,
452 true, swap
, SHR_SERIAL
,
453 &alginfo_c
, &alginfo_a
,
455 ses
->digest_length
, ses
->dir
);
459 if (shared_desc_len
< 0) {
460 CAAM_JR_ERR("error in preparing command block");
461 return shared_desc_len
;
465 SEC_DUMP_DESC(cdb
->sh_desc
);
468 cdb
->sh_hdr
.hi
.field
.idlen
= shared_desc_len
;
473 /* @brief Poll the HW for already processed jobs in the JR
474 * and silently discard the available jobs or notify them to UA
475 * with indicated error code.
477 * @param [in,out] job_ring The job ring to poll.
478 * @param [in] do_notify Can be #TRUE or #FALSE. Indicates if
479 * descriptors are to be discarded
480 * or notified to UA with given error_code.
481 * @param [out] notified_descs Number of notified descriptors. Can be NULL
482 * if do_notify is #FALSE
485 hw_flush_job_ring(struct sec_job_ring_t
*job_ring
,
487 uint32_t *notified_descs
)
489 int32_t jobs_no_to_discard
= 0;
490 int32_t discarded_descs_no
= 0;
492 CAAM_JR_DEBUG("Jr[%p] pi[%d] ci[%d].Flushing jr notify desc=[%d]",
493 job_ring
, job_ring
->pidx
, job_ring
->cidx
, do_notify
);
495 jobs_no_to_discard
= hw_get_no_finished_jobs(job_ring
);
497 /* Discard all jobs */
498 CAAM_JR_DEBUG("Jr[%p] pi[%d] ci[%d].Discarding %d descs",
499 job_ring
, job_ring
->pidx
, job_ring
->cidx
,
502 while (jobs_no_to_discard
> discarded_descs_no
) {
503 discarded_descs_no
++;
504 /* Now increment the consumer index for the current job ring,
505 * AFTER saving job in temporary location!
506 * Increment the consumer index for the current job ring
508 job_ring
->cidx
= SEC_CIRCULAR_COUNTER(job_ring
->cidx
,
511 hw_remove_entries(job_ring
, 1);
514 if (do_notify
== true) {
515 ASSERT(notified_descs
!= NULL
);
516 *notified_descs
= discarded_descs_no
;
520 /* @brief Poll the HW for already processed jobs in the JR
521 * and notify the available jobs to UA.
523 * @param [in] job_ring The job ring to poll.
524 * @param [in] limit The maximum number of jobs to notify.
525 * If set to negative value, all available jobs are
528 * @retval >=0 for No of jobs notified to UA.
529 * @retval -1 for error
532 hw_poll_job_ring(struct sec_job_ring_t
*job_ring
,
533 struct rte_crypto_op
**ops
, int32_t limit
,
534 struct caam_jr_qp
*jr_qp
)
536 int32_t jobs_no_to_notify
= 0; /* the number of done jobs to notify*/
537 int32_t number_of_jobs_available
= 0;
538 int32_t notified_descs_no
= 0;
539 uint32_t sec_error_code
= 0;
540 struct job_descriptor
*current_desc
;
541 phys_addr_t current_desc_addr
;
542 phys_addr_t
*temp_addr
;
543 struct caam_jr_op_ctx
*ctx
;
545 /* TODO check for ops have memory*/
546 /* check here if any JR error that cannot be written
547 * in the output status word has occurred
549 if (JR_REG_JRINT_JRE_EXTRACT(GET_JR_REG(JRINT
, job_ring
))) {
550 CAAM_JR_INFO("err received");
551 sec_error_code
= JR_REG_JRINT_ERR_TYPE_EXTRACT(
552 GET_JR_REG(JRINT
, job_ring
));
553 if (unlikely(sec_error_code
)) {
554 hw_job_ring_error_print(job_ring
, sec_error_code
);
558 /* compute the number of jobs available in the job ring based on the
559 * producer and consumer index values.
561 number_of_jobs_available
= hw_get_no_finished_jobs(job_ring
);
562 /* Compute the number of notifications that need to be raised to UA
563 * If limit > total number of done jobs -> notify all done jobs
564 * If limit = 0 -> error
565 * If limit < total number of done jobs -> notify a number
566 * of done jobs equal with limit
568 jobs_no_to_notify
= (limit
> number_of_jobs_available
) ?
569 number_of_jobs_available
: limit
;
571 "Jr[%p] pi[%d] ci[%d].limit =%d Available=%d.Jobs to notify=%d",
572 job_ring
, job_ring
->pidx
, job_ring
->cidx
,
573 limit
, number_of_jobs_available
, jobs_no_to_notify
);
577 while (jobs_no_to_notify
> notified_descs_no
) {
578 static uint64_t false_alarm
;
579 static uint64_t real_poll
;
581 /* Get job status here */
582 sec_error_code
= job_ring
->output_ring
[job_ring
->cidx
].status
;
583 /* Get completed descriptor */
584 temp_addr
= &(job_ring
->output_ring
[job_ring
->cidx
].desc
);
585 current_desc_addr
= (phys_addr_t
)sec_read_addr(temp_addr
);
588 /* todo check if it is false alarm no desc present */
589 if (!current_desc_addr
) {
591 printf("false alarm %" PRIu64
"real %" PRIu64
592 " sec_err =0x%x cidx Index =0%d\n",
593 false_alarm
, real_poll
,
594 sec_error_code
, job_ring
->cidx
);
595 rte_panic("CAAM JR descriptor NULL");
596 return notified_descs_no
;
598 current_desc
= (struct job_descriptor
*)
599 caam_jr_dma_ptov(current_desc_addr
);
600 /* now increment the consumer index for the current job ring,
601 * AFTER saving job in temporary location!
603 job_ring
->cidx
= SEC_CIRCULAR_COUNTER(job_ring
->cidx
,
605 /* Signal that the job has been processed and the slot is free*/
606 hw_remove_entries(job_ring
, 1);
607 /*TODO for multiple ops, packets*/
608 ctx
= container_of(current_desc
, struct caam_jr_op_ctx
, jobdes
);
609 if (unlikely(sec_error_code
)) {
610 CAAM_JR_ERR("desc at cidx %d generated error 0x%x\n",
611 job_ring
->cidx
, sec_error_code
);
612 hw_handle_job_ring_error(job_ring
, sec_error_code
);
613 //todo improve with exact errors
614 ctx
->op
->status
= RTE_CRYPTO_OP_STATUS_ERROR
;
617 ctx
->op
->status
= RTE_CRYPTO_OP_STATUS_SUCCESS
;
619 if (ctx
->op
->sym
->m_dst
) {
620 rte_hexdump(stdout
, "PROCESSED",
621 rte_pktmbuf_mtod(ctx
->op
->sym
->m_dst
, void *),
622 rte_pktmbuf_data_len(ctx
->op
->sym
->m_dst
));
624 rte_hexdump(stdout
, "PROCESSED",
625 rte_pktmbuf_mtod(ctx
->op
->sym
->m_src
, void *),
626 rte_pktmbuf_data_len(ctx
->op
->sym
->m_src
));
630 if (ctx
->op
->sess_type
== RTE_CRYPTO_OP_SECURITY_SESSION
) {
633 if (ctx
->op
->sym
->m_dst
) {
634 /*TODO check for ip header or other*/
635 ip4_hdr
= (struct ip
*)
636 rte_pktmbuf_mtod(ctx
->op
->sym
->m_dst
, char*);
637 ctx
->op
->sym
->m_dst
->pkt_len
=
638 rte_be_to_cpu_16(ip4_hdr
->ip_len
);
639 ctx
->op
->sym
->m_dst
->data_len
=
640 rte_be_to_cpu_16(ip4_hdr
->ip_len
);
642 ip4_hdr
= (struct ip
*)
643 rte_pktmbuf_mtod(ctx
->op
->sym
->m_src
, char*);
644 ctx
->op
->sym
->m_src
->pkt_len
=
645 rte_be_to_cpu_16(ip4_hdr
->ip_len
);
646 ctx
->op
->sym
->m_src
->data_len
=
647 rte_be_to_cpu_16(ip4_hdr
->ip_len
);
651 caam_jr_op_ending(ctx
);
655 return notified_descs_no
;
659 caam_jr_dequeue_burst(void *qp
, struct rte_crypto_op
**ops
,
662 struct caam_jr_qp
*jr_qp
= (struct caam_jr_qp
*)qp
;
663 struct sec_job_ring_t
*ring
= jr_qp
->ring
;
667 CAAM_JR_DP_DEBUG("Jr[%p]Polling. limit[%d]", ring
, nb_ops
);
670 * If nb_ops < 0 -> poll JR until no more notifications are available.
671 * If nb_ops > 0 -> poll JR until limit is reached.
674 /* Run hw poll job ring */
675 num_rx
= hw_poll_job_ring(ring
, ops
, nb_ops
, jr_qp
);
677 CAAM_JR_ERR("Error polling SEC engine (%d)", num_rx
);
681 CAAM_JR_DP_DEBUG("Jr[%p].Jobs notified[%d]. ", ring
, num_rx
);
683 if (ring
->jr_mode
== SEC_NOTIFICATION_TYPE_NAPI
) {
684 if (num_rx
< nb_ops
) {
685 ret
= caam_jr_enable_irqs(ring
->irq_fd
);
686 SEC_ASSERT(ret
== 0, ret
,
687 "Failed to enable irqs for job ring %p", ring
);
689 } else if (ring
->jr_mode
== SEC_NOTIFICATION_TYPE_IRQ
) {
691 /* Always enable IRQ generation when in pure IRQ mode */
692 ret
= caam_jr_enable_irqs(ring
->irq_fd
);
693 SEC_ASSERT(ret
== 0, ret
,
694 "Failed to enable irqs for job ring %p", ring
);
697 jr_qp
->rx_pkts
+= num_rx
;
704 * |<----data_len------->|
705 * |ip_header|ah_header|icv|payload|
710 static inline struct caam_jr_op_ctx
*
711 build_auth_only_sg(struct rte_crypto_op
*op
, struct caam_jr_session
*ses
)
713 struct rte_crypto_sym_op
*sym
= op
->sym
;
714 struct rte_mbuf
*mbuf
= sym
->m_src
;
715 struct caam_jr_op_ctx
*ctx
;
716 struct sec4_sg_entry
*sg
;
719 uint64_t sdesc_offset
;
720 struct sec_job_descriptor_t
*jobdescr
;
728 if ((mbuf
->nb_segs
+ extra_segs
) > MAX_SG_ENTRIES
) {
729 CAAM_JR_DP_ERR("Auth: Max sec segs supported is %d",
734 ctx
= caam_jr_alloc_ctx(ses
);
741 sdesc_offset
= (size_t) ((char *)&cdb
->sh_desc
- (char *)cdb
);
743 jobdescr
= (struct sec_job_descriptor_t
*) ctx
->jobdes
.desc
;
745 SEC_JD_INIT(jobdescr
);
746 SEC_JD_SET_SD(jobdescr
,
747 (phys_addr_t
)(caam_jr_dma_vtop(cdb
)) + sdesc_offset
,
748 cdb
->sh_hdr
.hi
.field
.idlen
);
751 SEC_JD_SET_OUT_PTR(jobdescr
, (uint64_t)sym
->auth
.digest
.phys_addr
,
752 0, ses
->digest_length
);
756 length
= sym
->auth
.data
.length
;
757 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
) + sym
->auth
.data
.offset
);
758 sg
->len
= cpu_to_caam32(mbuf
->data_len
- sym
->auth
.data
.offset
);
760 /* Successive segs */
764 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
));
765 sg
->len
= cpu_to_caam32(mbuf
->data_len
);
769 if (is_decode(ses
)) {
770 /* digest verification case */
772 /* hash result or digest, save digest first */
773 rte_memcpy(ctx
->digest
, sym
->auth
.digest
.data
,
776 rte_hexdump(stdout
, "ICV", ctx
->digest
, ses
->digest_length
);
778 sg
->ptr
= cpu_to_caam64(caam_jr_vtop_ctx(ctx
, ctx
->digest
));
779 sg
->len
= cpu_to_caam32(ses
->digest_length
);
780 length
+= ses
->digest_length
;
782 sg
->len
-= ses
->digest_length
;
786 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
788 SEC_JD_SET_IN_PTR(jobdescr
,
789 (uint64_t)caam_jr_vtop_ctx(ctx
, &ctx
->sg
[0]), 0, length
);
790 /* enabling sg list */
791 (jobdescr
)->seq_in
.command
.word
|= 0x01000000;
796 static inline struct caam_jr_op_ctx
*
797 build_auth_only(struct rte_crypto_op
*op
, struct caam_jr_session
*ses
)
799 struct rte_crypto_sym_op
*sym
= op
->sym
;
800 struct caam_jr_op_ctx
*ctx
;
801 struct sec4_sg_entry
*sg
;
802 rte_iova_t start_addr
;
804 uint64_t sdesc_offset
;
805 struct sec_job_descriptor_t
*jobdescr
;
807 ctx
= caam_jr_alloc_ctx(ses
);
814 sdesc_offset
= (size_t) ((char *)&cdb
->sh_desc
- (char *)cdb
);
816 start_addr
= rte_pktmbuf_iova(sym
->m_src
);
818 jobdescr
= (struct sec_job_descriptor_t
*) ctx
->jobdes
.desc
;
820 SEC_JD_INIT(jobdescr
);
821 SEC_JD_SET_SD(jobdescr
,
822 (phys_addr_t
)(caam_jr_dma_vtop(cdb
)) + sdesc_offset
,
823 cdb
->sh_hdr
.hi
.field
.idlen
);
826 SEC_JD_SET_OUT_PTR(jobdescr
, (uint64_t)sym
->auth
.digest
.phys_addr
,
827 0, ses
->digest_length
);
830 if (is_decode(ses
)) {
832 SEC_JD_SET_IN_PTR(jobdescr
,
833 (uint64_t)caam_jr_vtop_ctx(ctx
, sg
), 0,
834 (sym
->auth
.data
.length
+ ses
->digest_length
));
835 /* enabling sg list */
836 (jobdescr
)->seq_in
.command
.word
|= 0x01000000;
838 /* hash result or digest, save digest first */
839 rte_memcpy(ctx
->digest
, sym
->auth
.digest
.data
,
841 sg
->ptr
= cpu_to_caam64(start_addr
+ sym
->auth
.data
.offset
);
842 sg
->len
= cpu_to_caam32(sym
->auth
.data
.length
);
845 rte_hexdump(stdout
, "ICV", ctx
->digest
, ses
->digest_length
);
847 /* let's check digest by hw */
849 sg
->ptr
= cpu_to_caam64(caam_jr_vtop_ctx(ctx
, ctx
->digest
));
850 sg
->len
= cpu_to_caam32(ses
->digest_length
);
852 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
854 SEC_JD_SET_IN_PTR(jobdescr
, (uint64_t)start_addr
,
855 sym
->auth
.data
.offset
, sym
->auth
.data
.length
);
860 static inline struct caam_jr_op_ctx
*
861 build_cipher_only_sg(struct rte_crypto_op
*op
, struct caam_jr_session
*ses
)
863 struct rte_crypto_sym_op
*sym
= op
->sym
;
864 struct rte_mbuf
*mbuf
= sym
->m_src
;
865 struct caam_jr_op_ctx
*ctx
;
866 struct sec4_sg_entry
*sg
, *in_sg
;
869 uint64_t sdesc_offset
;
870 uint8_t *IV_ptr
= rte_crypto_op_ctod_offset(op
, uint8_t *,
872 struct sec_job_descriptor_t
*jobdescr
;
877 reg_segs
= mbuf
->nb_segs
+ sym
->m_src
->nb_segs
+ 2;
880 reg_segs
= mbuf
->nb_segs
* 2 + 2;
883 if (reg_segs
> MAX_SG_ENTRIES
) {
884 CAAM_JR_DP_ERR("Cipher: Max sec segs supported is %d",
889 ctx
= caam_jr_alloc_ctx(ses
);
895 sdesc_offset
= (size_t) ((char *)&cdb
->sh_desc
- (char *)cdb
);
897 jobdescr
= (struct sec_job_descriptor_t
*) ctx
->jobdes
.desc
;
899 SEC_JD_INIT(jobdescr
);
900 SEC_JD_SET_SD(jobdescr
,
901 (phys_addr_t
)(caam_jr_dma_vtop(cdb
)) + sdesc_offset
,
902 cdb
->sh_hdr
.hi
.field
.idlen
);
905 CAAM_JR_INFO("mbuf offset =%d, cipher offset = %d, length =%d+%d",
906 sym
->m_src
->data_off
, sym
->cipher
.data
.offset
,
907 sym
->cipher
.data
.length
, ses
->iv
.length
);
916 length
= sym
->cipher
.data
.length
;
918 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
)
919 + sym
->cipher
.data
.offset
);
920 sg
->len
= cpu_to_caam32(mbuf
->data_len
- sym
->cipher
.data
.offset
);
922 /* Successive segs */
926 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
));
927 sg
->len
= cpu_to_caam32(mbuf
->data_len
);
931 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
933 SEC_JD_SET_OUT_PTR(jobdescr
,
934 (uint64_t)caam_jr_vtop_ctx(ctx
, &ctx
->sg
[0]), 0,
937 (jobdescr
)->seq_out
.command
.word
|= 0x01000000;
944 length
= sym
->cipher
.data
.length
+ ses
->iv
.length
;
947 sg
->ptr
= cpu_to_caam64(caam_jr_dma_vtop(IV_ptr
));
948 sg
->len
= cpu_to_caam32(ses
->iv
.length
);
952 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
)
953 + sym
->cipher
.data
.offset
);
954 sg
->len
= cpu_to_caam32(mbuf
->data_len
- sym
->cipher
.data
.offset
);
956 /* Successive segs */
960 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
));
961 sg
->len
= cpu_to_caam32(mbuf
->data_len
);
965 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
968 SEC_JD_SET_IN_PTR(jobdescr
, (uint64_t)caam_jr_vtop_ctx(ctx
, in_sg
), 0,
971 (jobdescr
)->seq_in
.command
.word
|= 0x01000000;
976 static inline struct caam_jr_op_ctx
*
977 build_cipher_only(struct rte_crypto_op
*op
, struct caam_jr_session
*ses
)
979 struct rte_crypto_sym_op
*sym
= op
->sym
;
980 struct caam_jr_op_ctx
*ctx
;
981 struct sec4_sg_entry
*sg
;
982 rte_iova_t src_start_addr
, dst_start_addr
;
984 uint64_t sdesc_offset
;
985 uint8_t *IV_ptr
= rte_crypto_op_ctod_offset(op
, uint8_t *,
987 struct sec_job_descriptor_t
*jobdescr
;
989 ctx
= caam_jr_alloc_ctx(ses
);
995 sdesc_offset
= (size_t) ((char *)&cdb
->sh_desc
- (char *)cdb
);
997 src_start_addr
= rte_pktmbuf_iova(sym
->m_src
);
999 dst_start_addr
= rte_pktmbuf_iova(sym
->m_dst
);
1001 dst_start_addr
= src_start_addr
;
1003 jobdescr
= (struct sec_job_descriptor_t
*) ctx
->jobdes
.desc
;
1005 SEC_JD_INIT(jobdescr
);
1006 SEC_JD_SET_SD(jobdescr
,
1007 (phys_addr_t
)(caam_jr_dma_vtop(cdb
)) + sdesc_offset
,
1008 cdb
->sh_hdr
.hi
.field
.idlen
);
1011 CAAM_JR_INFO("mbuf offset =%d, cipher offset = %d, length =%d+%d",
1012 sym
->m_src
->data_off
, sym
->cipher
.data
.offset
,
1013 sym
->cipher
.data
.length
, ses
->iv
.length
);
1016 SEC_JD_SET_OUT_PTR(jobdescr
, (uint64_t)dst_start_addr
,
1017 sym
->cipher
.data
.offset
,
1018 sym
->cipher
.data
.length
+ ses
->iv
.length
);
1022 SEC_JD_SET_IN_PTR(jobdescr
, (uint64_t)caam_jr_vtop_ctx(ctx
, sg
), 0,
1023 sym
->cipher
.data
.length
+ ses
->iv
.length
);
1024 /*enabling sg bit */
1025 (jobdescr
)->seq_in
.command
.word
|= 0x01000000;
1027 sg
->ptr
= cpu_to_caam64(caam_jr_dma_vtop(IV_ptr
));
1028 sg
->len
= cpu_to_caam32(ses
->iv
.length
);
1031 sg
->ptr
= cpu_to_caam64(src_start_addr
+ sym
->cipher
.data
.offset
);
1032 sg
->len
= cpu_to_caam32(sym
->cipher
.data
.length
);
1034 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
1039 /* For decapsulation:
1041 * +----+----------------+--------------------------------+-----+
1042 * | IV | Auth-only data | Authenticated & Encrypted data | ICV |
1043 * +----+----------------+--------------------------------+-----+
1045 * +----+--------------------------+
1046 * | Decrypted & authenticated data |
1047 * +----+--------------------------+
1050 static inline struct caam_jr_op_ctx
*
1051 build_cipher_auth_sg(struct rte_crypto_op
*op
, struct caam_jr_session
*ses
)
1053 struct rte_crypto_sym_op
*sym
= op
->sym
;
1054 struct caam_jr_op_ctx
*ctx
;
1055 struct sec4_sg_entry
*sg
, *out_sg
, *in_sg
;
1056 struct rte_mbuf
*mbuf
;
1057 uint32_t length
= 0;
1058 struct sec_cdb
*cdb
;
1059 uint64_t sdesc_offset
;
1061 uint8_t *IV_ptr
= rte_crypto_op_ctod_offset(op
, uint8_t *,
1063 struct sec_job_descriptor_t
*jobdescr
;
1064 uint16_t auth_hdr_len
= sym
->cipher
.data
.offset
-
1065 sym
->auth
.data
.offset
;
1066 uint16_t auth_tail_len
= sym
->auth
.data
.length
-
1067 sym
->cipher
.data
.length
- auth_hdr_len
;
1068 uint32_t auth_only_len
= (auth_tail_len
<< 16) | auth_hdr_len
;
1072 req_segs
= mbuf
->nb_segs
+ sym
->m_src
->nb_segs
+ 3;
1075 req_segs
= mbuf
->nb_segs
* 2 + 3;
1078 if (req_segs
> MAX_SG_ENTRIES
) {
1079 CAAM_JR_DP_ERR("Cipher-Auth: Max sec segs supported is %d",
1084 ctx
= caam_jr_alloc_ctx(ses
);
1090 sdesc_offset
= (size_t) ((char *)&cdb
->sh_desc
- (char *)cdb
);
1092 jobdescr
= (struct sec_job_descriptor_t
*) ctx
->jobdes
.desc
;
1094 SEC_JD_INIT(jobdescr
);
1095 SEC_JD_SET_SD(jobdescr
,
1096 (phys_addr_t
)(caam_jr_dma_vtop(cdb
)) + sdesc_offset
,
1097 cdb
->sh_hdr
.hi
.field
.idlen
);
1105 out_sg
= &ctx
->sg
[0];
1107 length
= sym
->auth
.data
.length
+ ses
->digest_length
;
1109 length
= sym
->auth
.data
.length
;
1114 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
)
1115 + sym
->auth
.data
.offset
);
1116 sg
->len
= cpu_to_caam32(mbuf
->data_len
- sym
->auth
.data
.offset
);
1118 /* Successive segs */
1122 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
));
1123 sg
->len
= cpu_to_caam32(mbuf
->data_len
);
1127 if (is_encode(ses
)) {
1128 /* set auth output */
1130 sg
->ptr
= cpu_to_caam64(sym
->auth
.digest
.phys_addr
);
1131 sg
->len
= cpu_to_caam32(ses
->digest_length
);
1134 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
1136 SEC_JD_SET_OUT_PTR(jobdescr
,
1137 (uint64_t)caam_jr_dma_vtop(out_sg
), 0, length
);
1139 (jobdescr
)->seq_out
.command
.word
|= 0x01000000;
1146 length
= ses
->iv
.length
+ sym
->auth
.data
.length
;
1148 length
= ses
->iv
.length
+ sym
->auth
.data
.length
1149 + ses
->digest_length
;
1151 sg
->ptr
= cpu_to_caam64(caam_jr_dma_vtop(IV_ptr
));
1152 sg
->len
= cpu_to_caam32(ses
->iv
.length
);
1156 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
)
1157 + sym
->auth
.data
.offset
);
1158 sg
->len
= cpu_to_caam32(mbuf
->data_len
- sym
->auth
.data
.offset
);
1160 /* Successive segs */
1164 sg
->ptr
= cpu_to_caam64(rte_pktmbuf_iova(mbuf
));
1165 sg
->len
= cpu_to_caam32(mbuf
->data_len
);
1169 if (is_decode(ses
)) {
1171 rte_memcpy(ctx
->digest
, sym
->auth
.digest
.data
,
1172 ses
->digest_length
);
1173 sg
->ptr
= cpu_to_caam64(caam_jr_dma_vtop(ctx
->digest
));
1174 sg
->len
= cpu_to_caam32(ses
->digest_length
);
1177 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
1179 SEC_JD_SET_IN_PTR(jobdescr
, (uint64_t)caam_jr_dma_vtop(in_sg
), 0,
1182 (jobdescr
)->seq_in
.command
.word
|= 0x01000000;
1183 /* Auth_only_len is set as 0 in descriptor and it is
1184 * overwritten here in the jd which will update
1189 (jobdescr
)->dpovrd
= 0x80000000 | auth_only_len
;
1194 static inline struct caam_jr_op_ctx
*
1195 build_cipher_auth(struct rte_crypto_op
*op
, struct caam_jr_session
*ses
)
1197 struct rte_crypto_sym_op
*sym
= op
->sym
;
1198 struct caam_jr_op_ctx
*ctx
;
1199 struct sec4_sg_entry
*sg
;
1200 rte_iova_t src_start_addr
, dst_start_addr
;
1201 uint32_t length
= 0;
1202 struct sec_cdb
*cdb
;
1203 uint64_t sdesc_offset
;
1204 uint8_t *IV_ptr
= rte_crypto_op_ctod_offset(op
, uint8_t *,
1206 struct sec_job_descriptor_t
*jobdescr
;
1207 uint16_t auth_hdr_len
= sym
->cipher
.data
.offset
-
1208 sym
->auth
.data
.offset
;
1209 uint16_t auth_tail_len
= sym
->auth
.data
.length
-
1210 sym
->cipher
.data
.length
- auth_hdr_len
;
1211 uint32_t auth_only_len
= (auth_tail_len
<< 16) | auth_hdr_len
;
1213 src_start_addr
= rte_pktmbuf_iova(sym
->m_src
);
1215 dst_start_addr
= rte_pktmbuf_iova(sym
->m_dst
);
1217 dst_start_addr
= src_start_addr
;
1219 ctx
= caam_jr_alloc_ctx(ses
);
1225 sdesc_offset
= (size_t) ((char *)&cdb
->sh_desc
- (char *)cdb
);
1227 jobdescr
= (struct sec_job_descriptor_t
*) ctx
->jobdes
.desc
;
1229 SEC_JD_INIT(jobdescr
);
1230 SEC_JD_SET_SD(jobdescr
,
1231 (phys_addr_t
)(caam_jr_dma_vtop(cdb
)) + sdesc_offset
,
1232 cdb
->sh_hdr
.hi
.field
.idlen
);
1236 if (is_encode(ses
)) {
1237 sg
->ptr
= cpu_to_caam64(caam_jr_dma_vtop(IV_ptr
));
1238 sg
->len
= cpu_to_caam32(ses
->iv
.length
);
1239 length
+= ses
->iv
.length
;
1242 sg
->ptr
= cpu_to_caam64(src_start_addr
+ sym
->auth
.data
.offset
);
1243 sg
->len
= cpu_to_caam32(sym
->auth
.data
.length
);
1244 length
+= sym
->auth
.data
.length
;
1246 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
1248 sg
->ptr
= cpu_to_caam64(caam_jr_dma_vtop(IV_ptr
));
1249 sg
->len
= cpu_to_caam32(ses
->iv
.length
);
1250 length
+= ses
->iv
.length
;
1253 sg
->ptr
= cpu_to_caam64(src_start_addr
+ sym
->auth
.data
.offset
);
1254 sg
->len
= cpu_to_caam32(sym
->auth
.data
.length
);
1255 length
+= sym
->auth
.data
.length
;
1257 rte_memcpy(ctx
->digest
, sym
->auth
.digest
.data
,
1258 ses
->digest_length
);
1260 sg
->ptr
= cpu_to_caam64(caam_jr_dma_vtop(ctx
->digest
));
1261 sg
->len
= cpu_to_caam32(ses
->digest_length
);
1262 length
+= ses
->digest_length
;
1264 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
1267 SEC_JD_SET_IN_PTR(jobdescr
, (uint64_t)caam_jr_dma_vtop(&ctx
->sg
[0]), 0,
1270 (jobdescr
)->seq_in
.command
.word
|= 0x01000000;
1275 sg
->ptr
= cpu_to_caam64(dst_start_addr
+ sym
->cipher
.data
.offset
);
1276 sg
->len
= cpu_to_caam32(sym
->cipher
.data
.length
);
1277 length
= sym
->cipher
.data
.length
;
1279 if (is_encode(ses
)) {
1280 /* set auth output */
1282 sg
->ptr
= cpu_to_caam64(sym
->auth
.digest
.phys_addr
);
1283 sg
->len
= cpu_to_caam32(ses
->digest_length
);
1284 length
+= ses
->digest_length
;
1287 sg
->len
|= cpu_to_caam32(SEC4_SG_LEN_FIN
);
1289 SEC_JD_SET_OUT_PTR(jobdescr
,
1290 (uint64_t)caam_jr_dma_vtop(&ctx
->sg
[6]), 0, length
);
1292 (jobdescr
)->seq_out
.command
.word
|= 0x01000000;
1294 /* Auth_only_len is set as 0 in descriptor and it is
1295 * overwritten here in the jd which will update
1300 (jobdescr
)->dpovrd
= 0x80000000 | auth_only_len
;
1305 static inline struct caam_jr_op_ctx
*
1306 build_proto(struct rte_crypto_op
*op
, struct caam_jr_session
*ses
)
1308 struct rte_crypto_sym_op
*sym
= op
->sym
;
1309 struct caam_jr_op_ctx
*ctx
= NULL
;
1310 phys_addr_t src_start_addr
, dst_start_addr
;
1311 struct sec_cdb
*cdb
;
1312 uint64_t sdesc_offset
;
1313 struct sec_job_descriptor_t
*jobdescr
;
1315 ctx
= caam_jr_alloc_ctx(ses
);
1320 src_start_addr
= rte_pktmbuf_iova(sym
->m_src
);
1322 dst_start_addr
= rte_pktmbuf_iova(sym
->m_dst
);
1324 dst_start_addr
= src_start_addr
;
1327 sdesc_offset
= (size_t) ((char *)&cdb
->sh_desc
- (char *)cdb
);
1329 jobdescr
= (struct sec_job_descriptor_t
*) ctx
->jobdes
.desc
;
1331 SEC_JD_INIT(jobdescr
);
1332 SEC_JD_SET_SD(jobdescr
,
1333 (phys_addr_t
)(caam_jr_dma_vtop(cdb
)) + sdesc_offset
,
1334 cdb
->sh_hdr
.hi
.field
.idlen
);
1337 SEC_JD_SET_OUT_PTR(jobdescr
, (uint64_t)dst_start_addr
, 0,
1338 sym
->m_src
->buf_len
- sym
->m_src
->data_off
);
1340 SEC_JD_SET_IN_PTR(jobdescr
, (uint64_t)src_start_addr
, 0,
1341 sym
->m_src
->pkt_len
);
1342 sym
->m_src
->packet_type
&= ~RTE_PTYPE_L4_MASK
;
1348 caam_jr_enqueue_op(struct rte_crypto_op
*op
, struct caam_jr_qp
*qp
)
1350 struct sec_job_ring_t
*ring
= qp
->ring
;
1351 struct caam_jr_session
*ses
;
1352 struct caam_jr_op_ctx
*ctx
= NULL
;
1353 struct sec_job_descriptor_t
*jobdescr __rte_unused
;
1355 switch (op
->sess_type
) {
1356 case RTE_CRYPTO_OP_WITH_SESSION
:
1357 ses
= (struct caam_jr_session
*)
1358 get_sym_session_private_data(op
->sym
->session
,
1359 cryptodev_driver_id
);
1361 case RTE_CRYPTO_OP_SECURITY_SESSION
:
1362 ses
= (struct caam_jr_session
*)
1363 get_sec_session_private_data(
1364 op
->sym
->sec_session
);
1367 CAAM_JR_DP_ERR("sessionless crypto op not supported");
1372 if (unlikely(!ses
->qp
|| ses
->qp
!= qp
)) {
1373 CAAM_JR_DP_DEBUG("Old:sess->qp=%p New qp = %p\n", ses
->qp
, qp
);
1375 caam_jr_prep_cdb(ses
);
1378 if (rte_pktmbuf_is_contiguous(op
->sym
->m_src
)) {
1379 if (is_auth_cipher(ses
))
1380 ctx
= build_cipher_auth(op
, ses
);
1381 else if (is_aead(ses
))
1383 else if (is_auth_only(ses
))
1384 ctx
= build_auth_only(op
, ses
);
1385 else if (is_cipher_only(ses
))
1386 ctx
= build_cipher_only(op
, ses
);
1387 else if (is_proto_ipsec(ses
))
1388 ctx
= build_proto(op
, ses
);
1390 if (is_auth_cipher(ses
))
1391 ctx
= build_cipher_auth_sg(op
, ses
);
1392 else if (is_aead(ses
))
1394 else if (is_auth_only(ses
))
1395 ctx
= build_auth_only_sg(op
, ses
);
1396 else if (is_cipher_only(ses
))
1397 ctx
= build_cipher_only_sg(op
, ses
);
1400 if (unlikely(!ctx
)) {
1402 CAAM_JR_ERR("not supported sec op");
1407 rte_hexdump(stdout
, "DECODE",
1408 rte_pktmbuf_mtod(op
->sym
->m_src
, void *),
1409 rte_pktmbuf_data_len(op
->sym
->m_src
));
1411 rte_hexdump(stdout
, "ENCODE",
1412 rte_pktmbuf_mtod(op
->sym
->m_src
, void *),
1413 rte_pktmbuf_data_len(op
->sym
->m_src
));
1415 printf("\n JD before conversion\n");
1416 for (int i
= 0; i
< 12; i
++)
1417 printf("\n 0x%08x", ctx
->jobdes
.desc
[i
]);
1420 CAAM_JR_DP_DEBUG("Jr[%p] pi[%d] ci[%d].Before sending desc",
1421 ring
, ring
->pidx
, ring
->cidx
);
1423 /* todo - do we want to retry */
1424 if (SEC_JOB_RING_IS_FULL(ring
->pidx
, ring
->cidx
,
1425 SEC_JOB_RING_SIZE
, SEC_JOB_RING_SIZE
)) {
1426 CAAM_JR_DP_DEBUG("Ring FULL Jr[%p] pi[%d] ci[%d].Size = %d",
1427 ring
, ring
->pidx
, ring
->cidx
, SEC_JOB_RING_SIZE
);
1428 caam_jr_op_ending(ctx
);
1433 #if CORE_BYTE_ORDER != CAAM_BYTE_ORDER
1434 jobdescr
= (struct sec_job_descriptor_t
*) ctx
->jobdes
.desc
;
1436 jobdescr
->deschdr
.command
.word
=
1437 cpu_to_caam32(jobdescr
->deschdr
.command
.word
);
1438 jobdescr
->sd_ptr
= cpu_to_caam64(jobdescr
->sd_ptr
);
1439 jobdescr
->seq_out
.command
.word
=
1440 cpu_to_caam32(jobdescr
->seq_out
.command
.word
);
1441 jobdescr
->seq_out_ptr
= cpu_to_caam64(jobdescr
->seq_out_ptr
);
1442 jobdescr
->out_ext_length
= cpu_to_caam32(jobdescr
->out_ext_length
);
1443 jobdescr
->seq_in
.command
.word
=
1444 cpu_to_caam32(jobdescr
->seq_in
.command
.word
);
1445 jobdescr
->seq_in_ptr
= cpu_to_caam64(jobdescr
->seq_in_ptr
);
1446 jobdescr
->in_ext_length
= cpu_to_caam32(jobdescr
->in_ext_length
);
1447 jobdescr
->load_dpovrd
.command
.word
=
1448 cpu_to_caam32(jobdescr
->load_dpovrd
.command
.word
);
1449 jobdescr
->dpovrd
= cpu_to_caam32(jobdescr
->dpovrd
);
1452 /* Set ptr in input ring to current descriptor */
1453 sec_write_addr(&ring
->input_ring
[ring
->pidx
],
1454 (phys_addr_t
)caam_jr_vtop_ctx(ctx
, ctx
->jobdes
.desc
));
1457 /* Notify HW that a new job is enqueued */
1458 hw_enqueue_desc_on_job_ring(ring
);
1460 /* increment the producer index for the current job ring */
1461 ring
->pidx
= SEC_CIRCULAR_COUNTER(ring
->pidx
, SEC_JOB_RING_SIZE
);
1467 caam_jr_enqueue_burst(void *qp
, struct rte_crypto_op
**ops
,
1470 /* Function to transmit the frames to given device and queuepair */
1473 struct caam_jr_qp
*jr_qp
= (struct caam_jr_qp
*)qp
;
1474 uint16_t num_tx
= 0;
1475 /*Prepare each packet which is to be sent*/
1476 for (loop
= 0; loop
< nb_ops
; loop
++) {
1477 ret
= caam_jr_enqueue_op(ops
[loop
], jr_qp
);
1482 jr_qp
->tx_pkts
+= num_tx
;
1487 /* Release queue pair */
1489 caam_jr_queue_pair_release(struct rte_cryptodev
*dev
,
1492 struct sec_job_ring_t
*internals
;
1493 struct caam_jr_qp
*qp
= NULL
;
1495 PMD_INIT_FUNC_TRACE();
1496 CAAM_JR_DEBUG("dev =%p, queue =%d", dev
, qp_id
);
1498 internals
= dev
->data
->dev_private
;
1499 if (qp_id
>= internals
->max_nb_queue_pairs
) {
1500 CAAM_JR_ERR("Max supported qpid %d",
1501 internals
->max_nb_queue_pairs
);
1505 qp
= &internals
->qps
[qp_id
];
1507 dev
->data
->queue_pairs
[qp_id
] = NULL
;
1512 /* Setup a queue pair */
1514 caam_jr_queue_pair_setup(
1515 struct rte_cryptodev
*dev
, uint16_t qp_id
,
1516 __rte_unused
const struct rte_cryptodev_qp_conf
*qp_conf
,
1517 __rte_unused
int socket_id
)
1519 struct sec_job_ring_t
*internals
;
1520 struct caam_jr_qp
*qp
= NULL
;
1522 PMD_INIT_FUNC_TRACE();
1523 CAAM_JR_DEBUG("dev =%p, queue =%d, conf =%p", dev
, qp_id
, qp_conf
);
1525 internals
= dev
->data
->dev_private
;
1526 if (qp_id
>= internals
->max_nb_queue_pairs
) {
1527 CAAM_JR_ERR("Max supported qpid %d",
1528 internals
->max_nb_queue_pairs
);
1532 qp
= &internals
->qps
[qp_id
];
1533 qp
->ring
= internals
;
1534 dev
->data
->queue_pairs
[qp_id
] = qp
;
1539 /* Returns the size of the aesni gcm session structure */
1541 caam_jr_sym_session_get_size(struct rte_cryptodev
*dev __rte_unused
)
1543 PMD_INIT_FUNC_TRACE();
1545 return sizeof(struct caam_jr_session
);
1549 caam_jr_cipher_init(struct rte_cryptodev
*dev __rte_unused
,
1550 struct rte_crypto_sym_xform
*xform
,
1551 struct caam_jr_session
*session
)
1553 session
->cipher_alg
= xform
->cipher
.algo
;
1554 session
->iv
.length
= xform
->cipher
.iv
.length
;
1555 session
->iv
.offset
= xform
->cipher
.iv
.offset
;
1556 session
->cipher_key
.data
= rte_zmalloc(NULL
, xform
->cipher
.key
.length
,
1557 RTE_CACHE_LINE_SIZE
);
1558 if (session
->cipher_key
.data
== NULL
&& xform
->cipher
.key
.length
> 0) {
1559 CAAM_JR_ERR("No Memory for cipher key\n");
1562 session
->cipher_key
.length
= xform
->cipher
.key
.length
;
1564 memcpy(session
->cipher_key
.data
, xform
->cipher
.key
.data
,
1565 xform
->cipher
.key
.length
);
1566 session
->dir
= (xform
->cipher
.op
== RTE_CRYPTO_CIPHER_OP_ENCRYPT
) ?
1573 caam_jr_auth_init(struct rte_cryptodev
*dev __rte_unused
,
1574 struct rte_crypto_sym_xform
*xform
,
1575 struct caam_jr_session
*session
)
1577 session
->auth_alg
= xform
->auth
.algo
;
1578 session
->auth_key
.data
= rte_zmalloc(NULL
, xform
->auth
.key
.length
,
1579 RTE_CACHE_LINE_SIZE
);
1580 if (session
->auth_key
.data
== NULL
&& xform
->auth
.key
.length
> 0) {
1581 CAAM_JR_ERR("No Memory for auth key\n");
1584 session
->auth_key
.length
= xform
->auth
.key
.length
;
1585 session
->digest_length
= xform
->auth
.digest_length
;
1587 memcpy(session
->auth_key
.data
, xform
->auth
.key
.data
,
1588 xform
->auth
.key
.length
);
1589 session
->dir
= (xform
->auth
.op
== RTE_CRYPTO_AUTH_OP_GENERATE
) ?
1596 caam_jr_aead_init(struct rte_cryptodev
*dev __rte_unused
,
1597 struct rte_crypto_sym_xform
*xform
,
1598 struct caam_jr_session
*session
)
1600 session
->aead_alg
= xform
->aead
.algo
;
1601 session
->iv
.length
= xform
->aead
.iv
.length
;
1602 session
->iv
.offset
= xform
->aead
.iv
.offset
;
1603 session
->auth_only_len
= xform
->aead
.aad_length
;
1604 session
->aead_key
.data
= rte_zmalloc(NULL
, xform
->aead
.key
.length
,
1605 RTE_CACHE_LINE_SIZE
);
1606 if (session
->aead_key
.data
== NULL
&& xform
->aead
.key
.length
> 0) {
1607 CAAM_JR_ERR("No Memory for aead key\n");
1610 session
->aead_key
.length
= xform
->aead
.key
.length
;
1611 session
->digest_length
= xform
->aead
.digest_length
;
1613 memcpy(session
->aead_key
.data
, xform
->aead
.key
.data
,
1614 xform
->aead
.key
.length
);
1615 session
->dir
= (xform
->aead
.op
== RTE_CRYPTO_AEAD_OP_ENCRYPT
) ?
1622 caam_jr_set_session_parameters(struct rte_cryptodev
*dev
,
1623 struct rte_crypto_sym_xform
*xform
, void *sess
)
1625 struct sec_job_ring_t
*internals
= dev
->data
->dev_private
;
1626 struct caam_jr_session
*session
= sess
;
1628 PMD_INIT_FUNC_TRACE();
1630 if (unlikely(sess
== NULL
)) {
1631 CAAM_JR_ERR("invalid session struct");
1635 /* Default IV length = 0 */
1636 session
->iv
.length
= 0;
1639 if (xform
->type
== RTE_CRYPTO_SYM_XFORM_CIPHER
&& xform
->next
== NULL
) {
1640 session
->auth_alg
= RTE_CRYPTO_AUTH_NULL
;
1641 caam_jr_cipher_init(dev
, xform
, session
);
1643 /* Authentication Only */
1644 } else if (xform
->type
== RTE_CRYPTO_SYM_XFORM_AUTH
&&
1645 xform
->next
== NULL
) {
1646 session
->cipher_alg
= RTE_CRYPTO_CIPHER_NULL
;
1647 caam_jr_auth_init(dev
, xform
, session
);
1649 /* Cipher then Authenticate */
1650 } else if (xform
->type
== RTE_CRYPTO_SYM_XFORM_CIPHER
&&
1651 xform
->next
->type
== RTE_CRYPTO_SYM_XFORM_AUTH
) {
1652 if (xform
->cipher
.op
== RTE_CRYPTO_CIPHER_OP_ENCRYPT
) {
1653 caam_jr_cipher_init(dev
, xform
, session
);
1654 caam_jr_auth_init(dev
, xform
->next
, session
);
1656 CAAM_JR_ERR("Not supported: Auth then Cipher");
1660 /* Authenticate then Cipher */
1661 } else if (xform
->type
== RTE_CRYPTO_SYM_XFORM_AUTH
&&
1662 xform
->next
->type
== RTE_CRYPTO_SYM_XFORM_CIPHER
) {
1663 if (xform
->next
->cipher
.op
== RTE_CRYPTO_CIPHER_OP_DECRYPT
) {
1664 caam_jr_auth_init(dev
, xform
, session
);
1665 caam_jr_cipher_init(dev
, xform
->next
, session
);
1667 CAAM_JR_ERR("Not supported: Auth then Cipher");
1671 /* AEAD operation for AES-GCM kind of Algorithms */
1672 } else if (xform
->type
== RTE_CRYPTO_SYM_XFORM_AEAD
&&
1673 xform
->next
== NULL
) {
1674 caam_jr_aead_init(dev
, xform
, session
);
1677 CAAM_JR_ERR("Invalid crypto type");
1680 session
->ctx_pool
= internals
->ctx_pool
;
1685 rte_free(session
->cipher_key
.data
);
1686 rte_free(session
->auth_key
.data
);
1687 memset(session
, 0, sizeof(struct caam_jr_session
));
1693 caam_jr_sym_session_configure(struct rte_cryptodev
*dev
,
1694 struct rte_crypto_sym_xform
*xform
,
1695 struct rte_cryptodev_sym_session
*sess
,
1696 struct rte_mempool
*mempool
)
1698 void *sess_private_data
;
1701 PMD_INIT_FUNC_TRACE();
1703 if (rte_mempool_get(mempool
, &sess_private_data
)) {
1704 CAAM_JR_ERR("Couldn't get object from session mempool");
1708 memset(sess_private_data
, 0, sizeof(struct caam_jr_session
));
1709 ret
= caam_jr_set_session_parameters(dev
, xform
, sess_private_data
);
1711 CAAM_JR_ERR("failed to configure session parameters");
1712 /* Return session to mempool */
1713 rte_mempool_put(mempool
, sess_private_data
);
1717 set_sym_session_private_data(sess
, dev
->driver_id
, sess_private_data
);
1722 /* Clear the memory of session so it doesn't leave key material behind */
1724 caam_jr_sym_session_clear(struct rte_cryptodev
*dev
,
1725 struct rte_cryptodev_sym_session
*sess
)
1727 uint8_t index
= dev
->driver_id
;
1728 void *sess_priv
= get_sym_session_private_data(sess
, index
);
1729 struct caam_jr_session
*s
= (struct caam_jr_session
*)sess_priv
;
1731 PMD_INIT_FUNC_TRACE();
1734 struct rte_mempool
*sess_mp
= rte_mempool_from_obj(sess_priv
);
1736 rte_free(s
->cipher_key
.data
);
1737 rte_free(s
->auth_key
.data
);
1738 memset(s
, 0, sizeof(struct caam_jr_session
));
1739 set_sym_session_private_data(sess
, index
, NULL
);
1740 rte_mempool_put(sess_mp
, sess_priv
);
1745 caam_jr_set_ipsec_session(__rte_unused
struct rte_cryptodev
*dev
,
1746 struct rte_security_session_conf
*conf
,
1749 struct sec_job_ring_t
*internals
= dev
->data
->dev_private
;
1750 struct rte_security_ipsec_xform
*ipsec_xform
= &conf
->ipsec
;
1751 struct rte_crypto_auth_xform
*auth_xform
;
1752 struct rte_crypto_cipher_xform
*cipher_xform
;
1753 struct caam_jr_session
*session
= (struct caam_jr_session
*)sess
;
1755 PMD_INIT_FUNC_TRACE();
1757 if (ipsec_xform
->direction
== RTE_SECURITY_IPSEC_SA_DIR_EGRESS
) {
1758 cipher_xform
= &conf
->crypto_xform
->cipher
;
1759 auth_xform
= &conf
->crypto_xform
->next
->auth
;
1761 auth_xform
= &conf
->crypto_xform
->auth
;
1762 cipher_xform
= &conf
->crypto_xform
->next
->cipher
;
1764 session
->proto_alg
= conf
->protocol
;
1765 session
->cipher_key
.data
= rte_zmalloc(NULL
,
1766 cipher_xform
->key
.length
,
1767 RTE_CACHE_LINE_SIZE
);
1768 if (session
->cipher_key
.data
== NULL
&&
1769 cipher_xform
->key
.length
> 0) {
1770 CAAM_JR_ERR("No Memory for cipher key\n");
1774 session
->cipher_key
.length
= cipher_xform
->key
.length
;
1775 session
->auth_key
.data
= rte_zmalloc(NULL
,
1776 auth_xform
->key
.length
,
1777 RTE_CACHE_LINE_SIZE
);
1778 if (session
->auth_key
.data
== NULL
&&
1779 auth_xform
->key
.length
> 0) {
1780 CAAM_JR_ERR("No Memory for auth key\n");
1781 rte_free(session
->cipher_key
.data
);
1784 session
->auth_key
.length
= auth_xform
->key
.length
;
1785 memcpy(session
->cipher_key
.data
, cipher_xform
->key
.data
,
1786 cipher_xform
->key
.length
);
1787 memcpy(session
->auth_key
.data
, auth_xform
->key
.data
,
1788 auth_xform
->key
.length
);
1790 switch (auth_xform
->algo
) {
1791 case RTE_CRYPTO_AUTH_SHA1_HMAC
:
1792 session
->auth_alg
= RTE_CRYPTO_AUTH_SHA1_HMAC
;
1794 case RTE_CRYPTO_AUTH_MD5_HMAC
:
1795 session
->auth_alg
= RTE_CRYPTO_AUTH_MD5_HMAC
;
1797 case RTE_CRYPTO_AUTH_SHA256_HMAC
:
1798 session
->auth_alg
= RTE_CRYPTO_AUTH_SHA256_HMAC
;
1800 case RTE_CRYPTO_AUTH_SHA384_HMAC
:
1801 session
->auth_alg
= RTE_CRYPTO_AUTH_SHA384_HMAC
;
1803 case RTE_CRYPTO_AUTH_SHA512_HMAC
:
1804 session
->auth_alg
= RTE_CRYPTO_AUTH_SHA512_HMAC
;
1806 case RTE_CRYPTO_AUTH_AES_CMAC
:
1807 session
->auth_alg
= RTE_CRYPTO_AUTH_AES_CMAC
;
1809 case RTE_CRYPTO_AUTH_NULL
:
1810 session
->auth_alg
= RTE_CRYPTO_AUTH_NULL
;
1812 case RTE_CRYPTO_AUTH_SHA224_HMAC
:
1813 case RTE_CRYPTO_AUTH_AES_XCBC_MAC
:
1814 case RTE_CRYPTO_AUTH_SNOW3G_UIA2
:
1815 case RTE_CRYPTO_AUTH_SHA1
:
1816 case RTE_CRYPTO_AUTH_SHA256
:
1817 case RTE_CRYPTO_AUTH_SHA512
:
1818 case RTE_CRYPTO_AUTH_SHA224
:
1819 case RTE_CRYPTO_AUTH_SHA384
:
1820 case RTE_CRYPTO_AUTH_MD5
:
1821 case RTE_CRYPTO_AUTH_AES_GMAC
:
1822 case RTE_CRYPTO_AUTH_KASUMI_F9
:
1823 case RTE_CRYPTO_AUTH_AES_CBC_MAC
:
1824 case RTE_CRYPTO_AUTH_ZUC_EIA3
:
1825 CAAM_JR_ERR("Crypto: Unsupported auth alg %u\n",
1829 CAAM_JR_ERR("Crypto: Undefined Auth specified %u\n",
1834 switch (cipher_xform
->algo
) {
1835 case RTE_CRYPTO_CIPHER_AES_CBC
:
1836 session
->cipher_alg
= RTE_CRYPTO_CIPHER_AES_CBC
;
1838 case RTE_CRYPTO_CIPHER_3DES_CBC
:
1839 session
->cipher_alg
= RTE_CRYPTO_CIPHER_3DES_CBC
;
1841 case RTE_CRYPTO_CIPHER_AES_CTR
:
1842 session
->cipher_alg
= RTE_CRYPTO_CIPHER_AES_CTR
;
1844 case RTE_CRYPTO_CIPHER_NULL
:
1845 case RTE_CRYPTO_CIPHER_SNOW3G_UEA2
:
1846 case RTE_CRYPTO_CIPHER_3DES_ECB
:
1847 case RTE_CRYPTO_CIPHER_AES_ECB
:
1848 case RTE_CRYPTO_CIPHER_KASUMI_F8
:
1849 CAAM_JR_ERR("Crypto: Unsupported Cipher alg %u\n",
1850 cipher_xform
->algo
);
1853 CAAM_JR_ERR("Crypto: Undefined Cipher specified %u\n",
1854 cipher_xform
->algo
);
1858 if (ipsec_xform
->direction
== RTE_SECURITY_IPSEC_SA_DIR_EGRESS
) {
1859 memset(&session
->encap_pdb
, 0, sizeof(struct ipsec_encap_pdb
) +
1860 sizeof(session
->ip4_hdr
));
1861 session
->ip4_hdr
.ip_v
= IPVERSION
;
1862 session
->ip4_hdr
.ip_hl
= 5;
1863 session
->ip4_hdr
.ip_len
= rte_cpu_to_be_16(
1864 sizeof(session
->ip4_hdr
));
1865 session
->ip4_hdr
.ip_tos
= ipsec_xform
->tunnel
.ipv4
.dscp
;
1866 session
->ip4_hdr
.ip_id
= 0;
1867 session
->ip4_hdr
.ip_off
= 0;
1868 session
->ip4_hdr
.ip_ttl
= ipsec_xform
->tunnel
.ipv4
.ttl
;
1869 session
->ip4_hdr
.ip_p
= (ipsec_xform
->proto
==
1870 RTE_SECURITY_IPSEC_SA_PROTO_ESP
) ? IPPROTO_ESP
1872 session
->ip4_hdr
.ip_sum
= 0;
1873 session
->ip4_hdr
.ip_src
= ipsec_xform
->tunnel
.ipv4
.src_ip
;
1874 session
->ip4_hdr
.ip_dst
= ipsec_xform
->tunnel
.ipv4
.dst_ip
;
1875 session
->ip4_hdr
.ip_sum
= calc_chksum((uint16_t *)
1876 (void *)&session
->ip4_hdr
,
1879 session
->encap_pdb
.options
=
1880 (IPVERSION
<< PDBNH_ESP_ENCAP_SHIFT
) |
1881 PDBOPTS_ESP_OIHI_PDB_INL
|
1883 PDBHMO_ESP_ENCAP_DTTL
;
1884 if (ipsec_xform
->options
.esn
)
1885 session
->encap_pdb
.options
|= PDBOPTS_ESP_ESN
;
1886 session
->encap_pdb
.spi
= ipsec_xform
->spi
;
1887 session
->encap_pdb
.ip_hdr_len
= sizeof(struct ip
);
1889 session
->dir
= DIR_ENC
;
1890 } else if (ipsec_xform
->direction
==
1891 RTE_SECURITY_IPSEC_SA_DIR_INGRESS
) {
1892 memset(&session
->decap_pdb
, 0, sizeof(struct ipsec_decap_pdb
));
1893 session
->decap_pdb
.options
= sizeof(struct ip
) << 16;
1894 if (ipsec_xform
->options
.esn
)
1895 session
->decap_pdb
.options
|= PDBOPTS_ESP_ESN
;
1896 session
->dir
= DIR_DEC
;
1899 session
->ctx_pool
= internals
->ctx_pool
;
1903 rte_free(session
->auth_key
.data
);
1904 rte_free(session
->cipher_key
.data
);
1905 memset(session
, 0, sizeof(struct caam_jr_session
));
1910 caam_jr_security_session_create(void *dev
,
1911 struct rte_security_session_conf
*conf
,
1912 struct rte_security_session
*sess
,
1913 struct rte_mempool
*mempool
)
1915 void *sess_private_data
;
1916 struct rte_cryptodev
*cdev
= (struct rte_cryptodev
*)dev
;
1919 if (rte_mempool_get(mempool
, &sess_private_data
)) {
1920 CAAM_JR_ERR("Couldn't get object from session mempool");
1924 switch (conf
->protocol
) {
1925 case RTE_SECURITY_PROTOCOL_IPSEC
:
1926 ret
= caam_jr_set_ipsec_session(cdev
, conf
,
1929 case RTE_SECURITY_PROTOCOL_MACSEC
:
1935 CAAM_JR_ERR("failed to configure session parameters");
1936 /* Return session to mempool */
1937 rte_mempool_put(mempool
, sess_private_data
);
1941 set_sec_session_private_data(sess
, sess_private_data
);
1946 /* Clear the memory of session so it doesn't leave key material behind */
1948 caam_jr_security_session_destroy(void *dev __rte_unused
,
1949 struct rte_security_session
*sess
)
1951 PMD_INIT_FUNC_TRACE();
1952 void *sess_priv
= get_sec_session_private_data(sess
);
1954 struct caam_jr_session
*s
= (struct caam_jr_session
*)sess_priv
;
1957 struct rte_mempool
*sess_mp
= rte_mempool_from_obj(sess_priv
);
1959 rte_free(s
->cipher_key
.data
);
1960 rte_free(s
->auth_key
.data
);
1961 memset(sess
, 0, sizeof(struct caam_jr_session
));
1962 set_sec_session_private_data(sess
, NULL
);
1963 rte_mempool_put(sess_mp
, sess_priv
);
1970 caam_jr_dev_configure(struct rte_cryptodev
*dev
,
1971 struct rte_cryptodev_config
*config __rte_unused
)
1974 struct sec_job_ring_t
*internals
;
1976 PMD_INIT_FUNC_TRACE();
1978 internals
= dev
->data
->dev_private
;
1979 snprintf(str
, sizeof(str
), "ctx_pool_%d", dev
->data
->dev_id
);
1980 if (!internals
->ctx_pool
) {
1981 internals
->ctx_pool
= rte_mempool_create((const char *)str
,
1983 sizeof(struct caam_jr_op_ctx
),
1984 CTX_POOL_CACHE_SIZE
, 0,
1985 NULL
, NULL
, NULL
, NULL
,
1987 if (!internals
->ctx_pool
) {
1988 CAAM_JR_ERR("%s create failed\n", str
);
1992 CAAM_JR_INFO("mempool already created for dev_id : %d",
1999 caam_jr_dev_start(struct rte_cryptodev
*dev __rte_unused
)
2001 PMD_INIT_FUNC_TRACE();
2006 caam_jr_dev_stop(struct rte_cryptodev
*dev __rte_unused
)
2008 PMD_INIT_FUNC_TRACE();
2012 caam_jr_dev_close(struct rte_cryptodev
*dev
)
2014 struct sec_job_ring_t
*internals
;
2016 PMD_INIT_FUNC_TRACE();
2021 internals
= dev
->data
->dev_private
;
2022 rte_mempool_free(internals
->ctx_pool
);
2023 internals
->ctx_pool
= NULL
;
2029 caam_jr_dev_infos_get(struct rte_cryptodev
*dev
,
2030 struct rte_cryptodev_info
*info
)
2032 struct sec_job_ring_t
*internals
= dev
->data
->dev_private
;
2034 PMD_INIT_FUNC_TRACE();
2036 info
->max_nb_queue_pairs
= internals
->max_nb_queue_pairs
;
2037 info
->feature_flags
= dev
->feature_flags
;
2038 info
->capabilities
= caam_jr_get_cryptodev_capabilities();
2039 info
->sym
.max_nb_sessions
= internals
->max_nb_sessions
;
2040 info
->driver_id
= cryptodev_driver_id
;
2044 static struct rte_cryptodev_ops caam_jr_ops
= {
2045 .dev_configure
= caam_jr_dev_configure
,
2046 .dev_start
= caam_jr_dev_start
,
2047 .dev_stop
= caam_jr_dev_stop
,
2048 .dev_close
= caam_jr_dev_close
,
2049 .dev_infos_get
= caam_jr_dev_infos_get
,
2050 .stats_get
= caam_jr_stats_get
,
2051 .stats_reset
= caam_jr_stats_reset
,
2052 .queue_pair_setup
= caam_jr_queue_pair_setup
,
2053 .queue_pair_release
= caam_jr_queue_pair_release
,
2054 .sym_session_get_size
= caam_jr_sym_session_get_size
,
2055 .sym_session_configure
= caam_jr_sym_session_configure
,
2056 .sym_session_clear
= caam_jr_sym_session_clear
2059 static struct rte_security_ops caam_jr_security_ops
= {
2060 .session_create
= caam_jr_security_session_create
,
2061 .session_update
= NULL
,
2062 .session_stats_get
= NULL
,
2063 .session_destroy
= caam_jr_security_session_destroy
,
2064 .set_pkt_metadata
= NULL
,
2065 .capabilities_get
= caam_jr_get_security_capabilities
2068 /* @brief Flush job rings of any processed descs.
2069 * The processed descs are silently dropped,
2070 * WITHOUT being notified to UA.
2073 close_job_ring(struct sec_job_ring_t
*job_ring
)
2075 if (job_ring
->irq_fd
!= -1) {
2076 /* Producer index is frozen. If consumer index is not equal
2077 * with producer index, then we have descs to flush.
2079 while (job_ring
->pidx
!= job_ring
->cidx
)
2080 hw_flush_job_ring(job_ring
, false, NULL
);
2082 /* free the uio job ring */
2083 free_job_ring(job_ring
->irq_fd
);
2084 job_ring
->irq_fd
= -1;
2085 caam_jr_dma_free(job_ring
->input_ring
);
2086 caam_jr_dma_free(job_ring
->output_ring
);
2091 /** @brief Release the software and hardware resources tied to a job ring.
2092 * @param [in] job_ring The job ring
2094 * @retval 0 for success
2095 * @retval -1 for error
2098 shutdown_job_ring(struct sec_job_ring_t
*job_ring
)
2102 PMD_INIT_FUNC_TRACE();
2103 ASSERT(job_ring
!= NULL
);
2104 ret
= hw_shutdown_job_ring(job_ring
);
2105 SEC_ASSERT(ret
== 0, ret
,
2106 "Failed to shutdown hardware job ring %p",
2109 if (job_ring
->coalescing_en
)
2110 hw_job_ring_disable_coalescing(job_ring
);
2112 if (job_ring
->jr_mode
!= SEC_NOTIFICATION_TYPE_POLL
) {
2113 ret
= caam_jr_disable_irqs(job_ring
->irq_fd
);
2114 SEC_ASSERT(ret
== 0, ret
,
2115 "Failed to disable irqs for job ring %p",
2123 * @brief Release the resources used by the SEC user space driver.
2125 * Reset and release SEC's job rings indicated by the User Application at
2126 * init_job_ring() and free any memory allocated internally.
2127 * Call once during application tear down.
2129 * @note In case there are any descriptors in-flight (descriptors received by
2130 * SEC driver for processing and for which no response was yet provided to UA),
2131 * the descriptors are discarded without any notifications to User Application.
2133 * @retval ::0 is returned for a successful execution
2134 * @retval ::-1 is returned if SEC driver release is in progress
2137 caam_jr_dev_uninit(struct rte_cryptodev
*dev
)
2139 struct sec_job_ring_t
*internals
;
2141 PMD_INIT_FUNC_TRACE();
2145 internals
= dev
->data
->dev_private
;
2146 rte_free(dev
->security_ctx
);
2148 /* If any descriptors in flight , poll and wait
2149 * until all descriptors are received and silently discarded.
2152 shutdown_job_ring(internals
);
2153 close_job_ring(internals
);
2154 rte_mempool_free(internals
->ctx_pool
);
2157 CAAM_JR_INFO("Closing crypto device %s", dev
->data
->name
);
2159 /* last caam jr instance) */
2160 if (g_job_rings_no
== 0)
2161 g_driver_state
= SEC_DRIVER_STATE_IDLE
;
2166 /* @brief Initialize the software and hardware resources tied to a job ring.
2167 * @param [in] jr_mode; Model to be used by SEC Driver to receive
2168 * notifications from SEC. Can be either
2169 * of the three: #SEC_NOTIFICATION_TYPE_NAPI
2170 * #SEC_NOTIFICATION_TYPE_IRQ or
2171 * #SEC_NOTIFICATION_TYPE_POLL
2172 * @param [in] NAPI_mode The NAPI work mode to configure a job ring at
2173 * startup. Used only when #SEC_NOTIFICATION_TYPE
2174 * is set to #SEC_NOTIFICATION_TYPE_NAPI.
2175 * @param [in] irq_coalescing_timer This value determines the maximum
2176 * amount of time after processing a
2177 * descriptor before raising an interrupt.
2178 * @param [in] irq_coalescing_count This value determines how many
2179 * descriptors are completed before
2180 * raising an interrupt.
2181 * @param [in] reg_base_addr, The job ring base address register
2182 * @param [in] irq_id The job ring interrupt identification number.
2183 * @retval job_ring_handle for successful job ring configuration
2184 * @retval NULL on error
2188 init_job_ring(void *reg_base_addr
, int irq_id
)
2190 struct sec_job_ring_t
*job_ring
= NULL
;
2192 int jr_mode
= SEC_NOTIFICATION_TYPE_POLL
;
2194 int irq_coalescing_timer
= 0;
2195 int irq_coalescing_count
= 0;
2197 for (i
= 0; i
< MAX_SEC_JOB_RINGS
; i
++) {
2198 if (g_job_rings
[i
].irq_fd
== -1) {
2199 job_ring
= &g_job_rings
[i
];
2204 if (job_ring
== NULL
) {
2205 CAAM_JR_ERR("No free job ring\n");
2209 job_ring
->register_base_addr
= reg_base_addr
;
2210 job_ring
->jr_mode
= jr_mode
;
2211 job_ring
->napi_mode
= 0;
2212 job_ring
->irq_fd
= irq_id
;
2214 /* Allocate mem for input and output ring */
2216 /* Allocate memory for input ring */
2217 job_ring
->input_ring
= caam_jr_dma_mem_alloc(L1_CACHE_BYTES
,
2218 SEC_DMA_MEM_INPUT_RING_SIZE
);
2219 memset(job_ring
->input_ring
, 0, SEC_DMA_MEM_INPUT_RING_SIZE
);
2221 /* Allocate memory for output ring */
2222 job_ring
->output_ring
= caam_jr_dma_mem_alloc(L1_CACHE_BYTES
,
2223 SEC_DMA_MEM_OUTPUT_RING_SIZE
);
2224 memset(job_ring
->output_ring
, 0, SEC_DMA_MEM_OUTPUT_RING_SIZE
);
2226 /* Reset job ring in SEC hw and configure job ring registers */
2227 ret
= hw_reset_job_ring(job_ring
);
2229 CAAM_JR_ERR("Failed to reset hardware job ring");
2233 if (jr_mode
== SEC_NOTIFICATION_TYPE_NAPI
) {
2234 /* When SEC US driver works in NAPI mode, the UA can select
2235 * if the driver starts with IRQs on or off.
2237 if (napi_mode
== SEC_STARTUP_INTERRUPT_MODE
) {
2238 CAAM_JR_INFO("Enabling DONE IRQ generationon job ring - %p",
2240 ret
= caam_jr_enable_irqs(job_ring
->irq_fd
);
2242 CAAM_JR_ERR("Failed to enable irqs for job ring");
2246 } else if (jr_mode
== SEC_NOTIFICATION_TYPE_IRQ
) {
2247 /* When SEC US driver works in pure interrupt mode,
2248 * IRQ's are always enabled.
2250 CAAM_JR_INFO("Enabling DONE IRQ generation on job ring - %p",
2252 ret
= caam_jr_enable_irqs(job_ring
->irq_fd
);
2254 CAAM_JR_ERR("Failed to enable irqs for job ring");
2258 if (irq_coalescing_timer
|| irq_coalescing_count
) {
2259 hw_job_ring_set_coalescing_param(job_ring
,
2260 irq_coalescing_timer
,
2261 irq_coalescing_count
);
2263 hw_job_ring_enable_coalescing(job_ring
);
2264 job_ring
->coalescing_en
= 1;
2267 job_ring
->jr_state
= SEC_JOB_RING_STATE_STARTED
;
2268 job_ring
->max_nb_queue_pairs
= RTE_CAAM_MAX_NB_SEC_QPS
;
2269 job_ring
->max_nb_sessions
= RTE_CAAM_JR_PMD_MAX_NB_SESSIONS
;
2273 caam_jr_dma_free(job_ring
->output_ring
);
2274 caam_jr_dma_free(job_ring
->input_ring
);
2280 caam_jr_dev_init(const char *name
,
2281 struct rte_vdev_device
*vdev
,
2282 struct rte_cryptodev_pmd_init_params
*init_params
)
2284 struct rte_cryptodev
*dev
;
2285 struct rte_security_ctx
*security_instance
;
2286 struct uio_job_ring
*job_ring
;
2287 char str
[RTE_CRYPTODEV_NAME_MAX_LEN
];
2289 PMD_INIT_FUNC_TRACE();
2291 /* Validate driver state */
2292 if (g_driver_state
== SEC_DRIVER_STATE_IDLE
) {
2293 g_job_rings_max
= sec_configure();
2294 if (!g_job_rings_max
) {
2295 CAAM_JR_ERR("No job ring detected on UIO !!!!");
2298 /* Update driver state */
2299 g_driver_state
= SEC_DRIVER_STATE_STARTED
;
2302 if (g_job_rings_no
>= g_job_rings_max
) {
2303 CAAM_JR_ERR("No more job rings available max=%d!!!!",
2308 job_ring
= config_job_ring();
2309 if (job_ring
== NULL
) {
2310 CAAM_JR_ERR("failed to create job ring");
2314 snprintf(str
, sizeof(str
), "caam_jr%d", job_ring
->jr_id
);
2316 dev
= rte_cryptodev_pmd_create(name
, &vdev
->device
, init_params
);
2318 CAAM_JR_ERR("failed to create cryptodev vdev");
2321 /*TODO free it during teardown*/
2322 dev
->data
->dev_private
= init_job_ring(job_ring
->register_base_addr
,
2325 if (!dev
->data
->dev_private
) {
2326 CAAM_JR_ERR("Ring memory allocation failed\n");
2330 dev
->driver_id
= cryptodev_driver_id
;
2331 dev
->dev_ops
= &caam_jr_ops
;
2333 /* register rx/tx burst functions for data path */
2334 dev
->dequeue_burst
= caam_jr_dequeue_burst
;
2335 dev
->enqueue_burst
= caam_jr_enqueue_burst
;
2336 dev
->feature_flags
= RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO
|
2337 RTE_CRYPTODEV_FF_HW_ACCELERATED
|
2338 RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING
|
2339 RTE_CRYPTODEV_FF_SECURITY
|
2340 RTE_CRYPTODEV_FF_IN_PLACE_SGL
|
2341 RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT
|
2342 RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT
|
2343 RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT
|
2344 RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT
;
2346 /* For secondary processes, we don't initialise any further as primary
2347 * has already done this work. Only check we don't need a different
2350 if (rte_eal_process_type() != RTE_PROC_PRIMARY
) {
2351 CAAM_JR_WARN("Device already init by primary process");
2355 /*TODO free it during teardown*/
2356 security_instance
= rte_malloc("caam_jr",
2357 sizeof(struct rte_security_ctx
), 0);
2358 if (security_instance
== NULL
) {
2359 CAAM_JR_ERR("memory allocation failed\n");
2360 //todo error handling.
2364 security_instance
->device
= (void *)dev
;
2365 security_instance
->ops
= &caam_jr_security_ops
;
2366 security_instance
->sess_cnt
= 0;
2367 dev
->security_ctx
= security_instance
;
2369 RTE_LOG(INFO
, PMD
, "%s cryptodev init\n", dev
->data
->name
);
2374 caam_jr_dev_uninit(dev
);
2375 rte_cryptodev_pmd_release_device(dev
);
2377 free_job_ring(job_ring
->uio_fd
);
2379 CAAM_JR_ERR("driver %s: cryptodev_caam_jr_create failed",
2385 /** Initialise CAAM JR crypto device */
2387 cryptodev_caam_jr_probe(struct rte_vdev_device
*vdev
)
2389 struct rte_cryptodev_pmd_init_params init_params
= {
2391 sizeof(struct sec_job_ring_t
),
2393 RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
2396 const char *input_args
;
2398 name
= rte_vdev_device_name(vdev
);
2402 input_args
= rte_vdev_device_args(vdev
);
2403 rte_cryptodev_pmd_parse_input_args(&init_params
, input_args
);
2405 /* if sec device version is not configured */
2406 if (!rta_get_sec_era()) {
2407 const struct device_node
*caam_node
;
2409 for_each_compatible_node(caam_node
, NULL
, "fsl,sec-v4.0") {
2410 const uint32_t *prop
= of_get_property(caam_node
,
2415 INTL_SEC_ERA(cpu_to_caam32(*prop
)));
2420 #ifdef RTE_LIBRTE_PMD_CAAM_JR_BE
2421 if (rta_get_sec_era() > RTA_SEC_ERA_8
) {
2423 "CAAM is compiled in BE mode for device with sec era > 8???\n");
2428 return caam_jr_dev_init(name
, vdev
, &init_params
);
2431 /** Uninitialise CAAM JR crypto device */
2433 cryptodev_caam_jr_remove(struct rte_vdev_device
*vdev
)
2435 struct rte_cryptodev
*cryptodev
;
2438 name
= rte_vdev_device_name(vdev
);
2442 cryptodev
= rte_cryptodev_pmd_get_named_dev(name
);
2443 if (cryptodev
== NULL
)
2446 caam_jr_dev_uninit(cryptodev
);
2448 return rte_cryptodev_pmd_destroy(cryptodev
);
2452 sec_job_rings_init(void)
2456 for (i
= 0; i
< MAX_SEC_JOB_RINGS
; i
++)
2457 g_job_rings
[i
].irq_fd
= -1;
2460 static struct rte_vdev_driver cryptodev_caam_jr_drv
= {
2461 .probe
= cryptodev_caam_jr_probe
,
2462 .remove
= cryptodev_caam_jr_remove
2465 static struct cryptodev_driver caam_jr_crypto_drv
;
2467 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_CAAM_JR_PMD
, cryptodev_caam_jr_drv
);
2468 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_CAAM_JR_PMD
,
2469 "max_nb_queue_pairs=<int>"
2471 RTE_PMD_REGISTER_CRYPTO_DRIVER(caam_jr_crypto_drv
, cryptodev_caam_jr_drv
.driver
,
2472 cryptodev_driver_id
);
2474 RTE_INIT(caam_jr_init
)
2476 sec_uio_job_rings_init();
2477 sec_job_rings_init();
2480 RTE_INIT(caam_jr_init_log
)
2482 caam_jr_logtype
= rte_log_register("pmd.crypto.caam");
2483 if (caam_jr_logtype
>= 0)
2484 rte_log_set_level(caam_jr_logtype
, RTE_LOG_NOTICE
);