Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2024 Marvell.
*
*/
#ifndef CN20K_API_H
#define CN20K_API_H
#include "../rvu.h"
struct ng_rvu {
struct mbox_ops *rvu_mbox_ops;
struct qmem *pf_mbox_addr;
struct qmem *vf_mbox_addr;
};
/* Mbox related APIs */
int cn20k_rvu_mbox_init(struct rvu *rvu, int type, int num);
int cn20k_rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
int num, int type, unsigned long *pf_bmap);
void cn20k_free_mbox_memory(struct rvu *rvu);
int cn20k_register_afpf_mbox_intr(struct rvu *rvu);
int cn20k_register_afvf_mbox_intr(struct rvu *rvu, int pf_vec_start);
void cn20k_rvu_enable_mbox_intr(struct rvu *rvu);
void cn20k_rvu_unregister_interrupts(struct rvu *rvu);
int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev,
void *reg_base, int direction, int ndevs);
void cn20k_rvu_enable_afvf_intr(struct rvu *rvu, int vfs);
void cn20k_rvu_disable_afvf_intr(struct rvu *rvu, int vfs);
#endif /* CN20K_API_H */
@@ -0,0 +1,627 @@
// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2024 Marvell.
*
*/
#include <linux/fs.h>
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "struct.h"
#include "rvu.h"
#include "debugfs.h"
#include "cn20k/reg.h"
#include "cn20k/npc.h"
static int npc_mcam_layout_show(struct seq_file *s, void *unused)
{
int i, j, sbd, idx0, idx1, vidx0, vidx1;
struct npc_priv_t *npc_priv;
char buf0[32], buf1[32];
struct npc_subbank *sb;
unsigned int bw0, bw1;
bool v0, v1;
int pf1, pf2;
bool e0, e1;
void *map;
npc_priv = s->private;
sbd = npc_priv->subbank_depth;
for (i = npc_priv->num_subbanks - 1; i >= 0; i--) {
sb = &npc_priv->sb[i];
mutex_lock(&sb->lock);
if (sb->flags & NPC_SUBBANK_FLAG_FREE)
goto next;
bw0 = bitmap_weight(sb->b0map, npc_priv->subbank_depth);
if (sb->key_type == NPC_MCAM_KEY_X4) {
seq_printf(s, "\n\nsubbank:%u, x4, free=%u, used=%u\n",
sb->idx, sb->free_cnt, bw0);
for (j = sbd - 1; j >= 0; j--) {
if (!test_bit(j, sb->b0map))
continue;
idx0 = sb->b0b + j;
map = xa_load(&npc_priv->xa_idx2pf_map, idx0);
pf1 = xa_to_value(map);
map = xa_load(&npc_priv->xa_idx2vidx_map, idx0);
if (map) {
vidx0 = xa_to_value(map);
snprintf(buf0, sizeof(buf0),
"v:%u", vidx0);
}
seq_printf(s, "\t%u(%#x)%c %s\n", idx0, pf1,
test_bit(idx0, npc_priv->en_map) ? '+' : ' ',
map ? buf0 : " ");
}
goto next;
}
bw1 = bitmap_weight(sb->b1map, npc_priv->subbank_depth);
seq_printf(s, "\n\nsubbank:%u, x2, free=%u, used=%u\n",
sb->idx, sb->free_cnt, bw0 + bw1);
seq_printf(s, "bank1(%u)\t\tbank0(%u)\n", bw1, bw0);
for (j = sbd - 1; j >= 0; j--) {
e0 = test_bit(j, sb->b0map);
e1 = test_bit(j, sb->b1map);
if (!e1 && !e0)
continue;
if (e1 && e0) {
idx0 = sb->b0b + j;
map = xa_load(&npc_priv->xa_idx2pf_map, idx0);
pf1 = xa_to_value(map);
map = xa_load(&npc_priv->xa_idx2vidx_map, idx0);
v0 = !!map;
if (v0) {
vidx0 = xa_to_value(map);
snprintf(buf0, sizeof(buf0), "v:%05u",
vidx0);
}
idx1 = sb->b1b + j;
map = xa_load(&npc_priv->xa_idx2pf_map, idx1);
pf2 = xa_to_value(map);
map = xa_load(&npc_priv->xa_idx2vidx_map, idx1);
v1 = !!map;
if (v1) {
vidx1 = xa_to_value(map);
snprintf(buf1, sizeof(buf1), "v:%05u",
vidx1);
}
seq_printf(s, "%05u(%#x)%c %s\t\t%05u(%#x)%c %s\n",
idx1, pf2,
test_bit(idx1, npc_priv->en_map) ? '+' : ' ',
v1 ? buf1 : " ",
idx0, pf1,
test_bit(idx0, npc_priv->en_map) ? '+' : ' ',
v0 ? buf0 : " ");
continue;
}
if (e0) {
idx0 = sb->b0b + j;
map = xa_load(&npc_priv->xa_idx2pf_map, idx0);
pf1 = xa_to_value(map);
map = xa_load(&npc_priv->xa_idx2vidx_map, idx0);
if (map) {
vidx0 = xa_to_value(map);
snprintf(buf0, sizeof(buf0), "v:%05u",
vidx0);
}
seq_printf(s, "\t\t \t\t%05u(%#x)%c %s\n", idx0, pf1,
test_bit(idx0, npc_priv->en_map) ? '+' : ' ',
map ? buf0 : " ");
continue;
}
idx1 = sb->b1b + j;
map = xa_load(&npc_priv->xa_idx2pf_map, idx1);
pf1 = xa_to_value(map);
map = xa_load(&npc_priv->xa_idx2vidx_map, idx1);
if (map) {
vidx1 = xa_to_value(map);
snprintf(buf1, sizeof(buf1), "v:%05u", vidx1);
}
seq_printf(s, "%05u(%#x)%c %s\n", idx1, pf1,
test_bit(idx1, npc_priv->en_map) ? '+' : ' ',
map ? buf1 : " ");
}
next:
mutex_unlock(&sb->lock);
}
return 0;
}
DEFINE_SHOW_ATTRIBUTE(npc_mcam_layout);
#define __OCTEONTX2_DEBUGFS_ATTRIBUTE_FOPS(__name) \
static const struct file_operations __name ## _fops = { \
.owner = THIS_MODULE, \
.open = __name ## _open, \
.read = seq_read, \
.llseek = seq_lseek, \
.release = single_release, \
}
#define DEFINE_OCTEONTX2_DEBUGFS_ATTRIBUTE_WITH_SIZE(__name, __size) \
static int __name ## _open(struct inode *inode, struct file *file) \
{ \
return single_open_size(file, __name ## _show, inode->i_private, \
__size); \
} \
__OCTEONTX2_DEBUGFS_ATTRIBUTE_FOPS(__name)
static DEFINE_MUTEX(stats_lock);
/* MAX_NUM_BANKS, MAX_SUBBANK_DEPTH and MAX_NUM_SUB_BANKS represent
* hard limit on all silicon variants, preventing any possibility of
* out-of-bounds access.
*/
static u64 (*dstats)[MAX_NUM_BANKS][MAX_SUBBANK_DEPTH * MAX_NUM_SUB_BANKS];
static int npc_mcam_dstats_show(struct seq_file *s, void *unused)
{
struct npc_priv_t *npc_priv;
int blkaddr, pf, mcam_idx;
u64 stats, delta;
struct rvu *rvu;
char buff[64];
u8 key_type;
void *map;
npc_priv = npc_priv_get();
rvu = s->private;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return 0;
mutex_lock(&stats_lock);
seq_puts(s, "idx\tpfunc\tstats\n");
for (int bank = npc_priv->num_banks - 1; bank >= 0; bank--) {
for (int idx = npc_priv->bank_depth - 1; idx >= 0; idx--) {
mcam_idx = bank * npc_priv->bank_depth + idx;
if (npc_mcam_idx_2_key_type(rvu, mcam_idx, &key_type))
continue;
if (key_type == NPC_MCAM_KEY_X4 && bank != 0)
continue;
if (!test_bit(mcam_idx, npc_priv->en_map))
continue;
stats = rvu_read64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(idx, bank));
if (!stats)
continue;
if (stats == dstats[0][bank][idx])
continue;
if (stats < dstats[0][bank][idx])
dstats[0][bank][idx] = 0;
pf = 0xFFFF;
map = xa_load(&npc_priv->xa_idx2pf_map, mcam_idx);
if (map)
pf = xa_to_value(map);
delta = stats - dstats[0][bank][idx];
snprintf(buff, sizeof(buff), "%u\t%#04x\t%llu\n",
mcam_idx, pf, delta);
seq_puts(s, buff);
dstats[0][bank][idx] = stats;
}
}
mutex_unlock(&stats_lock);
return 0;
}
/* "%u\t%#04x\t%llu\n" needs less than 64 characters to print */
#define TOTAL_SZ (MAX_NUM_BANKS * MAX_NUM_SUB_BANKS * MAX_SUBBANK_DEPTH * 64)
DEFINE_OCTEONTX2_DEBUGFS_ATTRIBUTE_WITH_SIZE(npc_mcam_dstats, TOTAL_SZ);
static int npc_mcam_mismatch_show(struct seq_file *s, void *unused)
{
struct npc_priv_t *npc_priv;
struct npc_subbank *sb;
int mcam_idx, sb_off;
struct rvu *rvu;
char buff[64];
void *map;
int rc;
npc_priv = npc_priv_get();
rvu = s->private;
seq_puts(s, "index\tsb idx\tkw type\n");
for (int bank = npc_priv->num_banks - 1; bank >= 0; bank--) {
for (int idx = npc_priv->bank_depth - 1; idx >= 0; idx--) {
mcam_idx = bank * npc_priv->bank_depth + idx;
if (!test_bit(mcam_idx, npc_priv->en_map))
continue;
map = xa_load(&npc_priv->xa_idx2pf_map, mcam_idx);
if (map)
continue;
rc = npc_mcam_idx_2_subbank_idx(rvu, mcam_idx,
&sb, &sb_off);
if (rc)
continue;
snprintf(buff, sizeof(buff), "%u\t%d\t%u\n",
mcam_idx, sb->idx, sb->key_type);
seq_puts(s, buff);
}
}
return 0;
}
/* "%u\t%d\t%u\n" needs less than 64 characters to print. */
DEFINE_OCTEONTX2_DEBUGFS_ATTRIBUTE_WITH_SIZE(npc_mcam_mismatch, TOTAL_SZ);
static int npc_mcam_default_show(struct seq_file *s, void *unused)
{
struct npc_priv_t *npc_priv;
unsigned long index;
u16 ptr[4], pcifunc;
struct rvu *rvu;
int rc, i;
void *map;
npc_priv = npc_priv_get();
rvu = s->private;
seq_puts(s, "\npcifunc\tBcast\tmcast\tpromisc\tucast\n");
xa_for_each(&npc_priv->xa_pf_map, index, map) {
pcifunc = index;
for (i = 0; i < ARRAY_SIZE(ptr); i++)
ptr[i] = USHRT_MAX;
rc = npc_cn20k_dft_rules_idx_get(rvu, pcifunc, &ptr[0],
&ptr[1], &ptr[2], &ptr[3]);
if (rc)
continue;
seq_printf(s, "%#x\t", pcifunc);
for (i = 0; i < ARRAY_SIZE(ptr); i++) {
if (ptr[i] != USHRT_MAX)
seq_printf(s, "%u\t", ptr[i]);
else
seq_puts(s, "\t");
}
seq_puts(s, "\n");
}
return 0;
}
DEFINE_SHOW_ATTRIBUTE(npc_mcam_default);
static int npc_vidx2idx_map_show(struct seq_file *s, void *unused)
{
struct npc_priv_t *npc_priv;
unsigned long index, start;
struct xarray *xa;
void *map;
npc_priv = s->private;
start = npc_priv->bank_depth * 2;
xa = &npc_priv->xa_vidx2idx_map;
seq_puts(s, "\nvidx\tmcam_idx\n");
xa_for_each_start(xa, index, map, start)
seq_printf(s, "%lu\t%lu\n", index, xa_to_value(map));
return 0;
}
DEFINE_SHOW_ATTRIBUTE(npc_vidx2idx_map);
static int npc_idx2vidx_map_show(struct seq_file *s, void *unused)
{
struct npc_priv_t *npc_priv;
unsigned long index;
struct xarray *xa;
void *map;
npc_priv = s->private;
xa = &npc_priv->xa_idx2vidx_map;
seq_puts(s, "\nmidx\tvidx\n");
xa_for_each(xa, index, map)
seq_printf(s, "%lu\t%lu\n", index, xa_to_value(map));
return 0;
}
DEFINE_SHOW_ATTRIBUTE(npc_idx2vidx_map);
static int npc_defrag_show(struct seq_file *s, void *unused)
{
struct npc_defrag_show_node *node;
struct npc_priv_t *npc_priv;
u16 sbd, bdm;
npc_priv = s->private;
bdm = npc_priv->bank_depth - 1;
sbd = npc_priv->subbank_depth;
seq_puts(s, "\nold(sb) -> new(sb)\t\tvidx\n");
mutex_lock(&npc_priv->lock);
list_for_each_entry(node, &npc_priv->defrag_lh, list)
seq_printf(s, "%u(%u)\t%u(%u)\t%u\n", node->old_midx,
(node->old_midx & bdm) / sbd,
node->new_midx,
(node->new_midx & bdm) / sbd,
node->vidx);
mutex_unlock(&npc_priv->lock);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(npc_defrag);
int npc_cn20k_debugfs_init(struct rvu *rvu)
{
struct npc_priv_t *npc_priv = npc_priv_get();
debugfs_create_file("mcam_layout", 0444, rvu->rvu_dbg.npc,
npc_priv, &npc_mcam_layout_fops);
debugfs_create_file("mcam_default", 0444, rvu->rvu_dbg.npc,
rvu, &npc_mcam_default_fops);
debugfs_create_file("vidx2idx", 0444, rvu->rvu_dbg.npc,
npc_priv, &npc_vidx2idx_map_fops);
dstats = devm_kzalloc(rvu->dev, sizeof(*dstats), GFP_KERNEL);
if (!dstats)
return -ENOMEM;
debugfs_create_file("dstats", 0444, rvu->rvu_dbg.npc, rvu,
&npc_mcam_dstats_fops);
debugfs_create_file("mismatch", 0444, rvu->rvu_dbg.npc, rvu,
&npc_mcam_mismatch_fops);
debugfs_create_file("idx2vidx", 0444, rvu->rvu_dbg.npc,
npc_priv, &npc_idx2vidx_map_fops);
debugfs_create_file("defrag", 0444, rvu->rvu_dbg.npc,
npc_priv, &npc_defrag_fops);
return 0;
}
void npc_cn20k_debugfs_deinit(struct rvu *rvu)
{
debugfs_remove_recursive(rvu->rvu_dbg.npc);
}
void print_nix_cn20k_sq_ctx(struct seq_file *m,
struct nix_cn20k_sq_ctx_s *sq_ctx)
{
seq_printf(m, "W0: ena \t\t\t%d\nW0: qint_idx \t\t\t%d\n",
sq_ctx->ena, sq_ctx->qint_idx);
seq_printf(m, "W0: substream \t\t\t0x%03x\nW0: sdp_mcast \t\t\t%d\n",
sq_ctx->substream, sq_ctx->sdp_mcast);
seq_printf(m, "W0: cq \t\t\t\t%d\nW0: sqe_way_mask \t\t%d\n\n",
sq_ctx->cq, sq_ctx->sqe_way_mask);
seq_printf(m, "W1: smq \t\t\t%d\nW1: cq_ena \t\t\t%d\nW1: xoff\t\t\t%d\n",
sq_ctx->smq, sq_ctx->cq_ena, sq_ctx->xoff);
seq_printf(m, "W1: sso_ena \t\t\t%d\nW1: smq_rr_weight\t\t%d\n",
sq_ctx->sso_ena, sq_ctx->smq_rr_weight);
seq_printf(m, "W1: default_chan\t\t%d\nW1: sqb_count\t\t\t%d\n\n",
sq_ctx->default_chan, sq_ctx->sqb_count);
seq_printf(m, "W1: smq_rr_count_lb \t\t%d\n", sq_ctx->smq_rr_count_lb);
seq_printf(m, "W2: smq_rr_count_ub \t\t%d\n", sq_ctx->smq_rr_count_ub);
seq_printf(m, "W2: sqb_aura \t\t\t%d\nW2: sq_int \t\t\t%d\n",
sq_ctx->sqb_aura, sq_ctx->sq_int);
seq_printf(m, "W2: sq_int_ena \t\t\t%d\nW2: sqe_stype \t\t\t%d\n",
sq_ctx->sq_int_ena, sq_ctx->sqe_stype);
seq_printf(m, "W3: max_sqe_size\t\t%d\nW3: cq_limit\t\t\t%d\n",
sq_ctx->max_sqe_size, sq_ctx->cq_limit);
seq_printf(m, "W3: lmt_dis \t\t\t%d\nW3: mnq_dis \t\t\t%d\n",
sq_ctx->lmt_dis, sq_ctx->mnq_dis);
seq_printf(m, "W3: smq_next_sq\t\t\t%d\nW3: smq_lso_segnum\t\t%d\n",
sq_ctx->smq_next_sq, sq_ctx->smq_lso_segnum);
seq_printf(m, "W3: tail_offset \t\t%d\nW3: smenq_offset\t\t%d\n",
sq_ctx->tail_offset, sq_ctx->smenq_offset);
seq_printf(m, "W3: head_offset\t\t\t%d\nW3: smenq_next_sqb_vld\t\t%d\n\n",
sq_ctx->head_offset, sq_ctx->smenq_next_sqb_vld);
seq_printf(m, "W3: smq_next_sq_vld\t\t%d\nW3: smq_pend\t\t\t%d\n",
sq_ctx->smq_next_sq_vld, sq_ctx->smq_pend);
seq_printf(m, "W4: next_sqb \t\t\t%llx\n\n", sq_ctx->next_sqb);
seq_printf(m, "W5: tail_sqb \t\t\t%llx\n\n", sq_ctx->tail_sqb);
seq_printf(m, "W6: smenq_sqb \t\t\t%llx\n\n", sq_ctx->smenq_sqb);
seq_printf(m, "W7: smenq_next_sqb \t\t%llx\n\n",
sq_ctx->smenq_next_sqb);
seq_printf(m, "W8: head_sqb\t\t\t%llx\n\n", sq_ctx->head_sqb);
seq_printf(m, "W9: vfi_lso_total\t\t%d\n", sq_ctx->vfi_lso_total);
seq_printf(m, "W9: vfi_lso_sizem1\t\t%d\nW9: vfi_lso_sb\t\t\t%d\n",
sq_ctx->vfi_lso_sizem1, sq_ctx->vfi_lso_sb);
seq_printf(m, "W9: vfi_lso_mps\t\t\t%d\nW9: vfi_lso_vlan0_ins_ena\t%d\n",
sq_ctx->vfi_lso_mps, sq_ctx->vfi_lso_vlan0_ins_ena);
seq_printf(m, "W9: vfi_lso_vlan1_ins_ena\t%d\nW9: vfi_lso_vld \t\t%d\n\n",
sq_ctx->vfi_lso_vld, sq_ctx->vfi_lso_vlan1_ins_ena);
seq_printf(m, "W10: scm_lso_rem \t\t%llu\n\n",
(u64)sq_ctx->scm_lso_rem);
seq_printf(m, "W11: octs \t\t\t%llu\n\n", (u64)sq_ctx->octs);
seq_printf(m, "W12: pkts \t\t\t%llu\n\n", (u64)sq_ctx->pkts);
seq_printf(m, "W13: aged_drop_octs \t\t\t%llu\n\n",
(u64)sq_ctx->aged_drop_octs);
seq_printf(m, "W13: aged_drop_pkts \t\t\t%llu\n\n",
(u64)sq_ctx->aged_drop_pkts);
seq_printf(m, "W14: dropped_octs \t\t%llu\n\n",
(u64)sq_ctx->dropped_octs);
seq_printf(m, "W15: dropped_pkts \t\t%llu\n\n",
(u64)sq_ctx->dropped_pkts);
}
void print_nix_cn20k_cq_ctx(struct seq_file *m,
struct nix_cn20k_aq_enq_rsp *rsp)
{
struct nix_cn20k_cq_ctx_s *cq_ctx = &rsp->cq;
seq_printf(m, "W0: base \t\t\t%llx\n\n", cq_ctx->base);
seq_printf(m, "W1: wrptr \t\t\t%llx\n", (u64)cq_ctx->wrptr);
seq_printf(m, "W1: avg_con \t\t\t%d\nW1: cint_idx \t\t\t%d\n",
cq_ctx->avg_con, cq_ctx->cint_idx);
seq_printf(m, "W1: cq_err \t\t\t%d\nW1: qint_idx \t\t\t%d\n",
cq_ctx->cq_err, cq_ctx->qint_idx);
seq_printf(m, "W1: bpid \t\t\t%d\nW1: bp_ena \t\t\t%d\n\n",
cq_ctx->bpid, cq_ctx->bp_ena);
seq_printf(m, "W1: lbpid_high \t\t\t0x%03x\n", cq_ctx->lbpid_high);
seq_printf(m, "W1: lbpid_med \t\t\t0x%03x\n", cq_ctx->lbpid_med);
seq_printf(m, "W1: lbpid_low \t\t\t0x%03x\n", cq_ctx->lbpid_low);
seq_printf(m, "(W1: lbpid) \t\t\t0x%03x\n",
cq_ctx->lbpid_high << 6 | cq_ctx->lbpid_med << 3 |
cq_ctx->lbpid_low);
seq_printf(m, "W1: lbp_ena \t\t\t\t%d\n\n", cq_ctx->lbp_ena);
seq_printf(m, "W2: update_time \t\t%d\nW2:avg_level \t\t\t%d\n",
cq_ctx->update_time, cq_ctx->avg_level);
seq_printf(m, "W2: head \t\t\t%d\nW2:tail \t\t\t%d\n\n",
cq_ctx->head, cq_ctx->tail);
seq_printf(m, "W3: cq_err_int_ena \t\t%d\nW3:cq_err_int \t\t\t%d\n",
cq_ctx->cq_err_int_ena, cq_ctx->cq_err_int);
seq_printf(m, "W3: qsize \t\t\t%d\nW3:stashing \t\t\t%d\n",
cq_ctx->qsize, cq_ctx->stashing);
seq_printf(m, "W3: caching \t\t\t%d\n", cq_ctx->caching);
seq_printf(m, "W3: lbp_frac \t\t\t%d\n", cq_ctx->lbp_frac);
seq_printf(m, "W3: stash_thresh \t\t\t%d\n",
cq_ctx->stash_thresh);
seq_printf(m, "W3: msh_valid \t\t\t%d\nW3:msh_dst \t\t\t%d\n",
cq_ctx->msh_valid, cq_ctx->msh_dst);
seq_printf(m, "W3: cpt_drop_err_en \t\t\t%d\n",
cq_ctx->cpt_drop_err_en);
seq_printf(m, "W3: ena \t\t\t%d\n",
cq_ctx->ena);
seq_printf(m, "W3: drop_ena \t\t\t%d\nW3: drop \t\t\t%d\n",
cq_ctx->drop_ena, cq_ctx->drop);
seq_printf(m, "W3: bp \t\t\t\t%d\n\n", cq_ctx->bp);
seq_printf(m, "W4: lbpid_ext \t\t\t\t%d\n\n", cq_ctx->lbpid_ext);
seq_printf(m, "W4: bpid_ext \t\t\t\t%d\n\n", cq_ctx->bpid_ext);
}
void print_npa_cn20k_aura_ctx(struct seq_file *m,
struct npa_cn20k_aq_enq_rsp *rsp)
{
struct npa_cn20k_aura_s *aura = &rsp->aura;
seq_printf(m, "W0: Pool addr\t\t%llx\n", aura->pool_addr);
seq_printf(m, "W1: ena\t\t\t%d\nW1: pool caching\t%d\n",
aura->ena, aura->pool_caching);
seq_printf(m, "W1: avg con\t\t%d\n", aura->avg_con);
seq_printf(m, "W1: pool drop ena\t%d\nW1: aura drop ena\t%d\n",
aura->pool_drop_ena, aura->aura_drop_ena);
seq_printf(m, "W1: bp_ena\t\t%d\nW1: aura drop\t\t%d\n",
aura->bp_ena, aura->aura_drop);
seq_printf(m, "W1: aura shift\t\t%d\nW1: avg_level\t\t%d\n",
aura->shift, aura->avg_level);
seq_printf(m, "W2: count\t\t%llu\nW2: nix_bpid\t\t%d\n",
(u64)aura->count, aura->bpid);
seq_printf(m, "W3: limit\t\t%llu\nW3: bp\t\t\t%d\nW3: fc_ena\t\t%d\n",
(u64)aura->limit, aura->bp, aura->fc_ena);
seq_printf(m, "W3: fc_up_crossing\t%d\nW3: fc_stype\t\t%d\n",
aura->fc_up_crossing, aura->fc_stype);
seq_printf(m, "W3: fc_hyst_bits\t%d\n", aura->fc_hyst_bits);
seq_printf(m, "W4: fc_addr\t\t%llx\n", aura->fc_addr);
seq_printf(m, "W5: pool_drop\t\t%d\nW5: update_time\t\t%d\n",
aura->pool_drop, aura->update_time);
seq_printf(m, "W5: err_int \t\t%d\nW5: err_int_ena\t\t%d\n",
aura->err_int, aura->err_int_ena);
seq_printf(m, "W5: thresh_int\t\t%d\nW5: thresh_int_ena \t%d\n",
aura->thresh_int, aura->thresh_int_ena);
seq_printf(m, "W5: thresh_up\t\t%d\nW5: thresh_qint_idx\t%d\n",
aura->thresh_up, aura->thresh_qint_idx);
seq_printf(m, "W5: err_qint_idx \t%d\n", aura->err_qint_idx);
seq_printf(m, "W6: thresh\t\t%llu\n", (u64)aura->thresh);
seq_printf(m, "W6: fc_msh_dst\t\t%d\n", aura->fc_msh_dst);
}
void print_npa_cn20k_pool_ctx(struct seq_file *m,
struct npa_cn20k_aq_enq_rsp *rsp)
{
struct npa_cn20k_pool_s *pool = &rsp->pool;
seq_printf(m, "W0: Stack base\t\t%llx\n", pool->stack_base);
seq_printf(m, "W1: ena \t\t%d\nW1: nat_align \t\t%d\n",
pool->ena, pool->nat_align);
seq_printf(m, "W1: stack_caching\t%d\n",
pool->stack_caching);
seq_printf(m, "W1: buf_offset\t\t%d\nW1: buf_size\t\t%d\n",
pool->buf_offset, pool->buf_size);
seq_printf(m, "W2: stack_max_pages \t%d\nW2: stack_pages\t\t%d\n",
pool->stack_max_pages, pool->stack_pages);
seq_printf(m, "W4: stack_offset\t%d\nW4: shift\t\t%d\nW4: avg_level\t\t%d\n",
pool->stack_offset, pool->shift, pool->avg_level);
seq_printf(m, "W4: avg_con \t\t%d\nW4: fc_ena\t\t%d\nW4: fc_stype\t\t%d\n",
pool->avg_con, pool->fc_ena, pool->fc_stype);
seq_printf(m, "W4: fc_hyst_bits\t%d\nW4: fc_up_crossing\t%d\n",
pool->fc_hyst_bits, pool->fc_up_crossing);
seq_printf(m, "W4: update_time\t\t%d\n", pool->update_time);
seq_printf(m, "W5: fc_addr\t\t%llx\n", pool->fc_addr);
seq_printf(m, "W6: ptr_start\t\t%llx\n", pool->ptr_start);
seq_printf(m, "W7: ptr_end\t\t%llx\n", pool->ptr_end);
seq_printf(m, "W8: err_int\t\t%d\nW8: err_int_ena\t\t%d\n",
pool->err_int, pool->err_int_ena);
seq_printf(m, "W8: thresh_int\t\t%d\n", pool->thresh_int);
seq_printf(m, "W8: thresh_int_ena\t%d\nW8: thresh_up\t\t%d\n",
pool->thresh_int_ena, pool->thresh_up);
seq_printf(m, "W8: thresh_qint_idx\t%d\nW8: err_qint_idx\t%d\n",
pool->thresh_qint_idx, pool->err_qint_idx);
seq_printf(m, "W8: fc_msh_dst\t\t%d\n", pool->fc_msh_dst);
}
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Marvell OcteonTx2 CGX driver
*
* Copyright (C) 2024 Marvell.
*
*/
#ifndef DEBUFS_H
#define DEBUFS_H
#include <linux/fs.h>
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "struct.h"
#include "../mbox.h"
int npc_cn20k_debugfs_init(struct rvu *rvu);
void npc_cn20k_debugfs_deinit(struct rvu *rvu);
void print_nix_cn20k_sq_ctx(struct seq_file *m,
struct nix_cn20k_sq_ctx_s *sq_ctx);
void print_nix_cn20k_cq_ctx(struct seq_file *m,
struct nix_cn20k_aq_enq_rsp *rsp);
void print_npa_cn20k_aura_ctx(struct seq_file *m,
struct npa_cn20k_aq_enq_rsp *rsp);
void print_npa_cn20k_pool_ctx(struct seq_file *m,
struct npa_cn20k_aq_enq_rsp *rsp);
#endif
@@ -0,0 +1,441 @@
// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2024 Marvell.
*
*/
#include <linux/interrupt.h>
#include <linux/irq.h>
#include "rvu_trace.h"
#include "mbox.h"
#include "reg.h"
#include "api.h"
static irqreturn_t cn20k_afvf_mbox_intr_handler(int irq, void *rvu_irq)
{
struct rvu_irq_data *rvu_irq_data = rvu_irq;
struct rvu *rvu = rvu_irq_data->rvu;
u64 intr;
/* Sync with mbox memory region */
rmb();
/* Clear interrupts */
intr = rvupf_read64(rvu, rvu_irq_data->intr_status);
rvupf_write64(rvu, rvu_irq_data->intr_status, intr);
if (intr)
trace_otx2_msg_interrupt(rvu->pdev, "VF(s) to AF", intr);
rvu_irq_data->afvf_queue_work_hdlr(&rvu->afvf_wq_info, rvu_irq_data->start,
rvu_irq_data->mdevs, intr);
return IRQ_HANDLED;
}
int cn20k_register_afvf_mbox_intr(struct rvu *rvu, int pf_vec_start)
{
struct rvu_irq_data *irq_data;
int intr_vec, offset, vec = 0;
int err;
/* irq data for 4 VFPF intr vectors */
irq_data = devm_kcalloc(rvu->dev, 4,
sizeof(struct rvu_irq_data), GFP_KERNEL);
if (!irq_data)
return -ENOMEM;
for (intr_vec = RVU_MBOX_PF_INT_VEC_VFPF_MBOX0; intr_vec <=
RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1;
intr_vec++, vec++) {
switch (intr_vec) {
case RVU_MBOX_PF_INT_VEC_VFPF_MBOX0:
irq_data[vec].intr_status =
RVU_MBOX_PF_VFPF_INTX(0);
irq_data[vec].start = 0;
irq_data[vec].mdevs = 64;
break;
case RVU_MBOX_PF_INT_VEC_VFPF_MBOX1:
irq_data[vec].intr_status =
RVU_MBOX_PF_VFPF_INTX(1);
irq_data[vec].start = 64;
irq_data[vec].mdevs = 64;
break;
case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX0:
irq_data[vec].intr_status =
RVU_MBOX_PF_VFPF1_INTX(0);
irq_data[vec].start = 0;
irq_data[vec].mdevs = 64;
break;
case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1:
irq_data[vec].intr_status = RVU_MBOX_PF_VFPF1_INTX(1);
irq_data[vec].start = 64;
irq_data[vec].mdevs = 64;
break;
}
irq_data[vec].afvf_queue_work_hdlr =
rvu_queue_work;
offset = pf_vec_start + intr_vec;
irq_data[vec].vec_num = offset;
irq_data[vec].rvu = rvu;
sprintf(&rvu->irq_name[offset * NAME_SIZE], "RVUAF VFAF%d Mbox%d",
vec / 2, vec % 2);
err = request_irq(pci_irq_vector(rvu->pdev, offset),
rvu->ng_rvu->rvu_mbox_ops->afvf_intr_handler, 0,
&rvu->irq_name[offset * NAME_SIZE],
&irq_data[vec]);
if (err) {
dev_err(rvu->dev,
"RVUAF: IRQ registration failed for AFVF mbox irq\n");
return err;
}
rvu->irq_allocated[offset] = true;
}
return 0;
}
/* CN20K mbox PFx => AF irq handler */
static irqreturn_t cn20k_mbox_pf_common_intr_handler(int irq, void *rvu_irq)
{
struct rvu_irq_data *rvu_irq_data = rvu_irq;
struct rvu *rvu = rvu_irq_data->rvu;
u64 intr;
/* Clear interrupts */
intr = rvu_read64(rvu, BLKADDR_RVUM, rvu_irq_data->intr_status);
rvu_write64(rvu, BLKADDR_RVUM, rvu_irq_data->intr_status, intr);
if (intr)
trace_otx2_msg_interrupt(rvu->pdev, "PF(s) to AF", intr);
/* Sync with mbox memory region */
rmb();
rvu_irq_data->rvu_queue_work_hdlr(&rvu->afpf_wq_info,
rvu_irq_data->start,
rvu_irq_data->mdevs, intr);
return IRQ_HANDLED;
}
void cn20k_rvu_enable_mbox_intr(struct rvu *rvu)
{
struct rvu_hwinfo *hw = rvu->hw;
/* Clear spurious irqs, if any */
rvu_write64(rvu, BLKADDR_RVUM,
RVU_MBOX_AF_PFAF_INT(0), INTR_MASK(hw->total_pfs));
rvu_write64(rvu, BLKADDR_RVUM,
RVU_MBOX_AF_PFAF_INT(1), INTR_MASK(hw->total_pfs - 64));
rvu_write64(rvu, BLKADDR_RVUM,
RVU_MBOX_AF_PFAF1_INT(0), INTR_MASK(hw->total_pfs));
rvu_write64(rvu, BLKADDR_RVUM,
RVU_MBOX_AF_PFAF1_INT(1), INTR_MASK(hw->total_pfs - 64));
/* Enable mailbox interrupt for all PFs except PF0 i.e AF itself */
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF_INT_ENA_W1S(0),
INTR_MASK(hw->total_pfs) & ~1ULL);
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF_INT_ENA_W1S(1),
INTR_MASK(hw->total_pfs - 64));
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF1_INT_ENA_W1S(0),
INTR_MASK(hw->total_pfs) & ~1ULL);
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF1_INT_ENA_W1S(1),
INTR_MASK(hw->total_pfs - 64));
}
void cn20k_rvu_unregister_interrupts(struct rvu *rvu)
{
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF_INT_ENA_W1C(0),
INTR_MASK(rvu->hw->total_pfs) & ~1ULL);
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF_INT_ENA_W1C(1),
INTR_MASK(rvu->hw->total_pfs - 64));
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF1_INT_ENA_W1C(0),
INTR_MASK(rvu->hw->total_pfs) & ~1ULL);
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF1_INT_ENA_W1C(1),
INTR_MASK(rvu->hw->total_pfs - 64));
}
int cn20k_register_afpf_mbox_intr(struct rvu *rvu)
{
struct rvu_irq_data *irq_data;
int intr_vec, ret, vec = 0;
/* irq data for 4 PF intr vectors */
irq_data = devm_kcalloc(rvu->dev, 4,
sizeof(struct rvu_irq_data), GFP_KERNEL);
if (!irq_data)
return -ENOMEM;
for (intr_vec = RVU_AF_CN20K_INT_VEC_PFAF_MBOX0; intr_vec <=
RVU_AF_CN20K_INT_VEC_PFAF1_MBOX1; intr_vec++,
vec++) {
switch (intr_vec) {
case RVU_AF_CN20K_INT_VEC_PFAF_MBOX0:
irq_data[vec].intr_status =
RVU_MBOX_AF_PFAF_INT(0);
irq_data[vec].start = 0;
irq_data[vec].mdevs = 64;
break;
case RVU_AF_CN20K_INT_VEC_PFAF_MBOX1:
irq_data[vec].intr_status =
RVU_MBOX_AF_PFAF_INT(1);
irq_data[vec].start = 64;
irq_data[vec].mdevs = 96;
break;
case RVU_AF_CN20K_INT_VEC_PFAF1_MBOX0:
irq_data[vec].intr_status =
RVU_MBOX_AF_PFAF1_INT(0);
irq_data[vec].start = 0;
irq_data[vec].mdevs = 64;
break;
case RVU_AF_CN20K_INT_VEC_PFAF1_MBOX1:
irq_data[vec].intr_status =
RVU_MBOX_AF_PFAF1_INT(1);
irq_data[vec].start = 64;
irq_data[vec].mdevs = 96;
break;
}
irq_data[vec].rvu_queue_work_hdlr = rvu_queue_work;
irq_data[vec].vec_num = intr_vec;
irq_data[vec].rvu = rvu;
/* Register mailbox interrupt handler */
sprintf(&rvu->irq_name[intr_vec * NAME_SIZE],
"RVUAF PFAF%d Mbox%d",
vec / 2, vec % 2);
ret = request_irq(pci_irq_vector(rvu->pdev, intr_vec),
rvu->ng_rvu->rvu_mbox_ops->pf_intr_handler, 0,
&rvu->irq_name[intr_vec * NAME_SIZE],
&irq_data[vec]);
if (ret)
return ret;
rvu->irq_allocated[intr_vec] = true;
}
return 0;
}
int cn20k_rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
int num, int type, unsigned long *pf_bmap)
{
int region;
u64 bar;
if (type == TYPE_AFVF) {
for (region = 0; region < num; region++) {
if (!test_bit(region, pf_bmap))
continue;
bar = (u64)phys_to_virt((u64)rvu->ng_rvu->vf_mbox_addr->base);
bar += region * MBOX_SIZE;
mbox_addr[region] = (void *)bar;
if (!mbox_addr[region])
return -ENOMEM;
}
return 0;
}
for (region = 0; region < num; region++) {
if (!test_bit(region, pf_bmap))
continue;
bar = (u64)phys_to_virt((u64)rvu->ng_rvu->pf_mbox_addr->base);
bar += region * MBOX_SIZE;
mbox_addr[region] = (void *)bar;
if (!mbox_addr[region])
return -ENOMEM;
}
return 0;
}
static int rvu_alloc_mbox_memory(struct rvu *rvu, int type,
int ndevs, int mbox_size)
{
struct qmem *mbox_addr;
dma_addr_t iova;
int pf, err;
/* Allocate contiguous memory for mailbox communication.
* eg: AF <=> PFx mbox memory
* This allocated memory is split into chunks of MBOX_SIZE
* and setup into each of the RVU PFs. In HW this memory will
* get aliased to an offset within BAR2 of those PFs.
*
* AF will access mbox memory using direct physical addresses
* and PFs will access the same shared memory from BAR2.
*
* PF <=> VF mbox memory also works in the same fashion.
* AFPF, PFVF requires IOVA to be used to maintain the mailbox msgs
*/
err = qmem_alloc(rvu->dev, &mbox_addr, ndevs, mbox_size);
if (err)
return -ENOMEM;
switch (type) {
case TYPE_AFPF:
rvu->ng_rvu->pf_mbox_addr = mbox_addr;
iova = (u64)mbox_addr->iova;
for (pf = 0; pf < ndevs; pf++) {
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFX_ADDR(pf),
(u64)iova);
iova += mbox_size;
}
break;
case TYPE_AFVF:
rvu->ng_rvu->vf_mbox_addr = mbox_addr;
rvupf_write64(rvu, RVU_PF_VF_MBOX_ADDR, (u64)mbox_addr->iova);
break;
default:
return 0;
}
return 0;
}
static struct mbox_ops cn20k_mbox_ops = {
.pf_intr_handler = cn20k_mbox_pf_common_intr_handler,
.afvf_intr_handler = cn20k_afvf_mbox_intr_handler,
};
int cn20k_rvu_mbox_init(struct rvu *rvu, int type, int ndevs)
{
int dev;
if (!is_cn20k(rvu->pdev))
return 0;
rvu->ng_rvu->rvu_mbox_ops = &cn20k_mbox_ops;
if (type == TYPE_AFVF) {
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_PF_VF_CFG, ilog2(MBOX_SIZE));
} else {
for (dev = 0; dev < ndevs; dev++)
rvu_write64(rvu, BLKADDR_RVUM,
RVU_MBOX_AF_PFX_CFG(dev), ilog2(MBOX_SIZE));
}
return rvu_alloc_mbox_memory(rvu, type, ndevs, MBOX_SIZE);
}
void cn20k_free_mbox_memory(struct rvu *rvu)
{
if (!is_cn20k(rvu->pdev))
return;
qmem_free(rvu->dev, rvu->ng_rvu->pf_mbox_addr);
qmem_free(rvu->dev, rvu->ng_rvu->vf_mbox_addr);
}
void cn20k_rvu_disable_afvf_intr(struct rvu *rvu, int vfs)
{
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(0), INTR_MASK(vfs));
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(0), INTR_MASK(vfs));
rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(0), INTR_MASK(vfs));
rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(0), INTR_MASK(vfs));
if (vfs <= 64)
return;
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(1), INTR_MASK(vfs - 64));
}
void cn20k_rvu_enable_afvf_intr(struct rvu *rvu, int vfs)
{
/* Clear any pending interrupts and enable AF VF interrupts for
* the first 64 VFs.
*/
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INTX(0), INTR_MASK(vfs));
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(0), INTR_MASK(vfs));
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INTX(0), INTR_MASK(vfs));
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(0), INTR_MASK(vfs));
/* FLR */
rvupf_write64(rvu, RVU_PF_VFFLR_INTX(0), INTR_MASK(vfs));
rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1SX(0), INTR_MASK(vfs));
/* Same for remaining VFs, if any. */
if (vfs <= 64)
return;
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INTX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INTX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_PF_VFFLR_INTX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1SX(1), INTR_MASK(vfs - 64));
rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1SX(1), INTR_MASK(vfs - 64));
}
int rvu_alloc_cint_qint_mem(struct rvu *rvu, struct rvu_pfvf *pfvf,
int blkaddr, int nixlf)
{
int qints, hwctx_size, err;
u64 cfg, ctx_cfg;
if (is_rvu_otx2(rvu) || is_cn20k(rvu->pdev))
return 0;
/* sanity check */
cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_NIXX_CFG(0) |
(RVU_AFPF << 16));
if (!cfg)
return 0;
ctx_cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST3);
/* Alloc memory for CQINT's HW contexts */
cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
qints = (cfg >> 24) & 0xFFF;
hwctx_size = 1UL << ((ctx_cfg >> 24) & 0xF);
err = qmem_alloc(rvu->dev, &pfvf->cq_ints_ctx, qints, hwctx_size);
if (err)
return -ENOMEM;
rvu_write64(rvu, blkaddr, NIX_AF_LFX_CINTS_BASE(nixlf),
(u64)pfvf->cq_ints_ctx->iova);
/* Alloc memory for QINT's HW contexts */
cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
qints = (cfg >> 12) & 0xFFF;
hwctx_size = 1UL << ((ctx_cfg >> 20) & 0xF);
err = qmem_alloc(rvu->dev, &pfvf->nix_qints_ctx, qints, hwctx_size);
if (err)
return -ENOMEM;
rvu_write64(rvu, blkaddr, NIX_AF_LFX_QINTS_BASE(nixlf),
(u64)pfvf->nix_qints_ctx->iova);
rvu_write64(rvu, BLKADDR_NIX0, RVU_AF_BAR2_SEL, RVU_AF_BAR2_PFID);
rvu_write64(rvu, BLKADDR_NIX0,
AF_BAR2_ALIASX(0, NIX_GINT_INT_W1S), ALTAF_RDY);
/* wait for ack */
err = rvu_poll_reg(rvu, BLKADDR_NIX0,
AF_BAR2_ALIASX(0, NIX_GINT_INT), ALTAF_RDY, true);
if (err)
rvu->altaf_ready = false;
else
rvu->altaf_ready = true;
return 0;
}
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2024 Marvell.
*
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "struct.h"
#include "../rvu.h"
int rvu_mbox_handler_nix_cn20k_aq_enq(struct rvu *rvu,
struct nix_cn20k_aq_enq_req *req,
struct nix_cn20k_aq_enq_rsp *rsp)
{
return rvu_nix_aq_enq_inst(rvu, (struct nix_aq_enq_req *)req,
(struct nix_aq_enq_rsp *)rsp);
}
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2024 Marvell.
*
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "struct.h"
#include "../rvu.h"
int rvu_mbox_handler_npa_cn20k_aq_enq(struct rvu *rvu,
struct npa_cn20k_aq_enq_req *req,
struct npa_cn20k_aq_enq_rsp *rsp)
{
return rvu_npa_aq_enq_inst(rvu, (struct npa_aq_enq_req *)req,
(struct npa_aq_enq_rsp *)rsp);
}
EXPORT_SYMBOL(rvu_mbox_handler_npa_cn20k_aq_enq);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,352 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2026 Marvell.
*
*/
#ifndef NPC_CN20K_H
#define NPC_CN20K_H
#define MKEX_CN20K_SIGN 0x19bbfdbd160
/* MAX_NUM_BANKS, MAX_SUBBANK_DEPTH and MAX_NUM_SUB_BANKS represent
* hard limit on all silicon variants, preventing any possibility of
* out-of-bounds access on matrix defined using these values.
*/
#define MAX_NUM_BANKS 2
#define MAX_NUM_SUB_BANKS 32
#define MAX_SUBBANK_DEPTH 256
/* strtoull of "mkexprof" with base:36 */
#define MKEX_END_SIGN 0xdeadbeef
#define NPC_CN20K_BYTESM GENMASK_ULL(18, 16)
#define NPC_CN20K_PARSE_NIBBLE GENMASK_ULL(22, 0)
#define NPC_CN20K_TOTAL_NIBBLE 23
#define CN20K_SET_EXTR_LT(intf, extr, ltype, cfg) \
rvu_write64(rvu, BLKADDR_NPC, \
NPC_AF_INTFX_EXTRACTORX_LTX_CFG(intf, extr, ltype), cfg)
#define CN20K_GET_KEX_CFG(intf) \
rvu_read64(rvu, BLKADDR_NPC, NPC_AF_INTFX_KEX_CFG(intf))
#define CN20K_GET_EXTR_LID(intf, extr) \
rvu_read64(rvu, BLKADDR_NPC, \
NPC_AF_INTFX_EXTRACTORX_CFG(intf, extr))
#define CN20K_SET_EXTR_LT(intf, extr, ltype, cfg) \
rvu_write64(rvu, BLKADDR_NPC, \
NPC_AF_INTFX_EXTRACTORX_LTX_CFG(intf, extr, ltype), cfg)
#define CN20K_GET_EXTR_LT(intf, extr, ltype) \
rvu_read64(rvu, BLKADDR_NPC, \
NPC_AF_INTFX_EXTRACTORX_LTX_CFG(intf, extr, ltype))
/* NPC_PARSE_KEX_S nibble definitions for each field */
#define NPC_CN20K_PARSE_NIBBLE_CHAN GENMASK_ULL(2, 0)
#define NPC_CN20K_PARSE_NIBBLE_ERRLEV BIT_ULL(3)
#define NPC_CN20K_PARSE_NIBBLE_ERRCODE GENMASK_ULL(5, 4)
#define NPC_CN20K_PARSE_NIBBLE_L2L3_BCAST BIT_ULL(6)
#define NPC_CN20K_PARSE_NIBBLE_LA_FLAGS BIT_ULL(7)
#define NPC_CN20K_PARSE_NIBBLE_LA_LTYPE BIT_ULL(8)
#define NPC_CN20K_PARSE_NIBBLE_LB_FLAGS BIT_ULL(9)
#define NPC_CN20K_PARSE_NIBBLE_LB_LTYPE BIT_ULL(10)
#define NPC_CN20K_PARSE_NIBBLE_LC_FLAGS BIT_ULL(11)
#define NPC_CN20K_PARSE_NIBBLE_LC_LTYPE BIT_ULL(12)
#define NPC_CN20K_PARSE_NIBBLE_LD_FLAGS BIT_ULL(13)
#define NPC_CN20K_PARSE_NIBBLE_LD_LTYPE BIT_ULL(14)
#define NPC_CN20K_PARSE_NIBBLE_LE_FLAGS BIT_ULL(15)
#define NPC_CN20K_PARSE_NIBBLE_LE_LTYPE BIT_ULL(16)
#define NPC_CN20K_PARSE_NIBBLE_LF_FLAGS BIT_ULL(17)
#define NPC_CN20K_PARSE_NIBBLE_LF_LTYPE BIT_ULL(18)
#define NPC_CN20K_PARSE_NIBBLE_LG_FLAGS BIT_ULL(19)
#define NPC_CN20K_PARSE_NIBBLE_LG_LTYPE BIT_ULL(20)
#define NPC_CN20K_PARSE_NIBBLE_LH_FLAGS BIT_ULL(21)
#define NPC_CN20K_PARSE_NIBBLE_LH_LTYPE BIT_ULL(22)
/* Rx parse key extract nibble enable */
#define NPC_CN20K_PARSE_NIBBLE_INTF_RX (NPC_CN20K_PARSE_NIBBLE_CHAN | \
NPC_CN20K_PARSE_NIBBLE_L2L3_BCAST | \
NPC_CN20K_PARSE_NIBBLE_LA_LTYPE | \
NPC_CN20K_PARSE_NIBBLE_LB_LTYPE | \
NPC_CN20K_PARSE_NIBBLE_LC_FLAGS | \
NPC_CN20K_PARSE_NIBBLE_LC_LTYPE | \
NPC_CN20K_PARSE_NIBBLE_LD_LTYPE | \
NPC_CN20K_PARSE_NIBBLE_LE_LTYPE)
/* Tx parse key extract nibble enable */
#define NPC_CN20K_PARSE_NIBBLE_INTF_TX (NPC_CN20K_PARSE_NIBBLE_LA_LTYPE | \
NPC_CN20K_PARSE_NIBBLE_LB_LTYPE | \
NPC_CN20K_PARSE_NIBBLE_LC_LTYPE | \
NPC_CN20K_PARSE_NIBBLE_LD_LTYPE | \
NPC_CN20K_PARSE_NIBBLE_LE_LTYPE)
/**
* enum npc_subbank_flag - NPC subbank status
*
* subbank flag indicates whether the subbank is free
* or used.
*
* @NPC_SUBBANK_FLAG_UNINIT: Subbank is not initialized.
* @NPC_SUBBANK_FLAG_FREE: Subbank is free.
* @NPC_SUBBANK_FLAG_USED: Subbank is used.
*/
enum npc_subbank_flag {
NPC_SUBBANK_FLAG_UNINIT,
NPC_SUBBANK_FLAG_FREE = BIT(0),
NPC_SUBBANK_FLAG_USED = BIT(1),
};
/**
* enum npc_dft_rule_id - Default rule type
*
* Mcam default rule type.
*
* @NPC_DFT_RULE_START_ID: Not used
* @NPC_DFT_RULE_PROMISC_ID: promiscuous rule
* @NPC_DFT_RULE_MCAST_ID: multicast rule
* @NPC_DFT_RULE_BCAST_ID: broadcast rule
* @NPC_DFT_RULE_UCAST_ID: unicast rule
* @NPC_DFT_RULE_MAX_ID: Maximum index.
*/
enum npc_dft_rule_id {
NPC_DFT_RULE_START_ID = 1,
NPC_DFT_RULE_PROMISC_ID = NPC_DFT_RULE_START_ID,
NPC_DFT_RULE_MCAST_ID,
NPC_DFT_RULE_BCAST_ID,
NPC_DFT_RULE_UCAST_ID,
NPC_DFT_RULE_MAX_ID,
};
/**
* struct npc_subbank - Subbank fields.
* @b0b: Subbanks bottom index for bank0
* @b1b: Subbanks bottom index for bank1
* @b0t: Subbanks top index for bank0
* @b1t: Subbanks top index for bank1
* @flags: Subbank flags
* @lock: Mutex lock for flags and rsrc mofiication
* @b0map: Bitmap map for bank0 indexes
* @b1map: Bitmap map for bank1 indexes
* @idx: Subbank index
* @arr_idx: Index to the free array or used array
* @free_cnt: Number of free slots in the subbank.
* @key_type: X4 or X2 subbank.
*
* MCAM resource is divided horizontally into multiple subbanks and
* Resource allocation from each subbank is managed by this data
* structure.
*/
struct npc_subbank {
u16 b0t, b0b, b1t, b1b;
enum npc_subbank_flag flags;
struct mutex lock; /* Protect subbank resources */
DECLARE_BITMAP(b0map, MAX_SUBBANK_DEPTH);
DECLARE_BITMAP(b1map, MAX_SUBBANK_DEPTH);
u16 idx;
u16 arr_idx;
u16 free_cnt;
u8 key_type;
};
/**
* struct npc_defrag_show_node - Defragmentation show node
* @old_midx: Old mcam index.
* @new_midx: New mcam index.
* @vidx: Virtual index
* @list: Linked list of these nodes
*
* This structure holds information on last defragmentation
* executed on mcam resource.
*/
struct npc_defrag_show_node {
u16 old_midx;
u16 new_midx;
u16 vidx;
struct list_head list;
};
/**
* struct npc_priv_t - NPC private structure.
* @bank_depth: Total entries in each bank.
* @num_banks: Number of banks.
* @num_subbanks: Number of subbanks.
* @subbank_depth: Depth of subbank.
* @en_map: Enable/disable status.
* @kw: Kex configured key type.
* @sb: Subbank array.
* @xa_sb_used: Array of used subbanks.
* @xa_sb_free: Array of free subbanks.
* @xa_pf2idx_map: PF to mcam index map.
* @xa_idx2pf_map: Mcam index to PF map.
* @xa_pf_map: Pcifunc to index map.
* @pf_cnt: Number of PFs.
* @xa_pf2dfl_rmap: PF to default rule index map.
* @xa_idx2vidx_map: Mcam index to virtual index map.
* @xa_vidx2idx_map: virtual index to mcam index map.
* @defrag_lh: Defrag list head.
* @lock: Lock for defrag list
*
* This structure is populated during probing time by reading
* HW csr registers.
*/
struct npc_priv_t {
int bank_depth;
int num_banks;
int num_subbanks;
int subbank_depth;
DECLARE_BITMAP(en_map, MAX_NUM_BANKS *
MAX_NUM_SUB_BANKS *
MAX_SUBBANK_DEPTH);
u8 kw;
struct npc_subbank *sb;
struct xarray xa_sb_used;
struct xarray xa_sb_free;
struct xarray *xa_pf2idx_map;
struct xarray xa_idx2pf_map;
struct xarray xa_pf_map;
struct xarray xa_pf2dfl_rmap;
struct xarray xa_idx2vidx_map;
struct xarray xa_vidx2idx_map;
struct list_head defrag_lh;
struct mutex lock; /* protect defrag nodes */
int pf_cnt;
};
struct npc_kpm_action0 {
#if defined(__BIG_ENDIAN_BITFIELD)
u64 rsvd_63_57 : 7;
u64 byp_count : 3;
u64 capture_ena : 1;
u64 parse_done : 1;
u64 next_state : 8;
u64 rsvd_43 : 1;
u64 capture_lid : 3;
u64 capture_ltype : 4;
u64 rsvd_32_35 : 4;
u64 capture_flags : 4;
u64 ptr_advance : 8;
u64 var_len_offset : 8;
u64 var_len_mask : 8;
u64 var_len_right : 1;
u64 var_len_shift : 3;
#else
u64 var_len_shift : 3;
u64 var_len_right : 1;
u64 var_len_mask : 8;
u64 var_len_offset : 8;
u64 ptr_advance : 8;
u64 capture_flags : 4;
u64 rsvd_32_35 : 4;
u64 capture_ltype : 4;
u64 capture_lid : 3;
u64 rsvd_43 : 1;
u64 next_state : 8;
u64 parse_done : 1;
u64 capture_ena : 1;
u64 byp_count : 3;
u64 rsvd_63_57 : 7;
#endif
};
struct npc_mcam_kex_extr {
/* MKEX Profle Header */
u64 mkex_sign; /* "mcam-kex-profile" (8 bytes/ASCII characters) */
u8 name[MKEX_NAME_LEN]; /* MKEX Profile name */
u64 cpu_model; /* Format as profiled by CPU hardware */
u64 kpu_version; /* KPU firmware/profile version */
u64 reserved; /* Reserved for extension */
/* MKEX Profle Data */
u64 keyx_cfg[NPC_MAX_INTF]; /* NPC_AF_INTF(0..1)_KEX_CFG */
#define NPC_MAX_EXTRACTOR 24
/* MKEX Extractor data */
u64 intf_extr_lid[NPC_MAX_INTF][NPC_MAX_EXTRACTOR];
/* KEX configuration per extractor */
u64 intf_extr_lt[NPC_MAX_INTF][NPC_MAX_EXTRACTOR][NPC_MAX_LT];
} __packed;
struct npc_cn20k_kpu_profile_fwdata {
#define KPU_SIGN 0x00666f727075706b
#define KPU_NAME_LEN 32
/* Maximum number of custom KPU entries supported by
* the built-in profile.
*/
#define KPU_CN20K_MAX_CST_ENT 6
/* KPU Profle Header */
__le64 signature; /* "kpuprof\0" (8 bytes/ASCII characters) */
u8 name[KPU_NAME_LEN]; /* KPU Profile name */
__le64 version; /* KPU profile version */
u8 kpus;
u8 reserved[7];
/* Default MKEX profile to be used with this KPU profile. May be
* overridden with mkex_profile module parameter.
* Format is same as for the MKEX profile to streamline processing.
*/
struct npc_mcam_kex_extr mkex;
/* LTYPE values for specific HW offloaded protocols. */
struct npc_lt_def_cfg lt_def;
/* Dynamically sized data:
* Custom KPU CAM and ACTION configuration entries.
* struct npc_kpu_fwdata kpu[kpus];
*/
u8 data[];
} __packed;
struct rvu;
struct npc_priv_t *npc_priv_get(void);
int npc_cn20k_init(struct rvu *rvu);
void npc_cn20k_deinit(struct rvu *rvu);
void npc_cn20k_subbank_calc_free(struct rvu *rvu, int *x2_free,
int *x4_free, int *sb_free);
int npc_cn20k_ref_idx_alloc(struct rvu *rvu, int pcifunc, int key_type,
int prio, u16 *mcam_idx, int ref, int limit,
bool contig, int count, bool virt);
int npc_cn20k_idx_free(struct rvu *rvu, u16 *mcam_idx, int count);
void npc_cn20k_parser_profile_init(struct rvu *rvu, int blkaddr);
struct npc_mcam_kex_extr *npc_mkex_extr_default_get(void);
void npc_cn20k_load_mkex_profile(struct rvu *rvu, int blkaddr,
const char *mkex_profile);
int npc_cn20k_apply_custom_kpu(struct rvu *rvu,
struct npc_kpu_profile_adapter *profile);
void
npc_cn20k_update_action_entries_n_flags(struct rvu *rvu,
struct npc_kpu_profile_adapter *pfl);
int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc);
void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc);
int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast,
u16 *mcast, u16 *promisc, u16 *ucast);
int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
u8 intf, struct cn20k_mcam_entry *entry,
bool enable, u8 hw_prio, u8 req_kw_type);
int npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
int index, bool enable);
int npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr,
u16 src, u16 dest);
int npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
struct cn20k_mcam_entry *entry, u8 *intf,
u8 *ena, u8 *hw_prio);
int npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int index);
int npc_mcam_idx_2_key_type(struct rvu *rvu, u16 mcam_idx, u8 *key_type);
u16 npc_cn20k_vidx2idx(u16 index);
u16 npc_cn20k_idx2vidx(u16 idx);
int npc_cn20k_defrag(struct rvu *rvu);
bool npc_is_cgx_or_lbk(struct rvu *rvu, u16 pcifunc);
int npc_mcam_idx_2_subbank_idx(struct rvu *rvu, u16 mcam_idx,
struct npc_subbank **sb,
int *sb_off);
const u32 *npc_cn20k_search_order_get(bool *restricted_order, u32 *sz);
int npc_cn20k_search_order_set(struct rvu *rvu, u64 narr[MAX_NUM_SUB_BANKS],
int cnt);
#endif /* NPC_CN20K_H */
@@ -0,0 +1,146 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2024 Marvell.
*
*/
#ifndef RVU_MBOX_REG_H
#define RVU_MBOX_REG_H
#include "../rvu.h"
#include "../rvu_reg.h"
/* RVUM block registers */
#define RVU_PF_DISC (0x0)
#define RVU_PRIV_PFX_DISC(a) (0x8000208 | (a) << 16)
#define RVU_PRIV_HWVFX_DISC(a) (0xD000000 | (a) << 12)
/* Mbox Registers */
/* RVU AF BAR0 Mbox registers for AF => PFx */
#define RVU_MBOX_AF_PFX_ADDR(a) (0x5000 | (a) << 4)
#define RVU_MBOX_AF_PFX_CFG(a) (0x6000 | (a) << 4)
#define RVU_MBOX_AF_AFPFX_TRIGX(a) (0x9000 | (a) << 3)
#define RVU_MBOX_AF_PFAF_INT(a) (0x2980 | (a) << 6)
#define RVU_MBOX_AF_PFAF_INT_W1S(a) (0x2988 | (a) << 6)
#define RVU_MBOX_AF_PFAF_INT_ENA_W1S(a) (0x2990 | (a) << 6)
#define RVU_MBOX_AF_PFAF_INT_ENA_W1C(a) (0x2998 | (a) << 6)
#define RVU_MBOX_AF_PFAF1_INT(a) (0x29A0 | (a) << 6)
#define RVU_MBOX_AF_PFAF1_INT_W1S(a) (0x29A8 | (a) << 6)
#define RVU_MBOX_AF_PFAF1_INT_ENA_W1S(a) (0x29B0 | (a) << 6)
#define RVU_MBOX_AF_PFAF1_INT_ENA_W1C(a) (0x29B8 | (a) << 6)
/* RVU PF => AF mbox registers */
#define RVU_MBOX_PF_PFAF_TRIGX(a) (0xC00 | (a) << 3)
#define RVU_MBOX_PF_INT (0xC20)
#define RVU_MBOX_PF_INT_W1S (0xC28)
#define RVU_MBOX_PF_INT_ENA_W1S (0xC30)
#define RVU_MBOX_PF_INT_ENA_W1C (0xC38)
#define RVU_AF_BAR2_SEL (0x9000000)
#define RVU_AF_BAR2_PFID (0x16400)
#define NIX_CINTX_INT_W1S(a) (0xd30 | (a) << 12)
#define NIX_QINTX_CNT(a) (0xc00 | (a) << 12)
#define RVU_MBOX_AF_VFAF_INT(a) (0x3000 | (a) << 6)
#define RVU_MBOX_AF_VFAF_INT_W1S(a) (0x3008 | (a) << 6)
#define RVU_MBOX_AF_VFAF_INT_ENA_W1S(a) (0x3010 | (a) << 6)
#define RVU_MBOX_AF_VFAF_INT_ENA_W1C(a) (0x3018 | (a) << 6)
#define RVU_MBOX_AF_VFAF_INT_ENA_W1C(a) (0x3018 | (a) << 6)
#define RVU_MBOX_AF_VFAF1_INT(a) (0x3020 | (a) << 6)
#define RVU_MBOX_AF_VFAF1_INT_W1S(a) (0x3028 | (a) << 6)
#define RVU_MBOX_AF_VFAF1_IN_ENA_W1S(a) (0x3030 | (a) << 6)
#define RVU_MBOX_AF_VFAF1_IN_ENA_W1C(a) (0x3038 | (a) << 6)
#define RVU_MBOX_AF_AFVFX_TRIG(a, b) (0x10000 | (a) << 4 | (b) << 3)
#define RVU_MBOX_AF_VFX_ADDR(a) (0x20000 | (a) << 4)
#define RVU_MBOX_AF_VFX_CFG(a) (0x28000 | (a) << 4)
#define RVU_MBOX_PF_VFX_PFVF_TRIGX(a) (0x2000 | (a) << 3)
#define RVU_MBOX_PF_VFPF_INTX(a) (0x1000 | (a) << 3)
#define RVU_MBOX_PF_VFPF_INT_W1SX(a) (0x1020 | (a) << 3)
#define RVU_MBOX_PF_VFPF_INT_ENA_W1SX(a) (0x1040 | (a) << 3)
#define RVU_MBOX_PF_VFPF_INT_ENA_W1CX(a) (0x1060 | (a) << 3)
#define RVU_MBOX_PF_VFPF1_INTX(a) (0x1080 | (a) << 3)
#define RVU_MBOX_PF_VFPF1_INT_W1SX(a) (0x10a0 | (a) << 3)
#define RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(a) (0x10c0 | (a) << 3)
#define RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(a) (0x10e0 | (a) << 3)
#define RVU_MBOX_PF_VF_ADDR (0xC40)
#define RVU_MBOX_PF_LMTLINE_ADDR (0xC48)
#define RVU_MBOX_PF_VF_CFG (0xC60)
#define RVU_MBOX_VF_VFPF_TRIGX(a) (0x3000 | (a) << 3)
#define RVU_MBOX_VF_INT (0x20)
#define RVU_MBOX_VF_INT_W1S (0x28)
#define RVU_MBOX_VF_INT_ENA_W1S (0x30)
#define RVU_MBOX_VF_INT_ENA_W1C (0x38)
#define RVU_MBOX_VF_VFAF_TRIGX(a) (0x2000 | (a) << 3)
#define NIX_GINT_INT (0x200)
#define NIX_GINT_INT_W1S (0x208)
#define ALTAF_FLR BIT_ULL(0)
#define ALTAF_RDY BIT_ULL(1)
/* NPC registers */
#define NPC_AF_INTFX_EXTRACTORX_CFG(a, b) \
(0x20c000ull | (a) << 16 | (b) << 8)
#define NPC_AF_INTFX_EXTRACTORX_LTX_CFG(a, b, c) \
(0x204000ull | (a) << 16 | (b) << 8 | (c) << 3)
#define NPC_AF_KPMX_ENTRYX_CAMX(a, b, c) \
(0x20000ull | (a) << 12 | (b) << 3 | (c) << 16)
#define NPC_AF_KPMX_ENTRYX_ACTION0(a, b) \
(0x40000ull | (a) << 12 | (b) << 3)
#define NPC_AF_KPMX_ENTRYX_ACTION1(a, b) \
(0x50000ull | (a) << 12 | (b) << 3)
#define NPC_AF_KPMX_ENTRY_DISX(a, b) (0x60000ull | (a) << 12 | (b) << 3)
#define NPC_AF_KPM_PASS2_CFG 0x10210
#define NPC_AF_KPMX_PASS2_OFFSET(a) (0x60040ull | (a) << 12)
#define NPC_AF_MCAM_SECTIONX_CFG_EXT(a) (0xf000000ull | (a) << 3)
#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(a, b, c) ({ \
u64 offset; \
offset = (0x8000000ull | (a) << 4 | (b) << 20 | (c) << 3); \
offset; })
#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(a, b, c) ({ \
u64 offset; \
offset = (0x9000000ull | (a) << 4 | (b) << 20 | (c) << 3); \
offset; })
#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(a, b, c) ({ \
u64 offset; \
offset = (0x9400000ull | (a) << 4 | (b) << 20 | (c) << 3); \
offset; })
#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(a, b, c) ({ \
u64 offset; \
offset = (0x9800000ull | (a) << 4 | (b) << 20 | (c) << 3); \
offset; })
#define NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(a, b, c) ({ \
u64 offset; \
offset = (0x9c00000ull | (a) << 4 | (b) << 20 | (c) << 3); \
offset; })
#define NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(a, b) ({ \
u64 offset; \
offset = (0xa000000ull | (a) << 4 | (b) << 20); \
offset; })
#define NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(a, b, c) ({ \
u64 offset; \
offset = (0xc000000ull | (a) << 4 | (b) << 20 | (c) << 22); \
offset; })
#define NPC_AF_INTFX_MISS_ACTX(a, b) (0xf003000 | (a) << 6 | (b) << 4)
#define NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(a, b) ({ \
u64 offset; \
offset = (0xb000000ull | (a) << 4 | (b) << 20); \
offset; })
#endif /* RVU_MBOX_REG_H */
@@ -0,0 +1,380 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2024 Marvell.
*
*/
#ifndef STRUCT_H
#define STRUCT_H
#define NIX_MAX_CTX_SIZE 128
/*
* CN20k RVU PF MBOX Interrupt Vector Enumeration
*
* Vectors 0 - 3 are compatible with pre cn20k and hence
* existing macros are being reused.
*/
enum rvu_mbox_pf_int_vec_e {
RVU_MBOX_PF_INT_VEC_VFPF_MBOX0 = 0x4,
RVU_MBOX_PF_INT_VEC_VFPF_MBOX1 = 0x5,
RVU_MBOX_PF_INT_VEC_VFPF1_MBOX0 = 0x6,
RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1 = 0x7,
RVU_MBOX_PF_INT_VEC_AFPF_MBOX = 0x8,
RVU_MBOX_PF_INT_VEC_CNT = 0x9,
};
/* RVU Admin function Interrupt Vector Enumeration */
enum rvu_af_cn20k_int_vec_e {
RVU_AF_CN20K_INT_VEC_POISON = 0x0,
RVU_AF_CN20K_INT_VEC_PFFLR0 = 0x1,
RVU_AF_CN20K_INT_VEC_PFFLR1 = 0x2,
RVU_AF_CN20K_INT_VEC_PFME0 = 0x3,
RVU_AF_CN20K_INT_VEC_PFME1 = 0x4,
RVU_AF_CN20K_INT_VEC_GEN = 0x5,
RVU_AF_CN20K_INT_VEC_PFAF_MBOX0 = 0x6,
RVU_AF_CN20K_INT_VEC_PFAF_MBOX1 = 0x7,
RVU_AF_CN20K_INT_VEC_PFAF1_MBOX0 = 0x8,
RVU_AF_CN20K_INT_VEC_PFAF1_MBOX1 = 0x9,
RVU_AF_CN20K_INT_VEC_CNT = 0xa,
};
struct nix_cn20k_sq_ctx_s {
u64 ena : 1; /* W0 */
u64 qint_idx : 6;
u64 substream : 20;
u64 sdp_mcast : 1;
u64 cq : 20;
u64 sqe_way_mask : 16;
u64 smq : 11; /* W1 */
u64 cq_ena : 1;
u64 xoff : 1;
u64 sso_ena : 1;
u64 smq_rr_weight : 14;
u64 default_chan : 12;
u64 sqb_count : 16;
u64 reserved_120_120 : 1;
u64 smq_rr_count_lb : 7;
u64 smq_rr_count_ub : 25; /* W2 */
u64 sqb_aura : 20;
u64 sq_int : 8;
u64 sq_int_ena : 8;
u64 sqe_stype : 2;
u64 reserved_191_191 : 1;
u64 max_sqe_size : 2; /* W3 */
u64 cq_limit : 8;
u64 lmt_dis : 1;
u64 mnq_dis : 1;
u64 smq_next_sq : 20;
u64 smq_lso_segnum : 8;
u64 tail_offset : 6;
u64 smenq_offset : 6;
u64 head_offset : 6;
u64 smenq_next_sqb_vld : 1;
u64 smq_pend : 1;
u64 smq_next_sq_vld : 1;
u64 reserved_253_255 : 3;
u64 next_sqb : 64; /* W4 */
u64 tail_sqb : 64; /* W5 */
u64 smenq_sqb : 64; /* W6 */
u64 smenq_next_sqb : 64; /* W7 */
u64 head_sqb : 64; /* W8 */
u64 reserved_576_583 : 8; /* W9 */
u64 vfi_lso_total : 18;
u64 vfi_lso_sizem1 : 3;
u64 vfi_lso_sb : 8;
u64 vfi_lso_mps : 14;
u64 vfi_lso_vlan0_ins_ena : 1;
u64 vfi_lso_vlan1_ins_ena : 1;
u64 vfi_lso_vld : 1;
u64 reserved_630_639 : 10;
u64 scm_lso_rem : 18; /* W10 */
u64 reserved_658_703 : 46;
u64 octs : 48; /* W11 */
u64 reserved_752_767 : 16;
u64 pkts : 48; /* W12 */
u64 reserved_816_831 : 16;
u64 aged_drop_octs : 32; /* W13 */
u64 aged_drop_pkts : 32;
u64 dropped_octs : 48; /* W14 */
u64 reserved_944_959 : 16;
u64 dropped_pkts : 48; /* W15 */
u64 reserved_1008_1023 : 16;
};
static_assert(sizeof(struct nix_cn20k_sq_ctx_s) == NIX_MAX_CTX_SIZE);
struct nix_cn20k_cq_ctx_s {
u64 base : 64; /* W0 */
u64 lbp_ena : 1; /* W1 */
u64 lbpid_low : 3;
u64 bp_ena : 1;
u64 lbpid_med : 3;
u64 bpid : 9;
u64 lbpid_high : 3;
u64 qint_idx : 7;
u64 cq_err : 1;
u64 cint_idx : 7;
u64 avg_con : 9;
u64 wrptr : 20;
u64 tail : 20; /* W2 */
u64 head : 20;
u64 avg_level : 8;
u64 update_time : 16;
u64 bp : 8; /* W3 */
u64 drop : 8;
u64 drop_ena : 1;
u64 ena : 1;
u64 cpt_drop_err_en : 1;
u64 reserved_211_211 : 1;
u64 msh_dst : 11;
u64 msh_valid : 1;
u64 stash_thresh : 4;
u64 lbp_frac : 4;
u64 caching : 1;
u64 stashing : 1;
u64 reserved_234_235 : 2;
u64 qsize : 4;
u64 cq_err_int : 8;
u64 cq_err_int_ena : 8;
u64 bpid_ext : 2; /* W4 */
u64 reserved_258_259 : 2;
u64 lbpid_ext : 2;
u64 reserved_262_319 : 58;
u64 reserved_320_383 : 64; /* W5 */
u64 reserved_384_447 : 64; /* W6 */
u64 reserved_448_511 : 64; /* W7 */
u64 padding[8];
};
static_assert(sizeof(struct nix_cn20k_sq_ctx_s) == NIX_MAX_CTX_SIZE);
struct nix_cn20k_rq_ctx_s {
u64 ena : 1;
u64 sso_ena : 1;
u64 ipsech_ena : 1;
u64 ena_wqwd : 1;
u64 cq : 20;
u64 reserved_24_34 : 11;
u64 port_il4_dis : 1;
u64 port_ol4_dis : 1;
u64 lenerr_dis : 1;
u64 csum_il4_dis : 1;
u64 csum_ol4_dis : 1;
u64 len_il4_dis : 1;
u64 len_il3_dis : 1;
u64 len_ol4_dis : 1;
u64 len_ol3_dis : 1;
u64 wqe_aura : 20;
u64 spb_aura : 20;
u64 lpb_aura : 20;
u64 sso_grp : 10;
u64 sso_tt : 2;
u64 pb_caching : 2;
u64 wqe_caching : 1;
u64 xqe_drop_ena : 1;
u64 spb_drop_ena : 1;
u64 lpb_drop_ena : 1;
u64 pb_stashing : 1;
u64 ipsecd_drop_en : 1;
u64 chi_ena : 1;
u64 reserved_125_127 : 3;
u64 band_prof_id_l : 10;
u64 sso_fc_ena : 1;
u64 policer_ena : 1;
u64 spb_sizem1 : 6;
u64 wqe_skip : 2;
u64 spb_high_sizem1 : 3;
u64 spb_ena : 1;
u64 lpb_sizem1 : 12;
u64 first_skip : 7;
u64 reserved_171_171 : 1;
u64 later_skip : 6;
u64 xqe_imm_size : 6;
u64 band_prof_id_h : 4;
u64 reserved_188_189 : 2;
u64 xqe_imm_copy : 1;
u64 xqe_hdr_split : 1;
u64 xqe_drop : 8;
u64 xqe_pass : 8;
u64 wqe_pool_drop : 8;
u64 wqe_pool_pass : 8;
u64 spb_aura_drop : 8;
u64 spb_aura_pass : 8;
u64 spb_pool_drop : 8;
u64 spb_pool_pass : 8;
u64 lpb_aura_drop : 8;
u64 lpb_aura_pass : 8;
u64 lpb_pool_drop : 8;
u64 lpb_pool_pass : 8;
u64 reserved_288_291 : 4;
u64 rq_int : 8;
u64 rq_int_ena : 8;
u64 qint_idx : 7;
u64 reserved_315_319 : 5;
u64 ltag : 24;
u64 good_utag : 8;
u64 bad_utag : 8;
u64 flow_tagw : 6;
u64 ipsec_vwqe : 1;
u64 vwqe_ena : 1;
u64 vtime_wait : 8;
u64 max_vsize_exp : 4;
u64 vwqe_skip : 2;
u64 reserved_382_383 : 2;
u64 octs : 48;
u64 reserved_432_447 : 16;
u64 pkts : 48;
u64 reserved_496_511 : 16;
u64 drop_octs : 48;
u64 reserved_560_575 : 16;
u64 drop_pkts : 48;
u64 reserved_624_639 : 16;
u64 re_pkts : 48;
u64 reserved_688_703 : 16;
u64 reserved_704_767 : 64;
u64 reserved_768_831 : 64;
u64 reserved_832_895 : 64;
u64 reserved_896_959 : 64;
u64 reserved_960_1023 : 64;
};
static_assert(sizeof(struct nix_cn20k_rq_ctx_s) == NIX_MAX_CTX_SIZE);
struct npa_cn20k_aura_s {
u64 pool_addr; /* W0 */
u64 ena : 1; /* W1 */
u64 reserved_65 : 2;
u64 pool_caching : 1;
u64 reserved_68 : 16;
u64 avg_con : 9;
u64 reserved_93 : 1;
u64 pool_drop_ena : 1;
u64 aura_drop_ena : 1;
u64 bp_ena : 1;
u64 reserved_97_103 : 7;
u64 aura_drop : 8;
u64 shift : 6;
u64 reserved_118_119 : 2;
u64 avg_level : 8;
u64 count : 36; /* W2 */
u64 reserved_164_167 : 4;
u64 bpid : 12;
u64 reserved_180_191 : 12;
u64 limit : 36; /* W3 */
u64 reserved_228_231 : 4;
u64 bp : 7;
u64 reserved_239_243 : 5;
u64 fc_ena : 1;
u64 fc_up_crossing : 1;
u64 fc_stype : 2;
u64 fc_hyst_bits : 4;
u64 reserved_252_255 : 4;
u64 fc_addr; /* W4 */
u64 pool_drop : 8; /* W5 */
u64 update_time : 16;
u64 err_int : 8;
u64 err_int_ena : 8;
u64 thresh_int : 1;
u64 thresh_int_ena : 1;
u64 thresh_up : 1;
u64 reserved_363 : 1;
u64 thresh_qint_idx : 7;
u64 reserved_371 : 1;
u64 err_qint_idx : 7;
u64 reserved_379_383 : 5;
u64 thresh : 36; /* W6*/
u64 rsvd_423_420 : 4;
u64 fc_msh_dst : 11;
u64 reserved_435_438 : 4;
u64 op_dpc_ena : 1;
u64 op_dpc_set : 5;
u64 reserved_445_445 : 1;
u64 stream_ctx : 1;
u64 unified_ctx : 1;
u64 reserved_448_511; /* W7 */
u64 padding[8];
};
static_assert(sizeof(struct npa_cn20k_aura_s) == NIX_MAX_CTX_SIZE);
struct npa_cn20k_pool_s {
u64 stack_base; /* W0 */
u64 ena : 1;
u64 nat_align : 1;
u64 reserved_66_67 : 2;
u64 stack_caching : 1;
u64 reserved_69_87 : 19;
u64 buf_offset : 12;
u64 reserved_100_103 : 4;
u64 buf_size : 12;
u64 reserved_116_119 : 4;
u64 ref_cnt_prof : 3;
u64 reserved_123_127 : 5;
u64 stack_max_pages : 32;
u64 stack_pages : 32;
uint64_t bp_0 : 7;
uint64_t bp_1 : 7;
uint64_t bp_2 : 7;
uint64_t bp_3 : 7;
uint64_t bp_4 : 7;
uint64_t bp_5 : 7;
uint64_t bp_6 : 7;
uint64_t bp_7 : 7;
uint64_t bp_ena_0 : 1;
uint64_t bp_ena_1 : 1;
uint64_t bp_ena_2 : 1;
uint64_t bp_ena_3 : 1;
uint64_t bp_ena_4 : 1;
uint64_t bp_ena_5 : 1;
uint64_t bp_ena_6 : 1;
uint64_t bp_ena_7 : 1;
u64 stack_offset : 4;
u64 reserved_260_263 : 4;
u64 shift : 6;
u64 reserved_270_271 : 2;
u64 avg_level : 8;
u64 avg_con : 9;
u64 fc_ena : 1;
u64 fc_stype : 2;
u64 fc_hyst_bits : 4;
u64 fc_up_crossing : 1;
u64 reserved_297_299 : 3;
u64 update_time : 16;
u64 reserved_316_319 : 4;
u64 fc_addr; /* W5 */
u64 ptr_start; /* W6 */
u64 ptr_end; /* W7 */
u64 bpid_0 : 12;
u64 reserved_524_535 : 12;
u64 err_int : 8;
u64 err_int_ena : 8;
u64 thresh_int : 1;
u64 thresh_int_ena : 1;
u64 thresh_up : 1;
u64 reserved_555 : 1;
u64 thresh_qint_idx : 7;
u64 reserved_563 : 1;
u64 err_qint_idx : 7;
u64 reserved_571_575 : 5;
u64 thresh : 36;
u64 rsvd_612_615 : 4;
u64 fc_msh_dst : 11;
u64 reserved_627_630 : 4;
u64 op_dpc_ena : 1;
u64 op_dpc_set : 5;
u64 reserved_637_637 : 1;
u64 stream_ctx : 1;
u64 reserved_639 : 1;
u64 reserved_640_703; /* W10 */
u64 reserved_704_767; /* W11 */
u64 reserved_768_831; /* W12 */
u64 reserved_832_895; /* W13 */
u64 reserved_896_959; /* W14 */
u64 reserved_960_1023; /* W15 */
};
static_assert(sizeof(struct npa_cn20k_pool_s) == NIX_MAX_CTX_SIZE);
#endif