Commit ef992a0f authored by Suman Ghosh's avatar Suman Ghosh Committed by Jakub Kicinski
Browse files

octeontx2-af: npc: cn20k: MKEX profile support



In new silicon variant cn20k, a new parser profile is introduced. Instead
of having two layer-data information per key field type, a new key
extractor concept is introduced. As part of this change now a maximum of
24 extractor can be configured per packet parsing profile. For example,
LA type(ether) can have 24 unique parsing key, LC type(ip), LD
type(tcp/udp) also can have unique 24 parsing key associated.

Signed-off-by: default avatarSuman Ghosh <sumang@marvell.com>
Signed-off-by: default avatarRatheesh Kannoth <rkannoth@marvell.com>
Link: https://patch.msgid.link/20260224080009.4147301-5-rkannoth@marvell.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a2df2f95
Loading
Loading
Loading
Loading
+356 −5
Original line number Diff line number Diff line
@@ -29,19 +29,21 @@ static const char *npc_kw_name[NPC_MCAM_KEY_MAX] = {
		     (((bytesm1) << 16) | ((hdr_ofs) << 8) | ((ena) << 7) | \
		     ((key_ofs) & 0x3F))

static const char cn20k_def_pfl_name[] = "default";

static struct npc_mcam_kex_extr npc_mkex_extr_default = {
	.mkex_sign = MKEX_SIGN,
	.mkex_sign = MKEX_CN20K_SIGN,
	.name = "default",
	.kpu_version = NPC_KPU_PROFILE_VER,
	.keyx_cfg = {
		/* nibble: LA..LE (ltype only) + Error code + Channel */
		[NIX_INTF_RX] = ((u64)NPC_MCAM_KEY_DYN << 32) |
			NPC_PARSE_NIBBLE_INTF_RX |
				 NPC_PARSE_NIBBLE_ERRCODE,
				 NPC_CN20K_PARSE_NIBBLE_ERRCODE,

		/* nibble: LA..LE (ltype only) */
		[NIX_INTF_TX] = ((u64)NPC_MCAM_KEY_X2 << 32) |
			NPC_PARSE_NIBBLE_INTF_TX,
			NPC_CN20K_PARSE_NIBBLE_INTF_TX,
	},
	.intf_extr_lid = {
	/* Default RX MCAM KEX profile */
@@ -305,9 +307,9 @@ npc_enable_kpm_entry(struct rvu *rvu, int blkaddr, int kpm, int num_entries)
	u64 entry_mask;

	entry_mask = npc_enable_mask(num_entries);
	/* Disable first KPU_MAX_CST_ENT entries for built-in profile */
	/* Disable first KPU_CN20K_MAX_CST_ENT entries for built-in profile */
	if (!rvu->kpu.custom)
		entry_mask |= GENMASK_ULL(KPU_MAX_CST_ENT - 1, 0);
		entry_mask |= GENMASK_ULL(KPU_CN20K_MAX_CST_ENT - 1, 0);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_KPMX_ENTRY_DISX(kpm, 0), entry_mask);
	if (num_entries <= 64) {
@@ -428,6 +430,299 @@ struct npc_priv_t *npc_priv_get(void)
	return &npc_priv;
}

static void npc_program_mkex_rx(struct rvu *rvu, int blkaddr,
				struct npc_mcam_kex_extr *mkex_extr,
				u8 intf)
{
	u8 num_extr = rvu->hw->npc_kex_extr;
	int extr, lt;
	u64 val;

	if (is_npc_intf_tx(intf))
		return;

	rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(intf),
		    mkex_extr->keyx_cfg[NIX_INTF_RX]);

	/* Program EXTRACTOR */
	for (extr = 0; extr < num_extr; extr++)
		rvu_write64(rvu, blkaddr,
			    NPC_AF_INTFX_EXTRACTORX_CFG(intf, extr),
			    mkex_extr->intf_extr_lid[intf][extr]);

	/* Program EXTRACTOR_LTYPE */
	for (extr = 0; extr < num_extr; extr++) {
		for (lt = 0; lt < NPC_MAX_LT; lt++) {
			val = mkex_extr->intf_extr_lt[intf][extr][lt];
			CN20K_SET_EXTR_LT(intf, extr, lt, val);
		}
	}
}

static void npc_program_mkex_tx(struct rvu *rvu, int blkaddr,
				struct npc_mcam_kex_extr *mkex_extr,
				u8 intf)
{
	u8 num_extr = rvu->hw->npc_kex_extr;
	int extr, lt;
	u64 val;

	if (is_npc_intf_rx(intf))
		return;

	rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(intf),
		    mkex_extr->keyx_cfg[NIX_INTF_TX]);

	/* Program EXTRACTOR */
	for (extr = 0; extr < num_extr; extr++)
		rvu_write64(rvu, blkaddr,
			    NPC_AF_INTFX_EXTRACTORX_CFG(intf, extr),
			    mkex_extr->intf_extr_lid[intf][extr]);

	/* Program EXTRACTOR_LTYPE */
	for (extr = 0; extr < num_extr; extr++) {
		for (lt = 0; lt < NPC_MAX_LT; lt++) {
			val = mkex_extr->intf_extr_lt[intf][extr][lt];
			CN20K_SET_EXTR_LT(intf, extr, lt, val);
		}
	}
}

static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr,
				     struct npc_mcam_kex_extr *mkex_extr)
{
	struct rvu_hwinfo *hw = rvu->hw;
	u8 intf;

	for (intf = 0; intf < hw->npc_intfs; intf++) {
		npc_program_mkex_rx(rvu, blkaddr, mkex_extr, intf);
		npc_program_mkex_tx(rvu, blkaddr, mkex_extr, intf);
	}

	/* Programme mkex hash profile */
	npc_program_mkex_hash(rvu, blkaddr);
}

void npc_cn20k_load_mkex_profile(struct rvu *rvu, int blkaddr,
				 const char *mkex_profile)
{
	struct npc_mcam_kex_extr *mcam_kex_extr;
	struct device *dev = &rvu->pdev->dev;
	void __iomem *mkex_prfl_addr = NULL;
	u64 prfl_sz;
	int ret;

	/* If user not selected mkex profile */
	if (rvu->kpu_fwdata_sz ||
	    !strncmp(mkex_profile, cn20k_def_pfl_name, MKEX_NAME_LEN))
		goto program_mkex_extr;

	/* Setting up the mapping for mkex profile image */
	ret = npc_fwdb_prfl_img_map(rvu, &mkex_prfl_addr, &prfl_sz);
	if (ret < 0)
		goto program_mkex_extr;

	mcam_kex_extr = (struct npc_mcam_kex_extr __force *)mkex_prfl_addr;

	while (((s64)prfl_sz > 0) &&
	       (mcam_kex_extr->mkex_sign != MKEX_END_SIGN)) {
		/* Compare with mkex mod_param name string */
		if (mcam_kex_extr->mkex_sign == MKEX_CN20K_SIGN &&
		    !strncmp(mcam_kex_extr->name, mkex_profile,
			     MKEX_NAME_LEN)) {
			rvu->kpu.mcam_kex_prfl.mkex_extr = mcam_kex_extr;
			goto program_mkex_extr;
		}

		mcam_kex_extr++;
		prfl_sz -= sizeof(struct npc_mcam_kex_extr);
	}
	dev_warn(dev, "Failed to load requested profile: %s\n", mkex_profile);
	rvu->kpu.mcam_kex_prfl.mkex_extr = npc_mkex_extr_default_get();

program_mkex_extr:
	dev_info(rvu->dev, "Using %s mkex profile\n",
		 rvu->kpu.mcam_kex_prfl.mkex_extr->name);
	/* Program selected mkex profile */
	npc_program_mkex_profile(rvu, blkaddr,
				 rvu->kpu.mcam_kex_prfl.mkex_extr);
	if (mkex_prfl_addr)
		iounmap(mkex_prfl_addr);
}

static u8 npc_map2cn20k_flag(u8 flag)
{
	switch (flag) {
	case NPC_F_LC_U_IP_FRAG:
		return NPC_CN20K_F_LC_L_IP_FRAG;

	case NPC_F_LC_U_IP6_FRAG:
		return NPC_CN20K_F_LC_L_IP6_FRAG;

	case NPC_F_LC_L_6TO4:
		return NPC_CN20K_F_LC_L_6TO4;

	case NPC_F_LC_L_MPLS_IN_IP:
		return NPC_CN20K_F_LC_U_MPLS_IN_IP;

	case NPC_F_LC_L_IP6_TUN_IP6:
		return NPC_CN20K_F_LC_U_IP6_TUN_IP6;

	case NPC_F_LC_L_IP6_MPLS_IN_IP:
		return NPC_CN20K_F_LC_U_IP6_MPLS_IN_IP;

	default:
		break;
	}

	WARN(1, "%s: Invalid flag=%u\n", __func__, flag);
	return 0xff;
}

void
npc_cn20k_update_action_entries_n_flags(struct rvu *rvu,
					struct npc_kpu_profile_adapter *pfl)
{
	struct npc_kpu_profile_action *action;
	int entries, ltype;
	u8 flags, val;

	for (int i = 0; i < pfl->kpus; i++) {
		action = pfl->kpu[i].action;
		entries = pfl->kpu[i].action_entries;

		for (int j = 0; j < entries; j++) {
			if (action[j].lid != NPC_LID_LC)
				continue;

			ltype = action[j].ltype;

			if (ltype != NPC_LT_LC_IP &&
			    ltype != NPC_LT_LC_IP6 &&
			    ltype != NPC_LT_LC_IP_OPT &&
			    ltype != NPC_LT_LC_IP6_EXT)
				continue;

			flags = action[j].flags;

			switch (flags) {
			case NPC_F_LC_U_IP_FRAG:
			case NPC_F_LC_U_IP6_FRAG:
			case NPC_F_LC_L_6TO4:
			case NPC_F_LC_L_MPLS_IN_IP:
			case NPC_F_LC_L_IP6_TUN_IP6:
			case NPC_F_LC_L_IP6_MPLS_IN_IP:
				val = npc_map2cn20k_flag(flags);
				if (val == 0xFF) {
					dev_err(rvu->dev,
						"%s: Error to get flag value\n",
						__func__);
					return;
				}

				action[j].flags = val;
				break;
			default:
				break;
			}
		}
	}
}

int npc_cn20k_apply_custom_kpu(struct rvu *rvu,
			       struct npc_kpu_profile_adapter *profile)
{
	struct npc_cn20k_kpu_profile_fwdata *fw = rvu->kpu_fwdata;
	struct npc_kpu_profile_action *action;
	struct npc_kpu_profile_cam *cam;
	struct npc_kpu_fwdata *fw_kpu;
	size_t hdr_sz, offset = 0;
	u16 kpu, entry;
	int entries;

	hdr_sz = sizeof(struct npc_cn20k_kpu_profile_fwdata);

	if (rvu->kpu_fwdata_sz < hdr_sz) {
		dev_warn(rvu->dev, "Invalid KPU profile size\n");
		return -EINVAL;
	}

	if (le64_to_cpu(fw->signature) != KPU_SIGN) {
		dev_warn(rvu->dev, "Invalid KPU profile signature %llx\n",
			 fw->signature);
		return -EINVAL;
	}

	/* Verify if the using known profile structure */
	if (NPC_KPU_VER_MAJ(profile->version) >
	    NPC_KPU_VER_MAJ(NPC_KPU_PROFILE_VER)) {
		dev_warn(rvu->dev, "Not supported Major version: %d > %d\n",
			 NPC_KPU_VER_MAJ(profile->version),
			 NPC_KPU_VER_MAJ(NPC_KPU_PROFILE_VER));
		return -EINVAL;
	}

	/* Verify if profile is aligned with the required kernel changes */
	if (NPC_KPU_VER_MIN(profile->version) <
	    NPC_KPU_VER_MIN(NPC_KPU_PROFILE_VER)) {
		dev_warn(rvu->dev,
			 "Invalid KPU profile version: %d.%d.%d expected version <= %d.%d.%d\n",
			 NPC_KPU_VER_MAJ(profile->version),
			 NPC_KPU_VER_MIN(profile->version),
			 NPC_KPU_VER_PATCH(profile->version),
			 NPC_KPU_VER_MAJ(NPC_KPU_PROFILE_VER),
			 NPC_KPU_VER_MIN(NPC_KPU_PROFILE_VER),
			 NPC_KPU_VER_PATCH(NPC_KPU_PROFILE_VER));
		return -EINVAL;
	}

	/* Verify if profile fits the HW */
	if (fw->kpus > profile->kpus) {
		dev_warn(rvu->dev, "Not enough KPUs: %d > %ld\n", fw->kpus,
			 profile->kpus);
		return -EINVAL;
	}

	profile->mcam_kex_prfl.mkex_extr = &fw->mkex;
	if (profile->mcam_kex_prfl.mkex_extr->mkex_sign != MKEX_CN20K_SIGN) {
		dev_warn(rvu->dev, "Invalid MKEX profile signature:%llx\n",
			 profile->mcam_kex_prfl.mkex_extr->mkex_sign);
		return -EINVAL;
	}

	profile->custom = 1;
	profile->name = fw->name;
	profile->version = le64_to_cpu(fw->version);
	profile->lt_def = &fw->lt_def;

	for (kpu = 0; kpu < fw->kpus; kpu++) {
		fw_kpu = (struct npc_kpu_fwdata *)(fw->data + offset);
		if (fw_kpu->entries > KPU_CN20K_MAX_CST_ENT)
			dev_warn(rvu->dev,
				 "Too many custom entries on KPU%d: %d > %d\n",
				 kpu, fw_kpu->entries, KPU_CN20K_MAX_CST_ENT);
		entries = min(fw_kpu->entries, KPU_CN20K_MAX_CST_ENT);
		cam = (struct npc_kpu_profile_cam *)fw_kpu->data;
		offset += sizeof(*fw_kpu) + fw_kpu->entries * sizeof(*cam);
		action = (struct npc_kpu_profile_action *)(fw->data + offset);
		offset += fw_kpu->entries * sizeof(*action);
		if (rvu->kpu_fwdata_sz < hdr_sz + offset) {
			dev_warn(rvu->dev,
				 "Profile size mismatch on KPU%i parsing.\n",
				 kpu + 1);
			return -EINVAL;
		}

		for (entry = 0; entry < entries; entry++) {
			profile->kpu[kpu].cam[entry] = cam[entry];
			profile->kpu[kpu].action[entry] = action[entry];
		}
	}
	npc_cn20k_update_action_entries_n_flags(rvu, profile);

	return 0;
}

static int npc_subbank_idx_2_mcam_idx(struct rvu *rvu, struct npc_subbank *sb,
				      u16 sub_off, u16 *mcam_idx)
{
@@ -1960,6 +2255,38 @@ rvu_mbox_handler_npc_cn20k_get_fcnt(struct rvu *rvu,
	return 0;
}

int
rvu_mbox_handler_npc_cn20k_get_kex_cfg(struct rvu *rvu,
				       struct msg_req *req,
				       struct npc_cn20k_get_kex_cfg_rsp *rsp)
{
	int extr, lt;

	rsp->rx_keyx_cfg = CN20K_GET_KEX_CFG(NIX_INTF_RX);
	rsp->tx_keyx_cfg = CN20K_GET_KEX_CFG(NIX_INTF_TX);

	/* Get EXTRACTOR LID */
	for (extr = 0; extr < NPC_MAX_EXTRACTOR; extr++) {
		rsp->intf_extr_lid[NIX_INTF_RX][extr] =
			CN20K_GET_EXTR_LID(NIX_INTF_RX, extr);
		rsp->intf_extr_lid[NIX_INTF_TX][extr] =
			CN20K_GET_EXTR_LID(NIX_INTF_TX, extr);
	}

	/* Get EXTRACTOR LTYPE */
	for (extr = 0; extr < NPC_MAX_EXTRACTOR; extr++) {
		for (lt = 0; lt < NPC_MAX_LT; lt++) {
			rsp->intf_extr_lt[NIX_INTF_RX][extr][lt] =
				CN20K_GET_EXTR_LT(NIX_INTF_RX, extr, lt);
			rsp->intf_extr_lt[NIX_INTF_TX][extr][lt] =
				CN20K_GET_EXTR_LT(NIX_INTF_TX, extr, lt);
		}
	}

	memcpy(rsp->mkex_pfl_name, rvu->mkex_pfl_name, MKEX_NAME_LEN);
	return 0;
}

static int *subbank_srch_order;

static void npc_populate_restricted_idxs(int num_subbanks)
@@ -2172,6 +2499,23 @@ void npc_cn20k_deinit(struct rvu *rvu)
	kfree(subbank_srch_order);
}

static int npc_setup_mcam_section(struct rvu *rvu, int key_type)
{
	int blkaddr, sec;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
	if (blkaddr < 0) {
		dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
		return -ENODEV;
	}

	for (sec = 0; sec < npc_priv.num_subbanks; sec++)
		rvu_write64(rvu, blkaddr,
			    NPC_AF_MCAM_SECTIONX_CFG_EXT(sec), key_type);

	return 0;
}

int npc_cn20k_init(struct rvu *rvu)
{
	int err;
@@ -2183,6 +2527,13 @@ int npc_cn20k_init(struct rvu *rvu)
		return err;
	}

	err = npc_setup_mcam_section(rvu, NPC_MCAM_KEY_X2);
	if (err) {
		dev_err(rvu->dev, "%s: mcam section configuration failure\n",
			__func__);
		return err;
	}

	npc_priv.init_done = true;

	return 0;
+103 −0
Original line number Diff line number Diff line
@@ -8,10 +8,77 @@
#ifndef NPC_CN20K_H
#define NPC_CN20K_H

#define MKEX_CN20K_SIGN	0x19bbfdbd160

#define MAX_NUM_BANKS 2
#define MAX_NUM_SUB_BANKS 32
#define MAX_SUBBANK_DEPTH 256

/* strtoull of "mkexprof" with base:36 */
#define MKEX_END_SIGN  0xdeadbeef

#define NPC_CN20K_BYTESM GENMASK_ULL(18, 16)
#define NPC_CN20K_PARSE_NIBBLE GENMASK_ULL(22, 0)
#define NPC_CN20K_TOTAL_NIBBLE 23

#define CN20K_SET_EXTR_LT(intf, extr, ltype, cfg)	\
	rvu_write64(rvu, BLKADDR_NPC,	\
		    NPC_AF_INTFX_EXTRACTORX_LTX_CFG(intf, extr, ltype), cfg)

#define CN20K_GET_KEX_CFG(intf)	\
	rvu_read64(rvu, BLKADDR_NPC, NPC_AF_INTFX_KEX_CFG(intf))

#define CN20K_GET_EXTR_LID(intf, extr)	\
	rvu_read64(rvu, BLKADDR_NPC,	\
		   NPC_AF_INTFX_EXTRACTORX_CFG(intf, extr))

#define CN20K_SET_EXTR_LT(intf, extr, ltype, cfg)	\
	rvu_write64(rvu, BLKADDR_NPC,	\
		    NPC_AF_INTFX_EXTRACTORX_LTX_CFG(intf, extr, ltype), cfg)

#define CN20K_GET_EXTR_LT(intf, extr, ltype)	\
	rvu_read64(rvu, BLKADDR_NPC,	\
		   NPC_AF_INTFX_EXTRACTORX_LTX_CFG(intf, extr, ltype))

/* NPC_PARSE_KEX_S nibble definitions for each field */
#define NPC_CN20K_PARSE_NIBBLE_CHAN GENMASK_ULL(2, 0)
#define NPC_CN20K_PARSE_NIBBLE_ERRLEV BIT_ULL(3)
#define NPC_CN20K_PARSE_NIBBLE_ERRCODE GENMASK_ULL(5, 4)
#define NPC_CN20K_PARSE_NIBBLE_L2L3_BCAST BIT_ULL(6)
#define NPC_CN20K_PARSE_NIBBLE_LA_FLAGS BIT_ULL(7)
#define NPC_CN20K_PARSE_NIBBLE_LA_LTYPE BIT_ULL(8)
#define NPC_CN20K_PARSE_NIBBLE_LB_FLAGS BIT_ULL(9)
#define NPC_CN20K_PARSE_NIBBLE_LB_LTYPE BIT_ULL(10)
#define NPC_CN20K_PARSE_NIBBLE_LC_FLAGS BIT_ULL(11)
#define NPC_CN20K_PARSE_NIBBLE_LC_LTYPE BIT_ULL(12)
#define NPC_CN20K_PARSE_NIBBLE_LD_FLAGS BIT_ULL(13)
#define NPC_CN20K_PARSE_NIBBLE_LD_LTYPE BIT_ULL(14)
#define NPC_CN20K_PARSE_NIBBLE_LE_FLAGS BIT_ULL(15)
#define NPC_CN20K_PARSE_NIBBLE_LE_LTYPE BIT_ULL(16)
#define NPC_CN20K_PARSE_NIBBLE_LF_FLAGS BIT_ULL(17)
#define NPC_CN20K_PARSE_NIBBLE_LF_LTYPE BIT_ULL(18)
#define NPC_CN20K_PARSE_NIBBLE_LG_FLAGS BIT_ULL(19)
#define NPC_CN20K_PARSE_NIBBLE_LG_LTYPE BIT_ULL(20)
#define NPC_CN20K_PARSE_NIBBLE_LH_FLAGS BIT_ULL(21)
#define NPC_CN20K_PARSE_NIBBLE_LH_LTYPE BIT_ULL(22)

/* Rx parse key extract nibble enable */
#define NPC_CN20K_PARSE_NIBBLE_INTF_RX  (NPC_CN20K_PARSE_NIBBLE_CHAN | \
					 NPC_CN20K_PARSE_NIBBLE_L2L3_BCAST | \
					 NPC_CN20K_PARSE_NIBBLE_LA_LTYPE | \
					 NPC_CN20K_PARSE_NIBBLE_LB_LTYPE | \
					 NPC_CN20K_PARSE_NIBBLE_LC_FLAGS | \
					 NPC_CN20K_PARSE_NIBBLE_LC_LTYPE | \
					 NPC_CN20K_PARSE_NIBBLE_LD_LTYPE | \
					 NPC_CN20K_PARSE_NIBBLE_LE_LTYPE)

/* Tx parse key extract nibble enable */
#define NPC_CN20K_PARSE_NIBBLE_INTF_TX	(NPC_CN20K_PARSE_NIBBLE_LA_LTYPE | \
					 NPC_CN20K_PARSE_NIBBLE_LB_LTYPE | \
					 NPC_CN20K_PARSE_NIBBLE_LC_LTYPE | \
					 NPC_CN20K_PARSE_NIBBLE_LD_LTYPE | \
					 NPC_CN20K_PARSE_NIBBLE_LE_LTYPE)

/**
 * enum npc_subbank_flag - NPC subbank status
 *
@@ -147,6 +214,34 @@ struct npc_mcam_kex_extr {
	u64 intf_extr_lt[NPC_MAX_INTF][NPC_MAX_EXTRACTOR][NPC_MAX_LT];
} __packed;

struct npc_cn20k_kpu_profile_fwdata {
#define KPU_SIGN	0x00666f727075706b
#define KPU_NAME_LEN	32
	/* Maximum number of custom KPU entries supported by
	 * the built-in profile.
	 */
#define KPU_CN20K_MAX_CST_ENT	6
	/* KPU Profle Header */
	__le64	signature; /* "kpuprof\0" (8 bytes/ASCII characters) */
	u8	name[KPU_NAME_LEN]; /* KPU Profile name */
	__le64	version; /* KPU profile version */
	u8	kpus;
	u8	reserved[7];

	/* Default MKEX profile to be used with this KPU profile. May be
	 * overridden with mkex_profile module parameter.
	 * Format is same as for the MKEX profile to streamline processing.
	 */
	struct npc_mcam_kex_extr	mkex;
	/* LTYPE values for specific HW offloaded protocols. */
	struct npc_lt_def_cfg		lt_def;
	/* Dynamically sized data:
	 *  Custom KPU CAM and ACTION configuration entries.
	 * struct npc_kpu_fwdata kpu[kpus];
	 */
	u8	data[];
} __packed;

struct rvu;

struct npc_priv_t *npc_priv_get(void);
@@ -162,4 +257,12 @@ int npc_cn20k_ref_idx_alloc(struct rvu *rvu, int pcifunc, int key_type,
int npc_cn20k_idx_free(struct rvu *rvu, u16 *mcam_idx, int count);
void npc_cn20k_parser_profile_init(struct rvu *rvu, int blkaddr);
struct npc_mcam_kex_extr *npc_mkex_extr_default_get(void);
void npc_cn20k_load_mkex_profile(struct rvu *rvu, int blkaddr,
				 const char *mkex_profile);
int npc_cn20k_apply_custom_kpu(struct rvu *rvu,
			       struct npc_kpu_profile_adapter *profile);

void
npc_cn20k_update_action_entries_n_flags(struct rvu *rvu,
					struct npc_kpu_profile_adapter *pfl);
#endif /* NPC_CN20K_H */
+51 −9
Original line number Diff line number Diff line
@@ -80,18 +80,60 @@
#define RVU_MBOX_VF_VFAF_TRIGX(a)		(0x2000 | (a) << 3)
/* NPC registers */
#define NPC_AF_INTFX_EXTRACTORX_CFG(a, b) \
	(0x908000ull | (a) << 10 | (b) << 3)
	(0x20c000ull | (a) << 16 | (b) << 8)
#define NPC_AF_INTFX_EXTRACTORX_LTX_CFG(a, b, c) \
	(0x900000ull | (a) << 13 | (b) << 8  | (c) << 3)
	(0x204000ull | (a) << 16 | (b) << 8  | (c) << 3)
#define NPC_AF_KPMX_ENTRYX_CAMX(a, b, c) \
	(0x100000ull | (a) << 14 | (b) << 6 | (c) << 3)
	(0x20000ull | (a) << 12 | (b) << 3 | (c) << 16)
#define NPC_AF_KPMX_ENTRYX_ACTION0(a, b) \
	(0x100020ull | (a) << 14 | (b) << 6)
	(0x40000ull | (a) << 12 | (b) << 3)
#define NPC_AF_KPMX_ENTRYX_ACTION1(a, b) \
	(0x100028ull | (a) << 14 | (b) << 6)
#define NPC_AF_KPMX_ENTRY_DISX(a, b)	(0x180000ull | (a) << 6 | (b) << 3)
#define NPC_AF_KPM_PASS2_CFG	0x580
#define NPC_AF_KPMX_PASS2_OFFSET(a)	(0x190000ull | (a) << 3)
#define NPC_AF_MCAM_SECTIONX_CFG_EXT(a)	(0xC000000ull | (a) << 3)
	(0x50000ull | (a) << 12 | (b) << 3)
#define NPC_AF_KPMX_ENTRY_DISX(a, b)	(0x60000ull | (a) << 12 | (b) << 3)
#define NPC_AF_KPM_PASS2_CFG	0x10210
#define NPC_AF_KPMX_PASS2_OFFSET(a)	(0x60040ull | (a) << 12)
#define NPC_AF_MCAM_SECTIONX_CFG_EXT(a)	(0xf000000ull | (a) << 3)

#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(a, b, c) ({		\
	u64 offset;							\
	offset = (0x8000000ull | (a) << 4 | (b) << 20 | (c) << 3);	\
	offset; })

#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(a, b, c) ({		\
	u64 offset;							\
	offset = (0x9000000ull | (a) << 4 | (b) << 20 | (c) << 3);	\
	offset; })

#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(a, b, c) ({		\
	u64 offset;							\
	offset = (0x9400000ull | (a) << 4 | (b) << 20 | (c) << 3);	\
	offset; })

#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(a, b, c) ({		\
	u64 offset;							\
	offset = (0x9800000ull | (a) << 4 | (b) << 20 | (c) << 3);	\
	offset; })

#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(a, b, c) ({		\
	u64 offset;							\
	offset = (0x9c00000ull | (a) << 4 | (b) << 20 | (c) << 3);	\
	offset; })

#define NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(a, b) ({		\
	u64 offset;						\
	offset = (0xa000000ull | (a) << 4 | (b) << 20);		\
	offset; })

#define NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(a, b, c) ({		\
	u64 offset;							\
	offset = (0xc000000ull | (a) << 4 | (b) << 20 | (c) << 22);	\
	offset; })

#define NPC_AF_INTFX_MISS_ACTX(a, b)	(0xf003000 | (a) << 6 | (b) << 4)

#define NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(a, b) ({		\
	u64 offset;						\
	offset = (0xb000000ull | (a) << 4 | (b) << 20);		\
	offset; })

#endif /* RVU_MBOX_REG_H */
+16 −1
Original line number Diff line number Diff line
@@ -285,6 +285,8 @@ M(NPC_GET_FIELD_STATUS, 0x6014, npc_get_field_status, \
				   npc_get_field_status_rsp)              \
M(NPC_CN20K_MCAM_GET_FREE_COUNT, 0x6015, npc_cn20k_get_fcnt,		\
				 msg_req, npc_cn20k_get_fcnt_rsp)	\
M(NPC_CN20K_GET_KEX_CFG, 0x6016, npc_cn20k_get_kex_cfg,			\
				   msg_req, npc_cn20k_get_kex_cfg_rsp)	\
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */				\
M(NIX_LF_ALLOC,		0x8000, nix_lf_alloc,				\
				 nix_lf_alloc_req, nix_lf_alloc_rsp)	\
@@ -1559,7 +1561,7 @@ struct npc_mcam_free_entry_req {
};

struct mcam_entry {
#define NPC_MAX_KWS_IN_KEY	7 /* Number of keywords in max keywidth */
#define NPC_MAX_KWS_IN_KEY	8 /* Number of keywords in max keywidth */
	u64	kw[NPC_MAX_KWS_IN_KEY];
	u64	kw_mask[NPC_MAX_KWS_IN_KEY];
	u64	action;
@@ -1663,6 +1665,19 @@ struct npc_get_kex_cfg_rsp {
	u8 mkex_pfl_name[MKEX_NAME_LEN];
};

struct npc_cn20k_get_kex_cfg_rsp {
	struct mbox_msghdr hdr;
	u64 rx_keyx_cfg;   /* NPC_AF_INTF(0)_KEX_CFG */
	u64 tx_keyx_cfg;   /* NPC_AF_INTF(1)_KEX_CFG */
#define NPC_MAX_EXTRACTOR 24
	/* MKEX Extractor data */
	u64 intf_extr_lid[NPC_MAX_INTF][NPC_MAX_EXTRACTOR];
	/* KEX configuration per extractor */
	u64 intf_extr_lt[NPC_MAX_INTF][NPC_MAX_EXTRACTOR][NPC_MAX_LT];
#define MKEX_NAME_LEN 128
	u8 mkex_pfl_name[MKEX_NAME_LEN];
};

struct ptp_get_cap_rsp {
	struct mbox_msghdr hdr;
#define        PTP_CAP_HW_ATOMIC_UPDATE BIT_ULL(0)
+1 −0
Original line number Diff line number Diff line
@@ -429,6 +429,7 @@ struct nix_rx_action {

/* NPC_AF_INTFX_KEX_CFG field masks */
#define NPC_PARSE_NIBBLE		GENMASK_ULL(30, 0)
#define NPC_TOTAL_NIBBLE		31

/* NPC_PARSE_KEX_S nibble definitions for each field */
#define NPC_PARSE_NIBBLE_CHAN		GENMASK_ULL(2, 0)
Loading