Commit 041a1c17 authored by Subbaraya Sundeep's avatar Subbaraya Sundeep Committed by Jakub Kicinski

octeontx2-af: Verify MCAM entry channel and PF_FUNC

This patch adds support to verify the channel number sent by
mailbox requester before writing MCAM entry for Ingress packets.
Similarly for Egress packets, verifying the PF_FUNC sent by the
mailbox user.
Signed-off-by: default avatarSubbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: default avatarKiran Kumar K <kirankumark@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarNaveen Mamindlapalli <naveenm@marvell.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f1517f6f
......@@ -2642,7 +2642,7 @@ static void rvu_enable_afvf_intr(struct rvu *rvu)
#define PCI_DEVID_OCTEONTX2_LBK 0xA061
static int lbk_get_num_chans(void)
int rvu_get_num_lbk_chans(void)
{
struct pci_dev *pdev;
void __iomem *base;
......@@ -2677,7 +2677,7 @@ static int rvu_enable_sriov(struct rvu *rvu)
return 0;
}
chans = lbk_get_num_chans();
chans = rvu_get_num_lbk_chans();
if (chans < 0)
return chans;
......
......@@ -445,6 +445,7 @@ int rvu_get_lf(struct rvu *rvu, struct rvu_block *block, u16 pcifunc, u16 slot);
int rvu_lf_reset(struct rvu *rvu, struct rvu_block *block, int lf);
int rvu_get_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc);
int rvu_poll_reg(struct rvu *rvu, u64 block, u64 offset, u64 mask, bool zero);
int rvu_get_num_lbk_chans(void);
/* RVU HW reg validation */
enum regmap_block {
......@@ -535,6 +536,7 @@ bool is_npc_intf_tx(u8 intf);
bool is_npc_intf_rx(u8 intf);
bool is_npc_interface_valid(struct rvu *rvu, u8 intf);
int rvu_npc_get_tx_nibble_cfg(struct rvu *rvu, u64 nibble_ena);
int npc_mcam_verify_channel(struct rvu *rvu, u16 pcifunc, u8 intf, u16 channel);
#ifdef CONFIG_DEBUG_FS
void rvu_dbg_init(struct rvu *rvu);
......
......@@ -28,6 +28,8 @@
#define NPC_PARSE_RESULT_DMAC_OFFSET 8
#define NPC_HW_TSTAMP_OFFSET 8
#define NPC_KEX_CHAN_MASK 0xFFFULL
#define NPC_KEX_PF_FUNC_MASK 0xFFFFULL
static const char def_pfl_name[] = "default";
......@@ -63,6 +65,54 @@ int rvu_npc_get_tx_nibble_cfg(struct rvu *rvu, u64 nibble_ena)
return 0;
}
static int npc_mcam_verify_pf_func(struct rvu *rvu,
struct mcam_entry *entry_data, u8 intf,
u16 pcifunc)
{
u16 pf_func, pf_func_mask;
if (is_npc_intf_rx(intf))
return 0;
pf_func_mask = (entry_data->kw_mask[0] >> 32) &
NPC_KEX_PF_FUNC_MASK;
pf_func = (entry_data->kw[0] >> 32) & NPC_KEX_PF_FUNC_MASK;
pf_func = be16_to_cpu((__force __be16)pf_func);
if (pf_func_mask != NPC_KEX_PF_FUNC_MASK ||
((pf_func & ~RVU_PFVF_FUNC_MASK) !=
(pcifunc & ~RVU_PFVF_FUNC_MASK)))
return -EINVAL;
return 0;
}
int npc_mcam_verify_channel(struct rvu *rvu, u16 pcifunc, u8 intf, u16 channel)
{
int pf = rvu_get_pf(pcifunc);
u8 cgx_id, lmac_id;
int base = 0, end;
if (is_npc_intf_tx(intf))
return 0;
if (is_afvf(pcifunc)) {
end = rvu_get_num_lbk_chans();
if (end < 0)
return -EINVAL;
} else {
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
base = NIX_CHAN_CGX_LMAC_CHX(cgx_id, lmac_id, 0x0);
/* CGX mapped functions has maximum of 16 channels */
end = NIX_CHAN_CGX_LMAC_CHX(cgx_id, lmac_id, 0xF);
}
if (channel < base || channel > end)
return -EINVAL;
return 0;
}
void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf)
{
int blkaddr;
......@@ -1935,6 +1985,7 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 pcifunc = req->hdr.pcifunc;
u16 channel, chan_mask;
int blkaddr, rc;
u8 nix_intf;
......@@ -1942,6 +1993,10 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
chan_mask = req->entry_data.kw_mask[0] & NPC_KEX_CHAN_MASK;
channel = req->entry_data.kw[0] & NPC_KEX_CHAN_MASK;
channel &= chan_mask;
mutex_lock(&mcam->lock);
rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry);
if (rc)
......@@ -1963,6 +2018,17 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,
else
nix_intf = pfvf->nix_rx_intf;
if (npc_mcam_verify_channel(rvu, pcifunc, req->intf, channel)) {
rc = NPC_MCAM_INVALID_REQ;
goto exit;
}
if (npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf,
pcifunc)) {
rc = NPC_MCAM_INVALID_REQ;
goto exit;
}
npc_config_mcam_entry(rvu, mcam, blkaddr, req->entry, nix_intf,
&req->entry_data, req->enable_entry);
......@@ -2299,6 +2365,7 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu,
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 entry = NPC_MCAM_ENTRY_INVALID;
u16 cntr = NPC_MCAM_ENTRY_INVALID;
u16 channel, chan_mask;
int blkaddr, rc;
u8 nix_intf;
......@@ -2309,6 +2376,17 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu,
if (!is_npc_interface_valid(rvu, req->intf))
return NPC_MCAM_INVALID_REQ;
chan_mask = req->entry_data.kw_mask[0] & NPC_KEX_CHAN_MASK;
channel = req->entry_data.kw[0] & NPC_KEX_CHAN_MASK;
channel &= chan_mask;
if (npc_mcam_verify_channel(rvu, req->hdr.pcifunc, req->intf, channel))
return NPC_MCAM_INVALID_REQ;
if (npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf,
req->hdr.pcifunc))
return NPC_MCAM_INVALID_REQ;
/* Try to allocate a MCAM entry */
entry_req.hdr.pcifunc = req->hdr.pcifunc;
entry_req.contig = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment