]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
octeontx2-af: NPC MCAM and LDATA extract minimal configuration
authorSunil Goutham <sgoutham@marvell.com>
Mon, 22 Oct 2018 17:55:58 +0000 (23:25 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 23 Oct 2018 03:15:38 +0000 (20:15 -0700)
This patch adds some minimal configuration for NPC MCAM and
LDATA extraction which is sufficient enough to install
ucast/bcast/promiscuous forwarding rules. Below is the
config done
- LDATA extraction config to extract DMAC from pkt
  to offset 64bit in MCAM search key.
- Set MCAM lookup keysize to 224bits
- Set MCAM TX miss action to UCAST_DEFAULT
- Set MCAM RX miss action to DROP

Also inorder to have guaranteed space in MCAM to install
ucast forwarding rule for each of RVU PF/VF, reserved
one MCAM entry for each of NIXLF for ucast rule. And two
entries for each of RVU PF. One for bcast pkt replication
and other for promiscuous mode which allows all pkts
received on a HW CGX/LBK channel.

Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/common.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 7c53ba3545f1f5577d9f8be781de6cbc1d607183..e438f926e32a79e07b7ad70dd39a7deb6f37efd8 100644 (file)
@@ -143,6 +143,27 @@ enum nix_scheduler {
        NIX_TXSCH_LVL_CNT = 0x5,
 };
 
+/* NIX RX action operation*/
+#define NIX_RX_ACTIONOP_DROP           (0x0ull)
+#define NIX_RX_ACTIONOP_UCAST          (0x1ull)
+#define NIX_RX_ACTIONOP_UCAST_IPSEC    (0x2ull)
+#define NIX_RX_ACTIONOP_MCAST          (0x3ull)
+#define NIX_RX_ACTIONOP_RSS            (0x4ull)
+
+/* NIX TX action operation*/
+#define NIX_TX_ACTIONOP_DROP           (0x0ull)
+#define NIX_TX_ACTIONOP_UCAST_DEFAULT  (0x1ull)
+#define NIX_TX_ACTIONOP_UCAST_CHAN     (0x2ull)
+#define NIX_TX_ACTIONOP_MCAST          (0x3ull)
+#define NIX_TX_ACTIONOP_DROP_VIOL      (0x5ull)
+
+#define NPC_MCAM_KEY_X1                        0
+#define NPC_MCAM_KEY_X2                        1
+#define NPC_MCAM_KEY_X4                        2
+
+#define NIX_INTF_RX                    0
+#define NIX_INTF_TX                    1
+
 #define NIX_INTF_TYPE_CGX              0
 #define NIX_INTF_TYPE_LBK              1
 
index 1e85e80d28fd4a10ad8951c462d507f2cfb26cca..9fa5183226ebf0049edaa71871328736083a538e 100644 (file)
@@ -73,6 +73,18 @@ struct nix_mce_list {
        int                     max;
 };
 
+struct npc_mcam {
+       spinlock_t      lock;   /* MCAM entries and counters update lock */
+       u8      keysize;        /* MCAM keysize 112/224/448 bits */
+       u8      banks;          /* Number of MCAM banks */
+       u8      banks_per_entry;/* Number of keywords in key */
+       u16     banksize;       /* Number of MCAM entries in each bank */
+       u16     total_entries;  /* Total number of MCAM entries */
+       u16     entries;        /* Total minus reserved for NIX LFs */
+       u16     nixlf_offset;   /* Offset of nixlf rsvd uncast entries */
+       u16     pf_offset;      /* Offset of PF's rsvd bcast, promisc entries */
+};
+
 /* Structure for per RVU func info ie PF/VF */
 struct rvu_pfvf {
        bool            npalf; /* Only one NPALF per RVU_FUNC */
@@ -144,6 +156,7 @@ struct rvu_hwinfo {
        struct rvu_block block[BLK_COUNT]; /* Block info */
        struct nix_hw    *nix0;
        struct npc_pkind pkind;
+       struct npc_mcam  mcam;
 };
 
 struct rvu {
@@ -297,6 +310,7 @@ int rvu_mbox_handler_NPA_LF_FREE(struct rvu *rvu, struct msg_req *req,
 /* NIX APIs */
 int rvu_nix_init(struct rvu *rvu);
 void rvu_nix_freemem(struct rvu *rvu);
+int rvu_get_nixlf_count(struct rvu *rvu);
 int rvu_mbox_handler_NIX_LF_ALLOC(struct rvu *rvu,
                                  struct nix_lf_alloc_req *req,
                                  struct nix_lf_alloc_rsp *rsp);
index 02e1d16cf670001e96e9520ea4e8318a1631fdeb..55075e7cb749dc8e5d696298eefbb7c30f596cf2 100644 (file)
@@ -55,6 +55,18 @@ struct mce {
        u16                     pcifunc;
 };
 
+int rvu_get_nixlf_count(struct rvu *rvu)
+{
+       struct rvu_block *block;
+       int blkaddr;
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
+       if (blkaddr < 0)
+               return 0;
+       block = &rvu->hw->block[blkaddr];
+       return block->lf.max;
+}
+
 static void nix_mce_list_init(struct nix_mce_list *list, int max)
 {
        INIT_HLIST_HEAD(&list->head);
index cc1d8c9e8495afb65ca558fbb4c86f7db0e5c0b1..1c294363c4b07f4a2020913bb299d786f653ed21 100644 (file)
 #include "npc.h"
 #include "npc_profile.h"
 
+#define RSVD_MCAM_ENTRIES_PER_PF       2 /* Bcast & Promisc */
+#define RSVD_MCAM_ENTRIES_PER_NIXLF    1 /* Ucast for LFs */
+
+#define NIXLF_UCAST_ENTRY      0
+#define NIXLF_BCAST_ENTRY      1
+#define NIXLF_PROMISC_ENTRY    2
+
+#define NPC_PARSE_RESULT_DMAC_OFFSET   8
+
 void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf)
 {
        int blkaddr;
@@ -45,6 +54,53 @@ int rvu_npc_get_pkind(struct rvu *rvu, u16 pf)
        return -1;
 }
 
+#define LDATA_EXTRACT_CONFIG(intf, lid, ltype, ld, cfg) \
+       rvu_write64(rvu, blkaddr,                       \
+               NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, ltype, ld), cfg)
+
+#define LDATA_FLAGS_CONFIG(intf, ld, flags, cfg)       \
+       rvu_write64(rvu, blkaddr,                       \
+               NPC_AF_INTFX_LDATAX_FLAGSX_CFG(intf, ld, flags), cfg)
+
+static void npc_config_ldata_extract(struct rvu *rvu, int blkaddr)
+{
+       struct npc_mcam *mcam = &rvu->hw->mcam;
+       int lid, ltype;
+       int lid_count;
+       u64 cfg;
+
+       cfg = rvu_read64(rvu, blkaddr, NPC_AF_CONST);
+       lid_count = (cfg >> 4) & 0xF;
+
+       /* First clear any existing config i.e
+        * disable LDATA and FLAGS extraction.
+        */
+       for (lid = 0; lid < lid_count; lid++) {
+               for (ltype = 0; ltype < 16; ltype++) {
+                       LDATA_EXTRACT_CONFIG(NIX_INTF_RX, lid, ltype, 0, 0ULL);
+                       LDATA_EXTRACT_CONFIG(NIX_INTF_RX, lid, ltype, 1, 0ULL);
+                       LDATA_EXTRACT_CONFIG(NIX_INTF_TX, lid, ltype, 0, 0ULL);
+                       LDATA_EXTRACT_CONFIG(NIX_INTF_TX, lid, ltype, 1, 0ULL);
+
+                       LDATA_FLAGS_CONFIG(NIX_INTF_RX, 0, ltype, 0ULL);
+                       LDATA_FLAGS_CONFIG(NIX_INTF_RX, 1, ltype, 0ULL);
+                       LDATA_FLAGS_CONFIG(NIX_INTF_TX, 0, ltype, 0ULL);
+                       LDATA_FLAGS_CONFIG(NIX_INTF_TX, 1, ltype, 0ULL);
+               }
+       }
+
+       /* If we plan to extract Outer IPv4 tuple for TCP/UDP pkts
+        * then 112bit key is not sufficient
+        */
+       if (mcam->keysize != NPC_MCAM_KEY_X2)
+               return;
+
+       /* Start placing extracted data/flags from 64bit onwards, for now */
+       /* Extract DMAC from the packet */
+       cfg = (0x05 << 16) | BIT_ULL(7) | NPC_PARSE_RESULT_DMAC_OFFSET;
+       LDATA_EXTRACT_CONFIG(NIX_INTF_RX, NPC_LID_LA, NPC_LT_LA_ETHER, 0, cfg);
+}
+
 static void npc_config_kpuaction(struct rvu *rvu, int blkaddr,
                                 struct npc_kpu_profile_action *kpuaction,
                                 int kpu, int entry, bool pkind)
@@ -193,9 +249,61 @@ static void npc_parser_profile_init(struct rvu *rvu, int blkaddr)
                                        idx, &npc_kpu_profiles[idx]);
 }
 
+static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
+{
+       int nixlf_count = rvu_get_nixlf_count(rvu);
+       struct npc_mcam *mcam = &rvu->hw->mcam;
+       int rsvd;
+       u64 cfg;
+
+       /* Get HW limits */
+       cfg = rvu_read64(rvu, blkaddr, NPC_AF_CONST);
+       mcam->banks = (cfg >> 44) & 0xF;
+       mcam->banksize = (cfg >> 28) & 0xFFFF;
+
+       /* Actual number of MCAM entries vary by entry size */
+       cfg = (rvu_read64(rvu, blkaddr,
+                         NPC_AF_INTFX_KEX_CFG(0)) >> 32) & 0x07;
+       mcam->total_entries = (mcam->banks / BIT_ULL(cfg)) * mcam->banksize;
+       mcam->keysize = cfg;
+
+       /* Number of banks combined per MCAM entry */
+       if (cfg == NPC_MCAM_KEY_X4)
+               mcam->banks_per_entry = 4;
+       else if (cfg == NPC_MCAM_KEY_X2)
+               mcam->banks_per_entry = 2;
+       else
+               mcam->banks_per_entry = 1;
+
+       /* Reserve one MCAM entry for each of the NIX LF to
+        * guarantee space to install default matching DMAC rule.
+        * Also reserve 2 MCAM entries for each PF for default
+        * channel based matching or 'bcast & promisc' matching to
+        * support BCAST and PROMISC modes of operation for PFs.
+        * PF0 is excluded.
+        */
+       rsvd = (nixlf_count * RSVD_MCAM_ENTRIES_PER_NIXLF) +
+               ((rvu->hw->total_pfs - 1) * RSVD_MCAM_ENTRIES_PER_PF);
+       if (mcam->total_entries <= rsvd) {
+               dev_warn(rvu->dev,
+                        "Insufficient NPC MCAM size %d for pkt I/O, exiting\n",
+                        mcam->total_entries);
+               return -ENOMEM;
+       }
+
+       mcam->entries = mcam->total_entries - rsvd;
+       mcam->nixlf_offset = mcam->entries;
+       mcam->pf_offset = mcam->nixlf_offset + nixlf_count;
+
+       spin_lock_init(&mcam->lock);
+
+       return 0;
+}
+
 int rvu_npc_init(struct rvu *rvu)
 {
        struct npc_pkind *pkind = &rvu->hw->pkind;
+       u64 keyz = NPC_MCAM_KEY_X2;
        int blkaddr, err;
 
        blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
@@ -234,6 +342,32 @@ int rvu_npc_init(struct rvu *rvu)
                    rvu_read64(rvu, blkaddr, NPC_AF_PCK_CFG) |
                    BIT_ULL(6) | BIT_ULL(2));
 
+       /* Set RX and TX side MCAM search key size.
+        * Also enable parse key extract nibbles suchthat except
+        * layer E to H, rest of the key is included for MCAM search.
+        */
+       rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX),
+                   ((keyz & 0x3) << 32) | ((1ULL << 20) - 1));
+       rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_TX),
+                   ((keyz & 0x3) << 32) | ((1ULL << 20) - 1));
+
+       err = npc_mcam_rsrcs_init(rvu, blkaddr);
+       if (err)
+               return err;
+
+       /* Config packet data and flags extraction into PARSE result */
+       npc_config_ldata_extract(rvu, blkaddr);
+
+       /* Set TX miss action to UCAST_DEFAULT i.e
+        * transmit the packet on NIX LF SQ's default channel.
+        */
+       rvu_write64(rvu, blkaddr, NPC_AF_INTFX_MISS_ACT(NIX_INTF_TX),
+                   NIX_TX_ACTIONOP_UCAST_DEFAULT);
+
+       /* If MCAM lookup doesn't result in a match, drop the received packet */
+       rvu_write64(rvu, blkaddr, NPC_AF_INTFX_MISS_ACT(NIX_INTF_RX),
+                   NIX_RX_ACTIONOP_DROP);
+
        return 0;
 }