From: Vamsi Attunuru <vattun...@marvell.com>

Signed-off-by: Vamsi Attunuru <vattun...@marvell.com>
Signed-off-by: Tejasree Kondoj <ktejas...@marvell.com>
---
 drivers/crypto/octeontx2/otx2_cryptodev.h     |   8 +
 drivers/crypto/octeontx2/otx2_cryptodev_ops.c |  36 +++-
 drivers/crypto/octeontx2/otx2_ipsec_po.h      |   6 +
 drivers/crypto/octeontx2/otx2_ipsec_po_ops.h  | 179 ++++++++++++++++++
 4 files changed, 228 insertions(+), 1 deletion(-)
 create mode 100644 drivers/crypto/octeontx2/otx2_ipsec_po_ops.h

diff --git a/drivers/crypto/octeontx2/otx2_cryptodev.h 
b/drivers/crypto/octeontx2/otx2_cryptodev.h
index e7a1730b22..f329741b38 100644
--- a/drivers/crypto/octeontx2/otx2_cryptodev.h
+++ b/drivers/crypto/octeontx2/otx2_cryptodev.h
@@ -6,6 +6,7 @@
 #define _OTX2_CRYPTODEV_H_
 
 #include "cpt_common.h"
+#include "cpt_hw_types.h"
 
 #include "otx2_dev.h"
 
@@ -33,6 +34,13 @@ struct otx2_cpt_vf {
        /**< CPT device capabilities */
 };
 
+struct cpt_meta_info {
+       uint64_t deq_op_info[4];
+       uint64_t comp_code_sz;
+       union cpt_res_s cpt_res __rte_aligned(16);
+       struct cpt_request_info cpt_req __rte_aligned(8);
+};
+
 #define CPT_LOGTYPE otx2_cpt_logtype
 
 extern int otx2_cpt_logtype;
diff --git a/drivers/crypto/octeontx2/otx2_cryptodev_ops.c 
b/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
index 08254062e9..d796488def 100644
--- a/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
+++ b/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
@@ -13,8 +13,10 @@
 #include "otx2_cryptodev_hw_access.h"
 #include "otx2_cryptodev_mbox.h"
 #include "otx2_cryptodev_ops.h"
+#include "otx2_ipsec_po_ops.h"
 #include "otx2_mbox.h"
 #include "otx2_sec_idev.h"
+#include "otx2_security.h"
 
 #include "cpt_hw_types.h"
 #include "cpt_pmd_logs.h"
@@ -603,6 +605,36 @@ otx2_cpt_enqueue_sym(struct otx2_cpt_qp *qp, struct 
rte_crypto_op *op,
        return ret;
 }
 
+static __rte_always_inline int __rte_hot
+otx2_cpt_enqueue_sec(struct otx2_cpt_qp *qp, struct rte_crypto_op *op,
+                    struct pending_queue *pend_q)
+{
+       struct otx2_sec_session_ipsec_lp *sess;
+       struct otx2_ipsec_po_sa_ctl *ctl_wrd;
+       struct otx2_sec_session *priv;
+       struct cpt_request_info *req;
+       int ret;
+
+       priv = get_sec_session_private_data(op->sym->sec_session);
+       sess = &priv->ipsec.lp;
+
+       ctl_wrd = &sess->in_sa.ctl;
+
+       if (ctl_wrd->direction == OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND)
+               ret = process_outb_sa(op, sess, &qp->meta_info, (void **)&req);
+       else
+               ret = process_inb_sa(op, sess, &qp->meta_info, (void **)&req);
+
+       if (unlikely(ret)) {
+               otx2_err("Crypto req : op %p, ret 0x%x", op, ret);
+               return ret;
+       }
+
+       ret = otx2_cpt_enqueue_req(qp, pend_q, req);
+
+       return ret;
+}
+
 static __rte_always_inline int __rte_hot
 otx2_cpt_enqueue_sym_sessless(struct otx2_cpt_qp *qp, struct rte_crypto_op *op,
                              struct pending_queue *pend_q)
@@ -656,7 +688,9 @@ otx2_cpt_enqueue_burst(void *qptr, struct rte_crypto_op 
**ops, uint16_t nb_ops)
        for (count = 0; count < nb_ops; count++) {
                op = ops[count];
                if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
-                       if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION)
+                       if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION)
+                               ret = otx2_cpt_enqueue_sec(qp, op, pend_q);
+                       else if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION)
                                ret = otx2_cpt_enqueue_sym(qp, op, pend_q);
                        else
                                ret = otx2_cpt_enqueue_sym_sessless(qp, op,
diff --git a/drivers/crypto/octeontx2/otx2_ipsec_po.h 
b/drivers/crypto/octeontx2/otx2_ipsec_po.h
index 5d9f1393e2..d127f310b7 100644
--- a/drivers/crypto/octeontx2/otx2_ipsec_po.h
+++ b/drivers/crypto/octeontx2/otx2_ipsec_po.h
@@ -86,6 +86,12 @@ enum {
        OTX2_IPSEC_PO_SA_ENCAP_UDP = 1,
 };
 
+struct otx2_ipsec_po_out_hdr {
+       uint32_t ip_id;
+       uint32_t seq;
+       uint8_t iv[16];
+};
+
 union bit_perfect_iv {
        uint8_t aes_iv[16];
        uint8_t des_iv[8];
diff --git a/drivers/crypto/octeontx2/otx2_ipsec_po_ops.h 
b/drivers/crypto/octeontx2/otx2_ipsec_po_ops.h
new file mode 100644
index 0000000000..1bfcbbe75b
--- /dev/null
+++ b/drivers/crypto/octeontx2/otx2_ipsec_po_ops.h
@@ -0,0 +1,179 @@
+
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#ifndef __OTX2_IPSEC_PO_OPS_H__
+#define __OTX2_IPSEC_PO_OPS_H__
+
+#include <rte_crypto_sym.h>
+#include <rte_security.h>
+
+#include "otx2_cryptodev.h"
+#include "otx2_security.h"
+
+static __rte_always_inline int32_t
+otx2_ipsec_po_out_rlen_get(struct otx2_sec_session_ipsec_lp *sess,
+                          uint32_t plen)
+{
+       uint32_t enc_payload_len;
+
+       enc_payload_len = RTE_ALIGN_CEIL(plen + sess->roundup_len,
+                       sess->roundup_byte);
+
+       return sess->partial_len + enc_payload_len;
+}
+
+static __rte_always_inline struct cpt_request_info *
+alloc_request_struct(char *maddr, void *cop, int mdata_len)
+{
+       struct cpt_request_info *req;
+       struct cpt_meta_info *meta;
+       uint8_t *resp_addr;
+       uintptr_t *op;
+
+       meta = (void *)RTE_PTR_ALIGN((uint8_t *)maddr, 16);
+
+       op = meta->deq_op_info;
+       req = &meta->cpt_req;
+       resp_addr = (uint8_t *)&meta->cpt_res;
+
+       req->completion_addr = (uint64_t *)((uint8_t *)resp_addr);
+       *req->completion_addr = COMPLETION_CODE_INIT;
+       req->comp_baddr = rte_mem_virt2iova(resp_addr);
+       req->op = op;
+
+       op[0] = (uintptr_t)((uint64_t)meta | 1ull);
+       op[1] = (uintptr_t)cop;
+       op[2] = (uintptr_t)req;
+       op[3] = mdata_len;
+
+       return req;
+}
+
+static __rte_always_inline int
+process_outb_sa(struct rte_crypto_op *cop,
+              struct otx2_sec_session_ipsec_lp *sess,
+              struct cpt_qp_meta_info *m_info, void **prep_req)
+{
+       uint32_t dlen, rlen, extend_head, extend_tail;
+       struct rte_crypto_sym_op *sym_op = cop->sym;
+       struct rte_mbuf *m_src = sym_op->m_src;
+       struct otx2_ipsec_po_sa_ctl *ctl_wrd;
+       struct cpt_request_info *req = NULL;
+       struct otx2_ipsec_po_out_hdr *hdr;
+       struct otx2_ipsec_po_out_sa *sa;
+       int hdr_len, mdata_len, ret = 0;
+       vq_cmd_word0_t word0;
+       char *mdata, *data;
+
+       sa = &sess->out_sa;
+       ctl_wrd = &sa->ctl;
+       hdr_len = sizeof(*hdr);
+
+       dlen = rte_pktmbuf_pkt_len(m_src) + hdr_len;
+       rlen = otx2_ipsec_po_out_rlen_get(sess, dlen - hdr_len);
+
+       extend_head = hdr_len + RTE_ETHER_HDR_LEN;
+       extend_tail = rlen - dlen;
+       mdata_len = m_info->lb_mlen + 8;
+
+       mdata = rte_pktmbuf_append(m_src, extend_tail + mdata_len);
+       if (unlikely(mdata == NULL)) {
+               otx2_err("Not enough tail room\n");
+               ret = -ENOMEM;
+               goto exit;
+       }
+
+       mdata += extend_tail; /* mdata follows encrypted data */
+       req = alloc_request_struct(mdata, (void *)cop, mdata_len);
+
+       data = rte_pktmbuf_prepend(m_src, extend_head);
+       if (unlikely(data == NULL)) {
+               otx2_err("Not enough head room\n");
+               ret = -ENOMEM;
+               goto exit;
+       }
+
+       /*
+        * Move the Ethernet header, to insert otx2_ipsec_po_out_hdr prior
+        * to the IP header
+        */
+       memcpy(data, data + hdr_len, RTE_ETHER_HDR_LEN);
+
+       hdr = (struct otx2_ipsec_po_out_hdr *)rte_pktmbuf_adj(m_src,
+                                                       RTE_ETHER_HDR_LEN);
+
+       if (ctl_wrd->enc_type == OTX2_IPSEC_FP_SA_ENC_AES_GCM) {
+               memcpy(&hdr->iv[0], &sa->iv.misc.nonce, 4);
+               memcpy(&hdr->iv[4], rte_crypto_op_ctod_offset(cop, uint8_t *,
+                       sess->iv_offset), sess->iv_length);
+       } else if (ctl_wrd->auth_type == OTX2_IPSEC_FP_SA_ENC_AES_CBC) {
+               memcpy(&hdr->iv[0], rte_crypto_op_ctod_offset(cop, uint8_t *,
+                       sess->iv_offset), sess->iv_length);
+       }
+
+       /* Prepare CPT instruction */
+       word0.s.opcode = sess->ucmd_opcode;
+       word0.s.param1 = sess->ucmd_param1;
+       word0.s.param2 = sess->ucmd_param2;
+       word0.s.dlen   = dlen;
+
+       req->ist.ei0 = word0.u64;
+       req->ist.ei1 = rte_pktmbuf_iova(m_src);
+       req->ist.ei2 = req->ist.ei1;
+       req->ist.ei3 = sess->ucmd_w3;
+
+       hdr->seq = rte_cpu_to_be_32(sess->seq_lo);
+       hdr->ip_id = rte_cpu_to_be_32(sess->ip_id);
+
+       sess->ip_id++;
+       sess->esn++;
+
+exit:
+       *prep_req = req;
+
+       return ret;
+}
+
+static __rte_always_inline int
+process_inb_sa(struct rte_crypto_op *cop,
+             struct otx2_sec_session_ipsec_lp *sess,
+             struct cpt_qp_meta_info *m_info, void **prep_req)
+{
+       struct rte_crypto_sym_op *sym_op = cop->sym;
+       struct rte_mbuf *m_src = sym_op->m_src;
+       struct cpt_request_info *req = NULL;
+       int mdata_len, ret = 0;
+       vq_cmd_word0_t word0;
+       uint32_t dlen;
+       char *mdata;
+
+       dlen = rte_pktmbuf_pkt_len(m_src);
+       mdata_len = m_info->lb_mlen + 8;
+
+       mdata = rte_pktmbuf_append(m_src, mdata_len);
+       if (unlikely(mdata == NULL)) {
+               otx2_err("Not enough tail room\n");
+               ret = -ENOMEM;
+               goto exit;
+       }
+
+       req = alloc_request_struct(mdata, (void *)cop, mdata_len);
+
+       /* Prepare CPT instruction */
+       word0.s.opcode = sess->ucmd_opcode;
+       word0.s.param1 = sess->ucmd_param1;
+       word0.s.param2 = sess->ucmd_param2;
+       word0.s.dlen   = dlen;
+
+       req->ist.ei0 = word0.u64;
+       req->ist.ei1 = rte_pktmbuf_iova(m_src);
+       req->ist.ei2 = req->ist.ei1;
+       req->ist.ei3 = sess->ucmd_w3;
+
+exit:
+       *prep_req = req;
+       return ret;
+}
+#endif /* __OTX2_IPSEC_PO_OPS_H__ */
-- 
2.27.0

Reply via email to