/* SPDX-License-Identifier: BSD-3-Clause * Copyright(C) 2023 Marvell. */ #ifndef PDCP_ENTITY_H #define PDCP_ENTITY_H #include #include #include #include #include #include "pdcp_reorder.h" struct entity_priv; #define PDCP_HFN_MIN 0 /* IV generation function based on the entity configuration */ typedef void (*iv_gen_t)(struct rte_crypto_op *cop, const struct entity_priv *en_priv, uint32_t count); struct entity_state { uint32_t rx_next; uint32_t tx_next; uint32_t rx_deliv; uint32_t rx_reord; }; union auth_iv_partial { /* For AES-CMAC, there is no IV, but message gets prepended */ struct { #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN uint64_t count : 32; uint64_t zero_38_39 : 2; uint64_t direction : 1; uint64_t bearer : 5; uint64_t zero_40_63 : 24; #else uint64_t count : 32; uint64_t bearer : 5; uint64_t direction : 1; uint64_t zero_38_39 : 2; uint64_t zero_40_63 : 24; #endif } aes_cmac; struct { #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN uint64_t count : 32; uint64_t zero_37_39 : 3; uint64_t bearer : 5; uint64_t zero_40_63 : 24; uint64_t rsvd_65_71 : 7; uint64_t direction_64 : 1; uint64_t rsvd_72_111 : 40; uint64_t rsvd_113_119 : 7; uint64_t direction_112 : 1; uint64_t rsvd_120_127 : 8; #else uint64_t count : 32; uint64_t bearer : 5; uint64_t zero_37_39 : 3; uint64_t zero_40_63 : 24; uint64_t direction_64 : 1; uint64_t rsvd_65_71 : 7; uint64_t rsvd_72_111 : 40; uint64_t direction_112 : 1; uint64_t rsvd_113_119 : 7; uint64_t rsvd_120_127 : 8; #endif } zs; uint64_t u64[2]; }; union cipher_iv_partial { struct { #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN uint64_t count : 32; uint64_t zero_38_39 : 2; uint64_t direction : 1; uint64_t bearer : 5; uint64_t zero_40_63 : 24; #else uint64_t count : 32; uint64_t bearer : 5; uint64_t direction : 1; uint64_t zero_38_39 : 2; uint64_t zero_40_63 : 24; #endif uint64_t zero_64_127; } aes_ctr; struct { #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN uint64_t count : 32; uint64_t zero_38_39 : 2; uint64_t direction : 1; uint64_t bearer : 5; uint64_t zero_40_63 : 24; #else uint64_t count : 32; uint64_t bearer : 5; uint64_t direction : 1; uint64_t zero_38_39 : 2; uint64_t zero_40_63 : 24; #endif uint64_t rsvd_64_127; } zs; uint64_t u64[2]; }; enum timer_state { TIMER_STOP, TIMER_RUNNING, TIMER_EXPIRED, }; struct pdcp_t_reordering { /** Represent timer state */ enum timer_state state; /** User defined callback handles */ struct rte_pdcp_t_reordering handle; }; struct pdcp_cnt_bitmap { /** Number of entries that can be stored. */ uint32_t size; /** Bitmap of the count values already received.*/ struct rte_bitmap *bmp; }; /* * Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] [entity_dl/ul] [reorder/bitmap] */ struct entity_priv { /** Crypto sym session. */ struct rte_cryptodev_sym_session *crypto_sess; /** Entity specific IV generation function. */ iv_gen_t iv_gen; /** Pre-prepared auth IV. */ union auth_iv_partial auth_iv_part; /** Pre-prepared cipher IV. */ union cipher_iv_partial cipher_iv_part; /** Entity state variables. */ struct entity_state state; /** Flags. */ struct { /** PDCP PDU has 4 byte MAC-I. */ uint64_t is_authenticated : 1; /** Cipher offset & length in bits. */ uint64_t is_cipher_in_bits : 1; /** Auth offset & length in bits. */ uint64_t is_auth_in_bits : 1; /** Is UL/transmitting PDCP entity. */ uint64_t is_ul_entity : 1; /** Is NULL auth. */ uint64_t is_null_auth : 1; /** Is status report required.*/ uint64_t is_status_report_required : 1; /** Is out-of-order delivery enabled */ uint64_t is_out_of_order_delivery : 1; } flags; /** Crypto op pool. */ struct rte_mempool *cop_pool; /** Control PDU pool. */ struct rte_mempool *ctrl_pdu_pool; /** PDCP header size. */ uint8_t hdr_sz; /** PDCP AAD size. For AES-CMAC, additional message is prepended for the operation. */ uint8_t aad_sz; /** PDCP cipher skip size. When enabled, SDAP header needs to be skipped from ciphering */ uint8_t cipher_skip_sz; /** Device ID of the device to be used for offload. */ uint8_t dev_id; }; struct entity_priv_dl_part { /** PDCP would need to track the count values that are already received.*/ struct pdcp_cnt_bitmap bitmap; /** t-Reordering handles */ struct pdcp_t_reordering t_reorder; /** Reorder packet buffer */ struct pdcp_reorder reorder; /** Bitmap memory region */ uint8_t bitmap_mem[]; }; struct entity_priv_ul_part { /* * NOTE: when re-establish is supported, plain PDCP packets & COUNT values need to be * cached. */ uint8_t dummy; }; static inline struct entity_priv * entity_priv_get(const struct rte_pdcp_entity *entity) { return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity)); } static inline struct entity_priv_dl_part * entity_dl_part_get(const struct rte_pdcp_entity *entity) { return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) + sizeof(struct entity_priv)); } static inline struct entity_priv_ul_part * entity_ul_part_get(const struct rte_pdcp_entity *entity) { return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) + sizeof(struct entity_priv)); } static inline int pdcp_hdr_size_get(enum rte_security_pdcp_sn_size sn_size) { return RTE_ALIGN_MUL_CEIL(sn_size, 8) / 8; } static inline uint32_t pdcp_window_size_get(enum rte_security_pdcp_sn_size sn_size) { return 1 << (sn_size - 1); } static inline uint32_t pdcp_sn_mask_get(enum rte_security_pdcp_sn_size sn_size) { return (1 << sn_size) - 1; } static inline uint32_t pdcp_sn_from_count_get(uint32_t count, enum rte_security_pdcp_sn_size sn_size) { return (count & pdcp_sn_mask_get(sn_size)); } static inline uint32_t pdcp_hfn_mask_get(enum rte_security_pdcp_sn_size sn_size) { return ~pdcp_sn_mask_get(sn_size); } static inline uint32_t pdcp_hfn_from_count_get(uint32_t count, enum rte_security_pdcp_sn_size sn_size) { return (count & pdcp_hfn_mask_get(sn_size)) >> sn_size; } static inline uint32_t pdcp_count_from_hfn_sn_get(uint32_t hfn, uint32_t sn, enum rte_security_pdcp_sn_size sn_size) { return (((hfn << sn_size) & pdcp_hfn_mask_get(sn_size)) | (sn & pdcp_sn_mask_get(sn_size))); } static inline uint32_t pdcp_hfn_max(enum rte_security_pdcp_sn_size sn_size) { return (1 << (32 - sn_size)) - 1; } #endif /* PDCP_ENTITY_H */