[v2,1/3] common/cnxk: add ROC support to parse cnxk custom sa action

Message ID 20220504051118.2314804-1-kirankumark@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: Jerin Jacob
Headers
Series [v2,1/3] common/cnxk: add ROC support to parse cnxk custom sa action |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Kiran Kumar Kokkilagadda May 4, 2022, 5:11 a.m. UTC
  From: Kiran Kumar K <kirankumark@marvell.com>

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 <kirankumark@marvell.com>
---
 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(-)
  

Patch

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 826c6e99c1..e14f8a1f32 100644
--- a/drivers/common/cnxk/roc_nix_inl.c
+++ b/drivers/common/cnxk/roc_nix_inl.c
@@ -217,6 +217,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);
@@ -224,11 +232,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 fc88fd58bc..784f63d92a 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 6204139396..78cdf3a318 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -209,6 +209,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. */