[PATCH 2/2] net/cnxk: add PMD API to support custom profile setup
rkudurumalla
rkudurumalla at marvell.com
Tue May 5 10:50:37 CEST 2026
From: Rakesh Kudurumalla <rkudurumalla at marvell.com>
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 <rkudurumalla at marvell.com>
---
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
More information about the dev
mailing list