[09/27] common/cnxk: support RoC API to setup precolor table

Message ID 20210906075450.1452123-9-skori@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: Jerin Jacob
Headers
Series [01/27] common/cnxk: update policer MBOX APIs and HW definitions |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Sunil Kumar Kori Sept. 6, 2021, 7:54 a.m. UTC
  From: Sunil Kumar Kori <skori@marvell.com>

For initial coloring of input packet, CN10K platform maintains
precolor table for VLAN, DSCP and Generic. Implement RoC
interface to setup pre color table.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 drivers/common/cnxk/roc_nix.h     |  20 ++++
 drivers/common/cnxk/roc_nix_bpf.c | 188 ++++++++++++++++++++++++++++++
 drivers/common/cnxk/version.map   |   1 +
 3 files changed, 209 insertions(+)
  

Patch

diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index 19c376e9c4..36f6a35c50 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -87,6 +87,15 @@  enum roc_nix_bpf_level_flag {
 	ROC_NIX_BPF_LEVEL_F_TOP = BIT(2),
 };
 
+enum roc_nix_bpf_pc_mode {
+	ROC_NIX_BPF_PC_MODE_VLAN_INNER,
+	ROC_NIX_BPF_PC_MODE_VLAN_OUTER,
+	ROC_NIX_BPF_PC_MODE_DSCP_INNER,
+	ROC_NIX_BPF_PC_MODE_DSCP_OUTER,
+	ROC_NIX_BPF_PC_MODE_GEN_INNER,
+	ROC_NIX_BPF_PC_MODE_GEN_OUTER
+};
+
 enum roc_nix_bpf_color {
 	ROC_NIX_BPF_COLOR_GREEN,
 	ROC_NIX_BPF_COLOR_YELLOW,
@@ -149,6 +158,13 @@  struct roc_nix_bpf_objs {
 	uint16_t ids[ROC_NIX_BPF_PER_PFFUNC];
 };
 
+struct roc_nix_bpf_precolor {
+#define ROC_NIX_BPF_PRE_COLOR_MAX 64
+	uint8_t count;
+	enum roc_nix_bpf_pc_mode mode;
+	enum roc_nix_bpf_color color[ROC_NIX_BPF_PRE_COLOR_MAX];
+};
+
 struct roc_nix_vlan_config {
 	uint32_t type;
 	union {
@@ -610,6 +626,10 @@  int __roc_api roc_nix_bpf_ena_dis(struct roc_nix *roc_nix, uint16_t id,
 int __roc_api roc_nix_bpf_dump(struct roc_nix *roc_nix, uint16_t id,
 			       enum roc_nix_bpf_level_flag lvl_flag);
 
+int __roc_api roc_nix_bpf_pre_color_tbl_setup(
+	struct roc_nix *roc_nix, uint16_t id,
+	enum roc_nix_bpf_level_flag lvl_flag, struct roc_nix_bpf_precolor *tbl);
+
 uint8_t __roc_api
 roc_nix_bpf_level_to_idx(enum roc_nix_bpf_level_flag lvl_flag);
 
diff --git a/drivers/common/cnxk/roc_nix_bpf.c b/drivers/common/cnxk/roc_nix_bpf.c
index 2b2be20491..aae6f0ec77 100644
--- a/drivers/common/cnxk/roc_nix_bpf.c
+++ b/drivers/common/cnxk/roc_nix_bpf.c
@@ -9,6 +9,10 @@ 
 #define NIX_MAX_BPF_COUNT_MID_LAYER  8
 #define NIX_MAX_BPF_COUNT_TOP_LAYER  1
 
+#define NIX_BPF_PRECOLOR_GEN_TABLE_SIZE	 16
+#define NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE 16
+#define NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE 64
+
 #define NIX_BPF_LEVEL_F_MASK                                                   \
 	(ROC_NIX_BPF_LEVEL_F_LEAF | ROC_NIX_BPF_LEVEL_F_MID |                  \
 	 ROC_NIX_BPF_LEVEL_F_TOP)
@@ -177,6 +181,103 @@  nix_lf_bpf_dump(__io struct nix_band_prof_s *bpf)
 		 (uint64_t)bpf->red_octs_drop);
 }
 
+static inline void
+nix_precolor_conv_table_write(struct roc_nix *roc_nix, uint64_t val,
+			      uint32_t off)
+{
+	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+	int64_t *addr;
+
+	addr = PLT_PTR_ADD(nix->base, off);
+	plt_write64(val, addr);
+}
+
+static uint8_t
+nix_precolor_vlan_table_update(struct roc_nix *roc_nix,
+			       struct roc_nix_bpf_precolor *tbl)
+{
+	uint64_t val = 0, i;
+	uint8_t tn_ena;
+	uint32_t off;
+
+	for (i = 0; i < tbl->count; i++)
+		val |= (((uint64_t)tbl->color[i]) << (2 * i));
+
+	if (tbl->mode == ROC_NIX_BPF_PC_MODE_VLAN_INNER) {
+		off = NIX_LF_RX_VLAN1_COLOR_CONV;
+		tn_ena = true;
+	} else {
+		off = NIX_LF_RX_VLAN0_COLOR_CONV;
+		tn_ena = false;
+	}
+
+	nix_precolor_conv_table_write(roc_nix, val, off);
+	return tn_ena;
+}
+
+static uint8_t
+nix_precolor_inner_dscp_table_update(struct roc_nix *roc_nix,
+				     struct roc_nix_bpf_precolor *tbl)
+{
+	uint64_t val_lo = 0, val_hi = 0, i, j;
+
+	for (i = 0, j = 0; i < (tbl->count / 2); i++, j++)
+		val_lo |= (((uint64_t)tbl->color[i]) << (2 * j));
+
+	for (j = 0; i < tbl->count; i++, j++)
+		val_hi |= (((uint64_t)tbl->color[i]) << (2 * j));
+
+	nix_precolor_conv_table_write(roc_nix, val_lo,
+				      NIX_LF_RX_IIP_COLOR_CONV_LO);
+	nix_precolor_conv_table_write(roc_nix, val_hi,
+				      NIX_LF_RX_IIP_COLOR_CONV_HI);
+
+	return true;
+}
+
+static uint8_t
+nix_precolor_outer_dscp_table_update(struct roc_nix *roc_nix,
+				     struct roc_nix_bpf_precolor *tbl)
+{
+	uint64_t val_lo = 0, val_hi = 0, i, j;
+
+	for (i = 0, j = 0; i < (tbl->count / 2); i++, j++)
+		val_lo |= (((uint64_t)tbl->color[i]) << (2 * j));
+
+	for (j = 0; i < tbl->count; i++, j++)
+		val_hi |= (((uint64_t)tbl->color[i]) << (2 * j));
+
+	nix_precolor_conv_table_write(roc_nix, val_lo,
+				      NIX_LF_RX_OIP_COLOR_CONV_LO);
+	nix_precolor_conv_table_write(roc_nix, val_hi,
+				      NIX_LF_RX_OIP_COLOR_CONV_HI);
+
+	return false;
+}
+
+static uint8_t
+nix_precolor_gen_table_update(struct roc_nix *roc_nix,
+			      struct roc_nix_bpf_precolor *tbl)
+{
+	uint64_t val = 0, i;
+	uint8_t tn_ena;
+	uint32_t off;
+
+	for (i = 0; i < tbl->count; i++)
+		val |= (((uint64_t)tbl->color[i]) << (2 * i));
+
+	if (tbl->mode == ROC_NIX_BPF_PC_MODE_GEN_INNER) {
+		off = NIX_LF_RX_GEN_COLOR_CONVX(1);
+		tn_ena = true;
+	} else {
+		off = NIX_LF_RX_GEN_COLOR_CONVX(0);
+		tn_ena = false;
+	}
+
+	nix_precolor_conv_table_write(roc_nix, val, off);
+	return tn_ena;
+}
+
 uint8_t
 roc_nix_bpf_level_to_idx(enum roc_nix_bpf_level_flag level_f)
 {
@@ -555,3 +656,90 @@  roc_nix_bpf_dump(struct roc_nix *roc_nix, uint16_t id,
 
 	return rc;
 }
+
+int
+roc_nix_bpf_pre_color_tbl_setup(struct roc_nix *roc_nix, uint16_t id,
+				enum roc_nix_bpf_level_flag lvl_flag,
+				struct roc_nix_bpf_precolor *tbl)
+{
+	struct mbox *mbox = get_mbox(roc_nix);
+	struct nix_cn10k_aq_enq_req *aq;
+	uint8_t pc_mode, tn_ena;
+	uint8_t level_idx;
+	int rc;
+
+	if (!tbl || !tbl->count)
+		return NIX_ERR_PARAM;
+
+	if (roc_model_is_cn9k())
+		return NIX_ERR_HW_NOTSUP;
+
+	level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
+	if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
+		return NIX_ERR_PARAM;
+
+	switch (tbl->mode) {
+	case ROC_NIX_BPF_PC_MODE_VLAN_INNER:
+	case ROC_NIX_BPF_PC_MODE_VLAN_OUTER:
+		if (tbl->count != NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE) {
+			plt_err("Table size must be %d",
+				NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE);
+			rc = NIX_ERR_PARAM;
+			goto exit;
+		}
+		tn_ena = nix_precolor_vlan_table_update(roc_nix, tbl);
+		pc_mode = NIX_RX_BAND_PROF_PC_MODE_VLAN;
+		break;
+	case ROC_NIX_BPF_PC_MODE_DSCP_INNER:
+		if (tbl->count != NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE) {
+			plt_err("Table size must be %d",
+				NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE);
+			rc = NIX_ERR_PARAM;
+			goto exit;
+		}
+		tn_ena = nix_precolor_inner_dscp_table_update(roc_nix, tbl);
+		pc_mode = NIX_RX_BAND_PROF_PC_MODE_DSCP;
+		break;
+	case ROC_NIX_BPF_PC_MODE_DSCP_OUTER:
+		if (tbl->count != NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE) {
+			plt_err("Table size must be %d",
+				NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE);
+			rc = NIX_ERR_PARAM;
+			goto exit;
+		}
+		tn_ena = nix_precolor_outer_dscp_table_update(roc_nix, tbl);
+		pc_mode = NIX_RX_BAND_PROF_PC_MODE_DSCP;
+		break;
+	case ROC_NIX_BPF_PC_MODE_GEN_INNER:
+	case ROC_NIX_BPF_PC_MODE_GEN_OUTER:
+		if (tbl->count != NIX_BPF_PRECOLOR_GEN_TABLE_SIZE) {
+			plt_err("Table size must be %d",
+				NIX_BPF_PRECOLOR_GEN_TABLE_SIZE);
+			rc = NIX_ERR_PARAM;
+			goto exit;
+		}
+		tn_ena = nix_precolor_gen_table_update(roc_nix, tbl);
+		pc_mode = NIX_RX_BAND_PROF_PC_MODE_GEN;
+		break;
+	default:
+		rc = NIX_ERR_PARAM;
+		goto exit;
+	}
+
+	/* Update corresponding bandwidth profile too */
+	aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+	if (aq == NULL)
+		return -ENOSPC;
+	aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14) | id;
+	aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
+	aq->op = NIX_AQ_INSTOP_WRITE;
+	aq->prof.pc_mode = pc_mode;
+	aq->prof.tnl_ena = tn_ena;
+	aq->prof_mask.pc_mode = ~(aq->prof_mask.pc_mode);
+	aq->prof_mask.tnl_ena = ~(aq->prof_mask.tnl_ena);
+
+	return mbox_process(mbox);
+
+exit:
+	return rc;
+}
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index a201f6a755..984c239766 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -82,6 +82,7 @@  INTERNAL {
 	roc_nix_bpf_free;
 	roc_nix_bpf_free_all;
 	roc_nix_bpf_level_to_idx;
+	roc_nix_bpf_pre_color_tbl_setup;
 	roc_nix_cq_dump;
 	roc_nix_cq_fini;
 	roc_nix_cq_init;