octeontx2-af: Add support for multi channel in NIX promisc entry
authorNalla, Pradeep <pnalla@marvell.com>
Wed, 17 Mar 2021 13:35:35 +0000 (19:05 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 17 Mar 2021 19:29:39 +0000 (12:29 -0700)
This patch adds support for multi channel NIX promisc entry. Packets sent
on all those channels by the host should be received by the interface to
which those channels belong. Channel count, if greater than 1, should be
power of 2 as only one promisc entry is available for the interface. Key
mask is modified such that incoming packets from channel base to channel
count are directed to the same pci function.

Signed-off-by: Nalla, Pradeep <pnalla@marvell.com>
Signed-off-by: Naveen Mamindlapalli <naveenm@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
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 e6517a6..baaba01 100644 (file)
@@ -646,7 +646,8 @@ int npc_config_ts_kpuaction(struct rvu *rvu, int pf, u16 pcifunc, bool en);
 void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
                                 int nixlf, u64 chan, u8 *mac_addr);
 void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
-                                  int nixlf, u64 chan, bool allmulti);
+                                  int nixlf, u64 chan, u8 chan_cnt,
+                                  bool allmulti);
 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,
index d300019..f2a1c42 100644 (file)
@@ -273,7 +273,8 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
                pfvf->rx_chan_cnt = 1;
                pfvf->tx_chan_cnt = 1;
                rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
-                                             pfvf->rx_chan_base, false);
+                                             pfvf->rx_chan_base,
+                                             pfvf->rx_chan_cnt, false);
                break;
        }
 
@@ -3088,7 +3089,8 @@ int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,
                rvu_npc_disable_promisc_entry(rvu, pcifunc, nixlf);
        else
                rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
-                                             pfvf->rx_chan_base, allmulti);
+                                             pfvf->rx_chan_base,
+                                             pfvf->rx_chan_cnt, allmulti);
        return 0;
 }
 
index 80b90a4..73b430c 100644 (file)
@@ -647,13 +647,15 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
 }
 
 void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
-                                  int nixlf, u64 chan, bool allmulti)
+                                  int nixlf, u64 chan, u8 chan_cnt,
+                                  bool allmulti)
 {
        struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
        struct npc_mcam *mcam = &rvu->hw->mcam;
        int blkaddr, ucast_idx, index, kwi;
        struct mcam_entry entry = { {0} };
        struct nix_rx_action action = { };
+       u64 relaxed_mask;
 
        /* Only PF or AF VF can add a promiscuous entry */
        if ((pcifunc & RVU_PFVF_FUNC_MASK) && !is_afvf(pcifunc))
@@ -669,6 +671,16 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
        entry.kw[0] = chan;
        entry.kw_mask[0] = 0xFFFULL;
 
+       if (chan_cnt > 1) {
+               if (!is_power_of_2(chan_cnt)) {
+                       dev_err(rvu->dev, "channel count more than 1, must be power of 2\n");
+                       return;
+               }
+               relaxed_mask = GENMASK_ULL(BITS_PER_LONG_LONG - 1,
+                                          ilog2(chan_cnt));
+               entry.kw_mask[0] &= relaxed_mask;
+       }
+
        if (allmulti) {
                kwi = NPC_KEXOF_DMAC / sizeof(u64);
                entry.kw[kwi] = BIT_ULL(40); /* LSB bit of 1st byte in DMAC */