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