199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2018-2020 Intel Corporation
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson
599a2dd95SBruce Richardson #ifndef _MISC_H_
699a2dd95SBruce Richardson #define _MISC_H_
799a2dd95SBruce Richardson
899a2dd95SBruce Richardson /**
999a2dd95SBruce Richardson * @file misc.h
1099a2dd95SBruce Richardson * Contains miscellaneous functions/structures/macros used internally
1199a2dd95SBruce Richardson * by ipsec library.
1299a2dd95SBruce Richardson */
1399a2dd95SBruce Richardson
1499a2dd95SBruce Richardson /*
1599a2dd95SBruce Richardson * Move bad (unprocessed) mbufs beyond the good (processed) ones.
1699a2dd95SBruce Richardson * bad_idx[] contains the indexes of bad mbufs inside the mb[].
1799a2dd95SBruce Richardson */
1899a2dd95SBruce Richardson static inline void
move_bad_mbufs(struct rte_mbuf * mb[],const uint32_t bad_idx[],uint32_t nb_mb,uint32_t nb_bad)1999a2dd95SBruce Richardson move_bad_mbufs(struct rte_mbuf *mb[], const uint32_t bad_idx[], uint32_t nb_mb,
2099a2dd95SBruce Richardson uint32_t nb_bad)
2199a2dd95SBruce Richardson {
2299a2dd95SBruce Richardson uint32_t i, j, k;
2399a2dd95SBruce Richardson struct rte_mbuf *drb[nb_bad];
2499a2dd95SBruce Richardson
2599a2dd95SBruce Richardson j = 0;
2699a2dd95SBruce Richardson k = 0;
2799a2dd95SBruce Richardson
2899a2dd95SBruce Richardson /* copy bad ones into a temp place */
2999a2dd95SBruce Richardson for (i = 0; i != nb_mb; i++) {
3099a2dd95SBruce Richardson if (j != nb_bad && i == bad_idx[j])
3199a2dd95SBruce Richardson drb[j++] = mb[i];
3299a2dd95SBruce Richardson else
3399a2dd95SBruce Richardson mb[k++] = mb[i];
3499a2dd95SBruce Richardson }
3599a2dd95SBruce Richardson
3699a2dd95SBruce Richardson /* copy bad ones after the good ones */
3799a2dd95SBruce Richardson for (i = 0; i != nb_bad; i++)
3899a2dd95SBruce Richardson mb[k + i] = drb[i];
3999a2dd95SBruce Richardson }
4099a2dd95SBruce Richardson
4199a2dd95SBruce Richardson /*
4299a2dd95SBruce Richardson * Find packet's segment for the specified offset.
4399a2dd95SBruce Richardson * ofs - at input should contain required offset, at output would contain
4499a2dd95SBruce Richardson * offset value within the segment.
4599a2dd95SBruce Richardson */
4699a2dd95SBruce Richardson static inline struct rte_mbuf *
mbuf_get_seg_ofs(struct rte_mbuf * mb,uint32_t * ofs)4799a2dd95SBruce Richardson mbuf_get_seg_ofs(struct rte_mbuf *mb, uint32_t *ofs)
4899a2dd95SBruce Richardson {
4999a2dd95SBruce Richardson uint32_t k, n, plen;
5099a2dd95SBruce Richardson struct rte_mbuf *ms;
5199a2dd95SBruce Richardson
5299a2dd95SBruce Richardson plen = mb->pkt_len;
5399a2dd95SBruce Richardson n = *ofs;
5499a2dd95SBruce Richardson
5599a2dd95SBruce Richardson if (n == plen) {
5699a2dd95SBruce Richardson ms = rte_pktmbuf_lastseg(mb);
5799a2dd95SBruce Richardson n = n + rte_pktmbuf_data_len(ms) - plen;
5899a2dd95SBruce Richardson } else {
5999a2dd95SBruce Richardson ms = mb;
6099a2dd95SBruce Richardson for (k = rte_pktmbuf_data_len(ms); n >= k;
6199a2dd95SBruce Richardson k = rte_pktmbuf_data_len(ms)) {
6299a2dd95SBruce Richardson ms = ms->next;
6399a2dd95SBruce Richardson n -= k;
6499a2dd95SBruce Richardson }
6599a2dd95SBruce Richardson }
6699a2dd95SBruce Richardson
6799a2dd95SBruce Richardson *ofs = n;
6899a2dd95SBruce Richardson return ms;
6999a2dd95SBruce Richardson }
7099a2dd95SBruce Richardson
7199a2dd95SBruce Richardson /*
7299a2dd95SBruce Richardson * Trim multi-segment packet at the specified offset, and free
7399a2dd95SBruce Richardson * all unused segments.
7499a2dd95SBruce Richardson * mb - input packet
7599a2dd95SBruce Richardson * ms - segment where to cut
7699a2dd95SBruce Richardson * ofs - offset within the *ms*
7799a2dd95SBruce Richardson * len - length to cut (from given offset to the end of the packet)
7899a2dd95SBruce Richardson * Can be used in conjunction with mbuf_get_seg_ofs():
7999a2dd95SBruce Richardson * ofs = new_len;
8099a2dd95SBruce Richardson * ms = mbuf_get_seg_ofs(mb, &ofs);
8199a2dd95SBruce Richardson * mbuf_cut_seg_ofs(mb, ms, ofs, mb->pkt_len - new_len);
8299a2dd95SBruce Richardson */
8399a2dd95SBruce Richardson static inline void
mbuf_cut_seg_ofs(struct rte_mbuf * mb,struct rte_mbuf * ms,uint32_t ofs,uint32_t len)8499a2dd95SBruce Richardson mbuf_cut_seg_ofs(struct rte_mbuf *mb, struct rte_mbuf *ms, uint32_t ofs,
8599a2dd95SBruce Richardson uint32_t len)
8699a2dd95SBruce Richardson {
8799a2dd95SBruce Richardson uint32_t n, slen;
8899a2dd95SBruce Richardson struct rte_mbuf *mn;
8999a2dd95SBruce Richardson
9099a2dd95SBruce Richardson slen = ms->data_len;
9199a2dd95SBruce Richardson ms->data_len = ofs;
9299a2dd95SBruce Richardson
9399a2dd95SBruce Richardson /* tail spawns through multiple segments */
9499a2dd95SBruce Richardson if (slen < ofs + len) {
9599a2dd95SBruce Richardson mn = ms->next;
9699a2dd95SBruce Richardson ms->next = NULL;
9799a2dd95SBruce Richardson for (n = 0; mn != NULL; n++) {
9899a2dd95SBruce Richardson ms = mn->next;
9999a2dd95SBruce Richardson rte_pktmbuf_free_seg(mn);
10099a2dd95SBruce Richardson mn = ms;
10199a2dd95SBruce Richardson }
10299a2dd95SBruce Richardson mb->nb_segs -= n;
10399a2dd95SBruce Richardson }
10499a2dd95SBruce Richardson
10599a2dd95SBruce Richardson mb->pkt_len -= len;
10699a2dd95SBruce Richardson }
10799a2dd95SBruce Richardson
10899a2dd95SBruce Richardson /*
10999a2dd95SBruce Richardson * process packets using sync crypto engine.
11099a2dd95SBruce Richardson * expects *num* to be greater than zero.
11199a2dd95SBruce Richardson */
11299a2dd95SBruce Richardson static inline void
cpu_crypto_bulk(const struct rte_ipsec_session * ss,union rte_crypto_sym_ofs ofs,struct rte_mbuf * mb[],struct rte_crypto_va_iova_ptr iv[],struct rte_crypto_va_iova_ptr aad[],struct rte_crypto_va_iova_ptr dgst[],uint32_t l4ofs[],uint32_t clen[],uint32_t num)11399a2dd95SBruce Richardson cpu_crypto_bulk(const struct rte_ipsec_session *ss,
11499a2dd95SBruce Richardson union rte_crypto_sym_ofs ofs, struct rte_mbuf *mb[],
11599a2dd95SBruce Richardson struct rte_crypto_va_iova_ptr iv[],
11699a2dd95SBruce Richardson struct rte_crypto_va_iova_ptr aad[],
11799a2dd95SBruce Richardson struct rte_crypto_va_iova_ptr dgst[], uint32_t l4ofs[],
11899a2dd95SBruce Richardson uint32_t clen[], uint32_t num)
11999a2dd95SBruce Richardson {
12099a2dd95SBruce Richardson uint32_t i, j, n;
12199a2dd95SBruce Richardson int32_t vcnt, vofs;
12299a2dd95SBruce Richardson int32_t st[num];
12399a2dd95SBruce Richardson struct rte_crypto_sgl vecpkt[num];
12499a2dd95SBruce Richardson struct rte_crypto_vec vec[UINT8_MAX];
12599a2dd95SBruce Richardson struct rte_crypto_sym_vec symvec;
12699a2dd95SBruce Richardson
12799a2dd95SBruce Richardson const uint32_t vnum = RTE_DIM(vec);
12899a2dd95SBruce Richardson
12999a2dd95SBruce Richardson j = 0, n = 0;
13099a2dd95SBruce Richardson vofs = 0;
13199a2dd95SBruce Richardson for (i = 0; i != num; i++) {
13299a2dd95SBruce Richardson
13399a2dd95SBruce Richardson vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i],
13499a2dd95SBruce Richardson &vec[vofs], vnum - vofs);
13599a2dd95SBruce Richardson
13699a2dd95SBruce Richardson /* not enough space in vec[] to hold all segments */
13799a2dd95SBruce Richardson if (vcnt < 0) {
13899a2dd95SBruce Richardson /* fill the request structure */
13910488d59SHemant Agrawal symvec.src_sgl = &vecpkt[j];
14099a2dd95SBruce Richardson symvec.iv = &iv[j];
14199a2dd95SBruce Richardson symvec.digest = &dgst[j];
14299a2dd95SBruce Richardson symvec.aad = &aad[j];
14399a2dd95SBruce Richardson symvec.status = &st[j];
14499a2dd95SBruce Richardson symvec.num = i - j;
14599a2dd95SBruce Richardson
14699a2dd95SBruce Richardson /* flush vec array and try again */
14799a2dd95SBruce Richardson n += rte_cryptodev_sym_cpu_crypto_process(
14899a2dd95SBruce Richardson ss->crypto.dev_id, ss->crypto.ses, ofs,
14999a2dd95SBruce Richardson &symvec);
15099a2dd95SBruce Richardson vofs = 0;
15199a2dd95SBruce Richardson vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i],
15299a2dd95SBruce Richardson vec, vnum);
15399a2dd95SBruce Richardson RTE_ASSERT(vcnt > 0);
15499a2dd95SBruce Richardson j = i;
15599a2dd95SBruce Richardson }
15699a2dd95SBruce Richardson
15799a2dd95SBruce Richardson vecpkt[i].vec = &vec[vofs];
15899a2dd95SBruce Richardson vecpkt[i].num = vcnt;
15999a2dd95SBruce Richardson vofs += vcnt;
16099a2dd95SBruce Richardson }
16199a2dd95SBruce Richardson
16299a2dd95SBruce Richardson /* fill the request structure */
16310488d59SHemant Agrawal symvec.src_sgl = &vecpkt[j];
16499a2dd95SBruce Richardson symvec.iv = &iv[j];
16599a2dd95SBruce Richardson symvec.aad = &aad[j];
16699a2dd95SBruce Richardson symvec.digest = &dgst[j];
16799a2dd95SBruce Richardson symvec.status = &st[j];
16899a2dd95SBruce Richardson symvec.num = i - j;
16999a2dd95SBruce Richardson
17099a2dd95SBruce Richardson n += rte_cryptodev_sym_cpu_crypto_process(ss->crypto.dev_id,
17199a2dd95SBruce Richardson ss->crypto.ses, ofs, &symvec);
17299a2dd95SBruce Richardson
17399a2dd95SBruce Richardson j = num - n;
17499a2dd95SBruce Richardson for (i = 0; j != 0 && i != num; i++) {
17599a2dd95SBruce Richardson if (st[i] != 0) {
176*daa02b5cSOlivier Matz mb[i]->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
17799a2dd95SBruce Richardson j--;
17899a2dd95SBruce Richardson }
17999a2dd95SBruce Richardson }
18099a2dd95SBruce Richardson }
18199a2dd95SBruce Richardson
18299a2dd95SBruce Richardson #endif /* _MISC_H_ */
183