// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Admin Function driver
 *
 * Copyright (C) 2022 Marvell.
 *
 */

#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/stddef.h>
#include <linux/debugfs.h>

#include "rvu_struct.h"
#include "rvu_reg.h"
#include "rvu.h"
#include "npc.h"
#include "cgx.h"
#include "rvu_npc_fs.h"
#include "rvu_npc_hash.h"

static u64 rvu_npc_wide_extract(const u64 input[], size_t start_bit,
				size_t width_bits)
{
	const u64 mask = ~(u64)((~(__uint128_t)0) << width_bits);
	const size_t msb = start_bit + width_bits - 1;
	const size_t lword = start_bit >> 6;
	const size_t uword = msb >> 6;
	size_t lbits;
	u64 hi, lo;

	if (lword == uword)
		return (input[lword] >> (start_bit & 63)) & mask;

	lbits = 64 - (start_bit & 63);
	hi = input[uword];
	lo = (input[lword] >> (start_bit & 63));
	return ((hi << lbits) | lo) & mask;
}

static void rvu_npc_lshift_key(u64 *key, size_t key_bit_len)
{
	u64 prev_orig_word = 0;
	u64 cur_orig_word = 0;
	size_t extra = key_bit_len % 64;
	size_t max_idx = key_bit_len / 64;
	size_t i;

	if (extra)
		max_idx++;

	for (i = 0; i < max_idx; i++) {
		cur_orig_word = key[i];
		key[i] = key[i] << 1;
		key[i] |= ((prev_orig_word >> 63) & 0x1);
		prev_orig_word = cur_orig_word;
	}
}

static u32 rvu_npc_toeplitz_hash(const u64 *data, u64 *key, size_t data_bit_len,
				 size_t key_bit_len)
{
	u32 hash_out = 0;
	u64 temp_data = 0;
	int i;

	for (i = data_bit_len - 1; i >= 0; i--) {
		temp_data = (data[i / 64]);
		temp_data = temp_data >> (i % 64);
		temp_data &= 0x1;
		if (temp_data)
			hash_out ^= (u32)(rvu_npc_wide_extract(key, key_bit_len - 32, 32));

		rvu_npc_lshift_key(key, key_bit_len);
	}

	return hash_out;
}

u32 npc_field_hash_calc(u64 *ldata, struct npc_get_field_hash_info_rsp rsp,
			u8 intf, u8 hash_idx)
{
	u64 hash_key[3];
	u64 data_padded[2];
	u32 field_hash;

	hash_key[0] = rsp.secret_key[1] << 31;
	hash_key[0] |= rsp.secret_key[2];
	hash_key[1] = rsp.secret_key[1] >> 33;
	hash_key[1] |= rsp.secret_key[0] << 31;
	hash_key[2] = rsp.secret_key[0] >> 33;

	data_padded[0] = rsp.hash_mask[intf][hash_idx][0] & ldata[0];
	data_padded[1] = rsp.hash_mask[intf][hash_idx][1] & ldata[1];
	field_hash = rvu_npc_toeplitz_hash(data_padded, hash_key, 128, 159);

	field_hash &= FIELD_GET(GENMASK(63, 32), rsp.hash_ctrl[intf][hash_idx]);
	field_hash += FIELD_GET(GENMASK(31, 0), rsp.hash_ctrl[intf][hash_idx]);
	return field_hash;
}

static u64 npc_update_use_hash(struct rvu *rvu, int blkaddr,
			       u8 intf, int lid, int lt, int ld)
{
	u8 hdr, key;
	u64 cfg;

	cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, lt, ld));
	hdr = FIELD_GET(NPC_HDR_OFFSET, cfg);
	key = FIELD_GET(NPC_KEY_OFFSET, cfg);

	/* Update use_hash(bit-20) to 'true' and
	 * bytesm1(bit-16:19) to '0x3' in KEX_LD_CFG
	 */
	cfg = KEX_LD_CFG_USE_HASH(0x1, 0x03,
				  hdr, 0x1, 0x0, key);

	return cfg;
}

static void npc_program_mkex_hash_rx(struct rvu *rvu, int blkaddr,
				     u8 intf)
{
	struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
	int lid, lt, ld, hash_cnt = 0;

	if (is_npc_intf_tx(intf))
		return;

	/* Program HASH_CFG */
	for (lid = 0; lid < NPC_MAX_LID; lid++) {
		for (lt = 0; lt < NPC_MAX_LT; lt++) {
			for (ld = 0; ld < NPC_MAX_LD; ld++) {
				if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
					u64 cfg;

					if (hash_cnt == NPC_MAX_HASH)
						return;

					cfg = npc_update_use_hash(rvu, blkaddr,
								  intf, lid, lt, ld);
					/* Set updated KEX configuration */
					SET_KEX_LD(intf, lid, lt, ld, cfg);
					/* Set HASH configuration */
					SET_KEX_LD_HASH(intf, ld,
							mkex_hash->hash[intf][ld]);
					SET_KEX_LD_HASH_MASK(intf, ld, 0,
							     mkex_hash->hash_mask[intf][ld][0]);
					SET_KEX_LD_HASH_MASK(intf, ld, 1,
							     mkex_hash->hash_mask[intf][ld][1]);
					SET_KEX_LD_HASH_CTRL(intf, ld,
							     mkex_hash->hash_ctrl[intf][ld]);

					hash_cnt++;
				}
			}
		}
	}
}

static void npc_program_mkex_hash_tx(struct rvu *rvu, int blkaddr,
				     u8 intf)
{
	struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
	int lid, lt, ld, hash_cnt = 0;

	if (is_npc_intf_rx(intf))
		return;

	/* Program HASH_CFG */
	for (lid = 0; lid < NPC_MAX_LID; lid++) {
		for (lt = 0; lt < NPC_MAX_LT; lt++) {
			for (ld = 0; ld < NPC_MAX_LD; ld++)
				if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
					u64 cfg;

					if (hash_cnt == NPC_MAX_HASH)
						return;

					cfg = npc_update_use_hash(rvu, blkaddr,
								  intf, lid, lt, ld);
					/* Set updated KEX configuration */
					SET_KEX_LD(intf, lid, lt, ld, cfg);
					/* Set HASH configuration */
					SET_KEX_LD_HASH(intf, ld,
							mkex_hash->hash[intf][ld]);
					SET_KEX_LD_HASH_MASK(intf, ld, 0,
							     mkex_hash->hash_mask[intf][ld][0]);
					SET_KEX_LD_HASH_MASK(intf, ld, 1,
							     mkex_hash->hash_mask[intf][ld][1]);
					SET_KEX_LD_HASH_CTRL(intf, ld,
							     mkex_hash->hash_ctrl[intf][ld]);
					hash_cnt++;
				}
		}
	}
}

void npc_config_secret_key(struct rvu *rvu, int blkaddr)
{
	struct hw_cap *hwcap = &rvu->hw->cap;
	struct rvu_hwinfo *hw = rvu->hw;
	u8 intf;

	if (!hwcap->npc_hash_extract)
		return;

	for (intf = 0; intf < hw->npc_intfs; intf++) {
		rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf),
			    RVU_NPC_HASH_SECRET_KEY0);
		rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf),
			    RVU_NPC_HASH_SECRET_KEY1);
		rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf),
			    RVU_NPC_HASH_SECRET_KEY2);
	}
}

void npc_program_mkex_hash(struct rvu *rvu, int blkaddr)
{
	struct npc_mcam_kex_hash *mh = rvu->kpu.mkex_hash;
	struct hw_cap *hwcap = &rvu->hw->cap;
	u8 intf, ld, hdr_offset, byte_len;
	struct rvu_hwinfo *hw = rvu->hw;
	u64 cfg;

	/* Check if hardware supports hash extraction */
	if (!hwcap->npc_hash_extract)
		return;

	/* Check if IPv6 source/destination address
	 * should be hash enabled.
	 * Hashing reduces 128bit SIP/DIP fields to 32bit
	 * so that 224 bit X2 key can be used for IPv6 based filters as well,
	 * which in turn results in more number of MCAM entries available for
	 * use.
	 *
	 * Hashing of IPV6 SIP/DIP is enabled in below scenarios
	 * 1. If the silicon variant supports hashing feature
	 * 2. If the number of bytes of IP addr being extracted is 4 bytes ie
	 *    32bit. The assumption here is that if user wants 8bytes of LSB of
	 *    IP addr or full 16 bytes then his intention is not to use 32bit
	 *    hash.
	 */
	for (intf = 0; intf < hw->npc_intfs; intf++) {
		for (ld = 0; ld < NPC_MAX_LD; ld++) {
			cfg = rvu_read64(rvu, blkaddr,
					 NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf,
								       NPC_LID_LC,
								       NPC_LT_LC_IP6,
								       ld));
			hdr_offset = FIELD_GET(NPC_HDR_OFFSET, cfg);
			byte_len = FIELD_GET(NPC_BYTESM, cfg);
			/* Hashing of IPv6 source/destination address should be
			 * enabled if,
			 * hdr_offset == 8 (offset of source IPv6 address) or
			 * hdr_offset == 24 (offset of destination IPv6)
			 * address) and the number of byte to be
			 * extracted is 4. As per hardware configuration
			 * byte_len should be == actual byte_len - 1.
			 * Hence byte_len is checked against 3 but nor 4.
			 */
			if ((hdr_offset == 8 || hdr_offset == 24) && byte_len == 3)
				mh->lid_lt_ld_hash_en[intf][NPC_LID_LC][NPC_LT_LC_IP6][ld] = true;
		}
	}

	/* Update hash configuration if the field is hash enabled */
	for (intf = 0; intf < hw->npc_intfs; intf++) {
		npc_program_mkex_hash_rx(rvu, blkaddr, intf);
		npc_program_mkex_hash_tx(rvu, blkaddr, intf);
	}
}

void npc_update_field_hash(struct rvu *rvu, u8 intf,
			   struct mcam_entry *entry,
			   int blkaddr,
			   u64 features,
			   struct flow_msg *pkt,
			   struct flow_msg *mask,
			   struct flow_msg *opkt,
			   struct flow_msg *omask)
{
	struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
	struct npc_get_field_hash_info_req req;
	struct npc_get_field_hash_info_rsp rsp;
	u64 ldata[2], cfg;
	u32 field_hash;
	u8 hash_idx;

	if (!rvu->hw->cap.npc_hash_extract) {
		dev_dbg(rvu->dev, "%s: Field hash extract feature is not supported\n", __func__);
		return;
	}

	req.intf = intf;
	rvu_mbox_handler_npc_get_field_hash_info(rvu, &req, &rsp);

	for (hash_idx = 0; hash_idx < NPC_MAX_HASH; hash_idx++) {
		cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_CFG(intf, hash_idx));
		if ((cfg & BIT_ULL(11)) && (cfg & BIT_ULL(12))) {
			u8 lid = (cfg & GENMASK_ULL(10, 8)) >> 8;
			u8 ltype = (cfg & GENMASK_ULL(7, 4)) >> 4;
			u8 ltype_mask = cfg & GENMASK_ULL(3, 0);

			if (mkex_hash->lid_lt_ld_hash_en[intf][lid][ltype][hash_idx]) {
				switch (ltype & ltype_mask) {
				/* If hash extract enabled is supported for IPv6 then
				 * 128 bit IPv6 source and destination addressed
				 * is hashed to 32 bit value.
				 */
				case NPC_LT_LC_IP6:
					/* ld[0] == hash_idx[0] == Source IPv6
					 * ld[1] == hash_idx[1] == Destination IPv6
					 */
					if ((features & BIT_ULL(NPC_SIP_IPV6)) && !hash_idx) {
						u32 src_ip[IPV6_WORDS];

						be32_to_cpu_array(src_ip, pkt->ip6src, IPV6_WORDS);
						ldata[1] = (u64)src_ip[0] << 32 | src_ip[1];
						ldata[0] = (u64)src_ip[2] << 32 | src_ip[3];
						field_hash = npc_field_hash_calc(ldata,
										 rsp,
										 intf,
										 hash_idx);
						npc_update_entry(rvu, NPC_SIP_IPV6, entry,
								 field_hash, 0,
								 GENMASK(31, 0), 0, intf);
						memcpy(&opkt->ip6src, &pkt->ip6src,
						       sizeof(pkt->ip6src));
						memcpy(&omask->ip6src, &mask->ip6src,
						       sizeof(mask->ip6src));
					} else if ((features & BIT_ULL(NPC_DIP_IPV6)) && hash_idx) {
						u32 dst_ip[IPV6_WORDS];

						be32_to_cpu_array(dst_ip, pkt->ip6dst, IPV6_WORDS);
						ldata[1] = (u64)dst_ip[0] << 32 | dst_ip[1];
						ldata[0] = (u64)dst_ip[2] << 32 | dst_ip[3];
						field_hash = npc_field_hash_calc(ldata,
										 rsp,
										 intf,
										 hash_idx);
						npc_update_entry(rvu, NPC_DIP_IPV6, entry,
								 field_hash, 0,
								 GENMASK(31, 0), 0, intf);
						memcpy(&opkt->ip6dst, &pkt->ip6dst,
						       sizeof(pkt->ip6dst));
						memcpy(&omask->ip6dst, &mask->ip6dst,
						       sizeof(mask->ip6dst));
					}

					break;
				}
			}
		}
	}
}

int rvu_mbox_handler_npc_get_field_hash_info(struct rvu *rvu,
					     struct npc_get_field_hash_info_req *req,
					     struct npc_get_field_hash_info_rsp *rsp)
{
	u64 *secret_key = rsp->secret_key;
	u8 intf = req->intf;
	int i, j, blkaddr;

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

	secret_key[0] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf));
	secret_key[1] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf));
	secret_key[2] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf));

	for (i = 0; i < NPC_MAX_HASH; i++) {
		for (j = 0; j < NPC_MAX_HASH_MASK; j++) {
			rsp->hash_mask[NIX_INTF_RX][i][j] =
				GET_KEX_LD_HASH_MASK(NIX_INTF_RX, i, j);
			rsp->hash_mask[NIX_INTF_TX][i][j] =
				GET_KEX_LD_HASH_MASK(NIX_INTF_TX, i, j);
		}
	}

	for (i = 0; i < NPC_MAX_INTF; i++)
		for (j = 0; j < NPC_MAX_HASH; j++)
			rsp->hash_ctrl[i][j] = GET_KEX_LD_HASH_CTRL(i, j);

	return 0;
}

/**
 *	rvu_exact_prepare_mdata - Make mdata for mcam entry
 *	@mac: MAC address
 *	@chan: Channel number.
 *	@ctype: Channel Type.
 *	@mask: LDATA mask.
 *	Return: Meta data
 */
static u64 rvu_exact_prepare_mdata(u8 *mac, u16 chan, u16 ctype, u64 mask)
{
	u64 ldata = ether_addr_to_u64(mac);

	/* Please note that mask is 48bit which excludes chan and ctype.
	 * Increase mask bits if we need to include them as well.
	 */
	ldata |= ((u64)chan << 48);
	ldata |= ((u64)ctype  << 60);
	ldata &= mask;
	ldata = ldata << 2;

	return ldata;
}

/**
 *      rvu_exact_calculate_hash - calculate hash index to mem table.
 *	@rvu: resource virtualization unit.
 *	@chan: Channel number
 *	@ctype: Channel type.
 *	@mac: MAC address
 *	@mask: HASH mask.
 *	@table_depth: Depth of table.
 *	Return: Hash value
 */
static u32 rvu_exact_calculate_hash(struct rvu *rvu, u16 chan, u16 ctype, u8 *mac,
				    u64 mask, u32 table_depth)
{
	struct npc_exact_table *table = rvu->hw->table;
	u64 hash_key[2];
	u64 key_in[2];
	u64 ldata;
	u32 hash;

	key_in[0] = RVU_NPC_HASH_SECRET_KEY0;
	key_in[1] = RVU_NPC_HASH_SECRET_KEY2;

	hash_key[0] = key_in[0] << 31;
	hash_key[0] |= key_in[1];
	hash_key[1] = key_in[0] >> 33;

	ldata = rvu_exact_prepare_mdata(mac, chan, ctype, mask);

	dev_dbg(rvu->dev, "%s: ldata=0x%llx hash_key0=0x%llx hash_key2=0x%llx\n", __func__,
		ldata, hash_key[1], hash_key[0]);
	hash = rvu_npc_toeplitz_hash(&ldata, (u64 *)hash_key, 64, 95);

	hash &= table->mem_table.hash_mask;
	hash += table->mem_table.hash_offset;
	dev_dbg(rvu->dev, "%s: hash=%x\n", __func__,  hash);

	return hash;
}

/**
 *      rvu_npc_exact_alloc_mem_table_entry - find free entry in 4 way table.
 *      @rvu: resource virtualization unit.
 *	@way: Indicate way to table.
 *	@index: Hash index to 4 way table.
 *	@hash: Hash value.
 *
 *	Searches 4 way table using hash index. Returns 0 on success.
 *	Return: 0 upon success.
 */
static int rvu_npc_exact_alloc_mem_table_entry(struct rvu *rvu, u8 *way,
					       u32 *index, unsigned int hash)
{
	struct npc_exact_table *table;
	int depth, i;

	table = rvu->hw->table;
	depth = table->mem_table.depth;

	/* Check all the 4 ways for a free slot. */
	mutex_lock(&table->lock);
	for (i = 0; i <  table->mem_table.ways; i++) {
		if (test_bit(hash + i * depth, table->mem_table.bmap))
			continue;

		set_bit(hash + i * depth, table->mem_table.bmap);
		mutex_unlock(&table->lock);

		dev_dbg(rvu->dev, "%s: mem table entry alloc success (way=%d index=%d)\n",
			__func__, i, hash);

		*way = i;
		*index = hash;
		return 0;
	}
	mutex_unlock(&table->lock);

	dev_dbg(rvu->dev, "%s: No space in 4 way exact way, weight=%u\n", __func__,
		bitmap_weight(table->mem_table.bmap, table->mem_table.depth));
	return -ENOSPC;
}

/**
 *	rvu_npc_exact_free_id - Free seq id from bitmat.
 *	@rvu: Resource virtualization unit.
 *	@seq_id: Sequence identifier to be freed.
 */
static void rvu_npc_exact_free_id(struct rvu *rvu, u32 seq_id)
{
	struct npc_exact_table *table;

	table = rvu->hw->table;
	mutex_lock(&table->lock);
	clear_bit(seq_id, table->id_bmap);
	mutex_unlock(&table->lock);
	dev_dbg(rvu->dev, "%s: freed id %d\n", __func__, seq_id);
}

/**
 *	rvu_npc_exact_alloc_id - Alloc seq id from bitmap.
 *	@rvu: Resource virtualization unit.
 *	@seq_id: Sequence identifier.
 *	Return: True or false.
 */
static bool rvu_npc_exact_alloc_id(struct rvu *rvu, u32 *seq_id)
{
	struct npc_exact_table *table;
	u32 idx;

	table = rvu->hw->table;

	mutex_lock(&table->lock);
	idx = find_first_zero_bit(table->id_bmap, table->tot_ids);
	if (idx == table->tot_ids) {
		mutex_unlock(&table->lock);
		dev_err(rvu->dev, "%s: No space in id bitmap (%d)\n",
			__func__, table->tot_ids);

		return false;
	}

	/* Mark bit map to indicate that slot is used.*/
	set_bit(idx, table->id_bmap);
	mutex_unlock(&table->lock);

	*seq_id = idx;
	dev_dbg(rvu->dev, "%s: Allocated id (%d)\n", __func__, *seq_id);

	return true;
}

/**
 *      rvu_npc_exact_alloc_cam_table_entry - find free slot in fully associative table.
 *      @rvu: resource virtualization unit.
 *	@index: Index to exact CAM table.
 *	Return: 0 upon success; else error number.
 */
static int rvu_npc_exact_alloc_cam_table_entry(struct rvu *rvu, int *index)
{
	struct npc_exact_table *table;
	u32 idx;

	table = rvu->hw->table;

	mutex_lock(&table->lock);
	idx = find_first_zero_bit(table->cam_table.bmap, table->cam_table.depth);
	if (idx == table->cam_table.depth) {
		mutex_unlock(&table->lock);
		dev_info(rvu->dev, "%s: No space in exact cam table, weight=%u\n", __func__,
			 bitmap_weight(table->cam_table.bmap, table->cam_table.depth));
		return -ENOSPC;
	}

	/* Mark bit map to indicate that slot is used.*/
	set_bit(idx, table->cam_table.bmap);
	mutex_unlock(&table->lock);

	*index = idx;
	dev_dbg(rvu->dev, "%s: cam table entry alloc success (index=%d)\n",
		__func__, idx);
	return 0;
}

/**
 *	rvu_exact_prepare_table_entry - Data for exact match table entry.
 *	@rvu: Resource virtualization unit.
 *	@enable: Enable/Disable entry
 *	@ctype: Software defined channel type. Currently set as 0.
 *	@chan: Channel number.
 *	@mac_addr: Destination mac address.
 *	Return: mdata for exact match table.
 */
static u64 rvu_exact_prepare_table_entry(struct rvu *rvu, bool enable,
					 u8 ctype, u16 chan, u8 *mac_addr)

{
	u64 ldata = ether_addr_to_u64(mac_addr);

	/* Enable or disable */
	u64 mdata = FIELD_PREP(GENMASK_ULL(63, 63), enable ? 1 : 0);

	/* Set Ctype */
	mdata |= FIELD_PREP(GENMASK_ULL(61, 60), ctype);

	/* Set chan */
	mdata |= FIELD_PREP(GENMASK_ULL(59, 48), chan);

	/* MAC address */
	mdata |= FIELD_PREP(GENMASK_ULL(47, 0), ldata);

	return mdata;
}

/**
 *	rvu_exact_config_secret_key - Configure secret key.
 *	@rvu: Resource virtualization unit.
 */
static void rvu_exact_config_secret_key(struct rvu *rvu)
{
	int blkaddr;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
	rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET0(NIX_INTF_RX),
		    RVU_NPC_HASH_SECRET_KEY0);

	rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET1(NIX_INTF_RX),
		    RVU_NPC_HASH_SECRET_KEY1);

	rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET2(NIX_INTF_RX),
		    RVU_NPC_HASH_SECRET_KEY2);
}

/**
 *	rvu_exact_config_search_key - Configure search key
 *	@rvu: Resource virtualization unit.
 */
static void rvu_exact_config_search_key(struct rvu *rvu)
{
	int blkaddr;
	u64 reg_val;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);

	/* HDR offset */
	reg_val = FIELD_PREP(GENMASK_ULL(39, 32), 0);

	/* BYTESM1, number of bytes - 1 */
	reg_val |= FIELD_PREP(GENMASK_ULL(18, 16), ETH_ALEN - 1);

	/* Enable LID and set LID to  NPC_LID_LA */
	reg_val |= FIELD_PREP(GENMASK_ULL(11, 11), 1);
	reg_val |= FIELD_PREP(GENMASK_ULL(10, 8),  NPC_LID_LA);

	/* Clear layer type based extraction */

	/* Disable LT_EN */
	reg_val |= FIELD_PREP(GENMASK_ULL(12, 12), 0);

	/* Set LTYPE_MATCH to 0 */
	reg_val |= FIELD_PREP(GENMASK_ULL(7, 4), 0);

	/* Set LTYPE_MASK to 0 */
	reg_val |= FIELD_PREP(GENMASK_ULL(3, 0), 0);

	rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_CFG(NIX_INTF_RX), reg_val);
}

/**
 *	rvu_exact_config_result_ctrl - Set exact table hash control
 *	@rvu: Resource virtualization unit.
 *	@depth: Depth of Exact match table.
 *
 *	Sets mask and offset for hash for mem table.
 */
static void rvu_exact_config_result_ctrl(struct rvu *rvu, uint32_t depth)
{
	int blkaddr;
	u64 reg = 0;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);

	/* Set mask. Note that depth is a power of 2 */
	rvu->hw->table->mem_table.hash_mask = (depth - 1);
	reg |= FIELD_PREP(GENMASK_ULL(42, 32), (depth - 1));

	/* Set offset as 0 */
	rvu->hw->table->mem_table.hash_offset = 0;
	reg |= FIELD_PREP(GENMASK_ULL(10, 0), 0);

	/* Set reg for RX */
	rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_RESULT_CTL(NIX_INTF_RX), reg);
	/* Store hash mask and offset for s/w algorithm */
}

/**
 *	rvu_exact_config_table_mask - Set exact table mask.
 *	@rvu: Resource virtualization unit.
 */
static void rvu_exact_config_table_mask(struct rvu *rvu)
{
	int blkaddr;
	u64 mask = 0;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);

	/* Don't use Ctype */
	mask |= FIELD_PREP(GENMASK_ULL(61, 60), 0);

	/* Set chan */
	mask |= GENMASK_ULL(59, 48);

	/* Full ldata */
	mask |= GENMASK_ULL(47, 0);

	/* Store mask for s/w hash calcualtion */
	rvu->hw->table->mem_table.mask = mask;

	/* Set mask for RX.*/
	rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_MASK(NIX_INTF_RX), mask);
}

/**
 *      rvu_npc_exact_get_max_entries - Get total number of entries in table.
 *      @rvu: resource virtualization unit.
 *	Return: Maximum table entries possible.
 */
u32 rvu_npc_exact_get_max_entries(struct rvu *rvu)
{
	struct npc_exact_table *table;

	table = rvu->hw->table;
	return table->tot_ids;
}

/**
 *      rvu_npc_exact_has_match_table - Checks support for exact match.
 *      @rvu: resource virtualization unit.
 *	Return: True if exact match table is supported/enabled.
 */
bool rvu_npc_exact_has_match_table(struct rvu *rvu)
{
	return  rvu->hw->cap.npc_exact_match_enabled;
}

/**
 *      __rvu_npc_exact_find_entry_by_seq_id - find entry by id
 *      @rvu: resource virtualization unit.
 *	@seq_id: Sequence identifier.
 *
 *	Caller should acquire the lock.
 *	Return: Pointer to table entry.
 */
static struct npc_exact_table_entry *
__rvu_npc_exact_find_entry_by_seq_id(struct rvu *rvu, u32 seq_id)
{
	struct npc_exact_table *table = rvu->hw->table;
	struct npc_exact_table_entry *entry = NULL;
	struct list_head *lhead;

	lhead = &table->lhead_gbl;

	/* traverse to find the matching entry */
	list_for_each_entry(entry, lhead, glist) {
		if (entry->seq_id != seq_id)
			continue;

		return entry;
	}

	return NULL;
}

/**
 *      rvu_npc_exact_add_to_list - Add entry to list
 *      @rvu: resource virtualization unit.
 *	@opc_type: OPCODE to select MEM/CAM table.
 *	@ways: MEM table ways.
 *	@index: Index in MEM/CAM table.
 *	@cgx_id: CGX identifier.
 *	@lmac_id: LMAC identifier.
 *	@mac_addr: MAC address.
 *	@chan: Channel number.
 *	@ctype: Channel Type.
 *	@seq_id: Sequence identifier
 *	@cmd: True if function is called by ethtool cmd
 *	@mcam_idx: NPC mcam index of DMAC entry in NPC mcam.
 *	@pcifunc: pci function
 *	Return: 0 upon success.
 */
static int rvu_npc_exact_add_to_list(struct rvu *rvu, enum npc_exact_opc_type opc_type, u8 ways,
				     u32 index, u8 cgx_id, u8 lmac_id, u8 *mac_addr, u16 chan,
				     u8 ctype, u32 *seq_id, bool cmd, u32 mcam_idx, u16 pcifunc)
{
	struct npc_exact_table_entry *entry, *tmp, *iter;
	struct npc_exact_table *table = rvu->hw->table;
	struct list_head *lhead, *pprev;

	WARN_ON(ways >= NPC_EXACT_TBL_MAX_WAYS);

	if (!rvu_npc_exact_alloc_id(rvu, seq_id)) {
		dev_err(rvu->dev, "%s: Generate seq id failed\n", __func__);
		return -EFAULT;
	}

	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry) {
		rvu_npc_exact_free_id(rvu, *seq_id);
		dev_err(rvu->dev, "%s: Memory allocation failed\n", __func__);
		return -ENOMEM;
	}

	mutex_lock(&table->lock);
	switch (opc_type) {
	case NPC_EXACT_OPC_CAM:
		lhead = &table->lhead_cam_tbl_entry;
		table->cam_tbl_entry_cnt++;
		break;

	case NPC_EXACT_OPC_MEM:
		lhead = &table->lhead_mem_tbl_entry[ways];
		table->mem_tbl_entry_cnt++;
		break;

	default:
		mutex_unlock(&table->lock);
		kfree(entry);
		rvu_npc_exact_free_id(rvu, *seq_id);

		dev_err(rvu->dev, "%s: Unknown opc type%d\n", __func__, opc_type);
		return  -EINVAL;
	}

	/* Add to global list */
	INIT_LIST_HEAD(&entry->glist);
	list_add_tail(&entry->glist, &table->lhead_gbl);
	INIT_LIST_HEAD(&entry->list);
	entry->index = index;
	entry->ways = ways;
	entry->opc_type = opc_type;

	entry->pcifunc = pcifunc;

	ether_addr_copy(entry->mac, mac_addr);
	entry->chan = chan;
	entry->ctype = ctype;
	entry->cgx_id = cgx_id;
	entry->lmac_id = lmac_id;

	entry->seq_id = *seq_id;

	entry->mcam_idx = mcam_idx;
	entry->cmd = cmd;

	pprev = lhead;

	/* Insert entry in ascending order of index */
	list_for_each_entry_safe(iter, tmp, lhead, list) {
		if (index < iter->index)
			break;

		pprev = &iter->list;
	}

	/* Add to each table list */
	list_add(&entry->list, pprev);
	mutex_unlock(&table->lock);
	return 0;
}

/**
 *	rvu_npc_exact_mem_table_write - Wrapper for register write
 *	@rvu: resource virtualization unit.
 *	@blkaddr: Block address
 *	@ways: ways for MEM table.
 *	@index: Index in MEM
 *	@mdata: Meta data to be written to register.
 */
static void rvu_npc_exact_mem_table_write(struct rvu *rvu, int blkaddr, u8 ways,
					  u32 index, u64 mdata)
{
	rvu_write64(rvu, blkaddr, NPC_AF_EXACT_MEM_ENTRY(ways, index), mdata);
}

/**
 *	rvu_npc_exact_cam_table_write - Wrapper for register write
 *	@rvu: resource virtualization unit.
 *	@blkaddr: Block address
 *	@index: Index in MEM
 *	@mdata: Meta data to be written to register.
 */
static void rvu_npc_exact_cam_table_write(struct rvu *rvu, int blkaddr,
					  u32 index, u64 mdata)
{
	rvu_write64(rvu, blkaddr, NPC_AF_EXACT_CAM_ENTRY(index), mdata);
}

/**
 *      rvu_npc_exact_dealloc_table_entry - dealloc table entry
 *      @rvu: resource virtualization unit.
 *	@opc_type: OPCODE for selection of table(MEM or CAM)
 *	@ways: ways if opc_type is MEM table.
 *	@index: Index of MEM or CAM table.
 *	Return: 0 upon success.
 */
static int rvu_npc_exact_dealloc_table_entry(struct rvu *rvu, enum npc_exact_opc_type opc_type,
					     u8 ways, u32 index)
{
	int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
	struct npc_exact_table *table;
	u8 null_dmac[6] = { 0 };
	int depth;

	/* Prepare entry with all fields set to zero */
	u64 null_mdata = rvu_exact_prepare_table_entry(rvu, false, 0, 0, null_dmac);

	table = rvu->hw->table;
	depth = table->mem_table.depth;

	mutex_lock(&table->lock);

	switch (opc_type) {
	case NPC_EXACT_OPC_CAM:

		/* Check whether entry is used already */
		if (!test_bit(index, table->cam_table.bmap)) {
			mutex_unlock(&table->lock);
			dev_err(rvu->dev, "%s: Trying to free an unused entry ways=%d index=%d\n",
				__func__, ways, index);
			return -EINVAL;
		}

		rvu_npc_exact_cam_table_write(rvu, blkaddr, index, null_mdata);
		clear_bit(index, table->cam_table.bmap);
		break;

	case NPC_EXACT_OPC_MEM:

		/* Check whether entry is used already */
		if (!test_bit(index + ways * depth, table->mem_table.bmap)) {
			mutex_unlock(&table->lock);
			dev_err(rvu->dev, "%s: Trying to free an unused entry index=%d\n",
				__func__, index);
			return -EINVAL;
		}

		rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index, null_mdata);
		clear_bit(index + ways * depth, table->mem_table.bmap);
		break;

	default:
		mutex_unlock(&table->lock);
		dev_err(rvu->dev, "%s: invalid opc type %d", __func__, opc_type);
		return -ENOSPC;
	}

	mutex_unlock(&table->lock);

	dev_dbg(rvu->dev, "%s: Successfully deleted entry (index=%d, ways=%d opc_type=%d\n",
		__func__, index,  ways, opc_type);

	return 0;
}

/**
 *	rvu_npc_exact_alloc_table_entry - Allociate an entry
 *      @rvu: resource virtualization unit.
 *	@mac: MAC address.
 *	@chan: Channel number.
 *	@ctype: Channel Type.
 *	@index: Index of MEM table or CAM table.
 *	@ways: Ways. Only valid for MEM table.
 *	@opc_type: OPCODE to select table (MEM or CAM)
 *
 *	Try allocating a slot from MEM table. If all 4 ways
 *	slot are full for a hash index, check availability in
 *	32-entry CAM table for allocation.
 *	Return: 0 upon success.
 */
static int rvu_npc_exact_alloc_table_entry(struct rvu *rvu,  char *mac, u16 chan, u8 ctype,
					   u32 *index, u8 *ways, enum npc_exact_opc_type *opc_type)
{
	struct npc_exact_table *table;
	unsigned int hash;
	int err;

	table = rvu->hw->table;

	/* Check in 4-ways mem entry for free slote */
	hash =  rvu_exact_calculate_hash(rvu, chan, ctype, mac, table->mem_table.mask,
					 table->mem_table.depth);
	err = rvu_npc_exact_alloc_mem_table_entry(rvu, ways, index, hash);
	if (!err) {
		*opc_type = NPC_EXACT_OPC_MEM;
		dev_dbg(rvu->dev, "%s: inserted in 4 ways hash table ways=%d, index=%d\n",
			__func__, *ways, *index);
		return 0;
	}

	dev_dbg(rvu->dev, "%s: failed to insert in 4 ways hash table\n", __func__);

	/* wayss is 0 for cam table */
	*ways = 0;
	err = rvu_npc_exact_alloc_cam_table_entry(rvu, index);
	if (!err) {
		*opc_type = NPC_EXACT_OPC_CAM;
		dev_dbg(rvu->dev, "%s: inserted in fully associative hash table index=%u\n",
			__func__, *index);
		return 0;
	}

	dev_err(rvu->dev, "%s: failed to insert in fully associative hash table\n", __func__);
	return -ENOSPC;
}

/**
 *	rvu_npc_exact_save_drop_rule_chan_and_mask - Save drop rules info in data base.
 *      @rvu: resource virtualization unit.
 *	@drop_mcam_idx: Drop rule index in NPC mcam.
 *	@chan_val: Channel value.
 *	@chan_mask: Channel Mask.
 *	@pcifunc: pcifunc of interface.
 *	Return: True upon success.
 */
static bool rvu_npc_exact_save_drop_rule_chan_and_mask(struct rvu *rvu, int drop_mcam_idx,
						       u64 chan_val, u64 chan_mask, u16 pcifunc)
{
	struct npc_exact_table *table;
	int i;

	table = rvu->hw->table;

	for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
		if (!table->drop_rule_map[i].valid)
			break;

		if (table->drop_rule_map[i].chan_val != (u16)chan_val)
			continue;

		if (table->drop_rule_map[i].chan_mask != (u16)chan_mask)
			continue;

		return false;
	}

	if (i == NPC_MCAM_DROP_RULE_MAX)
		return false;

	table->drop_rule_map[i].drop_rule_idx = drop_mcam_idx;
	table->drop_rule_map[i].chan_val = (u16)chan_val;
	table->drop_rule_map[i].chan_mask = (u16)chan_mask;
	table->drop_rule_map[i].pcifunc = pcifunc;
	table->drop_rule_map[i].valid = true;
	return true;
}

/**
 *	rvu_npc_exact_calc_drop_rule_chan_and_mask - Calculate Channel number and mask.
 *      @rvu: resource virtualization unit.
 *	@intf_type: Interface type (SDK, LBK or CGX)
 *	@cgx_id: CGX identifier.
 *	@lmac_id: LAMC identifier.
 *	@val: Channel number.
 *	@mask: Channel mask.
 *	Return: True upon success.
 */
static bool rvu_npc_exact_calc_drop_rule_chan_and_mask(struct rvu *rvu, u8 intf_type,
						       u8 cgx_id, u8 lmac_id,
						       u64 *val, u64 *mask)
{
	u16 chan_val, chan_mask;

	/* No support for SDP and LBK */
	if (intf_type != NIX_INTF_TYPE_CGX)
		return false;

	chan_val = rvu_nix_chan_cgx(rvu, cgx_id, lmac_id, 0);
	chan_mask = 0xfff;

	if (val)
		*val = chan_val;

	if (mask)
		*mask = chan_mask;

	return true;
}

/**
 *	rvu_npc_exact_drop_rule_to_pcifunc - Retrieve pcifunc
 *      @rvu: resource virtualization unit.
 *	@drop_rule_idx: Drop rule index in NPC mcam.
 *
 *	Debugfs (exact_drop_cnt) entry displays pcifunc for interface
 *	by retrieving the pcifunc value from data base.
 *	Return: Drop rule index.
 */
u16 rvu_npc_exact_drop_rule_to_pcifunc(struct rvu *rvu, u32 drop_rule_idx)
{
	struct npc_exact_table *table;
	int i;

	table = rvu->hw->table;

	for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
		if (!table->drop_rule_map[i].valid)
			break;

		if (table->drop_rule_map[i].drop_rule_idx != drop_rule_idx)
			continue;

		return table->drop_rule_map[i].pcifunc;
	}

	dev_err(rvu->dev, "%s: drop mcam rule index (%d) >= NPC_MCAM_DROP_RULE_MAX\n",
		__func__, drop_rule_idx);
	return -1;
}

/**
 *	rvu_npc_exact_get_drop_rule_info - Get drop rule information.
 *      @rvu: resource virtualization unit.
 *	@intf_type: Interface type (CGX, SDP or LBK)
 *	@cgx_id: CGX identifier.
 *	@lmac_id: LMAC identifier.
 *	@drop_mcam_idx: NPC mcam drop rule index.
 *	@val: Channel value.
 *	@mask: Channel mask.
 *	@pcifunc: pcifunc of interface corresponding to the drop rule.
 *	Return: True upon success.
 */
static bool rvu_npc_exact_get_drop_rule_info(struct rvu *rvu, u8 intf_type, u8 cgx_id,
					     u8 lmac_id, u32 *drop_mcam_idx, u64 *val,
					     u64 *mask, u16 *pcifunc)
{
	struct npc_exact_table *table;
	u64 chan_val, chan_mask;
	bool rc;
	int i;

	table = rvu->hw->table;

	if (intf_type != NIX_INTF_TYPE_CGX) {
		dev_err(rvu->dev, "%s: No drop rule for LBK/SDP mode\n", __func__);
		return false;
	}

	rc = rvu_npc_exact_calc_drop_rule_chan_and_mask(rvu, intf_type, cgx_id,
							lmac_id, &chan_val, &chan_mask);
	if (!rc)
		return false;

	for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
		if (!table->drop_rule_map[i].valid)
			break;

		if (table->drop_rule_map[i].chan_val != (u16)chan_val)
			continue;

		if (val)
			*val = table->drop_rule_map[i].chan_val;
		if (mask)
			*mask = table->drop_rule_map[i].chan_mask;
		if (pcifunc)
			*pcifunc = table->drop_rule_map[i].pcifunc;

		*drop_mcam_idx = i;
		return true;
	}

	if (i == NPC_MCAM_DROP_RULE_MAX) {
		dev_err(rvu->dev, "%s: drop mcam rule index (%d) >= NPC_MCAM_DROP_RULE_MAX\n",
			__func__, *drop_mcam_idx);
		return false;
	}

	dev_err(rvu->dev, "%s: Could not retrieve for cgx=%d, lmac=%d\n",
		__func__, cgx_id, lmac_id);
	return false;
}

/**
 *	__rvu_npc_exact_cmd_rules_cnt_update - Update number dmac rules against a drop rule.
 *      @rvu: resource virtualization unit.
 *	@drop_mcam_idx: NPC mcam drop rule index.
 *	@val: +1 or -1.
 *	@enable_or_disable_cam: If no exact match rules against a drop rule, disable it.
 *
 *	when first exact match entry against a drop rule is added, enable_or_disable_cam
 *	is set to true. When last exact match entry against a drop rule is deleted,
 *	enable_or_disable_cam is set to true.
 *	Return: Number of rules
 */
static u16 __rvu_npc_exact_cmd_rules_cnt_update(struct rvu *rvu, int drop_mcam_idx,
						int val, bool *enable_or_disable_cam)
{
	struct npc_exact_table *table;
	u16 *cnt, old_cnt;
	bool promisc;

	table = rvu->hw->table;
	promisc = table->promisc_mode[drop_mcam_idx];

	cnt = &table->cnt_cmd_rules[drop_mcam_idx];
	old_cnt = *cnt;

	*cnt += val;

	if (!enable_or_disable_cam)
		goto done;

	*enable_or_disable_cam = false;

	if (promisc)
		goto done;

	/* If all rules are deleted and not already in promisc mode;
	 * disable cam
	 */
	if (!*cnt && val < 0) {
		*enable_or_disable_cam = true;
		goto done;
	}

	/* If rule got added and not already in promisc mode; enable cam */
	if (!old_cnt && val > 0) {
		*enable_or_disable_cam = true;
		goto done;
	}

done:
	return *cnt;
}

/**
 *      rvu_npc_exact_del_table_entry_by_id - Delete and free table entry.
 *      @rvu: resource virtualization unit.
 *	@seq_id: Sequence identifier of the entry.
 *
 *	Deletes entry from linked lists and free up slot in HW MEM or CAM
 *	table.
 *	Return: 0 upon success.
 */
static int rvu_npc_exact_del_table_entry_by_id(struct rvu *rvu, u32 seq_id)
{
	struct npc_exact_table_entry *entry = NULL;
	struct npc_exact_table *table;
	bool disable_cam = false;
	u32 drop_mcam_idx = -1;
	int *cnt;
	bool rc;

	table = rvu->hw->table;

	mutex_lock(&table->lock);

	/* Lookup for entry which needs to be updated */
	entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, seq_id);
	if (!entry) {
		dev_dbg(rvu->dev, "%s: failed to find entry for id=%d\n", __func__, seq_id);
		mutex_unlock(&table->lock);
		return -ENODATA;
	}

	cnt = (entry->opc_type == NPC_EXACT_OPC_CAM) ? &table->cam_tbl_entry_cnt :
				&table->mem_tbl_entry_cnt;

	/* delete from lists */
	list_del_init(&entry->list);
	list_del_init(&entry->glist);

	(*cnt)--;

	rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, entry->cgx_id,
					      entry->lmac_id, &drop_mcam_idx, NULL, NULL, NULL);
	if (!rc) {
		dev_dbg(rvu->dev, "%s: failed to retrieve drop info for id=0x%x\n",
			__func__, seq_id);
		mutex_unlock(&table->lock);
		return -ENODATA;
	}

	if (entry->cmd)
		__rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, -1, &disable_cam);

	/* No dmac filter rules; disable drop on hit rule */
	if (disable_cam) {
		rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, false);
		dev_dbg(rvu->dev, "%s: Disabling mcam idx %d\n",
			__func__, drop_mcam_idx);
	}

	mutex_unlock(&table->lock);

	rvu_npc_exact_dealloc_table_entry(rvu, entry->opc_type, entry->ways, entry->index);

	rvu_npc_exact_free_id(rvu, seq_id);

	dev_dbg(rvu->dev, "%s: delete entry success for id=0x%x, mca=%pM\n",
		__func__, seq_id, entry->mac);
	kfree(entry);

	return 0;
}

/**
 *      rvu_npc_exact_add_table_entry - Adds a table entry
 *      @rvu: resource virtualization unit.
 *	@cgx_id: cgx identifier.
 *	@lmac_id: lmac identifier.
 *	@mac: MAC address.
 *	@chan: Channel number.
 *	@ctype: Channel Type.
 *	@seq_id: Sequence number.
 *	@cmd: Whether it is invoked by ethtool cmd.
 *	@mcam_idx: NPC mcam index corresponding to MAC
 *	@pcifunc: PCI func.
 *
 *	Creates a new exact match table entry in either CAM or
 *	MEM table.
 *	Return: 0 upon success.
 */
static int rvu_npc_exact_add_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id, u8 *mac,
					 u16 chan, u8 ctype, u32 *seq_id, bool cmd,
					 u32 mcam_idx, u16 pcifunc)
{
	int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
	enum npc_exact_opc_type opc_type;
	bool enable_cam = false;
	u32 drop_mcam_idx;
	u32 index;
	u64 mdata;
	bool rc;
	int err;
	u8 ways;

	ctype = 0;

	err = rvu_npc_exact_alloc_table_entry(rvu, mac, chan, ctype, &index, &ways, &opc_type);
	if (err) {
		dev_err(rvu->dev, "%s: Could not alloc in exact match table\n", __func__);
		return err;
	}

	/* Write mdata to table */
	mdata = rvu_exact_prepare_table_entry(rvu, true, ctype, chan, mac);

	if (opc_type == NPC_EXACT_OPC_CAM)
		rvu_npc_exact_cam_table_write(rvu, blkaddr, index, mdata);
	else
		rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index,  mdata);

	/* Insert entry to linked list */
	err = rvu_npc_exact_add_to_list(rvu, opc_type, ways, index, cgx_id, lmac_id,
					mac, chan, ctype, seq_id, cmd, mcam_idx, pcifunc);
	if (err) {
		rvu_npc_exact_dealloc_table_entry(rvu, opc_type, ways, index);
		dev_err(rvu->dev, "%s: could not add to exact match table\n", __func__);
		return err;
	}

	rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
					      &drop_mcam_idx, NULL, NULL, NULL);
	if (!rc) {
		rvu_npc_exact_dealloc_table_entry(rvu, opc_type, ways, index);
		dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
			__func__, cgx_id, lmac_id);
		return -EINVAL;
	}

	if (cmd)
		__rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, 1, &enable_cam);

	/* First command rule; enable drop on hit rule */
	if (enable_cam) {
		rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, true);
		dev_dbg(rvu->dev, "%s: Enabling mcam idx %d\n",
			__func__, drop_mcam_idx);
	}

	dev_dbg(rvu->dev,
		"%s: Successfully added entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
		__func__, index, mac, ways, opc_type);

	return 0;
}

/**
 *      rvu_npc_exact_update_table_entry - Update exact match table.
 *      @rvu: resource virtualization unit.
 *	@cgx_id: CGX identifier.
 *	@lmac_id: LMAC identifier.
 *	@old_mac: Existing MAC address entry.
 *	@new_mac: New MAC address entry.
 *	@seq_id: Sequence identifier of the entry.
 *
 *	Updates MAC address of an entry. If entry is in MEM table, new
 *	hash value may not match with old one.
 *	Return: 0 upon success.
 */
static int rvu_npc_exact_update_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id,
					    u8 *old_mac, u8 *new_mac, u32 *seq_id)
{
	int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
	struct npc_exact_table_entry *entry;
	struct npc_exact_table *table;
	u32 hash_index;
	u64 mdata;

	table = rvu->hw->table;

	mutex_lock(&table->lock);

	/* Lookup for entry which needs to be updated */
	entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, *seq_id);
	if (!entry) {
		mutex_unlock(&table->lock);
		dev_dbg(rvu->dev,
			"%s: failed to find entry for cgx_id=%d lmac_id=%d old_mac=%pM\n",
			__func__, cgx_id, lmac_id, old_mac);
		return -ENODATA;
	}

	/* If entry is in mem table and new hash index is different than old
	 * hash index, we cannot update the entry. Fail in these scenarios.
	 */
	if (entry->opc_type == NPC_EXACT_OPC_MEM) {
		hash_index =  rvu_exact_calculate_hash(rvu, entry->chan, entry->ctype,
						       new_mac, table->mem_table.mask,
						       table->mem_table.depth);
		if (hash_index != entry->index) {
			dev_dbg(rvu->dev,
				"%s: Update failed due to index mismatch(new=0x%x, old=%x)\n",
				__func__, hash_index, entry->index);
			mutex_unlock(&table->lock);
			return -EINVAL;
		}
	}

	mdata = rvu_exact_prepare_table_entry(rvu, true, entry->ctype, entry->chan, new_mac);

	if (entry->opc_type == NPC_EXACT_OPC_MEM)
		rvu_npc_exact_mem_table_write(rvu, blkaddr, entry->ways, entry->index, mdata);
	else
		rvu_npc_exact_cam_table_write(rvu, blkaddr, entry->index, mdata);

	/* Update entry fields */
	ether_addr_copy(entry->mac, new_mac);
	*seq_id = entry->seq_id;

	dev_dbg(rvu->dev,
		"%s: Successfully updated entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
		__func__, entry->index, entry->mac, entry->ways, entry->opc_type);

	dev_dbg(rvu->dev, "%s: Successfully updated entry (old mac=%pM new_mac=%pM\n",
		__func__, old_mac, new_mac);

	mutex_unlock(&table->lock);
	return 0;
}

/**
 *	rvu_npc_exact_promisc_disable - Disable promiscuous mode.
 *      @rvu: resource virtualization unit.
 *	@pcifunc: pcifunc
 *
 *	Drop rule is against each PF. We dont support DMAC filter for
 *	VF.
 *	Return: 0 upon success
 */

int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
{
	struct npc_exact_table *table;
	int pf = rvu_get_pf(pcifunc);
	u8 cgx_id, lmac_id;
	u32 drop_mcam_idx;
	bool *promisc;
	bool rc;

	table = rvu->hw->table;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
					      &drop_mcam_idx, NULL, NULL, NULL);
	if (!rc) {
		dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
			__func__, cgx_id, lmac_id);
		return -EINVAL;
	}

	mutex_lock(&table->lock);
	promisc = &table->promisc_mode[drop_mcam_idx];

	if (!*promisc) {
		mutex_unlock(&table->lock);
		dev_dbg(rvu->dev, "%s: Err Already promisc mode disabled (cgx=%d lmac=%d)\n",
			__func__, cgx_id, lmac_id);
		return LMAC_AF_ERR_INVALID_PARAM;
	}
	*promisc = false;
	mutex_unlock(&table->lock);

	/* Enable drop rule */
	rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX,
					   true);

	dev_dbg(rvu->dev, "%s: disabled  promisc mode (cgx=%d lmac=%d)\n",
		__func__, cgx_id, lmac_id);
	return 0;
}

/**
 *	rvu_npc_exact_promisc_enable - Enable promiscuous mode.
 *      @rvu: resource virtualization unit.
 *	@pcifunc: pcifunc.
 *	Return: 0 upon success
 */
int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
{
	struct npc_exact_table *table;
	int pf = rvu_get_pf(pcifunc);
	u8 cgx_id, lmac_id;
	u32 drop_mcam_idx;
	bool *promisc;
	bool rc;

	table = rvu->hw->table;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
					      &drop_mcam_idx, NULL, NULL, NULL);
	if (!rc) {
		dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
			__func__, cgx_id, lmac_id);
		return -EINVAL;
	}

	mutex_lock(&table->lock);
	promisc = &table->promisc_mode[drop_mcam_idx];

	if (*promisc) {
		mutex_unlock(&table->lock);
		dev_dbg(rvu->dev, "%s: Already in promisc mode (cgx=%d lmac=%d)\n",
			__func__, cgx_id, lmac_id);
		return LMAC_AF_ERR_INVALID_PARAM;
	}
	*promisc = true;
	mutex_unlock(&table->lock);

	/*  disable drop rule */
	rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX,
					   false);

	dev_dbg(rvu->dev, "%s: Enabled promisc mode (cgx=%d lmac=%d)\n",
		__func__, cgx_id, lmac_id);
	return 0;
}

/**
 *	rvu_npc_exact_mac_addr_reset - Delete PF mac address.
 *      @rvu: resource virtualization unit.
 *	@req: Reset request
 *	@rsp: Reset response.
 *	Return: 0 upon success
 */
int rvu_npc_exact_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
				 struct msg_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u32 seq_id = req->index;
	struct rvu_pfvf *pfvf;
	u8 cgx_id, lmac_id;
	int rc;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);

	rc = rvu_npc_exact_del_table_entry_by_id(rvu, seq_id);
	if (rc) {
		/* TODO: how to handle this error case ? */
		dev_err(rvu->dev, "%s MAC (%pM) del PF=%d failed\n", __func__, pfvf->mac_addr, pf);
		return 0;
	}

	dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d success (seq_id=%u)\n",
		__func__, pfvf->mac_addr, pf, seq_id);
	return 0;
}

/**
 *	rvu_npc_exact_mac_addr_update - Update mac address field with new value.
 *      @rvu: resource virtualization unit.
 *	@req: Update request.
 *	@rsp: Update response.
 *	Return: 0 upon success
 */
int rvu_npc_exact_mac_addr_update(struct rvu *rvu,
				  struct cgx_mac_addr_update_req *req,
				  struct cgx_mac_addr_update_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	struct npc_exact_table_entry *entry;
	struct npc_exact_table *table;
	struct rvu_pfvf *pfvf;
	u32 seq_id, mcam_idx;
	u8 old_mac[ETH_ALEN];
	u8 cgx_id, lmac_id;
	int rc;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return LMAC_AF_ERR_PERM_DENIED;

	dev_dbg(rvu->dev, "%s: Update request for seq_id=%d, mac=%pM\n",
		__func__, req->index, req->mac_addr);

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);

	table = rvu->hw->table;

	mutex_lock(&table->lock);

	/* Lookup for entry which needs to be updated */
	entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, req->index);
	if (!entry) {
		dev_err(rvu->dev, "%s: failed to find entry for id=0x%x\n", __func__, req->index);
		mutex_unlock(&table->lock);
		return LMAC_AF_ERR_EXACT_MATCH_TBL_LOOK_UP_FAILED;
	}
	ether_addr_copy(old_mac, entry->mac);
	seq_id = entry->seq_id;
	mcam_idx = entry->mcam_idx;
	mutex_unlock(&table->lock);

	rc = rvu_npc_exact_update_table_entry(rvu, cgx_id, lmac_id,  old_mac,
					      req->mac_addr, &seq_id);
	if (!rc) {
		rsp->index = seq_id;
		dev_dbg(rvu->dev, "%s  mac:%pM (pfvf:%pM default:%pM) update to PF=%d success\n",
			__func__, req->mac_addr, pfvf->mac_addr, pfvf->default_mac, pf);
		ether_addr_copy(pfvf->mac_addr, req->mac_addr);
		return 0;
	}

	/* Try deleting and adding it again */
	rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
	if (rc) {
		/* This could be a new entry */
		dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d failed\n", __func__,
			pfvf->mac_addr, pf);
	}

	rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
					   pfvf->rx_chan_base, 0, &seq_id, true,
					   mcam_idx, req->hdr.pcifunc);
	if (rc) {
		dev_err(rvu->dev, "%s MAC (%pM) add PF=%d failed\n", __func__,
			req->mac_addr, pf);
		return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
	}

	rsp->index = seq_id;
	dev_dbg(rvu->dev,
		"%s MAC (new:%pM, old=%pM default:%pM) del and add to PF=%d success (seq_id=%u)\n",
		__func__, req->mac_addr, pfvf->mac_addr, pfvf->default_mac, pf, seq_id);

	ether_addr_copy(pfvf->mac_addr, req->mac_addr);
	return 0;
}

/**
 *	rvu_npc_exact_mac_addr_add - Adds MAC address to exact match table.
 *      @rvu: resource virtualization unit.
 *	@req: Add request.
 *	@rsp: Add response.
 *	Return: 0 upon success
 */
int rvu_npc_exact_mac_addr_add(struct rvu *rvu,
			       struct cgx_mac_addr_add_req *req,
			       struct cgx_mac_addr_add_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	struct rvu_pfvf *pfvf;
	u8 cgx_id, lmac_id;
	int rc = 0;
	u32 seq_id;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);

	rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
					   pfvf->rx_chan_base, 0, &seq_id,
					   true, -1, req->hdr.pcifunc);

	if (!rc) {
		rsp->index = seq_id;
		dev_dbg(rvu->dev, "%s MAC (%pM) add to PF=%d success (seq_id=%u)\n",
			__func__, req->mac_addr, pf, seq_id);
		return 0;
	}

	dev_err(rvu->dev, "%s MAC (%pM) add to PF=%d failed\n", __func__,
		req->mac_addr, pf);
	return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
}

/**
 *	rvu_npc_exact_mac_addr_del - Delete DMAC filter
 *      @rvu: resource virtualization unit.
 *	@req: Delete request.
 *	@rsp: Delete response.
 *	Return: 0 upon success
 */
int rvu_npc_exact_mac_addr_del(struct rvu *rvu,
			       struct cgx_mac_addr_del_req *req,
			       struct msg_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	int rc;

	rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
	if (!rc) {
		dev_dbg(rvu->dev, "%s del to PF=%d success (seq_id=%u)\n",
			__func__, pf, req->index);
		return 0;
	}

	dev_err(rvu->dev, "%s del to PF=%d failed (seq_id=%u)\n",
		__func__,  pf, req->index);
	return LMAC_AF_ERR_EXACT_MATCH_TBL_DEL_FAILED;
}

/**
 *	rvu_npc_exact_mac_addr_set - Add PF mac address to dmac filter.
 *      @rvu: resource virtualization unit.
 *	@req: Set request.
 *	@rsp: Set response.
 *	Return: 0 upon success
 */
int rvu_npc_exact_mac_addr_set(struct rvu *rvu, struct cgx_mac_addr_set_or_get *req,
			       struct cgx_mac_addr_set_or_get *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u32 seq_id = req->index;
	struct rvu_pfvf *pfvf;
	u8 cgx_id, lmac_id;
	u32 mcam_idx = -1;
	int rc, nixlf;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	pfvf = &rvu->pf[pf];

	/* If table does not have an entry; both update entry and del table entry API
	 * below fails. Those are not failure conditions.
	 */
	rc = rvu_npc_exact_update_table_entry(rvu, cgx_id, lmac_id, pfvf->mac_addr,
					      req->mac_addr, &seq_id);
	if (!rc) {
		rsp->index = seq_id;
		ether_addr_copy(pfvf->mac_addr, req->mac_addr);
		ether_addr_copy(rsp->mac_addr, req->mac_addr);
		dev_dbg(rvu->dev, "%s MAC (%pM) update to PF=%d success\n",
			__func__, req->mac_addr, pf);
		return 0;
	}

	/* Try deleting and adding it again */
	rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
	if (rc) {
		dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d failed\n",
			__func__, pfvf->mac_addr, pf);
	}

	/* find mcam entry if exist */
	rc = nix_get_nixlf(rvu, req->hdr.pcifunc, &nixlf, NULL);
	if (!rc) {
		mcam_idx = npc_get_nixlf_mcam_index(&rvu->hw->mcam, req->hdr.pcifunc,
						    nixlf, NIXLF_UCAST_ENTRY);
	}

	rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
					   pfvf->rx_chan_base, 0, &seq_id,
					   true, mcam_idx, req->hdr.pcifunc);
	if (rc) {
		dev_err(rvu->dev, "%s MAC (%pM) add PF=%d failed\n",
			__func__, req->mac_addr, pf);
		return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
	}

	rsp->index = seq_id;
	ether_addr_copy(rsp->mac_addr, req->mac_addr);
	ether_addr_copy(pfvf->mac_addr, req->mac_addr);
	dev_dbg(rvu->dev,
		"%s MAC (%pM) del and add to PF=%d success (seq_id=%u)\n",
		__func__, req->mac_addr, pf, seq_id);
	return 0;
}

/**
 *	rvu_npc_exact_can_disable_feature - Check if feature can be disabled.
 *      @rvu: resource virtualization unit.
 *	Return: True if exact match feature is supported.
 */
bool rvu_npc_exact_can_disable_feature(struct rvu *rvu)
{
	struct npc_exact_table *table = rvu->hw->table;
	bool empty;

	if (!rvu->hw->cap.npc_exact_match_enabled)
		return false;

	mutex_lock(&table->lock);
	empty = list_empty(&table->lhead_gbl);
	mutex_unlock(&table->lock);

	return empty;
}

/**
 *	rvu_npc_exact_disable_feature - Disable feature.
 *      @rvu: resource virtualization unit.
 */
void rvu_npc_exact_disable_feature(struct rvu *rvu)
{
	rvu->hw->cap.npc_exact_match_enabled = false;
}

/**
 *	rvu_npc_exact_reset - Delete and free all entry which match pcifunc.
 *      @rvu: resource virtualization unit.
 *	@pcifunc: PCI func to match.
 */
void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc)
{
	struct npc_exact_table *table = rvu->hw->table;
	struct npc_exact_table_entry *tmp, *iter;
	u32 seq_id;

	mutex_lock(&table->lock);
	list_for_each_entry_safe(iter, tmp, &table->lhead_gbl, glist) {
		if (pcifunc != iter->pcifunc)
			continue;

		seq_id = iter->seq_id;
		dev_dbg(rvu->dev, "%s: resetting pcifun=%d seq_id=%u\n", __func__,
			pcifunc, seq_id);

		mutex_unlock(&table->lock);
		rvu_npc_exact_del_table_entry_by_id(rvu, seq_id);
		mutex_lock(&table->lock);
	}
	mutex_unlock(&table->lock);
}

/**
 *      rvu_npc_exact_init - initialize exact match table
 *      @rvu: resource virtualization unit.
 *
 *	Initialize HW and SW resources to manage 4way-2K table and fully
 *	associative 32-entry mcam table.
 *	Return: 0 upon success.
 */
int rvu_npc_exact_init(struct rvu *rvu)
{
	u64 bcast_mcast_val, bcast_mcast_mask;
	struct npc_exact_table *table;
	u64 exact_val, exact_mask;
	u64 chan_val, chan_mask;
	u8 cgx_id, lmac_id;
	u32 *drop_mcam_idx;
	u16 max_lmac_cnt;
	u64 npc_const3;
	int table_size;
	int blkaddr;
	u16 pcifunc;
	int err, i;
	u64 cfg;
	bool rc;

	/* Read NPC_AF_CONST3 and check for have exact
	 * match functionality is present
	 */
	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
	if (blkaddr < 0) {
		dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
		return -EINVAL;
	}

	/* Check exact match feature is supported */
	npc_const3 = rvu_read64(rvu, blkaddr, NPC_AF_CONST3);
	if (!(npc_const3 & BIT_ULL(62)))
		return 0;

	/* Check if kex profile has enabled EXACT match nibble */
	cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX));
	if (!(cfg & NPC_EXACT_NIBBLE_HIT))
		return 0;

	/* Set capability to true */
	rvu->hw->cap.npc_exact_match_enabled = true;

	table = kzalloc(sizeof(*table), GFP_KERNEL);
	if (!table)
		return -ENOMEM;

	dev_dbg(rvu->dev, "%s: Memory allocation for table success\n", __func__);
	rvu->hw->table = table;

	/* Read table size, ways and depth */
	table->mem_table.ways = FIELD_GET(GENMASK_ULL(19, 16), npc_const3);
	table->mem_table.depth = FIELD_GET(GENMASK_ULL(15, 0), npc_const3);
	table->cam_table.depth = FIELD_GET(GENMASK_ULL(31, 24), npc_const3);

	dev_dbg(rvu->dev, "%s: NPC exact match 4way_2k table(ways=%d, depth=%d)\n",
		__func__,  table->mem_table.ways, table->cam_table.depth);

	/* Check if depth of table is not a sequre of 2
	 * TODO: why _builtin_popcount() is not working ?
	 */
	if ((table->mem_table.depth & (table->mem_table.depth - 1)) != 0) {
		dev_err(rvu->dev,
			"%s: NPC exact match 4way_2k table depth(%d) is not square of 2\n",
			__func__,  table->mem_table.depth);
		return -EINVAL;
	}

	table_size = table->mem_table.depth * table->mem_table.ways;

	/* Allocate bitmap for 4way 2K table */
	table->mem_table.bmap = devm_bitmap_zalloc(rvu->dev, table_size,
						   GFP_KERNEL);
	if (!table->mem_table.bmap)
		return -ENOMEM;

	dev_dbg(rvu->dev, "%s: Allocated bitmap for 4way 2K entry table\n", __func__);

	/* Allocate bitmap for 32 entry mcam */
	table->cam_table.bmap = devm_bitmap_zalloc(rvu->dev, 32, GFP_KERNEL);

	if (!table->cam_table.bmap)
		return -ENOMEM;

	dev_dbg(rvu->dev, "%s: Allocated bitmap for 32 entry cam\n", __func__);

	table->tot_ids = table_size + table->cam_table.depth;
	table->id_bmap = devm_bitmap_zalloc(rvu->dev, table->tot_ids,
					    GFP_KERNEL);

	if (!table->id_bmap)
		return -ENOMEM;

	dev_dbg(rvu->dev, "%s: Allocated bitmap for id map (total=%d)\n",
		__func__, table->tot_ids);

	/* Initialize list heads for npc_exact_table entries.
	 * This entry is used by debugfs to show entries in
	 * exact match table.
	 */
	for (i = 0; i < NPC_EXACT_TBL_MAX_WAYS; i++)
		INIT_LIST_HEAD(&table->lhead_mem_tbl_entry[i]);

	INIT_LIST_HEAD(&table->lhead_cam_tbl_entry);
	INIT_LIST_HEAD(&table->lhead_gbl);

	mutex_init(&table->lock);

	rvu_exact_config_secret_key(rvu);
	rvu_exact_config_search_key(rvu);

	rvu_exact_config_table_mask(rvu);
	rvu_exact_config_result_ctrl(rvu, table->mem_table.depth);

	/* - No drop rule for LBK
	 * - Drop rules for SDP and each LMAC.
	 */
	exact_val = !NPC_EXACT_RESULT_HIT;
	exact_mask = NPC_EXACT_RESULT_HIT;

	/* nibble - 3	2  1   0
	 *	   L3B L3M L2B L2M
	 */
	bcast_mcast_val = 0b0000;
	bcast_mcast_mask = 0b0011;

	/* Install SDP drop rule */
	drop_mcam_idx = &table->num_drop_rules;

	max_lmac_cnt = rvu->cgx_cnt_max * rvu->hw->lmac_per_cgx +
		       PF_CGXMAP_BASE;

	for (i = PF_CGXMAP_BASE; i < max_lmac_cnt; i++) {
		if (rvu->pf2cgxlmac_map[i] == 0xFF)
			continue;

		rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[i], &cgx_id, &lmac_id);

		rc = rvu_npc_exact_calc_drop_rule_chan_and_mask(rvu, NIX_INTF_TYPE_CGX, cgx_id,
								lmac_id, &chan_val, &chan_mask);
		if (!rc) {
			dev_err(rvu->dev,
				"%s: failed, info chan_val=0x%llx chan_mask=0x%llx rule_id=%d\n",
				__func__, chan_val, chan_mask, *drop_mcam_idx);
			return -EINVAL;
		}

		/* Filter rules are only for PF */
		pcifunc = RVU_PFFUNC(i, 0);

		dev_dbg(rvu->dev,
			"%s:Drop rule cgx=%d lmac=%d chan(val=0x%llx, mask=0x%llx\n",
			__func__, cgx_id, lmac_id, chan_val, chan_mask);

		rc = rvu_npc_exact_save_drop_rule_chan_and_mask(rvu, table->num_drop_rules,
								chan_val, chan_mask, pcifunc);
		if (!rc) {
			dev_err(rvu->dev,
				"%s: failed to set drop info for cgx=%d, lmac=%d, chan=%llx\n",
				__func__, cgx_id, lmac_id, chan_val);
			return -EINVAL;
		}

		err = npc_install_mcam_drop_rule(rvu, *drop_mcam_idx,
						 &table->counter_idx[*drop_mcam_idx],
						 chan_val, chan_mask,
						 exact_val, exact_mask,
						 bcast_mcast_val, bcast_mcast_mask);
		if (err) {
			dev_err(rvu->dev,
				"failed to configure drop rule (cgx=%d lmac=%d)\n",
				cgx_id, lmac_id);
			return err;
		}

		(*drop_mcam_idx)++;
	}

	dev_info(rvu->dev, "initialized exact match table successfully\n");
	return 0;
}
