xref: /dpdk/lib/pdcp/rte_pdcp.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2023 Marvell.
3  */
4 
5 #ifndef RTE_PDCP_H
6 #define RTE_PDCP_H
7 
8 /**
9  * @file rte_pdcp.h
10  *
11  * RTE PDCP support.
12  *
13  * A framework for PDCP protocol processing.
14  */
15 
16 #include <rte_compat.h>
17 #include <rte_common.h>
18 #include <rte_mempool.h>
19 #include <rte_pdcp_hdr.h>
20 #include <rte_security.h>
21 
22 /* Forward declarations. */
23 struct rte_pdcp_entity;
24 
25 /* PDCP pre-process function based on entity configuration. */
26 typedef uint16_t (*rte_pdcp_pre_p_t)(const struct rte_pdcp_entity *entity,
27 				     struct rte_mbuf *mb[],
28 				     struct rte_crypto_op *cop[],
29 				     uint16_t num, uint16_t *nb_err);
30 
31 /* PDCP post-process function based on entity configuration. */
32 typedef uint16_t (*rte_pdcp_post_p_t)(const struct rte_pdcp_entity *entity,
33 				      struct rte_mbuf *in_mb[],
34 				      struct rte_mbuf *out_mb[],
35 				      uint16_t num, uint16_t *nb_err);
36 
37 /**
38  * PDCP entity.
39  *
40  * 4.2.2 PDCP entities
41  *
42  * The PDCP entities are located in the PDCP sublayer.
43  * Several PDCP entities may be defined for a UE.
44  * Each PDCP entity is carrying the data of one radio bearer.
45  * A PDCP entity is associated either to the control plane or the user plane
46  * depending on which radio bearer it is carrying data for.
47  */
48 struct __rte_cache_aligned rte_pdcp_entity {
49 	/** Entity specific pre-process handle. */
50 	rte_pdcp_pre_p_t pre_process;
51 	/** Entity specific post-process handle. */
52 	rte_pdcp_post_p_t post_process;
53 	/**
54 	 * PDCP entities may hold packets for purposes of in-order delivery
55 	 * (in case of receiving PDCP entity) and re-transmission
56 	 * (in case of transmitting PDCP entity).
57 	 *
58 	 * The field 'max_pkt_cache' would be used to indicate the maximum
59 	 * number of packets that may be cached in an entity at any point of time.
60 	 * When application provides buffers to receive packets from PDCP entity,
61 	 * the size of the buffer should be such that it can
62 	 * hold additionally 'max_pkt_cache' number of packets.
63 	 */
64 	uint32_t max_pkt_cache;
65 };
66 
67 /**
68  * Callback function type for t-Reordering timer start, set during PDCP entity establish.
69  * This callback is invoked by PDCP library, during t-Reordering timer start event.
70  * Only one t-Reordering per receiving PDCP entity would be running at a given time.
71  *
72  * @see struct rte_pdcp_timer
73  * @see rte_pdcp_entity_establish()
74  *
75  * @param timer
76  *   Pointer to timer.
77  * @param args
78  *   Pointer to timer arguments.
79  */
80 typedef void (*rte_pdcp_t_reordering_start_cb_t)(void *timer, void *args);
81 
82 /**
83  * Callback function type for t-Reordering timer stop, set during PDCP entity establish.
84  * This callback will be invoked by PDCP library, during t-Reordering timer stop event.
85  *
86  * @see struct rte_pdcp_timer
87  * @see rte_pdcp_entity_establish()
88  *
89  * @param timer
90  *   Pointer to timer.
91  * @param args
92  *   Pointer to timer arguments.
93  */
94 typedef void (*rte_pdcp_t_reordering_stop_cb_t)(void *timer, void *args);
95 
96 /**
97  * PDCP t-Reordering timer interface
98  *
99  * Configuration provided by user, that PDCP library will invoke according to timer behaviour.
100  */
101 /* Structure rte_pdcp_t_reordering 8< */
102 struct rte_pdcp_t_reordering {
103 	/** Timer pointer, to be used in callback functions. */
104 	void *timer;
105 	/** Timer arguments, to be used in callback functions. */
106 	void *args;
107 	/** Timer start callback handle. */
108 	rte_pdcp_t_reordering_start_cb_t start;
109 	/** Timer stop callback handle. */
110 	rte_pdcp_t_reordering_stop_cb_t stop;
111 };
112 /* >8 End of structure rte_pdcp_t_reordering. */
113 
114 /**
115  * PDCP entity configuration to be used for establishing an entity.
116  */
117 /* Structure rte_pdcp_entity_conf 8< */
118 struct rte_pdcp_entity_conf {
119 	/** PDCP transform for the entity. */
120 	struct rte_security_pdcp_xform pdcp_xfrm;
121 	/** Crypto transform applicable for the entity. */
122 	struct rte_crypto_sym_xform *crypto_xfrm;
123 	/** Mempool for crypto symmetric session. */
124 	struct rte_mempool *sess_mpool;
125 	/** Crypto op pool. */
126 	struct rte_mempool *cop_pool;
127 	/** Mbuf pool to be used for allocating control PDUs.*/
128 	struct rte_mempool *ctrl_pdu_pool;
129 	/**
130 	 * Sequence number value to be used.
131 	 * 32 bit count value to be used for the first packet
132 	 * would be derived based on HFN (`rte_security_pdcp_xform.hfn`) and SN.
133 	 */
134 	uint32_t sn;
135 	/** Indicate whether the PDCP entity belongs to Side Link Radio Bearer. */
136 	bool is_slrb;
137 	/** Enable security offload on the device specified. */
138 	bool en_sec_offload;
139 	/** Device on which security/crypto session need to be created. */
140 	uint8_t dev_id;
141 	/**
142 	 * Reverse direction during IV generation.
143 	 * Can be used to simulate UE crypto processing.
144 	 */
145 	bool reverse_iv_direction;
146 	/**
147 	 * Status report required (specified in TS 38.331).
148 	 *
149 	 * If PDCP entity is configured to send a PDCP status report,
150 	 * the upper layer application may request a receiving PDCP entity
151 	 * to generate a PDCP status report using ``rte_pdcp_control_pdu_create``.
152 	 * In addition, PDCP status reports may be generated during operations
153 	 * such as entity re-establishment.
154 	 */
155 	bool status_report_required;
156 	/** Enable out of order delivery. */
157 	bool out_of_order_delivery;
158 	/** t-Reordering timer configuration. */
159 	struct rte_pdcp_t_reordering t_reordering;
160 };
161 /* >8 End of structure rte_pdcp_entity_conf. */
162 
163 /**
164  * @warning
165  * @b EXPERIMENTAL: this API may change without prior notice.
166  *
167  * 5.1.1 PDCP entity establishment
168  *
169  * Establish PDCP entity based on provided input configuration.
170  *
171  * @param conf
172  *   Parameters to be used for initializing PDCP entity object.
173  * @return
174  *   - Valid handle if success
175  *   - NULL in case of failure. rte_errno will be set to error code.
176  */
177 __rte_experimental
178 struct rte_pdcp_entity *
179 rte_pdcp_entity_establish(const struct rte_pdcp_entity_conf *conf);
180 
181 /**
182  * @warning
183  * @b EXPERIMENTAL: this API may change without prior notice.
184  *
185  * 5.1.3 PDCP entity release
186  *
187  * Release PDCP entity.
188  *
189  * For UL/transmitting PDCP entity, all stored PDCP SDUs would be dropped.
190  * For DL/receiving PDCP entity, the stored PDCP SDUs would be returned in
191  * *out_mb* buffer. The buffer should be large enough to hold all cached
192  * packets in the entity.
193  *
194  * Entity release would result in freeing all memory associated with the PDCP
195  * entity as well as any crypto/security sessions created.
196  *
197  * @param pdcp_entity
198  *   Pointer to the PDCP entity to be released.
199  * @param[out] out_mb
200  *   The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
201  *   pointers to *rte_mbuf* structures.
202  * @return
203  *   -  0: Success and no cached packets to return
204  *   - >0: Success and the number of packets returned in out_mb
205  *   - <0: Error code in case of failures
206  */
207 __rte_experimental
208 int
209 rte_pdcp_entity_release(struct rte_pdcp_entity *pdcp_entity,
210 			struct rte_mbuf *out_mb[]);
211 
212 /**
213  * @warning
214  * @b EXPERIMENTAL: this API may change without prior notice.
215  *
216  * 5.1.4 PDCP entity suspend
217  *
218  * Suspend PDCP entity.
219  *
220  * For DL/receiving PDCP entity, the stored PDCP SDUs would be returned in
221  * *out_mb* buffer. The buffer should be large enough to hold all cached
222  * packets in the entity.
223  *
224  * For UL/transmitting PDCP entity, *out_mb* buffer would be unused.
225  *
226  * @param pdcp_entity
227  *   Pointer to the PDCP entity to be suspended.
228  * @param[out] out_mb
229  *   The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
230  *   pointers to *rte_mbuf* structures.
231  * @return
232  *   -  0: Success and no cached packets to return.
233  *   - >0: Success and the number of packets returned in out_mb.
234  *   - <0: Error code in case of failures.
235  */
236 __rte_experimental
237 int
238 rte_pdcp_entity_suspend(struct rte_pdcp_entity *pdcp_entity,
239 			struct rte_mbuf *out_mb[]);
240 
241 /**
242  * @warning
243  * @b EXPERIMENTAL: this API may change without prior notice.
244  *
245  * Create control PDU packet of the `type` specified. The control PDU packet
246  * would be allocated from *rte_pdcp_entity_conf.ctrl_pdu_pool* by lib PDCP.
247  *
248  * @param pdcp_entity
249  *   Pointer to the PDCP entity for which the control PDU need to be generated.
250  * @param type
251  *   Type of control PDU to be generated.
252  * @return
253  *   - Control PDU generated, in case of success.
254  *   - NULL in case of failure. rte_errno will be set to error code.
255  */
256 __rte_experimental
257 struct rte_mbuf *
258 rte_pdcp_control_pdu_create(struct rte_pdcp_entity *pdcp_entity,
259 			    enum rte_pdcp_ctrl_pdu_type type);
260 
261 /**
262  * @warning
263  * @b EXPERIMENTAL: this API may change without prior notice.
264  *
265  * For input mbufs and given PDCP entity pre-process the mbufs and prepare
266  * crypto ops that can be enqueued to the cryptodev associated with given
267  * session. Only error packets would be moved returned in the input buffer,
268  * *mb*, and it is the responsibility of the application to free the same.
269  *
270  * @param entity
271  *   Pointer to the *rte_pdcp_entity* object the packets belong to.
272  * @param[in, out] mb
273  *   The address of an array of *num* pointers to *rte_mbuf* structures
274  *   which contain the input packets.
275  *   Any error packets would be returned in the same buffer.
276  * @param[out] cop
277  *   The address of an array that can hold up to *num* pointers to
278  *   *rte_crypto_op* structures. Crypto ops would be allocated by
279  *   ``rte_pdcp_pkt_pre_process`` API.
280  * @param num
281  *   The maximum number of packets to process.
282  * @param[out] nb_err
283  *   Pointer to return the number of error packets returned in *mb*.
284  * @return
285  *   Count of crypto_ops prepared.
286  */
287 __rte_experimental
288 static inline uint16_t
289 rte_pdcp_pkt_pre_process(const struct rte_pdcp_entity *entity,
290 			 struct rte_mbuf *mb[], struct rte_crypto_op *cop[],
291 			 uint16_t num, uint16_t *nb_err)
292 {
293 	return entity->pre_process(entity, mb, cop, num, nb_err);
294 }
295 
296 /**
297  * @warning
298  * @b EXPERIMENTAL: this API may change without prior notice.
299  *
300  * For input mbufs and given PDCP entity, perform PDCP post-processing of the mbufs.
301  *
302  * Input mbufs are the ones retrieved from rte_crypto_ops dequeued from cryptodev
303  * and grouped by *rte_pdcp_pkt_crypto_group()*.
304  *
305  * The post-processed packets would be returned in the *out_mb* buffer.
306  * The resultant mbufs would be grouped into success packets and error packets.
307  * Error packets would be grouped in the end of the array and
308  * it is the responsibility of the application to handle the same.
309  *
310  * When in-order delivery is enabled, PDCP entity may buffer packets and would
311  * deliver packets only when all prior packets have been post-processed.
312  * That would result in returning more/less packets than enqueued.
313  *
314  * @param entity
315  *   Pointer to the *rte_pdcp_entity* object the packets belong to.
316  * @param in_mb
317  *   The address of an array of *num* pointers to *rte_mbuf* structures.
318  * @param[out] out_mb
319  *   The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
320  *   pointers to *rte_mbuf* structures to output packets after PDCP post-processing.
321  * @param num
322  *   The maximum number of packets to process.
323  * @param[out] nb_err
324  *   The number of error packets returned in *out_mb* buffer.
325  * @return
326  *   Count of packets returned in *out_mb* buffer.
327  */
328 __rte_experimental
329 static inline uint16_t
330 rte_pdcp_pkt_post_process(const struct rte_pdcp_entity *entity,
331 			  struct rte_mbuf *in_mb[],
332 			  struct rte_mbuf *out_mb[],
333 			  uint16_t num, uint16_t *nb_err)
334 {
335 	return entity->post_process(entity, in_mb, out_mb, num, nb_err);
336 }
337 
338 /**
339  * @warning
340  * @b EXPERIMENTAL: this API may change without prior notice
341  *
342  * 5.2.2.2 Actions when a t-Reordering expires
343  *
344  * When t-Reordering timer expires, PDCP is required to slide the reception
345  * window by updating state variables such as RX_REORD & RX_DELIV.
346  * PDCP would need to deliver some of the buffered packets
347  * based on the state variables and conditions described.
348  *
349  * The expiry handle need to be invoked by the application when t-Reordering
350  * timer expires. In addition to returning buffered packets, it may also restart
351  * timer based on the state variables.
352  *
353  * @param entity
354  *   Pointer to the *rte_pdcp_entity* for which the timer expired.
355  * @param[out] out_mb
356  *   The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
357  *   pointers to *rte_mbuf* structures. Used to return buffered packets that are expired.
358  * @return
359  *   Number of packets returned in *out_mb* buffer.
360  */
361 __rte_experimental
362 uint16_t
363 rte_pdcp_t_reordering_expiry_handle(const struct rte_pdcp_entity *entity,
364 				    struct rte_mbuf *out_mb[]);
365 
366 /**
367  * The header 'rte_pdcp_group.h' depends on defines in 'rte_pdcp.h'.
368  * So include in the end.
369  */
370 #include <rte_pdcp_group.h>
371 
372 #ifdef __cplusplus
373 extern "C" {
374 #endif
375 
376 #ifdef __cplusplus
377 }
378 #endif
379 
380 #endif /* RTE_PDCP_H */
381