crypto/dpaa2_sec: support scatter gather for proto offloads

This patch add support for chained input or output
mbufs for PDCP and ipsec protocol offload cases.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
This commit is contained in:
Hemant Agrawal 2019-09-30 20:10:49 +05:30 committed by Akhil Goyal
parent fb5c100a14
commit af61f07509
2 changed files with 133 additions and 5 deletions

View File

@ -65,6 +65,121 @@ static uint8_t cryptodev_driver_id;
int dpaa2_logtype_sec;
static inline int
build_proto_compound_sg_fd(dpaa2_sec_session *sess,
struct rte_crypto_op *op,
struct qbman_fd *fd, uint16_t bpid)
{
struct rte_crypto_sym_op *sym_op = op->sym;
struct ctxt_priv *priv = sess->ctxt;
struct qbman_fle *fle, *sge, *ip_fle, *op_fle;
struct sec_flow_context *flc;
struct rte_mbuf *mbuf;
uint32_t in_len = 0, out_len = 0;
if (sym_op->m_dst)
mbuf = sym_op->m_dst;
else
mbuf = sym_op->m_src;
/* first FLE entry used to store mbuf and session ctxt */
fle = (struct qbman_fle *)rte_malloc(NULL, FLE_SG_MEM_SIZE,
RTE_CACHE_LINE_SIZE);
if (unlikely(!fle)) {
DPAA2_SEC_DP_ERR("Proto:SG: Memory alloc failed for SGE");
return -1;
}
memset(fle, 0, FLE_SG_MEM_SIZE);
DPAA2_SET_FLE_ADDR(fle, (size_t)op);
DPAA2_FLE_SAVE_CTXT(fle, (ptrdiff_t)priv);
/* Save the shared descriptor */
flc = &priv->flc_desc[0].flc;
op_fle = fle + 1;
ip_fle = fle + 2;
sge = fle + 3;
if (likely(bpid < MAX_BPID)) {
DPAA2_SET_FD_BPID(fd, bpid);
DPAA2_SET_FLE_BPID(op_fle, bpid);
DPAA2_SET_FLE_BPID(ip_fle, bpid);
} else {
DPAA2_SET_FD_IVP(fd);
DPAA2_SET_FLE_IVP(op_fle);
DPAA2_SET_FLE_IVP(ip_fle);
}
/* Configure FD as a FRAME LIST */
DPAA2_SET_FD_ADDR(fd, DPAA2_VADDR_TO_IOVA(op_fle));
DPAA2_SET_FD_COMPOUND_FMT(fd);
DPAA2_SET_FD_FLC(fd, DPAA2_VADDR_TO_IOVA(flc));
/* Configure Output FLE with Scatter/Gather Entry */
DPAA2_SET_FLE_SG_EXT(op_fle);
DPAA2_SET_FLE_ADDR(op_fle, DPAA2_VADDR_TO_IOVA(sge));
/* Configure Output SGE for Encap/Decap */
DPAA2_SET_FLE_ADDR(sge, DPAA2_MBUF_VADDR_TO_IOVA(mbuf));
DPAA2_SET_FLE_OFFSET(sge, mbuf->data_off);
/* o/p segs */
while (mbuf->next) {
sge->length = mbuf->data_len;
out_len += sge->length;
sge++;
mbuf = mbuf->next;
DPAA2_SET_FLE_ADDR(sge, DPAA2_MBUF_VADDR_TO_IOVA(mbuf));
DPAA2_SET_FLE_OFFSET(sge, mbuf->data_off);
}
/* using buf_len for last buf - so that extra data can be added */
sge->length = mbuf->buf_len - mbuf->data_off;
out_len += sge->length;
DPAA2_SET_FLE_FIN(sge);
op_fle->length = out_len;
sge++;
mbuf = sym_op->m_src;
/* Configure Input FLE with Scatter/Gather Entry */
DPAA2_SET_FLE_ADDR(ip_fle, DPAA2_VADDR_TO_IOVA(sge));
DPAA2_SET_FLE_SG_EXT(ip_fle);
DPAA2_SET_FLE_FIN(ip_fle);
/* Configure input SGE for Encap/Decap */
DPAA2_SET_FLE_ADDR(sge, DPAA2_MBUF_VADDR_TO_IOVA(mbuf));
DPAA2_SET_FLE_OFFSET(sge, mbuf->data_off);
sge->length = mbuf->data_len;
in_len += sge->length;
mbuf = mbuf->next;
/* i/p segs */
while (mbuf) {
sge++;
DPAA2_SET_FLE_ADDR(sge, DPAA2_MBUF_VADDR_TO_IOVA(mbuf));
DPAA2_SET_FLE_OFFSET(sge, mbuf->data_off);
sge->length = mbuf->data_len;
in_len += sge->length;
mbuf = mbuf->next;
}
ip_fle->length = in_len;
DPAA2_SET_FLE_FIN(sge);
/* In case of PDCP, per packet HFN is stored in
* mbuf priv after sym_op.
*/
if (sess->ctxt_type == DPAA2_SEC_PDCP && sess->pdcp.hfn_ovd) {
uint32_t hfn_ovd = *((uint8_t *)op + sess->pdcp.hfn_ovd_offset);
/*enable HFN override override */
DPAA2_SET_FLE_INTERNAL_JD(ip_fle, hfn_ovd);
DPAA2_SET_FLE_INTERNAL_JD(op_fle, hfn_ovd);
DPAA2_SET_FD_INTERNAL_JD(fd, hfn_ovd);
}
DPAA2_SET_FD_LEN(fd, ip_fle->length);
return 0;
}
static inline int
build_proto_compound_fd(dpaa2_sec_session *sess,
struct rte_crypto_op *op,
@ -87,7 +202,7 @@ build_proto_compound_fd(dpaa2_sec_session *sess,
/* we are using the first FLE entry to store Mbuf */
retval = rte_mempool_get(priv->fle_pool, (void **)(&fle));
if (retval) {
DPAA2_SEC_ERR("Memory alloc failed");
DPAA2_SEC_DP_ERR("Memory alloc failed");
return -1;
}
memset(fle, 0, FLE_POOL_BUF_SIZE);
@ -1170,8 +1285,10 @@ build_sec_fd(struct rte_crypto_op *op,
else
return -1;
/* Segmented buffer */
if (unlikely(!rte_pktmbuf_is_contiguous(op->sym->m_src))) {
/* Any of the buffer is segmented*/
if (!rte_pktmbuf_is_contiguous(op->sym->m_src) ||
((op->sym->m_dst != NULL) &&
!rte_pktmbuf_is_contiguous(op->sym->m_dst))) {
switch (sess->ctxt_type) {
case DPAA2_SEC_CIPHER:
ret = build_cipher_sg_fd(sess, op, fd, bpid);
@ -1185,6 +1302,10 @@ build_sec_fd(struct rte_crypto_op *op,
case DPAA2_SEC_CIPHER_HASH:
ret = build_authenc_sg_fd(sess, op, fd, bpid);
break;
case DPAA2_SEC_IPSEC:
case DPAA2_SEC_PDCP:
ret = build_proto_compound_sg_fd(sess, op, fd, bpid);
break;
case DPAA2_SEC_HASH_CIPHER:
default:
DPAA2_SEC_ERR("error: Unsupported session");
@ -1372,9 +1493,14 @@ sec_fd_to_mbuf(const struct qbman_fd *fd)
if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
dpaa2_sec_session *sess = (dpaa2_sec_session *)
get_sec_session_private_data(op->sym->sec_session);
if (sess->ctxt_type == DPAA2_SEC_IPSEC) {
if (sess->ctxt_type == DPAA2_SEC_IPSEC ||
sess->ctxt_type == DPAA2_SEC_PDCP) {
uint16_t len = DPAA2_GET_FD_LEN(fd);
dst->pkt_len = len;
while (dst->next != NULL) {
len -= dst->data_len;
dst = dst->next;
}
dst->data_len = len;
}
}

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
* Copyright 2016 NXP
* Copyright 2016,2019 NXP
*
*/
@ -37,6 +37,8 @@ extern int dpaa2_logtype_sec;
DPAA2_SEC_DP_LOG(INFO, fmt, ## args)
#define DPAA2_SEC_DP_WARN(fmt, args...) \
DPAA2_SEC_DP_LOG(WARNING, fmt, ## args)
#define DPAA2_SEC_DP_ERR(fmt, args...) \
DPAA2_SEC_DP_LOG(ERR, fmt, ## args)
#endif /* _DPAA2_SEC_LOGS_H_ */