2 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(C) 2019 Marvell International Ltd.
6 #ifndef __OTX2_IPSEC_PO_OPS_H__
7 #define __OTX2_IPSEC_PO_OPS_H__
9 #include <rte_crypto_sym.h>
10 #include <rte_security.h>
12 #include "otx2_cryptodev.h"
13 #include "otx2_security.h"
15 static __rte_always_inline int32_t
16 otx2_ipsec_po_out_rlen_get(struct otx2_sec_session_ipsec_lp *sess,
19 uint32_t enc_payload_len;
21 enc_payload_len = RTE_ALIGN_CEIL(plen + sess->roundup_len,
24 return sess->partial_len + enc_payload_len;
27 static __rte_always_inline struct cpt_request_info *
28 alloc_request_struct(char *maddr, void *cop, int mdata_len)
30 struct cpt_request_info *req;
31 struct cpt_meta_info *meta;
35 meta = (void *)RTE_PTR_ALIGN((uint8_t *)maddr, 16);
37 op = (uintptr_t *)meta->deq_op_info;
39 resp_addr = (uint8_t *)&meta->cpt_res;
41 req->completion_addr = (uint64_t *)((uint8_t *)resp_addr);
42 *req->completion_addr = COMPLETION_CODE_INIT;
43 req->comp_baddr = rte_mem_virt2iova(resp_addr);
46 op[0] = (uintptr_t)((uint64_t)meta | 1ull);
47 op[1] = (uintptr_t)cop;
48 op[2] = (uintptr_t)req;
54 static __rte_always_inline int
55 process_outb_sa(struct rte_crypto_op *cop,
56 struct otx2_sec_session_ipsec_lp *sess,
57 struct cpt_qp_meta_info *m_info, void **prep_req)
59 uint32_t dlen, rlen, extend_head, extend_tail;
60 struct rte_crypto_sym_op *sym_op = cop->sym;
61 struct rte_mbuf *m_src = sym_op->m_src;
62 struct cpt_request_info *req = NULL;
63 struct otx2_ipsec_po_out_hdr *hdr;
64 struct otx2_ipsec_po_out_sa *sa;
65 int hdr_len, mdata_len, ret = 0;
70 hdr_len = sizeof(*hdr);
72 dlen = rte_pktmbuf_pkt_len(m_src) + hdr_len;
73 rlen = otx2_ipsec_po_out_rlen_get(sess, dlen - hdr_len);
75 extend_head = hdr_len + RTE_ETHER_HDR_LEN;
76 extend_tail = rlen - dlen;
77 mdata_len = m_info->lb_mlen + 8;
79 mdata = rte_pktmbuf_append(m_src, extend_tail + mdata_len);
80 if (unlikely(mdata == NULL)) {
81 otx2_err("Not enough tail room\n");
86 mdata += extend_tail; /* mdata follows encrypted data */
87 req = alloc_request_struct(mdata, (void *)cop, mdata_len);
89 data = rte_pktmbuf_prepend(m_src, extend_head);
90 if (unlikely(data == NULL)) {
91 otx2_err("Not enough head room\n");
97 * Move the Ethernet header, to insert otx2_ipsec_po_out_hdr prior
100 memcpy(data, data + hdr_len, RTE_ETHER_HDR_LEN);
102 hdr = (struct otx2_ipsec_po_out_hdr *)rte_pktmbuf_adj(m_src,
105 memcpy(&hdr->iv[0], rte_crypto_op_ctod_offset(cop, uint8_t *,
106 sess->iv_offset), sess->iv_length);
108 /* Prepare CPT instruction */
109 word0.u64 = sess->ucmd_w0;
112 req->ist.ei0 = word0.u64;
113 req->ist.ei1 = rte_pktmbuf_iova(m_src);
114 req->ist.ei2 = req->ist.ei1;
116 sa->esn_hi = sess->seq_hi;
118 hdr->seq = rte_cpu_to_be_32(sess->seq_lo);
119 hdr->ip_id = rte_cpu_to_be_32(sess->ip_id);
130 static __rte_always_inline int
131 process_inb_sa(struct rte_crypto_op *cop,
132 struct otx2_sec_session_ipsec_lp *sess,
133 struct cpt_qp_meta_info *m_info, void **prep_req)
135 struct rte_crypto_sym_op *sym_op = cop->sym;
136 struct rte_mbuf *m_src = sym_op->m_src;
137 struct cpt_request_info *req = NULL;
138 int mdata_len, ret = 0;
139 vq_cmd_word0_t word0;
143 dlen = rte_pktmbuf_pkt_len(m_src);
144 mdata_len = m_info->lb_mlen + 8;
146 mdata = rte_pktmbuf_append(m_src, mdata_len);
147 if (unlikely(mdata == NULL)) {
148 otx2_err("Not enough tail room\n");
153 req = alloc_request_struct(mdata, (void *)cop, mdata_len);
155 /* Prepare CPT instruction */
156 word0.u64 = sess->ucmd_w0;
159 req->ist.ei0 = word0.u64;
160 req->ist.ei1 = rte_pktmbuf_iova(m_src);
161 req->ist.ei2 = req->ist.ei1;
167 #endif /* __OTX2_IPSEC_PO_OPS_H__ */