14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang * Copyright(C) 2019 Marvell International Ltd.
34418919fSjohnjiang */
44418919fSjohnjiang
54418919fSjohnjiang #include <rte_crypto.h>
64418919fSjohnjiang #include <rte_cryptodev.h>
74418919fSjohnjiang #include <rte_cycles.h>
84418919fSjohnjiang #include <rte_errno.h>
94418919fSjohnjiang
104418919fSjohnjiang #include "nitrox_sym_reqmgr.h"
114418919fSjohnjiang #include "nitrox_logs.h"
124418919fSjohnjiang
134418919fSjohnjiang #define MAX_SGBUF_CNT 16
144418919fSjohnjiang #define MAX_SGCOMP_CNT 5
154418919fSjohnjiang /* SLC_STORE_INFO */
164418919fSjohnjiang #define MIN_UDD_LEN 16
174418919fSjohnjiang /* PKT_IN_HDR + SLC_STORE_INFO */
184418919fSjohnjiang #define FDATA_SIZE 32
194418919fSjohnjiang /* Base destination port for the solicited requests */
204418919fSjohnjiang #define SOLICIT_BASE_DPORT 256
214418919fSjohnjiang #define PENDING_SIG 0xFFFFFFFFFFFFFFFFUL
224418919fSjohnjiang #define CMD_TIMEOUT 2
234418919fSjohnjiang
244418919fSjohnjiang struct gphdr {
254418919fSjohnjiang uint16_t param0;
264418919fSjohnjiang uint16_t param1;
274418919fSjohnjiang uint16_t param2;
284418919fSjohnjiang uint16_t param3;
294418919fSjohnjiang };
304418919fSjohnjiang
314418919fSjohnjiang union pkt_instr_hdr {
324418919fSjohnjiang uint64_t value;
334418919fSjohnjiang struct {
344418919fSjohnjiang #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
354418919fSjohnjiang uint64_t raz_48_63 : 16;
364418919fSjohnjiang uint64_t g : 1;
374418919fSjohnjiang uint64_t gsz : 7;
384418919fSjohnjiang uint64_t ihi : 1;
394418919fSjohnjiang uint64_t ssz : 7;
404418919fSjohnjiang uint64_t raz_30_31 : 2;
414418919fSjohnjiang uint64_t fsz : 6;
424418919fSjohnjiang uint64_t raz_16_23 : 8;
434418919fSjohnjiang uint64_t tlen : 16;
444418919fSjohnjiang #else
454418919fSjohnjiang uint64_t tlen : 16;
464418919fSjohnjiang uint64_t raz_16_23 : 8;
474418919fSjohnjiang uint64_t fsz : 6;
484418919fSjohnjiang uint64_t raz_30_31 : 2;
494418919fSjohnjiang uint64_t ssz : 7;
504418919fSjohnjiang uint64_t ihi : 1;
514418919fSjohnjiang uint64_t gsz : 7;
524418919fSjohnjiang uint64_t g : 1;
534418919fSjohnjiang uint64_t raz_48_63 : 16;
544418919fSjohnjiang #endif
554418919fSjohnjiang } s;
564418919fSjohnjiang };
574418919fSjohnjiang
584418919fSjohnjiang union pkt_hdr {
594418919fSjohnjiang uint64_t value[2];
604418919fSjohnjiang struct {
614418919fSjohnjiang #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
624418919fSjohnjiang uint64_t opcode : 8;
634418919fSjohnjiang uint64_t arg : 8;
644418919fSjohnjiang uint64_t ctxc : 2;
654418919fSjohnjiang uint64_t unca : 1;
664418919fSjohnjiang uint64_t raz_44 : 1;
674418919fSjohnjiang uint64_t info : 3;
684418919fSjohnjiang uint64_t destport : 9;
694418919fSjohnjiang uint64_t unc : 8;
704418919fSjohnjiang uint64_t raz_19_23 : 5;
714418919fSjohnjiang uint64_t grp : 3;
724418919fSjohnjiang uint64_t raz_15 : 1;
734418919fSjohnjiang uint64_t ctxl : 7;
744418919fSjohnjiang uint64_t uddl : 8;
754418919fSjohnjiang #else
764418919fSjohnjiang uint64_t uddl : 8;
774418919fSjohnjiang uint64_t ctxl : 7;
784418919fSjohnjiang uint64_t raz_15 : 1;
794418919fSjohnjiang uint64_t grp : 3;
804418919fSjohnjiang uint64_t raz_19_23 : 5;
814418919fSjohnjiang uint64_t unc : 8;
824418919fSjohnjiang uint64_t destport : 9;
834418919fSjohnjiang uint64_t info : 3;
844418919fSjohnjiang uint64_t raz_44 : 1;
854418919fSjohnjiang uint64_t unca : 1;
864418919fSjohnjiang uint64_t ctxc : 2;
874418919fSjohnjiang uint64_t arg : 8;
884418919fSjohnjiang uint64_t opcode : 8;
894418919fSjohnjiang #endif
904418919fSjohnjiang uint64_t ctxp;
914418919fSjohnjiang } s;
924418919fSjohnjiang };
934418919fSjohnjiang
944418919fSjohnjiang union slc_store_info {
954418919fSjohnjiang uint64_t value[2];
964418919fSjohnjiang struct {
974418919fSjohnjiang #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
984418919fSjohnjiang uint64_t raz_39_63 : 25;
994418919fSjohnjiang uint64_t ssz : 7;
1004418919fSjohnjiang uint64_t raz_0_31 : 32;
1014418919fSjohnjiang #else
1024418919fSjohnjiang uint64_t raz_0_31 : 32;
1034418919fSjohnjiang uint64_t ssz : 7;
1044418919fSjohnjiang uint64_t raz_39_63 : 25;
1054418919fSjohnjiang #endif
1064418919fSjohnjiang uint64_t rptr;
1074418919fSjohnjiang } s;
1084418919fSjohnjiang };
1094418919fSjohnjiang
1104418919fSjohnjiang struct nps_pkt_instr {
1114418919fSjohnjiang uint64_t dptr0;
1124418919fSjohnjiang union pkt_instr_hdr ih;
1134418919fSjohnjiang union pkt_hdr irh;
1144418919fSjohnjiang union slc_store_info slc;
1154418919fSjohnjiang uint64_t fdata[2];
1164418919fSjohnjiang };
1174418919fSjohnjiang
1184418919fSjohnjiang struct resp_hdr {
1194418919fSjohnjiang uint64_t orh;
1204418919fSjohnjiang uint64_t completion;
1214418919fSjohnjiang };
1224418919fSjohnjiang
1234418919fSjohnjiang struct nitrox_sglist {
1244418919fSjohnjiang uint16_t len;
1254418919fSjohnjiang uint16_t raz0;
1264418919fSjohnjiang uint32_t raz1;
1274418919fSjohnjiang rte_iova_t iova;
1284418919fSjohnjiang void *virt;
1294418919fSjohnjiang };
1304418919fSjohnjiang
1314418919fSjohnjiang struct nitrox_sgcomp {
1324418919fSjohnjiang uint16_t len[4];
1334418919fSjohnjiang uint64_t iova[4];
1344418919fSjohnjiang };
1354418919fSjohnjiang
1364418919fSjohnjiang struct nitrox_sgtable {
1374418919fSjohnjiang uint8_t map_bufs_cnt;
1384418919fSjohnjiang uint8_t nr_sgcomp;
1394418919fSjohnjiang uint16_t total_bytes;
1404418919fSjohnjiang
1414418919fSjohnjiang struct nitrox_sglist sglist[MAX_SGBUF_CNT];
1424418919fSjohnjiang struct nitrox_sgcomp sgcomp[MAX_SGCOMP_CNT];
1434418919fSjohnjiang };
1444418919fSjohnjiang
1454418919fSjohnjiang struct iv {
1464418919fSjohnjiang uint8_t *virt;
1474418919fSjohnjiang rte_iova_t iova;
1484418919fSjohnjiang uint16_t len;
1494418919fSjohnjiang };
1504418919fSjohnjiang
1514418919fSjohnjiang struct nitrox_softreq {
1524418919fSjohnjiang struct nitrox_crypto_ctx *ctx;
1534418919fSjohnjiang struct rte_crypto_op *op;
1544418919fSjohnjiang struct gphdr gph;
1554418919fSjohnjiang struct nps_pkt_instr instr;
1564418919fSjohnjiang struct resp_hdr resp;
1574418919fSjohnjiang struct nitrox_sgtable in;
1584418919fSjohnjiang struct nitrox_sgtable out;
1594418919fSjohnjiang struct iv iv;
1604418919fSjohnjiang uint64_t timeout;
1614418919fSjohnjiang rte_iova_t dptr;
1624418919fSjohnjiang rte_iova_t rptr;
1634418919fSjohnjiang rte_iova_t iova;
1644418919fSjohnjiang };
1654418919fSjohnjiang
1664418919fSjohnjiang static void
softreq_init(struct nitrox_softreq * sr,rte_iova_t iova)1674418919fSjohnjiang softreq_init(struct nitrox_softreq *sr, rte_iova_t iova)
1684418919fSjohnjiang {
1694418919fSjohnjiang memset(sr, 0, sizeof(*sr));
1704418919fSjohnjiang sr->iova = iova;
1714418919fSjohnjiang }
1724418919fSjohnjiang
1734418919fSjohnjiang /*
1744418919fSjohnjiang * 64-Byte Instruction Format
1754418919fSjohnjiang *
1764418919fSjohnjiang * ----------------------
1774418919fSjohnjiang * | DPTR0 | 8 bytes
1784418919fSjohnjiang * ----------------------
1794418919fSjohnjiang * | PKT_IN_INSTR_HDR | 8 bytes
1804418919fSjohnjiang * ----------------------
1814418919fSjohnjiang * | PKT_IN_HDR | 16 bytes
1824418919fSjohnjiang * ----------------------
1834418919fSjohnjiang * | SLC_INFO | 16 bytes
1844418919fSjohnjiang * ----------------------
1854418919fSjohnjiang * | Front data | 16 bytes
1864418919fSjohnjiang * ----------------------
1874418919fSjohnjiang */
1884418919fSjohnjiang static void
create_se_instr(struct nitrox_softreq * sr,uint8_t qno)1894418919fSjohnjiang create_se_instr(struct nitrox_softreq *sr, uint8_t qno)
1904418919fSjohnjiang {
1914418919fSjohnjiang struct nitrox_crypto_ctx *ctx = sr->ctx;
1924418919fSjohnjiang rte_iova_t ctx_handle;
1934418919fSjohnjiang
1944418919fSjohnjiang /* fill the packet instruction */
1954418919fSjohnjiang /* word 0 */
1964418919fSjohnjiang sr->instr.dptr0 = rte_cpu_to_be_64(sr->dptr);
1974418919fSjohnjiang
1984418919fSjohnjiang /* word 1 */
1994418919fSjohnjiang sr->instr.ih.value = 0;
2004418919fSjohnjiang sr->instr.ih.s.g = 1;
2014418919fSjohnjiang sr->instr.ih.s.gsz = sr->in.map_bufs_cnt;
2024418919fSjohnjiang sr->instr.ih.s.ssz = sr->out.map_bufs_cnt;
2034418919fSjohnjiang sr->instr.ih.s.fsz = FDATA_SIZE + sizeof(struct gphdr);
2044418919fSjohnjiang sr->instr.ih.s.tlen = sr->instr.ih.s.fsz + sr->in.total_bytes;
2054418919fSjohnjiang sr->instr.ih.value = rte_cpu_to_be_64(sr->instr.ih.value);
2064418919fSjohnjiang
2074418919fSjohnjiang /* word 2 */
2084418919fSjohnjiang sr->instr.irh.value[0] = 0;
2094418919fSjohnjiang sr->instr.irh.s.uddl = MIN_UDD_LEN;
2104418919fSjohnjiang /* context length in 64-bit words */
2114418919fSjohnjiang sr->instr.irh.s.ctxl = RTE_ALIGN_MUL_CEIL(sizeof(ctx->fctx), 8) / 8;
2124418919fSjohnjiang /* offset from solicit base port 256 */
2134418919fSjohnjiang sr->instr.irh.s.destport = SOLICIT_BASE_DPORT + qno;
2144418919fSjohnjiang /* Invalid context cache */
2154418919fSjohnjiang sr->instr.irh.s.ctxc = 0x3;
2164418919fSjohnjiang sr->instr.irh.s.arg = ctx->req_op;
2174418919fSjohnjiang sr->instr.irh.s.opcode = ctx->opcode;
2184418919fSjohnjiang sr->instr.irh.value[0] = rte_cpu_to_be_64(sr->instr.irh.value[0]);
2194418919fSjohnjiang
2204418919fSjohnjiang /* word 3 */
2214418919fSjohnjiang ctx_handle = ctx->iova + offsetof(struct nitrox_crypto_ctx, fctx);
2224418919fSjohnjiang sr->instr.irh.s.ctxp = rte_cpu_to_be_64(ctx_handle);
2234418919fSjohnjiang
2244418919fSjohnjiang /* word 4 */
2254418919fSjohnjiang sr->instr.slc.value[0] = 0;
2264418919fSjohnjiang sr->instr.slc.s.ssz = sr->out.map_bufs_cnt;
2274418919fSjohnjiang sr->instr.slc.value[0] = rte_cpu_to_be_64(sr->instr.slc.value[0]);
2284418919fSjohnjiang
2294418919fSjohnjiang /* word 5 */
2304418919fSjohnjiang sr->instr.slc.s.rptr = rte_cpu_to_be_64(sr->rptr);
2314418919fSjohnjiang /*
2324418919fSjohnjiang * No conversion for front data,
2334418919fSjohnjiang * It goes into payload
2344418919fSjohnjiang * put GP Header in front data
2354418919fSjohnjiang */
2364418919fSjohnjiang memcpy(&sr->instr.fdata[0], &sr->gph, sizeof(sr->instr.fdata[0]));
2374418919fSjohnjiang sr->instr.fdata[1] = 0;
2384418919fSjohnjiang }
2394418919fSjohnjiang
2404418919fSjohnjiang static void
softreq_copy_iv(struct nitrox_softreq * sr,uint8_t salt_size)241*2d9fd380Sjfb8856606 softreq_copy_iv(struct nitrox_softreq *sr, uint8_t salt_size)
2424418919fSjohnjiang {
243*2d9fd380Sjfb8856606 uint16_t offset = sr->ctx->iv.offset + salt_size;
2444418919fSjohnjiang
245*2d9fd380Sjfb8856606 sr->iv.virt = rte_crypto_op_ctod_offset(sr->op, uint8_t *, offset);
246*2d9fd380Sjfb8856606 sr->iv.iova = rte_crypto_op_ctophys_offset(sr->op, offset);
247*2d9fd380Sjfb8856606 sr->iv.len = sr->ctx->iv.length - salt_size;
2484418919fSjohnjiang }
2494418919fSjohnjiang
2504418919fSjohnjiang static void
fill_sglist(struct nitrox_sgtable * sgtbl,uint16_t len,rte_iova_t iova,void * virt)2514418919fSjohnjiang fill_sglist(struct nitrox_sgtable *sgtbl, uint16_t len, rte_iova_t iova,
2524418919fSjohnjiang void *virt)
2534418919fSjohnjiang {
2544418919fSjohnjiang struct nitrox_sglist *sglist = sgtbl->sglist;
2554418919fSjohnjiang uint8_t cnt = sgtbl->map_bufs_cnt;
2564418919fSjohnjiang
2574418919fSjohnjiang if (unlikely(!len))
2584418919fSjohnjiang return;
2594418919fSjohnjiang
2604418919fSjohnjiang sglist[cnt].len = len;
2614418919fSjohnjiang sglist[cnt].iova = iova;
2624418919fSjohnjiang sglist[cnt].virt = virt;
2634418919fSjohnjiang sgtbl->total_bytes += len;
2644418919fSjohnjiang cnt++;
2654418919fSjohnjiang sgtbl->map_bufs_cnt = cnt;
2664418919fSjohnjiang }
2674418919fSjohnjiang
2684418919fSjohnjiang static int
create_sglist_from_mbuf(struct nitrox_sgtable * sgtbl,struct rte_mbuf * mbuf,uint32_t off,int datalen)2694418919fSjohnjiang create_sglist_from_mbuf(struct nitrox_sgtable *sgtbl, struct rte_mbuf *mbuf,
2704418919fSjohnjiang uint32_t off, int datalen)
2714418919fSjohnjiang {
2724418919fSjohnjiang struct nitrox_sglist *sglist = sgtbl->sglist;
2734418919fSjohnjiang uint8_t cnt = sgtbl->map_bufs_cnt;
2744418919fSjohnjiang struct rte_mbuf *m;
2754418919fSjohnjiang int mlen;
2764418919fSjohnjiang
2774418919fSjohnjiang if (unlikely(datalen <= 0))
2784418919fSjohnjiang return 0;
2794418919fSjohnjiang
2804418919fSjohnjiang for (m = mbuf; m && off > rte_pktmbuf_data_len(m); m = m->next)
2814418919fSjohnjiang off -= rte_pktmbuf_data_len(m);
2824418919fSjohnjiang
2834418919fSjohnjiang if (unlikely(!m))
2844418919fSjohnjiang return -EIO;
2854418919fSjohnjiang
2864418919fSjohnjiang mlen = rte_pktmbuf_data_len(m) - off;
2874418919fSjohnjiang if (datalen <= mlen)
2884418919fSjohnjiang mlen = datalen;
2894418919fSjohnjiang sglist[cnt].len = mlen;
290*2d9fd380Sjfb8856606 sglist[cnt].iova = rte_pktmbuf_iova_offset(m, off);
2914418919fSjohnjiang sglist[cnt].virt = rte_pktmbuf_mtod_offset(m, uint8_t *, off);
2924418919fSjohnjiang sgtbl->total_bytes += mlen;
2934418919fSjohnjiang cnt++;
2944418919fSjohnjiang datalen -= mlen;
2954418919fSjohnjiang for (m = m->next; m && datalen; m = m->next) {
2964418919fSjohnjiang mlen = rte_pktmbuf_data_len(m) < datalen ?
2974418919fSjohnjiang rte_pktmbuf_data_len(m) : datalen;
2984418919fSjohnjiang sglist[cnt].len = mlen;
299*2d9fd380Sjfb8856606 sglist[cnt].iova = rte_pktmbuf_iova(m);
3004418919fSjohnjiang sglist[cnt].virt = rte_pktmbuf_mtod(m, uint8_t *);
3014418919fSjohnjiang sgtbl->total_bytes += mlen;
3024418919fSjohnjiang cnt++;
3034418919fSjohnjiang datalen -= mlen;
3044418919fSjohnjiang }
3054418919fSjohnjiang
3064418919fSjohnjiang RTE_VERIFY(cnt <= MAX_SGBUF_CNT);
3074418919fSjohnjiang sgtbl->map_bufs_cnt = cnt;
3084418919fSjohnjiang return 0;
3094418919fSjohnjiang }
3104418919fSjohnjiang
3114418919fSjohnjiang static void
create_sgcomp(struct nitrox_sgtable * sgtbl)3124418919fSjohnjiang create_sgcomp(struct nitrox_sgtable *sgtbl)
3134418919fSjohnjiang {
3144418919fSjohnjiang int i, j, nr_sgcomp;
3154418919fSjohnjiang struct nitrox_sgcomp *sgcomp = sgtbl->sgcomp;
3164418919fSjohnjiang struct nitrox_sglist *sglist = sgtbl->sglist;
3174418919fSjohnjiang
3184418919fSjohnjiang nr_sgcomp = RTE_ALIGN_MUL_CEIL(sgtbl->map_bufs_cnt, 4) / 4;
3194418919fSjohnjiang sgtbl->nr_sgcomp = nr_sgcomp;
3204418919fSjohnjiang for (i = 0; i < nr_sgcomp; i++, sgcomp++) {
3214418919fSjohnjiang for (j = 0; j < 4; j++, sglist++) {
3224418919fSjohnjiang sgcomp->len[j] = rte_cpu_to_be_16(sglist->len);
3234418919fSjohnjiang sgcomp->iova[j] = rte_cpu_to_be_64(sglist->iova);
3244418919fSjohnjiang }
3254418919fSjohnjiang }
3264418919fSjohnjiang }
3274418919fSjohnjiang
3284418919fSjohnjiang static int
create_cipher_inbuf(struct nitrox_softreq * sr)329*2d9fd380Sjfb8856606 create_cipher_inbuf(struct nitrox_softreq *sr)
330*2d9fd380Sjfb8856606 {
331*2d9fd380Sjfb8856606 int err;
332*2d9fd380Sjfb8856606 struct rte_crypto_op *op = sr->op;
333*2d9fd380Sjfb8856606
334*2d9fd380Sjfb8856606 fill_sglist(&sr->in, sr->iv.len, sr->iv.iova, sr->iv.virt);
335*2d9fd380Sjfb8856606 err = create_sglist_from_mbuf(&sr->in, op->sym->m_src,
336*2d9fd380Sjfb8856606 op->sym->cipher.data.offset,
337*2d9fd380Sjfb8856606 op->sym->cipher.data.length);
338*2d9fd380Sjfb8856606 if (unlikely(err))
339*2d9fd380Sjfb8856606 return err;
340*2d9fd380Sjfb8856606
341*2d9fd380Sjfb8856606 create_sgcomp(&sr->in);
342*2d9fd380Sjfb8856606 sr->dptr = sr->iova + offsetof(struct nitrox_softreq, in.sgcomp);
343*2d9fd380Sjfb8856606
344*2d9fd380Sjfb8856606 return 0;
345*2d9fd380Sjfb8856606 }
346*2d9fd380Sjfb8856606
347*2d9fd380Sjfb8856606 static int
create_cipher_outbuf(struct nitrox_softreq * sr)348*2d9fd380Sjfb8856606 create_cipher_outbuf(struct nitrox_softreq *sr)
349*2d9fd380Sjfb8856606 {
350*2d9fd380Sjfb8856606 struct rte_crypto_op *op = sr->op;
351*2d9fd380Sjfb8856606 int err, cnt = 0;
352*2d9fd380Sjfb8856606 struct rte_mbuf *m_dst = op->sym->m_dst ? op->sym->m_dst :
353*2d9fd380Sjfb8856606 op->sym->m_src;
354*2d9fd380Sjfb8856606
355*2d9fd380Sjfb8856606 sr->resp.orh = PENDING_SIG;
356*2d9fd380Sjfb8856606 sr->out.sglist[cnt].len = sizeof(sr->resp.orh);
357*2d9fd380Sjfb8856606 sr->out.sglist[cnt].iova = sr->iova + offsetof(struct nitrox_softreq,
358*2d9fd380Sjfb8856606 resp.orh);
359*2d9fd380Sjfb8856606 sr->out.sglist[cnt].virt = &sr->resp.orh;
360*2d9fd380Sjfb8856606 cnt++;
361*2d9fd380Sjfb8856606
362*2d9fd380Sjfb8856606 sr->out.map_bufs_cnt = cnt;
363*2d9fd380Sjfb8856606 fill_sglist(&sr->out, sr->iv.len, sr->iv.iova, sr->iv.virt);
364*2d9fd380Sjfb8856606 err = create_sglist_from_mbuf(&sr->out, m_dst,
365*2d9fd380Sjfb8856606 op->sym->cipher.data.offset,
366*2d9fd380Sjfb8856606 op->sym->cipher.data.length);
367*2d9fd380Sjfb8856606 if (unlikely(err))
368*2d9fd380Sjfb8856606 return err;
369*2d9fd380Sjfb8856606
370*2d9fd380Sjfb8856606 cnt = sr->out.map_bufs_cnt;
371*2d9fd380Sjfb8856606 sr->resp.completion = PENDING_SIG;
372*2d9fd380Sjfb8856606 sr->out.sglist[cnt].len = sizeof(sr->resp.completion);
373*2d9fd380Sjfb8856606 sr->out.sglist[cnt].iova = sr->iova + offsetof(struct nitrox_softreq,
374*2d9fd380Sjfb8856606 resp.completion);
375*2d9fd380Sjfb8856606 sr->out.sglist[cnt].virt = &sr->resp.completion;
376*2d9fd380Sjfb8856606 cnt++;
377*2d9fd380Sjfb8856606
378*2d9fd380Sjfb8856606 RTE_VERIFY(cnt <= MAX_SGBUF_CNT);
379*2d9fd380Sjfb8856606 sr->out.map_bufs_cnt = cnt;
380*2d9fd380Sjfb8856606
381*2d9fd380Sjfb8856606 create_sgcomp(&sr->out);
382*2d9fd380Sjfb8856606 sr->rptr = sr->iova + offsetof(struct nitrox_softreq, out.sgcomp);
383*2d9fd380Sjfb8856606
384*2d9fd380Sjfb8856606 return 0;
385*2d9fd380Sjfb8856606 }
386*2d9fd380Sjfb8856606
387*2d9fd380Sjfb8856606 static void
create_cipher_gph(uint32_t cryptlen,uint16_t ivlen,struct gphdr * gph)388*2d9fd380Sjfb8856606 create_cipher_gph(uint32_t cryptlen, uint16_t ivlen, struct gphdr *gph)
389*2d9fd380Sjfb8856606 {
390*2d9fd380Sjfb8856606 gph->param0 = rte_cpu_to_be_16(cryptlen);
391*2d9fd380Sjfb8856606 gph->param1 = 0;
392*2d9fd380Sjfb8856606 gph->param2 = rte_cpu_to_be_16(ivlen);
393*2d9fd380Sjfb8856606 gph->param3 = 0;
394*2d9fd380Sjfb8856606 }
395*2d9fd380Sjfb8856606
396*2d9fd380Sjfb8856606 static int
process_cipher_data(struct nitrox_softreq * sr)397*2d9fd380Sjfb8856606 process_cipher_data(struct nitrox_softreq *sr)
398*2d9fd380Sjfb8856606 {
399*2d9fd380Sjfb8856606 struct rte_crypto_op *op = sr->op;
400*2d9fd380Sjfb8856606 int err;
401*2d9fd380Sjfb8856606
402*2d9fd380Sjfb8856606 softreq_copy_iv(sr, 0);
403*2d9fd380Sjfb8856606 err = create_cipher_inbuf(sr);
404*2d9fd380Sjfb8856606 if (unlikely(err))
405*2d9fd380Sjfb8856606 return err;
406*2d9fd380Sjfb8856606
407*2d9fd380Sjfb8856606 err = create_cipher_outbuf(sr);
408*2d9fd380Sjfb8856606 if (unlikely(err))
409*2d9fd380Sjfb8856606 return err;
410*2d9fd380Sjfb8856606
411*2d9fd380Sjfb8856606 create_cipher_gph(op->sym->cipher.data.length, sr->iv.len, &sr->gph);
412*2d9fd380Sjfb8856606
413*2d9fd380Sjfb8856606 return 0;
414*2d9fd380Sjfb8856606 }
415*2d9fd380Sjfb8856606
416*2d9fd380Sjfb8856606 static int
extract_cipher_auth_digest(struct nitrox_softreq * sr,struct nitrox_sglist * digest)417*2d9fd380Sjfb8856606 extract_cipher_auth_digest(struct nitrox_softreq *sr,
4184418919fSjohnjiang struct nitrox_sglist *digest)
4194418919fSjohnjiang {
420*2d9fd380Sjfb8856606 struct rte_crypto_op *op = sr->op;
421*2d9fd380Sjfb8856606 struct rte_mbuf *mdst = op->sym->m_dst ? op->sym->m_dst :
422*2d9fd380Sjfb8856606 op->sym->m_src;
423*2d9fd380Sjfb8856606
424*2d9fd380Sjfb8856606 if (sr->ctx->req_op == NITROX_OP_DECRYPT &&
425*2d9fd380Sjfb8856606 unlikely(!op->sym->auth.digest.data))
426*2d9fd380Sjfb8856606 return -EINVAL;
427*2d9fd380Sjfb8856606
428*2d9fd380Sjfb8856606 digest->len = sr->ctx->digest_length;
429*2d9fd380Sjfb8856606 if (op->sym->auth.digest.data) {
430*2d9fd380Sjfb8856606 digest->iova = op->sym->auth.digest.phys_addr;
431*2d9fd380Sjfb8856606 digest->virt = op->sym->auth.digest.data;
432*2d9fd380Sjfb8856606 return 0;
433*2d9fd380Sjfb8856606 }
434*2d9fd380Sjfb8856606
435*2d9fd380Sjfb8856606 if (unlikely(rte_pktmbuf_data_len(mdst) < op->sym->auth.data.offset +
436*2d9fd380Sjfb8856606 op->sym->auth.data.length + digest->len))
437*2d9fd380Sjfb8856606 return -EINVAL;
438*2d9fd380Sjfb8856606
439*2d9fd380Sjfb8856606 digest->iova = rte_pktmbuf_iova_offset(mdst,
440*2d9fd380Sjfb8856606 op->sym->auth.data.offset +
441*2d9fd380Sjfb8856606 op->sym->auth.data.length);
442*2d9fd380Sjfb8856606 digest->virt = rte_pktmbuf_mtod_offset(mdst, uint8_t *,
443*2d9fd380Sjfb8856606 op->sym->auth.data.offset +
444*2d9fd380Sjfb8856606 op->sym->auth.data.length);
445*2d9fd380Sjfb8856606 return 0;
446*2d9fd380Sjfb8856606 }
447*2d9fd380Sjfb8856606
448*2d9fd380Sjfb8856606 static int
create_cipher_auth_sglist(struct nitrox_softreq * sr,struct nitrox_sgtable * sgtbl,struct rte_mbuf * mbuf)449*2d9fd380Sjfb8856606 create_cipher_auth_sglist(struct nitrox_softreq *sr,
450*2d9fd380Sjfb8856606 struct nitrox_sgtable *sgtbl, struct rte_mbuf *mbuf)
451*2d9fd380Sjfb8856606 {
452*2d9fd380Sjfb8856606 struct rte_crypto_op *op = sr->op;
453*2d9fd380Sjfb8856606 int auth_only_len;
454*2d9fd380Sjfb8856606 int err;
455*2d9fd380Sjfb8856606
456*2d9fd380Sjfb8856606 fill_sglist(sgtbl, sr->iv.len, sr->iv.iova, sr->iv.virt);
457*2d9fd380Sjfb8856606 auth_only_len = op->sym->auth.data.length - op->sym->cipher.data.length;
458*2d9fd380Sjfb8856606 if (unlikely(auth_only_len < 0))
459*2d9fd380Sjfb8856606 return -EINVAL;
460*2d9fd380Sjfb8856606
461*2d9fd380Sjfb8856606 if (unlikely(
462*2d9fd380Sjfb8856606 op->sym->cipher.data.offset + op->sym->cipher.data.length !=
463*2d9fd380Sjfb8856606 op->sym->auth.data.offset + op->sym->auth.data.length)) {
464*2d9fd380Sjfb8856606 NITROX_LOG(ERR, "Auth only data after cipher data not supported\n");
465*2d9fd380Sjfb8856606 return -ENOTSUP;
466*2d9fd380Sjfb8856606 }
467*2d9fd380Sjfb8856606
468*2d9fd380Sjfb8856606 err = create_sglist_from_mbuf(sgtbl, mbuf, op->sym->auth.data.offset,
469*2d9fd380Sjfb8856606 auth_only_len);
470*2d9fd380Sjfb8856606 if (unlikely(err))
471*2d9fd380Sjfb8856606 return err;
472*2d9fd380Sjfb8856606
473*2d9fd380Sjfb8856606 err = create_sglist_from_mbuf(sgtbl, mbuf, op->sym->cipher.data.offset,
474*2d9fd380Sjfb8856606 op->sym->cipher.data.length);
475*2d9fd380Sjfb8856606 if (unlikely(err))
476*2d9fd380Sjfb8856606 return err;
477*2d9fd380Sjfb8856606
478*2d9fd380Sjfb8856606 return 0;
479*2d9fd380Sjfb8856606 }
480*2d9fd380Sjfb8856606
481*2d9fd380Sjfb8856606 static int
create_combined_sglist(struct nitrox_softreq * sr,struct nitrox_sgtable * sgtbl,struct rte_mbuf * mbuf)482*2d9fd380Sjfb8856606 create_combined_sglist(struct nitrox_softreq *sr, struct nitrox_sgtable *sgtbl,
483*2d9fd380Sjfb8856606 struct rte_mbuf *mbuf)
484*2d9fd380Sjfb8856606 {
485*2d9fd380Sjfb8856606 struct rte_crypto_op *op = sr->op;
486*2d9fd380Sjfb8856606
487*2d9fd380Sjfb8856606 fill_sglist(sgtbl, sr->iv.len, sr->iv.iova, sr->iv.virt);
488*2d9fd380Sjfb8856606 fill_sglist(sgtbl, sr->ctx->aad_length, op->sym->aead.aad.phys_addr,
489*2d9fd380Sjfb8856606 op->sym->aead.aad.data);
490*2d9fd380Sjfb8856606 return create_sglist_from_mbuf(sgtbl, mbuf, op->sym->cipher.data.offset,
491*2d9fd380Sjfb8856606 op->sym->cipher.data.length);
492*2d9fd380Sjfb8856606 }
493*2d9fd380Sjfb8856606
494*2d9fd380Sjfb8856606 static int
create_aead_sglist(struct nitrox_softreq * sr,struct nitrox_sgtable * sgtbl,struct rte_mbuf * mbuf)495*2d9fd380Sjfb8856606 create_aead_sglist(struct nitrox_softreq *sr, struct nitrox_sgtable *sgtbl,
496*2d9fd380Sjfb8856606 struct rte_mbuf *mbuf)
497*2d9fd380Sjfb8856606 {
498*2d9fd380Sjfb8856606 int err;
499*2d9fd380Sjfb8856606
500*2d9fd380Sjfb8856606 switch (sr->ctx->nitrox_chain) {
501*2d9fd380Sjfb8856606 case NITROX_CHAIN_CIPHER_AUTH:
502*2d9fd380Sjfb8856606 case NITROX_CHAIN_AUTH_CIPHER:
503*2d9fd380Sjfb8856606 err = create_cipher_auth_sglist(sr, sgtbl, mbuf);
504*2d9fd380Sjfb8856606 break;
505*2d9fd380Sjfb8856606 case NITROX_CHAIN_COMBINED:
506*2d9fd380Sjfb8856606 err = create_combined_sglist(sr, sgtbl, mbuf);
507*2d9fd380Sjfb8856606 break;
508*2d9fd380Sjfb8856606 default:
509*2d9fd380Sjfb8856606 err = -EINVAL;
510*2d9fd380Sjfb8856606 break;
511*2d9fd380Sjfb8856606 }
512*2d9fd380Sjfb8856606
513*2d9fd380Sjfb8856606 return err;
514*2d9fd380Sjfb8856606 }
515*2d9fd380Sjfb8856606
516*2d9fd380Sjfb8856606 static int
create_aead_inbuf(struct nitrox_softreq * sr,struct nitrox_sglist * digest)517*2d9fd380Sjfb8856606 create_aead_inbuf(struct nitrox_softreq *sr, struct nitrox_sglist *digest)
518*2d9fd380Sjfb8856606 {
5194418919fSjohnjiang int err;
5204418919fSjohnjiang struct nitrox_crypto_ctx *ctx = sr->ctx;
5214418919fSjohnjiang
522*2d9fd380Sjfb8856606 err = create_aead_sglist(sr, &sr->in, sr->op->sym->m_src);
5234418919fSjohnjiang if (unlikely(err))
5244418919fSjohnjiang return err;
5254418919fSjohnjiang
526*2d9fd380Sjfb8856606 if (ctx->req_op == NITROX_OP_DECRYPT)
5274418919fSjohnjiang fill_sglist(&sr->in, digest->len, digest->iova, digest->virt);
5284418919fSjohnjiang
5294418919fSjohnjiang create_sgcomp(&sr->in);
5304418919fSjohnjiang sr->dptr = sr->iova + offsetof(struct nitrox_softreq, in.sgcomp);
5314418919fSjohnjiang return 0;
5324418919fSjohnjiang }
5334418919fSjohnjiang
5344418919fSjohnjiang static int
create_aead_oop_outbuf(struct nitrox_softreq * sr,struct nitrox_sglist * digest)535*2d9fd380Sjfb8856606 create_aead_oop_outbuf(struct nitrox_softreq *sr, struct nitrox_sglist *digest)
5364418919fSjohnjiang {
5374418919fSjohnjiang int err;
5384418919fSjohnjiang struct nitrox_crypto_ctx *ctx = sr->ctx;
5394418919fSjohnjiang
540*2d9fd380Sjfb8856606 err = create_aead_sglist(sr, &sr->out, sr->op->sym->m_dst);
5414418919fSjohnjiang if (unlikely(err))
5424418919fSjohnjiang return err;
5434418919fSjohnjiang
544*2d9fd380Sjfb8856606 if (ctx->req_op == NITROX_OP_ENCRYPT)
5454418919fSjohnjiang fill_sglist(&sr->out, digest->len, digest->iova, digest->virt);
5464418919fSjohnjiang
5474418919fSjohnjiang return 0;
5484418919fSjohnjiang }
5494418919fSjohnjiang
5504418919fSjohnjiang static void
create_aead_inplace_outbuf(struct nitrox_softreq * sr,struct nitrox_sglist * digest)551*2d9fd380Sjfb8856606 create_aead_inplace_outbuf(struct nitrox_softreq *sr,
5524418919fSjohnjiang struct nitrox_sglist *digest)
5534418919fSjohnjiang {
5544418919fSjohnjiang int i, cnt;
5554418919fSjohnjiang struct nitrox_crypto_ctx *ctx = sr->ctx;
5564418919fSjohnjiang
5574418919fSjohnjiang cnt = sr->out.map_bufs_cnt;
5584418919fSjohnjiang for (i = 0; i < sr->in.map_bufs_cnt; i++, cnt++) {
5594418919fSjohnjiang sr->out.sglist[cnt].len = sr->in.sglist[i].len;
5604418919fSjohnjiang sr->out.sglist[cnt].iova = sr->in.sglist[i].iova;
5614418919fSjohnjiang sr->out.sglist[cnt].virt = sr->in.sglist[i].virt;
5624418919fSjohnjiang }
5634418919fSjohnjiang
5644418919fSjohnjiang sr->out.map_bufs_cnt = cnt;
565*2d9fd380Sjfb8856606 if (ctx->req_op == NITROX_OP_ENCRYPT) {
5664418919fSjohnjiang fill_sglist(&sr->out, digest->len, digest->iova,
5674418919fSjohnjiang digest->virt);
568*2d9fd380Sjfb8856606 } else if (ctx->req_op == NITROX_OP_DECRYPT) {
5694418919fSjohnjiang sr->out.map_bufs_cnt--;
5704418919fSjohnjiang }
5714418919fSjohnjiang }
5724418919fSjohnjiang
5734418919fSjohnjiang static int
create_aead_outbuf(struct nitrox_softreq * sr,struct nitrox_sglist * digest)574*2d9fd380Sjfb8856606 create_aead_outbuf(struct nitrox_softreq *sr, struct nitrox_sglist *digest)
5754418919fSjohnjiang {
5764418919fSjohnjiang struct rte_crypto_op *op = sr->op;
5774418919fSjohnjiang int cnt = 0;
5784418919fSjohnjiang
5794418919fSjohnjiang sr->resp.orh = PENDING_SIG;
5804418919fSjohnjiang sr->out.sglist[cnt].len = sizeof(sr->resp.orh);
5814418919fSjohnjiang sr->out.sglist[cnt].iova = sr->iova + offsetof(struct nitrox_softreq,
5824418919fSjohnjiang resp.orh);
5834418919fSjohnjiang sr->out.sglist[cnt].virt = &sr->resp.orh;
5844418919fSjohnjiang cnt++;
5854418919fSjohnjiang sr->out.map_bufs_cnt = cnt;
5864418919fSjohnjiang if (op->sym->m_dst) {
5874418919fSjohnjiang int err;
5884418919fSjohnjiang
589*2d9fd380Sjfb8856606 err = create_aead_oop_outbuf(sr, digest);
5904418919fSjohnjiang if (unlikely(err))
5914418919fSjohnjiang return err;
5924418919fSjohnjiang } else {
593*2d9fd380Sjfb8856606 create_aead_inplace_outbuf(sr, digest);
5944418919fSjohnjiang }
5954418919fSjohnjiang
5964418919fSjohnjiang cnt = sr->out.map_bufs_cnt;
5974418919fSjohnjiang sr->resp.completion = PENDING_SIG;
5984418919fSjohnjiang sr->out.sglist[cnt].len = sizeof(sr->resp.completion);
5994418919fSjohnjiang sr->out.sglist[cnt].iova = sr->iova + offsetof(struct nitrox_softreq,
6004418919fSjohnjiang resp.completion);
6014418919fSjohnjiang sr->out.sglist[cnt].virt = &sr->resp.completion;
6024418919fSjohnjiang cnt++;
6034418919fSjohnjiang RTE_VERIFY(cnt <= MAX_SGBUF_CNT);
6044418919fSjohnjiang sr->out.map_bufs_cnt = cnt;
6054418919fSjohnjiang
6064418919fSjohnjiang create_sgcomp(&sr->out);
6074418919fSjohnjiang sr->rptr = sr->iova + offsetof(struct nitrox_softreq, out.sgcomp);
6084418919fSjohnjiang return 0;
6094418919fSjohnjiang }
6104418919fSjohnjiang
6114418919fSjohnjiang static void
create_aead_gph(uint32_t cryptlen,uint16_t ivlen,uint32_t authlen,struct gphdr * gph)6124418919fSjohnjiang create_aead_gph(uint32_t cryptlen, uint16_t ivlen, uint32_t authlen,
6134418919fSjohnjiang struct gphdr *gph)
6144418919fSjohnjiang {
6154418919fSjohnjiang int auth_only_len;
6164418919fSjohnjiang union {
6174418919fSjohnjiang struct {
6184418919fSjohnjiang #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
6194418919fSjohnjiang uint16_t iv_offset : 8;
6204418919fSjohnjiang uint16_t auth_offset : 8;
6214418919fSjohnjiang #else
6224418919fSjohnjiang uint16_t auth_offset : 8;
6234418919fSjohnjiang uint16_t iv_offset : 8;
6244418919fSjohnjiang #endif
6254418919fSjohnjiang };
6264418919fSjohnjiang uint16_t value;
6274418919fSjohnjiang } param3;
6284418919fSjohnjiang
6294418919fSjohnjiang gph->param0 = rte_cpu_to_be_16(cryptlen);
6304418919fSjohnjiang gph->param1 = rte_cpu_to_be_16(authlen);
6314418919fSjohnjiang
6324418919fSjohnjiang auth_only_len = authlen - cryptlen;
6334418919fSjohnjiang gph->param2 = rte_cpu_to_be_16(ivlen + auth_only_len);
6344418919fSjohnjiang
6354418919fSjohnjiang param3.iv_offset = 0;
6364418919fSjohnjiang param3.auth_offset = ivlen;
6374418919fSjohnjiang gph->param3 = rte_cpu_to_be_16(param3.value);
6384418919fSjohnjiang }
6394418919fSjohnjiang
6404418919fSjohnjiang static int
process_cipher_auth_data(struct nitrox_softreq * sr)6414418919fSjohnjiang process_cipher_auth_data(struct nitrox_softreq *sr)
6424418919fSjohnjiang {
6434418919fSjohnjiang struct rte_crypto_op *op = sr->op;
6444418919fSjohnjiang int err;
6454418919fSjohnjiang struct nitrox_sglist digest;
6464418919fSjohnjiang
647*2d9fd380Sjfb8856606 softreq_copy_iv(sr, 0);
6484418919fSjohnjiang err = extract_cipher_auth_digest(sr, &digest);
6494418919fSjohnjiang if (unlikely(err))
6504418919fSjohnjiang return err;
6514418919fSjohnjiang
652*2d9fd380Sjfb8856606 err = create_aead_inbuf(sr, &digest);
6534418919fSjohnjiang if (unlikely(err))
6544418919fSjohnjiang return err;
6554418919fSjohnjiang
656*2d9fd380Sjfb8856606 err = create_aead_outbuf(sr, &digest);
6574418919fSjohnjiang if (unlikely(err))
6584418919fSjohnjiang return err;
6594418919fSjohnjiang
6604418919fSjohnjiang create_aead_gph(op->sym->cipher.data.length, sr->iv.len,
6614418919fSjohnjiang op->sym->auth.data.length, &sr->gph);
6624418919fSjohnjiang return 0;
6634418919fSjohnjiang }
6644418919fSjohnjiang
6654418919fSjohnjiang static int
softreq_copy_salt(struct nitrox_softreq * sr)666*2d9fd380Sjfb8856606 softreq_copy_salt(struct nitrox_softreq *sr)
667*2d9fd380Sjfb8856606 {
668*2d9fd380Sjfb8856606 struct nitrox_crypto_ctx *ctx = sr->ctx;
669*2d9fd380Sjfb8856606 uint8_t *addr;
670*2d9fd380Sjfb8856606
671*2d9fd380Sjfb8856606 if (unlikely(ctx->iv.length < AES_GCM_SALT_SIZE)) {
672*2d9fd380Sjfb8856606 NITROX_LOG(ERR, "Invalid IV length %d\n", ctx->iv.length);
673*2d9fd380Sjfb8856606 return -EINVAL;
674*2d9fd380Sjfb8856606 }
675*2d9fd380Sjfb8856606
676*2d9fd380Sjfb8856606 addr = rte_crypto_op_ctod_offset(sr->op, uint8_t *, ctx->iv.offset);
677*2d9fd380Sjfb8856606 if (!memcmp(ctx->salt, addr, AES_GCM_SALT_SIZE))
678*2d9fd380Sjfb8856606 return 0;
679*2d9fd380Sjfb8856606
680*2d9fd380Sjfb8856606 memcpy(ctx->salt, addr, AES_GCM_SALT_SIZE);
681*2d9fd380Sjfb8856606 memcpy(ctx->fctx.crypto.iv, addr, AES_GCM_SALT_SIZE);
682*2d9fd380Sjfb8856606 return 0;
683*2d9fd380Sjfb8856606 }
684*2d9fd380Sjfb8856606
685*2d9fd380Sjfb8856606 static int
extract_combined_digest(struct nitrox_softreq * sr,struct nitrox_sglist * digest)686*2d9fd380Sjfb8856606 extract_combined_digest(struct nitrox_softreq *sr, struct nitrox_sglist *digest)
687*2d9fd380Sjfb8856606 {
688*2d9fd380Sjfb8856606 struct rte_crypto_op *op = sr->op;
689*2d9fd380Sjfb8856606 struct rte_mbuf *mdst = op->sym->m_dst ? op->sym->m_dst :
690*2d9fd380Sjfb8856606 op->sym->m_src;
691*2d9fd380Sjfb8856606
692*2d9fd380Sjfb8856606 digest->len = sr->ctx->digest_length;
693*2d9fd380Sjfb8856606 if (op->sym->aead.digest.data) {
694*2d9fd380Sjfb8856606 digest->iova = op->sym->aead.digest.phys_addr;
695*2d9fd380Sjfb8856606 digest->virt = op->sym->aead.digest.data;
696*2d9fd380Sjfb8856606
697*2d9fd380Sjfb8856606 return 0;
698*2d9fd380Sjfb8856606 }
699*2d9fd380Sjfb8856606
700*2d9fd380Sjfb8856606 if (unlikely(rte_pktmbuf_data_len(mdst) < op->sym->aead.data.offset +
701*2d9fd380Sjfb8856606 op->sym->aead.data.length + digest->len))
702*2d9fd380Sjfb8856606 return -EINVAL;
703*2d9fd380Sjfb8856606
704*2d9fd380Sjfb8856606 digest->iova = rte_pktmbuf_iova_offset(mdst,
705*2d9fd380Sjfb8856606 op->sym->aead.data.offset +
706*2d9fd380Sjfb8856606 op->sym->aead.data.length);
707*2d9fd380Sjfb8856606 digest->virt = rte_pktmbuf_mtod_offset(mdst, uint8_t *,
708*2d9fd380Sjfb8856606 op->sym->aead.data.offset +
709*2d9fd380Sjfb8856606 op->sym->aead.data.length);
710*2d9fd380Sjfb8856606
711*2d9fd380Sjfb8856606 return 0;
712*2d9fd380Sjfb8856606 }
713*2d9fd380Sjfb8856606
714*2d9fd380Sjfb8856606 static int
process_combined_data(struct nitrox_softreq * sr)715*2d9fd380Sjfb8856606 process_combined_data(struct nitrox_softreq *sr)
716*2d9fd380Sjfb8856606 {
717*2d9fd380Sjfb8856606 int err;
718*2d9fd380Sjfb8856606 struct nitrox_sglist digest;
719*2d9fd380Sjfb8856606 struct rte_crypto_op *op = sr->op;
720*2d9fd380Sjfb8856606
721*2d9fd380Sjfb8856606 err = softreq_copy_salt(sr);
722*2d9fd380Sjfb8856606 if (unlikely(err))
723*2d9fd380Sjfb8856606 return err;
724*2d9fd380Sjfb8856606
725*2d9fd380Sjfb8856606 softreq_copy_iv(sr, AES_GCM_SALT_SIZE);
726*2d9fd380Sjfb8856606 err = extract_combined_digest(sr, &digest);
727*2d9fd380Sjfb8856606 if (unlikely(err))
728*2d9fd380Sjfb8856606 return err;
729*2d9fd380Sjfb8856606
730*2d9fd380Sjfb8856606 err = create_aead_inbuf(sr, &digest);
731*2d9fd380Sjfb8856606 if (unlikely(err))
732*2d9fd380Sjfb8856606 return err;
733*2d9fd380Sjfb8856606
734*2d9fd380Sjfb8856606 err = create_aead_outbuf(sr, &digest);
735*2d9fd380Sjfb8856606 if (unlikely(err))
736*2d9fd380Sjfb8856606 return err;
737*2d9fd380Sjfb8856606
738*2d9fd380Sjfb8856606 create_aead_gph(op->sym->aead.data.length, sr->iv.len,
739*2d9fd380Sjfb8856606 op->sym->aead.data.length + sr->ctx->aad_length,
740*2d9fd380Sjfb8856606 &sr->gph);
741*2d9fd380Sjfb8856606
742*2d9fd380Sjfb8856606 return 0;
743*2d9fd380Sjfb8856606 }
744*2d9fd380Sjfb8856606
745*2d9fd380Sjfb8856606 static int
process_softreq(struct nitrox_softreq * sr)7464418919fSjohnjiang process_softreq(struct nitrox_softreq *sr)
7474418919fSjohnjiang {
7484418919fSjohnjiang struct nitrox_crypto_ctx *ctx = sr->ctx;
7494418919fSjohnjiang int err = 0;
7504418919fSjohnjiang
7514418919fSjohnjiang switch (ctx->nitrox_chain) {
752*2d9fd380Sjfb8856606 case NITROX_CHAIN_CIPHER_ONLY:
753*2d9fd380Sjfb8856606 err = process_cipher_data(sr);
754*2d9fd380Sjfb8856606 break;
7554418919fSjohnjiang case NITROX_CHAIN_CIPHER_AUTH:
7564418919fSjohnjiang case NITROX_CHAIN_AUTH_CIPHER:
7574418919fSjohnjiang err = process_cipher_auth_data(sr);
7584418919fSjohnjiang break;
759*2d9fd380Sjfb8856606 case NITROX_CHAIN_COMBINED:
760*2d9fd380Sjfb8856606 err = process_combined_data(sr);
761*2d9fd380Sjfb8856606 break;
7624418919fSjohnjiang default:
7634418919fSjohnjiang err = -EINVAL;
7644418919fSjohnjiang break;
7654418919fSjohnjiang }
7664418919fSjohnjiang
7674418919fSjohnjiang return err;
7684418919fSjohnjiang }
7694418919fSjohnjiang
7704418919fSjohnjiang int
nitrox_process_se_req(uint16_t qno,struct rte_crypto_op * op,struct nitrox_crypto_ctx * ctx,struct nitrox_softreq * sr)7714418919fSjohnjiang nitrox_process_se_req(uint16_t qno, struct rte_crypto_op *op,
7724418919fSjohnjiang struct nitrox_crypto_ctx *ctx,
7734418919fSjohnjiang struct nitrox_softreq *sr)
7744418919fSjohnjiang {
775*2d9fd380Sjfb8856606 int err;
776*2d9fd380Sjfb8856606
7774418919fSjohnjiang softreq_init(sr, sr->iova);
7784418919fSjohnjiang sr->ctx = ctx;
7794418919fSjohnjiang sr->op = op;
780*2d9fd380Sjfb8856606 err = process_softreq(sr);
781*2d9fd380Sjfb8856606 if (unlikely(err))
782*2d9fd380Sjfb8856606 return err;
783*2d9fd380Sjfb8856606
7844418919fSjohnjiang create_se_instr(sr, qno);
7854418919fSjohnjiang sr->timeout = rte_get_timer_cycles() + CMD_TIMEOUT * rte_get_timer_hz();
7864418919fSjohnjiang return 0;
7874418919fSjohnjiang }
7884418919fSjohnjiang
7894418919fSjohnjiang int
nitrox_check_se_req(struct nitrox_softreq * sr,struct rte_crypto_op ** op)7904418919fSjohnjiang nitrox_check_se_req(struct nitrox_softreq *sr, struct rte_crypto_op **op)
7914418919fSjohnjiang {
7924418919fSjohnjiang uint64_t cc;
7934418919fSjohnjiang uint64_t orh;
7944418919fSjohnjiang int err;
7954418919fSjohnjiang
7964418919fSjohnjiang cc = *(volatile uint64_t *)(&sr->resp.completion);
7974418919fSjohnjiang orh = *(volatile uint64_t *)(&sr->resp.orh);
7984418919fSjohnjiang if (cc != PENDING_SIG)
799*2d9fd380Sjfb8856606 err = orh & 0xff;
8004418919fSjohnjiang else if ((orh != PENDING_SIG) && (orh & 0xff))
8014418919fSjohnjiang err = orh & 0xff;
8024418919fSjohnjiang else if (rte_get_timer_cycles() >= sr->timeout)
8034418919fSjohnjiang err = 0xff;
8044418919fSjohnjiang else
8054418919fSjohnjiang return -EAGAIN;
8064418919fSjohnjiang
8074418919fSjohnjiang if (unlikely(err))
8084418919fSjohnjiang NITROX_LOG(ERR, "Request err 0x%x, orh 0x%"PRIx64"\n", err,
8094418919fSjohnjiang sr->resp.orh);
8104418919fSjohnjiang
8114418919fSjohnjiang *op = sr->op;
8124418919fSjohnjiang return err;
8134418919fSjohnjiang }
8144418919fSjohnjiang
8154418919fSjohnjiang void *
nitrox_sym_instr_addr(struct nitrox_softreq * sr)8164418919fSjohnjiang nitrox_sym_instr_addr(struct nitrox_softreq *sr)
8174418919fSjohnjiang {
8184418919fSjohnjiang return &sr->instr;
8194418919fSjohnjiang }
8204418919fSjohnjiang
8214418919fSjohnjiang static void
req_pool_obj_init(__rte_unused struct rte_mempool * mp,__rte_unused void * opaque,void * obj,__rte_unused unsigned int obj_idx)8224418919fSjohnjiang req_pool_obj_init(__rte_unused struct rte_mempool *mp,
8234418919fSjohnjiang __rte_unused void *opaque, void *obj,
8244418919fSjohnjiang __rte_unused unsigned int obj_idx)
8254418919fSjohnjiang {
8264418919fSjohnjiang softreq_init(obj, rte_mempool_virt2iova(obj));
8274418919fSjohnjiang }
8284418919fSjohnjiang
8294418919fSjohnjiang struct rte_mempool *
nitrox_sym_req_pool_create(struct rte_cryptodev * cdev,uint32_t nobjs,uint16_t qp_id,int socket_id)8304418919fSjohnjiang nitrox_sym_req_pool_create(struct rte_cryptodev *cdev, uint32_t nobjs,
8314418919fSjohnjiang uint16_t qp_id, int socket_id)
8324418919fSjohnjiang {
8334418919fSjohnjiang char softreq_pool_name[RTE_RING_NAMESIZE];
8344418919fSjohnjiang struct rte_mempool *mp;
8354418919fSjohnjiang
8364418919fSjohnjiang snprintf(softreq_pool_name, RTE_RING_NAMESIZE, "%s_sr_%d",
8374418919fSjohnjiang cdev->data->name, qp_id);
8384418919fSjohnjiang mp = rte_mempool_create(softreq_pool_name,
8394418919fSjohnjiang RTE_ALIGN_MUL_CEIL(nobjs, 64),
8404418919fSjohnjiang sizeof(struct nitrox_softreq),
8414418919fSjohnjiang 64, 0, NULL, NULL, req_pool_obj_init, NULL,
8424418919fSjohnjiang socket_id, 0);
8434418919fSjohnjiang if (unlikely(!mp))
8444418919fSjohnjiang NITROX_LOG(ERR, "Failed to create req pool, qid %d, err %d\n",
8454418919fSjohnjiang qp_id, rte_errno);
8464418919fSjohnjiang
8474418919fSjohnjiang return mp;
8484418919fSjohnjiang }
8494418919fSjohnjiang
8504418919fSjohnjiang void
nitrox_sym_req_pool_free(struct rte_mempool * mp)8514418919fSjohnjiang nitrox_sym_req_pool_free(struct rte_mempool *mp)
8524418919fSjohnjiang {
8534418919fSjohnjiang rte_mempool_free(mp);
8544418919fSjohnjiang }
855