octeontx2-af: Support for NIXLF's UCAST/PROMISC/ALLMULTI modes
authorSunil Goutham <sgoutham@marvell.com>
Mon, 22 Oct 2018 17:56:04 +0000 (23:26 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 23 Oct 2018 03:15:38 +0000 (20:15 -0700)
By default NIXLF is set in UCAST mode. This patch adds a new
mailbox message which when sent by a RVU PF changes this default
mode. When promiscuous mode is needed, the reserved promisc entry
for each of RVU PF is setup to match against ingress channel number
only, so that all pkts on that channel are accepted and forwarded
to the mode change requesting PF_FUNC's NIXLF.

PROMISC and ALLMULTI modes are supported only for PFs, for VFs only
UCAST mode is supported.

Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
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 afa2ead929a987fc3e91121e36b3461000fcdf10..a15a59c9a2397ac5176b63eb73249065ad6868a3 100644 (file)
@@ -159,7 +159,8 @@ M(NIX_TXSCHQ_CFG,   0x8006, nix_txschq_config, msg_rsp)             \
 M(NIX_STATS_RST,       0x8007, msg_req, msg_rsp)                       \
 M(NIX_VTAG_CFG,        0x8008, nix_vtag_config, msg_rsp)               \
 M(NIX_RSS_FLOWKEY_CFG,  0x8009, nix_rss_flowkey_cfg, msg_rsp)          \
-M(NIX_SET_MAC_ADDR,    0x800a, nix_set_mac_addr, msg_rsp)
+M(NIX_SET_MAC_ADDR,    0x800a, nix_set_mac_addr, msg_rsp)              \
+M(NIX_SET_RX_MODE,     0x800b, nix_rx_mode, msg_rsp)
 
 /* Messages initiated by AF (range 0xC00 - 0xDFF) */
 #define MBOX_UP_CGX_MESSAGES                                           \
@@ -513,4 +514,12 @@ struct nix_set_mac_addr {
        u8 mac_addr[ETH_ALEN]; /* MAC address to be set for this pcifunc */
 };
 
+struct nix_rx_mode {
+       struct mbox_msghdr hdr;
+#define NIX_RX_MODE_UCAST      BIT(0)
+#define NIX_RX_MODE_PROMISC    BIT(1)
+#define NIX_RX_MODE_ALLMULTI   BIT(2)
+       u16     mode;
+};
+
 #endif /* MBOX_H */
index 93e68915a63c8d0c490e99e98a167f718e008e96..2c0580cd28078a8741902667c86e9b80efca5a91 100644 (file)
@@ -347,6 +347,8 @@ int rvu_mbox_handler_NIX_RSS_FLOWKEY_CFG(struct rvu *rvu,
 int rvu_mbox_handler_NIX_SET_MAC_ADDR(struct rvu *rvu,
                                      struct nix_set_mac_addr *req,
                                      struct msg_rsp *rsp);
+int rvu_mbox_handler_NIX_SET_RX_MODE(struct rvu *rvu, struct nix_rx_mode *req,
+                                    struct msg_rsp *rsp);
 
 /* NPC APIs */
 int rvu_npc_init(struct rvu *rvu);
@@ -355,6 +357,9 @@ int rvu_npc_get_pkind(struct rvu *rvu, u16 pf);
 void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf);
 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);
+void rvu_npc_disable_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_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
index 3caf81bbf2f25b34a6848209214a89dc070f8790..8890c95831ca70aef73ed45ee931744ba64cc5fc 100644 (file)
@@ -1745,6 +1745,39 @@ int rvu_mbox_handler_NIX_SET_MAC_ADDR(struct rvu *rvu,
        return 0;
 }
 
+int rvu_mbox_handler_NIX_SET_RX_MODE(struct rvu *rvu, struct nix_rx_mode *req,
+                                    struct msg_rsp *rsp)
+{
+       bool allmulti = false, disable_promisc = false;
+       struct rvu_hwinfo *hw = rvu->hw;
+       u16 pcifunc = req->hdr.pcifunc;
+       struct rvu_pfvf *pfvf;
+       int blkaddr, nixlf;
+
+       pfvf = rvu_get_pfvf(rvu, pcifunc);
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+       if (!pfvf->nixlf || blkaddr < 0)
+               return NIX_AF_ERR_AF_LF_INVALID;
+
+       nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
+       if (nixlf < 0)
+               return NIX_AF_ERR_AF_LF_INVALID;
+
+       if (req->mode & NIX_RX_MODE_PROMISC)
+               allmulti = false;
+       else if (req->mode & NIX_RX_MODE_ALLMULTI)
+               allmulti = true;
+       else
+               disable_promisc = true;
+
+       if (disable_promisc)
+               rvu_npc_disable_promisc_entry(rvu, pcifunc, nixlf);
+       else
+               rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
+                                             pfvf->rx_chan_base, allmulti);
+       return 0;
+}
+
 static int nix_calibrate_x2p(struct rvu *rvu, int blkaddr)
 {
        int idx, err;
index a22eeb8af4ad3c8567a1dfd7d76a6bee3c5e5acc..23ff47f7efc56563ac12a2c586693502db45f562 100644 (file)
@@ -310,6 +310,61 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
                              NIX_INTF_RX, &entry, true);
 }
 
+void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
+                                  int nixlf, u64 chan, bool allmulti)
+{
+       struct npc_mcam *mcam = &rvu->hw->mcam;
+       struct mcam_entry entry = { {0} };
+       struct nix_rx_action action;
+       int blkaddr, index, kwi;
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
+       if (blkaddr < 0)
+               return;
+
+       /* Only PF or AF VF can add a promiscuous entry */
+       if (pcifunc & RVU_PFVF_FUNC_MASK)
+               return;
+
+       index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+                                        nixlf, NIXLF_PROMISC_ENTRY);
+
+       entry.kw[0] = chan;
+       entry.kw_mask[0] = 0xFFFULL;
+
+       if (allmulti) {
+               kwi = NPC_PARSE_RESULT_DMAC_OFFSET / sizeof(u64);
+               entry.kw[kwi] = BIT_ULL(40); /* LSB bit of 1st byte in DMAC */
+               entry.kw_mask[kwi] = BIT_ULL(40);
+       }
+
+       *(u64 *)&action = 0x00;
+       action.op = NIX_RX_ACTIONOP_UCAST;
+       action.pf_func = pcifunc;
+
+       entry.action = *(u64 *)&action;
+       npc_config_mcam_entry(rvu, mcam, blkaddr, index,
+                             NIX_INTF_RX, &entry, true);
+}
+
+void rvu_npc_disable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf)
+{
+       struct npc_mcam *mcam = &rvu->hw->mcam;
+       int blkaddr, index;
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
+       if (blkaddr < 0)
+               return;
+
+       /* Only PF's have a promiscuous entry */
+       if (pcifunc & RVU_PFVF_FUNC_MASK)
+               return;
+
+       index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+                                        nixlf, NIXLF_PROMISC_ENTRY);
+       npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
+}
+
 void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
                                       int nixlf, u64 chan)
 {
@@ -431,6 +486,8 @@ void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
                                     NPC_AF_MCAMEX_BANKX_ACTION(index, bank));
                if (action.op != NIX_RX_ACTIONOP_MCAST)
                        npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
+
+               rvu_npc_disable_promisc_entry(rvu, pcifunc, nixlf);
        }
 }