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

octeontx2-af: npc: cn20k: Use common APIs



In cn20k silicon, the register definitions and the algorithms used to
read, write, copy, and enable MCAM entries have changed. This patch
updates the common APIs to support both cn20k and previous silicon
variants.

Additionally, cn20k introduces a new algorithm for MCAM index management.
The common APIs are updated to invoke the cn20k-specific index management
routines for allocating, freeing, and retrieving default MCAM entries.

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-7-rkannoth@marvell.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 09d3b7a1
Loading
Loading
Loading
Loading
+502 −1
Original line number Diff line number Diff line
@@ -568,6 +568,472 @@ void npc_cn20k_load_mkex_profile(struct rvu *rvu, int blkaddr,
		iounmap(mkex_prfl_addr);
}

void
npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
			    int index, bool enable)
{
	struct npc_mcam *mcam = &rvu->hw->mcam;
	int mcam_idx = index % mcam->banksize;
	int bank = index / mcam->banksize;
	u64 cfg, hw_prio;
	u8 kw_type;

	npc_mcam_idx_2_key_type(rvu, index, &kw_type);
	if (kw_type == NPC_MCAM_KEY_X2) {
		cfg = rvu_read64(rvu, blkaddr,
				 NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx,
								   bank));
		hw_prio = cfg & GENMASK_ULL(14, 8);
		cfg = enable ? 1 : 0;
		cfg |= hw_prio;
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
			    cfg);
		return;
	}

	/* For NPC_CN20K_MCAM_KEY_X4 keys, both the banks
	 * need to be programmed with the same value.
	 */
	for (bank = 0; bank < mcam->banks_per_entry; bank++) {
		cfg = rvu_read64(rvu, blkaddr,
				 NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx,
								   bank));
		hw_prio = cfg & GENMASK_ULL(14, 8);
		cfg = enable ? 1 : 0;
		cfg |= hw_prio;
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
			    cfg);
	}
}

void
npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int bank, int index)
{
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(index, bank, 1),
		    0);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(index, bank, 0),
		    0);

	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index, bank, 1), 0);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index, bank, 0), 0);

	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index, bank, 1), 0);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index, bank, 0), 0);

	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index, bank, 1), 0);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index, bank, 0), 0);

	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 1), 0);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 0), 0);
}

static void npc_cn20k_get_keyword(struct mcam_entry *entry, int idx,
				  u64 *cam0, u64 *cam1)
{
	u64 kw_mask;

	/* The two banks of every MCAM entry are used as a single double-wide
	 * entry that is compared with the search key as follows:
	 *
	 * NPC_AF_MCAME()_BANK(0)_CAM(0..1)_W0_EXT[MD] ->NPC_MCAM_KEY_X4_S[KW0]
	 * NPC_AF_MCAME()_BANK(0)_CAM(0..1)_W1_EXT[MD] ->NPC_MCAM_KEY_X4_S[KW1]
	 * NPC_AF_MCAME()_BANK(0)_CAM(0..1)_W2_EXT[MD] ->NPC_MCAM_KEY_X4_S[KW2]
	 * NPC_AF_MCAME()_BANK(0)_CAM(0..1)_W3_EXT[MD] ->NPC_MCAM_KEY_X4_S[KW3]
	 * NPC_AF_MCAME()_BANK(1)_CAM(0..1)_W0_EXT[MD] ->NPC_MCAM_KEY_X4_S[KW4]
	 * NPC_AF_MCAME()_BANK(1)_CAM(0..1)_W1_EXT[MD] ->NPC_MCAM_KEY_X4_S[KW5]
	 * NPC_AF_MCAME()_BANK(1)_CAM(0..1)_W2_EXT[MD] ->NPC_MCAM_KEY_X4_S[KW6]
	 * NPC_AF_MCAME()_BANK(1)_CAM(0..1)_W3_EXT[MD] ->NPC_MCAM_KEY_X4_S[KW7]
	 */
	*cam1 = entry->kw[idx];
	kw_mask = entry->kw_mask[idx];
	*cam1 &= kw_mask;
	*cam0 = ~*cam1 & kw_mask;
}

/*-----------------------------------------------------------------------------|
 *Kex type  |  mcam entry   |  cam1	   |	cam 0	|| <----- output ----> |
 *profile   |  len	    | (key type)   | (key type)	|| len	  |   type     |
 *-----------------------------------------------------------------------------|
 *X2	    |  256 (X2)	    |  001b	   |	110b	|| X2	  |    X2      |
 *-----------------------------------------------------------------------------|
 *X4	    |  256 (X2)	    |  000b	   |	000b	|| X2	  |  DYNAMIC   |
 *-----------------------------------------------------------------------------|
 *X4	    |  512 (X4)	    |  010b	   |	101b	|| X4	  |    X4      |
 *-----------------------------------------------------------------------------|
 *DYN	    |  256 (X2)	    |  000b	   |	000b	|| X2	  |  DYNAMIC   |
 *-----------------------------------------------------------------------------|
 *DYN	    |  512 (X4)	    |  010b	   |	101b	|| X4	  |    X4      |
 *-----------------------------------------------------------------------------|
 */
static void npc_cn20k_config_kw_x2(struct rvu *rvu, struct npc_mcam *mcam,
				   int blkaddr, int index, u8 intf,
				   struct mcam_entry *entry,
				   int bank, u8 kw_type, int kw)
{
	u64 intf_ext = 0, intf_ext_mask = 0;
	u8 tx_intf_mask = ~intf & 0x3;
	u8 tx_intf = intf, kex_type;
	u8 kw_type_mask = ~kw_type;
	u64 cam0, cam1, kex_cfg;

	if (is_npc_intf_tx(intf)) {
		/* Last bit must be set and rest don't care
		 * for TX interfaces
		 */
		tx_intf_mask = 0x1;
		tx_intf = intf & tx_intf_mask;
		tx_intf_mask = ~tx_intf & tx_intf_mask;
	}

	kex_cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(intf));
	kex_type = (kex_cfg & GENMASK_ULL(34, 32)) >> 32;
	if ((kex_type == NPC_MCAM_KEY_DYN || kex_type == NPC_MCAM_KEY_X4) &&
	    kw_type == NPC_MCAM_KEY_X2) {
		kw_type = 0;
		kw_type_mask = 0;
	}

	intf_ext = ((u64)kw_type << 16) | tx_intf;
	intf_ext_mask = (((u64)kw_type_mask  << 16) & GENMASK_ULL(18, 16)) |
		tx_intf_mask;
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(index, bank, 1),
		    intf_ext);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(index, bank, 0),
		    intf_ext_mask);

	/* Set the match key */
	npc_cn20k_get_keyword(entry, kw, &cam0, &cam1);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index, bank, 1),
		    cam1);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index, bank, 0),
		    cam0);

	npc_cn20k_get_keyword(entry, kw + 1, &cam0, &cam1);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index, bank, 1),
		    cam1);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index, bank, 0),
		    cam0);

	npc_cn20k_get_keyword(entry, kw + 2, &cam0, &cam1);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index, bank, 1),
		    cam1);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index, bank, 0),
		    cam0);

	npc_cn20k_get_keyword(entry, kw + 3, &cam0, &cam1);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 1),
		    cam1);
	rvu_write64(rvu, blkaddr,
		    NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 0),
		    cam0);
}

static void npc_cn20k_config_kw_x4(struct rvu *rvu, struct npc_mcam *mcam,
				   int blkaddr, int index, u8 intf,
				   struct mcam_entry *entry, u8 kw_type)
{
	int kw = 0, bank;

	for (bank = 0; bank < mcam->banks_per_entry; bank++, kw = kw + 4)
		npc_cn20k_config_kw_x2(rvu, mcam, blkaddr,
				       index, intf,
				       entry, bank, kw_type, kw);
}

static void
npc_cn20k_set_mcam_bank_cfg(struct rvu *rvu, int blkaddr, int mcam_idx,
			    int bank, u8 kw_type, bool enable, u8 hw_prio)
{
	struct npc_mcam *mcam = &rvu->hw->mcam;
	u64 bank_cfg;

	bank_cfg = (u64)hw_prio << 8;
	if (enable)
		bank_cfg |= 0x1;

	if (kw_type == NPC_MCAM_KEY_X2) {
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
			    bank_cfg);
		return;
	}

	/* For NPC_MCAM_KEY_X4 keys, both the banks
	 * need to be programmed with the same value.
	 */
	for (bank = 0; bank < mcam->banks_per_entry; bank++) {
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
			    bank_cfg);
	}
}

void
npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index, u8 intf,
			    struct mcam_entry *entry, bool enable, u8 hw_prio)
{
	struct npc_mcam *mcam = &rvu->hw->mcam;
	int mcam_idx = index % mcam->banksize;
	int bank = index / mcam->banksize;
	int kw = 0;
	u8 kw_type;

	/* Disable before mcam entry update */
	npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, false);

	npc_mcam_idx_2_key_type(rvu, index, &kw_type);
	/* CAM1 takes the comparison value and
	 * CAM0 specifies match for a bit in key being '0' or '1' or 'dontcare'.
	 * CAM1<n> = 0 & CAM0<n> = 1 => match if key<n> = 0
	 * CAM1<n> = 1 & CAM0<n> = 0 => match if key<n> = 1
	 * CAM1<n> = 0 & CAM0<n> = 0 => always match i.e dontcare.
	 */
	if (kw_type == NPC_MCAM_KEY_X2) {
		/* Clear mcam entry to avoid writes being suppressed by NPC */
		npc_cn20k_clear_mcam_entry(rvu, blkaddr, bank, mcam_idx);
		npc_cn20k_config_kw_x2(rvu, mcam, blkaddr,
				       mcam_idx, intf, entry,
				       bank, kw_type, kw);
		/* Set 'action' */
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
								  bank, 0),
			    entry->action);

		/* Set TAG 'action' */
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
								  bank, 1),
			    entry->vtag_action);

		goto set_cfg;
	}
	/* Clear mcam entry to avoid writes being suppressed by NPC */
	npc_cn20k_clear_mcam_entry(rvu, blkaddr, 0, mcam_idx);
	npc_cn20k_clear_mcam_entry(rvu, blkaddr, 1, mcam_idx);

	npc_cn20k_config_kw_x4(rvu, mcam, blkaddr,
			       mcam_idx, intf, entry, kw_type);
	for (bank = 0; bank < mcam->banks_per_entry; bank++) {
		/* Set 'action' */
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
								  bank, 0),
			    entry->action);

		/* Set TAG 'action' */
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
								  bank, 1),
			    entry->vtag_action);
	}

set_cfg:
	/* TODO: */
	/* PF installing VF rule */
	npc_cn20k_set_mcam_bank_cfg(rvu, blkaddr, mcam_idx, bank,
				    kw_type, enable, hw_prio);
}

void npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr, u16 src, u16 dest)
{
	struct npc_mcam *mcam = &rvu->hw->mcam;
	u64 cfg, sreg, dreg, soff, doff;
	u8 src_kwtype, dest_kwtype;
	int bank, i, sb, db;
	int dbank, sbank;

	dbank = npc_get_bank(mcam, dest);
	sbank = npc_get_bank(mcam, src);
	npc_mcam_idx_2_key_type(rvu, src, &src_kwtype);
	npc_mcam_idx_2_key_type(rvu, dest, &dest_kwtype);
	if (src_kwtype != dest_kwtype)
		return;

	src &= (mcam->banksize - 1);
	dest &= (mcam->banksize - 1);

	/* Copy INTF's, W0's, W1's, W2's, W3s CAM0 and CAM1 configuration */
	for (bank = 0; bank < mcam->banks_per_entry; bank++) {
		sb = sbank + bank;
		sreg = NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(src, sb, 0);
		db = dbank + bank;
		dreg = NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(dest, db, 0);
		for (i = 0; i < 10; i++) {
			cfg = rvu_read64(rvu, blkaddr, sreg + (i * 8));
			rvu_write64(rvu, blkaddr, dreg + (i * 8), cfg);
		}

		/* Copy action */
		for (i = 0; i < 3; i++) {
			soff = NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(src,
								     sb, i);
			cfg = rvu_read64(rvu, blkaddr, soff);

			doff = NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(dest, db,
								     i);
			rvu_write64(rvu, blkaddr, doff, cfg);
		}

		/* Copy bank configuration */
		cfg = rvu_read64(rvu, blkaddr,
				 NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(src, sb));
		rvu_write64(rvu, blkaddr,
			    NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(dest, db), cfg);
		if (src_kwtype == NPC_MCAM_KEY_X2)
			break;
	}
}

static void npc_cn20k_fill_entryword(struct mcam_entry *entry, int idx,
				     u64 cam0, u64 cam1)
{
	entry->kw[idx] = cam1;
	entry->kw_mask[idx] = cam1 ^ cam0;
}

void npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
			       struct mcam_entry *entry, u8 *intf, u8 *ena,
			       u8 *hw_prio)
{
	struct npc_mcam *mcam = &rvu->hw->mcam;
	u64 cam0, cam1, bank_cfg, cfg;
	int kw = 0, bank;
	u8 kw_type;

	npc_mcam_idx_2_key_type(rvu, index, &kw_type);

	bank = npc_get_bank(mcam, index);
	index &= (mcam->banksize - 1);

	cfg = rvu_read64(rvu, blkaddr,
			 NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(index,
								 bank, 1)) & 3;
	*intf = cfg;

	bank_cfg = rvu_read64(rvu, blkaddr,
			      NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(index, bank));
	*ena = bank_cfg & 0x1;
	*hw_prio = (bank_cfg & GENMASK_ULL(14, 8)) >> 8;
	if (kw_type == NPC_MCAM_KEY_X2) {
		cam1 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index,
									bank,
									1));
		cam0 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index,
									bank,
									0));
		npc_cn20k_fill_entryword(entry, kw, cam0, cam1);

		cam1 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index,
									bank,
									1));
		cam0 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index,
									bank,
									0));
		npc_cn20k_fill_entryword(entry, kw + 1, cam0, cam1);

		cam1 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index,
									bank,
									1));
		cam0 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index,
									bank,
									0));
		npc_cn20k_fill_entryword(entry, kw + 2, cam0, cam1);

		cam1 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index,
									bank,
									1));
		cam0 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index,
									bank,
									0));
		npc_cn20k_fill_entryword(entry, kw + 3, cam0, cam1);
		goto read_action;
	}

	for (bank = 0; bank < mcam->banks_per_entry; bank++, kw = kw + 4) {
		cam1 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index,
									bank,
									1));
		cam0 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index,
									bank,
									0));
		npc_cn20k_fill_entryword(entry, kw, cam0, cam1);

		cam1 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index,
									bank,
									1));
		cam0 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index,
									bank,
									0));
		npc_cn20k_fill_entryword(entry, kw + 1, cam0, cam1);

		cam1 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index,
									bank,
									1));
		cam0 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index,
									bank,
									0));
		npc_cn20k_fill_entryword(entry, kw + 2, cam0, cam1);

		cam1 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index,
									bank,
									1));
		cam0 = rvu_read64(rvu, blkaddr,
				  NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index,
									bank,
									0));
		npc_cn20k_fill_entryword(entry, kw + 3, cam0, cam1);
	}

read_action:
	/* 'action' is set to same value for both bank '0' and '1'.
	 * Hence, reading bank '0' should be enough.
	 */
	cfg = rvu_read64(rvu, blkaddr,
			 NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, 0, 0));
	entry->action = cfg;

	cfg = rvu_read64(rvu, blkaddr,
			 NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, 0, 1));
	entry->vtag_action = cfg;
}

static u8 npc_map2cn20k_flag(u8 flag)
{
	switch (flag) {
@@ -650,11 +1116,12 @@ npc_cn20k_update_action_entries_n_flags(struct rvu *rvu,
int npc_cn20k_apply_custom_kpu(struct rvu *rvu,
			       struct npc_kpu_profile_adapter *profile)
{
	size_t hdr_sz = sizeof(struct npc_cn20k_kpu_profile_fwdata);
	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;
	size_t offset = 0;
	u16 kpu, entry;
	int entries;

@@ -741,6 +1208,40 @@ int npc_cn20k_apply_custom_kpu(struct rvu *rvu,
	return 0;
}

int npc_mcam_idx_2_key_type(struct rvu *rvu, u16 mcam_idx, u8 *key_type)
{
	struct npc_subbank *sb;
	int bank_off, sb_id;

	/* mcam_idx should be less than (2 * bank depth) */
	if (mcam_idx >= npc_priv.bank_depth * 2) {
		dev_err(rvu->dev, "%s:%d bad params\n",
			__func__, __LINE__);
		return -EINVAL;
	}

	/* find mcam offset per bank */
	bank_off = mcam_idx & (npc_priv.bank_depth - 1);

	/* Find subbank id */
	sb_id = bank_off / npc_priv.subbank_depth;

	/* Check if subbank id is more than maximum
	 * number of subbanks available
	 */
	if (sb_id >= npc_priv.num_subbanks) {
		dev_err(rvu->dev, "%s:%d invalid subbank %d\n",
			__func__, __LINE__, sb_id);
		return -EINVAL;
	}

	sb = &npc_priv.sb[sb_id];

	*key_type = sb->key_type;

	return 0;
}

static int npc_subbank_idx_2_mcam_idx(struct rvu *rvu, struct npc_subbank *sb,
				      u16 sub_off, u16 *mcam_idx)
{
+15 −0
Original line number Diff line number Diff line
@@ -294,4 +294,19 @@ void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc);

int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast,
				u16 *mcast, u16 *promisc, u16 *ucast);

void npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
				 u8 intf, struct mcam_entry *entry,
				 bool enable, u8 hw_prio);
void npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
				 int index, bool enable);
void npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr,
			       u16 src, u16 dest);
void npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
			       struct mcam_entry *entry, u8 *intf, u8 *ena,
			       u8 *hw_prio);
void npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr,
				int bank, int index);
int npc_mcam_idx_2_key_type(struct rvu *rvu, u16 mcam_idx, u8 *key_type);

#endif /* NPC_CN20K_H */
+3 −0
Original line number Diff line number Diff line
@@ -1577,6 +1577,8 @@ struct npc_mcam_write_entry_req {
	u8  intf;	 /* Rx or Tx interface */
	u8  enable_entry;/* Enable this MCAM entry ? */
	u8  set_cntr;    /* Set counter for this entry ? */
	u8  hw_prio;	 /* hardware priority, valid for cn20k */
	u64 reserved;	 /* reserved for future use */
};

/* Enable/Disable a given entry */
@@ -1824,6 +1826,7 @@ struct npc_mcam_read_entry_rsp {
	struct mcam_entry entry_data;
	u8 intf;
	u8 enable;
	u8 hw_prio; /* valid for cn20k */
};

/* Available entries to use */
+2 −2
Original line number Diff line number Diff line
@@ -1124,8 +1124,8 @@ int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause
void rvu_mac_reset(struct rvu *rvu, u16 pcifunc);
u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac);
void cgx_start_linkup(struct rvu *rvu);
int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
			     int type);
int npc_get_nixlf_mcam_index(struct npc_mcam *mcam,
			     u16 pcifunc, int nixlf, int type);
bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
			   int index);
int rvu_npc_init(struct rvu *rvu);
+0 −1
Original line number Diff line number Diff line
@@ -5289,7 +5289,6 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
	/* Disable the interface if it is in any multicast list */
	nix_mcast_update_mce_entry(rvu, pcifunc, 0);


	pfvf = rvu_get_pfvf(rvu, pcifunc);
	clear_bit(NIXLF_INITIALIZED, &pfvf->flags);

Loading