numam-dpdk/drivers/common/cnxk/roc_nix_rss.c
Satha Rao 6b7fcb7a5d common/cnxk: support locking NIX RQ contexts
This patch will consider device argument to lock RSS table
in NIX.

This patch also adds few misc fixes such as disabling NIX Tx
vlan insertion conf in SMQ, enabling SSO in NIX Tx SQ
for Tx completions and TM related stats API.

Signed-off-by: Satha Rao <skoteshwar@marvell.com>
2021-06-29 20:12:25 +02:00

264 lines
6.1 KiB
C

/* 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], uint8_t lock_rx_ctx)
{
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;
if (!lock_rx_ctx)
continue;
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_LOCK;
}
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], uint8_t lock_rx_ctx)
{
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;
if (!lock_rx_ctx)
continue;
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_LOCK;
}
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,
roc_nix->lock_rx_ctx);
else
rc = nix_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx);
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;
}