提交 55307fcb 编写于 作者: S Subbaraya Sundeep 提交者: Jakub Kicinski

octeontx2-af: Add mbox messages to install and delete MCAM rules

Added new mailbox messages to install and delete MCAM rules.
These mailbox messages will be used for adding/deleting ethtool
n-tuple filters by NIX PF. The installed MCAM rules are stored
in a list that will be traversed later to delete the MCAM entries
when the interface is brought down or when PCIe FLR is received.
The delete mailbox supports deleting a single MCAM entry or range
of entries or all the MCAM entries owned by the pcifunc. Each MCAM
entry can be associated with a HW match stat entry if the mailbox
requester wants to check the hit count for debugging.

Modified adding default unicast DMAC match rule using install
flow API. The default unicast DMAC match entry installed by
Administrative Function is saved and can be changed later by the
mailbox user to fit additional fields, or the default MCAM entry
rule action can be used for other flow rules installed later.

Modified rvu_mbox_handler_nix_lf_free mailbox to add a flag to
disable or delete the MCAM entries. The MCAM entries are disabled
when the interface is brought down and deleted in FLR handler.
The disabled MCAM entries will be re-enabled when the interface
is brought up again.
Signed-off-by: NSubbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: NSunil Goutham <sgoutham@marvell.com>
Signed-off-by: NNaveen Mamindlapalli <naveenm@marvell.com>
Signed-off-by: NJakub Kicinski <kuba@kernel.org>
上级 9b179a96
......@@ -162,6 +162,8 @@ enum nix_scheduler {
#define NIX_RX_ACTIONOP_UCAST_IPSEC (0x2ull)
#define NIX_RX_ACTIONOP_MCAST (0x3ull)
#define NIX_RX_ACTIONOP_RSS (0x4ull)
/* Use the RX action set in the default unicast entry */
#define NIX_RX_ACTION_DEFAULT (0xfull)
/* NIX TX action operation*/
#define NIX_TX_ACTIONOP_DROP (0x0ull)
......
......@@ -188,10 +188,14 @@ M(NPC_MCAM_ALLOC_AND_WRITE_ENTRY, 0x600b, npc_mcam_alloc_and_write_entry, \
npc_mcam_alloc_and_write_entry_rsp) \
M(NPC_GET_KEX_CFG, 0x600c, npc_get_kex_cfg, \
msg_req, npc_get_kex_cfg_rsp) \
M(NPC_INSTALL_FLOW, 0x600d, npc_install_flow, \
npc_install_flow_req, npc_install_flow_rsp) \
M(NPC_DELETE_FLOW, 0x600e, npc_delete_flow, \
npc_delete_flow_req, msg_rsp) \
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
M(NIX_LF_ALLOC, 0x8000, nix_lf_alloc, \
nix_lf_alloc_req, nix_lf_alloc_rsp) \
M(NIX_LF_FREE, 0x8001, nix_lf_free, msg_req, msg_rsp) \
M(NIX_LF_FREE, 0x8001, nix_lf_free, nix_lf_free_req, msg_rsp) \
M(NIX_AQ_ENQ, 0x8002, nix_aq_enq, nix_aq_enq_req, nix_aq_enq_rsp) \
M(NIX_HWCTX_DISABLE, 0x8003, nix_hwctx_disable, \
hwctx_disable_req, msg_rsp) \
......@@ -510,6 +514,12 @@ struct nix_lf_alloc_rsp {
u8 sdp_links; /* No. of SDP links present in HW */
};
struct nix_lf_free_req {
struct mbox_msghdr hdr;
#define NIX_LF_DISABLE_FLOWS BIT_ULL(0)
u64 flags;
};
/* NIX AQ enqueue msg */
struct nix_aq_enq_req {
struct mbox_msghdr hdr;
......@@ -882,6 +892,70 @@ struct npc_get_kex_cfg_rsp {
u8 mkex_pfl_name[MKEX_NAME_LEN];
};
struct flow_msg {
unsigned char dmac[6];
unsigned char smac[6];
__be16 etype;
__be16 vlan_etype;
__be16 vlan_tci;
union {
__be32 ip4src;
__be32 ip6src[4];
};
union {
__be32 ip4dst;
__be32 ip6dst[4];
};
u8 tos;
u8 ip_ver;
u8 ip_proto;
u8 tc;
__be16 sport;
__be16 dport;
};
struct npc_install_flow_req {
struct mbox_msghdr hdr;
struct flow_msg packet;
struct flow_msg mask;
u64 features;
u16 entry;
u16 channel;
u8 intf;
u8 set_cntr; /* If counter is available set counter for this entry ? */
u8 default_rule;
u8 append; /* overwrite(0) or append(1) flow to default rule? */
u16 vf;
/* action */
u32 index;
u16 match_id;
u8 flow_key_alg;
u8 op;
/* vtag rx action */
u8 vtag0_type;
u8 vtag0_valid;
u8 vtag1_type;
u8 vtag1_valid;
/* vtag tx action */
u16 vtag0_def;
u8 vtag0_op;
u16 vtag1_def;
u8 vtag1_op;
};
struct npc_install_flow_rsp {
struct mbox_msghdr hdr;
int counter; /* negative if no counter else counter number */
};
struct npc_delete_flow_req {
struct mbox_msghdr hdr;
u16 entry;
u16 start;/*Disable range of entries */
u16 end;
u8 all; /* PF + VFs */
};
enum ptp_op {
PTP_OP_ADJFINE = 0,
PTP_OP_GET_CLOCK = 1,
......
......@@ -379,11 +379,41 @@ struct nix_rx_action {
#define NPC_PARSE_NIBBLE_LH_FLAGS GENMASK_ULL(29, 28)
#define NPC_PARSE_NIBBLE_LH_LTYPE BIT_ULL(30)
struct nix_tx_action {
#if defined(__BIG_ENDIAN_BITFIELD)
u64 rsvd_63_48 :16;
u64 match_id :16;
u64 index :20;
u64 rsvd_11_8 :8;
u64 op :4;
#else
u64 op :4;
u64 rsvd_11_8 :8;
u64 index :20;
u64 match_id :16;
u64 rsvd_63_48 :16;
#endif
};
/* NIX Receive Vtag Action Structure */
#define VTAG0_VALID_BIT BIT_ULL(15)
#define VTAG0_TYPE_MASK GENMASK_ULL(14, 12)
#define VTAG0_LID_MASK GENMASK_ULL(10, 8)
#define VTAG0_RELPTR_MASK GENMASK_ULL(7, 0)
#define RX_VTAG0_VALID_BIT BIT_ULL(15)
#define RX_VTAG0_TYPE_MASK GENMASK_ULL(14, 12)
#define RX_VTAG0_LID_MASK GENMASK_ULL(10, 8)
#define RX_VTAG0_RELPTR_MASK GENMASK_ULL(7, 0)
#define RX_VTAG1_VALID_BIT BIT_ULL(47)
#define RX_VTAG1_TYPE_MASK GENMASK_ULL(46, 44)
#define RX_VTAG1_LID_MASK GENMASK_ULL(42, 40)
#define RX_VTAG1_RELPTR_MASK GENMASK_ULL(39, 32)
/* NIX Transmit Vtag Action Structure */
#define TX_VTAG0_DEF_MASK GENMASK_ULL(25, 16)
#define TX_VTAG0_OP_MASK GENMASK_ULL(13, 12)
#define TX_VTAG0_LID_MASK GENMASK_ULL(10, 8)
#define TX_VTAG0_RELPTR_MASK GENMASK_ULL(7, 0)
#define TX_VTAG1_DEF_MASK GENMASK_ULL(57, 48)
#define TX_VTAG1_OP_MASK GENMASK_ULL(45, 44)
#define TX_VTAG1_LID_MASK GENMASK_ULL(42, 40)
#define TX_VTAG1_RELPTR_MASK GENMASK_ULL(39, 32)
struct npc_mcam_kex {
/* MKEX Profle Header */
......@@ -436,4 +466,23 @@ struct npc_lt_def_cfg {
struct npc_lt_def pck_iip4;
};
struct rvu_npc_mcam_rule {
struct flow_msg packet;
struct flow_msg mask;
u8 intf;
union {
struct nix_tx_action tx_action;
struct nix_rx_action rx_action;
};
u64 vtag_action;
struct list_head list;
u64 features;
u16 owner;
u16 entry;
u16 cntr;
bool has_cntr;
u8 default_rule;
bool enable;
};
#endif /* NPC_H */
......@@ -147,6 +147,7 @@ struct npc_mcam {
u16 *entry2cntr_map;
u16 *cntr2pfvf_map;
u16 *cntr_refcnt;
u16 *entry2target_pffunc;
u8 keysize; /* MCAM keysize 112/224/448 bits */
u8 banks; /* Number of MCAM banks */
u8 banks_per_entry;/* Number of keywords in key */
......@@ -164,6 +165,7 @@ struct npc_mcam {
struct npc_key_field rx_key_fields[NPC_KEY_FIELDS_MAX];
u64 tx_features;
u64 rx_features;
struct list_head mcam_rules;
};
/* Structure for per RVU func info ie PF/VF */
......@@ -218,6 +220,8 @@ struct rvu_pfvf {
int rxvlan_index;
bool rxvlan;
struct rvu_npc_mcam_rule *def_ucast_rule;
bool cgx_in_use; /* this PF/VF using CGX? */
int cgx_users; /* number of cgx users - used only by PFs */
......@@ -558,6 +562,7 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable);
int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_disable_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_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
......@@ -575,6 +580,14 @@ 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);
int npc_flow_steering_init(struct rvu *rvu, int blkaddr);
const char *npc_get_field_name(u8 hdr);
bool rvu_npc_write_default_rule(struct rvu *rvu, int blkaddr, int nixlf,
u16 pcifunc, u8 intf, struct mcam_entry *entry,
int *entry_index);
int npc_get_bank(struct npc_mcam *mcam, int index);
void npc_mcam_enable_flows(struct rvu *rvu, u16 target);
void npc_mcam_disable_flows(struct rvu *rvu, u16 target);
void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, bool enable);
#ifdef CONFIG_DEBUG_FS
void rvu_dbg_init(struct rvu *rvu);
......
......@@ -302,7 +302,6 @@ static void nix_interface_deinit(struct rvu *rvu, u16 pcifunc, u8 nixlf)
pfvf->maxlen = 0;
pfvf->minlen = 0;
pfvf->rxvlan = false;
/* Remove this PF_FUNC from bcast pkt replication list */
err = nix_update_bcast_mce_list(rvu, pcifunc, false);
......@@ -1228,7 +1227,7 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
return rc;
}
int rvu_mbox_handler_nix_lf_free(struct rvu *rvu, struct msg_req *req,
int rvu_mbox_handler_nix_lf_free(struct rvu *rvu, struct nix_lf_free_req *req,
struct msg_rsp *rsp)
{
struct rvu_hwinfo *hw = rvu->hw;
......@@ -1247,6 +1246,11 @@ int rvu_mbox_handler_nix_lf_free(struct rvu *rvu, struct msg_req *req,
if (nixlf < 0)
return NIX_AF_ERR_AF_LF_INVALID;
if (req->flags & NIX_LF_DISABLE_FLOWS)
rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf);
else
rvu_npc_free_mcam_entries(rvu, pcifunc, nixlf);
nix_interface_deinit(rvu, pcifunc, nixlf);
/* Reset this NIX LF */
......@@ -2762,8 +2766,6 @@ int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
rvu_npc_install_ucast_entry(rvu, pcifunc, nixlf,
pfvf->rx_chan_base, req->mac_addr);
rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
return 0;
}
......@@ -2810,9 +2812,6 @@ int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,
else
rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
pfvf->rx_chan_base, allmulti);
rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
return 0;
}
......@@ -3376,6 +3375,8 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
rvu_npc_enable_default_entries(rvu, pcifunc, nixlf);
npc_mcam_enable_flows(rvu, pcifunc);
return rvu_cgx_start_stop_io(rvu, pcifunc, true);
}
......@@ -3391,6 +3392,8 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
rvu_npc_disable_default_entries(rvu, pcifunc, nixlf);
npc_mcam_disable_flows(rvu, pcifunc);
return rvu_cgx_start_stop_io(rvu, pcifunc, false);
}
......@@ -3403,6 +3406,8 @@ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
ctx_req.hdr.pcifunc = pcifunc;
/* Cleanup NPC MCAM entries, free Tx scheduler queues being used */
rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf);
rvu_npc_free_mcam_entries(rvu, pcifunc, nixlf);
nix_interface_deinit(rvu, pcifunc, nixlf);
nix_rx_sync(rvu, blkaddr);
nix_txschq_free(rvu, pcifunc);
......
......@@ -219,7 +219,7 @@ static int npc_get_nixlf_mcam_index(struct npc_mcam *mcam,
return npc_get_ucast_mcam_index(mcam, pcifunc, nixlf);
}
static int npc_get_bank(struct npc_mcam *mcam, int index)
int npc_get_bank(struct npc_mcam *mcam, int index)
{
int bank = index / mcam->banksize;
......@@ -241,8 +241,8 @@ static bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam,
return (cfg & 1);
}
static void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, bool enable)
void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, bool enable)
{
int bank = npc_get_bank(mcam, index);
int actbank = bank;
......@@ -359,6 +359,41 @@ static void npc_get_keyword(struct mcam_entry *entry, int idx,
*cam0 = ~*cam1 & kw_mask;
}
static void npc_get_default_entry_action(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index,
struct mcam_entry *entry)
{
u16 owner, target_func;
struct rvu_pfvf *pfvf;
int bank, nixlf;
u64 rx_action;
owner = mcam->entry2pfvf_map[index];
target_func = (entry->action >> 4) & 0xffff;
/* return incase target is PF or LBK or rule owner is not PF */
if (is_afvf(target_func) || (owner & RVU_PFVF_FUNC_MASK) ||
!(target_func & RVU_PFVF_FUNC_MASK))
return;
pfvf = rvu_get_pfvf(rvu, target_func);
mcam->entry2target_pffunc[index] = target_func;
/* return if nixlf is not attached or initialized */
if (!is_nixlf_attached(rvu, target_func) || !pfvf->def_ucast_rule)
return;
/* get VF ucast entry rule */
nix_get_nixlf(rvu, target_func, &nixlf, NULL);
index = npc_get_nixlf_mcam_index(mcam, target_func,
nixlf, NIXLF_UCAST_ENTRY);
bank = npc_get_bank(mcam, index);
index &= (mcam->banksize - 1);
rx_action = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_ACTION(index, bank));
if (rx_action)
entry->action = rx_action;
}
static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, u8 intf,
struct mcam_entry *entry, bool enable)
......@@ -406,6 +441,11 @@ static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 0), cam0);
}
/* copy VF default entry action to the VF mcam entry */
if (intf == NIX_INTF_RX && actindex < mcam->bmap_entries)
npc_get_default_entry_action(rvu, mcam, blkaddr, actindex,
entry);
/* Set 'action' */
rvu_write64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_ACTION(index, actbank), entry->action);
......@@ -473,11 +513,11 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
int nixlf, u64 chan, u8 *mac_addr)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
struct npc_install_flow_req req = { 0 };
struct npc_install_flow_rsp rsp = { 0 };
struct npc_mcam *mcam = &rvu->hw->mcam;
struct mcam_entry entry = { {0} };
struct nix_rx_action action;
int blkaddr, index, kwi;
u64 mac = 0;
int blkaddr, index;
/* AF's VFs work in promiscuous mode */
if (is_afvf(pcifunc))
......@@ -487,20 +527,9 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
if (blkaddr < 0)
return;
for (index = ETH_ALEN - 1; index >= 0; index--)
mac |= ((u64)*mac_addr++) << (8 * index);
index = npc_get_nixlf_mcam_index(mcam, pcifunc,
nixlf, NIXLF_UCAST_ENTRY);
/* Match ingress channel and DMAC */
entry.kw[0] = chan;
entry.kw_mask[0] = 0xFFFULL;
kwi = NPC_PARSE_RESULT_DMAC_OFFSET / sizeof(u64);
entry.kw[kwi] = mac;
entry.kw_mask[kwi] = BIT_ULL(48) - 1;
/* Don't change the action if entry is already enabled
* Otherwise RSS action may get overwritten.
*/
......@@ -513,20 +542,20 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
action.pf_func = pcifunc;
}
entry.action = *(u64 *)&action;
npc_config_mcam_entry(rvu, mcam, blkaddr, index,
pfvf->nix_rx_intf, &entry, true);
/* add VLAN matching, setup action and save entry back for later */
entry.kw[0] |= (NPC_LT_LB_STAG_QINQ | NPC_LT_LB_CTAG) << 20;
entry.kw_mask[0] |= (NPC_LT_LB_STAG_QINQ & NPC_LT_LB_CTAG) << 20;
req.default_rule = 1;
ether_addr_copy(req.packet.dmac, mac_addr);
eth_broadcast_addr((u8 *)&req.mask.dmac);
req.features = BIT_ULL(NPC_DMAC);
req.channel = chan;
req.intf = pfvf->nix_rx_intf;
req.op = action.op;
req.hdr.pcifunc = 0; /* AF is requester */
req.vf = action.pf_func;
req.index = action.index;
req.match_id = action.match_id;
req.flow_key_alg = action.flow_key_alg;
entry.vtag_action = VTAG0_VALID_BIT |
FIELD_PREP(VTAG0_TYPE_MASK, 0) |
FIELD_PREP(VTAG0_LID_MASK, NPC_LID_LA) |
FIELD_PREP(VTAG0_RELPTR_MASK, 12);
memcpy(&pfvf->entry, &entry, sizeof(entry));
rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
}
void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
......@@ -682,12 +711,47 @@ void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable)
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
}
static void npc_update_vf_flow_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, u16 pcifunc, u64 rx_action)
{
int actindex, index, bank;
bool enable;
if (!(pcifunc & RVU_PFVF_FUNC_MASK))
return;
mutex_lock(&mcam->lock);
for (index = 0; index < mcam->bmap_entries; index++) {
if (mcam->entry2target_pffunc[index] == pcifunc) {
bank = npc_get_bank(mcam, index);
actindex = index;
index &= (mcam->banksize - 1);
/* read vf flow entry enable status */
enable = is_mcam_entry_enabled(rvu, mcam, blkaddr,
actindex);
/* disable before mcam entry update */
npc_enable_mcam_entry(rvu, mcam, blkaddr, actindex,
false);
/* update 'action' */
rvu_write64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_ACTION(index, bank),
rx_action);
if (enable)
npc_enable_mcam_entry(rvu, mcam, blkaddr,
actindex, true);
}
}
mutex_unlock(&mcam->lock);
}
void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
int group, int alg_idx, int mcam_index)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
struct nix_rx_action action;
int blkaddr, index, bank;
struct rvu_pfvf *pfvf;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
......@@ -724,6 +788,16 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
rvu_write64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
/* update the VF flow rule action with the VF default entry action */
if (mcam_index < 0)
npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
*(u64 *)&action);
/* update the action change in default rule */
pfvf = rvu_get_pfvf(rvu, pcifunc);
if (pfvf->def_ucast_rule)
pfvf->def_ucast_rule->rx_action = action;
index = npc_get_nixlf_mcam_index(mcam, pcifunc,
nixlf, NIXLF_PROMISC_ENTRY);
......@@ -738,8 +812,6 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
NPC_AF_MCAMEX_BANKX_ACTION(index, bank),
*(u64 *)&action);
}
rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
}
static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
......@@ -791,8 +863,6 @@ static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf);
else
rvu_npc_disable_promisc_entry(rvu, pcifunc, nixlf);
rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
}
void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
......@@ -807,7 +877,9 @@ void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
struct npc_mcam *mcam = &rvu->hw->mcam;
struct rvu_npc_mcam_rule *rule;
int blkaddr;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
......@@ -816,12 +888,52 @@ void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
mutex_lock(&mcam->lock);
/* Disable and free all MCAM entries mapped to this 'pcifunc' */
/* Disable MCAM entries directing traffic to this 'pcifunc' */
list_for_each_entry(rule, &mcam->mcam_rules, list) {
if (is_npc_intf_rx(rule->intf) &&
rule->rx_action.pf_func == pcifunc) {
npc_enable_mcam_entry(rvu, mcam, blkaddr,
rule->entry, false);
rule->enable = false;
/* Indicate that default rule is disabled */
if (rule->default_rule)
pfvf->def_ucast_rule = NULL;
}
}
mutex_unlock(&mcam->lock);
npc_mcam_disable_flows(rvu, pcifunc);
rvu_npc_disable_default_entries(rvu, pcifunc, nixlf);
}
void rvu_npc_free_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
struct rvu_npc_mcam_rule *rule, *tmp;
int blkaddr;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return;
mutex_lock(&mcam->lock);
/* Free all MCAM entries owned by this 'pcifunc' */
npc_mcam_free_all_entries(rvu, mcam, blkaddr, pcifunc);
/* Free all MCAM counters mapped to this 'pcifunc' */
/* Free all MCAM counters owned by this 'pcifunc' */
npc_mcam_free_all_counters(rvu, mcam, pcifunc);
/* Delete MCAM entries owned by this 'pcifunc' */
list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) {
if (rule->owner == pcifunc && !rule->default_rule) {
list_del(&rule->list);
kfree(rule);
}
}
mutex_unlock(&mcam->lock);
rvu_npc_disable_default_entries(rvu, pcifunc, nixlf);
......@@ -1231,6 +1343,12 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
if (!mcam->cntr_refcnt)
goto free_mem;
/* Alloc memory for saving target device of mcam rule */
mcam->entry2target_pffunc = devm_kcalloc(rvu->dev, mcam->total_entries,
sizeof(u16), GFP_KERNEL);
if (!mcam->entry2target_pffunc)
goto free_mem;
mutex_init(&mcam->lock);
return 0;
......@@ -1580,6 +1698,7 @@ static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
npc_unmap_mcam_entry_and_cntr(rvu, mcam,
blkaddr, index,
cntr);
mcam->entry2target_pffunc[index] = 0x0;
}
}
}
......@@ -1966,6 +2085,7 @@ int rvu_mbox_handler_npc_mcam_free_entry(struct rvu *rvu,
goto exit;
mcam->entry2pfvf_map[req->entry] = 0;
mcam->entry2target_pffunc[req->entry] = 0x0;
npc_mcam_clear_bit(mcam, req->entry);
npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, false);
......@@ -2521,3 +2641,27 @@ int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf)
return 0;
}
bool rvu_npc_write_default_rule(struct rvu *rvu, int blkaddr, int nixlf,
u16 pcifunc, u8 intf, struct mcam_entry *entry,
int *index)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
struct npc_mcam *mcam = &rvu->hw->mcam;
bool enable;
u8 nix_intf;
if (is_npc_intf_tx(intf))
nix_intf = pfvf->nix_tx_intf;
else
nix_intf = pfvf->nix_rx_intf;
*index = npc_get_nixlf_mcam_index(mcam, pcifunc,
nixlf, NIXLF_UCAST_ENTRY);
/* dont force enable unicast entry */
enable = is_mcam_entry_enabled(rvu, mcam, blkaddr, *index);
npc_config_mcam_entry(rvu, mcam, blkaddr, *index, nix_intf,
entry, enable);
return enable;
}
......@@ -1278,6 +1278,7 @@ static void otx2_free_sq_res(struct otx2_nic *pf)
static int otx2_init_hw_resources(struct otx2_nic *pf)
{
struct nix_lf_free_req *free_req;
struct mbox *mbox = &pf->mbox;
struct otx2_hw *hw = &pf->hw;
struct msg_req *req;
......@@ -1359,8 +1360,9 @@ static int otx2_init_hw_resources(struct otx2_nic *pf)
otx2_aura_pool_free(pf);
err_free_nix_lf:
mutex_lock(&mbox->lock);
req = otx2_mbox_alloc_msg_nix_lf_free(mbox);
if (req) {
free_req = otx2_mbox_alloc_msg_nix_lf_free(mbox);
if (free_req) {
free_req->flags = NIX_LF_DISABLE_FLOWS;
if (otx2_sync_mbox_msg(mbox))
dev_err(pf->dev, "%s failed to free nixlf\n", __func__);
}
......@@ -1379,6 +1381,7 @@ static int otx2_init_hw_resources(struct otx2_nic *pf)
static void otx2_free_hw_resources(struct otx2_nic *pf)
{
struct otx2_qset *qset = &pf->qset;
struct nix_lf_free_req *free_req;
struct mbox *mbox = &pf->mbox;
struct otx2_cq_queue *cq;
struct msg_req *req;
......@@ -1419,8 +1422,9 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
mutex_lock(&mbox->lock);
/* Reset NIX LF */
req = otx2_mbox_alloc_msg_nix_lf_free(mbox);
if (req) {
free_req = otx2_mbox_alloc_msg_nix_lf_free(mbox);
if (free_req) {
free_req->flags = NIX_LF_DISABLE_FLOWS;
if (otx2_sync_mbox_msg(mbox))
dev_err(pf->dev, "%s failed to free nixlf\n", __func__);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册