From bbe8d1f198a978ae43394a01c6db6ad4d21057fe Mon Sep 17 00:00:00 2001 From: Kiran Kumar K Date: Wed, 4 May 2022 10:41:16 +0530 Subject: [PATCH] common/cnxk: support parsing custom SA action Adding ROC Flow changes to parse custom SA action for cnxk device. When custom sa action is enabled, VTAG actions are not allowed. And custom SA index will be calculated based on SA_HI and SA_LO values. This allows the potential for a MCAM entry to match many SAs, rather than only match a single SA. Signed-off-by: Kiran Kumar K Acked-by: Jerin Jacob --- drivers/common/cnxk/roc_nix.h | 1 + drivers/common/cnxk/roc_nix_inl.c | 13 ++++--- drivers/common/cnxk/roc_npc.c | 58 +++++++++++++++++++++++++++++++ drivers/common/cnxk/roc_npc.h | 19 ++++++++++ 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h index dbb816d961..7313cc4d36 100644 --- a/drivers/common/cnxk/roc_nix.h +++ b/drivers/common/cnxk/roc_nix.h @@ -405,6 +405,7 @@ struct roc_nix { bool io_enabled; bool rx_ptp_ena; uint16_t cints; + bool custom_sa_action; #define ROC_NIX_MEM_SZ (6 * 1024) uint8_t reserved[ROC_NIX_MEM_SZ] __plt_cache_aligned; diff --git a/drivers/common/cnxk/roc_nix_inl.c b/drivers/common/cnxk/roc_nix_inl.c index 569b7f6da2..cba1ae93ee 100644 --- a/drivers/common/cnxk/roc_nix_inl.c +++ b/drivers/common/cnxk/roc_nix_inl.c @@ -219,6 +219,14 @@ roc_nix_inl_inb_sa_get(struct roc_nix *roc_nix, bool inb_inl_dev, uint32_t spi) if (!sa_base) return 0; + /* Get SA size */ + sz = roc_nix_inl_inb_sa_sz(roc_nix, inb_inl_dev); + if (!sz) + return 0; + + if (roc_nix->custom_sa_action) + return (sa_base + (spi * sz)); + /* Check if SPI is in range */ mask = roc_nix_inl_inb_spi_range(roc_nix, inb_inl_dev, &min_spi, &max_spi); @@ -226,11 +234,6 @@ roc_nix_inl_inb_sa_get(struct roc_nix *roc_nix, bool inb_inl_dev, uint32_t spi) plt_warn("Inbound SA SPI %u not in range (%u..%u)", spi, min_spi, max_spi); - /* Get SA size */ - sz = roc_nix_inl_inb_sa_sz(roc_nix, inb_inl_dev); - if (!sz) - return 0; - /* Basic logic of SPI->SA for now */ return (sa_base + ((spi & mask) * sz)); } diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c index 51e36f141f..c8ada96bfb 100644 --- a/drivers/common/cnxk/roc_npc.c +++ b/drivers/common/cnxk/roc_npc.c @@ -293,6 +293,48 @@ roc_npc_validate_portid_action(struct roc_npc *roc_npc_src, return 0; } +static int +npc_parse_msns_action(struct roc_npc *roc_npc, const struct roc_npc_action *act, + struct roc_npc_flow *flow, uint8_t *has_msns_action) +{ + const struct roc_npc_sec_action *sec_action; + union { + uint64_t reg; + union nix_rx_vtag_action_u act; + } vtag_act; + + if (roc_npc->roc_nix->custom_sa_action == 0 || + roc_model_is_cn9k() == 1 || act->conf == NULL) + return 0; + + *has_msns_action = true; + sec_action = act->conf; + + vtag_act.reg = 0; + vtag_act.act.sa_xor = sec_action->sa_xor; + vtag_act.act.sa_hi = sec_action->sa_hi; + vtag_act.act.sa_lo = sec_action->sa_lo; + + switch (sec_action->alg) { + case ROC_NPC_SEC_ACTION_ALG0: + break; + case ROC_NPC_SEC_ACTION_ALG1: + vtag_act.act.vtag1_valid = false; + vtag_act.act.vtag1_lid = ROC_NPC_SEC_ACTION_ALG1; + break; + case ROC_NPC_SEC_ACTION_ALG2: + vtag_act.act.vtag1_valid = false; + vtag_act.act.vtag1_lid = ROC_NPC_SEC_ACTION_ALG2; + break; + default: + return -1; + } + + flow->vtag_action = vtag_act.reg; + + return 0; +} + static int npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, const struct roc_npc_action actions[], @@ -305,11 +347,13 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, const struct roc_npc_action_queue *act_q; const struct roc_npc_action_vf *vf_act; bool vlan_insert_action = false; + uint8_t has_msns_act = 0; int sel_act, req_act = 0; uint16_t pf_func, vf_id; int errcode = 0; int mark = 0; int rq = 0; + int rc = 0; /* Initialize actions */ flow->ctr_id = NPC_COUNTER_NONE; @@ -399,6 +443,12 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, rq = 0; pf_func = nix_inl_dev_pffunc_get(); } + rc = npc_parse_msns_action(roc_npc, actions, flow, + &has_msns_act); + if (rc) { + errcode = NPC_ERR_ACTION_NOTSUP; + goto err_exit; + } break; case ROC_NPC_ACTION_TYPE_VLAN_STRIP: req_act |= ROC_NPC_ACTION_TYPE_VLAN_STRIP; @@ -438,6 +488,14 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, goto err_exit; } + if (has_msns_act && (vlan_insert_action || + (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP))) { + plt_err("Both MSNS and VLAN insert/strip action can't be supported" + " together"); + errcode = NPC_ERR_ACTION_NOTSUP; + goto err_exit; + } + /* Both STRIP and INSERT actions are not supported */ if (vlan_insert_action && (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP)) { errcode = NPC_ERR_ACTION_NOTSUP; diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h index 723eadc649..ac985e7b31 100644 --- a/drivers/common/cnxk/roc_npc.h +++ b/drivers/common/cnxk/roc_npc.h @@ -210,6 +210,25 @@ struct roc_npc_action_meter { uint32_t mtr_id; /**< Meter id to be applied. > */ }; +enum roc_npc_sec_action_alg { + ROC_NPC_SEC_ACTION_ALG0, + ROC_NPC_SEC_ACTION_ALG1, + ROC_NPC_SEC_ACTION_ALG2, + ROC_NPC_SEC_ACTION_ALG3, +}; + +struct roc_npc_sec_action { + /* Used as lookup result for ALG3 */ + uint32_t sa_index; + /* When true XOR initial SA_INDEX with SA_HI/SA_LO to get SA_MCAM */ + bool sa_xor; + uint16_t sa_hi, sa_lo; + /* Determines alg to be applied post SA_MCAM computation with/without + * XOR + */ + enum roc_npc_sec_action_alg alg; +}; + struct roc_npc_attr { uint32_t priority; /**< Rule priority level within group. */ uint32_t ingress : 1; /**< Rule applies to ingress traffic. */ -- 2.39.5