]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/dpdk/drivers/net/octeontx2/otx2_ethdev_sec_tx.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / octeontx2 / otx2_ethdev_sec_tx.h
CommitLineData
f67539c2
TL
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2020 Marvell International Ltd.
3 */
4
5#ifndef __OTX2_ETHDEV_SEC_TX_H__
6#define __OTX2_ETHDEV_SEC_TX_H__
7
8#include <rte_security.h>
9#include <rte_mbuf.h>
10
11#include "otx2_ethdev_sec.h"
12
13struct otx2_ipsec_fp_out_hdr {
14 uint32_t ip_id;
15 uint32_t seq;
16 uint8_t iv[16];
17};
18
19static __rte_always_inline int32_t
20otx2_ipsec_fp_out_rlen_get(struct otx2_sec_session_ipsec_ip *sess,
21 uint32_t plen)
22{
23 uint32_t enc_payload_len;
24
25 enc_payload_len = RTE_ALIGN_CEIL(plen + sess->roundup_len,
26 sess->roundup_byte);
27
28 return sess->partial_len + enc_payload_len;
29}
30
31static __rte_always_inline void
32otx2_ssogws_head_wait(struct otx2_ssogws *ws);
33
34static __rte_always_inline int
35otx2_sec_event_tx(struct otx2_ssogws *ws, struct rte_event *ev,
36 struct rte_mbuf *m, const struct otx2_eth_txq *txq,
37 const uint32_t offload_flags)
38{
39 uint32_t dlen, rlen, desc_headroom, extend_head, extend_tail;
40 struct otx2_sec_session_ipsec_ip *sess;
41 struct otx2_ipsec_fp_out_hdr *hdr;
42 struct otx2_ipsec_fp_out_sa *sa;
43 uint64_t data_addr, desc_addr;
44 struct otx2_sec_session *priv;
45 struct otx2_cpt_inst_s inst;
46 uint64_t lmt_status;
47 char *data;
48
49 struct desc {
50 struct otx2_cpt_res cpt_res __rte_aligned(OTX2_CPT_RES_ALIGN);
51 struct nix_send_hdr_s nix_hdr
52 __rte_aligned(OTX2_NIX_SEND_DESC_ALIGN);
53 union nix_send_sg_s nix_sg;
54 struct nix_iova_s nix_iova;
55 } *sd;
56
57 priv = get_sec_session_private_data((void *)(m->udata64));
58 sess = &priv->ipsec.ip;
59 sa = &sess->out_sa;
60
61 RTE_ASSERT(sess->cpt_lmtline != NULL);
62 RTE_ASSERT(!(offload_flags & (NIX_TX_OFFLOAD_MBUF_NOFF_F |
63 NIX_TX_OFFLOAD_VLAN_QINQ_F)));
64
65 dlen = rte_pktmbuf_pkt_len(m) + sizeof(*hdr) - RTE_ETHER_HDR_LEN;
66 rlen = otx2_ipsec_fp_out_rlen_get(sess, dlen - sizeof(*hdr));
67
68 RTE_BUILD_BUG_ON(OTX2_CPT_RES_ALIGN % OTX2_NIX_SEND_DESC_ALIGN);
69 RTE_BUILD_BUG_ON(sizeof(sd->cpt_res) % OTX2_NIX_SEND_DESC_ALIGN);
70
71 extend_head = sizeof(*hdr);
72 extend_tail = rlen - dlen;
73
74 desc_headroom = (OTX2_CPT_RES_ALIGN - 1) + sizeof(*sd);
75
76 if (unlikely(!rte_pktmbuf_is_contiguous(m)) ||
77 unlikely(rte_pktmbuf_headroom(m) < extend_head + desc_headroom) ||
78 unlikely(rte_pktmbuf_tailroom(m) < extend_tail)) {
79 goto drop;
80 }
81
82 /*
83 * Extend mbuf data to point to the expected packet buffer for NIX.
84 * This includes the Ethernet header followed by the encrypted IPsec
85 * payload
86 */
87 rte_pktmbuf_append(m, extend_tail);
88 data = rte_pktmbuf_prepend(m, extend_head);
89 data_addr = rte_pktmbuf_mtophys(m);
90
91 /*
92 * Move the Ethernet header, to insert otx2_ipsec_fp_out_hdr prior
93 * to the IP header
94 */
95 memcpy(data, data + sizeof(*hdr), RTE_ETHER_HDR_LEN);
96
97 hdr = (struct otx2_ipsec_fp_out_hdr *)(data + RTE_ETHER_HDR_LEN);
98
99 if (sa->ctl.enc_type == OTX2_IPSEC_FP_SA_ENC_AES_GCM) {
100 /* AES-128-GCM */
101 memcpy(hdr->iv, &sa->nonce, 4);
102 memset(hdr->iv + 4, 0, 12); //TODO: make it random
103 } else {
104 /* AES-128-[CBC] + [SHA1] */
105 memset(hdr->iv, 0, 16); //TODO: make it random
106 }
107
108 /* Keep CPT result and NIX send descriptors in headroom */
109 sd = (void *)RTE_PTR_ALIGN(data - desc_headroom, OTX2_CPT_RES_ALIGN);
110 desc_addr = data_addr - RTE_PTR_DIFF(data, sd);
111
112 /* Prepare CPT instruction */
113
114 inst.nixtx_addr = (desc_addr + offsetof(struct desc, nix_hdr)) >> 4;
115 inst.doneint = 0;
116 inst.nixtxl = 1;
117 inst.res_addr = desc_addr + offsetof(struct desc, cpt_res);
118 inst.u64[2] = 0;
119 inst.u64[3] = 0;
120 inst.wqe_ptr = desc_addr >> 3; /* FIXME: Handle errors */
121 inst.qord = 1;
122 inst.opcode = OTX2_CPT_OP_INLINE_IPSEC_OUTB;
123 inst.dlen = dlen;
124 inst.dptr = data_addr + RTE_ETHER_HDR_LEN;
125 inst.u64[7] = sess->inst_w7;
126
127 /* First word contains 8 bit completion code & 8 bit uc comp code */
128 sd->cpt_res.u16[0] = 0;
129
130 /* Prepare NIX send descriptors for output expected from CPT */
131
132 sd->nix_hdr.w0.u = 0;
133 sd->nix_hdr.w1.u = 0;
134 sd->nix_hdr.w0.sq = txq->sq;
135 sd->nix_hdr.w0.sizem1 = 1;
136 sd->nix_hdr.w0.total = rte_pktmbuf_data_len(m);
137 sd->nix_hdr.w0.aura = npa_lf_aura_handle_to_aura(m->pool->pool_id);
138
139 sd->nix_sg.u = 0;
140 sd->nix_sg.subdc = NIX_SUBDC_SG;
141 sd->nix_sg.ld_type = NIX_SENDLDTYPE_LDD;
142 sd->nix_sg.segs = 1;
143 sd->nix_sg.seg1_size = rte_pktmbuf_data_len(m);
144
145 sd->nix_iova.addr = rte_mbuf_data_iova(m);
146
147 /* Mark mempool object as "put" since it is freed by NIX */
148 __mempool_check_cookies(m->pool, (void **)&m, 1, 0);
149
150 if (!ev->sched_type)
151 otx2_ssogws_head_wait(ws);
152
153 inst.param1 = sess->esn_hi >> 16;
154 inst.param2 = sess->esn_hi & 0xffff;
155
156 hdr->seq = rte_cpu_to_be_32(sess->seq);
157 hdr->ip_id = rte_cpu_to_be_32(sess->ip_id);
158
159 sess->ip_id++;
160 sess->esn++;
161
162 rte_cio_wmb();
163
164 do {
165 otx2_lmt_mov(sess->cpt_lmtline, &inst, 2);
166 lmt_status = otx2_lmt_submit(sess->cpt_nq_reg);
167 } while (lmt_status == 0);
168
169 return 1;
170
171drop:
172 if (offload_flags & NIX_TX_OFFLOAD_MBUF_NOFF_F) {
173 /* Don't free if reference count > 1 */
174 if (rte_pktmbuf_prefree_seg(m) == NULL)
175 return 0;
176 }
177 rte_pktmbuf_free(m);
178 return 0;
179}
180
181#endif /* __OTX2_ETHDEV_SEC_TX_H__ */