Commit 3571fe07 authored by Ratheesh Kannoth's avatar Ratheesh Kannoth Committed by Jakub Kicinski

octeontx2-af: Drop rules for NPC MCAM

NPC exact match table installs drop on hit rules in
NPC mcam for each channel. This rule has broadcast and multicast
bits cleared. Exact match bit cleared and channel bits
set. If exact match table hit bit is 0, corresponding NPC mcam
drop rule will be hit for the packet and will be dropped.
Signed-off-by: default avatarRatheesh Kannoth <rkannoth@marvell.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent bab9eed5
...@@ -1128,6 +1128,12 @@ static int rvu_setup_hw_resources(struct rvu *rvu) ...@@ -1128,6 +1128,12 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
goto cgx_err; goto cgx_err;
} }
err = rvu_npc_exact_init(rvu);
if (err) {
dev_err(rvu->dev, "failed to initialize exact match table\n");
return err;
}
/* Assign MACs for CGX mapped functions */ /* Assign MACs for CGX mapped functions */
rvu_setup_pfvf_macaddress(rvu); rvu_setup_pfvf_macaddress(rvu);
......
...@@ -791,6 +791,7 @@ void rvu_npc_enable_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, ...@@ -791,6 +791,7 @@ void rvu_npc_enable_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf,
void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
int nixlf, int type, bool enable); int nixlf, int type, bool enable);
void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf); void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
bool rvu_npc_enable_mcam_by_entry_index(struct rvu *rvu, int entry, int intf, bool enable);
void rvu_npc_free_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf); void rvu_npc_free_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf); void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf); void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
...@@ -835,6 +836,7 @@ int rvu_npc_init(struct rvu *rvu); ...@@ -835,6 +836,7 @@ int rvu_npc_init(struct rvu *rvu);
int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx, int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
u64 chan_val, u64 chan_mask, u64 exact_val, u64 exact_mask, u64 chan_val, u64 chan_mask, u64 exact_val, u64 exact_mask,
u64 bcast_mcast_val, u64 bcast_mcast_mask); u64 bcast_mcast_val, u64 bcast_mcast_mask);
void npc_mcam_rsrcs_reserve(struct rvu *rvu, int blkaddr, int entry_idx);
/* CPT APIs */ /* CPT APIs */
int rvu_cpt_register_interrupts(struct rvu *rvu); int rvu_cpt_register_interrupts(struct rvu *rvu);
......
...@@ -1106,6 +1106,34 @@ void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf) ...@@ -1106,6 +1106,34 @@ void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
NIXLF_PROMISC_ENTRY, false); NIXLF_PROMISC_ENTRY, false);
} }
bool rvu_npc_enable_mcam_by_entry_index(struct rvu *rvu, int entry, int intf, bool enable)
{
int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
struct npc_mcam *mcam = &rvu->hw->mcam;
struct rvu_npc_mcam_rule *rule, *tmp;
mutex_lock(&mcam->lock);
list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) {
if (rule->intf != intf)
continue;
if (rule->entry != entry)
continue;
rule->enable = enable;
mutex_unlock(&mcam->lock);
npc_enable_mcam_entry(rvu, mcam, blkaddr,
entry, enable);
return true;
}
mutex_unlock(&mcam->lock);
return false;
}
void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf) void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
{ {
/* Enables only broadcast match entry. Promisc/Allmulti are enabled /* Enables only broadcast match entry. Promisc/Allmulti are enabled
...@@ -1816,7 +1844,6 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr) ...@@ -1816,7 +1844,6 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
mcam->hprio_count = mcam->lprio_count; mcam->hprio_count = mcam->lprio_count;
mcam->hprio_end = mcam->hprio_count; mcam->hprio_end = mcam->hprio_count;
/* Allocate bitmap for managing MCAM counters and memory /* Allocate bitmap for managing MCAM counters and memory
* for saving counter to RVU PFFUNC allocation mapping. * for saving counter to RVU PFFUNC allocation mapping.
*/ */
...@@ -2560,6 +2587,14 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc, ...@@ -2560,6 +2587,14 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc,
return 0; return 0;
} }
/* Marks bitmaps to reserved the mcam slot */
void npc_mcam_rsrcs_reserve(struct rvu *rvu, int blkaddr, int entry_idx)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
npc_mcam_set_bit(mcam, entry_idx);
}
int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu, int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu,
struct npc_mcam_alloc_entry_req *req, struct npc_mcam_alloc_entry_req *req,
struct npc_mcam_alloc_entry_rsp *rsp) struct npc_mcam_alloc_entry_rsp *rsp)
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
#include "rvu_reg.h" #include "rvu_reg.h"
#include "rvu.h" #include "rvu.h"
#include "npc.h" #include "npc.h"
#include "rvu_npc_hash.h"
#include "rvu_npc_fs.h" #include "rvu_npc_fs.h"
#include "rvu_npc_hash.h"
#define NPC_BYTESM GENMASK_ULL(19, 16) #define NPC_BYTESM GENMASK_ULL(19, 16)
#define NPC_HDR_OFFSET GENMASK_ULL(15, 8) #define NPC_HDR_OFFSET GENMASK_ULL(15, 8)
...@@ -297,6 +297,7 @@ static void npc_scan_parse_result(struct npc_mcam *mcam, u8 bit_number, ...@@ -297,6 +297,7 @@ static void npc_scan_parse_result(struct npc_mcam *mcam, u8 bit_number,
default: default:
return; return;
} }
npc_set_kw_masks(mcam, type, nr_bits, kwi, offset, intf); npc_set_kw_masks(mcam, type, nr_bits, kwi, offset, intf);
} }
...@@ -860,6 +861,7 @@ do { \ ...@@ -860,6 +861,7 @@ do { \
} while (0) } while (0)
NPC_WRITE_FLOW(NPC_DMAC, dmac, dmac_val, 0, dmac_mask, 0); NPC_WRITE_FLOW(NPC_DMAC, dmac, dmac_val, 0, dmac_mask, 0);
NPC_WRITE_FLOW(NPC_SMAC, smac, smac_val, 0, smac_mask, 0); NPC_WRITE_FLOW(NPC_SMAC, smac, smac_val, 0, smac_mask, 0);
NPC_WRITE_FLOW(NPC_ETYPE, etype, ntohs(pkt->etype), 0, NPC_WRITE_FLOW(NPC_ETYPE, etype, ntohs(pkt->etype), 0,
ntohs(mask->etype), 0); ntohs(mask->etype), 0);
...@@ -891,8 +893,7 @@ do { \ ...@@ -891,8 +893,7 @@ do { \
pkt, mask, opkt, omask); pkt, mask, opkt, omask);
} }
static struct rvu_npc_mcam_rule *rvu_mcam_find_rule(struct npc_mcam *mcam, static struct rvu_npc_mcam_rule *rvu_mcam_find_rule(struct npc_mcam *mcam, u16 entry)
u16 entry)
{ {
struct rvu_npc_mcam_rule *iter; struct rvu_npc_mcam_rule *iter;
...@@ -1058,8 +1059,9 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target, ...@@ -1058,8 +1059,9 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
u16 owner = req->hdr.pcifunc; u16 owner = req->hdr.pcifunc;
struct msg_rsp write_rsp; struct msg_rsp write_rsp;
struct mcam_entry *entry; struct mcam_entry *entry;
int entry_index, err;
bool new = false; bool new = false;
u16 entry_index;
int err;
installed_features = req->features; installed_features = req->features;
features = req->features; features = req->features;
...@@ -1460,3 +1462,98 @@ void npc_mcam_disable_flows(struct rvu *rvu, u16 target) ...@@ -1460,3 +1462,98 @@ void npc_mcam_disable_flows(struct rvu *rvu, u16 target)
} }
mutex_unlock(&mcam->lock); mutex_unlock(&mcam->lock);
} }
/* single drop on non hit rule starting from 0th index. This an extension
* to RPM mac filter to support more rules.
*/
int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
u64 chan_val, u64 chan_mask, u64 exact_val, u64 exact_mask,
u64 bcast_mcast_val, u64 bcast_mcast_mask)
{
struct npc_mcam_alloc_counter_req cntr_req = { 0 };
struct npc_mcam_alloc_counter_rsp cntr_rsp = { 0 };
struct npc_mcam_write_entry_req req = { 0 };
struct npc_mcam *mcam = &rvu->hw->mcam;
struct rvu_npc_mcam_rule *rule;
struct msg_rsp rsp;
bool enabled;
int blkaddr;
int err;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0) {
dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
return -ENODEV;
}
/* Bail out if no exact match support */
if (!rvu_npc_exact_has_match_table(rvu)) {
dev_info(rvu->dev, "%s: No support for exact match feature\n", __func__);
return -EINVAL;
}
/* If 0th entry is already used, return err */
enabled = is_mcam_entry_enabled(rvu, mcam, blkaddr, mcam_idx);
if (enabled) {
dev_err(rvu->dev, "%s: failed to add single drop on non hit rule at %d th index\n",
__func__, mcam_idx);
return -EINVAL;
}
/* Add this entry to mcam rules list */
rule = kzalloc(sizeof(*rule), GFP_KERNEL);
if (!rule)
return -ENOMEM;
/* Disable rule by default. Enable rule when first dmac filter is
* installed
*/
rule->enable = false;
rule->chan = chan_val;
rule->chan_mask = chan_mask;
rule->entry = mcam_idx;
rvu_mcam_add_rule(mcam, rule);
/* Reserve slot 0 */
npc_mcam_rsrcs_reserve(rvu, blkaddr, mcam_idx);
/* Allocate counter for this single drop on non hit rule */
cntr_req.hdr.pcifunc = 0; /* AF request */
cntr_req.contig = true;
cntr_req.count = 1;
err = rvu_mbox_handler_npc_mcam_alloc_counter(rvu, &cntr_req, &cntr_rsp);
if (err) {
dev_err(rvu->dev, "%s: Err to allocate cntr for drop rule (err=%d)\n",
__func__, err);
return -EFAULT;
}
*counter_idx = cntr_rsp.cntr;
/* Fill in fields for this mcam entry */
npc_update_entry(rvu, NPC_EXACT_RESULT, &req.entry_data, exact_val, 0,
exact_mask, 0, NIX_INTF_RX);
npc_update_entry(rvu, NPC_CHAN, &req.entry_data, chan_val, 0,
chan_mask, 0, NIX_INTF_RX);
npc_update_entry(rvu, NPC_LXMB, &req.entry_data, bcast_mcast_val, 0,
bcast_mcast_mask, 0, NIX_INTF_RX);
req.intf = NIX_INTF_RX;
req.set_cntr = true;
req.cntr = cntr_rsp.cntr;
req.entry = mcam_idx;
err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &req, &rsp);
if (err) {
dev_err(rvu->dev, "%s: Installation of single drop on non hit rule at %d failed\n",
__func__, mcam_idx);
return err;
}
dev_err(rvu->dev, "%s: Installed single drop on non hit rule at %d, cntr=%d\n",
__func__, mcam_idx, req.cntr);
/* disable entry at Bank 0, index 0 */
npc_enable_mcam_entry(rvu, mcam, blkaddr, mcam_idx, false);
return 0;
}
...@@ -129,6 +129,14 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = { ...@@ -129,6 +129,14 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = {
}, },
}; };
/* If exact match table support is enabled, enable drop rules */
#define NPC_MCAM_DROP_RULE_MAX 30
#define NPC_MCAM_SDP_DROP_RULE_IDX 0
#define RVU_PFFUNC(pf, func) \
((((pf) & RVU_PFVF_PF_MASK) << RVU_PFVF_PF_SHIFT) | \
(((func) & RVU_PFVF_FUNC_MASK) << RVU_PFVF_FUNC_SHIFT))
enum npc_exact_opc_type { enum npc_exact_opc_type {
NPC_EXACT_OPC_MEM, NPC_EXACT_OPC_MEM,
NPC_EXACT_OPC_CAM, NPC_EXACT_OPC_CAM,
...@@ -155,7 +163,11 @@ struct npc_exact_table_entry { ...@@ -155,7 +163,11 @@ struct npc_exact_table_entry {
struct npc_exact_table { struct npc_exact_table {
struct mutex lock; /* entries update lock */ struct mutex lock; /* entries update lock */
unsigned long *id_bmap; unsigned long *id_bmap;
int num_drop_rules;
u32 tot_ids; u32 tot_ids;
u16 cnt_cmd_rules[NPC_MCAM_DROP_RULE_MAX];
u16 counter_idx[NPC_MCAM_DROP_RULE_MAX];
bool promisc_mode[NPC_MCAM_DROP_RULE_MAX];
struct { struct {
int ways; int ways;
int depth; int depth;
...@@ -169,6 +181,15 @@ struct npc_exact_table { ...@@ -169,6 +181,15 @@ struct npc_exact_table {
int depth; int depth;
unsigned long *bmap; unsigned long *bmap;
} cam_table; } cam_table;
struct {
bool valid;
u16 chan_val;
u16 chan_mask;
u16 pcifunc;
u8 drop_rule_idx;
} drop_rule_map[NPC_MCAM_DROP_RULE_MAX];
#define NPC_EXACT_TBL_MAX_WAYS 4 #define NPC_EXACT_TBL_MAX_WAYS 4
struct list_head lhead_mem_tbl_entry[NPC_EXACT_TBL_MAX_WAYS]; struct list_head lhead_mem_tbl_entry[NPC_EXACT_TBL_MAX_WAYS];
...@@ -188,5 +209,6 @@ int rvu_npc_exact_init(struct rvu *rvu); ...@@ -188,5 +209,6 @@ int rvu_npc_exact_init(struct rvu *rvu);
bool rvu_npc_exact_can_disable_feature(struct rvu *rvu); bool rvu_npc_exact_can_disable_feature(struct rvu *rvu);
void rvu_npc_exact_disable_feature(struct rvu *rvu); void rvu_npc_exact_disable_feature(struct rvu *rvu);
void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc); void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc);
u16 rvu_npc_exact_drop_rule_to_pcifunc(struct rvu *rvu, u32 drop_rule_idx);
#endif /* RVU_NPC_HASH_H */ #endif /* RVU_NPC_HASH_H */
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