Commit 561e8752 authored by Sunil Goutham's avatar Sunil Goutham Committed by David S. Miller

octeontx2-af: Enable broadcast packet replication

Ingress packet replication support has been added to 96xx B0
silicon. This patch enables using that feature to replicate
ingress broadcast packets to PF and it's VFs.

Also fixed below issues
- VFs can also install NPC MCAM entry to forward broadcast pkts.
  Otherwise, unless PF's interface is UP, VFs will not receive
  bcast packets.
- NPC MCAM entry is disabled when PF and all it's VFs are down.
- Few corner cases in installing multicast entry list.
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d9b976d
......@@ -64,6 +64,7 @@ static void rvu_setup_hw_capabilities(struct rvu *rvu)
hw->cap.nix_fixed_txschq_mapping = false;
hw->cap.nix_shaping = true;
hw->cap.nix_tx_link_bp = true;
hw->cap.nix_rx_multicast = true;
if (is_rvu_96xx_B0(rvu)) {
hw->cap.nix_fixed_txschq_mapping = true;
......@@ -72,6 +73,8 @@ static void rvu_setup_hw_capabilities(struct rvu *rvu)
hw->cap.nix_txsch_per_sdp_lmac = 76;
hw->cap.nix_shaping = false;
hw->cap.nix_tx_link_bp = false;
if (is_rvu_96xx_A0(rvu))
hw->cap.nix_rx_multicast = false;
}
}
......
......@@ -235,6 +235,7 @@ struct hw_cap {
bool nix_fixed_txschq_mapping; /* Schq mapping fixed or flexible */
bool nix_shaping; /* Is shaping and coloring supported */
bool nix_tx_link_bp; /* Can link backpressure TL queues ? */
bool nix_rx_multicast; /* Rx packet replication support */
};
struct rvu_hwinfo {
......@@ -441,6 +442,7 @@ void rvu_npc_disable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_enable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
int nixlf, u64 chan);
void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc);
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_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
......
......@@ -64,7 +64,6 @@ enum nix_makr_fmt_indexes {
struct mce {
struct hlist_node node;
u16 idx;
u16 pcifunc;
};
......@@ -1754,7 +1753,7 @@ static int nix_setup_mce(struct rvu *rvu, int mce, u8 op,
}
static int nix_update_mce_list(struct nix_mce_list *mce_list,
u16 pcifunc, int idx, bool add)
u16 pcifunc, bool add)
{
struct mce *mce, *tail = NULL;
bool delete = false;
......@@ -1783,7 +1782,6 @@ static int nix_update_mce_list(struct nix_mce_list *mce_list,
mce = kzalloc(sizeof(*mce), GFP_KERNEL);
if (!mce)
return -ENOMEM;
mce->idx = idx;
mce->pcifunc = pcifunc;
if (!tail)
hlist_add_head(&mce->node, &mce_list->head);
......@@ -1795,12 +1793,12 @@ static int nix_update_mce_list(struct nix_mce_list *mce_list,
static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
{
int err = 0, idx, next_idx, count;
int err = 0, idx, next_idx, last_idx;
struct nix_mce_list *mce_list;
struct mce *mce, *next_mce;
struct nix_mcast *mcast;
struct nix_hw *nix_hw;
struct rvu_pfvf *pfvf;
struct mce *mce;
int blkaddr;
/* Broadcast pkt replication is not needed for AF's VFs, hence skip */
......@@ -1832,31 +1830,31 @@ static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
mutex_lock(&mcast->mce_lock);
err = nix_update_mce_list(mce_list, pcifunc, idx, add);
err = nix_update_mce_list(mce_list, pcifunc, add);
if (err)
goto end;
/* Disable MCAM entry in NPC */
if (!mce_list->count)
if (!mce_list->count) {
rvu_npc_disable_bcast_entry(rvu, pcifunc);
goto end;
count = mce_list->count;
}
/* Dump the updated list to HW */
idx = pfvf->bcast_mce_idx;
last_idx = idx + mce_list->count - 1;
hlist_for_each_entry(mce, &mce_list->head, node) {
next_idx = 0;
count--;
if (count) {
next_mce = hlist_entry(mce->node.next,
struct mce, node);
next_idx = next_mce->idx;
}
if (idx > last_idx)
break;
next_idx = idx + 1;
/* EOL should be set in last MCE */
err = nix_setup_mce(rvu, mce->idx,
NIX_AQ_INSTOP_WRITE, mce->pcifunc,
next_idx, count ? false : true);
err = nix_setup_mce(rvu, idx, NIX_AQ_INSTOP_WRITE,
mce->pcifunc, next_idx,
(next_idx > last_idx) ? true : false);
if (err)
goto end;
idx++;
}
end:
......
......@@ -477,68 +477,75 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
{
struct npc_mcam *mcam = &rvu->hw->mcam;
struct mcam_entry entry = { {0} };
struct rvu_hwinfo *hw = rvu->hw;
struct nix_rx_action action;
#ifdef MCAST_MCE
struct rvu_pfvf *pfvf;
#endif
int blkaddr, index;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return;
/* Only PF can add a bcast match entry */
if (pcifunc & RVU_PFVF_FUNC_MASK)
/* Skip LBK VFs */
if (is_afvf(pcifunc))
return;
/* If pkt replication is not supported,
* then only PF is allowed to add a bcast match entry.
*/
if (!hw->cap.nix_rx_multicast && pcifunc & RVU_PFVF_FUNC_MASK)
return;
#ifdef MCAST_MCE
pfvf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
#endif
/* Get 'pcifunc' of PF device */
pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
index = npc_get_nixlf_mcam_index(mcam, pcifunc,
nixlf, NIXLF_BCAST_ENTRY);
/* Check for L2B bit and LMAC channel
* NOTE: Since MKEX default profile(a reduced version intended to
* accommodate more capability but igoring few bits) a stap-gap
* approach.
* Since we care for L2B which by HRM NPC_PARSE_KEX_S at BIT_POS[25], So
* moved to BIT_POS[13], ignoring ERRCODE, ERRLEV as we'll loose out
* on capability features needed for CoS (/from ODP PoV) e.g: VLAN,
* DSCP.
*
* Reduced layout of MKEX default profile -
* Includes following are (i.e.CHAN, L2/3{B/M}, LA, LB, LC, LD):
*
* BIT_POS[31:28] : LD
* BIT_POS[27:24] : LC
* BIT_POS[23:20] : LB
* BIT_POS[19:16] : LA
* BIT_POS[15:12] : L3B, L3M, L2B, L2M
* BIT_POS[11:00] : CHAN
*
/* Match ingress channel */
entry.kw[0] = chan;
entry.kw_mask[0] = 0xfffull;
/* Match broadcast MAC address.
* DMAC is extracted at 0th bit of PARSE_KEX::KW1
*/
entry.kw[0] = BIT_ULL(13) | chan;
entry.kw_mask[0] = BIT_ULL(13) | 0xFFFULL;
entry.kw[1] = 0xffffffffffffull;
entry.kw_mask[1] = 0xffffffffffffull;
*(u64 *)&action = 0x00;
#ifdef MCAST_MCE
/* Early silicon doesn't support pkt replication,
* so install entry with UCAST action, so that PF
* receives all broadcast packets.
*/
action.op = NIX_RX_ACTIONOP_MCAST;
action.pf_func = pcifunc;
action.index = pfvf->bcast_mce_idx;
#else
action.op = NIX_RX_ACTIONOP_UCAST;
action.pf_func = pcifunc;
#endif
if (!hw->cap.nix_rx_multicast) {
/* Early silicon doesn't support pkt replication,
* so install entry with UCAST action, so that PF
* receives all broadcast packets.
*/
action.op = NIX_RX_ACTIONOP_UCAST;
action.pf_func = pcifunc;
} else {
pfvf = rvu_get_pfvf(rvu, pcifunc);
action.index = pfvf->bcast_mce_idx;
action.op = NIX_RX_ACTIONOP_MCAST;
}
entry.action = *(u64 *)&action;
npc_config_mcam_entry(rvu, mcam, blkaddr, index,
NIX_INTF_RX, &entry, true);
}
void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int blkaddr, index;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return;
/* Get 'pcifunc' of PF device */
pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
index = npc_get_nixlf_mcam_index(mcam, pcifunc, 0, NIXLF_BCAST_ENTRY);
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
}
void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
int group, int alg_idx, int mcam_index)
{
......
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