6b7fcb7a5d
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>
264 lines
6.1 KiB
C
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;
|
|
}
|