common/cnxk: support NIX RSS
authorJerin Jacob <jerinj@marvell.com>
Tue, 6 Apr 2021 14:41:16 +0000 (20:11 +0530)
committerJerin Jacob <jerinj@marvell.com>
Fri, 9 Apr 2021 06:32:24 +0000 (08:32 +0200)
Add API's for default/non-default reta table setup,
key set/get, and flow algo setup for CN9K and CN10K.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
drivers/common/cnxk/meson.build
drivers/common/cnxk/roc_nix.h
drivers/common/cnxk/roc_nix_rss.c [new file with mode: 0644]
drivers/common/cnxk/version.map

index f216d4a..f6a8880 100644 (file)
@@ -21,6 +21,7 @@ sources = files('roc_dev.c',
                'roc_nix_mcast.c',
                'roc_nix_npc.c',
                'roc_nix_queue.c',
+               'roc_nix_rss.c',
                'roc_npa.c',
                'roc_npa_debug.c',
                'roc_npa_irq.c',
index 1c097cb..83388ce 100644 (file)
@@ -215,6 +215,23 @@ int __roc_api roc_nix_npc_rx_ena_dis(struct roc_nix *roc_nix, bool enable);
 int __roc_api roc_nix_npc_mcast_config(struct roc_nix *roc_nix,
                                       bool mcast_enable, bool prom_enable);
 
+/* RSS */
+void __roc_api roc_nix_rss_key_default_fill(struct roc_nix *roc_nix,
+                                           uint8_t key[ROC_NIX_RSS_KEY_LEN]);
+void __roc_api roc_nix_rss_key_set(struct roc_nix *roc_nix,
+                                  const uint8_t key[ROC_NIX_RSS_KEY_LEN]);
+void __roc_api roc_nix_rss_key_get(struct roc_nix *roc_nix,
+                                  uint8_t key[ROC_NIX_RSS_KEY_LEN]);
+int __roc_api roc_nix_rss_reta_set(struct roc_nix *roc_nix, uint8_t group,
+                                  uint16_t reta[ROC_NIX_RSS_RETA_MAX]);
+int __roc_api roc_nix_rss_reta_get(struct roc_nix *roc_nix, uint8_t group,
+                                  uint16_t reta[ROC_NIX_RSS_RETA_MAX]);
+int __roc_api roc_nix_rss_flowkey_set(struct roc_nix *roc_nix, uint8_t *alg_idx,
+                                     uint32_t flowkey, uint8_t group,
+                                     int mcam_index);
+int __roc_api roc_nix_rss_default_setup(struct roc_nix *roc_nix,
+                                       uint32_t flowkey);
+
 /* Queue */
 int __roc_api roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq,
                              bool ena);
diff --git a/drivers/common/cnxk/roc_nix_rss.c b/drivers/common/cnxk/roc_nix_rss.c
new file mode 100644 (file)
index 0000000..2d7b84a
--- /dev/null
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+void
+roc_nix_rss_key_default_fill(struct roc_nix *roc_nix,
+                            uint8_t key[ROC_NIX_RSS_KEY_LEN])
+{
+       PLT_SET_USED(roc_nix);
+       const uint8_t default_key[ROC_NIX_RSS_KEY_LEN] = {
+               0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED,
+               0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
+               0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED,
+               0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
+               0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD};
+
+       memcpy(key, default_key, ROC_NIX_RSS_KEY_LEN);
+}
+
+void
+roc_nix_rss_key_set(struct roc_nix *roc_nix,
+                   const uint8_t key[ROC_NIX_RSS_KEY_LEN])
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       const uint64_t *keyptr;
+       uint64_t val;
+       uint32_t idx;
+
+       keyptr = (const uint64_t *)key;
+       for (idx = 0; idx < (ROC_NIX_RSS_KEY_LEN >> 3); idx++) {
+               val = plt_cpu_to_be_64(keyptr[idx]);
+               plt_write64(val, nix->base + NIX_LF_RX_SECRETX(idx));
+       }
+}
+
+void
+roc_nix_rss_key_get(struct roc_nix *roc_nix, uint8_t key[ROC_NIX_RSS_KEY_LEN])
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       uint64_t *keyptr = (uint64_t *)key;
+       uint64_t val;
+       uint32_t idx;
+
+       for (idx = 0; idx < (ROC_NIX_RSS_KEY_LEN >> 3); idx++) {
+               val = plt_read64(nix->base + NIX_LF_RX_SECRETX(idx));
+               keyptr[idx] = plt_be_to_cpu_64(val);
+       }
+}
+
+static int
+nix_cn9k_rss_reta_set(struct nix *nix, uint8_t group,
+                     uint16_t reta[ROC_NIX_RSS_RETA_MAX])
+{
+       struct mbox *mbox = (&nix->dev)->mbox;
+       struct nix_aq_enq_req *req;
+       uint16_t idx;
+       int rc;
+
+       for (idx = 0; idx < nix->reta_sz; idx++) {
+               req = mbox_alloc_msg_nix_aq_enq(mbox);
+               if (!req) {
+                       /* The shared memory buffer can be full.
+                        * Flush it and retry
+                        */
+                       rc = mbox_process(mbox);
+                       if (rc < 0)
+                               return rc;
+                       req = mbox_alloc_msg_nix_aq_enq(mbox);
+                       if (!req)
+                               return NIX_ERR_NO_MEM;
+               }
+               req->rss.rq = reta[idx];
+               /* Fill AQ info */
+               req->qidx = (group * nix->reta_sz) + idx;
+               req->ctype = NIX_AQ_CTYPE_RSS;
+               req->op = NIX_AQ_INSTOP_INIT;
+       }
+
+       rc = mbox_process(mbox);
+       if (rc < 0)
+               return rc;
+
+       return 0;
+}
+
+static int
+nix_rss_reta_set(struct nix *nix, uint8_t group,
+                uint16_t reta[ROC_NIX_RSS_RETA_MAX])
+{
+       struct mbox *mbox = (&nix->dev)->mbox;
+       struct nix_cn10k_aq_enq_req *req;
+       uint16_t idx;
+       int rc;
+
+       for (idx = 0; idx < nix->reta_sz; idx++) {
+               req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+               if (!req) {
+                       /* The shared memory buffer can be full.
+                        * Flush it and retry
+                        */
+                       rc = mbox_process(mbox);
+                       if (rc < 0)
+                               return rc;
+                       req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+                       if (!req)
+                               return NIX_ERR_NO_MEM;
+               }
+               req->rss.rq = reta[idx];
+               /* Fill AQ info */
+               req->qidx = (group * nix->reta_sz) + idx;
+               req->ctype = NIX_AQ_CTYPE_RSS;
+               req->op = NIX_AQ_INSTOP_INIT;
+       }
+
+       rc = mbox_process(mbox);
+       if (rc < 0)
+               return rc;
+
+       return 0;
+}
+
+int
+roc_nix_rss_reta_set(struct roc_nix *roc_nix, uint8_t group,
+                    uint16_t reta[ROC_NIX_RSS_RETA_MAX])
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       int rc;
+
+       if (group >= ROC_NIX_RSS_GRPS)
+               return NIX_ERR_PARAM;
+
+       if (roc_model_is_cn9k())
+               rc = nix_cn9k_rss_reta_set(nix, group, reta);
+       else
+               rc = nix_rss_reta_set(nix, group, reta);
+       if (rc)
+               return rc;
+
+       memcpy(&nix->reta[group], reta, ROC_NIX_RSS_RETA_MAX);
+       return 0;
+}
+
+int
+roc_nix_rss_reta_get(struct roc_nix *roc_nix, uint8_t group,
+                    uint16_t reta[ROC_NIX_RSS_RETA_MAX])
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+
+       if (group >= ROC_NIX_RSS_GRPS)
+               return NIX_ERR_PARAM;
+
+       memcpy(reta, &nix->reta[group], ROC_NIX_RSS_RETA_MAX);
+       return 0;
+}
+
+int
+roc_nix_rss_flowkey_set(struct roc_nix *roc_nix, uint8_t *alg_idx,
+                       uint32_t flowkey, uint8_t group, int mcam_index)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       struct nix_rss_flowkey_cfg_rsp *rss_rsp;
+       struct mbox *mbox = (&nix->dev)->mbox;
+       struct nix_rss_flowkey_cfg *cfg;
+       int rc = -ENOSPC;
+
+       if (group >= ROC_NIX_RSS_GRPS)
+               return NIX_ERR_PARAM;
+
+       cfg = mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
+       if (cfg == NULL)
+               return rc;
+       cfg->flowkey_cfg = flowkey;
+       cfg->mcam_index = mcam_index; /* -1 indicates default group */
+       cfg->group = group;           /* 0 is default group */
+       rc = mbox_process_msg(mbox, (void *)&rss_rsp);
+       if (rc)
+               return rc;
+       if (alg_idx)
+               *alg_idx = rss_rsp->alg_idx;
+
+       return rc;
+}
+
+int
+roc_nix_rss_default_setup(struct roc_nix *roc_nix, uint32_t flowkey)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       uint16_t idx, qcnt = nix->nb_rx_queues;
+       uint16_t reta[ROC_NIX_RSS_RETA_MAX];
+       uint8_t key[ROC_NIX_RSS_KEY_LEN];
+       uint8_t alg_idx;
+       int rc;
+
+       roc_nix_rss_key_default_fill(roc_nix, key);
+       roc_nix_rss_key_set(roc_nix, key);
+
+       /* Update default RSS RETA */
+       for (idx = 0; idx < nix->reta_sz; idx++)
+               reta[idx] = idx % qcnt;
+       rc = roc_nix_rss_reta_set(roc_nix, 0, reta);
+       if (rc) {
+               plt_err("Failed to set RSS reta table rc=%d", rc);
+               goto fail;
+       }
+
+       /* Update the default flowkey */
+       rc = roc_nix_rss_flowkey_set(roc_nix, &alg_idx, flowkey,
+                                    ROC_NIX_RSS_GROUP_DEFAULT, -1);
+       if (rc) {
+               plt_err("Failed to set RSS flowkey rc=%d", rc);
+               goto fail;
+       }
+
+       nix->rss_alg_idx = alg_idx;
+fail:
+       return rc;
+}
index a0df26a..3196738 100644 (file)
@@ -62,6 +62,13 @@ INTERNAL {
        roc_nix_rq_fini;
        roc_nix_rq_init;
        roc_nix_rq_modify;
+       roc_nix_rss_default_setup;
+       roc_nix_rss_flowkey_set;
+       roc_nix_rss_key_default_fill;
+       roc_nix_rss_key_get;
+       roc_nix_rss_key_set;
+       roc_nix_rss_reta_get;
+       roc_nix_rss_reta_set;
        roc_nix_rx_queue_intr_disable;
        roc_nix_rx_queue_intr_enable;
        roc_nix_sq_fini;