From 1bf6746e653b5f31dbd64bbcea572ebfadc1c8cb Mon Sep 17 00:00:00 2001 From: Jerin Jacob Date: Tue, 6 Apr 2021 20:11:16 +0530 Subject: [PATCH] common/cnxk: support NIX RSS 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 Acked-by: Nithin Dabilpuram --- drivers/common/cnxk/meson.build | 1 + drivers/common/cnxk/roc_nix.h | 17 +++ drivers/common/cnxk/roc_nix_rss.c | 220 ++++++++++++++++++++++++++++++ drivers/common/cnxk/version.map | 7 + 4 files changed, 245 insertions(+) create mode 100644 drivers/common/cnxk/roc_nix_rss.c diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build index f216d4aad2..f6a8880b8d 100644 --- a/drivers/common/cnxk/meson.build +++ b/drivers/common/cnxk/meson.build @@ -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', diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h index 1c097cb1a8..83388ce77d 100644 --- a/drivers/common/cnxk/roc_nix.h +++ b/drivers/common/cnxk/roc_nix.h @@ -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 index 0000000000..2d7b84adf6 --- /dev/null +++ b/drivers/common/cnxk/roc_nix_rss.c @@ -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; +} diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index a0df26a8e8..3196738c82 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -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; -- 2.20.1