xref: /dpdk/lib/pdcp/rte_pdcp_group.h (revision b4f0a9bb5807a4f0a4904595bb85a9a386696311)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2023 Marvell.
3  */
4 
5 #ifndef RTE_PDCP_GROUP_H
6 #define RTE_PDCP_GROUP_H
7 
8 /**
9  * @file rte_pdcp_group.h
10  *
11  * RTE PDCP grouping support.
12  * It is not recommended to include this file directly, include <rte_pdcp.h>
13  * instead.
14  * Provides helper functions to process completed crypto-ops and group related
15  * packets by sessions they belong to.
16  */
17 
18 #include <rte_common.h>
19 #include <rte_crypto.h>
20 #include <rte_cryptodev.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /**
27  * Group packets belonging to same PDCP entity.
28  */
29 struct rte_pdcp_group {
30 	union {
31 		uint64_t val;
32 		void *ptr;
33 	} id; /**< Grouped by value */
34 	struct rte_mbuf **m;  /**< Start of the group */
35 	uint32_t cnt;         /**< Number of entries in the group */
36 	int32_t rc;           /**< Status code associated with the group */
37 };
38 
39 /**
40  * @warning
41  * @b EXPERIMENTAL: this API may change without prior notice.
42  *
43  * Take crypto-op as an input and extract pointer to related PDCP entity.
44  * @param cop
45  *   The address of an input *rte_crypto_op* structure.
46  * @return
47  *   The pointer to the related *rte_pdcp_entity* structure.
48  */
49 static inline struct rte_pdcp_entity *
rte_pdcp_en_from_cop(const struct rte_crypto_op * cop)50 rte_pdcp_en_from_cop(const struct rte_crypto_op *cop)
51 {
52 	void *sess = cop->sym[0].session;
53 
54 	return (struct rte_pdcp_entity *)(uintptr_t)
55 		rte_cryptodev_sym_session_opaque_data_get(sess);
56 }
57 
58 /**
59  * @warning
60  * @b EXPERIMENTAL: this API may change without prior notice.
61  *
62  * Take as input completed crypto ops, extract related mbufs and group them by
63  * *rte_pdcp_entity* they belong to. Mbuf for which the crypto operation has
64  * failed would be flagged using *RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED* flag
65  * in rte_mbuf.ol_flags. The crypto_ops would be freed after the grouping.
66  *
67  * Note that application must ensure only crypto-ops prepared by lib_pdcp is
68  * provided back to @see rte_pdcp_pkt_crypto_group().
69  *
70  * @param cop
71  *   The address of an array of *num* pointers to the input *rte_crypto_op*
72  *   structures.
73  * @param[out] mb
74  *   The address of an array of *num* pointers to output *rte_mbuf* structures.
75  * @param[out] grp
76  *   The address of an array of *num* to output *rte_pdcp_group* structures.
77  * @param num
78  *   The maximum number of crypto-ops to process.
79  * @return
80  *   Number of filled elements in *grp* array.
81  */
82 static inline uint16_t
rte_pdcp_pkt_crypto_group(struct rte_crypto_op * cop[],struct rte_mbuf * mb[],struct rte_pdcp_group grp[],uint16_t num)83 rte_pdcp_pkt_crypto_group(struct rte_crypto_op *cop[], struct rte_mbuf *mb[],
84 			  struct rte_pdcp_group grp[], uint16_t num)
85 {
86 	uint32_t i, j = 0, n = 0;
87 	void *ns, *ps = NULL;
88 	struct rte_mbuf *m;
89 
90 	for (i = 0; i != num; i++) {
91 		m = cop[i]->sym[0].m_src;
92 		ns = cop[i]->sym[0].session;
93 
94 		m->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
95 		if (cop[i]->status != RTE_CRYPTO_OP_STATUS_SUCCESS)
96 			m->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
97 
98 		/* Different entity */
99 		if (ps != ns) {
100 
101 			/* Finalize open group and start a new one */
102 			if (ps != NULL) {
103 				grp[n].cnt = mb + j - grp[n].m;
104 				n++;
105 			}
106 
107 			/* Start new group */
108 			grp[n].m = mb + j;
109 			ps = ns;
110 			grp[n].id.ptr =	rte_pdcp_en_from_cop(cop[i]);
111 		}
112 
113 		mb[j++] = m;
114 		rte_crypto_op_free(cop[i]);
115 	}
116 
117 	/* Finalize last group */
118 	if (ps != NULL) {
119 		grp[n].cnt = mb + j - grp[n].m;
120 		n++;
121 	}
122 
123 	return n;
124 }
125 
126 #ifdef __cplusplus
127 }
128 #endif
129 
130 #endif /* RTE_PDCP_GROUP_H */
131