Commit bb91f754 authored by Hariprasad Kelam's avatar Hariprasad Kelam Committed by David S. Miller
Browse files

octeontx2-af: NPC: Clear Unicast rule on nixlf detach



The AF driver assigns reserved MCAM entries (for unicast, broadcast,
etc.) based on the NIXLF number. When a NIXLF is detached, these entries
are disabled.

For example,

         PF           NIXLF
        --------------------
         PF0             0
         SDP-VF0         1

If the user unbinds both PF0 and SDP-VF0 interfaces and then binds them in
reverse order

         PF            NIXLF
        ---------------------
         SDP-VF0         0
         PF0             1

In this scenario, the PF0 unicast entry is getting corrupted because
the MCAM entry contains stale data (SDP-VF0 ucast data)

This patch resolves the issue by clearing the unicast MCAM entry during
NIXLF detach

Signed-off-by: default avatarHariprasad Kelam <hkelam@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 819aad96
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1393,8 +1393,6 @@ static void rvu_detach_block(struct rvu *rvu, int pcifunc, int blktype)
	if (blkaddr < 0)
		return;

	if (blktype == BLKTYPE_NIX)
		rvu_nix_reset_mac(pfvf, pcifunc);

	block = &hw->block[blkaddr];

@@ -1407,6 +1405,10 @@ static void rvu_detach_block(struct rvu *rvu, int pcifunc, int blktype)
		if (lf < 0) /* This should never happen */
			continue;

		if (blktype == BLKTYPE_NIX) {
			rvu_nix_reset_mac(pfvf, pcifunc);
			rvu_npc_clear_ucast_entry(rvu, pcifunc, lf);
		}
		/* Disable the LF */
		rvu_write64(rvu, blkaddr, block->lfcfg_reg |
			    (lf << block->lfshift), 0x00ULL);
+2 −0
Original line number Diff line number Diff line
@@ -994,6 +994,8 @@ void rvu_npc_get_mcam_entry_alloc_info(struct rvu *rvu, u16 pcifunc,
void rvu_npc_get_mcam_counter_alloc_info(struct rvu *rvu, u16 pcifunc,
					 int blkaddr, int *alloc_cnt,
					 int *enable_cnt);
void rvu_npc_clear_ucast_entry(struct rvu *rvu, int pcifunc, int nixlf);

bool is_npc_intf_tx(u8 intf);
bool is_npc_intf_rx(u8 intf);
bool is_npc_interface_valid(struct rvu *rvu, u8 intf);
+37 −3
Original line number Diff line number Diff line
@@ -1107,6 +1107,7 @@ void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
				       int nixlf, bool enable)
{
	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
	struct npc_mcam *mcam = &rvu->hw->mcam;
	int index, blkaddr;

@@ -1115,9 +1116,12 @@ static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
		return;

	/* Ucast MCAM match entry of this PF/VF */
	if (npc_is_feature_supported(rvu, BIT_ULL(NPC_DMAC),
				     pfvf->nix_rx_intf)) {
		index = npc_get_nixlf_mcam_index(mcam, pcifunc,
						 nixlf, NIXLF_UCAST_ENTRY);
		npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
	}

	/* Nothing to do for VFs, on platforms where pkt replication
	 * is not supported
@@ -3570,3 +3574,33 @@ int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu *rvu,

	return 0;
}

void rvu_npc_clear_ucast_entry(struct rvu *rvu, int pcifunc, int nixlf)
{
	struct npc_mcam *mcam = &rvu->hw->mcam;
	struct rvu_npc_mcam_rule *rule;
	int ucast_idx, blkaddr;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
	if (blkaddr < 0)
		return;

	ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc,
					     nixlf, NIXLF_UCAST_ENTRY);

	npc_enable_mcam_entry(rvu, mcam, blkaddr, ucast_idx, false);

	npc_set_mcam_action(rvu, mcam, blkaddr, ucast_idx, 0);

	npc_clear_mcam_entry(rvu, mcam, blkaddr, ucast_idx);

	mutex_lock(&mcam->lock);
	list_for_each_entry(rule, &mcam->mcam_rules, list) {
		if (rule->entry == ucast_idx) {
			list_del(&rule->list);
			kfree(rule);
			break;
		}
	}
	mutex_unlock(&mcam->lock);
}