]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
octeontx2-af: Enable broadcast packet replication
authorSunil Goutham <sgoutham@marvell.com>
Thu, 14 Nov 2019 05:26:30 +0000 (10:56 +0530)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Nov 2019 02:09:16 +0000 (18:09 -0800)
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: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c

index bf9272fafd693e9e3b2adaf888a11143b0b861f1..3985053fa217c43e2d352dde4977bb90a1774e72 100644 (file)
@@ -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;
        }
 }
 
index 000d02bb2ccf9b5b10a1624d54d3557a47c911c9..7370864c546cd805207296e8d659df60f4f4347a 100644 (file)
@@ -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);
index 3b32e91482fcc418122c1e344233204464637ddd..4519d80212cafef1522a3c81a6cedc63e4c6f7be 100644 (file)
@@ -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:
index f0363d08c36d6956c8e3420060b349330b4e8c0e..40e431debbe94642c540866cf46e1d5f0442849b 100644 (file)
@@ -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)
 {