From: Rakesh Kudurumalla <[email protected]> Added new PMD APIS to create custom profile and API to update SA table created during profile setup based on profile ID
Signed-off-by: Rakesh Kudurumalla <[email protected]> --- drivers/net/cnxk/cnxk_ethdev.h | 4 + drivers/net/cnxk/cnxk_ethdev_sec.c | 175 +++++++++++++++++++++++ drivers/net/cnxk/rte_pmd_cnxk.h | 216 +++++++++++++++++++++++++++++ 3 files changed, 395 insertions(+) diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h index 8691acc642..ea6a2be30e 100644 --- a/drivers/net/cnxk/cnxk_ethdev.h +++ b/drivers/net/cnxk/cnxk_ethdev.h @@ -26,6 +26,10 @@ #define CNXK_ETH_DEV_PMD_VERSION "1.0" +/* Macros for packing configuration fields */ +#define CNXK_FIELD_MASK(width) ((1ULL << (width)) - 1) +#define PACK(val, shift, width) (((uint64_t)((val) & CNXK_FIELD_MASK(width))) << (shift)) + /* Used for struct cnxk_eth_dev::flags */ #define CNXK_LINK_CFG_IN_PROGRESS_F BIT_ULL(0) diff --git a/drivers/net/cnxk/cnxk_ethdev_sec.c b/drivers/net/cnxk/cnxk_ethdev_sec.c index abb50d32de..fa7eacfbe4 100644 --- a/drivers/net/cnxk/cnxk_ethdev_sec.c +++ b/drivers/net/cnxk/cnxk_ethdev_sec.c @@ -348,6 +348,181 @@ rte_pmd_cnxk_hw_session_base_get(uint16_t portid, bool inb) return (union rte_pmd_cnxk_ipsec_hw_sa *)sa_base; } +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_cnxk_inl_inb_prof_sa_base_get, 25.11) +union rte_pmd_cnxk_ipsec_hw_sa * +rte_pmd_cnxk_inl_inb_prof_sa_base_get(uint16_t portid, uint16_t profile_id) +{ + struct rte_eth_dev *eth_dev; + struct cnxk_eth_dev *dev; + uintptr_t sa_base; + + if (!rte_eth_dev_is_valid_port(portid)) + return NULL; + + eth_dev = &rte_eth_devices[portid]; + dev = cnxk_eth_pmd_priv(eth_dev); + + sa_base = roc_nix_inl_inb_prof_sa_base_get(&dev->nix, !dev->inb.no_inl_dev, profile_id); + + if (!sa_base) + return NULL; + + return (union rte_pmd_cnxk_ipsec_hw_sa *)sa_base; +} + +static uint64_t +cnxk_rx_def_inl_cfg_pack(const struct rte_pmd_cnxk_rx_def_inl_cfg *cfg) +{ + uint64_t val = 0; + + val |= PACK(cfg->ltype_mask, NIX_LTYPE_MASK_SHIFT, 4); + val |= PACK(cfg->ltype_match, NIX_LTYPE_MATCH_SHIFT, 4); + val |= PACK(cfg->lid, NIX_LID_SHIFT, 3); + val |= PACK(cfg->gen_offset_ng, NIX_GEN_OFFSET_NG_SHIFT, 1); + val |= PACK(cfg->gen_offset, NIX_GEN_OFFSET_SHIFT, 4); + val |= PACK(cfg->gen_nz, NIX_GEN_NZ_SHIFT, 1); + val |= PACK(cfg->cpt_l3_lid, NIX_CPT_L3_LID_SHIFT, 3); + val |= PACK(cfg->flags_mask, NIX_FLAGS_MASK_SHIFT, 4); + val |= PACK(cfg->flags_match, NIX_FLAGS_MATCH_SHIFT, 4); + val |= PACK(cfg->match_oipv4, NIX_MATCH_OIPV4_SHIFT, 1); + val |= PACK(cfg->match_oipv6, NIX_MATCH_OIPV6_SHIFT, 1); + val |= PACK(cfg->oiplen_ena, NIX_OIPLEN_ENA_SHIFT, 1); + val |= PACK(cfg->inline_shift, NIX_INLINE_SHIFT_SHIFT, 2); + + return val; +} + +static uint64_t +cnxk_rx_gen_inl_cfg_pack(const struct rte_pmd_cnxk_rx_gen_inl_cfg *cfg) +{ + uint64_t val = 0; + + /* CPT instruction fields */ + val |= PACK(cfg->param2, NIX_PARAM2_SHIFT, 16); + val |= PACK(cfg->param1, NIX_PARAM1_SHIFT, 16); + val |= PACK(cfg->opcode, NIX_OPCODE_SHIFT, 16); + val |= PACK(cfg->egrp, NIX_EGRP_SHIFT, 3); + val |= PACK(cfg->ctx_val, NIX_CTX_VAL_SHIFT, 1); + + return val; +} + +static uint64_t +cnxk_rx_extract_inl_cfg_pack(const struct rte_pmd_cnxk_rx_extract_inl_cfg *cfg) +{ + uint64_t val = 0; + + val |= PACK(cfg->len_l, NIX_LEN_L_SHIFT, 6); + val |= PACK(cfg->bitpos_l, NIX_BITPOS_L_SHIFT, 6); + val |= PACK(cfg->len_m, NIX_LEN_M_SHIFT, 6); + val |= PACK(cfg->bitpos_m, NIX_BITPOS_M_SHIFT, 6); + val |= PACK(cfg->len_h, NIX_LEN_H_SHIFT, 6); + val |= PACK(cfg->bitpos_h, NIX_BITPOS_H_SHIFT, 6); + + return val; +} + +static uint64_t +cnxk_rx_prot_field_inline_cfg_pack(const struct rte_pmd_cnxk_rx_prot_field_inl_cfg *cfg) +{ + uint64_t val = 0; + + val |= PACK(cfg->valid, NIX_VALID_SHIFT, 1); + val |= PACK(cfg->offset, NIX_OFFSET_SHIFT, 6); + val |= PACK(cfg->sizem1, NIX_SIZEM1_SHIFT, 4); + val |= PACK(cfg->logmult, NIX_LOGMULT_SHIFT, 2); + + return val; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_cnxk_nix_inl_custom_profile_setup, 25.11) +int +rte_pmd_cnxk_nix_inl_custom_profile_setup(uint16_t portid, + const struct rte_pmd_cnxk_profile_cfg_params *cfg, + uint16_t *profile_id) +{ + uint64_t prot_field_cfg_val[RTE_PMD_CNXK_MAX_PROT_FIELDS] = {0}; + struct rte_eth_dev *eth_dev; + struct cnxk_eth_dev *dev; + uint64_t extract_cfg_val = 0; + uint64_t def_cfg_val = 0; + uint64_t gen_cfg_val = 0; + uint32_t sa_size = 0; + uint32_t max_sa = 0; + uint16_t prof_id = 0; + int rc = 0; + int i; + + if (!roc_feature_nix_has_inl_profile()) + return -ENOTSUP; + + if (!rte_eth_dev_is_valid_port(portid)) + return -EINVAL; + + if (!cfg || !profile_id) + return -EINVAL; + + eth_dev = &rte_eth_devices[portid]; + dev = cnxk_eth_pmd_priv(eth_dev); + + /* Pack default inline configuration */ + def_cfg_val = cnxk_rx_def_inl_cfg_pack(&cfg->def_cfg); + + /* Pack generic inline configuration */ + gen_cfg_val = cnxk_rx_gen_inl_cfg_pack(&cfg->gen_cfg); + + /* Pack extract inline configuration */ + extract_cfg_val = cnxk_rx_extract_inl_cfg_pack(&cfg->extract_cfg); + + /* Pack protocol field inline configurations */ + for (i = 0; i < RTE_PMD_CNXK_MAX_PROT_FIELDS; i++) + prot_field_cfg_val[i] = cnxk_rx_prot_field_inline_cfg_pack(&cfg->prot_field_cfg[i]); + + /* Get SA size and max SA count */ + sa_size = cfg->sa_size; + max_sa = cfg->max_sa; + + /* Call ROC API to configure the custom profile */ + rc = roc_nix_inl_custom_profile_setup(&dev->nix, def_cfg_val, gen_cfg_val, extract_cfg_val, + prot_field_cfg_val, sa_size, max_sa, + !dev->inb.no_inl_dev, &prof_id); + if (rc) { + plt_err("Failed to setup custom profile: rc=%d", rc); + return rc; + } + + *profile_id = prof_id; + + plt_nix_dbg("Custom profile setup: port=%u, sa_size=%u, max_sa=%u, profile_id=%u", portid, + sa_size, max_sa, *profile_id); + + return 0; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_cnxk_nix_inl_custom_profile_release, 25.11) +int +rte_pmd_cnxk_nix_inl_custom_profile_release(uint16_t portid, uint16_t profile_id) +{ + struct rte_eth_dev *eth_dev; + struct cnxk_eth_dev *dev; + int rc; + + if (!rte_eth_dev_is_valid_port(portid)) + return -EINVAL; + + eth_dev = &rte_eth_devices[portid]; + dev = cnxk_eth_pmd_priv(eth_dev); + + /* Call ROC API to release the custom profile */ + rc = roc_nix_inl_custom_profile_release(&dev->nix, profile_id, !dev->inb.no_inl_dev); + if (rc) { + plt_err("Failed to release custom profile %u: rc=%d", profile_id, rc); + return rc; + } + + return 0; +} + RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_cnxk_sa_flush, 23.11) int rte_pmd_cnxk_sa_flush(uint16_t portid, union rte_pmd_cnxk_ipsec_hw_sa *sess, bool inb) diff --git a/drivers/net/cnxk/rte_pmd_cnxk.h b/drivers/net/cnxk/rte_pmd_cnxk.h index d344137dd5..1960288cef 100644 --- a/drivers/net/cnxk/rte_pmd_cnxk.h +++ b/drivers/net/cnxk/rte_pmd_cnxk.h @@ -83,6 +83,15 @@ struct rte_pmd_cnxk_sec_action { */ enum rte_pmd_cnxk_sec_action_alg alg; bool is_non_inp; + /** Inline profile ID (0-7) for custom profiles. + * Only used when use_custom_profile is true. + * Use profile_id returned by rte_pmd_cnxk_nix_inl_custom_profile_setup(). + */ + uint16_t profile_id; + /** When true, use custom inline profile specified by profile_id. + * When false, use default IPsec profile (backward compatible). + */ + bool use_custom_profile; }; #define RTE_PMD_CNXK_CTX_MAX_CKEY_LEN 32 @@ -607,6 +616,21 @@ union rte_pmd_cnxk_cpt_res_s *rte_pmd_cnxk_inl_ipsec_res(struct rte_mbuf *mbuf); __rte_experimental union rte_pmd_cnxk_ipsec_hw_sa *rte_pmd_cnxk_hw_session_base_get(uint16_t portid, bool inb); +/** + * Get pointer to the Inline Inbound SA table base for a specific custom profile. + * + * @param portid + * Port identifier of Ethernet device. + * @param profile_id + * Custom profile ID to get the SA base for. + * + * @return + * Pointer to Inbound SA base for the specified profile, or NULL on error. + */ +__rte_experimental +union rte_pmd_cnxk_ipsec_hw_sa *rte_pmd_cnxk_inl_inb_prof_sa_base_get(uint16_t portid, + uint16_t profile_id); + /** * Executes a CPT flush on the specified session. * @@ -682,6 +706,198 @@ int rte_pmd_cnxk_cpt_q_stats_get(uint16_t portid, enum rte_pmd_cnxk_cpt_q_stats_ __rte_experimental void rte_pmd_cnxk_hw_inline_inb_cfg_set(uint16_t portid, struct rte_pmd_cnxk_ipsec_inb_cfg *cfg); +/** + * RX Default Inline Configuration structure + * This structure represents the NIX_AF_RX_DEF_INLINE register fields + * used for configuring inline IPsec processing. + */ +struct rte_pmd_cnxk_rx_def_inl_cfg { + /** Layer type mask (bits 3:0) */ + uint64_t ltype_mask; + /** Layer type match value (bits 7:4) */ + uint64_t ltype_match; + /** Layer ID (bits 10:8) - Enumerated by NPC_LID_E */ + uint64_t lid; + /** Generic offset negative (bit 11) */ + uint64_t gen_offset_ng; + /** Generic offset in bytes (bits 15:12) */ + uint64_t gen_offset; + /** Generic field non-zero (bit 16) */ + uint64_t gen_nz; + /** CPT L3 Layer ID (bits 19:17) */ + uint64_t cpt_l3_lid; + /** Layer type mask (bits 23:20) */ + uint64_t flags_mask; + /** Layer type match value (bits 27:24) */ + uint64_t flags_match; + /** Match on IPv4 (bit 28) */ + uint64_t match_oipv4; + /** Match on IPv6 (bit 29) */ + uint64_t match_oipv6; + /** OIP Length Enable (bit 30) */ + uint64_t oiplen_ena; + /** Inline shift (bits 33:32) - Valid values: 0, 1, 2 */ + uint64_t inline_shift; +}; + +/** + * RX Generic Inline Configuration structure + * This structure represents the NIX_AF_RX_INLINE_GEN_CFG(0..7) register fields. + */ +struct rte_pmd_cnxk_rx_gen_inl_cfg { + /** Layer type mask (bits 3:0) */ + uint64_t ltype_mask; + /** Layer type match value (bits 7:4) */ + uint64_t ltype_match; + /** Layer ID (bits 10:8) */ + uint64_t lid; + /** Nibble Offset (bit 11) - 0: IPv4, 1: IPv6 */ + uint64_t noffset; + /** Offset (bits 17:12) - Offset to DSCP field */ + uint64_t offset; + /** PARAM2 (bits 15:0) - CPT_INST_S[PARAM2] */ + uint64_t param2; + /** PARAM1 (bits 31:16) - CPT_INST_S[PARAM1] */ + uint64_t param1; + /** OPCODE (bits 47:32) - CPT_INST_S[OPCODE] */ + uint64_t opcode; + /** Engine Group (bits 50:48) - CPT_INST_S[EGRP] */ + uint64_t egrp; + /** Context Valid (bit 51) - CPT_INST_S[CTX_VAL] */ + uint64_t ctx_val; +}; + +/** + * RX Extract Inline Configuration structure + * This structure represents the NIX_AF_RX_EXTRACT_INLINE(0..7) register fields. + */ +struct rte_pmd_cnxk_rx_extract_inl_cfg { + /** LEN_L (bits 5:0) - Bit length from BITPOS_L (0-32) */ + uint64_t len_l; + /** BITPOS_L (bits 13:8) - Bit pos to start extraction */ + uint64_t bitpos_l; + /** LEN_M (bits 21:16) - Bit length from BITPOS_M (0-32) */ + uint64_t len_m; + /** BITPOS_M (bits 29:24) - Bit pos to start extraction */ + uint64_t bitpos_m; + /** LEN_H (bits 37:32) - Bit length from BITPOS_H (0-32) */ + uint64_t len_h; + /** BITPOS_H (bits 45:40) - Bit pos to start extraction */ + uint64_t bitpos_h; +}; + +/** + * Protocol field types for inline IPsec configuration + */ +enum rte_pmd_cnxk_nix_rx_prot_e { + RTE_PMD_CNXK_RX_PROT_OPCODE = 0, /**< Opcode (max 2 bytes) */ + RTE_PMD_CNXK_RX_PROT_PARAM1 = 1, /**< Parameter 1 (max 2 bytes) */ + RTE_PMD_CNXK_RX_PROT_PARAM2 = 2, /**< Parameter 2 (max 2 bytes) */ + RTE_PMD_CNXK_RX_PROT_SA_INDEX = 3, /**< SA index (max 4 bytes) */ + RTE_PMD_CNXK_RX_PROT_RPTR_H = 4, /**< RPTR high bits (max 4 bytes) */ + RTE_PMD_CNXK_RX_PROT_IP_OFFSET = 5, /**< IP offset (max 1 byte) */ + RTE_PMD_CNXK_RX_PROT_INL_OFFSET = 6, /**< Inline offset (max 4 bytes) */ + RTE_PMD_CNXK_RX_PROT_ALG = 7, /**< ALG override (max 1 nibble) */ + RTE_PMD_CNXK_RX_PROT_SUB_INDEX = 8, /**< Sub index (max 1 nibble) */ +}; + +/** Maximum number of inline profiles supported */ +#define RTE_PMD_CNXK_MAX_PROT_FIELDS 9 + +/** + * RX Protocol Field Inline Configuration structure + * This structure represents the NIX_AF_RX_PROT_FIELD(0..8)_INLINE(0..7) registers. + */ +struct rte_pmd_cnxk_rx_prot_field_inl_cfg { + /** LOGMULT (bits 13:12) - Multiply: 0=1, 1=2, 2=4, 3=8 */ + uint64_t logmult; + /** SIZEM1 (bits 11:8) - Size of field in nibbles */ + uint64_t sizem1; + /** OFFSET (bits 7:2) - Offset from header start in nibbles */ + uint64_t offset; + /** VALID (bit 0) - Valid flag */ + uint64_t valid; +}; + +/** + * Combined profile configuration parameters structure + * This structure combines all configuration parameters needed for + * setting up a custom inline IPsec profile. + */ +struct rte_pmd_cnxk_profile_cfg_params { + /** Default inline configuration (NIX_AF_RX_DEF_INLINE) */ + struct rte_pmd_cnxk_rx_def_inl_cfg def_cfg; + + /** Generic inline configuration (NIX_AF_RX_INLINE_GEN_CFG) */ + struct rte_pmd_cnxk_rx_gen_inl_cfg gen_cfg; + + /** Extract inline configuration (NIX_AF_RX_EXTRACT_INLINE) */ + struct rte_pmd_cnxk_rx_extract_inl_cfg extract_cfg; + + /** Protocol field inline configuration + * Array of configs for NIX_AF_RX_PROT_FIELD(prot_field)_INLINE(0..7) + */ + struct rte_pmd_cnxk_rx_prot_field_inl_cfg prot_field_cfg[RTE_PMD_CNXK_MAX_PROT_FIELDS]; + + /** SA size in bytes. + * Size of each SA entry for this profile. + * Must be a power of 2 and >= 128 bytes. + * If 0, default SA size is used. + */ + uint32_t sa_size; + + /** Maximum number of SAs for this profile. + * Number of SA entries to allocate for this profile. + * If 0, default max_sa is used. + */ + uint32_t max_sa; +}; + +/** + * Setup custom inline IPsec profile + * + * This function configures a custom inline IPsec profile for the specified port. + * The profile includes default inline configuration, generic inline configuration, + * extract inline configuration, protocol field inline configuration, and + * optional custom SA size and max SA count. + * + * @param portid + * Port identifier of the Ethernet device. + * @param cfg + * Pointer to the combined profile configuration structure. + * @param[out] profile_id + * Pointer to store the returned profile ID (0-7). + * This ID can be used in rte_pmd_cnxk_sec_action.profile_id. + * + * @return + * 0 on success, a negative errno value otherwise. + * - -EINVAL: Invalid parameters + * - -ENOTSUP: Function not supported on this device + * - -ENOSPC: No free profile available + * - -ENOMEM: Memory allocation failed for SA table + */ +__rte_experimental +int rte_pmd_cnxk_nix_inl_custom_profile_setup(uint16_t portid, + const struct rte_pmd_cnxk_profile_cfg_params *cfg, uint16_t *profile_id); + +/** + * Release a custom inline profile. + * + * This function releases resources associated with a custom inline profile + * that was previously created using rte_pmd_cnxk_nix_inl_custom_profile_setup(). + * + * @param portid + * Port identifier of the Ethernet device. + * @param profile_id + * Custom profile ID to release. + * + * @return + * 0 on success, a negative errno value otherwise. + */ +__rte_experimental +int rte_pmd_cnxk_nix_inl_custom_profile_release(uint16_t portid, + uint16_t profile_id); + /** * Retrieves model name on which it is running as a string. * -- 2.25.1

