Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2017-2019 NXP
3 : : */
4 : :
5 : : #include <fcntl.h>
6 : : #include <unistd.h>
7 : : #include <sched.h>
8 : : #include <net/if.h>
9 : :
10 : : #include <rte_byteorder.h>
11 : : #include <rte_common.h>
12 : : #include <cryptodev_pmd.h>
13 : : #include <rte_crypto.h>
14 : : #include <rte_cryptodev.h>
15 : : #include <bus_vdev_driver.h>
16 : : #include <rte_malloc.h>
17 : : #include <rte_security_driver.h>
18 : : #include <rte_hexdump.h>
19 : :
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>
26 : :
27 : : /* RTA header files */
28 : : #include <desc/common.h>
29 : : #include <desc/algo.h>
30 : : #include <dpaa_of.h>
31 : : #ifdef RTE_LIBRTE_PMD_CAAM_JR_DEBUG
32 : : #define CAAM_JR_DBG 1
33 : : #else
34 : : #define CAAM_JR_DBG 0
35 : : #endif
36 : : #define CRYPTODEV_NAME_CAAM_JR_PMD crypto_caam_jr
37 : : static uint8_t cryptodev_driver_id;
38 : :
39 : : /* Lists the states possible for the SEC user space driver. */
40 : : enum sec_driver_state_e {
41 : : SEC_DRIVER_STATE_IDLE, /* Driver not initialized */
42 : : SEC_DRIVER_STATE_STARTED, /* Driver initialized and can be used*/
43 : : SEC_DRIVER_STATE_RELEASE, /* Driver release is in progress */
44 : : };
45 : :
46 : : /* Job rings used for communication with SEC HW */
47 : : static struct sec_job_ring_t g_job_rings[MAX_SEC_JOB_RINGS];
48 : :
49 : : /* The current state of SEC user space driver */
50 : : static enum sec_driver_state_e g_driver_state = SEC_DRIVER_STATE_IDLE;
51 : :
52 : : /* The number of job rings used by SEC user space driver */
53 : : static int g_job_rings_no;
54 : : static int g_job_rings_max;
55 : :
56 : : struct sec_outring_entry {
57 : : phys_addr_t desc; /* Pointer to completed descriptor */
58 : : uint32_t status; /* Status for completed descriptor */
59 : : } __rte_packed;
60 : :
61 : : /* virtual address conversin when mempool support is available for ctx */
62 : : static inline phys_addr_t
63 : : caam_jr_vtop_ctx(struct caam_jr_op_ctx *ctx, void *vaddr)
64 : : {
65 : 0 : return (size_t)vaddr - ctx->vtop_offset;
66 : : }
67 : :
68 : : static inline void
69 : 0 : caam_jr_op_ending(struct caam_jr_op_ctx *ctx)
70 : : {
71 : : /* report op status to sym->op and then free the ctx memory */
72 [ # # ]: 0 : rte_mempool_put(ctx->ctx_pool, (void *)ctx);
73 : 0 : }
74 : :
75 : : static inline struct caam_jr_op_ctx *
76 : 0 : caam_jr_alloc_ctx(struct caam_jr_session *ses)
77 : : {
78 : : struct caam_jr_op_ctx *ctx;
79 : : int ret;
80 : :
81 [ # # ]: 0 : ret = rte_mempool_get(ses->ctx_pool, (void **)(&ctx));
82 [ # # # # ]: 0 : if (!ctx || ret) {
83 : 0 : CAAM_JR_DP_WARN("Alloc sec descriptor failed!");
84 : 0 : return NULL;
85 : : }
86 : : /*
87 : : * Clear SG memory. There are 16 SG entries of 16 Bytes each.
88 : : * one call to dcbz_64() clear 64 bytes, hence calling it 4 times
89 : : * to clear all the SG entries. caam_jr_alloc_ctx() is called for
90 : : * each packet, memset is costlier than dcbz_64().
91 : : */
92 : : dcbz_64(&ctx->sg[SG_CACHELINE_0]);
93 : : dcbz_64(&ctx->sg[SG_CACHELINE_1]);
94 : : dcbz_64(&ctx->sg[SG_CACHELINE_2]);
95 : : dcbz_64(&ctx->sg[SG_CACHELINE_3]);
96 : :
97 : 0 : ctx->ctx_pool = ses->ctx_pool;
98 : 0 : ctx->vtop_offset = (size_t) ctx - rte_mempool_virt2iova(ctx);
99 : :
100 : 0 : return ctx;
101 : : }
102 : :
103 : : static
104 : 0 : void caam_jr_stats_get(struct rte_cryptodev *dev,
105 : : struct rte_cryptodev_stats *stats)
106 : : {
107 : 0 : struct caam_jr_qp **qp = (struct caam_jr_qp **)
108 : 0 : dev->data->queue_pairs;
109 : : int i;
110 : :
111 : 0 : PMD_INIT_FUNC_TRACE();
112 [ # # ]: 0 : if (stats == NULL) {
113 : 0 : CAAM_JR_ERR("Invalid stats ptr NULL");
114 : 0 : return;
115 : : }
116 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
117 [ # # ]: 0 : if (qp[i] == NULL) {
118 : 0 : CAAM_JR_WARN("Uninitialised queue pair");
119 : 0 : continue;
120 : : }
121 : :
122 : 0 : stats->enqueued_count += qp[i]->tx_pkts;
123 : 0 : stats->dequeued_count += qp[i]->rx_pkts;
124 : 0 : stats->enqueue_err_count += qp[i]->tx_errs;
125 : 0 : stats->dequeue_err_count += qp[i]->rx_errs;
126 : 0 : CAAM_JR_INFO("extra stats:\n\tRX Poll ERR = %" PRIu64
127 : : "\n\tTX Ring Full = %" PRIu64,
128 : : qp[i]->rx_poll_err,
129 : : qp[i]->tx_ring_full);
130 : : }
131 : : }
132 : :
133 : : static
134 : 0 : void caam_jr_stats_reset(struct rte_cryptodev *dev)
135 : : {
136 : : int i;
137 : 0 : struct caam_jr_qp **qp = (struct caam_jr_qp **)
138 : 0 : (dev->data->queue_pairs);
139 : :
140 : 0 : PMD_INIT_FUNC_TRACE();
141 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
142 [ # # ]: 0 : if (qp[i] == NULL) {
143 : 0 : CAAM_JR_WARN("Uninitialised queue pair");
144 : 0 : continue;
145 : : }
146 : 0 : qp[i]->rx_pkts = 0;
147 : 0 : qp[i]->rx_errs = 0;
148 : 0 : qp[i]->rx_poll_err = 0;
149 : 0 : qp[i]->tx_pkts = 0;
150 : 0 : qp[i]->tx_errs = 0;
151 : 0 : qp[i]->tx_ring_full = 0;
152 : : }
153 : 0 : }
154 : :
155 : : static inline int
156 : : is_cipher_only(struct caam_jr_session *ses)
157 : : {
158 [ # # # # : 0 : return ((ses->cipher_alg != RTE_CRYPTO_CIPHER_NULL) &&
# # ]
159 [ # # # # : 0 : (ses->auth_alg == RTE_CRYPTO_AUTH_NULL));
# # ]
160 : : }
161 : :
162 : : static inline int
163 : : is_auth_only(struct caam_jr_session *ses)
164 : : {
165 [ # # # # : 0 : return ((ses->cipher_alg == RTE_CRYPTO_CIPHER_NULL) &&
# # ]
166 [ # # # # : 0 : (ses->auth_alg != RTE_CRYPTO_AUTH_NULL));
# # ]
167 : : }
168 : :
169 : : static inline int
170 : : is_aead(struct caam_jr_session *ses)
171 : : {
172 : 0 : return ((ses->cipher_alg == 0) &&
173 [ # # # # : 0 : (ses->auth_alg == 0) &&
# # # # #
# # # ]
174 [ # # # # : 0 : (ses->aead_alg != 0));
# # ]
175 : : }
176 : :
177 : : static inline int
178 : : is_auth_cipher(struct caam_jr_session *ses)
179 : : {
180 : 0 : return ((ses->cipher_alg != RTE_CRYPTO_CIPHER_NULL) &&
181 [ # # # # : 0 : (ses->auth_alg != RTE_CRYPTO_AUTH_NULL) &&
# # # # ]
182 [ # # # # ]: 0 : (ses->proto_alg != RTE_SECURITY_PROTOCOL_IPSEC));
183 : : }
184 : :
185 : : static inline int
186 : : is_proto_ipsec(struct caam_jr_session *ses)
187 : : {
188 : 0 : return (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC);
189 : : }
190 : :
191 : : static inline int
192 : : is_encode(struct caam_jr_session *ses)
193 : : {
194 : 0 : return ses->dir == DIR_ENC;
195 : : }
196 : :
197 : : static inline int
198 : : is_decode(struct caam_jr_session *ses)
199 : : {
200 : 0 : return ses->dir == DIR_DEC;
201 : : }
202 : :
203 : : static inline void
204 : 0 : caam_auth_alg(struct caam_jr_session *ses, struct alginfo *alginfo_a)
205 : : {
206 [ # # # # : 0 : switch (ses->auth_alg) {
# # # # ]
207 : 0 : case RTE_CRYPTO_AUTH_NULL:
208 : 0 : ses->digest_length = 0;
209 : 0 : break;
210 : 0 : case RTE_CRYPTO_AUTH_MD5_HMAC:
211 : 0 : alginfo_a->algtype =
212 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
213 [ # # ]: 0 : OP_PCL_IPSEC_HMAC_MD5_96 : OP_ALG_ALGSEL_MD5;
214 : 0 : alginfo_a->algmode = OP_ALG_AAI_HMAC;
215 : 0 : break;
216 : 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
217 : 0 : alginfo_a->algtype =
218 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
219 [ # # ]: 0 : OP_PCL_IPSEC_HMAC_SHA1_96 : OP_ALG_ALGSEL_SHA1;
220 : 0 : alginfo_a->algmode = OP_ALG_AAI_HMAC;
221 : 0 : break;
222 : 0 : case RTE_CRYPTO_AUTH_SHA224_HMAC:
223 : 0 : alginfo_a->algtype =
224 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
225 [ # # ]: 0 : OP_PCL_IPSEC_HMAC_SHA1_160 : OP_ALG_ALGSEL_SHA224;
226 : 0 : alginfo_a->algmode = OP_ALG_AAI_HMAC;
227 : 0 : break;
228 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
229 : 0 : alginfo_a->algtype =
230 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
231 [ # # ]: 0 : OP_PCL_IPSEC_HMAC_SHA2_256_128 : OP_ALG_ALGSEL_SHA256;
232 : 0 : alginfo_a->algmode = OP_ALG_AAI_HMAC;
233 : 0 : break;
234 : 0 : case RTE_CRYPTO_AUTH_SHA384_HMAC:
235 : 0 : alginfo_a->algtype =
236 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
237 [ # # ]: 0 : OP_PCL_IPSEC_HMAC_SHA2_384_192 : OP_ALG_ALGSEL_SHA384;
238 : 0 : alginfo_a->algmode = OP_ALG_AAI_HMAC;
239 : 0 : break;
240 : 0 : case RTE_CRYPTO_AUTH_SHA512_HMAC:
241 : 0 : alginfo_a->algtype =
242 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
243 [ # # ]: 0 : OP_PCL_IPSEC_HMAC_SHA2_512_256 : OP_ALG_ALGSEL_SHA512;
244 : 0 : alginfo_a->algmode = OP_ALG_AAI_HMAC;
245 : 0 : break;
246 : 0 : default:
247 : 0 : CAAM_JR_DEBUG("unsupported auth alg %u", ses->auth_alg);
248 : : }
249 : 0 : }
250 : :
251 : : static inline void
252 : 0 : caam_cipher_alg(struct caam_jr_session *ses, struct alginfo *alginfo_c)
253 : : {
254 [ # # # # : 0 : switch (ses->cipher_alg) {
# ]
255 : : case RTE_CRYPTO_CIPHER_NULL:
256 : : break;
257 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
258 : 0 : alginfo_c->algtype =
259 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
260 [ # # ]: 0 : OP_PCL_IPSEC_AES_CBC : OP_ALG_ALGSEL_AES;
261 : 0 : alginfo_c->algmode = OP_ALG_AAI_CBC;
262 : 0 : break;
263 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
264 : 0 : alginfo_c->algtype =
265 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
266 [ # # ]: 0 : OP_PCL_IPSEC_3DES : OP_ALG_ALGSEL_3DES;
267 : 0 : alginfo_c->algmode = OP_ALG_AAI_CBC;
268 : 0 : break;
269 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
270 : 0 : alginfo_c->algtype =
271 : 0 : (ses->proto_alg == RTE_SECURITY_PROTOCOL_IPSEC) ?
272 [ # # ]: 0 : OP_PCL_IPSEC_AES_CTR : OP_ALG_ALGSEL_AES;
273 : 0 : alginfo_c->algmode = OP_ALG_AAI_CTR;
274 : 0 : break;
275 : 0 : default:
276 : 0 : CAAM_JR_DEBUG("unsupported cipher alg %d", ses->cipher_alg);
277 : : }
278 : 0 : }
279 : :
280 : : static inline void
281 : 0 : caam_aead_alg(struct caam_jr_session *ses, struct alginfo *alginfo)
282 : : {
283 [ # # ]: 0 : switch (ses->aead_alg) {
284 : 0 : case RTE_CRYPTO_AEAD_AES_GCM:
285 : 0 : alginfo->algtype = OP_ALG_ALGSEL_AES;
286 : 0 : alginfo->algmode = OP_ALG_AAI_GCM;
287 : 0 : break;
288 : 0 : default:
289 : 0 : CAAM_JR_DEBUG("unsupported AEAD alg %d", ses->aead_alg);
290 : : }
291 : 0 : }
292 : :
293 : : /* prepare command block of the session */
294 : : static int
295 : 0 : caam_jr_prep_cdb(struct caam_jr_session *ses)
296 : : {
297 : 0 : struct alginfo alginfo_c = {0}, alginfo_a = {0}, alginfo = {0};
298 : : int32_t shared_desc_len = 0;
299 : : struct sec_cdb *cdb;
300 : : int err;
301 : : #if CAAM_BYTE_ORDER == CORE_BYTE_ORDER
302 : : int swap = false;
303 : : #else
304 : : int swap = true;
305 : : #endif
306 : :
307 [ # # ]: 0 : if (ses->cdb)
308 : : caam_jr_dma_free(ses->cdb);
309 : :
310 : : cdb = caam_jr_dma_mem_alloc(L1_CACHE_BYTES, sizeof(struct sec_cdb));
311 [ # # ]: 0 : if (!cdb) {
312 : 0 : CAAM_JR_ERR("failed to allocate memory for cdb\n");
313 : 0 : return -1;
314 : : }
315 : :
316 [ # # ]: 0 : ses->cdb = cdb;
317 : :
318 : : memset(cdb, 0, sizeof(struct sec_cdb));
319 : :
320 : : if (is_cipher_only(ses)) {
321 : 0 : caam_cipher_alg(ses, &alginfo_c);
322 [ # # ]: 0 : if (alginfo_c.algtype == (unsigned int)CAAM_JR_ALG_UNSUPPORT) {
323 : 0 : CAAM_JR_ERR("not supported cipher alg");
324 : 0 : rte_free(cdb);
325 : 0 : return -ENOTSUP;
326 : : }
327 : :
328 : 0 : alginfo_c.key = (size_t)ses->cipher_key.data;
329 : 0 : alginfo_c.keylen = ses->cipher_key.length;
330 : 0 : alginfo_c.key_enc_flags = 0;
331 : 0 : alginfo_c.key_type = RTA_DATA_IMM;
332 : :
333 : 0 : shared_desc_len = cnstr_shdsc_blkcipher(
334 : 0 : cdb->sh_desc, true,
335 : : swap, SHR_NEVER, &alginfo_c,
336 : 0 : ses->iv.length,
337 : 0 : ses->dir);
338 : : } else if (is_auth_only(ses)) {
339 : 0 : caam_auth_alg(ses, &alginfo_a);
340 [ # # ]: 0 : if (alginfo_a.algtype == (unsigned int)CAAM_JR_ALG_UNSUPPORT) {
341 : 0 : CAAM_JR_ERR("not supported auth alg");
342 : 0 : rte_free(cdb);
343 : 0 : return -ENOTSUP;
344 : : }
345 : :
346 : 0 : alginfo_a.key = (size_t)ses->auth_key.data;
347 : 0 : alginfo_a.keylen = ses->auth_key.length;
348 : 0 : alginfo_a.key_enc_flags = 0;
349 : 0 : alginfo_a.key_type = RTA_DATA_IMM;
350 : :
351 : 0 : shared_desc_len = cnstr_shdsc_hmac(cdb->sh_desc, true,
352 : : swap, SHR_NEVER, &alginfo_a,
353 : 0 : !ses->dir,
354 : 0 : ses->digest_length);
355 : : } else if (is_aead(ses)) {
356 : 0 : caam_aead_alg(ses, &alginfo);
357 [ # # ]: 0 : if (alginfo.algtype == (unsigned int)CAAM_JR_ALG_UNSUPPORT) {
358 : 0 : CAAM_JR_ERR("not supported aead alg");
359 : 0 : rte_free(cdb);
360 : 0 : return -ENOTSUP;
361 : : }
362 : 0 : alginfo.key = (size_t)ses->aead_key.data;
363 : 0 : alginfo.keylen = ses->aead_key.length;
364 : 0 : alginfo.key_enc_flags = 0;
365 : 0 : alginfo.key_type = RTA_DATA_IMM;
366 : :
367 [ # # ]: 0 : if (ses->dir == DIR_ENC)
368 : 0 : shared_desc_len = cnstr_shdsc_gcm_encap(
369 : 0 : cdb->sh_desc, true, swap,
370 : : SHR_NEVER, &alginfo,
371 : 0 : ses->iv.length,
372 : : ses->digest_length);
373 : : else
374 : 0 : shared_desc_len = cnstr_shdsc_gcm_decap(
375 : 0 : cdb->sh_desc, true, swap,
376 : : SHR_NEVER, &alginfo,
377 : 0 : ses->iv.length,
378 : : ses->digest_length);
379 : : } else {
380 : 0 : caam_cipher_alg(ses, &alginfo_c);
381 [ # # ]: 0 : if (alginfo_c.algtype == (unsigned int)CAAM_JR_ALG_UNSUPPORT) {
382 : 0 : CAAM_JR_ERR("not supported cipher alg");
383 : 0 : rte_free(cdb);
384 : 0 : return -ENOTSUP;
385 : : }
386 : :
387 : 0 : alginfo_c.key = (size_t)ses->cipher_key.data;
388 : 0 : alginfo_c.keylen = ses->cipher_key.length;
389 : 0 : alginfo_c.key_enc_flags = 0;
390 : 0 : alginfo_c.key_type = RTA_DATA_IMM;
391 : :
392 : 0 : caam_auth_alg(ses, &alginfo_a);
393 [ # # ]: 0 : if (alginfo_a.algtype == (unsigned int)CAAM_JR_ALG_UNSUPPORT) {
394 : 0 : CAAM_JR_ERR("not supported auth alg");
395 : 0 : rte_free(cdb);
396 : 0 : return -ENOTSUP;
397 : : }
398 : :
399 : 0 : alginfo_a.key = (size_t)ses->auth_key.data;
400 : 0 : alginfo_a.keylen = ses->auth_key.length;
401 : 0 : alginfo_a.key_enc_flags = 0;
402 : 0 : alginfo_a.key_type = RTA_DATA_IMM;
403 : :
404 : 0 : cdb->sh_desc[0] = alginfo_c.keylen;
405 : 0 : cdb->sh_desc[1] = alginfo_a.keylen;
406 : 0 : err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN,
407 : : MIN_JOB_DESC_SIZE,
408 : 0 : (unsigned int *)cdb->sh_desc,
409 : : &cdb->sh_desc[2], 2);
410 : :
411 [ # # ]: 0 : if (err < 0) {
412 : 0 : CAAM_JR_ERR("Crypto: Incorrect key lengths");
413 : 0 : rte_free(cdb);
414 : 0 : return err;
415 : : }
416 [ # # ]: 0 : if (cdb->sh_desc[2] & 1)
417 : 0 : alginfo_c.key_type = RTA_DATA_IMM;
418 : : else {
419 : 0 : alginfo_c.key = (size_t)caam_jr_mem_vtop(
420 : 0 : (void *)(size_t)alginfo_c.key);
421 : 0 : alginfo_c.key_type = RTA_DATA_PTR;
422 : : }
423 [ # # ]: 0 : if (cdb->sh_desc[2] & (1<<1))
424 : 0 : alginfo_a.key_type = RTA_DATA_IMM;
425 : : else {
426 : 0 : alginfo_a.key = (size_t)caam_jr_mem_vtop(
427 : 0 : (void *)(size_t)alginfo_a.key);
428 : 0 : alginfo_a.key_type = RTA_DATA_PTR;
429 : : }
430 : 0 : cdb->sh_desc[0] = 0;
431 : 0 : cdb->sh_desc[1] = 0;
432 : 0 : cdb->sh_desc[2] = 0;
433 [ # # ]: 0 : if (is_proto_ipsec(ses)) {
434 [ # # ]: 0 : if (ses->dir == DIR_ENC) {
435 : 0 : shared_desc_len = cnstr_shdsc_ipsec_new_encap(
436 : : cdb->sh_desc,
437 : : true, swap, SHR_SERIAL,
438 : : &ses->encap_pdb,
439 : 0 : (uint8_t *)&ses->ip4_hdr,
440 : : &alginfo_c, &alginfo_a);
441 [ # # ]: 0 : } else if (ses->dir == DIR_DEC) {
442 : 0 : shared_desc_len = cnstr_shdsc_ipsec_new_decap(
443 : : cdb->sh_desc,
444 : : true, swap, SHR_SERIAL,
445 : : &ses->decap_pdb,
446 : : &alginfo_c, &alginfo_a);
447 : : }
448 : : } else {
449 : : /* Auth_only_len is overwritten in fd for each job */
450 : 0 : shared_desc_len = cnstr_shdsc_authenc(cdb->sh_desc,
451 : : true, swap, SHR_SERIAL,
452 : : &alginfo_c, &alginfo_a,
453 : 0 : ses->iv.length,
454 : 0 : ses->digest_length, ses->dir);
455 : : }
456 : : }
457 : :
458 [ # # ]: 0 : if (shared_desc_len < 0) {
459 : 0 : CAAM_JR_ERR("error in preparing command block");
460 : 0 : return shared_desc_len;
461 : : }
462 : :
463 : : #if CAAM_JR_DBG
464 : : SEC_DUMP_DESC(cdb->sh_desc);
465 : : #endif
466 : :
467 : 0 : cdb->sh_hdr.hi.field.idlen = shared_desc_len;
468 : :
469 : 0 : return 0;
470 : : }
471 : :
472 : : /* @brief Poll the HW for already processed jobs in the JR
473 : : * and silently discard the available jobs or notify them to UA
474 : : * with indicated error code.
475 : : *
476 : : * @param [in,out] job_ring The job ring to poll.
477 : : * @param [in] do_notify Can be #TRUE or #FALSE. Indicates if
478 : : * descriptors are to be discarded
479 : : * or notified to UA with given error_code.
480 : : * @param [out] notified_descs Number of notified descriptors. Can be NULL
481 : : * if do_notify is #FALSE
482 : : */
483 : : static void
484 : 0 : hw_flush_job_ring(struct sec_job_ring_t *job_ring,
485 : : uint32_t do_notify,
486 : : uint32_t *notified_descs)
487 : : {
488 : : int32_t jobs_no_to_discard = 0;
489 : : int32_t discarded_descs_no = 0;
490 : :
491 : 0 : CAAM_JR_DEBUG("Jr[%p] pi[%d] ci[%d].Flushing jr notify desc=[%d]",
492 : : job_ring, job_ring->pidx, job_ring->cidx, do_notify);
493 : :
494 : 0 : jobs_no_to_discard = hw_get_no_finished_jobs(job_ring);
495 : :
496 : : /* Discard all jobs */
497 : 0 : CAAM_JR_DEBUG("Jr[%p] pi[%d] ci[%d].Discarding %d descs",
498 : : job_ring, job_ring->pidx, job_ring->cidx,
499 : : jobs_no_to_discard);
500 : :
501 [ # # ]: 0 : while (jobs_no_to_discard > discarded_descs_no) {
502 : 0 : discarded_descs_no++;
503 : : /* Now increment the consumer index for the current job ring,
504 : : * AFTER saving job in temporary location!
505 : : * Increment the consumer index for the current job ring
506 : : */
507 : 0 : job_ring->cidx = SEC_CIRCULAR_COUNTER(job_ring->cidx,
508 : : SEC_JOB_RING_SIZE);
509 : :
510 : 0 : hw_remove_entries(job_ring, 1);
511 : : }
512 : :
513 [ # # ]: 0 : if (do_notify == true) {
514 : : ASSERT(notified_descs != NULL);
515 : 0 : *notified_descs = discarded_descs_no;
516 : : }
517 : 0 : }
518 : :
519 : : /* @brief Poll the HW for already processed jobs in the JR
520 : : * and notify the available jobs to UA.
521 : : *
522 : : * @param [in] job_ring The job ring to poll.
523 : : * @param [in] limit The maximum number of jobs to notify.
524 : : * If set to negative value, all available jobs are
525 : : * notified.
526 : : *
527 : : * @retval >=0 for No of jobs notified to UA.
528 : : * @retval -1 for error
529 : : */
530 : : static int
531 : 0 : hw_poll_job_ring(struct sec_job_ring_t *job_ring,
532 : : struct rte_crypto_op **ops, int32_t limit,
533 : : struct caam_jr_qp *jr_qp)
534 : : {
535 : : int32_t jobs_no_to_notify = 0; /* the number of done jobs to notify*/
536 : : int32_t number_of_jobs_available = 0;
537 : : int32_t notified_descs_no = 0;
538 : : uint32_t sec_error_code = 0;
539 : : struct job_descriptor *current_desc;
540 : : phys_addr_t current_desc_addr;
541 : : phys_addr_t *temp_addr;
542 : : struct caam_jr_op_ctx *ctx;
543 : :
544 : : /* TODO check for ops have memory*/
545 : : /* check here if any JR error that cannot be written
546 : : * in the output status word has occurred
547 : : */
548 [ # # ]: 0 : if (JR_REG_JRINT_JRE_EXTRACT(GET_JR_REG(JRINT, job_ring))) {
549 : 0 : CAAM_JR_INFO("err received");
550 : 0 : sec_error_code = JR_REG_JRINT_ERR_TYPE_EXTRACT(
551 : : GET_JR_REG(JRINT, job_ring));
552 [ # # ]: 0 : if (unlikely(sec_error_code)) {
553 : 0 : hw_job_ring_error_print(job_ring, sec_error_code);
554 : 0 : return -1;
555 : : }
556 : : }
557 : : /* compute the number of jobs available in the job ring based on the
558 : : * producer and consumer index values.
559 : : */
560 : 0 : number_of_jobs_available = hw_get_no_finished_jobs(job_ring);
561 : : /* Compute the number of notifications that need to be raised to UA
562 : : * If limit > total number of done jobs -> notify all done jobs
563 : : * If limit = 0 -> error
564 : : * If limit < total number of done jobs -> notify a number
565 : : * of done jobs equal with limit
566 : : */
567 : 0 : jobs_no_to_notify = (limit > number_of_jobs_available) ?
568 : : number_of_jobs_available : limit;
569 : : CAAM_JR_DP_DEBUG(
570 : : "Jr[%p] pi[%d] ci[%d].limit =%d Available=%d.Jobs to notify=%d",
571 : : job_ring, job_ring->pidx, job_ring->cidx,
572 : : limit, number_of_jobs_available, jobs_no_to_notify);
573 : :
574 : 0 : rte_smp_rmb();
575 : :
576 [ # # ]: 0 : while (jobs_no_to_notify > notified_descs_no) {
577 : : static uint64_t false_alarm;
578 : : static uint64_t real_poll;
579 : :
580 : : /* Get job status here */
581 : 0 : sec_error_code = job_ring->output_ring[job_ring->cidx].status;
582 : : /* Get completed descriptor */
583 : : temp_addr = &(job_ring->output_ring[job_ring->cidx].desc);
584 : 0 : current_desc_addr = (phys_addr_t)sec_read_addr(temp_addr);
585 : :
586 : 0 : real_poll++;
587 : : /* todo check if it is false alarm no desc present */
588 [ # # ]: 0 : if (!current_desc_addr) {
589 : 0 : false_alarm++;
590 : : printf("false alarm %" PRIu64 "real %" PRIu64
591 : : " sec_err =0x%x cidx Index =0%d\n",
592 : : false_alarm, real_poll,
593 : : sec_error_code, job_ring->cidx);
594 : 0 : rte_panic("CAAM JR descriptor NULL");
595 : : return notified_descs_no;
596 : : }
597 : : current_desc = (struct job_descriptor *)
598 : 0 : caam_jr_dma_ptov(current_desc_addr);
599 : : /* now increment the consumer index for the current job ring,
600 : : * AFTER saving job in temporary location!
601 : : */
602 : 0 : job_ring->cidx = SEC_CIRCULAR_COUNTER(job_ring->cidx,
603 : : SEC_JOB_RING_SIZE);
604 : : /* Signal that the job has been processed and the slot is free*/
605 : 0 : hw_remove_entries(job_ring, 1);
606 : : /*TODO for multiple ops, packets*/
607 : : ctx = container_of(current_desc, struct caam_jr_op_ctx, jobdes);
608 [ # # ]: 0 : if (unlikely(sec_error_code)) {
609 : 0 : CAAM_JR_ERR("desc at cidx %d generated error 0x%x\n",
610 : : job_ring->cidx, sec_error_code);
611 : 0 : hw_handle_job_ring_error(job_ring, sec_error_code);
612 : : //todo improve with exact errors
613 : 0 : ctx->op->status = RTE_CRYPTO_OP_STATUS_ERROR;
614 : 0 : jr_qp->rx_errs++;
615 : : } else {
616 : 0 : ctx->op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
617 : : #if CAAM_JR_DBG
618 : : if (ctx->op->sym->m_dst) {
619 : : rte_hexdump(stdout, "PROCESSED",
620 : : rte_pktmbuf_mtod(ctx->op->sym->m_dst, void *),
621 : : rte_pktmbuf_data_len(ctx->op->sym->m_dst));
622 : : } else {
623 : : rte_hexdump(stdout, "PROCESSED",
624 : : rte_pktmbuf_mtod(ctx->op->sym->m_src, void *),
625 : : rte_pktmbuf_data_len(ctx->op->sym->m_src));
626 : : }
627 : : #endif
628 : : }
629 [ # # ]: 0 : if (ctx->op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
630 : : struct ip *ip4_hdr;
631 : :
632 [ # # ]: 0 : if (ctx->op->sym->m_dst) {
633 : : /*TODO check for ip header or other*/
634 : 0 : ip4_hdr = rte_pktmbuf_mtod(ctx->op->sym->m_dst,
635 : : struct ip *);
636 : 0 : ctx->op->sym->m_dst->pkt_len =
637 [ # # ]: 0 : rte_be_to_cpu_16(ip4_hdr->ip_len);
638 : 0 : ctx->op->sym->m_dst->data_len =
639 [ # # ]: 0 : rte_be_to_cpu_16(ip4_hdr->ip_len);
640 : : } else {
641 : 0 : ip4_hdr = rte_pktmbuf_mtod(ctx->op->sym->m_src,
642 : : struct ip *);
643 : 0 : ctx->op->sym->m_src->pkt_len =
644 [ # # ]: 0 : rte_be_to_cpu_16(ip4_hdr->ip_len);
645 : 0 : ctx->op->sym->m_src->data_len =
646 [ # # ]: 0 : rte_be_to_cpu_16(ip4_hdr->ip_len);
647 : : }
648 : : }
649 : 0 : *ops = ctx->op;
650 : 0 : caam_jr_op_ending(ctx);
651 : 0 : ops++;
652 : 0 : notified_descs_no++;
653 : : }
654 : : return notified_descs_no;
655 : : }
656 : :
657 : : static uint16_t
658 : 0 : caam_jr_dequeue_burst(void *qp, struct rte_crypto_op **ops,
659 : : uint16_t nb_ops)
660 : : {
661 : : struct caam_jr_qp *jr_qp = (struct caam_jr_qp *)qp;
662 : 0 : struct sec_job_ring_t *ring = jr_qp->ring;
663 : : int num_rx;
664 : : int ret;
665 : :
666 : : CAAM_JR_DP_DEBUG("Jr[%p]Polling. limit[%d]", ring, nb_ops);
667 : :
668 : : /* Poll job ring
669 : : * If nb_ops < 0 -> poll JR until no more notifications are available.
670 : : * If nb_ops > 0 -> poll JR until limit is reached.
671 : : */
672 : :
673 : : /* Run hw poll job ring */
674 : 0 : num_rx = hw_poll_job_ring(ring, ops, nb_ops, jr_qp);
675 [ # # ]: 0 : if (num_rx < 0) {
676 : 0 : CAAM_JR_ERR("Error polling SEC engine (%d)", num_rx);
677 : 0 : return 0;
678 : : }
679 : :
680 : : CAAM_JR_DP_DEBUG("Jr[%p].Jobs notified[%d]. ", ring, num_rx);
681 : :
682 [ # # ]: 0 : if (ring->jr_mode == SEC_NOTIFICATION_TYPE_NAPI) {
683 [ # # ]: 0 : if (num_rx < nb_ops) {
684 : 0 : ret = caam_jr_enable_irqs(ring->irq_fd);
685 [ # # ]: 0 : SEC_ASSERT(ret == 0, ret,
686 : : "Failed to enable irqs for job ring %p", ring);
687 : : }
688 [ # # ]: 0 : } else if (ring->jr_mode == SEC_NOTIFICATION_TYPE_IRQ) {
689 : :
690 : : /* Always enable IRQ generation when in pure IRQ mode */
691 : 0 : ret = caam_jr_enable_irqs(ring->irq_fd);
692 [ # # ]: 0 : SEC_ASSERT(ret == 0, ret,
693 : : "Failed to enable irqs for job ring %p", ring);
694 : : }
695 : :
696 : 0 : jr_qp->rx_pkts += num_rx;
697 : :
698 : 0 : return num_rx;
699 : : }
700 : :
701 : : /**
702 : : * packet looks like:
703 : : * |<----data_len------->|
704 : : * |ip_header|ah_header|icv|payload|
705 : : * ^
706 : : * |
707 : : * mbuf->pkt.data
708 : : */
709 : : static inline struct caam_jr_op_ctx *
710 : 0 : build_auth_only_sg(struct rte_crypto_op *op, struct caam_jr_session *ses)
711 : : {
712 : : struct rte_crypto_sym_op *sym = op->sym;
713 : 0 : struct rte_mbuf *mbuf = sym->m_src;
714 : : struct caam_jr_op_ctx *ctx;
715 : : struct sec4_sg_entry *sg;
716 : : int length;
717 : : struct sec_cdb *cdb;
718 : : uint64_t sdesc_offset;
719 : : struct sec_job_descriptor_t *jobdescr;
720 : : uint8_t extra_segs;
721 : :
722 [ # # ]: 0 : if (is_decode(ses))
723 : : extra_segs = 2;
724 : : else
725 : : extra_segs = 1;
726 : :
727 [ # # ]: 0 : if ((mbuf->nb_segs + extra_segs) > MAX_SG_ENTRIES) {
728 : 0 : CAAM_JR_DP_ERR("Auth: Max sec segs supported is %d",
729 : : MAX_SG_ENTRIES);
730 : 0 : return NULL;
731 : : }
732 : :
733 : 0 : ctx = caam_jr_alloc_ctx(ses);
734 [ # # ]: 0 : if (!ctx)
735 : : return NULL;
736 : :
737 : 0 : ctx->op = op;
738 : :
739 : 0 : cdb = ses->cdb;
740 : : sdesc_offset = (size_t) ((char *)&cdb->sh_desc - (char *)cdb);
741 : :
742 : : jobdescr = (struct sec_job_descriptor_t *) ctx->jobdes.desc;
743 : :
744 : 0 : SEC_JD_INIT(jobdescr);
745 : 0 : SEC_JD_SET_SD(jobdescr,
746 : : (phys_addr_t)(caam_jr_dma_vtop(cdb)) + sdesc_offset,
747 : : cdb->sh_hdr.hi.field.idlen);
748 : :
749 : : /* output */
750 : 0 : SEC_JD_SET_OUT_PTR(jobdescr, (uint64_t)sym->auth.digest.phys_addr,
751 : : 0, ses->digest_length);
752 : :
753 : : /*input */
754 : 0 : sg = &ctx->sg[0];
755 : 0 : length = sym->auth.data.length;
756 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf) + sym->auth.data.offset);
757 : 0 : sg->len = cpu_to_caam32(mbuf->data_len - sym->auth.data.offset);
758 : :
759 : : /* Successive segs */
760 : 0 : mbuf = mbuf->next;
761 [ # # ]: 0 : while (mbuf) {
762 : 0 : sg++;
763 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf));
764 : 0 : sg->len = cpu_to_caam32(mbuf->data_len);
765 : 0 : mbuf = mbuf->next;
766 : : }
767 : :
768 [ # # ]: 0 : if (is_decode(ses)) {
769 : : /* digest verification case */
770 : 0 : sg++;
771 : : /* hash result or digest, save digest first */
772 [ # # ]: 0 : rte_memcpy(ctx->digest, sym->auth.digest.data,
773 : : ses->digest_length);
774 : : #if CAAM_JR_DBG
775 : : rte_hexdump(stdout, "ICV", ctx->digest, ses->digest_length);
776 : : #endif
777 : 0 : sg->ptr = cpu_to_caam64(caam_jr_vtop_ctx(ctx, ctx->digest));
778 : 0 : sg->len = cpu_to_caam32(ses->digest_length);
779 : 0 : length += ses->digest_length;
780 : : } else {
781 : 0 : sg->len -= ses->digest_length;
782 : : }
783 : :
784 : : /* last element*/
785 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
786 : :
787 : 0 : SEC_JD_SET_IN_PTR(jobdescr,
788 : : (uint64_t)caam_jr_vtop_ctx(ctx, &ctx->sg[0]), 0, length);
789 : : /* enabling sg list */
790 : 0 : (jobdescr)->seq_in.command.word |= 0x01000000;
791 : :
792 : 0 : return ctx;
793 : : }
794 : :
795 : : static inline struct caam_jr_op_ctx *
796 : 0 : build_auth_only(struct rte_crypto_op *op, struct caam_jr_session *ses)
797 : : {
798 : : struct rte_crypto_sym_op *sym = op->sym;
799 : : struct caam_jr_op_ctx *ctx;
800 : : struct sec4_sg_entry *sg;
801 : : rte_iova_t start_addr;
802 : : struct sec_cdb *cdb;
803 : : uint64_t sdesc_offset;
804 : : struct sec_job_descriptor_t *jobdescr;
805 : :
806 : 0 : ctx = caam_jr_alloc_ctx(ses);
807 [ # # ]: 0 : if (!ctx)
808 : : return NULL;
809 : :
810 : 0 : ctx->op = op;
811 : :
812 : 0 : cdb = ses->cdb;
813 : : sdesc_offset = (size_t) ((char *)&cdb->sh_desc - (char *)cdb);
814 : :
815 : 0 : start_addr = rte_pktmbuf_iova(sym->m_src);
816 : :
817 : : jobdescr = (struct sec_job_descriptor_t *) ctx->jobdes.desc;
818 : :
819 : 0 : SEC_JD_INIT(jobdescr);
820 : 0 : SEC_JD_SET_SD(jobdescr,
821 : : (phys_addr_t)(caam_jr_dma_vtop(cdb)) + sdesc_offset,
822 : : cdb->sh_hdr.hi.field.idlen);
823 : :
824 : : /* output */
825 : 0 : SEC_JD_SET_OUT_PTR(jobdescr, (uint64_t)sym->auth.digest.phys_addr,
826 : : 0, ses->digest_length);
827 : :
828 : : /*input */
829 [ # # ]: 0 : if (is_decode(ses)) {
830 : 0 : sg = &ctx->sg[0];
831 : 0 : SEC_JD_SET_IN_PTR(jobdescr,
832 : : (uint64_t)caam_jr_vtop_ctx(ctx, sg), 0,
833 : : (sym->auth.data.length + ses->digest_length));
834 : : /* enabling sg list */
835 : 0 : (jobdescr)->seq_in.command.word |= 0x01000000;
836 : :
837 : : /* hash result or digest, save digest first */
838 [ # # ]: 0 : rte_memcpy(ctx->digest, sym->auth.digest.data,
839 : : ses->digest_length);
840 : 0 : sg->ptr = cpu_to_caam64(start_addr + sym->auth.data.offset);
841 : 0 : sg->len = cpu_to_caam32(sym->auth.data.length);
842 : :
843 : : #if CAAM_JR_DBG
844 : : rte_hexdump(stdout, "ICV", ctx->digest, ses->digest_length);
845 : : #endif
846 : : /* let's check digest by hw */
847 : : sg++;
848 : 0 : sg->ptr = cpu_to_caam64(caam_jr_vtop_ctx(ctx, ctx->digest));
849 : 0 : sg->len = cpu_to_caam32(ses->digest_length);
850 : : /* last element*/
851 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
852 : : } else {
853 : 0 : SEC_JD_SET_IN_PTR(jobdescr, (uint64_t)start_addr,
854 : : sym->auth.data.offset, sym->auth.data.length);
855 : : }
856 : : return ctx;
857 : : }
858 : :
859 : : static inline struct caam_jr_op_ctx *
860 : 0 : build_cipher_only_sg(struct rte_crypto_op *op, struct caam_jr_session *ses)
861 : : {
862 : : struct rte_crypto_sym_op *sym = op->sym;
863 : 0 : struct rte_mbuf *mbuf = sym->m_src;
864 : : struct caam_jr_op_ctx *ctx;
865 : : struct sec4_sg_entry *sg, *in_sg;
866 : : int length;
867 : : struct sec_cdb *cdb;
868 : : uint64_t sdesc_offset;
869 : 0 : uint8_t *IV_ptr = rte_crypto_op_ctod_offset(op, uint8_t *,
870 : : ses->iv.offset);
871 : : struct sec_job_descriptor_t *jobdescr;
872 : : uint8_t reg_segs;
873 : :
874 [ # # ]: 0 : if (sym->m_dst) {
875 : : mbuf = sym->m_dst;
876 : 0 : reg_segs = mbuf->nb_segs + sym->m_src->nb_segs + 2;
877 : : } else {
878 : : mbuf = sym->m_src;
879 : 0 : reg_segs = mbuf->nb_segs * 2 + 2;
880 : : }
881 : :
882 [ # # ]: 0 : if (reg_segs > MAX_SG_ENTRIES) {
883 : 0 : CAAM_JR_DP_ERR("Cipher: Max sec segs supported is %d",
884 : : MAX_SG_ENTRIES);
885 : 0 : return NULL;
886 : : }
887 : :
888 : 0 : ctx = caam_jr_alloc_ctx(ses);
889 [ # # ]: 0 : if (!ctx)
890 : : return NULL;
891 : :
892 : 0 : ctx->op = op;
893 : 0 : cdb = ses->cdb;
894 : : sdesc_offset = (size_t) ((char *)&cdb->sh_desc - (char *)cdb);
895 : :
896 : : jobdescr = (struct sec_job_descriptor_t *) ctx->jobdes.desc;
897 : :
898 : 0 : SEC_JD_INIT(jobdescr);
899 : 0 : SEC_JD_SET_SD(jobdescr,
900 : : (phys_addr_t)(caam_jr_dma_vtop(cdb)) + sdesc_offset,
901 : : cdb->sh_hdr.hi.field.idlen);
902 : :
903 : : #if CAAM_JR_DBG
904 : : CAAM_JR_INFO("mbuf offset =%d, cipher offset = %d, length =%d+%d",
905 : : sym->m_src->data_off, sym->cipher.data.offset,
906 : : sym->cipher.data.length, ses->iv.length);
907 : : #endif
908 : : /* output */
909 [ # # ]: 0 : if (sym->m_dst)
910 : : mbuf = sym->m_dst;
911 : : else
912 : 0 : mbuf = sym->m_src;
913 : :
914 : 0 : sg = &ctx->sg[0];
915 : 0 : length = sym->cipher.data.length;
916 : :
917 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf)
918 : 0 : + sym->cipher.data.offset);
919 : 0 : sg->len = cpu_to_caam32(mbuf->data_len - sym->cipher.data.offset);
920 : :
921 : : /* Successive segs */
922 : 0 : mbuf = mbuf->next;
923 [ # # ]: 0 : while (mbuf) {
924 : 0 : sg++;
925 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf));
926 : 0 : sg->len = cpu_to_caam32(mbuf->data_len);
927 : 0 : mbuf = mbuf->next;
928 : : }
929 : : /* last element*/
930 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
931 : :
932 : 0 : SEC_JD_SET_OUT_PTR(jobdescr,
933 : : (uint64_t)caam_jr_vtop_ctx(ctx, &ctx->sg[0]), 0,
934 : : length);
935 : : /*enabling sg bit */
936 : 0 : (jobdescr)->seq_out.command.word |= 0x01000000;
937 : :
938 : : /*input */
939 : 0 : sg++;
940 : 0 : mbuf = sym->m_src;
941 : : in_sg = sg;
942 : :
943 : 0 : length = sym->cipher.data.length + ses->iv.length;
944 : :
945 : : /* IV */
946 : 0 : sg->ptr = cpu_to_caam64(caam_jr_dma_vtop(IV_ptr));
947 : 0 : sg->len = cpu_to_caam32(ses->iv.length);
948 : :
949 : : /* 1st seg */
950 : 0 : sg++;
951 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf)
952 : 0 : + sym->cipher.data.offset);
953 : 0 : sg->len = cpu_to_caam32(mbuf->data_len - sym->cipher.data.offset);
954 : :
955 : : /* Successive segs */
956 : 0 : mbuf = mbuf->next;
957 [ # # ]: 0 : while (mbuf) {
958 : 0 : sg++;
959 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf));
960 : 0 : sg->len = cpu_to_caam32(mbuf->data_len);
961 : 0 : mbuf = mbuf->next;
962 : : }
963 : : /* last element*/
964 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
965 : :
966 : :
967 : 0 : SEC_JD_SET_IN_PTR(jobdescr, (uint64_t)caam_jr_vtop_ctx(ctx, in_sg), 0,
968 : : length);
969 : : /*enabling sg bit */
970 : 0 : (jobdescr)->seq_in.command.word |= 0x01000000;
971 : :
972 : 0 : return ctx;
973 : : }
974 : :
975 : : static inline struct caam_jr_op_ctx *
976 : 0 : build_cipher_only(struct rte_crypto_op *op, struct caam_jr_session *ses)
977 : : {
978 : : struct rte_crypto_sym_op *sym = op->sym;
979 : : struct caam_jr_op_ctx *ctx;
980 : : struct sec4_sg_entry *sg;
981 : : rte_iova_t src_start_addr, dst_start_addr;
982 : : struct sec_cdb *cdb;
983 : : uint64_t sdesc_offset;
984 : 0 : uint8_t *IV_ptr = rte_crypto_op_ctod_offset(op, uint8_t *,
985 : : ses->iv.offset);
986 : : struct sec_job_descriptor_t *jobdescr;
987 : :
988 : 0 : ctx = caam_jr_alloc_ctx(ses);
989 [ # # ]: 0 : if (!ctx)
990 : : return NULL;
991 : :
992 : 0 : ctx->op = op;
993 : 0 : cdb = ses->cdb;
994 : : sdesc_offset = (size_t) ((char *)&cdb->sh_desc - (char *)cdb);
995 : :
996 [ # # ]: 0 : src_start_addr = rte_pktmbuf_iova(sym->m_src);
997 [ # # ]: 0 : if (sym->m_dst)
998 : 0 : dst_start_addr = rte_pktmbuf_iova(sym->m_dst);
999 : : else
1000 : : dst_start_addr = src_start_addr;
1001 : :
1002 : : jobdescr = (struct sec_job_descriptor_t *) ctx->jobdes.desc;
1003 : :
1004 : 0 : SEC_JD_INIT(jobdescr);
1005 : 0 : SEC_JD_SET_SD(jobdescr,
1006 : : (phys_addr_t)(caam_jr_dma_vtop(cdb)) + sdesc_offset,
1007 : : cdb->sh_hdr.hi.field.idlen);
1008 : :
1009 : : #if CAAM_JR_DBG
1010 : : CAAM_JR_INFO("mbuf offset =%d, cipher offset = %d, length =%d+%d",
1011 : : sym->m_src->data_off, sym->cipher.data.offset,
1012 : : sym->cipher.data.length, ses->iv.length);
1013 : : #endif
1014 : : /* output */
1015 : 0 : SEC_JD_SET_OUT_PTR(jobdescr, (uint64_t)dst_start_addr,
1016 : : sym->cipher.data.offset,
1017 : : sym->cipher.data.length + ses->iv.length);
1018 : :
1019 : : /*input */
1020 : 0 : sg = &ctx->sg[0];
1021 : 0 : SEC_JD_SET_IN_PTR(jobdescr, (uint64_t)caam_jr_vtop_ctx(ctx, sg), 0,
1022 : : sym->cipher.data.length + ses->iv.length);
1023 : : /*enabling sg bit */
1024 : 0 : (jobdescr)->seq_in.command.word |= 0x01000000;
1025 : :
1026 : 0 : sg->ptr = cpu_to_caam64(caam_jr_dma_vtop(IV_ptr));
1027 : 0 : sg->len = cpu_to_caam32(ses->iv.length);
1028 : :
1029 : : sg = &ctx->sg[1];
1030 : 0 : sg->ptr = cpu_to_caam64(src_start_addr + sym->cipher.data.offset);
1031 : 0 : sg->len = cpu_to_caam32(sym->cipher.data.length);
1032 : : /* last element*/
1033 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
1034 : :
1035 : 0 : return ctx;
1036 : : }
1037 : :
1038 : : /* For decapsulation:
1039 : : * Input:
1040 : : * +----+----------------+--------------------------------+-----+
1041 : : * | IV | Auth-only data | Authenticated & Encrypted data | ICV |
1042 : : * +----+----------------+--------------------------------+-----+
1043 : : * Output:
1044 : : * +----+--------------------------+
1045 : : * | Decrypted & authenticated data |
1046 : : * +----+--------------------------+
1047 : : */
1048 : :
1049 : : static inline struct caam_jr_op_ctx *
1050 : 0 : build_cipher_auth_sg(struct rte_crypto_op *op, struct caam_jr_session *ses)
1051 : : {
1052 : : struct rte_crypto_sym_op *sym = op->sym;
1053 : : struct caam_jr_op_ctx *ctx;
1054 : : struct sec4_sg_entry *sg, *out_sg, *in_sg;
1055 : : struct rte_mbuf *mbuf;
1056 : : uint32_t length = 0;
1057 : : struct sec_cdb *cdb;
1058 : : uint64_t sdesc_offset;
1059 : : uint8_t req_segs;
1060 : 0 : uint8_t *IV_ptr = rte_crypto_op_ctod_offset(op, uint8_t *,
1061 : : ses->iv.offset);
1062 : : struct sec_job_descriptor_t *jobdescr;
1063 : 0 : uint16_t auth_hdr_len = sym->cipher.data.offset -
1064 : 0 : sym->auth.data.offset;
1065 : 0 : uint16_t auth_tail_len = sym->auth.data.length -
1066 : 0 : sym->cipher.data.length - auth_hdr_len;
1067 : 0 : uint32_t auth_only_len = (auth_tail_len << 16) | auth_hdr_len;
1068 : :
1069 [ # # ]: 0 : if (sym->m_dst) {
1070 : : mbuf = sym->m_dst;
1071 : 0 : req_segs = mbuf->nb_segs + sym->m_src->nb_segs + 3;
1072 : : } else {
1073 : 0 : mbuf = sym->m_src;
1074 : 0 : req_segs = mbuf->nb_segs * 2 + 3;
1075 : : }
1076 : :
1077 [ # # ]: 0 : if (req_segs > MAX_SG_ENTRIES) {
1078 : 0 : CAAM_JR_DP_ERR("Cipher-Auth: Max sec segs supported is %d",
1079 : : MAX_SG_ENTRIES);
1080 : 0 : return NULL;
1081 : : }
1082 : :
1083 : 0 : ctx = caam_jr_alloc_ctx(ses);
1084 [ # # ]: 0 : if (!ctx)
1085 : : return NULL;
1086 : :
1087 : 0 : ctx->op = op;
1088 : 0 : cdb = ses->cdb;
1089 : : sdesc_offset = (size_t) ((char *)&cdb->sh_desc - (char *)cdb);
1090 : :
1091 : : jobdescr = (struct sec_job_descriptor_t *) ctx->jobdes.desc;
1092 : :
1093 : 0 : SEC_JD_INIT(jobdescr);
1094 : 0 : SEC_JD_SET_SD(jobdescr,
1095 : : (phys_addr_t)(caam_jr_dma_vtop(cdb)) + sdesc_offset,
1096 : : cdb->sh_hdr.hi.field.idlen);
1097 : :
1098 : : /* output */
1099 [ # # ]: 0 : if (sym->m_dst)
1100 : : mbuf = sym->m_dst;
1101 : : else
1102 : 0 : mbuf = sym->m_src;
1103 : :
1104 : 0 : out_sg = &ctx->sg[0];
1105 [ # # ]: 0 : if (is_encode(ses))
1106 : 0 : length = sym->auth.data.length + ses->digest_length;
1107 : : else
1108 : 0 : length = sym->auth.data.length;
1109 : :
1110 : : sg = &ctx->sg[0];
1111 : :
1112 : : /* 1st seg */
1113 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf)
1114 : 0 : + sym->auth.data.offset);
1115 : 0 : sg->len = cpu_to_caam32(mbuf->data_len - sym->auth.data.offset);
1116 : :
1117 : : /* Successive segs */
1118 : 0 : mbuf = mbuf->next;
1119 [ # # ]: 0 : while (mbuf) {
1120 : 0 : sg++;
1121 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf));
1122 : 0 : sg->len = cpu_to_caam32(mbuf->data_len);
1123 : 0 : mbuf = mbuf->next;
1124 : : }
1125 : :
1126 [ # # ]: 0 : if (is_encode(ses)) {
1127 : : /* set auth output */
1128 : 0 : sg++;
1129 : 0 : sg->ptr = cpu_to_caam64(sym->auth.digest.phys_addr);
1130 : 0 : sg->len = cpu_to_caam32(ses->digest_length);
1131 : : }
1132 : : /* last element*/
1133 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
1134 : :
1135 : 0 : SEC_JD_SET_OUT_PTR(jobdescr,
1136 : : (uint64_t)caam_jr_dma_vtop(out_sg), 0, length);
1137 : : /* set sg bit */
1138 : 0 : (jobdescr)->seq_out.command.word |= 0x01000000;
1139 : :
1140 : : /* input */
1141 : 0 : sg++;
1142 : 0 : mbuf = sym->m_src;
1143 : : in_sg = sg;
1144 [ # # ]: 0 : if (is_encode(ses))
1145 : 0 : length = ses->iv.length + sym->auth.data.length;
1146 : : else
1147 : 0 : length = ses->iv.length + sym->auth.data.length
1148 : 0 : + ses->digest_length;
1149 : :
1150 : 0 : sg->ptr = cpu_to_caam64(caam_jr_dma_vtop(IV_ptr));
1151 : 0 : sg->len = cpu_to_caam32(ses->iv.length);
1152 : :
1153 : 0 : sg++;
1154 : : /* 1st seg */
1155 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf)
1156 : 0 : + sym->auth.data.offset);
1157 : 0 : sg->len = cpu_to_caam32(mbuf->data_len - sym->auth.data.offset);
1158 : :
1159 : : /* Successive segs */
1160 : 0 : mbuf = mbuf->next;
1161 [ # # ]: 0 : while (mbuf) {
1162 : 0 : sg++;
1163 : 0 : sg->ptr = cpu_to_caam64(rte_pktmbuf_iova(mbuf));
1164 : 0 : sg->len = cpu_to_caam32(mbuf->data_len);
1165 : 0 : mbuf = mbuf->next;
1166 : : }
1167 : :
1168 [ # # ]: 0 : if (is_decode(ses)) {
1169 : 0 : sg++;
1170 : 0 : rte_memcpy(ctx->digest, sym->auth.digest.data,
1171 [ # # ]: 0 : ses->digest_length);
1172 : 0 : sg->ptr = cpu_to_caam64(caam_jr_dma_vtop(ctx->digest));
1173 : 0 : sg->len = cpu_to_caam32(ses->digest_length);
1174 : : }
1175 : : /* last element*/
1176 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
1177 : :
1178 : 0 : SEC_JD_SET_IN_PTR(jobdescr, (uint64_t)caam_jr_dma_vtop(in_sg), 0,
1179 : : length);
1180 : : /* set sg bit */
1181 : 0 : (jobdescr)->seq_in.command.word |= 0x01000000;
1182 : : /* Auth_only_len is set as 0 in descriptor and it is
1183 : : * overwritten here in the jd which will update
1184 : : * the DPOVRD reg.
1185 : : */
1186 [ # # ]: 0 : if (auth_only_len)
1187 : : /* set sg bit */
1188 : 0 : (jobdescr)->dpovrd = 0x80000000 | auth_only_len;
1189 : :
1190 : : return ctx;
1191 : : }
1192 : :
1193 : : static inline struct caam_jr_op_ctx *
1194 : 0 : build_cipher_auth(struct rte_crypto_op *op, struct caam_jr_session *ses)
1195 : : {
1196 : : struct rte_crypto_sym_op *sym = op->sym;
1197 : : struct caam_jr_op_ctx *ctx;
1198 : : struct sec4_sg_entry *sg;
1199 : : rte_iova_t src_start_addr, dst_start_addr;
1200 : : uint32_t length = 0;
1201 : : struct sec_cdb *cdb;
1202 : : uint64_t sdesc_offset;
1203 : 0 : uint8_t *IV_ptr = rte_crypto_op_ctod_offset(op, uint8_t *,
1204 : : ses->iv.offset);
1205 : : struct sec_job_descriptor_t *jobdescr;
1206 : 0 : uint16_t auth_hdr_len = sym->cipher.data.offset -
1207 : 0 : sym->auth.data.offset;
1208 : 0 : uint16_t auth_tail_len = sym->auth.data.length -
1209 : 0 : sym->cipher.data.length - auth_hdr_len;
1210 : 0 : uint32_t auth_only_len = (auth_tail_len << 16) | auth_hdr_len;
1211 : :
1212 [ # # ]: 0 : src_start_addr = rte_pktmbuf_iova(sym->m_src);
1213 [ # # ]: 0 : if (sym->m_dst)
1214 : 0 : dst_start_addr = rte_pktmbuf_iova(sym->m_dst);
1215 : : else
1216 : : dst_start_addr = src_start_addr;
1217 : :
1218 : 0 : ctx = caam_jr_alloc_ctx(ses);
1219 [ # # ]: 0 : if (!ctx)
1220 : : return NULL;
1221 : :
1222 : 0 : ctx->op = op;
1223 : 0 : cdb = ses->cdb;
1224 : : sdesc_offset = (size_t) ((char *)&cdb->sh_desc - (char *)cdb);
1225 : :
1226 : : jobdescr = (struct sec_job_descriptor_t *) ctx->jobdes.desc;
1227 : :
1228 : 0 : SEC_JD_INIT(jobdescr);
1229 : 0 : SEC_JD_SET_SD(jobdescr,
1230 : : (phys_addr_t)(caam_jr_dma_vtop(cdb)) + sdesc_offset,
1231 : : cdb->sh_hdr.hi.field.idlen);
1232 : :
1233 : : /* input */
1234 : 0 : sg = &ctx->sg[0];
1235 [ # # ]: 0 : if (is_encode(ses)) {
1236 : 0 : sg->ptr = cpu_to_caam64(caam_jr_dma_vtop(IV_ptr));
1237 : 0 : sg->len = cpu_to_caam32(ses->iv.length);
1238 : : length += ses->iv.length;
1239 : :
1240 : : sg++;
1241 : 0 : sg->ptr = cpu_to_caam64(src_start_addr + sym->auth.data.offset);
1242 : 0 : sg->len = cpu_to_caam32(sym->auth.data.length);
1243 : 0 : length += sym->auth.data.length;
1244 : : /* last element*/
1245 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
1246 : : } else {
1247 : 0 : sg->ptr = cpu_to_caam64(caam_jr_dma_vtop(IV_ptr));
1248 : 0 : sg->len = cpu_to_caam32(ses->iv.length);
1249 : : length += ses->iv.length;
1250 : :
1251 : : sg++;
1252 : 0 : sg->ptr = cpu_to_caam64(src_start_addr + sym->auth.data.offset);
1253 : 0 : sg->len = cpu_to_caam32(sym->auth.data.length);
1254 : 0 : length += sym->auth.data.length;
1255 : :
1256 : 0 : rte_memcpy(ctx->digest, sym->auth.digest.data,
1257 [ # # ]: 0 : ses->digest_length);
1258 : : sg++;
1259 : 0 : sg->ptr = cpu_to_caam64(caam_jr_dma_vtop(ctx->digest));
1260 : 0 : sg->len = cpu_to_caam32(ses->digest_length);
1261 : 0 : length += ses->digest_length;
1262 : : /* last element*/
1263 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
1264 : : }
1265 : :
1266 : 0 : SEC_JD_SET_IN_PTR(jobdescr, (uint64_t)caam_jr_dma_vtop(&ctx->sg[0]), 0,
1267 : : length);
1268 : : /* set sg bit */
1269 : 0 : (jobdescr)->seq_in.command.word |= 0x01000000;
1270 : :
1271 : : /* output */
1272 : 0 : sg = &ctx->sg[6];
1273 : :
1274 : 0 : sg->ptr = cpu_to_caam64(dst_start_addr + sym->cipher.data.offset);
1275 : 0 : sg->len = cpu_to_caam32(sym->cipher.data.length);
1276 : : length = sym->cipher.data.length;
1277 : :
1278 [ # # ]: 0 : if (is_encode(ses)) {
1279 : : /* set auth output */
1280 : 0 : sg++;
1281 : 0 : sg->ptr = cpu_to_caam64(sym->auth.digest.phys_addr);
1282 : 0 : sg->len = cpu_to_caam32(ses->digest_length);
1283 : 0 : length += ses->digest_length;
1284 : : }
1285 : : /* last element*/
1286 : 0 : sg->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
1287 : :
1288 : 0 : SEC_JD_SET_OUT_PTR(jobdescr,
1289 : : (uint64_t)caam_jr_dma_vtop(&ctx->sg[6]), 0, length);
1290 : : /* set sg bit */
1291 : 0 : (jobdescr)->seq_out.command.word |= 0x01000000;
1292 : :
1293 : : /* Auth_only_len is set as 0 in descriptor and it is
1294 : : * overwritten here in the jd which will update
1295 : : * the DPOVRD reg.
1296 : : */
1297 [ # # ]: 0 : if (auth_only_len)
1298 : : /* set sg bit */
1299 : 0 : (jobdescr)->dpovrd = 0x80000000 | auth_only_len;
1300 : :
1301 : : return ctx;
1302 : : }
1303 : :
1304 : : static inline struct caam_jr_op_ctx *
1305 : 0 : build_proto(struct rte_crypto_op *op, struct caam_jr_session *ses)
1306 : : {
1307 : : struct rte_crypto_sym_op *sym = op->sym;
1308 : : struct caam_jr_op_ctx *ctx = NULL;
1309 : : phys_addr_t src_start_addr, dst_start_addr;
1310 : : struct sec_cdb *cdb;
1311 : : uint64_t sdesc_offset;
1312 : : struct sec_job_descriptor_t *jobdescr;
1313 : :
1314 : 0 : ctx = caam_jr_alloc_ctx(ses);
1315 [ # # ]: 0 : if (!ctx)
1316 : : return NULL;
1317 : 0 : ctx->op = op;
1318 : :
1319 [ # # ]: 0 : src_start_addr = rte_pktmbuf_iova(sym->m_src);
1320 [ # # ]: 0 : if (sym->m_dst)
1321 : 0 : dst_start_addr = rte_pktmbuf_iova(sym->m_dst);
1322 : : else
1323 : : dst_start_addr = src_start_addr;
1324 : :
1325 : 0 : cdb = ses->cdb;
1326 : : sdesc_offset = (size_t) ((char *)&cdb->sh_desc - (char *)cdb);
1327 : :
1328 : : jobdescr = (struct sec_job_descriptor_t *) ctx->jobdes.desc;
1329 : :
1330 : 0 : SEC_JD_INIT(jobdescr);
1331 : 0 : SEC_JD_SET_SD(jobdescr,
1332 : : (phys_addr_t)(caam_jr_dma_vtop(cdb)) + sdesc_offset,
1333 : : cdb->sh_hdr.hi.field.idlen);
1334 : :
1335 : : /* output */
1336 : 0 : SEC_JD_SET_OUT_PTR(jobdescr, (uint64_t)dst_start_addr, 0,
1337 : : sym->m_src->buf_len - sym->m_src->data_off);
1338 : : /* input */
1339 : 0 : SEC_JD_SET_IN_PTR(jobdescr, (uint64_t)src_start_addr, 0,
1340 : : sym->m_src->pkt_len);
1341 : 0 : sym->m_src->packet_type &= ~RTE_PTYPE_L4_MASK;
1342 : :
1343 : 0 : return ctx;
1344 : : }
1345 : :
1346 : : static int
1347 : 0 : caam_jr_enqueue_op(struct rte_crypto_op *op, struct caam_jr_qp *qp)
1348 : : {
1349 : 0 : struct sec_job_ring_t *ring = qp->ring;
1350 : : struct caam_jr_session *ses;
1351 : : struct caam_jr_op_ctx *ctx = NULL;
1352 : : struct sec_job_descriptor_t *jobdescr __rte_unused;
1353 : : #if CAAM_JR_DBG
1354 : : int i;
1355 : : #endif
1356 : :
1357 [ # # # ]: 0 : switch (op->sess_type) {
1358 : 0 : case RTE_CRYPTO_OP_WITH_SESSION:
1359 : 0 : ses = CRYPTODEV_GET_SYM_SESS_PRIV(op->sym->session);
1360 : 0 : break;
1361 : 0 : case RTE_CRYPTO_OP_SECURITY_SESSION:
1362 : 0 : ses = SECURITY_GET_SESS_PRIV(op->sym->session);
1363 : 0 : break;
1364 : 0 : default:
1365 : 0 : CAAM_JR_DP_ERR("sessionless crypto op not supported");
1366 : 0 : qp->tx_errs++;
1367 : 0 : return -1;
1368 : : }
1369 : :
1370 [ # # # # ]: 0 : if (unlikely(!ses->qp || ses->qp != qp)) {
1371 : : CAAM_JR_DP_DEBUG("Old:sess->qp=%p New qp = %p\n", ses->qp, qp);
1372 : 0 : ses->qp = qp;
1373 : 0 : caam_jr_prep_cdb(ses);
1374 : : }
1375 : :
1376 [ # # ]: 0 : if (rte_pktmbuf_is_contiguous(op->sym->m_src)) {
1377 : : if (is_auth_cipher(ses))
1378 : 0 : ctx = build_cipher_auth(op, ses);
1379 : : else if (is_aead(ses))
1380 : 0 : goto err1;
1381 : : else if (is_auth_only(ses))
1382 : 0 : ctx = build_auth_only(op, ses);
1383 : : else if (is_cipher_only(ses))
1384 : 0 : ctx = build_cipher_only(op, ses);
1385 [ # # ]: 0 : else if (is_proto_ipsec(ses))
1386 : 0 : ctx = build_proto(op, ses);
1387 : : } else {
1388 : : if (is_auth_cipher(ses))
1389 : 0 : ctx = build_cipher_auth_sg(op, ses);
1390 : : else if (is_aead(ses))
1391 : 0 : goto err1;
1392 : : else if (is_auth_only(ses))
1393 : 0 : ctx = build_auth_only_sg(op, ses);
1394 : : else if (is_cipher_only(ses))
1395 : 0 : ctx = build_cipher_only_sg(op, ses);
1396 : : }
1397 : 0 : err1:
1398 [ # # ]: 0 : if (unlikely(!ctx)) {
1399 : 0 : qp->tx_errs++;
1400 : 0 : CAAM_JR_ERR("not supported sec op");
1401 : 0 : return -1;
1402 : : }
1403 : : #if CAAM_JR_DBG
1404 : : if (is_decode(ses))
1405 : : rte_hexdump(stdout, "DECODE",
1406 : : rte_pktmbuf_mtod(op->sym->m_src, void *),
1407 : : rte_pktmbuf_data_len(op->sym->m_src));
1408 : : else
1409 : : rte_hexdump(stdout, "ENCODE",
1410 : : rte_pktmbuf_mtod(op->sym->m_src, void *),
1411 : : rte_pktmbuf_data_len(op->sym->m_src));
1412 : :
1413 : : printf("\n JD before conversion\n");
1414 : : for (i = 0; i < 12; i++)
1415 : : printf("\n 0x%08x", ctx->jobdes.desc[i]);
1416 : : #endif
1417 : :
1418 : : CAAM_JR_DP_DEBUG("Jr[%p] pi[%d] ci[%d].Before sending desc",
1419 : : ring, ring->pidx, ring->cidx);
1420 : :
1421 : : /* todo - do we want to retry */
1422 [ # # ]: 0 : if (SEC_JOB_RING_IS_FULL(ring->pidx, ring->cidx,
1423 : : SEC_JOB_RING_SIZE, SEC_JOB_RING_SIZE)) {
1424 : : CAAM_JR_DP_DEBUG("Ring FULL Jr[%p] pi[%d] ci[%d].Size = %d",
1425 : : ring, ring->pidx, ring->cidx, SEC_JOB_RING_SIZE);
1426 : 0 : caam_jr_op_ending(ctx);
1427 : 0 : qp->tx_ring_full++;
1428 : 0 : return -EBUSY;
1429 : : }
1430 : :
1431 : : #if CORE_BYTE_ORDER != CAAM_BYTE_ORDER
1432 : : jobdescr = (struct sec_job_descriptor_t *) ctx->jobdes.desc;
1433 : :
1434 : : jobdescr->deschdr.command.word =
1435 : : cpu_to_caam32(jobdescr->deschdr.command.word);
1436 : : jobdescr->sd_ptr = cpu_to_caam64(jobdescr->sd_ptr);
1437 : : jobdescr->seq_out.command.word =
1438 : : cpu_to_caam32(jobdescr->seq_out.command.word);
1439 : : jobdescr->seq_out_ptr = cpu_to_caam64(jobdescr->seq_out_ptr);
1440 : : jobdescr->out_ext_length = cpu_to_caam32(jobdescr->out_ext_length);
1441 : : jobdescr->seq_in.command.word =
1442 : : cpu_to_caam32(jobdescr->seq_in.command.word);
1443 : : jobdescr->seq_in_ptr = cpu_to_caam64(jobdescr->seq_in_ptr);
1444 : : jobdescr->in_ext_length = cpu_to_caam32(jobdescr->in_ext_length);
1445 : : jobdescr->load_dpovrd.command.word =
1446 : : cpu_to_caam32(jobdescr->load_dpovrd.command.word);
1447 : : jobdescr->dpovrd = cpu_to_caam32(jobdescr->dpovrd);
1448 : : #endif
1449 : :
1450 : : /* Set ptr in input ring to current descriptor */
1451 : 0 : sec_write_addr(&ring->input_ring[ring->pidx],
1452 : : (phys_addr_t)caam_jr_vtop_ctx(ctx, ctx->jobdes.desc));
1453 : 0 : rte_smp_wmb();
1454 : :
1455 : : /* Notify HW that a new job is enqueued */
1456 : 0 : hw_enqueue_desc_on_job_ring(ring);
1457 : :
1458 : : /* increment the producer index for the current job ring */
1459 : 0 : ring->pidx = SEC_CIRCULAR_COUNTER(ring->pidx, SEC_JOB_RING_SIZE);
1460 : :
1461 : 0 : return 0;
1462 : : }
1463 : :
1464 : : static uint16_t
1465 : 0 : caam_jr_enqueue_burst(void *qp, struct rte_crypto_op **ops,
1466 : : uint16_t nb_ops)
1467 : : {
1468 : : /* Function to transmit the frames to given device and queuepair */
1469 : : uint32_t loop;
1470 : : int32_t ret;
1471 : : struct caam_jr_qp *jr_qp = (struct caam_jr_qp *)qp;
1472 : : uint16_t num_tx = 0;
1473 : : /*Prepare each packet which is to be sent*/
1474 [ # # ]: 0 : for (loop = 0; loop < nb_ops; loop++) {
1475 : 0 : ret = caam_jr_enqueue_op(ops[loop], jr_qp);
1476 [ # # ]: 0 : if (!ret)
1477 : 0 : num_tx++;
1478 : : }
1479 : :
1480 : 0 : jr_qp->tx_pkts += num_tx;
1481 : :
1482 : 0 : return num_tx;
1483 : : }
1484 : :
1485 : : /* Release queue pair */
1486 : : static int
1487 : 0 : caam_jr_queue_pair_release(struct rte_cryptodev *dev,
1488 : : uint16_t qp_id)
1489 : : {
1490 : : struct sec_job_ring_t *internals;
1491 : : struct caam_jr_qp *qp = NULL;
1492 : :
1493 : 0 : PMD_INIT_FUNC_TRACE();
1494 : 0 : CAAM_JR_DEBUG("dev =%p, queue =%d", dev, qp_id);
1495 : :
1496 : 0 : internals = dev->data->dev_private;
1497 [ # # ]: 0 : if (qp_id >= internals->max_nb_queue_pairs) {
1498 : 0 : CAAM_JR_ERR("Max supported qpid %d",
1499 : : internals->max_nb_queue_pairs);
1500 : 0 : return -EINVAL;
1501 : : }
1502 : :
1503 : : qp = &internals->qps[qp_id];
1504 : 0 : qp->ring = NULL;
1505 : 0 : dev->data->queue_pairs[qp_id] = NULL;
1506 : :
1507 : 0 : return 0;
1508 : : }
1509 : :
1510 : : /* Setup a queue pair */
1511 : : static int
1512 : 0 : caam_jr_queue_pair_setup(
1513 : : struct rte_cryptodev *dev, uint16_t qp_id,
1514 : : __rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
1515 : : __rte_unused int socket_id)
1516 : : {
1517 : : struct sec_job_ring_t *internals;
1518 : : struct caam_jr_qp *qp = NULL;
1519 : :
1520 : 0 : PMD_INIT_FUNC_TRACE();
1521 : 0 : CAAM_JR_DEBUG("dev =%p, queue =%d, conf =%p", dev, qp_id, qp_conf);
1522 : :
1523 : 0 : internals = dev->data->dev_private;
1524 [ # # ]: 0 : if (qp_id >= internals->max_nb_queue_pairs) {
1525 : 0 : CAAM_JR_ERR("Max supported qpid %d",
1526 : : internals->max_nb_queue_pairs);
1527 : 0 : return -EINVAL;
1528 : : }
1529 : :
1530 : 0 : qp = &internals->qps[qp_id];
1531 : 0 : qp->ring = internals;
1532 : 0 : dev->data->queue_pairs[qp_id] = qp;
1533 : :
1534 : 0 : return 0;
1535 : : }
1536 : :
1537 : : /* Returns the size of the aesni gcm session structure */
1538 : : static unsigned int
1539 : 0 : caam_jr_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
1540 : : {
1541 : 0 : PMD_INIT_FUNC_TRACE();
1542 : :
1543 : 0 : return sizeof(struct caam_jr_session);
1544 : : }
1545 : :
1546 : : static int
1547 : 0 : caam_jr_cipher_init(struct rte_cryptodev *dev __rte_unused,
1548 : : struct rte_crypto_sym_xform *xform,
1549 : : struct caam_jr_session *session)
1550 : : {
1551 : 0 : session->cipher_alg = xform->cipher.algo;
1552 : 0 : session->iv.length = xform->cipher.iv.length;
1553 : 0 : session->iv.offset = xform->cipher.iv.offset;
1554 : 0 : session->cipher_key.data = rte_zmalloc(NULL, xform->cipher.key.length,
1555 : : RTE_CACHE_LINE_SIZE);
1556 [ # # # # ]: 0 : if (session->cipher_key.data == NULL && xform->cipher.key.length > 0) {
1557 : 0 : CAAM_JR_ERR("No Memory for cipher key\n");
1558 : 0 : return -ENOMEM;
1559 : : }
1560 : 0 : session->cipher_key.length = xform->cipher.key.length;
1561 : :
1562 : 0 : memcpy(session->cipher_key.data, xform->cipher.key.data,
1563 : : xform->cipher.key.length);
1564 : 0 : session->dir = (xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) ?
1565 : 0 : DIR_ENC : DIR_DEC;
1566 : :
1567 : 0 : return 0;
1568 : : }
1569 : :
1570 : : static int
1571 : 0 : caam_jr_auth_init(struct rte_cryptodev *dev __rte_unused,
1572 : : struct rte_crypto_sym_xform *xform,
1573 : : struct caam_jr_session *session)
1574 : : {
1575 : 0 : session->auth_alg = xform->auth.algo;
1576 : 0 : session->auth_key.data = rte_zmalloc(NULL, xform->auth.key.length,
1577 : : RTE_CACHE_LINE_SIZE);
1578 [ # # # # ]: 0 : if (session->auth_key.data == NULL && xform->auth.key.length > 0) {
1579 : 0 : CAAM_JR_ERR("No Memory for auth key\n");
1580 : 0 : return -ENOMEM;
1581 : : }
1582 : 0 : session->auth_key.length = xform->auth.key.length;
1583 : 0 : session->digest_length = xform->auth.digest_length;
1584 : :
1585 : 0 : memcpy(session->auth_key.data, xform->auth.key.data,
1586 : : xform->auth.key.length);
1587 : 0 : session->dir = (xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) ?
1588 : 0 : DIR_ENC : DIR_DEC;
1589 : :
1590 : 0 : return 0;
1591 : : }
1592 : :
1593 : : static int
1594 : 0 : caam_jr_aead_init(struct rte_cryptodev *dev __rte_unused,
1595 : : struct rte_crypto_sym_xform *xform,
1596 : : struct caam_jr_session *session)
1597 : : {
1598 : 0 : session->aead_alg = xform->aead.algo;
1599 : 0 : session->iv.length = xform->aead.iv.length;
1600 : 0 : session->iv.offset = xform->aead.iv.offset;
1601 : 0 : session->auth_only_len = xform->aead.aad_length;
1602 : 0 : session->aead_key.data = rte_zmalloc(NULL, xform->aead.key.length,
1603 : : RTE_CACHE_LINE_SIZE);
1604 [ # # # # ]: 0 : if (session->aead_key.data == NULL && xform->aead.key.length > 0) {
1605 : 0 : CAAM_JR_ERR("No Memory for aead key\n");
1606 : 0 : return -ENOMEM;
1607 : : }
1608 : 0 : session->aead_key.length = xform->aead.key.length;
1609 : 0 : session->digest_length = xform->aead.digest_length;
1610 : :
1611 : 0 : memcpy(session->aead_key.data, xform->aead.key.data,
1612 : : xform->aead.key.length);
1613 : 0 : session->dir = (xform->aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
1614 : 0 : DIR_ENC : DIR_DEC;
1615 : :
1616 : 0 : return 0;
1617 : : }
1618 : :
1619 : : static int
1620 : 0 : caam_jr_set_session_parameters(struct rte_cryptodev *dev,
1621 : : struct rte_crypto_sym_xform *xform, void *sess)
1622 : : {
1623 : 0 : struct sec_job_ring_t *internals = dev->data->dev_private;
1624 : : struct caam_jr_session *session = sess;
1625 : :
1626 : 0 : PMD_INIT_FUNC_TRACE();
1627 : :
1628 [ # # ]: 0 : if (unlikely(sess == NULL)) {
1629 : 0 : CAAM_JR_ERR("invalid session struct");
1630 : 0 : return -EINVAL;
1631 : : }
1632 : :
1633 : : /* Default IV length = 0 */
1634 : 0 : session->iv.length = 0;
1635 : :
1636 : : /* Cipher Only */
1637 [ # # # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && xform->next == NULL) {
1638 : 0 : session->auth_alg = RTE_CRYPTO_AUTH_NULL;
1639 : 0 : caam_jr_cipher_init(dev, xform, session);
1640 : :
1641 : : /* Authentication Only */
1642 [ # # ]: 0 : } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
1643 [ # # ]: 0 : xform->next == NULL) {
1644 : 0 : session->cipher_alg = RTE_CRYPTO_CIPHER_NULL;
1645 : 0 : caam_jr_auth_init(dev, xform, session);
1646 : :
1647 : : /* Cipher then Authenticate */
1648 [ # # ]: 0 : } else if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
1649 [ # # ]: 0 : xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
1650 [ # # ]: 0 : if (xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
1651 : 0 : caam_jr_cipher_init(dev, xform, session);
1652 : 0 : caam_jr_auth_init(dev, xform->next, session);
1653 : : } else {
1654 : 0 : CAAM_JR_ERR("Not supported: Auth then Cipher");
1655 : 0 : goto err1;
1656 : : }
1657 : :
1658 : : /* Authenticate then Cipher */
1659 [ # # ]: 0 : } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
1660 [ # # ]: 0 : xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
1661 [ # # ]: 0 : if (xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
1662 : 0 : caam_jr_auth_init(dev, xform, session);
1663 : 0 : caam_jr_cipher_init(dev, xform->next, session);
1664 : : } else {
1665 : 0 : CAAM_JR_ERR("Not supported: Auth then Cipher");
1666 : 0 : goto err1;
1667 : : }
1668 : :
1669 : : /* AEAD operation for AES-GCM kind of Algorithms */
1670 [ # # ]: 0 : } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD &&
1671 [ # # ]: 0 : xform->next == NULL) {
1672 : 0 : caam_jr_aead_init(dev, xform, session);
1673 : :
1674 : : } else {
1675 : 0 : CAAM_JR_ERR("Invalid crypto type");
1676 : 0 : return -EINVAL;
1677 : : }
1678 : 0 : session->ctx_pool = internals->ctx_pool;
1679 : :
1680 : 0 : return 0;
1681 : :
1682 : 0 : err1:
1683 : 0 : rte_free(session->cipher_key.data);
1684 : 0 : rte_free(session->auth_key.data);
1685 : : memset(session, 0, sizeof(struct caam_jr_session));
1686 : :
1687 : 0 : return -EINVAL;
1688 : : }
1689 : :
1690 : : static int
1691 : 0 : caam_jr_sym_session_configure(struct rte_cryptodev *dev __rte_unused,
1692 : : struct rte_crypto_sym_xform *xform,
1693 : : struct rte_cryptodev_sym_session *sess)
1694 : : {
1695 : : void *sess_private_data;
1696 : : int ret;
1697 : :
1698 : 0 : PMD_INIT_FUNC_TRACE();
1699 : 0 : sess_private_data = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
1700 : : memset(sess_private_data, 0, sizeof(struct caam_jr_session));
1701 : 0 : ret = caam_jr_set_session_parameters(dev, xform, sess_private_data);
1702 [ # # ]: 0 : if (ret != 0) {
1703 : 0 : CAAM_JR_ERR("failed to configure session parameters");
1704 : : /* Return session to mempool */
1705 : 0 : return ret;
1706 : : }
1707 : :
1708 : : return 0;
1709 : : }
1710 : :
1711 : : /* Clear the memory of session so it doesn't leave key material behind */
1712 : : static void
1713 : 0 : caam_jr_sym_session_clear(struct rte_cryptodev *dev __rte_unused,
1714 : : struct rte_cryptodev_sym_session *sess)
1715 : : {
1716 : : struct caam_jr_session *s = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
1717 : :
1718 : 0 : PMD_INIT_FUNC_TRACE();
1719 : :
1720 : : if (s) {
1721 : 0 : rte_free(s->cipher_key.data);
1722 : 0 : rte_free(s->auth_key.data);
1723 : : }
1724 : 0 : }
1725 : :
1726 : : static int
1727 : 0 : caam_jr_set_ipsec_session(__rte_unused struct rte_cryptodev *dev,
1728 : : struct rte_security_session_conf *conf,
1729 : : void *sess)
1730 : : {
1731 : 0 : struct sec_job_ring_t *internals = dev->data->dev_private;
1732 : : struct rte_security_ipsec_xform *ipsec_xform = &conf->ipsec;
1733 : : struct rte_crypto_auth_xform *auth_xform;
1734 : : struct rte_crypto_cipher_xform *cipher_xform;
1735 : : struct caam_jr_session *session = (struct caam_jr_session *)sess;
1736 : :
1737 : 0 : PMD_INIT_FUNC_TRACE();
1738 : :
1739 [ # # ]: 0 : if (ipsec_xform->life.bytes_hard_limit != 0 ||
1740 [ # # ]: 0 : ipsec_xform->life.bytes_soft_limit != 0 ||
1741 [ # # ]: 0 : ipsec_xform->life.packets_hard_limit != 0 ||
1742 [ # # ]: 0 : ipsec_xform->life.packets_soft_limit != 0)
1743 : : return -ENOTSUP;
1744 : :
1745 [ # # ]: 0 : if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
1746 : 0 : cipher_xform = &conf->crypto_xform->cipher;
1747 : 0 : auth_xform = &conf->crypto_xform->next->auth;
1748 : : } else {
1749 : 0 : auth_xform = &conf->crypto_xform->auth;
1750 : 0 : cipher_xform = &conf->crypto_xform->next->cipher;
1751 : : }
1752 : 0 : session->proto_alg = conf->protocol;
1753 : 0 : session->cipher_key.data = rte_zmalloc(NULL,
1754 : 0 : cipher_xform->key.length,
1755 : : RTE_CACHE_LINE_SIZE);
1756 [ # # ]: 0 : if (session->cipher_key.data == NULL &&
1757 [ # # ]: 0 : cipher_xform->key.length > 0) {
1758 : 0 : CAAM_JR_ERR("No Memory for cipher key\n");
1759 : 0 : return -ENOMEM;
1760 : : }
1761 : :
1762 : 0 : session->cipher_key.length = cipher_xform->key.length;
1763 : 0 : session->auth_key.data = rte_zmalloc(NULL,
1764 : 0 : auth_xform->key.length,
1765 : : RTE_CACHE_LINE_SIZE);
1766 [ # # ]: 0 : if (session->auth_key.data == NULL &&
1767 [ # # ]: 0 : auth_xform->key.length > 0) {
1768 : 0 : CAAM_JR_ERR("No Memory for auth key\n");
1769 : 0 : rte_free(session->cipher_key.data);
1770 : 0 : return -ENOMEM;
1771 : : }
1772 : 0 : session->auth_key.length = auth_xform->key.length;
1773 : 0 : memcpy(session->cipher_key.data, cipher_xform->key.data,
1774 [ # # # # : 0 : cipher_xform->key.length);
# # # #
# ]
1775 : 0 : memcpy(session->auth_key.data, auth_xform->key.data,
1776 : 0 : auth_xform->key.length);
1777 : :
1778 [ # # # # : 0 : switch (auth_xform->algo) {
# # # #
# ]
1779 : 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
1780 : 0 : session->auth_alg = RTE_CRYPTO_AUTH_SHA1_HMAC;
1781 : 0 : break;
1782 : 0 : case RTE_CRYPTO_AUTH_MD5_HMAC:
1783 : 0 : session->auth_alg = RTE_CRYPTO_AUTH_MD5_HMAC;
1784 : 0 : break;
1785 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
1786 : 0 : session->auth_alg = RTE_CRYPTO_AUTH_SHA256_HMAC;
1787 : 0 : break;
1788 : 0 : case RTE_CRYPTO_AUTH_SHA384_HMAC:
1789 : 0 : session->auth_alg = RTE_CRYPTO_AUTH_SHA384_HMAC;
1790 : 0 : break;
1791 : 0 : case RTE_CRYPTO_AUTH_SHA512_HMAC:
1792 : 0 : session->auth_alg = RTE_CRYPTO_AUTH_SHA512_HMAC;
1793 : 0 : break;
1794 : 0 : case RTE_CRYPTO_AUTH_AES_CMAC:
1795 : 0 : session->auth_alg = RTE_CRYPTO_AUTH_AES_CMAC;
1796 : 0 : break;
1797 : 0 : case RTE_CRYPTO_AUTH_NULL:
1798 : 0 : session->auth_alg = RTE_CRYPTO_AUTH_NULL;
1799 : 0 : break;
1800 : 0 : case RTE_CRYPTO_AUTH_SHA224_HMAC:
1801 : : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
1802 : : case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
1803 : : case RTE_CRYPTO_AUTH_SHA1:
1804 : : case RTE_CRYPTO_AUTH_SHA256:
1805 : : case RTE_CRYPTO_AUTH_SHA512:
1806 : : case RTE_CRYPTO_AUTH_SHA224:
1807 : : case RTE_CRYPTO_AUTH_SHA384:
1808 : : case RTE_CRYPTO_AUTH_MD5:
1809 : : case RTE_CRYPTO_AUTH_AES_GMAC:
1810 : : case RTE_CRYPTO_AUTH_KASUMI_F9:
1811 : : case RTE_CRYPTO_AUTH_AES_CBC_MAC:
1812 : : case RTE_CRYPTO_AUTH_ZUC_EIA3:
1813 : 0 : CAAM_JR_ERR("Crypto: Unsupported auth alg %u\n",
1814 : : auth_xform->algo);
1815 : 0 : goto out;
1816 : 0 : default:
1817 : 0 : CAAM_JR_ERR("Crypto: Undefined Auth specified %u\n",
1818 : : auth_xform->algo);
1819 : 0 : goto out;
1820 : : }
1821 : :
1822 [ # # # # : 0 : switch (cipher_xform->algo) {
# ]
1823 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
1824 : 0 : session->cipher_alg = RTE_CRYPTO_CIPHER_AES_CBC;
1825 : 0 : break;
1826 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
1827 : 0 : session->cipher_alg = RTE_CRYPTO_CIPHER_3DES_CBC;
1828 : 0 : break;
1829 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
1830 : 0 : session->cipher_alg = RTE_CRYPTO_CIPHER_AES_CTR;
1831 : 0 : break;
1832 : 0 : case RTE_CRYPTO_CIPHER_NULL:
1833 : : case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
1834 : : case RTE_CRYPTO_CIPHER_3DES_ECB:
1835 : : case RTE_CRYPTO_CIPHER_AES_ECB:
1836 : : case RTE_CRYPTO_CIPHER_KASUMI_F8:
1837 : 0 : CAAM_JR_ERR("Crypto: Unsupported Cipher alg %u\n",
1838 : : cipher_xform->algo);
1839 : 0 : goto out;
1840 : 0 : default:
1841 : 0 : CAAM_JR_ERR("Crypto: Undefined Cipher specified %u\n",
1842 : : cipher_xform->algo);
1843 : 0 : goto out;
1844 : : }
1845 : :
1846 [ # # ]: 0 : if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
1847 [ # # ]: 0 : memset(&session->encap_pdb, 0, sizeof(struct ipsec_encap_pdb) +
1848 : : sizeof(session->ip4_hdr));
1849 : 0 : session->ip4_hdr.ip_v = IPVERSION;
1850 : 0 : session->ip4_hdr.ip_hl = 5;
1851 : 0 : session->ip4_hdr.ip_len = rte_cpu_to_be_16(
1852 : : sizeof(session->ip4_hdr));
1853 : 0 : session->ip4_hdr.ip_tos = ipsec_xform->tunnel.ipv4.dscp;
1854 : : session->ip4_hdr.ip_id = 0;
1855 : : session->ip4_hdr.ip_off = 0;
1856 : 0 : session->ip4_hdr.ip_ttl = ipsec_xform->tunnel.ipv4.ttl;
1857 [ # # ]: 0 : session->ip4_hdr.ip_p = (ipsec_xform->proto ==
1858 : : RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? IPPROTO_ESP
1859 : : : IPPROTO_AH;
1860 : : session->ip4_hdr.ip_sum = 0;
1861 : 0 : session->ip4_hdr.ip_src = ipsec_xform->tunnel.ipv4.src_ip;
1862 : 0 : session->ip4_hdr.ip_dst = ipsec_xform->tunnel.ipv4.dst_ip;
1863 : 0 : session->ip4_hdr.ip_sum = calc_chksum((uint16_t *)
1864 : 0 : (void *)&session->ip4_hdr,
1865 : : sizeof(struct ip));
1866 : :
1867 : 0 : session->encap_pdb.options =
1868 : : (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) |
1869 : : PDBOPTS_ESP_OIHI_PDB_INL |
1870 : : PDBOPTS_ESP_IVSRC;
1871 [ # # ]: 0 : if (ipsec_xform->options.dec_ttl)
1872 : 0 : session->encap_pdb.options |= PDBHMO_ESP_ENCAP_DTTL;
1873 [ # # ]: 0 : if (ipsec_xform->options.esn)
1874 : 0 : session->encap_pdb.options |= PDBOPTS_ESP_ESN;
1875 : 0 : session->encap_pdb.spi = ipsec_xform->spi;
1876 : 0 : session->encap_pdb.ip_hdr_len = sizeof(struct ip);
1877 : :
1878 : 0 : session->dir = DIR_ENC;
1879 [ # # ]: 0 : } else if (ipsec_xform->direction ==
1880 : : RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
1881 [ # # ]: 0 : memset(&session->decap_pdb, 0, sizeof(struct ipsec_decap_pdb));
1882 : 0 : session->decap_pdb.options = sizeof(struct ip) << 16;
1883 [ # # ]: 0 : if (ipsec_xform->options.esn)
1884 : 0 : session->decap_pdb.options |= PDBOPTS_ESP_ESN;
1885 : 0 : session->dir = DIR_DEC;
1886 : : } else
1887 : 0 : goto out;
1888 : 0 : session->ctx_pool = internals->ctx_pool;
1889 : :
1890 : 0 : return 0;
1891 : 0 : out:
1892 : 0 : rte_free(session->auth_key.data);
1893 : 0 : rte_free(session->cipher_key.data);
1894 : : memset(session, 0, sizeof(struct caam_jr_session));
1895 : 0 : return -1;
1896 : : }
1897 : :
1898 : : static int
1899 : 0 : caam_jr_security_session_create(void *dev,
1900 : : struct rte_security_session_conf *conf,
1901 : : struct rte_security_session *sess)
1902 : : {
1903 : 0 : void *sess_private_data = SECURITY_GET_SESS_PRIV(sess);
1904 : : struct rte_cryptodev *cdev = (struct rte_cryptodev *)dev;
1905 : : int ret;
1906 : :
1907 [ # # # ]: 0 : switch (conf->protocol) {
1908 : 0 : case RTE_SECURITY_PROTOCOL_IPSEC:
1909 : 0 : ret = caam_jr_set_ipsec_session(cdev, conf,
1910 : : sess_private_data);
1911 : : break;
1912 : : case RTE_SECURITY_PROTOCOL_MACSEC:
1913 : : return -ENOTSUP;
1914 : 0 : default:
1915 : 0 : return -EINVAL;
1916 : : }
1917 [ # # ]: 0 : if (ret != 0) {
1918 : 0 : CAAM_JR_ERR("failed to configure session parameters");
1919 : : }
1920 : :
1921 : : return ret;
1922 : : }
1923 : :
1924 : : /* Clear the memory of session so it doesn't leave key material behind */
1925 : : static int
1926 : 0 : caam_jr_security_session_destroy(void *dev __rte_unused,
1927 : : struct rte_security_session *sess)
1928 : : {
1929 : 0 : PMD_INIT_FUNC_TRACE();
1930 : 0 : struct caam_jr_session *s = SECURITY_GET_SESS_PRIV(sess);
1931 : :
1932 : : if (s) {
1933 : 0 : rte_free(s->cipher_key.data);
1934 : 0 : rte_free(s->auth_key.data);
1935 : : memset(s, 0, sizeof(struct caam_jr_session));
1936 : : }
1937 : 0 : return 0;
1938 : : }
1939 : :
1940 : : static unsigned int
1941 : 0 : caam_jr_security_session_get_size(void *device __rte_unused)
1942 : : {
1943 : 0 : return sizeof(struct caam_jr_session);
1944 : : }
1945 : :
1946 : : static int
1947 : 0 : caam_jr_dev_configure(struct rte_cryptodev *dev,
1948 : : struct rte_cryptodev_config *config __rte_unused)
1949 : : {
1950 : : char str[20];
1951 : : struct sec_job_ring_t *internals;
1952 : :
1953 : 0 : PMD_INIT_FUNC_TRACE();
1954 : :
1955 : 0 : internals = dev->data->dev_private;
1956 [ # # ]: 0 : snprintf(str, sizeof(str), "ctx_pool_%d", dev->data->dev_id);
1957 [ # # ]: 0 : if (!internals->ctx_pool) {
1958 : 0 : internals->ctx_pool = rte_mempool_create((const char *)str,
1959 : : CTX_POOL_NUM_BUFS,
1960 : : sizeof(struct caam_jr_op_ctx),
1961 : : CTX_POOL_CACHE_SIZE, 0,
1962 : : NULL, NULL, NULL, NULL,
1963 : : SOCKET_ID_ANY, 0);
1964 [ # # ]: 0 : if (!internals->ctx_pool) {
1965 : 0 : CAAM_JR_ERR("%s create failed\n", str);
1966 : 0 : return -ENOMEM;
1967 : : }
1968 : : } else
1969 : 0 : CAAM_JR_INFO("mempool already created for dev_id : %d",
1970 : : dev->data->dev_id);
1971 : :
1972 : : return 0;
1973 : : }
1974 : :
1975 : : static int
1976 : 0 : caam_jr_dev_start(struct rte_cryptodev *dev __rte_unused)
1977 : : {
1978 : 0 : PMD_INIT_FUNC_TRACE();
1979 : 0 : return 0;
1980 : : }
1981 : :
1982 : : static void
1983 : 0 : caam_jr_dev_stop(struct rte_cryptodev *dev __rte_unused)
1984 : : {
1985 : 0 : PMD_INIT_FUNC_TRACE();
1986 : 0 : }
1987 : :
1988 : : static int
1989 : 0 : caam_jr_dev_close(struct rte_cryptodev *dev)
1990 : : {
1991 : : struct sec_job_ring_t *internals;
1992 : :
1993 : 0 : PMD_INIT_FUNC_TRACE();
1994 : :
1995 [ # # ]: 0 : if (dev == NULL)
1996 : : return -ENOMEM;
1997 : :
1998 : 0 : internals = dev->data->dev_private;
1999 : 0 : rte_mempool_free(internals->ctx_pool);
2000 : 0 : internals->ctx_pool = NULL;
2001 : :
2002 : 0 : return 0;
2003 : : }
2004 : :
2005 : : static void
2006 : 0 : caam_jr_dev_infos_get(struct rte_cryptodev *dev,
2007 : : struct rte_cryptodev_info *info)
2008 : : {
2009 : 0 : struct sec_job_ring_t *internals = dev->data->dev_private;
2010 : :
2011 : 0 : PMD_INIT_FUNC_TRACE();
2012 [ # # ]: 0 : if (info != NULL) {
2013 : 0 : info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
2014 : 0 : info->feature_flags = dev->feature_flags;
2015 : 0 : info->capabilities = caam_jr_get_cryptodev_capabilities();
2016 : 0 : info->sym.max_nb_sessions = internals->max_nb_sessions;
2017 : 0 : info->driver_id = cryptodev_driver_id;
2018 : : }
2019 : 0 : }
2020 : :
2021 : : static struct rte_cryptodev_ops caam_jr_ops = {
2022 : : .dev_configure = caam_jr_dev_configure,
2023 : : .dev_start = caam_jr_dev_start,
2024 : : .dev_stop = caam_jr_dev_stop,
2025 : : .dev_close = caam_jr_dev_close,
2026 : : .dev_infos_get = caam_jr_dev_infos_get,
2027 : : .stats_get = caam_jr_stats_get,
2028 : : .stats_reset = caam_jr_stats_reset,
2029 : : .queue_pair_setup = caam_jr_queue_pair_setup,
2030 : : .queue_pair_release = caam_jr_queue_pair_release,
2031 : : .sym_session_get_size = caam_jr_sym_session_get_size,
2032 : : .sym_session_configure = caam_jr_sym_session_configure,
2033 : : .sym_session_clear = caam_jr_sym_session_clear
2034 : : };
2035 : :
2036 : : static struct rte_security_ops caam_jr_security_ops = {
2037 : : .session_create = caam_jr_security_session_create,
2038 : : .session_update = NULL,
2039 : : .session_get_size = caam_jr_security_session_get_size,
2040 : : .session_stats_get = NULL,
2041 : : .session_destroy = caam_jr_security_session_destroy,
2042 : : .set_pkt_metadata = NULL,
2043 : : .capabilities_get = caam_jr_get_security_capabilities
2044 : : };
2045 : :
2046 : : /* @brief Flush job rings of any processed descs.
2047 : : * The processed descs are silently dropped,
2048 : : * WITHOUT being notified to UA.
2049 : : */
2050 : : static void
2051 : 0 : close_job_ring(struct sec_job_ring_t *job_ring)
2052 : : {
2053 [ # # ]: 0 : if (job_ring->irq_fd != -1) {
2054 : : /* Producer index is frozen. If consumer index is not equal
2055 : : * with producer index, then we have descs to flush.
2056 : : */
2057 [ # # ]: 0 : while (job_ring->pidx != job_ring->cidx)
2058 : 0 : hw_flush_job_ring(job_ring, false, NULL);
2059 : :
2060 : : /* free the uio job ring */
2061 : 0 : free_job_ring(job_ring->irq_fd);
2062 : 0 : job_ring->irq_fd = -1;
2063 : 0 : caam_jr_dma_free(job_ring->input_ring);
2064 : 0 : caam_jr_dma_free(job_ring->output_ring);
2065 : 0 : g_job_rings_no--;
2066 : : }
2067 : 0 : }
2068 : :
2069 : : /** @brief Release the software and hardware resources tied to a job ring.
2070 : : * @param [in] job_ring The job ring
2071 : : *
2072 : : * @retval 0 for success
2073 : : * @retval -1 for error
2074 : : */
2075 : : static int
2076 : 0 : shutdown_job_ring(struct sec_job_ring_t *job_ring)
2077 : : {
2078 : : int ret = 0;
2079 : :
2080 : 0 : PMD_INIT_FUNC_TRACE();
2081 : : ASSERT(job_ring != NULL);
2082 : 0 : ret = hw_shutdown_job_ring(job_ring);
2083 [ # # ]: 0 : SEC_ASSERT(ret == 0, ret,
2084 : : "Failed to shutdown hardware job ring %p",
2085 : : job_ring);
2086 : :
2087 [ # # ]: 0 : if (job_ring->coalescing_en)
2088 : 0 : hw_job_ring_disable_coalescing(job_ring);
2089 : :
2090 [ # # ]: 0 : if (job_ring->jr_mode != SEC_NOTIFICATION_TYPE_POLL) {
2091 : 0 : ret = caam_jr_disable_irqs(job_ring->irq_fd);
2092 [ # # ]: 0 : SEC_ASSERT(ret == 0, ret,
2093 : : "Failed to disable irqs for job ring %p",
2094 : : job_ring);
2095 : : }
2096 : :
2097 : : return ret;
2098 : : }
2099 : :
2100 : : /*
2101 : : * @brief Release the resources used by the SEC user space driver.
2102 : : *
2103 : : * Reset and release SEC's job rings indicated by the User Application at
2104 : : * init_job_ring() and free any memory allocated internally.
2105 : : * Call once during application tear down.
2106 : : *
2107 : : * @note In case there are any descriptors in-flight (descriptors received by
2108 : : * SEC driver for processing and for which no response was yet provided to UA),
2109 : : * the descriptors are discarded without any notifications to User Application.
2110 : : *
2111 : : * @retval ::0 is returned for a successful execution
2112 : : * @retval ::-1 is returned if SEC driver release is in progress
2113 : : */
2114 : : static int
2115 : 0 : caam_jr_dev_uninit(struct rte_cryptodev *dev)
2116 : : {
2117 : : struct sec_job_ring_t *internals;
2118 : :
2119 : 0 : PMD_INIT_FUNC_TRACE();
2120 [ # # ]: 0 : if (dev == NULL)
2121 : : return -ENODEV;
2122 : :
2123 : 0 : internals = dev->data->dev_private;
2124 : 0 : rte_free(dev->security_ctx);
2125 : :
2126 : : /* If any descriptors in flight , poll and wait
2127 : : * until all descriptors are received and silently discarded.
2128 : : */
2129 [ # # ]: 0 : if (internals) {
2130 : 0 : shutdown_job_ring(internals);
2131 : 0 : close_job_ring(internals);
2132 : 0 : rte_mempool_free(internals->ctx_pool);
2133 : : }
2134 : :
2135 : 0 : CAAM_JR_INFO("Closing crypto device %s", dev->data->name);
2136 : :
2137 : : /* last caam jr instance) */
2138 [ # # ]: 0 : if (g_job_rings_no == 0)
2139 : 0 : g_driver_state = SEC_DRIVER_STATE_IDLE;
2140 : :
2141 : : return SEC_SUCCESS;
2142 : : }
2143 : :
2144 : : /* @brief Initialize the software and hardware resources tied to a job ring.
2145 : : * @param [in] jr_mode; Model to be used by SEC Driver to receive
2146 : : * notifications from SEC. Can be either
2147 : : * of the three: #SEC_NOTIFICATION_TYPE_NAPI
2148 : : * #SEC_NOTIFICATION_TYPE_IRQ or
2149 : : * #SEC_NOTIFICATION_TYPE_POLL
2150 : : * @param [in] NAPI_mode The NAPI work mode to configure a job ring at
2151 : : * startup. Used only when #SEC_NOTIFICATION_TYPE
2152 : : * is set to #SEC_NOTIFICATION_TYPE_NAPI.
2153 : : * @param [in] irq_coalescing_timer This value determines the maximum
2154 : : * amount of time after processing a
2155 : : * descriptor before raising an interrupt.
2156 : : * @param [in] irq_coalescing_count This value determines how many
2157 : : * descriptors are completed before
2158 : : * raising an interrupt.
2159 : : * @param [in] reg_base_addr, The job ring base address register
2160 : : * @param [in] irq_id The job ring interrupt identification number.
2161 : : * @retval job_ring_handle for successful job ring configuration
2162 : : * @retval NULL on error
2163 : : *
2164 : : */
2165 : : static void *
2166 : 0 : init_job_ring(void *reg_base_addr, int irq_id)
2167 : : {
2168 : : struct sec_job_ring_t *job_ring = NULL;
2169 : : int i, ret = 0;
2170 : : int jr_mode = SEC_NOTIFICATION_TYPE_POLL;
2171 : : int napi_mode = 0;
2172 : : int irq_coalescing_timer = 0;
2173 : : int irq_coalescing_count = 0;
2174 : :
2175 [ # # ]: 0 : for (i = 0; i < MAX_SEC_JOB_RINGS; i++) {
2176 [ # # ]: 0 : if (g_job_rings[i].irq_fd == -1) {
2177 : 0 : job_ring = &g_job_rings[i];
2178 : 0 : g_job_rings_no++;
2179 : 0 : break;
2180 : : }
2181 : : }
2182 [ # # ]: 0 : if (job_ring == NULL) {
2183 : 0 : CAAM_JR_ERR("No free job ring\n");
2184 : 0 : return NULL;
2185 : : }
2186 : :
2187 : 0 : job_ring->register_base_addr = reg_base_addr;
2188 : 0 : job_ring->jr_mode = jr_mode;
2189 : 0 : job_ring->napi_mode = 0;
2190 : 0 : job_ring->irq_fd = irq_id;
2191 : :
2192 : : /* Allocate mem for input and output ring */
2193 : :
2194 : : /* Allocate memory for input ring */
2195 : 0 : job_ring->input_ring = caam_jr_dma_mem_alloc(L1_CACHE_BYTES,
2196 : : SEC_DMA_MEM_INPUT_RING_SIZE);
2197 : : memset(job_ring->input_ring, 0, SEC_DMA_MEM_INPUT_RING_SIZE);
2198 : :
2199 : : /* Allocate memory for output ring */
2200 : 0 : job_ring->output_ring = caam_jr_dma_mem_alloc(L1_CACHE_BYTES,
2201 : : SEC_DMA_MEM_OUTPUT_RING_SIZE);
2202 : : memset(job_ring->output_ring, 0, SEC_DMA_MEM_OUTPUT_RING_SIZE);
2203 : :
2204 : : /* Reset job ring in SEC hw and configure job ring registers */
2205 : 0 : ret = hw_reset_job_ring(job_ring);
2206 [ # # ]: 0 : if (ret != 0) {
2207 : 0 : CAAM_JR_ERR("Failed to reset hardware job ring");
2208 : 0 : goto cleanup;
2209 : : }
2210 : :
2211 : : if (jr_mode == SEC_NOTIFICATION_TYPE_NAPI) {
2212 : : /* When SEC US driver works in NAPI mode, the UA can select
2213 : : * if the driver starts with IRQs on or off.
2214 : : */
2215 : : if (napi_mode == SEC_STARTUP_INTERRUPT_MODE) {
2216 : : CAAM_JR_INFO("Enabling DONE IRQ generationon job ring - %p",
2217 : : job_ring);
2218 : : ret = caam_jr_enable_irqs(job_ring->irq_fd);
2219 : : if (ret != 0) {
2220 : : CAAM_JR_ERR("Failed to enable irqs for job ring");
2221 : : goto cleanup;
2222 : : }
2223 : : }
2224 : : } else if (jr_mode == SEC_NOTIFICATION_TYPE_IRQ) {
2225 : : /* When SEC US driver works in pure interrupt mode,
2226 : : * IRQ's are always enabled.
2227 : : */
2228 : : CAAM_JR_INFO("Enabling DONE IRQ generation on job ring - %p",
2229 : : job_ring);
2230 : : ret = caam_jr_enable_irqs(job_ring->irq_fd);
2231 : : if (ret != 0) {
2232 : : CAAM_JR_ERR("Failed to enable irqs for job ring");
2233 : : goto cleanup;
2234 : : }
2235 : : }
2236 : : if (irq_coalescing_timer || irq_coalescing_count) {
2237 : : hw_job_ring_set_coalescing_param(job_ring,
2238 : : irq_coalescing_timer,
2239 : : irq_coalescing_count);
2240 : :
2241 : : hw_job_ring_enable_coalescing(job_ring);
2242 : : job_ring->coalescing_en = 1;
2243 : : }
2244 : :
2245 : 0 : job_ring->jr_state = SEC_JOB_RING_STATE_STARTED;
2246 : 0 : job_ring->max_nb_queue_pairs = RTE_CAAM_MAX_NB_SEC_QPS;
2247 : 0 : job_ring->max_nb_sessions = RTE_CAAM_JR_PMD_MAX_NB_SESSIONS;
2248 : :
2249 : 0 : return job_ring;
2250 : : cleanup:
2251 : 0 : caam_jr_dma_free(job_ring->output_ring);
2252 : 0 : caam_jr_dma_free(job_ring->input_ring);
2253 : 0 : return NULL;
2254 : : }
2255 : :
2256 : :
2257 : : static int
2258 : 0 : caam_jr_dev_init(const char *name,
2259 : : struct rte_vdev_device *vdev,
2260 : : struct rte_cryptodev_pmd_init_params *init_params)
2261 : : {
2262 : : struct rte_cryptodev *dev;
2263 : : struct rte_security_ctx *security_instance;
2264 : : struct uio_job_ring *job_ring;
2265 : : char str[RTE_CRYPTODEV_NAME_MAX_LEN];
2266 : :
2267 : 0 : PMD_INIT_FUNC_TRACE();
2268 : :
2269 : : /* Validate driver state */
2270 [ # # ]: 0 : if (g_driver_state == SEC_DRIVER_STATE_IDLE) {
2271 : 0 : g_job_rings_max = sec_configure();
2272 [ # # ]: 0 : if (!g_job_rings_max) {
2273 : 0 : CAAM_JR_ERR("No job ring detected on UIO !!!!");
2274 : 0 : return -1;
2275 : : }
2276 : : /* Update driver state */
2277 : 0 : g_driver_state = SEC_DRIVER_STATE_STARTED;
2278 : : }
2279 : :
2280 [ # # ]: 0 : if (g_job_rings_no >= g_job_rings_max) {
2281 : 0 : CAAM_JR_ERR("No more job rings available max=%d!!!!",
2282 : : g_job_rings_max);
2283 : 0 : return -1;
2284 : : }
2285 : :
2286 : 0 : job_ring = config_job_ring();
2287 [ # # ]: 0 : if (job_ring == NULL) {
2288 : 0 : CAAM_JR_ERR("failed to create job ring");
2289 : 0 : goto init_error;
2290 : : }
2291 : :
2292 : 0 : snprintf(str, sizeof(str), "caam_jr%d", job_ring->jr_id);
2293 : :
2294 : 0 : dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params);
2295 [ # # ]: 0 : if (dev == NULL) {
2296 : 0 : CAAM_JR_ERR("failed to create cryptodev vdev");
2297 : 0 : goto cleanup;
2298 : : }
2299 : : /*TODO free it during teardown*/
2300 : 0 : dev->data->dev_private = init_job_ring(job_ring->register_base_addr,
2301 : : job_ring->uio_fd);
2302 : :
2303 [ # # ]: 0 : if (!dev->data->dev_private) {
2304 : 0 : CAAM_JR_ERR("Ring memory allocation failed\n");
2305 : 0 : goto cleanup2;
2306 : : }
2307 : :
2308 : 0 : dev->driver_id = cryptodev_driver_id;
2309 : 0 : dev->dev_ops = &caam_jr_ops;
2310 : :
2311 : : /* register rx/tx burst functions for data path */
2312 : 0 : dev->dequeue_burst = caam_jr_dequeue_burst;
2313 : 0 : dev->enqueue_burst = caam_jr_enqueue_burst;
2314 : 0 : dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
2315 : : RTE_CRYPTODEV_FF_HW_ACCELERATED |
2316 : : RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
2317 : : RTE_CRYPTODEV_FF_SECURITY |
2318 : : RTE_CRYPTODEV_FF_IN_PLACE_SGL |
2319 : : RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT |
2320 : : RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
2321 : : RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT |
2322 : : RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT;
2323 : :
2324 : : /* For secondary processes, we don't initialise any further as primary
2325 : : * has already done this work. Only check we don't need a different
2326 : : * RX function
2327 : : */
2328 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
2329 : 0 : CAAM_JR_WARN("Device already init by primary process");
2330 : 0 : return 0;
2331 : : }
2332 : :
2333 : : /*TODO free it during teardown*/
2334 : 0 : security_instance = rte_malloc("caam_jr",
2335 : : sizeof(struct rte_security_ctx), 0);
2336 [ # # ]: 0 : if (security_instance == NULL) {
2337 : 0 : CAAM_JR_ERR("memory allocation failed\n");
2338 : : //todo error handling.
2339 : 0 : goto cleanup2;
2340 : : }
2341 : :
2342 : 0 : security_instance->device = (void *)dev;
2343 : 0 : security_instance->ops = &caam_jr_security_ops;
2344 : 0 : security_instance->sess_cnt = 0;
2345 : 0 : dev->security_ctx = security_instance;
2346 : :
2347 : 0 : rte_cryptodev_pmd_probing_finish(dev);
2348 : :
2349 : 0 : RTE_LOG(INFO, PMD, "%s cryptodev init\n", dev->data->name);
2350 : :
2351 : 0 : return 0;
2352 : :
2353 : 0 : cleanup2:
2354 : 0 : caam_jr_dev_uninit(dev);
2355 : 0 : rte_cryptodev_pmd_release_device(dev);
2356 : 0 : cleanup:
2357 : 0 : free_job_ring(job_ring->uio_fd);
2358 : 0 : init_error:
2359 : 0 : CAAM_JR_ERR("driver %s: cryptodev_caam_jr_create failed",
2360 : : init_params->name);
2361 : :
2362 : 0 : return -ENXIO;
2363 : : }
2364 : :
2365 : : /** Initialise CAAM JR crypto device */
2366 : : static int
2367 : 0 : cryptodev_caam_jr_probe(struct rte_vdev_device *vdev)
2368 : : {
2369 : : int ret;
2370 : :
2371 : 0 : struct rte_cryptodev_pmd_init_params init_params = {
2372 : : "",
2373 : : sizeof(struct sec_job_ring_t),
2374 [ # # ]: 0 : rte_socket_id(),
2375 : : RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
2376 : : };
2377 : : const char *name;
2378 : : const char *input_args;
2379 : :
2380 : : name = rte_vdev_device_name(vdev);
2381 : : if (name == NULL)
2382 : : return -EINVAL;
2383 : :
2384 : : input_args = rte_vdev_device_args(vdev);
2385 : 0 : rte_cryptodev_pmd_parse_input_args(&init_params, input_args);
2386 : :
2387 : : ret = of_init();
2388 [ # # ]: 0 : if (ret) {
2389 : 0 : RTE_LOG(ERR, PMD,
2390 : : "of_init failed\n");
2391 : 0 : return -EINVAL;
2392 : : }
2393 : : /* if sec device version is not configured */
2394 [ # # ]: 0 : if (!rta_get_sec_era()) {
2395 : : const struct device_node *caam_node;
2396 : :
2397 [ # # ]: 0 : for_each_compatible_node(caam_node, NULL, "fsl,sec-v4.0") {
2398 : 0 : const uint32_t *prop = of_get_property(caam_node,
2399 : : "fsl,sec-era",
2400 : : NULL);
2401 [ # # ]: 0 : if (prop) {
2402 : 0 : rta_set_sec_era(
2403 [ # # ]: 0 : INTL_SEC_ERA(rte_be_to_cpu_32(*prop)));
2404 : 0 : break;
2405 : : }
2406 : : }
2407 : : }
2408 : : #ifdef RTE_LIBRTE_PMD_CAAM_JR_BE
2409 : : if (rta_get_sec_era() > RTA_SEC_ERA_8) {
2410 : : RTE_LOG(ERR, PMD,
2411 : : "CAAM is compiled in BE mode for device with sec era > 8???\n");
2412 : : return -EINVAL;
2413 : : }
2414 : : #endif
2415 : :
2416 : 0 : return caam_jr_dev_init(name, vdev, &init_params);
2417 : : }
2418 : :
2419 : : /** Uninitialise CAAM JR crypto device */
2420 : : static int
2421 [ # # ]: 0 : cryptodev_caam_jr_remove(struct rte_vdev_device *vdev)
2422 : : {
2423 : : struct rte_cryptodev *cryptodev;
2424 : : const char *name;
2425 : :
2426 : : name = rte_vdev_device_name(vdev);
2427 : : if (name == NULL)
2428 : : return -EINVAL;
2429 : :
2430 : 0 : cryptodev = rte_cryptodev_pmd_get_named_dev(name);
2431 [ # # ]: 0 : if (cryptodev == NULL)
2432 : : return -ENODEV;
2433 : :
2434 : 0 : caam_jr_dev_uninit(cryptodev);
2435 : :
2436 : 0 : return rte_cryptodev_pmd_destroy(cryptodev);
2437 : : }
2438 : :
2439 : : static void
2440 : : sec_job_rings_init(void)
2441 : : {
2442 : : int i;
2443 : :
2444 [ + + ]: 1175 : for (i = 0; i < MAX_SEC_JOB_RINGS; i++)
2445 : 940 : g_job_rings[i].irq_fd = -1;
2446 : : }
2447 : :
2448 : : static struct rte_vdev_driver cryptodev_caam_jr_drv = {
2449 : : .probe = cryptodev_caam_jr_probe,
2450 : : .remove = cryptodev_caam_jr_remove
2451 : : };
2452 : :
2453 : : static struct cryptodev_driver caam_jr_crypto_drv;
2454 : :
2455 : 235 : RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_CAAM_JR_PMD, cryptodev_caam_jr_drv);
2456 : : RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_CAAM_JR_PMD,
2457 : : "max_nb_queue_pairs=<int>"
2458 : : "socket_id=<int>");
2459 : 235 : RTE_PMD_REGISTER_CRYPTO_DRIVER(caam_jr_crypto_drv, cryptodev_caam_jr_drv.driver,
2460 : : cryptodev_driver_id);
2461 : :
2462 : 235 : RTE_INIT(caam_jr_init)
2463 : : {
2464 : 235 : sec_uio_job_rings_init();
2465 : : sec_job_rings_init();
2466 : 235 : }
2467 : :
2468 [ - + ]: 235 : RTE_LOG_REGISTER(caam_jr_logtype, pmd.crypto.caam, NOTICE);
|