// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Admin Function driver
*
* Copyright (C) 2019 Marvell.
*
*/
#ifdef CONFIG_DEBUG_FS
#include <linux/fs.h>
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "rvu_struct.h"
#include "rvu_reg.h"
#include "rvu.h"
#include "cgx.h"
#include "lmac_common.h"
#include "npc.h"
#include "rvu_npc_hash.h"
#include "mcs.h"
#define DEBUGFS_DIR_NAME "octeontx2"
enum {
CGX_STAT0,
CGX_STAT1,
CGX_STAT2,
CGX_STAT3,
CGX_STAT4,
CGX_STAT5,
CGX_STAT6,
CGX_STAT7,
CGX_STAT8,
CGX_STAT9,
CGX_STAT10,
CGX_STAT11,
CGX_STAT12,
CGX_STAT13,
CGX_STAT14,
CGX_STAT15,
CGX_STAT16,
CGX_STAT17,
CGX_STAT18,
};
static char *cgx_rx_stats_fields[] = {
[CGX_STAT0] = "Received packets" ,
[CGX_STAT1] = "Octets of received packets" ,
[CGX_STAT2] = "Received PAUSE packets" ,
[CGX_STAT3] = "Received PAUSE and control packets" ,
[CGX_STAT4] = "Filtered DMAC0 (NIX-bound) packets" ,
[CGX_STAT5] = "Filtered DMAC0 (NIX-bound) octets" ,
[CGX_STAT6] = "Packets dropped due to RX FIFO full" ,
[CGX_STAT7] = "Octets dropped due to RX FIFO full" ,
[CGX_STAT8] = "Error packets" ,
[CGX_STAT9] = "Filtered DMAC1 (NCSI-bound) packets" ,
[CGX_STAT10] = "Filtered DMAC1 (NCSI-bound) octets" ,
[CGX_STAT11] = "NCSI-bound packets dropped" ,
[CGX_STAT12] = "NCSI-bound octets dropped" ,
};
static char *cgx_tx_stats_fields[] = {
[CGX_STAT0] = "Packets dropped due to excessive collisions" ,
[CGX_STAT1] = "Packets dropped due to excessive deferral" ,
[CGX_STAT2] = "Multiple collisions before successful transmission" ,
[CGX_STAT3] = "Single collisions before successful transmission" ,
[CGX_STAT4] = "Total octets sent on the interface" ,
[CGX_STAT5] = "Total frames sent on the interface" ,
[CGX_STAT6] = "Packets sent with an octet count < 64" ,
[CGX_STAT7] = "Packets sent with an octet count == 64" ,
[CGX_STAT8] = "Packets sent with an octet count of 65-127" ,
[CGX_STAT9] = "Packets sent with an octet count of 128-255" ,
[CGX_STAT10] = "Packets sent with an octet count of 256-511" ,
[CGX_STAT11] = "Packets sent with an octet count of 512-1023" ,
[CGX_STAT12] = "Packets sent with an octet count of 1024-1518" ,
[CGX_STAT13] = "Packets sent with an octet count of > 1518" ,
[CGX_STAT14] = "Packets sent to a broadcast DMAC" ,
[CGX_STAT15] = "Packets sent to the multicast DMAC" ,
[CGX_STAT16] = "Transmit underflow and were truncated" ,
[CGX_STAT17] = "Control/PAUSE packets sent" ,
};
static char *rpm_rx_stats_fields[] = {
"Octets of received packets" ,
"Octets of received packets with out error" ,
"Received packets with alignment errors" ,
"Control/PAUSE packets received" ,
"Packets received with Frame too long Errors" ,
"Packets received with a1nrange length Errors" ,
"Received packets" ,
"Packets received with FrameCheckSequenceErrors" ,
"Packets received with VLAN header" ,
"Error packets" ,
"Packets received with unicast DMAC" ,
"Packets received with multicast DMAC" ,
"Packets received with broadcast DMAC" ,
"Dropped packets" ,
"Total frames received on interface" ,
"Packets received with an octet count < 64" ,
"Packets received with an octet count == 64" ,
"Packets received with an octet count of 65-127" ,
"Packets received with an octet count of 128-255" ,
"Packets received with an octet count of 256-511" ,
"Packets received with an octet count of 512-1023" ,
"Packets received with an octet count of 1024-1518" ,
"Packets received with an octet count of > 1518" ,
"Oversized Packets" ,
"Jabber Packets" ,
"Fragmented Packets" ,
"CBFC(class based flow control) pause frames received for class 0" ,
"CBFC pause frames received for class 1" ,
"CBFC pause frames received for class 2" ,
"CBFC pause frames received for class 3" ,
"CBFC pause frames received for class 4" ,
"CBFC pause frames received for class 5" ,
"CBFC pause frames received for class 6" ,
"CBFC pause frames received for class 7" ,
"CBFC pause frames received for class 8" ,
"CBFC pause frames received for class 9" ,
"CBFC pause frames received for class 10" ,
"CBFC pause frames received for class 11" ,
"CBFC pause frames received for class 12" ,
"CBFC pause frames received for class 13" ,
"CBFC pause frames received for class 14" ,
"CBFC pause frames received for class 15" ,
"MAC control packets received" ,
};
static char *rpm_tx_stats_fields[] = {
"Total octets sent on the interface" ,
"Total octets transmitted OK" ,
"Control/Pause frames sent" ,
"Total frames transmitted OK" ,
"Total frames sent with VLAN header" ,
"Error Packets" ,
"Packets sent to unicast DMAC" ,
"Packets sent to the multicast DMAC" ,
"Packets sent to a broadcast DMAC" ,
"Packets sent with an octet count == 64" ,
"Packets sent with an octet count of 65-127" ,
"Packets sent with an octet count of 128-255" ,
"Packets sent with an octet count of 256-511" ,
"Packets sent with an octet count of 512-1023" ,
"Packets sent with an octet count of 1024-1518" ,
"Packets sent with an octet count of > 1518" ,
"CBFC(class based flow control) pause frames transmitted for class 0" ,
"CBFC pause frames transmitted for class 1" ,
"CBFC pause frames transmitted for class 2" ,
"CBFC pause frames transmitted for class 3" ,
"CBFC pause frames transmitted for class 4" ,
"CBFC pause frames transmitted for class 5" ,
"CBFC pause frames transmitted for class 6" ,
"CBFC pause frames transmitted for class 7" ,
"CBFC pause frames transmitted for class 8" ,
"CBFC pause frames transmitted for class 9" ,
"CBFC pause frames transmitted for class 10" ,
"CBFC pause frames transmitted for class 11" ,
"CBFC pause frames transmitted for class 12" ,
"CBFC pause frames transmitted for class 13" ,
"CBFC pause frames transmitted for class 14" ,
"CBFC pause frames transmitted for class 15" ,
"MAC control packets sent" ,
"Total frames sent on the interface"
};
enum cpt_eng_type {
CPT_AE_TYPE = 1,
CPT_SE_TYPE = 2,
CPT_IE_TYPE = 3,
};
#define rvu_dbg_NULL NULL
#define rvu_dbg_open_NULL NULL
#define RVU_DEBUG_SEQ_FOPS(name, read_op, write_op) \
static int rvu_dbg_open_## name(struct inode *inode, struct file *file) \
{ \
return single_open(file, rvu_dbg_## read_op, inode->i_private); \
} \
static const struct file_operations rvu_dbg_## name## _fops = { \
.owner = THIS_MODULE, \
.open = rvu_dbg_open_## name, \
.read = seq_read, \
.write = rvu_dbg_## write_op, \
.llseek = seq_lseek, \
.release = single_release, \
}
#define RVU_DEBUG_FOPS(name, read_op, write_op) \
static const struct file_operations rvu_dbg_## name## _fops = { \
.owner = THIS_MODULE, \
.open = simple_open, \
.read = rvu_dbg_## read_op, \
.write = rvu_dbg_## write_op \
}
static void print_nix_qsize(struct seq_file *filp, struct rvu_pfvf *pfvf);
static int rvu_dbg_mcs_port_stats_display(struct seq_file *filp, void *unused, int dir)
{
struct mcs *mcs = filp->private ;
struct mcs_port_stats stats;
int lmac;
seq_puts(filp, "\n port stats\n" );
mutex_lock(&mcs->stats_lock);
for_each_set_bit(lmac, &mcs->hw->lmac_bmap, mcs->hw->lmac_cnt) {
mcs_get_port_stats(mcs, &stats, lmac, dir);
seq_printf(filp, "port%d: Tcam Miss: %lld\n" , lmac, stats.tcam_miss_cnt);
seq_printf(filp, "port%d: Parser errors: %lld\n" , lmac, stats.parser_err_cnt);
if (dir == MCS_RX && mcs->hw->mcs_blks > 1)
seq_printf(filp, "port%d: Preempt error: %lld\n" , lmac,
stats.preempt_err_cnt);
if (dir == MCS_TX)
seq_printf(filp, "port%d: Sectag insert error: %lld\n" , lmac,
stats.sectag_insert_err_cnt);
}
mutex_unlock(&mcs->stats_lock);
return 0;
}
static int rvu_dbg_mcs_rx_port_stats_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_mcs_port_stats_display(filp, unused, MCS_RX);
}
RVU_DEBUG_SEQ_FOPS(mcs_rx_port_stats, mcs_rx_port_stats_display, NULL);
static int rvu_dbg_mcs_tx_port_stats_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_mcs_port_stats_display(filp, unused, MCS_TX);
}
RVU_DEBUG_SEQ_FOPS(mcs_tx_port_stats, mcs_tx_port_stats_display, NULL);
static int rvu_dbg_mcs_sa_stats_display(struct seq_file *filp, void *unused, int dir)
{
struct mcs *mcs = filp->private ;
struct mcs_sa_stats stats;
struct rsrc_bmap *map;
int sa_id;
if (dir == MCS_TX) {
map = &mcs->tx.sa;
mutex_lock(&mcs->stats_lock);
for_each_set_bit(sa_id, map->bmap, mcs->hw->sa_entries) {
seq_puts(filp, "\n TX SA stats\n" );
mcs_get_sa_stats(mcs, &stats, sa_id, MCS_TX);
seq_printf(filp, "sa%d: Pkts encrypted: %lld\n" , sa_id,
stats.pkt_encrypt_cnt);
seq_printf(filp, "sa%d: Pkts protected: %lld\n" , sa_id,
stats.pkt_protected_cnt);
}
mutex_unlock(&mcs->stats_lock);
return 0;
}
/* RX stats */
map = &mcs->rx.sa;
mutex_lock(&mcs->stats_lock);
for_each_set_bit(sa_id, map->bmap, mcs->hw->sa_entries) {
seq_puts(filp, "\n RX SA stats\n" );
mcs_get_sa_stats(mcs, &stats, sa_id, MCS_RX);
seq_printf(filp, "sa%d: Invalid pkts: %lld\n" , sa_id, stats.pkt_invalid_cnt);
seq_printf(filp, "sa%d: Pkts no sa error: %lld\n" , sa_id, stats.pkt_nosaerror_cnt);
seq_printf(filp, "sa%d: Pkts not valid: %lld\n" , sa_id, stats.pkt_notvalid_cnt);
seq_printf(filp, "sa%d: Pkts ok: %lld\n" , sa_id, stats.pkt_ok_cnt);
seq_printf(filp, "sa%d: Pkts no sa: %lld\n" , sa_id, stats.pkt_nosa_cnt);
}
mutex_unlock(&mcs->stats_lock);
return 0;
}
static int rvu_dbg_mcs_rx_sa_stats_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_mcs_sa_stats_display(filp, unused, MCS_RX);
}
RVU_DEBUG_SEQ_FOPS(mcs_rx_sa_stats, mcs_rx_sa_stats_display, NULL);
static int rvu_dbg_mcs_tx_sa_stats_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_mcs_sa_stats_display(filp, unused, MCS_TX);
}
RVU_DEBUG_SEQ_FOPS(mcs_tx_sa_stats, mcs_tx_sa_stats_display, NULL);
static int rvu_dbg_mcs_tx_sc_stats_display(struct seq_file *filp, void *unused)
{
struct mcs *mcs = filp->private ;
struct mcs_sc_stats stats;
struct rsrc_bmap *map;
int sc_id;
map = &mcs->tx.sc;
seq_puts(filp, "\n SC stats\n" );
mutex_lock(&mcs->stats_lock);
for_each_set_bit(sc_id, map->bmap, mcs->hw->sc_entries) {
mcs_get_sc_stats(mcs, &stats, sc_id, MCS_TX);
seq_printf(filp, "\n=======sc%d======\n\n" , sc_id);
seq_printf(filp, "sc%d: Pkts encrypted: %lld\n" , sc_id, stats.pkt_encrypt_cnt);
seq_printf(filp, "sc%d: Pkts protected: %lld\n" , sc_id, stats.pkt_protected_cnt);
if (mcs->hw->mcs_blks == 1) {
seq_printf(filp, "sc%d: Octets encrypted: %lld\n" , sc_id,
stats.octet_encrypt_cnt);
seq_printf(filp, "sc%d: Octets protected: %lld\n" , sc_id,
stats.octet_protected_cnt);
}
}
mutex_unlock(&mcs->stats_lock);
return 0;
}
RVU_DEBUG_SEQ_FOPS(mcs_tx_sc_stats, mcs_tx_sc_stats_display, NULL);
static int rvu_dbg_mcs_rx_sc_stats_display(struct seq_file *filp, void *unused)
{
struct mcs *mcs = filp->private ;
struct mcs_sc_stats stats;
struct rsrc_bmap *map;
int sc_id;
map = &mcs->rx.sc;
seq_puts(filp, "\n SC stats\n" );
mutex_lock(&mcs->stats_lock);
for_each_set_bit(sc_id, map->bmap, mcs->hw->sc_entries) {
mcs_get_sc_stats(mcs, &stats, sc_id, MCS_RX);
seq_printf(filp, "\n=======sc%d======\n\n" , sc_id);
seq_printf(filp, "sc%d: Cam hits: %lld\n" , sc_id, stats.hit_cnt);
seq_printf(filp, "sc%d: Invalid pkts: %lld\n" , sc_id, stats.pkt_invalid_cnt);
seq_printf(filp, "sc%d: Late pkts: %lld\n" , sc_id, stats.pkt_late_cnt);
seq_printf(filp, "sc%d: Notvalid pkts: %lld\n" , sc_id, stats.pkt_notvalid_cnt);
seq_printf(filp, "sc%d: Unchecked pkts: %lld\n" , sc_id, stats.pkt_unchecked_cnt);
if (mcs->hw->mcs_blks > 1) {
seq_printf(filp, "sc%d: Delay pkts: %lld\n" , sc_id, stats.pkt_delay_cnt);
seq_printf(filp, "sc%d: Pkts ok: %lld\n" , sc_id, stats.pkt_ok_cnt);
}
if (mcs->hw->mcs_blks == 1) {
seq_printf(filp, "sc%d: Octets decrypted: %lld\n" , sc_id,
stats.octet_decrypt_cnt);
seq_printf(filp, "sc%d: Octets validated: %lld\n" , sc_id,
stats.octet_validate_cnt);
}
}
mutex_unlock(&mcs->stats_lock);
return 0;
}
RVU_DEBUG_SEQ_FOPS(mcs_rx_sc_stats, mcs_rx_sc_stats_display, NULL);
static int rvu_dbg_mcs_flowid_stats_display(struct seq_file *filp, void *unused, int dir)
{
struct mcs *mcs = filp->private ;
struct mcs_flowid_stats stats;
struct rsrc_bmap *map;
int flow_id;
seq_puts(filp, "\n Flowid stats\n" );
if (dir == MCS_RX)
map = &mcs->rx.flow_ids;
else
map = &mcs->tx.flow_ids;
mutex_lock(&mcs->stats_lock);
for_each_set_bit(flow_id, map->bmap, mcs->hw->tcam_entries) {
mcs_get_flowid_stats(mcs, &stats, flow_id, dir);
seq_printf(filp, "Flowid%d: Hit:%lld\n" , flow_id, stats.tcam_hit_cnt);
}
mutex_unlock(&mcs->stats_lock);
return 0;
}
static int rvu_dbg_mcs_tx_flowid_stats_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_mcs_flowid_stats_display(filp, unused, MCS_TX);
}
RVU_DEBUG_SEQ_FOPS(mcs_tx_flowid_stats, mcs_tx_flowid_stats_display, NULL);
static int rvu_dbg_mcs_rx_flowid_stats_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_mcs_flowid_stats_display(filp, unused, MCS_RX);
}
RVU_DEBUG_SEQ_FOPS(mcs_rx_flowid_stats, mcs_rx_flowid_stats_display, NULL);
static int rvu_dbg_mcs_tx_secy_stats_display(struct seq_file *filp, void *unused)
{
struct mcs *mcs = filp->private ;
struct mcs_secy_stats stats;
struct rsrc_bmap *map;
int secy_id;
map = &mcs->tx.secy;
seq_puts(filp, "\n MCS TX secy stats\n" );
mutex_lock(&mcs->stats_lock);
for_each_set_bit(secy_id, map->bmap, mcs->hw->secy_entries) {
mcs_get_tx_secy_stats(mcs, &stats, secy_id);
seq_printf(filp, "\n=======Secy%d======\n\n" , secy_id);
seq_printf(filp, "secy%d: Ctrl bcast pkts: %lld\n" , secy_id,
stats.ctl_pkt_bcast_cnt);
seq_printf(filp, "secy%d: Ctrl Mcast pkts: %lld\n" , secy_id,
stats.ctl_pkt_mcast_cnt);
seq_printf(filp, "secy%d: Ctrl ucast pkts: %lld\n" , secy_id,
stats.ctl_pkt_ucast_cnt);
seq_printf(filp, "secy%d: Ctrl octets: %lld\n" , secy_id, stats.ctl_octet_cnt);
seq_printf(filp, "secy%d: Unctrl bcast cnt: %lld\n" , secy_id,
stats.unctl_pkt_bcast_cnt);
seq_printf(filp, "secy%d: Unctrl mcast pkts: %lld\n" , secy_id,
stats.unctl_pkt_mcast_cnt);
seq_printf(filp, "secy%d: Unctrl ucast pkts: %lld\n" , secy_id,
stats.unctl_pkt_ucast_cnt);
seq_printf(filp, "secy%d: Unctrl octets: %lld\n" , secy_id, stats.unctl_octet_cnt);
seq_printf(filp, "secy%d: Octet encrypted: %lld\n" , secy_id,
stats.octet_encrypted_cnt);
seq_printf(filp, "secy%d: octet protected: %lld\n" , secy_id,
stats.octet_protected_cnt);
seq_printf(filp, "secy%d: Pkts on active sa: %lld\n" , secy_id,
stats.pkt_noactivesa_cnt);
seq_printf(filp, "secy%d: Pkts too long: %lld\n" , secy_id, stats.pkt_toolong_cnt);
seq_printf(filp, "secy%d: Pkts untagged: %lld\n" , secy_id, stats.pkt_untagged_cnt);
}
mutex_unlock(&mcs->stats_lock);
return 0;
}
RVU_DEBUG_SEQ_FOPS(mcs_tx_secy_stats, mcs_tx_secy_stats_display, NULL);
static int rvu_dbg_mcs_rx_secy_stats_display(struct seq_file *filp, void *unused)
{
struct mcs *mcs = filp->private ;
struct mcs_secy_stats stats;
struct rsrc_bmap *map;
int secy_id;
map = &mcs->rx.secy;
seq_puts(filp, "\n MCS secy stats\n" );
mutex_lock(&mcs->stats_lock);
for_each_set_bit(secy_id, map->bmap, mcs->hw->secy_entries) {
mcs_get_rx_secy_stats(mcs, &stats, secy_id);
seq_printf(filp, "\n=======Secy%d======\n\n" , secy_id);
seq_printf(filp, "secy%d: Ctrl bcast pkts: %lld\n" , secy_id,
stats.ctl_pkt_bcast_cnt);
seq_printf(filp, "secy%d: Ctrl Mcast pkts: %lld\n" , secy_id,
stats.ctl_pkt_mcast_cnt);
seq_printf(filp, "secy%d: Ctrl ucast pkts: %lld\n" , secy_id,
stats.ctl_pkt_ucast_cnt);
seq_printf(filp, "secy%d: Ctrl octets: %lld\n" , secy_id, stats.ctl_octet_cnt);
seq_printf(filp, "secy%d: Unctrl bcast cnt: %lld\n" , secy_id,
stats.unctl_pkt_bcast_cnt);
seq_printf(filp, "secy%d: Unctrl mcast pkts: %lld\n" , secy_id,
stats.unctl_pkt_mcast_cnt);
seq_printf(filp, "secy%d: Unctrl ucast pkts: %lld\n" , secy_id,
stats.unctl_pkt_ucast_cnt);
seq_printf(filp, "secy%d: Unctrl octets: %lld\n" , secy_id, stats.unctl_octet_cnt);
seq_printf(filp, "secy%d: Octet decrypted: %lld\n" , secy_id,
stats.octet_decrypted_cnt);
seq_printf(filp, "secy%d: octet validated: %lld\n" , secy_id,
stats.octet_validated_cnt);
seq_printf(filp, "secy%d: Pkts on disable port: %lld\n" , secy_id,
stats.pkt_port_disabled_cnt);
seq_printf(filp, "secy%d: Pkts with badtag: %lld\n" , secy_id, stats.pkt_badtag_cnt);
seq_printf(filp, "secy%d: Pkts with no SA(sectag.tci.c=0): %lld\n" , secy_id,
stats.pkt_nosa_cnt);
seq_printf(filp, "secy%d: Pkts with nosaerror: %lld\n" , secy_id,
stats.pkt_nosaerror_cnt);
seq_printf(filp, "secy%d: Tagged ctrl pkts: %lld\n" , secy_id,
stats.pkt_tagged_ctl_cnt);
seq_printf(filp, "secy%d: Untaged pkts: %lld\n" , secy_id, stats.pkt_untaged_cnt);
seq_printf(filp, "secy%d: Ctrl pkts: %lld\n" , secy_id, stats.pkt_ctl_cnt);
if (mcs->hw->mcs_blks > 1)
seq_printf(filp, "secy%d: pkts notag: %lld\n" , secy_id,
stats.pkt_notag_cnt);
}
mutex_unlock(&mcs->stats_lock);
return 0;
}
RVU_DEBUG_SEQ_FOPS(mcs_rx_secy_stats, mcs_rx_secy_stats_display, NULL);
static void rvu_dbg_mcs_init(struct rvu *rvu)
{
struct mcs *mcs;
char dname[10];
int i;
if (!rvu->mcs_blk_cnt)
return ;
rvu->rvu_dbg.mcs_root = debugfs_create_dir("mcs" , rvu->rvu_dbg.root);
for (i = 0; i < rvu->mcs_blk_cnt; i++) {
mcs = mcs_get_pdata(i);
sprintf(dname, "mcs%d" , i);
rvu->rvu_dbg.mcs = debugfs_create_dir(dname,
rvu->rvu_dbg.mcs_root);
rvu->rvu_dbg.mcs_rx = debugfs_create_dir("rx_stats" , rvu->rvu_dbg.mcs);
debugfs_create_file("flowid" , 0600, rvu->rvu_dbg.mcs_rx, mcs,
&rvu_dbg_mcs_rx_flowid_stats_fops);
debugfs_create_file("secy" , 0600, rvu->rvu_dbg.mcs_rx, mcs,
&rvu_dbg_mcs_rx_secy_stats_fops);
debugfs_create_file("sc" , 0600, rvu->rvu_dbg.mcs_rx, mcs,
&rvu_dbg_mcs_rx_sc_stats_fops);
debugfs_create_file("sa" , 0600, rvu->rvu_dbg.mcs_rx, mcs,
&rvu_dbg_mcs_rx_sa_stats_fops);
debugfs_create_file("port" , 0600, rvu->rvu_dbg.mcs_rx, mcs,
&rvu_dbg_mcs_rx_port_stats_fops);
rvu->rvu_dbg.mcs_tx = debugfs_create_dir("tx_stats" , rvu->rvu_dbg.mcs);
debugfs_create_file("flowid" , 0600, rvu->rvu_dbg.mcs_tx, mcs,
&rvu_dbg_mcs_tx_flowid_stats_fops);
debugfs_create_file("secy" , 0600, rvu->rvu_dbg.mcs_tx, mcs,
&rvu_dbg_mcs_tx_secy_stats_fops);
debugfs_create_file("sc" , 0600, rvu->rvu_dbg.mcs_tx, mcs,
&rvu_dbg_mcs_tx_sc_stats_fops);
debugfs_create_file("sa" , 0600, rvu->rvu_dbg.mcs_tx, mcs,
&rvu_dbg_mcs_tx_sa_stats_fops);
debugfs_create_file("port" , 0600, rvu->rvu_dbg.mcs_tx, mcs,
&rvu_dbg_mcs_tx_port_stats_fops);
}
}
#define LMT_MAPTBL_ENTRY_SIZE 16
/* Dump LMTST map table */
static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp,
char __user *buffer,
size_t count, loff_t *ppos)
{
struct rvu *rvu = filp->private_data;
u64 lmt_addr, val, tbl_base;
int pf, vf, num_vfs, hw_vfs;
void __iomem *lmt_map_base;
int apr_pfs, apr_vfs;
int buf_size = 10240;
size_t off = 0;
int index = 0;
char *buf;
int ret;
/* don't allow partial reads */
if (*ppos != 0)
return 0;
buf = kzalloc(buf_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
tbl_base = rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_MAP_BASE);
val = rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_CFG);
apr_vfs = 1 << (val & 0xF);
apr_pfs = 1 << ((val >> 4) & 0x7);
lmt_map_base = ioremap_wc(tbl_base, apr_pfs * apr_vfs *
LMT_MAPTBL_ENTRY_SIZE);
if (!lmt_map_base) {
dev_err(rvu->dev, "Failed to setup lmt map table mapping!!\n" );
kfree(buf);
return false ;
}
off += scnprintf(&buf[off], buf_size - 1 - off,
"\n\t\t\t\t\tLmtst Map Table Entries" );
off += scnprintf(&buf[off], buf_size - 1 - off,
"\n\t\t\t\t\t=======================" );
off += scnprintf(&buf[off], buf_size - 1 - off, "\nPcifunc\t\t\t" );
off += scnprintf(&buf[off], buf_size - 1 - off, "Table Index\t\t" );
off += scnprintf(&buf[off], buf_size - 1 - off,
"Lmtline Base (word 0)\t\t" );
off += scnprintf(&buf[off], buf_size - 1 - off,
"Lmt Map Entry (word 1)" );
off += scnprintf(&buf[off], buf_size - 1 - off, "\n" );
for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
off += scnprintf(&buf[off], buf_size - 1 - off, "PF%d \t\t\t" ,
pf);
index = pf * apr_vfs * LMT_MAPTBL_ENTRY_SIZE;
off += scnprintf(&buf[off], buf_size - 1 - off, " 0x%llx\t\t" ,
(tbl_base + index));
lmt_addr = readq(lmt_map_base + index);
off += scnprintf(&buf[off], buf_size - 1 - off,
" 0x%016llx\t\t" , lmt_addr);
index += 8;
val = readq(lmt_map_base + index);
off += scnprintf(&buf[off], buf_size - 1 - off, " 0x%016llx\n" ,
val);
/* Reading num of VFs per PF */
rvu_get_pf_numvfs(rvu, pf, &num_vfs, &hw_vfs);
for (vf = 0; vf < num_vfs; vf++) {
index = (pf * apr_vfs * LMT_MAPTBL_ENTRY_SIZE) +
((vf + 1) * LMT_MAPTBL_ENTRY_SIZE);
off += scnprintf(&buf[off], buf_size - 1 - off,
"PF%d:VF%d \t\t" , pf, vf);
off += scnprintf(&buf[off], buf_size - 1 - off,
" 0x%llx\t\t" , (tbl_base + index));
lmt_addr = readq(lmt_map_base + index);
off += scnprintf(&buf[off], buf_size - 1 - off,
" 0x%016llx\t\t" , lmt_addr);
index += 8;
val = readq(lmt_map_base + index);
off += scnprintf(&buf[off], buf_size - 1 - off,
" 0x%016llx\n" , val);
}
}
off += scnprintf(&buf[off], buf_size - 1 - off, "\n" );
ret = min(off, count);
if (copy_to_user(buffer, buf, ret))
ret = -EFAULT;
kfree(buf);
iounmap(lmt_map_base);
if (ret < 0)
return ret;
*ppos = ret;
return ret;
}
RVU_DEBUG_FOPS(lmtst_map_table, lmtst_map_table_display, NULL);
static void get_lf_str_list(const struct rvu_block *block, int pcifunc,
char *lfs)
{
int lf = 0, seq = 0, len = 0, prev_lf = block->lf.max;
for_each_set_bit(lf, block->lf.bmap, block->lf.max) {
if (lf >= block->lf.max)
break ;
if (block->fn_map[lf] != pcifunc)
continue ;
if (lf == prev_lf + 1) {
prev_lf = lf;
seq = 1;
continue ;
}
if (seq)
len += sprintf(lfs + len, "-%d,%d" , prev_lf, lf);
else
len += (len ? sprintf(lfs + len, ",%d" , lf) :
sprintf(lfs + len, "%d" , lf));
prev_lf = lf;
seq = 0;
}
if (seq)
len += sprintf(lfs + len, "-%d" , prev_lf);
lfs[len] = '\0' ;
}
static int get_max_column_width(struct rvu *rvu)
{
int index, pf, vf, lf_str_size = 12, buf_size = 256;
struct rvu_block block;
u16 pcifunc;
char *buf;
buf = kzalloc(buf_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
for (vf = 0; vf <= rvu->hw->total_vfs; vf++) {
pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf);
if (!pcifunc)
continue ;
for (index = 0; index < BLK_COUNT; index++) {
block = rvu->hw->block[index];
if (!strlen(block.name))
continue ;
get_lf_str_list(&block, pcifunc, buf);
if (lf_str_size <= strlen(buf))
lf_str_size = strlen(buf) + 1;
}
}
}
kfree(buf);
return lf_str_size;
}
/* Dumps current provisioning status of all RVU block LFs */
static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,
char __user *buffer,
size_t count, loff_t *ppos)
{
int index, off = 0, flag = 0, len = 0, i = 0;
struct rvu *rvu = filp->private_data;
int bytes_not_copied = 0;
struct rvu_block block;
int pf, vf, pcifunc;
int buf_size = 2048;
int lf_str_size;
char *lfs;
char *buf;
/* don't allow partial reads */
if (*ppos != 0)
return 0;
buf = kzalloc(buf_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
/* Get the maximum width of a column */
lf_str_size = get_max_column_width(rvu);
lfs = kzalloc(lf_str_size, GFP_KERNEL);
if (!lfs) {
kfree(buf);
return -ENOMEM;
}
off += scnprintf(&buf[off], buf_size - 1 - off, "%-*s" , lf_str_size,
"pcifunc" );
for (index = 0; index < BLK_COUNT; index++)
if (strlen(rvu->hw->block[index].name)) {
off += scnprintf(&buf[off], buf_size - 1 - off,
"%-*s" , lf_str_size,
rvu->hw->block[index].name);
}
off += scnprintf(&buf[off], buf_size - 1 - off, "\n" );
bytes_not_copied = copy_to_user(buffer + (i * off), buf, off);
if (bytes_not_copied)
goto out;
i++;
*ppos += off;
for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
for (vf = 0; vf <= rvu->hw->total_vfs; vf++) {
off = 0;
flag = 0;
pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf);
if (!pcifunc)
continue ;
if (vf) {
sprintf(lfs, "PF%d:VF%d" , pf, vf - 1);
off = scnprintf(&buf[off],
buf_size - 1 - off,
"%-*s" , lf_str_size, lfs);
} else {
sprintf(lfs, "PF%d" , pf);
off = scnprintf(&buf[off],
buf_size - 1 - off,
"%-*s" , lf_str_size, lfs);
}
for (index = 0; index < BLK_COUNT; index++) {
block = rvu->hw->block[index];
if (!strlen(block.name))
continue ;
len = 0;
lfs[len] = '\0' ;
get_lf_str_list(&block, pcifunc, lfs);
if (strlen(lfs))
flag = 1;
off += scnprintf(&buf[off], buf_size - 1 - off,
"%-*s" , lf_str_size, lfs);
}
if (flag) {
off += scnprintf(&buf[off],
buf_size - 1 - off, "\n" );
bytes_not_copied = copy_to_user(buffer +
(i * off),
buf, off);
if (bytes_not_copied)
goto out;
i++;
*ppos += off;
}
}
}
out:
kfree(lfs);
kfree(buf);
if (bytes_not_copied)
return -EFAULT;
return *ppos;
}
RVU_DEBUG_FOPS(rsrc_status, rsrc_attach_status, NULL);
static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
{
char cgx[10], lmac[10], chan[10];
struct rvu *rvu = filp->private ;
struct pci_dev *pdev = NULL;
struct mac_ops *mac_ops;
struct rvu_pfvf *pfvf;
int pf, domain, blkid;
u8 cgx_id, lmac_id;
u16 pcifunc;
domain = 2;
mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));
/* There can be no CGX devices at all */
if (!mac_ops)
return 0;
seq_printf(filp, "PCI dev\t\tRVU PF Func\tNIX block\t%s\tLMAC\tCHAN\n" ,
mac_ops->name);
for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
if (!is_pf_cgxmapped(rvu, pf))
continue ;
pdev = pci_get_domain_bus_and_slot(domain, pf + 1, 0);
if (!pdev)
continue ;
cgx[0] = 0;
lmac[0] = 0;
pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
pfvf = rvu_get_pfvf(rvu, pcifunc);
if (pfvf->nix_blkaddr == BLKADDR_NIX0)
blkid = 0;
else
blkid = 1;
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id,
&lmac_id);
sprintf(cgx, "%s%d" , mac_ops->name, cgx_id);
sprintf(lmac, "LMAC%d" , lmac_id);
sprintf(chan, "%d" ,
rvu_nix_chan_cgx(rvu, cgx_id, lmac_id, 0));
seq_printf(filp, "%s\t0x%x\t\tNIX%d\t\t%s\t%s\t%s\n" ,
dev_name(&pdev->dev), pcifunc, blkid, cgx, lmac,
chan);
pci_dev_put(pdev);
}
return 0;
}
RVU_DEBUG_SEQ_FOPS(rvu_pf_cgx_map, rvu_pf_cgx_map_display, NULL);
static int rvu_dbg_rvu_fwdata_display(struct seq_file *s, void *unused)
{
struct rvu *rvu = s->private ;
struct rvu_fwdata *fwdata;
u8 mac[ETH_ALEN];
int count = 0, i;
if (!rvu->fwdata)
return -EAGAIN;
fwdata = rvu->fwdata;
seq_puts(s, "\nRVU Firmware Data:\n" );
seq_puts(s, "\n\t\tPTP INFORMATION\n" );
seq_puts(s, "\t\t===============\n" );
seq_printf(s, "\t\texternal clockrate \t :%x\n" ,
fwdata->ptp_ext_clk_rate);
seq_printf(s, "\t\texternal timestamp \t :%x\n" ,
fwdata->ptp_ext_tstamp);
seq_puts(s, "\n" );
seq_puts(s, "\n\t\tSDP CHANNEL INFORMATION\n" );
seq_puts(s, "\t\t=======================\n" );
seq_printf(s, "\t\tValid \t\t\t :%x\n" , fwdata->channel_data.valid);
seq_printf(s, "\t\tNode ID \t\t :%x\n" ,
fwdata->channel_data.info.node_id);
seq_printf(s, "\t\tNumber of VFs \t\t :%x\n" ,
fwdata->channel_data.info.max_vfs);
seq_printf(s, "\t\tNumber of PF-Rings \t :%x\n" ,
fwdata->channel_data.info.num_pf_rings);
seq_printf(s, "\t\tPF SRN \t\t\t :%x\n" ,
fwdata->channel_data.info.pf_srn);
seq_puts(s, "\n" );
seq_puts(s, "\n\t\tPF-INDEX MACADDRESS\n" );
seq_puts(s, "\t\t====================\n" );
for (i = 0; i < PF_MACNUM_MAX; i++) {
u64_to_ether_addr(fwdata->pf_macs[i], mac);
if (!is_zero_ether_addr(mac)) {
seq_printf(s, "\t\t %d %pM\n" , i, mac);
count++;
}
}
if (!count)
seq_puts(s, "\t\tNo valid address found\n" );
seq_puts(s, "\n\t\tVF-INDEX MACADDRESS\n" );
seq_puts(s, "\t\t====================\n" );
count = 0;
for (i = 0; i < VF_MACNUM_MAX; i++) {
u64_to_ether_addr(fwdata->vf_macs[i], mac);
if (!is_zero_ether_addr(mac)) {
seq_printf(s, "\t\t %d %pM\n" , i, mac);
count++;
}
}
if (!count)
seq_puts(s, "\t\tNo valid address found\n" );
return 0;
}
RVU_DEBUG_SEQ_FOPS(rvu_fwdata, rvu_fwdata_display, NULL);
static bool rvu_dbg_is_valid_lf(struct rvu *rvu, int blkaddr, int lf,
u16 *pcifunc)
{
struct rvu_block *block;
struct rvu_hwinfo *hw;
hw = rvu->hw;
block = &hw->block[blkaddr];
if (lf < 0 || lf >= block->lf.max) {
dev_warn(rvu->dev, "Invalid LF: valid range: 0-%d\n" ,
block->lf.max - 1);
return false ;
}
*pcifunc = block->fn_map[lf];
if (!*pcifunc) {
dev_warn(rvu->dev,
"This LF is not attached to any RVU PFFUNC\n" );
return false ;
}
return true ;
}
static void print_npa_qsize(struct seq_file *m, struct rvu_pfvf *pfvf)
{
char *buf;
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!buf)
return ;
if (!pfvf->aura_ctx) {
seq_puts(m, "Aura context is not initialized\n" );
} else {
bitmap_print_to_pagebuf(false , buf, pfvf->aura_bmap,
pfvf->aura_ctx->qsize);
seq_printf(m, "Aura count : %d\n" , pfvf->aura_ctx->qsize);
seq_printf(m, "Aura context ena/dis bitmap : %s\n" , buf);
}
if (!pfvf->pool_ctx) {
seq_puts(m, "Pool context is not initialized\n" );
} else {
bitmap_print_to_pagebuf(false , buf, pfvf->pool_bmap,
pfvf->pool_ctx->qsize);
seq_printf(m, "Pool count : %d\n" , pfvf->pool_ctx->qsize);
seq_printf(m, "Pool context ena/dis bitmap : %s\n" , buf);
}
kfree(buf);
}
/* The 'qsize' entry dumps current Aura/Pool context Qsize
* and each context's current enable/disable status in a bitmap.
*/
static int rvu_dbg_qsize_display(struct seq_file *s, void *unsused,
int blktype)
{
void (*print_qsize)(struct seq_file *s,
struct rvu_pfvf *pfvf) = NULL;
struct rvu_pfvf *pfvf;
struct rvu *rvu;
int qsize_id;
u16 pcifunc;
int blkaddr;
rvu = s->private ;
switch (blktype) {
case BLKTYPE_NPA:
qsize_id = rvu->rvu_dbg.npa_qsize_id;
print_qsize = print_npa_qsize;
break ;
case BLKTYPE_NIX:
qsize_id = rvu->rvu_dbg.nix_qsize_id;
print_qsize = print_nix_qsize;
break ;
default :
return -EINVAL;
}
if (blktype == BLKTYPE_NPA)
blkaddr = BLKADDR_NPA;
else
blkaddr = debugfs_get_aux_num(s->file);
if (!rvu_dbg_is_valid_lf(rvu, blkaddr, qsize_id, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
print_qsize(s, pfvf);
return 0;
}
static ssize_t rvu_dbg_qsize_write(struct file *file,
const char __user *buffer, size_t count,
loff_t *ppos, int blktype)
{
char *blk_string = (blktype == BLKTYPE_NPA) ? "npa" : "nix" ;
struct seq_file *seqfile = file->private_data;
char *cmd_buf, *cmd_buf_tmp, *subtoken;
struct rvu *rvu = seqfile->private ;
int blkaddr;
u16 pcifunc;
int ret, lf;
cmd_buf = memdup_user_nul(buffer, count);
if (IS_ERR(cmd_buf))
return -ENOMEM;
cmd_buf_tmp = strchr(cmd_buf, '\n' );
if (cmd_buf_tmp) {
*cmd_buf_tmp = '\0' ;
count = cmd_buf_tmp - cmd_buf + 1;
}
cmd_buf_tmp = cmd_buf;
subtoken = strsep(&cmd_buf, " " );
ret = subtoken ? kstrtoint(subtoken, 10, &lf) : -EINVAL;
if (cmd_buf)
ret = -EINVAL;
if (ret < 0 || !strncmp(subtoken, "help" , 4)) {
dev_info(rvu->dev, "Use echo <%s-lf > qsize\n" , blk_string);
goto qsize_write_done;
}
if (blktype == BLKTYPE_NPA)
blkaddr = BLKADDR_NPA;
else
blkaddr = debugfs_get_aux_num(file);
if (!rvu_dbg_is_valid_lf(rvu, blkaddr, lf, &pcifunc)) {
ret = -EINVAL;
goto qsize_write_done;
}
if (blktype == BLKTYPE_NPA)
rvu->rvu_dbg.npa_qsize_id = lf;
else
rvu->rvu_dbg.nix_qsize_id = lf;
qsize_write_done:
kfree(cmd_buf_tmp);
return ret ? ret : count;
}
static ssize_t rvu_dbg_npa_qsize_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
return rvu_dbg_qsize_write(filp, buffer, count, ppos,
BLKTYPE_NPA);
}
static int rvu_dbg_npa_qsize_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_qsize_display(filp, unused, BLKTYPE_NPA);
}
RVU_DEBUG_SEQ_FOPS(npa_qsize, npa_qsize_display, npa_qsize_write);
/* Dumps given NPA Aura's context */
static void print_npa_aura_ctx(struct seq_file *m, struct npa_aq_enq_rsp *rsp)
{
struct npa_aura_s *aura = &rsp->aura;
struct rvu *rvu = m->private ;
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: pool way mask\t%d\nW1: avg con\t\t%d\n" ,
aura->pool_way_mask, 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: nix0_bpid\t\t%d\nW2: nix1_bpid\t\t%d\n" ,
(u64)aura->count, aura->nix0_bpid, aura->nix1_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);
if (!is_rvu_otx2(rvu))
seq_printf(m, "W3: fc_be\t\t%d\n" , aura->fc_be);
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);
if (!is_rvu_otx2(rvu))
seq_printf(m, "W6: fc_msh_dst\t\t%d\n" , aura->fc_msh_dst);
}
/* Dumps given NPA Pool's context */
static void print_npa_pool_ctx(struct seq_file *m, struct npa_aq_enq_rsp *rsp)
{
struct npa_pool_s *pool = &rsp->pool;
struct rvu *rvu = m->private ;
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\nW1: stack_way_mask\t%d\n" ,
pool->stack_caching, pool->stack_way_mask);
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, "W3: op_pc \t\t%llu\n" , (u64)pool->op_pc);
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);
if (!is_rvu_otx2(rvu))
seq_printf(m, "W4: fc_be\t\t%d\n" , pool->fc_be);
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);
if (!is_rvu_otx2(rvu))
seq_printf(m, "W8: fc_msh_dst\t\t%d\n" , pool->fc_msh_dst);
}
/* Reads aura/pool's ctx from admin queue */
static int rvu_dbg_npa_ctx_display(struct seq_file *m, void *unused, int ctype)
{
void (*print_npa_ctx)(struct seq_file *m, struct npa_aq_enq_rsp *rsp);
struct npa_aq_enq_req aq_req;
struct npa_aq_enq_rsp rsp;
struct rvu_pfvf *pfvf;
int aura, rc, max_id;
int npalf, id, all;
struct rvu *rvu;
u16 pcifunc;
rvu = m->private ;
switch (ctype) {
case NPA_AQ_CTYPE_AURA:
npalf = rvu->rvu_dbg.npa_aura_ctx.lf;
id = rvu->rvu_dbg.npa_aura_ctx.id;
all = rvu->rvu_dbg.npa_aura_ctx.all;
break ;
case NPA_AQ_CTYPE_POOL:
npalf = rvu->rvu_dbg.npa_pool_ctx.lf;
id = rvu->rvu_dbg.npa_pool_ctx.id;
all = rvu->rvu_dbg.npa_pool_ctx.all;
break ;
default :
return -EINVAL;
}
if (!rvu_dbg_is_valid_lf(rvu, BLKADDR_NPA, npalf, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
if (ctype == NPA_AQ_CTYPE_AURA && !pfvf->aura_ctx) {
seq_puts(m, "Aura context is not initialized\n" );
return -EINVAL;
} else if (ctype == NPA_AQ_CTYPE_POOL && !pfvf->pool_ctx) {
seq_puts(m, "Pool context is not initialized\n" );
return -EINVAL;
}
memset(&aq_req, 0, sizeof (struct npa_aq_enq_req));
aq_req.hdr.pcifunc = pcifunc;
aq_req.ctype = ctype;
aq_req.op = NPA_AQ_INSTOP_READ;
if (ctype == NPA_AQ_CTYPE_AURA) {
max_id = pfvf->aura_ctx->qsize;
print_npa_ctx = print_npa_aura_ctx;
} else {
max_id = pfvf->pool_ctx->qsize;
print_npa_ctx = print_npa_pool_ctx;
}
if (id < 0 || id >= max_id) {
seq_printf(m, "Invalid %s, valid range is 0-%d\n" ,
(ctype == NPA_AQ_CTYPE_AURA) ? "aura" : "pool" ,
max_id - 1);
return -EINVAL;
}
if (all)
id = 0;
else
max_id = id + 1;
for (aura = id; aura < max_id; aura++) {
aq_req.aura_id = aura;
/* Skip if queue is uninitialized */
if (ctype == NPA_AQ_CTYPE_POOL && !test_bit(aura, pfvf->pool_bmap))
continue ;
seq_printf(m, "======%s : %d=======\n" ,
(ctype == NPA_AQ_CTYPE_AURA) ? "AURA" : "POOL" ,
aq_req.aura_id);
rc = rvu_npa_aq_enq_inst(rvu, &aq_req, &rsp);
if (rc) {
seq_puts(m, "Failed to read context\n" );
return -EINVAL;
}
print_npa_ctx(m, &rsp);
}
return 0;
}
static int write_npa_ctx(struct rvu *rvu, bool all,
int npalf, int id, int ctype)
{
struct rvu_pfvf *pfvf;
int max_id = 0;
u16 pcifunc;
if (!rvu_dbg_is_valid_lf(rvu, BLKADDR_NPA, npalf, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
if (ctype == NPA_AQ_CTYPE_AURA) {
if (!pfvf->aura_ctx) {
dev_warn(rvu->dev, "Aura context is not initialized\n" );
return -EINVAL;
}
max_id = pfvf->aura_ctx->qsize;
} else if (ctype == NPA_AQ_CTYPE_POOL) {
if (!pfvf->pool_ctx) {
dev_warn(rvu->dev, "Pool context is not initialized\n" );
return -EINVAL;
}
max_id = pfvf->pool_ctx->qsize;
}
if (id < 0 || id >= max_id) {
dev_warn(rvu->dev, "Invalid %s, valid range is 0-%d\n" ,
(ctype == NPA_AQ_CTYPE_AURA) ? "aura" : "pool" ,
max_id - 1);
return -EINVAL;
}
switch (ctype) {
case NPA_AQ_CTYPE_AURA:
rvu->rvu_dbg.npa_aura_ctx.lf = npalf;
rvu->rvu_dbg.npa_aura_ctx.id = id;
rvu->rvu_dbg.npa_aura_ctx.all = all;
break ;
case NPA_AQ_CTYPE_POOL:
rvu->rvu_dbg.npa_pool_ctx.lf = npalf;
rvu->rvu_dbg.npa_pool_ctx.id = id;
rvu->rvu_dbg.npa_pool_ctx.all = all;
break ;
default :
return -EINVAL;
}
return 0;
}
static int parse_cmd_buffer_ctx(char *cmd_buf, size_t *count,
const char __user *buffer, int *npalf,
int *id, bool *all)
{
int bytes_not_copied;
char *cmd_buf_tmp;
char *subtoken;
int ret;
bytes_not_copied = copy_from_user(cmd_buf, buffer, *count);
if (bytes_not_copied)
return -EFAULT;
cmd_buf[*count] = '\0' ;
cmd_buf_tmp = strchr(cmd_buf, '\n' );
if (cmd_buf_tmp) {
*cmd_buf_tmp = '\0' ;
*count = cmd_buf_tmp - cmd_buf + 1;
}
subtoken = strsep(&cmd_buf, " " );
ret = subtoken ? kstrtoint(subtoken, 10, npalf) : -EINVAL;
if (ret < 0)
return ret;
subtoken = strsep(&cmd_buf, " " );
if (subtoken && strcmp(subtoken, "all" ) == 0) {
*all = true ;
} else {
ret = subtoken ? kstrtoint(subtoken, 10, id) : -EINVAL;
if (ret < 0)
return ret;
}
if (cmd_buf)
return -EINVAL;
return ret;
}
static ssize_t rvu_dbg_npa_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos, int ctype)
{
char *cmd_buf, *ctype_string = (ctype == NPA_AQ_CTYPE_AURA) ?
"aura" : "pool" ;
struct seq_file *seqfp = filp->private_data;
struct rvu *rvu = seqfp->private ;
int npalf, id = 0, ret;
bool all = false ;
if ((*ppos != 0) || !count)
return -EINVAL;
cmd_buf = kzalloc(count + 1, GFP_KERNEL);
if (!cmd_buf)
return count;
ret = parse_cmd_buffer_ctx(cmd_buf, &count, buffer,
&npalf, &id, &all);
if (ret < 0) {
dev_info(rvu->dev,
"Usage: echo <npalf> [%s number/all] > %s_ctx\n" ,
ctype_string, ctype_string);
goto done;
} else {
ret = write_npa_ctx(rvu, all, npalf, id, ctype);
}
done:
kfree(cmd_buf);
return ret ? ret : count;
}
static ssize_t rvu_dbg_npa_aura_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
return rvu_dbg_npa_ctx_write(filp, buffer, count, ppos,
NPA_AQ_CTYPE_AURA);
}
static int rvu_dbg_npa_aura_ctx_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_npa_ctx_display(filp, unused, NPA_AQ_CTYPE_AURA);
}
RVU_DEBUG_SEQ_FOPS(npa_aura_ctx, npa_aura_ctx_display, npa_aura_ctx_write);
static ssize_t rvu_dbg_npa_pool_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
return rvu_dbg_npa_ctx_write(filp, buffer, count, ppos,
NPA_AQ_CTYPE_POOL);
}
static int rvu_dbg_npa_pool_ctx_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_npa_ctx_display(filp, unused, NPA_AQ_CTYPE_POOL);
}
RVU_DEBUG_SEQ_FOPS(npa_pool_ctx, npa_pool_ctx_display, npa_pool_ctx_write);
static void ndc_cache_stats(struct seq_file *s, int blk_addr,
int ctype, int transaction)
{
u64 req, out_req, lat, cant_alloc;
struct nix_hw *nix_hw;
struct rvu *rvu;
int port;
if (blk_addr == BLKADDR_NDC_NPA0) {
rvu = s->private ;
} else {
nix_hw = s->private ;
rvu = nix_hw->rvu;
}
for (port = 0; port < NDC_MAX_PORT; port++) {
req = rvu_read64(rvu, blk_addr, NDC_AF_PORTX_RTX_RWX_REQ_PC
(port, ctype, transaction));
lat = rvu_read64(rvu, blk_addr, NDC_AF_PORTX_RTX_RWX_LAT_PC
(port, ctype, transaction));
out_req = rvu_read64(rvu, blk_addr,
NDC_AF_PORTX_RTX_RWX_OSTDN_PC
(port, ctype, transaction));
cant_alloc = rvu_read64(rvu, blk_addr,
NDC_AF_PORTX_RTX_CANT_ALLOC_PC
(port, transaction));
seq_printf(s, "\nPort:%d\n" , port);
seq_printf(s, "\tTotal Requests:\t\t%lld\n" , req);
seq_printf(s, "\tTotal Time Taken:\t%lld cycles\n" , lat);
seq_printf(s, "\tAvg Latency:\t\t%lld cycles\n" , lat / req);
seq_printf(s, "\tOutstanding Requests:\t%lld\n" , out_req);
seq_printf(s, "\tCant Alloc Requests:\t%lld\n" , cant_alloc);
}
}
static int ndc_blk_cache_stats(struct seq_file *s, int idx, int blk_addr)
{
seq_puts(s, "\n***** CACHE mode read stats *****\n" );
ndc_cache_stats(s, blk_addr, CACHING, NDC_READ_TRANS);
seq_puts(s, "\n***** CACHE mode write stats *****\n" );
ndc_cache_stats(s, blk_addr, CACHING, NDC_WRITE_TRANS);
seq_puts(s, "\n***** BY-PASS mode read stats *****\n" );
ndc_cache_stats(s, blk_addr, BYPASS, NDC_READ_TRANS);
seq_puts(s, "\n***** BY-PASS mode write stats *****\n" );
ndc_cache_stats(s, blk_addr, BYPASS, NDC_WRITE_TRANS);
return 0;
}
static int rvu_dbg_npa_ndc_cache_display(struct seq_file *filp, void *unused)
{
return ndc_blk_cache_stats(filp, NPA0_U, BLKADDR_NDC_NPA0);
}
RVU_DEBUG_SEQ_FOPS(npa_ndc_cache, npa_ndc_cache_display, NULL);
static int ndc_blk_hits_miss_stats(struct seq_file *s, int idx, int blk_addr)
{
struct nix_hw *nix_hw;
struct rvu *rvu;
int bank, max_bank;
u64 ndc_af_const;
if (blk_addr == BLKADDR_NDC_NPA0) {
rvu = s->private ;
} else {
nix_hw = s->private ;
rvu = nix_hw->rvu;
}
ndc_af_const = rvu_read64(rvu, blk_addr, NDC_AF_CONST);
max_bank = FIELD_GET(NDC_AF_BANK_MASK, ndc_af_const);
for (bank = 0; bank < max_bank; bank++) {
seq_printf(s, "BANK:%d\n" , bank);
seq_printf(s, "\tHits:\t%lld\n" ,
(u64)rvu_read64(rvu, blk_addr,
NDC_AF_BANKX_HIT_PC(bank)));
seq_printf(s, "\tMiss:\t%lld\n" ,
(u64)rvu_read64(rvu, blk_addr,
NDC_AF_BANKX_MISS_PC(bank)));
}
return 0;
}
static int rvu_dbg_nix_ndc_rx_cache_display(struct seq_file *filp, void *unused)
{
struct nix_hw *nix_hw = filp->private ;
int blkaddr = 0;
int ndc_idx = 0;
blkaddr = (nix_hw->blkaddr == BLKADDR_NIX1 ?
BLKADDR_NDC_NIX1_RX : BLKADDR_NDC_NIX0_RX);
ndc_idx = (nix_hw->blkaddr == BLKADDR_NIX1 ? NIX1_RX : NIX0_RX);
return ndc_blk_cache_stats(filp, ndc_idx, blkaddr);
}
RVU_DEBUG_SEQ_FOPS(nix_ndc_rx_cache, nix_ndc_rx_cache_display, NULL);
static int rvu_dbg_nix_ndc_tx_cache_display(struct seq_file *filp, void *unused)
{
struct nix_hw *nix_hw = filp->private ;
int blkaddr = 0;
int ndc_idx = 0;
blkaddr = (nix_hw->blkaddr == BLKADDR_NIX1 ?
BLKADDR_NDC_NIX1_TX : BLKADDR_NDC_NIX0_TX);
ndc_idx = (nix_hw->blkaddr == BLKADDR_NIX1 ? NIX1_TX : NIX0_TX);
return ndc_blk_cache_stats(filp, ndc_idx, blkaddr);
}
RVU_DEBUG_SEQ_FOPS(nix_ndc_tx_cache, nix_ndc_tx_cache_display, NULL);
static int rvu_dbg_npa_ndc_hits_miss_display(struct seq_file *filp,
void *unused)
{
return ndc_blk_hits_miss_stats(filp, NPA0_U, BLKADDR_NDC_NPA0);
}
RVU_DEBUG_SEQ_FOPS(npa_ndc_hits_miss, npa_ndc_hits_miss_display, NULL);
static int rvu_dbg_nix_ndc_rx_hits_miss_display(struct seq_file *filp,
void *unused)
{
struct nix_hw *nix_hw = filp->private ;
int ndc_idx = NPA0_U;
int blkaddr = 0;
blkaddr = (nix_hw->blkaddr == BLKADDR_NIX1 ?
BLKADDR_NDC_NIX1_RX : BLKADDR_NDC_NIX0_RX);
return ndc_blk_hits_miss_stats(filp, ndc_idx, blkaddr);
}
RVU_DEBUG_SEQ_FOPS(nix_ndc_rx_hits_miss, nix_ndc_rx_hits_miss_display, NULL);
static int rvu_dbg_nix_ndc_tx_hits_miss_display(struct seq_file *filp,
void *unused)
{
struct nix_hw *nix_hw = filp->private ;
int ndc_idx = NPA0_U;
int blkaddr = 0;
blkaddr = (nix_hw->blkaddr == BLKADDR_NIX1 ?
BLKADDR_NDC_NIX1_TX : BLKADDR_NDC_NIX0_TX);
return ndc_blk_hits_miss_stats(filp, ndc_idx, blkaddr);
}
RVU_DEBUG_SEQ_FOPS(nix_ndc_tx_hits_miss, nix_ndc_tx_hits_miss_display, NULL);
static void print_nix_cn10k_sq_ctx(struct seq_file *m,
struct nix_cn10k_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, "W2: 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->mnq_dis, sq_ctx->lmt_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, "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);
}
static void print_tm_tree(struct seq_file *m,
struct nix_aq_enq_rsp *rsp, u64 sq)
{
struct nix_sq_ctx_s *sq_ctx = &rsp->sq;
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
u16 p1, p2, p3, p4, schq;
int blkaddr;
u64 cfg;
blkaddr = nix_hw->blkaddr;
schq = sq_ctx->smq;
cfg = rvu_read64(rvu, blkaddr, NIX_AF_MDQX_PARENT(schq));
p1 = FIELD_GET(NIX_AF_MDQ_PARENT_MASK, cfg);
cfg = rvu_read64(rvu, blkaddr, NIX_AF_TL4X_PARENT(p1));
p2 = FIELD_GET(NIX_AF_TL4_PARENT_MASK, cfg);
cfg = rvu_read64(rvu, blkaddr, NIX_AF_TL3X_PARENT(p2));
p3 = FIELD_GET(NIX_AF_TL3_PARENT_MASK, cfg);
cfg = rvu_read64(rvu, blkaddr, NIX_AF_TL2X_PARENT(p3));
p4 = FIELD_GET(NIX_AF_TL2_PARENT_MASK, cfg);
seq_printf(m,
"SQ(%llu) -> SMQ(%u) -> TL4(%u) -> TL3(%u) -> TL2(%u) -> TL1(%u)\n" ,
sq, schq, p1, p2, p3, p4);
}
/*dumps given tm_tree registers*/
static int rvu_dbg_nix_tm_tree_display(struct seq_file *m, void *unused)
{
int qidx, nixlf, rc, id, max_id = 0;
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
struct nix_aq_enq_req aq_req;
struct nix_aq_enq_rsp rsp;
struct rvu_pfvf *pfvf;
u16 pcifunc;
nixlf = rvu->rvu_dbg.nix_tm_ctx.lf;
id = rvu->rvu_dbg.nix_tm_ctx.id;
if (!rvu_dbg_is_valid_lf(rvu, nix_hw->blkaddr, nixlf, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
max_id = pfvf->sq_ctx->qsize;
memset(&aq_req, 0, sizeof (struct nix_aq_enq_req));
aq_req.hdr.pcifunc = pcifunc;
aq_req.ctype = NIX_AQ_CTYPE_SQ;
aq_req.op = NIX_AQ_INSTOP_READ;
seq_printf(m, "pcifunc is 0x%x\n" , pcifunc);
for (qidx = id; qidx < max_id; qidx++) {
aq_req.qidx = qidx;
/* Skip SQ's if not initialized */
if (!test_bit(qidx, pfvf->sq_bmap))
continue ;
rc = rvu_mbox_handler_nix_aq_enq(rvu, &aq_req, &rsp);
if (rc) {
seq_printf(m, "Failed to read SQ(%d) context\n" ,
aq_req.qidx);
continue ;
}
print_tm_tree(m, &rsp, aq_req.qidx);
}
return 0;
}
static ssize_t rvu_dbg_nix_tm_tree_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
struct seq_file *m = filp->private_data;
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
struct rvu_pfvf *pfvf;
u16 pcifunc;
u64 nixlf;
int ret;
ret = kstrtoull_from_user(buffer, count, 10, &nixlf);
if (ret)
return ret;
if (!rvu_dbg_is_valid_lf(rvu, nix_hw->blkaddr, nixlf, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
if (!pfvf->sq_ctx) {
dev_warn(rvu->dev, "SQ context is not initialized\n" );
return -EINVAL;
}
rvu->rvu_dbg.nix_tm_ctx.lf = nixlf;
return count;
}
RVU_DEBUG_SEQ_FOPS(nix_tm_tree, nix_tm_tree_display, nix_tm_tree_write);
static void print_tm_topo(struct seq_file *m, u64 schq, u32 lvl)
{
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
int blkaddr, link, link_level;
struct rvu_hwinfo *hw;
hw = rvu->hw;
blkaddr = nix_hw->blkaddr;
if (lvl == NIX_TXSCH_LVL_MDQ) {
seq_printf(m, "NIX_AF_SMQ[%llu]_CFG =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(schq)));
seq_printf(m, "NIX_AF_SMQ[%llu]_STATUS =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_SMQX_STATUS(schq)));
seq_printf(m, "NIX_AF_MDQ[%llu]_OUT_MD_COUNT =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_MDQX_OUT_MD_COUNT(schq)));
seq_printf(m, "NIX_AF_MDQ[%llu]_SCHEDULE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_MDQX_SCHEDULE(schq)));
seq_printf(m, "NIX_AF_MDQ[%llu]_SHAPE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_MDQX_SHAPE(schq)));
seq_printf(m, "NIX_AF_MDQ[%llu]_CIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_MDQX_CIR(schq)));
seq_printf(m, "NIX_AF_MDQ[%llu]_PIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_MDQX_PIR(schq)));
seq_printf(m, "NIX_AF_MDQ[%llu]_SW_XOFF =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_MDQX_SW_XOFF(schq)));
seq_printf(m, "NIX_AF_MDQ[%llu]_PARENT =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_MDQX_PARENT(schq)));
seq_puts(m, "\n" );
}
if (lvl == NIX_TXSCH_LVL_TL4) {
seq_printf(m, "NIX_AF_TL4[%llu]_SDP_LINK_CFG =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL4X_SDP_LINK_CFG(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_SCHEDULE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL4X_SCHEDULE(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_SHAPE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL4X_SHAPE(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_CIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL4X_CIR(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_PIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL4X_PIR(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_SW_XOFF =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL4X_SW_XOFF(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_TOPOLOGY =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL4X_TOPOLOGY(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_PARENT =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL4X_PARENT(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_MD_DEBUG0 =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL4X_MD_DEBUG0(schq)));
seq_printf(m, "NIX_AF_TL4[%llu]_MD_DEBUG1 =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL4X_MD_DEBUG1(schq)));
seq_puts(m, "\n" );
}
if (lvl == NIX_TXSCH_LVL_TL3) {
seq_printf(m, "NIX_AF_TL3[%llu]_SCHEDULE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL3X_SCHEDULE(schq)));
seq_printf(m, "NIX_AF_TL3[%llu]_SHAPE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL3X_SHAPE(schq)));
seq_printf(m, "NIX_AF_TL3[%llu]_CIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL3X_CIR(schq)));
seq_printf(m, "NIX_AF_TL3[%llu]_PIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL3X_PIR(schq)));
seq_printf(m, "NIX_AF_TL3[%llu]_SW_XOFF =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL3X_SW_XOFF(schq)));
seq_printf(m, "NIX_AF_TL3[%llu]_TOPOLOGY =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL3X_TOPOLOGY(schq)));
seq_printf(m, "NIX_AF_TL3[%llu]_PARENT =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL3X_PARENT(schq)));
seq_printf(m, "NIX_AF_TL3[%llu]_MD_DEBUG0 =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL3X_MD_DEBUG0(schq)));
seq_printf(m, "NIX_AF_TL3[%llu]_MD_DEBUG1 =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL3X_MD_DEBUG1(schq)));
link_level = rvu_read64(rvu, blkaddr, NIX_AF_PSE_CHANNEL_LEVEL)
& 0x01 ? NIX_TXSCH_LVL_TL3 : NIX_TXSCH_LVL_TL2;
if (lvl == link_level) {
seq_printf(m,
"NIX_AF_TL3_TL2[%llu]_BP_STATUS =0x%llx\n" ,
schq, rvu_read64(rvu, blkaddr,
NIX_AF_TL3_TL2X_BP_STATUS(schq)));
for (link = 0; link < hw->cgx_links; link++)
seq_printf(m,
"NIX_AF_TL3_TL2[%llu]_LINK[%d]_CFG =0x%llx\n" ,
schq, link,
rvu_read64(rvu, blkaddr,
NIX_AF_TL3_TL2X_LINKX_CFG(schq, link)));
}
seq_puts(m, "\n" );
}
if (lvl == NIX_TXSCH_LVL_TL2) {
seq_printf(m, "NIX_AF_TL2[%llu]_SHAPE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL2X_SHAPE(schq)));
seq_printf(m, "NIX_AF_TL2[%llu]_CIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL2X_CIR(schq)));
seq_printf(m, "NIX_AF_TL2[%llu]_PIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL2X_PIR(schq)));
seq_printf(m, "NIX_AF_TL2[%llu]_SW_XOFF =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL2X_SW_XOFF(schq)));
seq_printf(m, "NIX_AF_TL2[%llu]_TOPOLOGY =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL2X_TOPOLOGY(schq)));
seq_printf(m, "NIX_AF_TL2[%llu]_PARENT =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL2X_PARENT(schq)));
seq_printf(m, "NIX_AF_TL2[%llu]_MD_DEBUG0 =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL2X_MD_DEBUG0(schq)));
seq_printf(m, "NIX_AF_TL2[%llu]_MD_DEBUG1 =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL2X_MD_DEBUG1(schq)));
link_level = rvu_read64(rvu, blkaddr, NIX_AF_PSE_CHANNEL_LEVEL)
& 0x01 ? NIX_TXSCH_LVL_TL3 : NIX_TXSCH_LVL_TL2;
if (lvl == link_level) {
seq_printf(m,
"NIX_AF_TL3_TL2[%llu]_BP_STATUS =0x%llx\n" ,
schq, rvu_read64(rvu, blkaddr,
NIX_AF_TL3_TL2X_BP_STATUS(schq)));
for (link = 0; link < hw->cgx_links; link++)
seq_printf(m,
"NIX_AF_TL3_TL2[%llu]_LINK[%d]_CFG =0x%llx\n" ,
schq, link, rvu_read64(rvu, blkaddr,
NIX_AF_TL3_TL2X_LINKX_CFG(schq, link)));
}
seq_puts(m, "\n" );
}
if (lvl == NIX_TXSCH_LVL_TL1) {
seq_printf(m, "NIX_AF_TX_LINK[%llu]_NORM_CREDIT =0x%llx\n" ,
schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TX_LINKX_NORM_CREDIT(schq)));
seq_printf(m, "NIX_AF_TX_LINK[%llu]_HW_XOFF =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TX_LINKX_HW_XOFF(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_SCHEDULE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_SCHEDULE(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_SHAPE =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL1X_SHAPE(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_CIR =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL1X_CIR(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_SW_XOFF =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr, NIX_AF_TL1X_SW_XOFF(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_TOPOLOGY =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_TOPOLOGY(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_MD_DEBUG0 =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_MD_DEBUG0(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_MD_DEBUG1 =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_MD_DEBUG1(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_DROPPED_PACKETS =0x%llx\n" ,
schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_DROPPED_PACKETS(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_DROPPED_BYTES =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_DROPPED_BYTES(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_RED_PACKETS =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_RED_PACKETS(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_RED_BYTES =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_RED_BYTES(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_YELLOW_PACKETS =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_YELLOW_PACKETS(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_YELLOW_BYTES =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_YELLOW_BYTES(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_GREEN_PACKETS =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_GREEN_PACKETS(schq)));
seq_printf(m, "NIX_AF_TL1[%llu]_GREEN_BYTES =0x%llx\n" , schq,
rvu_read64(rvu, blkaddr,
NIX_AF_TL1X_GREEN_BYTES(schq)));
seq_puts(m, "\n" );
}
}
/*dumps given tm_topo registers*/
static int rvu_dbg_nix_tm_topo_display(struct seq_file *m, void *unused)
{
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
struct nix_aq_enq_req aq_req;
struct nix_txsch *txsch;
int nixlf, lvl, schq;
u16 pcifunc;
nixlf = rvu->rvu_dbg.nix_tm_ctx.lf;
if (!rvu_dbg_is_valid_lf(rvu, nix_hw->blkaddr, nixlf, &pcifunc))
return -EINVAL;
memset(&aq_req, 0, sizeof (struct nix_aq_enq_req));
aq_req.hdr.pcifunc = pcifunc;
aq_req.ctype = NIX_AQ_CTYPE_SQ;
aq_req.op = NIX_AQ_INSTOP_READ;
seq_printf(m, "pcifunc is 0x%x\n" , pcifunc);
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
txsch = &nix_hw->txsch[lvl];
for (schq = 0; schq < txsch->schq.max; schq++) {
if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) == pcifunc)
print_tm_topo(m, schq, lvl);
}
}
return 0;
}
static ssize_t rvu_dbg_nix_tm_topo_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
struct seq_file *m = filp->private_data;
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
struct rvu_pfvf *pfvf;
u16 pcifunc;
u64 nixlf;
int ret;
ret = kstrtoull_from_user(buffer, count, 10, &nixlf);
if (ret)
return ret;
if (!rvu_dbg_is_valid_lf(rvu, nix_hw->blkaddr, nixlf, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
if (!pfvf->sq_ctx) {
dev_warn(rvu->dev, "SQ context is not initialized\n" );
return -EINVAL;
}
rvu->rvu_dbg.nix_tm_ctx.lf = nixlf;
return count;
}
RVU_DEBUG_SEQ_FOPS(nix_tm_topo, nix_tm_topo_display, nix_tm_topo_write);
/* Dumps given nix_sq's context */
static void print_nix_sq_ctx(struct seq_file *m, struct nix_aq_enq_rsp *rsp)
{
struct nix_sq_ctx_s *sq_ctx = &rsp->sq;
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
if (!is_rvu_otx2(rvu)) {
print_nix_cn10k_sq_ctx(m, (struct nix_cn10k_sq_ctx_s *)sq_ctx);
return ;
}
seq_printf(m, "W0: sqe_way_mask \t\t%d\nW0: cq \t\t\t\t%d\n" ,
sq_ctx->sqe_way_mask, sq_ctx->cq);
seq_printf(m, "W0: sdp_mcast \t\t\t%d\nW0: substream \t\t\t0x%03x\n" ,
sq_ctx->sdp_mcast, sq_ctx->substream);
seq_printf(m, "W0: qint_idx \t\t\t%d\nW0: ena \t\t\t%d\n\n" ,
sq_ctx->qint_idx, sq_ctx->ena);
seq_printf(m, "W1: sqb_count \t\t\t%d\nW1: default_chan \t\t%d\n" ,
sq_ctx->sqb_count, sq_ctx->default_chan);
seq_printf(m, "W1: smq_rr_quantum \t\t%d\nW1: sso_ena \t\t\t%d\n" ,
sq_ctx->smq_rr_quantum, sq_ctx->sso_ena);
seq_printf(m, "W1: xoff \t\t\t%d\nW1: cq_ena \t\t\t%d\nW1: smq\t\t\t\t%d\n\n" ,
sq_ctx->xoff, sq_ctx->cq_ena, sq_ctx->smq);
seq_printf(m, "W2: sqe_stype \t\t\t%d\nW2: sq_int_ena \t\t\t%d\n" ,
sq_ctx->sqe_stype, sq_ctx->sq_int_ena);
seq_printf(m, "W2: sq_int \t\t\t%d\nW2: sqb_aura \t\t\t%d\n" ,
sq_ctx->sq_int, sq_ctx->sqb_aura);
seq_printf(m, "W2: smq_rr_count \t\t%d\n\n" , sq_ctx->smq_rr_count);
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, "W3: smenq_next_sqb_vld \t\t%d\nW3: head_offset\t\t\t%d\n" ,
sq_ctx->smenq_next_sqb_vld, sq_ctx->head_offset);
seq_printf(m, "W3: smenq_offset\t\t%d\nW3: tail_offset\t\t\t%d\n" ,
sq_ctx->smenq_offset, sq_ctx->tail_offset);
seq_printf(m, "W3: smq_lso_segnum \t\t%d\nW3: smq_next_sq\t\t\t%d\n" ,
sq_ctx->smq_lso_segnum, sq_ctx->smq_next_sq);
seq_printf(m, "W3: mnq_dis \t\t\t%d\nW3: lmt_dis \t\t\t%d\n" ,
sq_ctx->mnq_dis, sq_ctx->lmt_dis);
seq_printf(m, "W3: cq_limit\t\t\t%d\nW3: max_sqe_size\t\t%d\n\n" ,
sq_ctx->cq_limit, sq_ctx->max_sqe_size);
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_vld\t\t\t%d\nW9: vfi_lso_vlan1_ins_ena\t%d\n" ,
sq_ctx->vfi_lso_vld, sq_ctx->vfi_lso_vlan1_ins_ena);
seq_printf(m, "W9: vfi_lso_vlan0_ins_ena\t%d\nW9: vfi_lso_mps\t\t\t%d\n" ,
sq_ctx->vfi_lso_vlan0_ins_ena, sq_ctx->vfi_lso_mps);
seq_printf(m, "W9: vfi_lso_sb\t\t\t%d\nW9: vfi_lso_sizem1\t\t%d\n" ,
sq_ctx->vfi_lso_sb, sq_ctx->vfi_lso_sizem1);
seq_printf(m, "W9: vfi_lso_total\t\t%d\n\n" , sq_ctx->vfi_lso_total);
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, "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);
}
static void print_nix_cn10k_rq_ctx(struct seq_file *m,
struct nix_cn10k_rq_ctx_s *rq_ctx)
{
seq_printf(m, "W0: ena \t\t\t%d\nW0: sso_ena \t\t\t%d\n" ,
rq_ctx->ena, rq_ctx->sso_ena);
seq_printf(m, "W0: ipsech_ena \t\t\t%d\nW0: ena_wqwd \t\t\t%d\n" ,
rq_ctx->ipsech_ena, rq_ctx->ena_wqwd);
seq_printf(m, "W0: cq \t\t\t\t%d\nW0: lenerr_dis \t\t\t%d\n" ,
rq_ctx->cq, rq_ctx->lenerr_dis);
seq_printf(m, "W0: csum_il4_dis \t\t%d\nW0: csum_ol4_dis \t\t%d\n" ,
rq_ctx->csum_il4_dis, rq_ctx->csum_ol4_dis);
seq_printf(m, "W0: len_il4_dis \t\t%d\nW0: len_il3_dis \t\t%d\n" ,
rq_ctx->len_il4_dis, rq_ctx->len_il3_dis);
seq_printf(m, "W0: len_ol4_dis \t\t%d\nW0: len_ol3_dis \t\t%d\n" ,
rq_ctx->len_ol4_dis, rq_ctx->len_ol3_dis);
seq_printf(m, "W0: wqe_aura \t\t\t%d\n\n" , rq_ctx->wqe_aura);
seq_printf(m, "W1: spb_aura \t\t\t%d\nW1: lpb_aura \t\t\t%d\n" ,
rq_ctx->spb_aura, rq_ctx->lpb_aura);
seq_printf(m, "W1: spb_aura \t\t\t%d\n" , rq_ctx->spb_aura);
seq_printf(m, "W1: sso_grp \t\t\t%d\nW1: sso_tt \t\t\t%d\n" ,
rq_ctx->sso_grp, rq_ctx->sso_tt);
seq_printf(m, "W1: pb_caching \t\t\t%d\nW1: wqe_caching \t\t%d\n" ,
rq_ctx->pb_caching, rq_ctx->wqe_caching);
seq_printf(m, "W1: xqe_drop_ena \t\t%d\nW1: spb_drop_ena \t\t%d\n" ,
rq_ctx->xqe_drop_ena, rq_ctx->spb_drop_ena);
seq_printf(m, "W1: lpb_drop_ena \t\t%d\nW1: pb_stashing \t\t%d\n" ,
rq_ctx->lpb_drop_ena, rq_ctx->pb_stashing);
seq_printf(m, "W1: ipsecd_drop_ena \t\t%d\nW1: chi_ena \t\t\t%d\n\n" ,
rq_ctx->ipsecd_drop_ena, rq_ctx->chi_ena);
seq_printf(m, "W2: band_prof_id \t\t%d\n" , rq_ctx->band_prof_id);
seq_printf(m, "W2: policer_ena \t\t%d\n" , rq_ctx->policer_ena);
seq_printf(m, "W2: spb_sizem1 \t\t\t%d\n" , rq_ctx->spb_sizem1);
seq_printf(m, "W2: wqe_skip \t\t\t%d\nW2: sqb_ena \t\t\t%d\n" ,
rq_ctx->wqe_skip, rq_ctx->spb_ena);
seq_printf(m, "W2: lpb_size1 \t\t\t%d\nW2: first_skip \t\t\t%d\n" ,
rq_ctx->lpb_sizem1, rq_ctx->first_skip);
seq_printf(m, "W2: later_skip\t\t\t%d\nW2: xqe_imm_size\t\t%d\n" ,
rq_ctx->later_skip, rq_ctx->xqe_imm_size);
seq_printf(m, "W2: xqe_imm_copy \t\t%d\nW2: xqe_hdr_split \t\t%d\n\n" ,
rq_ctx->xqe_imm_copy, rq_ctx->xqe_hdr_split);
seq_printf(m, "W3: xqe_drop \t\t\t%d\nW3: xqe_pass \t\t\t%d\n" ,
rq_ctx->xqe_drop, rq_ctx->xqe_pass);
seq_printf(m, "W3: wqe_pool_drop \t\t%d\nW3: wqe_pool_pass \t\t%d\n" ,
rq_ctx->wqe_pool_drop, rq_ctx->wqe_pool_pass);
seq_printf(m, "W3: spb_pool_drop \t\t%d\nW3: spb_pool_pass \t\t%d\n" ,
rq_ctx->spb_pool_drop, rq_ctx->spb_pool_pass);
seq_printf(m, "W3: spb_aura_drop \t\t%d\nW3: spb_aura_pass \t\t%d\n\n" ,
rq_ctx->spb_aura_pass, rq_ctx->spb_aura_drop);
seq_printf(m, "W4: lpb_aura_drop \t\t%d\nW3: lpb_aura_pass \t\t%d\n" ,
rq_ctx->lpb_aura_pass, rq_ctx->lpb_aura_drop);
seq_printf(m, "W4: lpb_pool_drop \t\t%d\nW3: lpb_pool_pass \t\t%d\n" ,
rq_ctx->lpb_pool_drop, rq_ctx->lpb_pool_pass);
seq_printf(m, "W4: rq_int \t\t\t%d\nW4: rq_int_ena\t\t\t%d\n" ,
rq_ctx->rq_int, rq_ctx->rq_int_ena);
seq_printf(m, "W4: qint_idx \t\t\t%d\n\n" , rq_ctx->qint_idx);
seq_printf(m, "W5: ltag \t\t\t%d\nW5: good_utag \t\t\t%d\n" ,
rq_ctx->ltag, rq_ctx->good_utag);
seq_printf(m, "W5: bad_utag \t\t\t%d\nW5: flow_tagw \t\t\t%d\n" ,
rq_ctx->bad_utag, rq_ctx->flow_tagw);
seq_printf(m, "W5: ipsec_vwqe \t\t\t%d\nW5: vwqe_ena \t\t\t%d\n" ,
rq_ctx->ipsec_vwqe, rq_ctx->vwqe_ena);
seq_printf(m, "W5: vwqe_wait \t\t\t%d\nW5: max_vsize_exp\t\t%d\n" ,
rq_ctx->vwqe_wait, rq_ctx->max_vsize_exp);
seq_printf(m, "W5: vwqe_skip \t\t\t%d\n\n" , rq_ctx->vwqe_skip);
seq_printf(m, "W6: octs \t\t\t%llu\n\n" , (u64)rq_ctx->octs);
seq_printf(m, "W7: pkts \t\t\t%llu\n\n" , (u64)rq_ctx->pkts);
seq_printf(m, "W8: drop_octs \t\t\t%llu\n\n" , (u64)rq_ctx->drop_octs);
seq_printf(m, "W9: drop_pkts \t\t\t%llu\n\n" , (u64)rq_ctx->drop_pkts);
seq_printf(m, "W10: re_pkts \t\t\t%llu\n" , (u64)rq_ctx->re_pkts);
}
/* Dumps given nix_rq's context */
static void print_nix_rq_ctx(struct seq_file *m, struct nix_aq_enq_rsp *rsp)
{
struct nix_rq_ctx_s *rq_ctx = &rsp->rq;
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
if (!is_rvu_otx2(rvu)) {
print_nix_cn10k_rq_ctx(m, (struct nix_cn10k_rq_ctx_s *)rq_ctx);
return ;
}
seq_printf(m, "W0: wqe_aura \t\t\t%d\nW0: substream \t\t\t0x%03x\n" ,
rq_ctx->wqe_aura, rq_ctx->substream);
seq_printf(m, "W0: cq \t\t\t\t%d\nW0: ena_wqwd \t\t\t%d\n" ,
rq_ctx->cq, rq_ctx->ena_wqwd);
seq_printf(m, "W0: ipsech_ena \t\t\t%d\nW0: sso_ena \t\t\t%d\n" ,
rq_ctx->ipsech_ena, rq_ctx->sso_ena);
seq_printf(m, "W0: ena \t\t\t%d\n\n" , rq_ctx->ena);
seq_printf(m, "W1: lpb_drop_ena \t\t%d\nW1: spb_drop_ena \t\t%d\n" ,
rq_ctx->lpb_drop_ena, rq_ctx->spb_drop_ena);
seq_printf(m, "W1: xqe_drop_ena \t\t%d\nW1: wqe_caching \t\t%d\n" ,
rq_ctx->xqe_drop_ena, rq_ctx->wqe_caching);
seq_printf(m, "W1: pb_caching \t\t\t%d\nW1: sso_tt \t\t\t%d\n" ,
rq_ctx->pb_caching, rq_ctx->sso_tt);
seq_printf(m, "W1: sso_grp \t\t\t%d\nW1: lpb_aura \t\t\t%d\n" ,
rq_ctx->sso_grp, rq_ctx->lpb_aura);
seq_printf(m, "W1: spb_aura \t\t\t%d\n\n" , rq_ctx->spb_aura);
seq_printf(m, "W2: xqe_hdr_split \t\t%d\nW2: xqe_imm_copy \t\t%d\n" ,
rq_ctx->xqe_hdr_split, rq_ctx->xqe_imm_copy);
seq_printf(m, "W2: xqe_imm_size \t\t%d\nW2: later_skip \t\t\t%d\n" ,
rq_ctx->xqe_imm_size, rq_ctx->later_skip);
seq_printf(m, "W2: first_skip \t\t\t%d\nW2: lpb_sizem1 \t\t\t%d\n" ,
rq_ctx->first_skip, rq_ctx->lpb_sizem1);
seq_printf(m, "W2: spb_ena \t\t\t%d\nW2: wqe_skip \t\t\t%d\n" ,
rq_ctx->spb_ena, rq_ctx->wqe_skip);
seq_printf(m, "W2: spb_sizem1 \t\t\t%d\n\n" , rq_ctx->spb_sizem1);
seq_printf(m, "W3: spb_pool_pass \t\t%d\nW3: spb_pool_drop \t\t%d\n" ,
rq_ctx->spb_pool_pass, rq_ctx->spb_pool_drop);
seq_printf(m, "W3: spb_aura_pass \t\t%d\nW3: spb_aura_drop \t\t%d\n" ,
rq_ctx->spb_aura_pass, rq_ctx->spb_aura_drop);
seq_printf(m, "W3: wqe_pool_pass \t\t%d\nW3: wqe_pool_drop \t\t%d\n" ,
rq_ctx->wqe_pool_pass, rq_ctx->wqe_pool_drop);
seq_printf(m, "W3: xqe_pass \t\t\t%d\nW3: xqe_drop \t\t\t%d\n\n" ,
rq_ctx->xqe_pass, rq_ctx->xqe_drop);
seq_printf(m, "W4: qint_idx \t\t\t%d\nW4: rq_int_ena \t\t\t%d\n" ,
rq_ctx->qint_idx, rq_ctx->rq_int_ena);
seq_printf(m, "W4: rq_int \t\t\t%d\nW4: lpb_pool_pass \t\t%d\n" ,
rq_ctx->rq_int, rq_ctx->lpb_pool_pass);
seq_printf(m, "W4: lpb_pool_drop \t\t%d\nW4: lpb_aura_pass \t\t%d\n" ,
rq_ctx->lpb_pool_drop, rq_ctx->lpb_aura_pass);
seq_printf(m, "W4: lpb_aura_drop \t\t%d\n\n" , rq_ctx->lpb_aura_drop);
seq_printf(m, "W5: flow_tagw \t\t\t%d\nW5: bad_utag \t\t\t%d\n" ,
rq_ctx->flow_tagw, rq_ctx->bad_utag);
seq_printf(m, "W5: good_utag \t\t\t%d\nW5: ltag \t\t\t%d\n\n" ,
rq_ctx->good_utag, rq_ctx->ltag);
seq_printf(m, "W6: octs \t\t\t%llu\n\n" , (u64)rq_ctx->octs);
seq_printf(m, "W7: pkts \t\t\t%llu\n\n" , (u64)rq_ctx->pkts);
seq_printf(m, "W8: drop_octs \t\t\t%llu\n\n" , (u64)rq_ctx->drop_octs);
seq_printf(m, "W9: drop_pkts \t\t\t%llu\n\n" , (u64)rq_ctx->drop_pkts);
seq_printf(m, "W10: re_pkts \t\t\t%llu\n" , (u64)rq_ctx->re_pkts);
}
/* Dumps given nix_cq's context */
static void print_nix_cq_ctx(struct seq_file *m, struct nix_aq_enq_rsp *rsp)
{
struct nix_cq_ctx_s *cq_ctx = &rsp->cq;
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
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);
if (!is_rvu_otx2(rvu)) {
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:caching \t\t\t%d\n" ,
cq_ctx->qsize, cq_ctx->caching);
seq_printf(m, "W3: substream \t\t\t0x%03x\nW3: ena \t\t\t%d\n" ,
cq_ctx->substream, cq_ctx->ena);
if (!is_rvu_otx2(rvu)) {
seq_printf(m, "W3: lbp_frac \t\t\t%d\n" , cq_ctx->lbp_frac);
seq_printf(m, "W3: cpt_drop_err_en \t\t\t%d\n" ,
cq_ctx->cpt_drop_err_en);
}
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);
}
static int rvu_dbg_nix_queue_ctx_display(struct seq_file *filp,
void *unused, int ctype)
{
void (*print_nix_ctx)(struct seq_file *filp,
struct nix_aq_enq_rsp *rsp) = NULL;
struct nix_hw *nix_hw = filp->private ;
struct rvu *rvu = nix_hw->rvu;
struct nix_aq_enq_req aq_req;
struct nix_aq_enq_rsp rsp;
char *ctype_string = NULL;
int qidx, rc, max_id = 0;
struct rvu_pfvf *pfvf;
int nixlf, id, all;
u16 pcifunc;
switch (ctype) {
case NIX_AQ_CTYPE_CQ:
nixlf = rvu->rvu_dbg.nix_cq_ctx.lf;
id = rvu->rvu_dbg.nix_cq_ctx.id;
all = rvu->rvu_dbg.nix_cq_ctx.all;
break ;
case NIX_AQ_CTYPE_SQ:
nixlf = rvu->rvu_dbg.nix_sq_ctx.lf;
id = rvu->rvu_dbg.nix_sq_ctx.id;
all = rvu->rvu_dbg.nix_sq_ctx.all;
break ;
case NIX_AQ_CTYPE_RQ:
nixlf = rvu->rvu_dbg.nix_rq_ctx.lf;
id = rvu->rvu_dbg.nix_rq_ctx.id;
all = rvu->rvu_dbg.nix_rq_ctx.all;
break ;
default :
return -EINVAL;
}
if (!rvu_dbg_is_valid_lf(rvu, nix_hw->blkaddr, nixlf, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
if (ctype == NIX_AQ_CTYPE_SQ && !pfvf->sq_ctx) {
seq_puts(filp, "SQ context is not initialized\n" );
return -EINVAL;
} else if (ctype == NIX_AQ_CTYPE_RQ && !pfvf->rq_ctx) {
seq_puts(filp, "RQ context is not initialized\n" );
return -EINVAL;
} else if (ctype == NIX_AQ_CTYPE_CQ && !pfvf->cq_ctx) {
seq_puts(filp, "CQ context is not initialized\n" );
return -EINVAL;
}
if (ctype == NIX_AQ_CTYPE_SQ) {
max_id = pfvf->sq_ctx->qsize;
ctype_string = "sq" ;
print_nix_ctx = print_nix_sq_ctx;
} else if (ctype == NIX_AQ_CTYPE_RQ) {
max_id = pfvf->rq_ctx->qsize;
ctype_string = "rq" ;
print_nix_ctx = print_nix_rq_ctx;
} else if (ctype == NIX_AQ_CTYPE_CQ) {
max_id = pfvf->cq_ctx->qsize;
ctype_string = "cq" ;
print_nix_ctx = print_nix_cq_ctx;
}
memset(&aq_req, 0, sizeof (struct nix_aq_enq_req));
aq_req.hdr.pcifunc = pcifunc;
aq_req.ctype = ctype;
aq_req.op = NIX_AQ_INSTOP_READ;
if (all)
id = 0;
else
max_id = id + 1;
for (qidx = id; qidx < max_id; qidx++) {
aq_req.qidx = qidx;
seq_printf(filp, "=====%s_ctx for nixlf:%d and qidx:%d is=====\n" ,
ctype_string, nixlf, aq_req.qidx);
rc = rvu_mbox_handler_nix_aq_enq(rvu, &aq_req, &rsp);
if (rc) {
seq_puts(filp, "Failed to read the context\n" );
return -EINVAL;
}
print_nix_ctx(filp, &rsp);
}
return 0;
}
static int write_nix_queue_ctx(struct rvu *rvu, bool all, int nixlf,
int id, int ctype, char *ctype_string,
struct seq_file *m)
{
struct nix_hw *nix_hw = m->private ;
struct rvu_pfvf *pfvf;
int max_id = 0;
u16 pcifunc;
if (!rvu_dbg_is_valid_lf(rvu, nix_hw->blkaddr, nixlf, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
if (ctype == NIX_AQ_CTYPE_SQ) {
if (!pfvf->sq_ctx) {
dev_warn(rvu->dev, "SQ context is not initialized\n" );
return -EINVAL;
}
max_id = pfvf->sq_ctx->qsize;
} else if (ctype == NIX_AQ_CTYPE_RQ) {
if (!pfvf->rq_ctx) {
dev_warn(rvu->dev, "RQ context is not initialized\n" );
return -EINVAL;
}
max_id = pfvf->rq_ctx->qsize;
} else if (ctype == NIX_AQ_CTYPE_CQ) {
if (!pfvf->cq_ctx) {
dev_warn(rvu->dev, "CQ context is not initialized\n" );
return -EINVAL;
}
max_id = pfvf->cq_ctx->qsize;
}
if (id < 0 || id >= max_id) {
dev_warn(rvu->dev, "Invalid %s_ctx valid range 0-%d\n" ,
ctype_string, max_id - 1);
return -EINVAL;
}
switch (ctype) {
case NIX_AQ_CTYPE_CQ:
rvu->rvu_dbg.nix_cq_ctx.lf = nixlf;
rvu->rvu_dbg.nix_cq_ctx.id = id;
rvu->rvu_dbg.nix_cq_ctx.all = all;
break ;
case NIX_AQ_CTYPE_SQ:
rvu->rvu_dbg.nix_sq_ctx.lf = nixlf;
rvu->rvu_dbg.nix_sq_ctx.id = id;
rvu->rvu_dbg.nix_sq_ctx.all = all;
break ;
case NIX_AQ_CTYPE_RQ:
rvu->rvu_dbg.nix_rq_ctx.lf = nixlf;
rvu->rvu_dbg.nix_rq_ctx.id = id;
rvu->rvu_dbg.nix_rq_ctx.all = all;
break ;
default :
return -EINVAL;
}
return 0;
}
static ssize_t rvu_dbg_nix_queue_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos,
int ctype)
{
struct seq_file *m = filp->private_data;
struct nix_hw *nix_hw = m->private ;
struct rvu *rvu = nix_hw->rvu;
char *cmd_buf, *ctype_string;
int nixlf, id = 0, ret;
bool all = false ;
if ((*ppos != 0) || !count)
return -EINVAL;
switch (ctype) {
case NIX_AQ_CTYPE_SQ:
ctype_string = "sq" ;
break ;
case NIX_AQ_CTYPE_RQ:
ctype_string = "rq" ;
break ;
case NIX_AQ_CTYPE_CQ:
ctype_string = "cq" ;
break ;
default :
return -EINVAL;
}
cmd_buf = kzalloc(count + 1, GFP_KERNEL);
if (!cmd_buf)
return count;
ret = parse_cmd_buffer_ctx(cmd_buf, &count, buffer,
&nixlf, &id, &all);
if (ret < 0) {
dev_info(rvu->dev,
"Usage: echo <nixlf> [%s number/all] > %s_ctx\n" ,
ctype_string, ctype_string);
goto done;
} else {
ret = write_nix_queue_ctx(rvu, all, nixlf, id, ctype,
ctype_string, m);
}
done:
kfree(cmd_buf);
return ret ? ret : count;
}
static ssize_t rvu_dbg_nix_sq_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
return rvu_dbg_nix_queue_ctx_write(filp, buffer, count, ppos,
NIX_AQ_CTYPE_SQ);
}
static int rvu_dbg_nix_sq_ctx_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_nix_queue_ctx_display(filp, unused, NIX_AQ_CTYPE_SQ);
}
RVU_DEBUG_SEQ_FOPS(nix_sq_ctx, nix_sq_ctx_display, nix_sq_ctx_write);
static ssize_t rvu_dbg_nix_rq_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
return rvu_dbg_nix_queue_ctx_write(filp, buffer, count, ppos,
NIX_AQ_CTYPE_RQ);
}
static int rvu_dbg_nix_rq_ctx_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_nix_queue_ctx_display(filp, unused, NIX_AQ_CTYPE_RQ);
}
RVU_DEBUG_SEQ_FOPS(nix_rq_ctx, nix_rq_ctx_display, nix_rq_ctx_write);
static ssize_t rvu_dbg_nix_cq_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
return rvu_dbg_nix_queue_ctx_write(filp, buffer, count, ppos,
NIX_AQ_CTYPE_CQ);
}
static int rvu_dbg_nix_cq_ctx_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_nix_queue_ctx_display(filp, unused, NIX_AQ_CTYPE_CQ);
}
RVU_DEBUG_SEQ_FOPS(nix_cq_ctx, nix_cq_ctx_display, nix_cq_ctx_write);
static void print_nix_qctx_qsize(struct seq_file *filp, int qsize,
unsigned long *bmap, char *qtype)
{
char *buf;
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!buf)
return ;
bitmap_print_to_pagebuf(false , buf, bmap, qsize);
seq_printf(filp, "%s context count : %d\n" , qtype, qsize);
seq_printf(filp, "%s context ena/dis bitmap : %s\n" ,
qtype, buf);
kfree(buf);
}
static void print_nix_qsize(struct seq_file *filp, struct rvu_pfvf *pfvf)
{
if (!pfvf->cq_ctx)
seq_puts(filp, "cq context is not initialized\n" );
else
print_nix_qctx_qsize(filp, pfvf->cq_ctx->qsize, pfvf->cq_bmap,
"cq" );
if (!pfvf->rq_ctx)
seq_puts(filp, "rq context is not initialized\n" );
else
print_nix_qctx_qsize(filp, pfvf->rq_ctx->qsize, pfvf->rq_bmap,
"rq" );
if (!pfvf->sq_ctx)
seq_puts(filp, "sq context is not initialized\n" );
else
print_nix_qctx_qsize(filp, pfvf->sq_ctx->qsize, pfvf->sq_bmap,
"sq" );
}
static ssize_t rvu_dbg_nix_qsize_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
{
return rvu_dbg_qsize_write(filp, buffer, count, ppos,
BLKTYPE_NIX);
}
static int rvu_dbg_nix_qsize_display(struct seq_file *filp, void *unused)
{
return rvu_dbg_qsize_display(filp, unused, BLKTYPE_NIX);
}
RVU_DEBUG_SEQ_FOPS(nix_qsize, nix_qsize_display, nix_qsize_write);
static void print_band_prof_ctx(struct seq_file *m,
struct nix_bandprof_s *prof)
{
char *str;
switch (prof->pc_mode) {
case NIX_RX_PC_MODE_VLAN:
str = "VLAN" ;
break ;
case NIX_RX_PC_MODE_DSCP:
str = "DSCP" ;
break ;
case NIX_RX_PC_MODE_GEN:
str = "Generic" ;
break ;
case NIX_RX_PC_MODE_RSVD:
str = "Reserved" ;
break ;
}
seq_printf(m, "W0: pc_mode\t\t%s\n" , str);
str = (prof->icolor == 3) ? "Color blind" :
(prof->icolor == 0) ? "Green" :
(prof->icolor == 1) ? "Yellow" : "Red" ;
seq_printf(m, "W0: icolor\t\t%s\n" , str);
seq_printf(m, "W0: tnl_ena\t\t%d\n" , prof->tnl_ena);
seq_printf(m, "W0: peir_exponent\t%d\n" , prof->peir_exponent);
seq_printf(m, "W0: pebs_exponent\t%d\n" , prof->pebs_exponent);
seq_printf(m, "W0: cir_exponent\t%d\n" , prof->cir_exponent);
seq_printf(m, "W0: cbs_exponent\t%d\n" , prof->cbs_exponent);
seq_printf(m, "W0: peir_mantissa\t%d\n" , prof->peir_mantissa);
seq_printf(m, "W0: pebs_mantissa\t%d\n" , prof->pebs_mantissa);
seq_printf(m, "W0: cir_mantissa\t%d\n" , prof->cir_mantissa);
seq_printf(m, "W1: cbs_mantissa\t%d\n" , prof->cbs_mantissa);
str = (prof->lmode == 0) ? "byte" : "packet" ;
seq_printf(m, "W1: lmode\t\t%s\n" , str);
seq_printf(m, "W1: l_select\t\t%d\n" , prof->l_sellect);
seq_printf(m, "W1: rdiv\t\t%d\n" , prof->rdiv);
seq_printf(m, "W1: adjust_exponent\t%d\n" , prof->adjust_exponent);
seq_printf(m, "W1: adjust_mantissa\t%d\n" , prof->adjust_mantissa);
str = (prof->gc_action == 0) ? "PASS" :
(prof->gc_action == 1) ? "DROP" : "RED" ;
seq_printf(m, "W1: gc_action\t\t%s\n" , str);
str = (prof->yc_action == 0) ? "PASS" :
(prof->yc_action == 1) ? "DROP" : "RED" ;
seq_printf(m, "W1: yc_action\t\t%s\n" , str);
str = (prof->rc_action == 0) ? "PASS" :
(prof->rc_action == 1) ? "DROP" : "RED" ;
seq_printf(m, "W1: rc_action\t\t%s\n" , str);
seq_printf(m, "W1: meter_algo\t\t%d\n" , prof->meter_algo);
seq_printf(m, "W1: band_prof_id\t%d\n" , prof->band_prof_id);
seq_printf(m, "W1: hl_en\t\t%d\n" , prof->hl_en);
seq_printf(m, "W2: ts\t\t\t%lld\n" , (u64)prof->ts);
seq_printf(m, "W3: pe_accum\t\t%d\n" , prof->pe_accum);
seq_printf(m, "W3: c_accum\t\t%d\n" , prof->c_accum);
seq_printf(m, "W4: green_pkt_pass\t%lld\n" ,
(u64)prof->green_pkt_pass);
seq_printf(m, "W5: yellow_pkt_pass\t%lld\n" ,
(u64)prof->yellow_pkt_pass);
seq_printf(m, "W6: red_pkt_pass\t%lld\n" , (u64)prof->red_pkt_pass);
seq_printf(m, "W7: green_octs_pass\t%lld\n" ,
(u64)prof->green_octs_pass);
seq_printf(m, "W8: yellow_octs_pass\t%lld\n" ,
(u64)prof->yellow_octs_pass);
seq_printf(m, "W9: red_octs_pass\t%lld\n" , (u64)prof->red_octs_pass);
seq_printf(m, "W10: green_pkt_drop\t%lld\n" ,
(u64)prof->green_pkt_drop);
seq_printf(m, "W11: yellow_pkt_drop\t%lld\n" ,
(u64)prof->yellow_pkt_drop);
seq_printf(m, "W12: red_pkt_drop\t%lld\n" , (u64)prof->red_pkt_drop);
seq_printf(m, "W13: green_octs_drop\t%lld\n" ,
(u64)prof->green_octs_drop);
seq_printf(m, "W14: yellow_octs_drop\t%lld\n" ,
(u64)prof->yellow_octs_drop);
seq_printf(m, "W15: red_octs_drop\t%lld\n" , (u64)prof->red_octs_drop);
seq_puts(m, "==============================\n" );
}
static int rvu_dbg_nix_band_prof_ctx_display(struct seq_file *m, void *unused)
{
struct nix_hw *nix_hw = m->private ;
struct nix_cn10k_aq_enq_req aq_req;
struct nix_cn10k_aq_enq_rsp aq_rsp;
struct rvu *rvu = nix_hw->rvu;
struct nix_ipolicer *ipolicer;
int layer, prof_idx, idx, rc;
u16 pcifunc;
char *str;
/* Ingress policers do not exist on all platforms */
if (!nix_hw->ipolicer)
return 0;
for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
if (layer == BAND_PROF_INVAL_LAYER)
continue ;
str = (layer == BAND_PROF_LEAF_LAYER) ? "Leaf" :
(layer == BAND_PROF_MID_LAYER) ? "Mid" : "Top" ;
seq_printf(m, "\n%s bandwidth profiles\n" , str);
seq_puts(m, "=======================\n" );
ipolicer = &nix_hw->ipolicer[layer];
for (idx = 0; idx < ipolicer->band_prof.max; idx++) {
if (is_rsrc_free(&ipolicer->band_prof, idx))
continue ;
prof_idx = (idx & 0x3FFF) | (layer << 14);
rc = nix_aq_context_read(rvu, nix_hw, &aq_req, &aq_rsp,
0x00, NIX_AQ_CTYPE_BANDPROF,
prof_idx);
if (rc) {
dev_err(rvu->dev,
"%s: Failed to fetch context of %s profile %d, err %d\n" ,
__func__, str, idx, rc);
return 0;
}
seq_printf(m, "\n%s bandwidth profile:: %d\n" , str, idx);
pcifunc = ipolicer->pfvf_map[idx];
if (!(pcifunc & RVU_PFVF_FUNC_MASK))
seq_printf(m, "Allocated to :: PF %d\n" ,
rvu_get_pf(rvu->pdev, pcifunc));
else
seq_printf(m, "Allocated to :: PF %d VF %d\n" ,
rvu_get_pf(rvu->pdev, pcifunc),
(pcifunc & RVU_PFVF_FUNC_MASK) - 1);
print_band_prof_ctx(m, &aq_rsp.prof);
}
}
return 0;
}
RVU_DEBUG_SEQ_FOPS(nix_band_prof_ctx, nix_band_prof_ctx_display, NULL);
static int rvu_dbg_nix_band_prof_rsrc_display(struct seq_file *m, void *unused)
{
struct nix_hw *nix_hw = m->private ;
struct nix_ipolicer *ipolicer;
int layer;
char *str;
/* Ingress policers do not exist on all platforms */
if (!nix_hw->ipolicer)
return 0;
seq_puts(m, "\nBandwidth profile resource free count\n" );
seq_puts(m, "=====================================\n" );
for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
if (layer == BAND_PROF_INVAL_LAYER)
continue ;
str = (layer == BAND_PROF_LEAF_LAYER) ? "Leaf" :
(layer == BAND_PROF_MID_LAYER) ? "Mid " : "Top " ;
ipolicer = &nix_hw->ipolicer[layer];
seq_printf(m, "%s :: Max: %4d Free: %4d\n" , str,
ipolicer->band_prof.max,
rvu_rsrc_free_count(&ipolicer->band_prof));
}
seq_puts(m, "=====================================\n" );
return 0;
}
RVU_DEBUG_SEQ_FOPS(nix_band_prof_rsrc, nix_band_prof_rsrc_display, NULL);
static void rvu_dbg_nix_init(struct rvu *rvu, int blkaddr)
{
struct nix_hw *nix_hw;
if (!is_block_implemented(rvu->hw, blkaddr))
return ;
if (blkaddr == BLKADDR_NIX0) {
rvu->rvu_dbg.nix = debugfs_create_dir("nix" , rvu->rvu_dbg.root);
nix_hw = &rvu->hw->nix[0];
} else {
rvu->rvu_dbg.nix = debugfs_create_dir("nix1" ,
rvu->rvu_dbg.root);
nix_hw = &rvu->hw->nix[1];
}
debugfs_create_file("tm_tree" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_tm_tree_fops);
debugfs_create_file("tm_topo" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_tm_topo_fops);
debugfs_create_file("sq_ctx" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_sq_ctx_fops);
debugfs_create_file("rq_ctx" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_rq_ctx_fops);
debugfs_create_file("cq_ctx" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_cq_ctx_fops);
debugfs_create_file("ndc_tx_cache" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_ndc_tx_cache_fops);
debugfs_create_file("ndc_rx_cache" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_ndc_rx_cache_fops);
debugfs_create_file("ndc_tx_hits_miss" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_ndc_tx_hits_miss_fops);
debugfs_create_file("ndc_rx_hits_miss" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_ndc_rx_hits_miss_fops);
debugfs_create_file_aux_num("qsize" , 0600, rvu->rvu_dbg.nix, rvu,
blkaddr, &rvu_dbg_nix_qsize_fops);
debugfs_create_file("ingress_policer_ctx" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_band_prof_ctx_fops);
debugfs_create_file("ingress_policer_rsrc" , 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_band_prof_rsrc_fops);
}
static void rvu_dbg_npa_init(struct rvu *rvu)
{
rvu->rvu_dbg.npa = debugfs_create_dir("npa" , rvu->rvu_dbg.root);
debugfs_create_file("qsize" , 0600, rvu->rvu_dbg.npa, rvu,
&rvu_dbg_npa_qsize_fops);
debugfs_create_file("aura_ctx" , 0600, rvu->rvu_dbg.npa, rvu,
&rvu_dbg_npa_aura_ctx_fops);
debugfs_create_file("pool_ctx" , 0600, rvu->rvu_dbg.npa, rvu,
&rvu_dbg_npa_pool_ctx_fops);
debugfs_create_file("ndc_cache" , 0600, rvu->rvu_dbg.npa, rvu,
&rvu_dbg_npa_ndc_cache_fops);
debugfs_create_file("ndc_hits_miss" , 0600, rvu->rvu_dbg.npa, rvu,
&rvu_dbg_npa_ndc_hits_miss_fops);
}
#define PRINT_CGX_CUML_NIXRX_STATUS(idx, name) \
({ \
u64 cnt; \
err = rvu_cgx_nix_cuml_stats(rvu, cgxd, lmac_id, (idx), \
NIX_STATS_RX, &(cnt)); \
if (!err) \
seq_printf(s, "%s: %llu\n" , name, cnt); \
cnt; \
})
#define PRINT_CGX_CUML_NIXTX_STATUS(idx, name) \
({ \
u64 cnt; \
err = rvu_cgx_nix_cuml_stats(rvu, cgxd, lmac_id, (idx), \
NIX_STATS_TX, &(cnt)); \
if (!err) \
seq_printf(s, "%s: %llu\n" , name, cnt); \
cnt; \
})
static int cgx_print_stats(struct seq_file *s, int lmac_id)
{
struct cgx_link_user_info linfo;
struct mac_ops *mac_ops;
void *cgxd = s->private ;
u64 ucast, mcast, bcast;
int stat = 0, err = 0;
u64 tx_stat, rx_stat;
struct rvu *rvu;
rvu = pci_get_drvdata(pci_get_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVID_OCTEONTX2_RVU_AF, NULL));
if (!rvu)
return -ENODEV;
mac_ops = get_mac_ops(cgxd);
/* There can be no CGX devices at all */
if (!mac_ops)
return 0;
/* Link status */
seq_puts(s, "\n=======Link Status======\n\n" );
err = cgx_get_link_info(cgxd, lmac_id, &linfo);
if (err)
seq_puts(s, "Failed to read link status\n" );
seq_printf(s, "\nLink is %s %d Mbps\n\n" ,
linfo.link_up ? "UP" : "DOWN" , linfo.speed);
/* Rx stats */
seq_printf(s, "\n=======NIX RX_STATS(%s port level)======\n\n" ,
mac_ops->name);
ucast = PRINT_CGX_CUML_NIXRX_STATUS(RX_UCAST, "rx_ucast_frames" );
if (err)
return err;
mcast = PRINT_CGX_CUML_NIXRX_STATUS(RX_MCAST, "rx_mcast_frames" );
if (err)
return err;
bcast = PRINT_CGX_CUML_NIXRX_STATUS(RX_BCAST, "rx_bcast_frames" );
if (err)
return err;
seq_printf(s, "rx_frames: %llu\n" , ucast + mcast + bcast);
PRINT_CGX_CUML_NIXRX_STATUS(RX_OCTS, "rx_bytes" );
if (err)
return err;
PRINT_CGX_CUML_NIXRX_STATUS(RX_DROP, "rx_drops" );
if (err)
return err;
PRINT_CGX_CUML_NIXRX_STATUS(RX_ERR, "rx_errors" );
if (err)
return err;
/* Tx stats */
seq_printf(s, "\n=======NIX TX_STATS(%s port level)======\n\n" ,
mac_ops->name);
ucast = PRINT_CGX_CUML_NIXTX_STATUS(TX_UCAST, "tx_ucast_frames" );
if (err)
return err;
mcast = PRINT_CGX_CUML_NIXTX_STATUS(TX_MCAST, "tx_mcast_frames" );
if (err)
return err;
bcast = PRINT_CGX_CUML_NIXTX_STATUS(TX_BCAST, "tx_bcast_frames" );
if (err)
return err;
seq_printf(s, "tx_frames: %llu\n" , ucast + mcast + bcast);
PRINT_CGX_CUML_NIXTX_STATUS(TX_OCTS, "tx_bytes" );
if (err)
return err;
PRINT_CGX_CUML_NIXTX_STATUS(TX_DROP, "tx_drops" );
if (err)
return err;
/* Rx stats */
seq_printf(s, "\n=======%s RX_STATS======\n\n" , mac_ops->name);
while (stat < mac_ops->rx_stats_cnt) {
err = mac_ops->mac_get_rx_stats(cgxd, lmac_id, stat, &rx_stat);
if (err)
return err;
if (is_rvu_otx2(rvu))
seq_printf(s, "%s: %llu\n" , cgx_rx_stats_fields[stat],
rx_stat);
else
seq_printf(s, "%s: %llu\n" , rpm_rx_stats_fields[stat],
rx_stat);
stat++;
}
/* Tx stats */
stat = 0;
seq_printf(s, "\n=======%s TX_STATS======\n\n" , mac_ops->name);
while (stat < mac_ops->tx_stats_cnt) {
err = mac_ops->mac_get_tx_stats(cgxd, lmac_id, stat, &tx_stat);
if (err)
return err;
if (is_rvu_otx2(rvu))
seq_printf(s, "%s: %llu\n" , cgx_tx_stats_fields[stat],
tx_stat);
else
seq_printf(s, "%s: %llu\n" , rpm_tx_stats_fields[stat],
tx_stat);
stat++;
}
return err;
}
static int rvu_dbg_derive_lmacid(struct seq_file *s)
{
return debugfs_get_aux_num(s->file);
}
static int rvu_dbg_cgx_stat_display(struct seq_file *s, void *unused)
{
return cgx_print_stats(s, rvu_dbg_derive_lmacid(s));
}
RVU_DEBUG_SEQ_FOPS(cgx_stat, cgx_stat_display, NULL);
static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
{
struct pci_dev *pdev = NULL;
void *cgxd = s->private ;
char *bcast, *mcast;
u16 index, domain;
u8 dmac[ETH_ALEN];
struct rvu *rvu;
u64 cfg, mac;
int pf;
rvu = pci_get_drvdata(pci_get_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVID_OCTEONTX2_RVU_AF, NULL));
if (!rvu)
return -ENODEV;
pf = cgxlmac_to_pf(rvu, cgx_get_cgxid(cgxd), lmac_id);
domain = 2;
pdev = pci_get_domain_bus_and_slot(domain, pf + 1, 0);
if (!pdev)
return 0;
cfg = cgx_read_dmac_ctrl(cgxd, lmac_id);
bcast = cfg & CGX_DMAC_BCAST_MODE ? "ACCEPT" : "REJECT" ;
mcast = cfg & CGX_DMAC_MCAST_MODE ? "ACCEPT" : "REJECT" ;
seq_puts(s,
"PCI dev RVUPF BROADCAST MULTICAST FILTER-MODE\n" );
seq_printf(s, "%s PF%d %9s %9s" ,
dev_name(&pdev->dev), pf, bcast, mcast);
if (cfg & CGX_DMAC_CAM_ACCEPT)
seq_printf(s, "%12s\n\n" , "UNICAST" );
else
seq_printf(s, "%16s\n\n" , "PROMISCUOUS" );
seq_puts(s, "\nDMAC-INDEX ADDRESS\n" );
for (index = 0 ; index < 32 ; index++) {
cfg = cgx_read_dmac_entry(cgxd, index);
/* Display enabled dmac entries associated with current lmac */
if (lmac_id == FIELD_GET(CGX_DMAC_CAM_ENTRY_LMACID, cfg) &&
FIELD_GET(CGX_DMAC_CAM_ADDR_ENABLE, cfg)) {
mac = FIELD_GET(CGX_RX_DMAC_ADR_MASK, cfg);
u64_to_ether_addr(mac, dmac);
seq_printf(s, "%7d %pM\n" , index, dmac);
}
}
pci_dev_put(pdev);
return 0;
}
static int rvu_dbg_cgx_dmac_flt_display(struct seq_file *s, void *unused)
{
return cgx_print_dmac_flt(s, rvu_dbg_derive_lmacid(s));
}
RVU_DEBUG_SEQ_FOPS(cgx_dmac_flt, cgx_dmac_flt_display, NULL);
static int cgx_print_fwdata(struct seq_file *s, int lmac_id)
{
struct cgx_lmac_fwdata_s *fwdata;
void *cgxd = s->private ;
struct phy_s *phy;
struct rvu *rvu;
int cgx_id, i;
rvu = pci_get_drvdata(pci_get_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVID_OCTEONTX2_RVU_AF, NULL));
if (!rvu)
return -ENODEV;
if (!rvu->fwdata)
return -EAGAIN;
cgx_id = cgx_get_cgxid(cgxd);
if (rvu->hw->lmac_per_cgx == CGX_LMACS_USX)
fwdata = &rvu->fwdata->cgx_fw_data_usx[cgx_id][lmac_id];
else
fwdata = &rvu->fwdata->cgx_fw_data[cgx_id][lmac_id];
seq_puts(s, "\nFIRMWARE SHARED:\n" );
seq_puts(s, "\t\tSUPPORTED LINK INFORMATION\t\t\n" );
seq_puts(s, "\t\t==========================\n" );
seq_printf(s, "\t\t Link modes \t\t :%llx\n" ,
fwdata->supported_link_modes);
seq_printf(s, "\t\t Autoneg \t\t :%llx\n" , fwdata->supported_an);
seq_printf(s, "\t\t FEC \t\t\t :%llx\n" , fwdata->supported_fec);
seq_puts(s, "\n" );
seq_puts(s, "\t\tADVERTISED LINK INFORMATION\t\t\n" );
seq_puts(s, "\t\t==========================\n" );
seq_printf(s, "\t\t Link modes \t\t :%llx\n" ,
(u64)fwdata->advertised_link_modes);
seq_printf(s, "\t\t Autoneg \t\t :%x\n" , fwdata->advertised_an);
seq_printf(s, "\t\t FEC \t\t\t :%llx\n" , fwdata->advertised_fec);
seq_puts(s, "\n" );
seq_puts(s, "\t\tLMAC CONFIG\t\t\n" );
seq_puts(s, "\t\t============\n" );
seq_printf(s, "\t\t rw_valid \t\t :%x\n" , fwdata->rw_valid);
seq_printf(s, "\t\t lmac_type \t\t :%x\n" , fwdata->lmac_type);
seq_printf(s, "\t\t portm_idx \t\t :%x\n" , fwdata->portm_idx);
seq_printf(s, "\t\t mgmt_port \t\t :%x\n" , fwdata->mgmt_port);
seq_printf(s, "\t\t Link modes own \t :%llx\n" ,
(u64)fwdata->advertised_link_modes_own);
seq_puts(s, "\n" );
seq_puts(s, "\n\t\tEEPROM DATA\n" );
seq_puts(s, "\t\t===========\n" );
seq_printf(s, "\t\t sff_id \t\t :%x\n" , fwdata->sfp_eeprom.sff_id);
seq_puts(s, "\t\t data \t\t\t :\n" );
seq_puts(s, "\t\t" );
for (i = 0; i < SFP_EEPROM_SIZE; i++) {
seq_printf(s, "%x" , fwdata->sfp_eeprom.buf[i]);
if ((i + 1) % 16 == 0) {
seq_puts(s, "\n" );
seq_puts(s, "\t\t" );
}
}
seq_puts(s, "\n" );
phy = &fwdata->phy;
seq_puts(s, "\n\t\tPHY INFORMATION\n" );
seq_puts(s, "\t\t===============\n" );
seq_printf(s, "\t\t Mod type configurable \t\t :%x\n" ,
phy->misc.can_change_mod_type);
seq_printf(s, "\t\t Mod type \t\t\t :%x\n" , phy->misc.mod_type);
seq_printf(s, "\t\t Support FEC \t\t\t :%x\n" , phy->misc.has_fec_stats);
seq_printf(s, "\t\t RSFEC corrected words \t\t :%x\n" ,
phy->fec_stats.rsfec_corr_cws);
seq_printf(s, "\t\t RSFEC uncorrected words \t :%x\n" ,
phy->fec_stats.rsfec_uncorr_cws);
seq_printf(s, "\t\t BRFEC corrected words \t\t :%x\n" ,
phy->fec_stats.brfec_corr_blks);
seq_printf(s, "\t\t BRFEC uncorrected words \t :%x\n" ,
phy->fec_stats.brfec_uncorr_blks);
seq_puts(s, "\n" );
return 0;
}
static int rvu_dbg_cgx_fwdata_display(struct seq_file *s, void *unused)
{
return cgx_print_fwdata(s, rvu_dbg_derive_lmacid(s));
}
RVU_DEBUG_SEQ_FOPS(cgx_fwdata, cgx_fwdata_display, NULL);
static void rvu_dbg_cgx_init(struct rvu *rvu)
{
struct mac_ops *mac_ops;
unsigned long lmac_bmap;
int i, lmac_id;
char dname[20];
void *cgx;
if (!cgx_get_cgxcnt_max())
return ;
mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));
if (!mac_ops)
return ;
rvu->rvu_dbg.cgx_root = debugfs_create_dir(mac_ops->name,
rvu->rvu_dbg.root);
for (i = 0; i < cgx_get_cgxcnt_max(); i++) {
cgx = rvu_cgx_pdata(i, rvu);
if (!cgx)
continue ;
lmac_bmap = cgx_get_lmac_bmap(cgx);
/* cgx debugfs dir */
sprintf(dname, "%s%d" , mac_ops->name, i);
rvu->rvu_dbg.cgx = debugfs_create_dir(dname,
rvu->rvu_dbg.cgx_root);
for_each_set_bit(lmac_id, &lmac_bmap, rvu->hw->lmac_per_cgx) {
/* lmac debugfs dir */
sprintf(dname, "lmac%d" , lmac_id);
rvu->rvu_dbg.lmac =
debugfs_create_dir(dname, rvu->rvu_dbg.cgx);
debugfs_create_file_aux_num("stats" , 0600, rvu->rvu_dbg.lmac,
cgx, lmac_id, &rvu_dbg_cgx_stat_fops);
debugfs_create_file_aux_num("mac_filter" , 0600,
rvu->rvu_dbg.lmac, cgx, lmac_id,
&rvu_dbg_cgx_dmac_flt_fops);
debugfs_create_file("fwdata" , 0600,
rvu->rvu_dbg.lmac, cgx,
&rvu_dbg_cgx_fwdata_fops);
}
}
}
/* NPC debugfs APIs */
static void rvu_print_npc_mcam_info(struct seq_file *s,
u16 pcifunc, int blkaddr)
{
struct rvu *rvu = s->private ;
int entry_acnt, entry_ecnt;
int cntr_acnt, cntr_ecnt;
rvu_npc_get_mcam_entry_alloc_info(rvu, pcifunc, blkaddr,
&entry_acnt, &entry_ecnt);
rvu_npc_get_mcam_counter_alloc_info(rvu, pcifunc, blkaddr,
&cntr_acnt, &cntr_ecnt);
if (!entry_acnt && !cntr_acnt)
return ;
if (!(pcifunc & RVU_PFVF_FUNC_MASK))
seq_printf(s, "\n\t\t Device \t\t: PF%d\n" ,
rvu_get_pf(rvu->pdev, pcifunc));
else
seq_printf(s, "\n\t\t Device \t\t: PF%d VF%d\n" ,
rvu_get_pf(rvu->pdev, pcifunc),
(pcifunc & RVU_PFVF_FUNC_MASK) - 1);
if (entry_acnt) {
seq_printf(s, "\t\t Entries allocated \t: %d\n" , entry_acnt);
seq_printf(s, "\t\t Entries enabled \t: %d\n" , entry_ecnt);
}
if (cntr_acnt) {
seq_printf(s, "\t\t Counters allocated \t: %d\n" , cntr_acnt);
seq_printf(s, "\t\t Counters enabled \t: %d\n" , cntr_ecnt);
}
}
static int rvu_dbg_npc_mcam_info_display(struct seq_file *filp, void *unsued)
{
struct rvu *rvu = filp->private ;
int pf, vf, numvfs, blkaddr;
struct npc_mcam *mcam;
u16 pcifunc, counters;
u64 cfg;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return -ENODEV;
mcam = &rvu->hw->mcam;
counters = rvu->hw->npc_counters;
seq_puts(filp, "\nNPC MCAM info:\n" );
/* MCAM keywidth on receive and transmit sides */
cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX));
cfg = (cfg >> 32) & 0x07;
seq_printf(filp, "\t\t RX keywidth \t: %s\n" , (cfg == NPC_MCAM_KEY_X1) ?
"112bits" : ((cfg == NPC_MCAM_KEY_X2) ?
"224bits" : "448bits" ));
cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_TX));
cfg = (cfg >> 32) & 0x07;
seq_printf(filp, "\t\t TX keywidth \t: %s\n" , (cfg == NPC_MCAM_KEY_X1) ?
"112bits" : ((cfg == NPC_MCAM_KEY_X2) ?
"224bits" : "448bits" ));
mutex_lock(&mcam->lock);
/* MCAM entries */
seq_printf(filp, "\n\t\t MCAM entries \t: %d\n" , mcam->total_entries);
seq_printf(filp, "\t\t Reserved \t: %d\n" ,
mcam->total_entries - mcam->bmap_entries);
seq_printf(filp, "\t\t Available \t: %d\n" , mcam->bmap_fcnt);
/* MCAM counters */
seq_printf(filp, "\n\t\t MCAM counters \t: %d\n" , counters);
seq_printf(filp, "\t\t Reserved \t: %d\n" ,
counters - mcam->counters.max);
seq_printf(filp, "\t\t Available \t: %d\n" ,
rvu_rsrc_free_count(&mcam->counters));
if (mcam->bmap_entries == mcam->bmap_fcnt) {
mutex_unlock(&mcam->lock);
return 0;
}
seq_puts(filp, "\n\t\t Current allocation\n" );
seq_puts(filp, "\t\t====================\n" );
for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
rvu_print_npc_mcam_info(filp, pcifunc, blkaddr);
cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf));
numvfs = (cfg >> 12) & 0xFF;
for (vf = 0; vf < numvfs; vf++) {
pcifunc = rvu_make_pcifunc(rvu->pdev, pf, (vf + 1));
rvu_print_npc_mcam_info(filp, pcifunc, blkaddr);
}
}
mutex_unlock(&mcam->lock);
return 0;
}
RVU_DEBUG_SEQ_FOPS(npc_mcam_info, npc_mcam_info_display, NULL);
static int rvu_dbg_npc_rx_miss_stats_display(struct seq_file *filp,
void *unused)
{
struct rvu *rvu = filp->private ;
struct npc_mcam *mcam;
int blkaddr;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return -ENODEV;
mcam = &rvu->hw->mcam;
seq_puts(filp, "\nNPC MCAM RX miss action stats\n" );
seq_printf(filp, "\t\tStat %d: \t%lld\n" , mcam->rx_miss_act_cntr,
rvu_read64(rvu, blkaddr,
NPC_AF_MATCH_STATX(mcam->rx_miss_act_cntr)));
return 0;
}
RVU_DEBUG_SEQ_FOPS(npc_rx_miss_act, npc_rx_miss_stats_display, NULL);
#define RVU_DBG_PRINT_MPLS_TTL(pkt, mask) \
do { \
seq_printf(s, "%ld " , FIELD_GET(OTX2_FLOWER_MASK_MPLS_TTL, pkt)); \
seq_printf(s, "mask 0x%lx\n" , \
FIELD_GET(OTX2_FLOWER_MASK_MPLS_TTL, mask)); \
} while (0) \
#define RVU_DBG_PRINT_MPLS_LBTCBOS(_pkt, _mask) \
do { \
typeof(_pkt) (pkt) = (_pkt); \
typeof(_mask) (mask) = (_mask); \
seq_printf(s, "%ld %ld %ld\n" , \
FIELD_GET(OTX2_FLOWER_MASK_MPLS_LB, pkt), \
FIELD_GET(OTX2_FLOWER_MASK_MPLS_TC, pkt), \
FIELD_GET(OTX2_FLOWER_MASK_MPLS_BOS, pkt)); \
seq_printf(s, "\tmask 0x%lx 0x%lx 0x%lx\n" , \
FIELD_GET(OTX2_FLOWER_MASK_MPLS_LB, mask), \
FIELD_GET(OTX2_FLOWER_MASK_MPLS_TC, mask), \
FIELD_GET(OTX2_FLOWER_MASK_MPLS_BOS, mask)); \
} while (0) \
static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
struct rvu_npc_mcam_rule *rule)
{
u8 bit;
for_each_set_bit(bit, (unsigned long *)&rule->features, 64) {
seq_printf(s, "\t%s " , npc_get_field_name(bit));
switch (bit) {
case NPC_LXMB:
if (rule->lxmb == 1)
seq_puts(s, "\tL2M nibble is set\n" );
else
seq_puts(s, "\tL2B nibble is set\n" );
break ;
case NPC_DMAC:
seq_printf(s, "%pM " , rule->packet.dmac);
seq_printf(s, "mask %pM\n" , rule->mask.dmac);
break ;
case NPC_SMAC:
seq_printf(s, "%pM " , rule->packet.smac);
seq_printf(s, "mask %pM\n" , rule->mask.smac);
break ;
case NPC_ETYPE:
seq_printf(s, "0x%x " , ntohs(rule->packet.etype));
seq_printf(s, "mask 0x%x\n" , ntohs(rule->mask.etype));
break ;
case NPC_OUTER_VID:
seq_printf(s, "0x%x " , ntohs(rule->packet.vlan_tci));
seq_printf(s, "mask 0x%x\n" ,
ntohs(rule->mask.vlan_tci));
break ;
case NPC_INNER_VID:
seq_printf(s, "0x%x " , ntohs(rule->packet.vlan_itci));
seq_printf(s, "mask 0x%x\n" ,
ntohs(rule->mask.vlan_itci));
break ;
case NPC_TOS:
seq_printf(s, "%d " , rule->packet.tos);
seq_printf(s, "mask 0x%x\n" , rule->mask.tos);
break ;
case NPC_SIP_IPV4:
seq_printf(s, "%pI4 " , &rule->packet.ip4src);
seq_printf(s, "mask %pI4\n" , &rule->mask.ip4src);
break ;
case NPC_DIP_IPV4:
seq_printf(s, "%pI4 " , &rule->packet.ip4dst);
seq_printf(s, "mask %pI4\n" , &rule->mask.ip4dst);
break ;
case NPC_SIP_IPV6:
seq_printf(s, "%pI6 " , rule->packet.ip6src);
seq_printf(s, "mask %pI6\n" , rule->mask.ip6src);
break ;
case NPC_DIP_IPV6:
seq_printf(s, "%pI6 " , rule->packet.ip6dst);
seq_printf(s, "mask %pI6\n" , rule->mask.ip6dst);
break ;
case NPC_IPFRAG_IPV6:
seq_printf(s, "0x%x " , rule->packet.next_header);
seq_printf(s, "mask 0x%x\n" , rule->mask.next_header);
break ;
case NPC_IPFRAG_IPV4:
seq_printf(s, "0x%x " , rule->packet.ip_flag);
seq_printf(s, "mask 0x%x\n" , rule->mask.ip_flag);
break ;
case NPC_SPORT_TCP:
case NPC_SPORT_UDP:
case NPC_SPORT_SCTP:
seq_printf(s, "%d " , ntohs(rule->packet.sport));
seq_printf(s, "mask 0x%x\n" , ntohs(rule->mask.sport));
break ;
case NPC_DPORT_TCP:
case NPC_DPORT_UDP:
case NPC_DPORT_SCTP:
seq_printf(s, "%d " , ntohs(rule->packet.dport));
seq_printf(s, "mask 0x%x\n" , ntohs(rule->mask.dport));
break ;
case NPC_TCP_FLAGS:
seq_printf(s, "%d " , rule->packet.tcp_flags);
seq_printf(s, "mask 0x%x\n" , rule->mask.tcp_flags);
break ;
case NPC_IPSEC_SPI:
seq_printf(s, "0x%x " , ntohl(rule->packet.spi));
seq_printf(s, "mask 0x%x\n" , ntohl(rule->mask.spi));
break ;
case NPC_MPLS1_LBTCBOS:
RVU_DBG_PRINT_MPLS_LBTCBOS(rule->packet.mpls_lse[0],
rule->mask.mpls_lse[0]);
break ;
case NPC_MPLS1_TTL:
RVU_DBG_PRINT_MPLS_TTL(rule->packet.mpls_lse[0],
rule->mask.mpls_lse[0]);
break ;
case NPC_MPLS2_LBTCBOS:
RVU_DBG_PRINT_MPLS_LBTCBOS(rule->packet.mpls_lse[1],
rule->mask.mpls_lse[1]);
break ;
case NPC_MPLS2_TTL:
RVU_DBG_PRINT_MPLS_TTL(rule->packet.mpls_lse[1],
rule->mask.mpls_lse[1]);
break ;
case NPC_MPLS3_LBTCBOS:
RVU_DBG_PRINT_MPLS_LBTCBOS(rule->packet.mpls_lse[2],
rule->mask.mpls_lse[2]);
break ;
case NPC_MPLS3_TTL:
RVU_DBG_PRINT_MPLS_TTL(rule->packet.mpls_lse[2],
rule->mask.mpls_lse[2]);
break ;
case NPC_MPLS4_LBTCBOS:
RVU_DBG_PRINT_MPLS_LBTCBOS(rule->packet.mpls_lse[3],
rule->mask.mpls_lse[3]);
break ;
case NPC_MPLS4_TTL:
RVU_DBG_PRINT_MPLS_TTL(rule->packet.mpls_lse[3],
rule->mask.mpls_lse[3]);
break ;
case NPC_TYPE_ICMP:
seq_printf(s, "%d " , rule->packet.icmp_type);
seq_printf(s, "mask 0x%x\n" , rule->mask.icmp_type);
break ;
case NPC_CODE_ICMP:
seq_printf(s, "%d " , rule->packet.icmp_code);
seq_printf(s, "mask 0x%x\n" , rule->mask.icmp_code);
break ;
default :
seq_puts(s, "\n" );
break ;
}
}
}
static void rvu_dbg_npc_mcam_show_action(struct seq_file *s,
struct rvu_npc_mcam_rule *rule)
{
if (is_npc_intf_tx(rule->intf)) {
switch (rule->tx_action.op) {
case NIX_TX_ACTIONOP_DROP:
seq_puts(s, "\taction: Drop\n" );
break ;
case NIX_TX_ACTIONOP_UCAST_DEFAULT:
seq_puts(s, "\taction: Unicast to default channel\n" );
break ;
case NIX_TX_ACTIONOP_UCAST_CHAN:
seq_printf(s, "\taction: Unicast to channel %d\n" ,
rule->tx_action.index);
break ;
case NIX_TX_ACTIONOP_MCAST:
seq_puts(s, "\taction: Multicast\n" );
break ;
case NIX_TX_ACTIONOP_DROP_VIOL:
seq_puts(s, "\taction: Lockdown Violation Drop\n" );
break ;
default :
break ;
}
} else {
switch (rule->rx_action.op) {
case NIX_RX_ACTIONOP_DROP:
seq_puts(s, "\taction: Drop\n" );
break ;
case NIX_RX_ACTIONOP_UCAST:
seq_printf(s, "\taction: Direct to queue %d\n" ,
rule->rx_action.index);
break ;
case NIX_RX_ACTIONOP_RSS:
seq_puts(s, "\taction: RSS\n" );
break ;
case NIX_RX_ACTIONOP_UCAST_IPSEC:
seq_puts(s, "\taction: Unicast ipsec\n" );
break ;
case NIX_RX_ACTIONOP_MCAST:
seq_puts(s, "\taction: Multicast\n" );
break ;
default :
break ;
}
}
}
static const char *rvu_dbg_get_intf_name(int intf)
{
switch (intf) {
case NIX_INTFX_RX(0):
return "NIX0_RX" ;
case NIX_INTFX_RX(1):
return "NIX1_RX" ;
case NIX_INTFX_TX(0):
return "NIX0_TX" ;
case NIX_INTFX_TX(1):
return "NIX1_TX" ;
default :
break ;
}
return "unknown" ;
}
static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)
{
struct rvu_npc_mcam_rule *iter;
struct rvu *rvu = s->private ;
struct npc_mcam *mcam;
int pf, vf = -1;
bool enabled;
int blkaddr;
u16 target;
u64 hits;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return 0;
mcam = &rvu->hw->mcam;
mutex_lock(&mcam->lock);
list_for_each_entry(iter, &mcam->mcam_rules, list) {
pf = rvu_get_pf(rvu->pdev, iter->owner);
seq_printf(s, "\n\tInstalled by: PF%d " , pf);
if (iter->owner & RVU_PFVF_FUNC_MASK) {
vf = (iter->owner & RVU_PFVF_FUNC_MASK) - 1;
seq_printf(s, "VF%d" , vf);
}
seq_puts(s, "\n" );
seq_printf(s, "\tdirection: %s\n" , is_npc_intf_rx(iter->intf) ?
"RX" : "TX" );
seq_printf(s, "\tinterface: %s\n" ,
rvu_dbg_get_intf_name(iter->intf));
seq_printf(s, "\tmcam entry: %d\n" , iter->entry);
rvu_dbg_npc_mcam_show_flows(s, iter);
if (is_npc_intf_rx(iter->intf)) {
target = iter->rx_action.pf_func;
pf = rvu_get_pf(rvu->pdev, target);
seq_printf(s, "\tForward to: PF%d " , pf);
if (target & RVU_PFVF_FUNC_MASK) {
vf = (target & RVU_PFVF_FUNC_MASK) - 1;
seq_printf(s, "VF%d" , vf);
}
seq_puts(s, "\n" );
seq_printf(s, "\tchannel: 0x%x\n" , iter->chan);
seq_printf(s, "\tchannel_mask: 0x%x\n" , iter->chan_mask);
}
rvu_dbg_npc_mcam_show_action(s, iter);
enabled = is_mcam_entry_enabled(rvu, mcam, blkaddr, iter->entry);
seq_printf(s, "\tenabled: %s\n" , enabled ? "yes" : "no" );
if (!iter->has_cntr)
continue ;
seq_printf(s, "\tcounter: %d\n" , iter->cntr);
hits = rvu_read64(rvu, blkaddr, NPC_AF_MATCH_STATX(iter->cntr));
seq_printf(s, "\thits: %lld\n" , hits);
}
mutex_unlock(&mcam->lock);
return 0;
}
RVU_DEBUG_SEQ_FOPS(npc_mcam_rules, npc_mcam_show_rules, NULL);
static int rvu_dbg_npc_exact_show_entries(struct seq_file *s, void *unused)
{
struct npc_exact_table_entry *mem_entry[NPC_EXACT_TBL_MAX_WAYS] = { 0 };
struct npc_exact_table_entry *cam_entry;
struct npc_exact_table *table;
struct rvu *rvu = s->private ;
int i, j;
u8 bitmap = 0;
table = rvu->hw->table;
mutex_lock(&table->lock);
/* Check if there is at least one entry in mem table */
if (!table->mem_tbl_entry_cnt)
goto dump_cam_table;
/* Print table headers */
seq_puts(s, "\n\tExact Match MEM Table\n" );
seq_puts(s, "Index\t" );
for (i = 0; i < table->mem_table.ways; i++) {
mem_entry[i] = list_first_entry_or_null(&table->lhead_mem_tbl_entry[i],
struct npc_exact_table_entry, list);
seq_printf(s, "Way-%d\t\t\t\t\t" , i);
}
seq_puts(s, "\n" );
for (i = 0; i < table->mem_table.ways; i++)
seq_puts(s, "\tChan MAC \t" );
seq_puts(s, "\n\n" );
/* Print mem table entries */
for (i = 0; i < table->mem_table.depth; i++) {
bitmap = 0;
for (j = 0; j < table->mem_table.ways; j++) {
if (!mem_entry[j])
continue ;
if (mem_entry[j]->index != i)
continue ;
bitmap |= BIT(j);
}
/* No valid entries */
if (!bitmap)
continue ;
seq_printf(s, "%d\t" , i);
for (j = 0; j < table->mem_table.ways; j++) {
if (!(bitmap & BIT(j))) {
seq_puts(s, "nil\t\t\t\t\t" );
continue ;
}
seq_printf(s, "0x%x %pM\t\t\t" , mem_entry[j]->chan,
mem_entry[j]->mac);
mem_entry[j] = list_next_entry(mem_entry[j], list);
}
seq_puts(s, "\n" );
}
dump_cam_table:
if (!table->cam_tbl_entry_cnt)
goto done;
seq_puts(s, "\n\tExact Match CAM Table\n" );
seq_puts(s, "index\tchan\tMAC\n" );
/* Traverse cam table entries */
list_for_each_entry(cam_entry, &table->lhead_cam_tbl_entry, list) {
seq_printf(s, "%d\t0x%x\t%pM\n" , cam_entry->index, cam_entry->chan,
cam_entry->mac);
}
done:
mutex_unlock(&table->lock);
return 0;
}
RVU_DEBUG_SEQ_FOPS(npc_exact_entries, npc_exact_show_entries, NULL);
static int rvu_dbg_npc_exact_show_info(struct seq_file *s, void *unused)
{
struct npc_exact_table *table;
struct rvu *rvu = s->private ;
int i;
table = rvu->hw->table;
seq_puts(s, "\n\tExact Table Info\n" );
seq_printf(s, "Exact Match Feature : %s\n" ,
rvu->hw->cap.npc_exact_match_enabled ? "enabled" : "disable" );
if (!rvu->hw->cap.npc_exact_match_enabled)
return 0;
seq_puts(s, "\nMCAM Index\tMAC Filter Rules Count\n" );
for (i = 0; i < table->num_drop_rules; i++)
seq_printf(s, "%d\t\t%d\n" , i, table->cnt_cmd_rules[i]);
seq_puts(s, "\nMcam Index\tPromisc Mode Status\n" );
for (i = 0; i < table->num_drop_rules; i++)
seq_printf(s, "%d\t\t%s\n" , i, table->promisc_mode[i] ? "on" : "off" );
seq_puts(s, "\n\tMEM Table Info\n" );
seq_printf(s, "Ways : %d\n" , table->mem_table.ways);
seq_printf(s, "Depth : %d\n" , table->mem_table.depth);
seq_printf(s, "Mask : 0x%llx\n" , table->mem_table.mask);
seq_printf(s, "Hash Mask : 0x%x\n" , table->mem_table.hash_mask);
seq_printf(s, "Hash Offset : 0x%x\n" , table->mem_table.hash_offset);
seq_puts(s, "\n\tCAM Table Info\n" );
seq_printf(s, "Depth : %d\n" , table->cam_table.depth);
return 0;
}
RVU_DEBUG_SEQ_FOPS(npc_exact_info, npc_exact_show_info, NULL);
static int rvu_dbg_npc_exact_drop_cnt(struct seq_file *s, void *unused)
{
struct npc_exact_table *table;
struct rvu *rvu = s->private ;
struct npc_key_field *field;
u16 chan, pcifunc;
int blkaddr, i;
u64 cfg, cam1;
char *str;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
table = rvu->hw->table;
field = &rvu->hw->mcam.rx_key_fields[NPC_CHAN];
seq_puts(s, "\n\t Exact Hit on drop status\n" );
seq_puts(s, "\npcifunc\tmcam_idx\tHits\tchan\tstatus\n" );
for (i = 0; i < table->num_drop_rules; i++) {
pcifunc = rvu_npc_exact_drop_rule_to_pcifunc(rvu, i);
cfg = rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_CFG(i, 0));
/* channel will be always in keyword 0 */
cam1 = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CAMX_W0(i, 0, 1));
chan = field->kw_mask[0] & cam1;
str = (cfg & 1) ? "enabled" : "disabled" ;
seq_printf(s, "0x%x\t%d\t\t%llu\t0x%x\t%s\n" , pcifunc, i,
rvu_read64(rvu, blkaddr,
NPC_AF_MATCH_STATX(table->counter_idx[i])),
chan, str);
}
return 0;
}
RVU_DEBUG_SEQ_FOPS(npc_exact_drop_cnt, npc_exact_drop_cnt, NULL);
static void rvu_dbg_npc_init(struct rvu *rvu)
{
rvu->rvu_dbg.npc = debugfs_create_dir("npc" , rvu->rvu_dbg.root);
debugfs_create_file("mcam_info" , 0444, rvu->rvu_dbg.npc, rvu,
&rvu_dbg_npc_mcam_info_fops);
debugfs_create_file("mcam_rules" , 0444, rvu->rvu_dbg.npc, rvu,
&rvu_dbg_npc_mcam_rules_fops);
debugfs_create_file("rx_miss_act_stats" , 0444, rvu->rvu_dbg.npc, rvu,
&rvu_dbg_npc_rx_miss_act_fops);
if (!rvu->hw->cap.npc_exact_match_enabled)
return ;
debugfs_create_file("exact_entries" , 0444, rvu->rvu_dbg.npc, rvu,
&rvu_dbg_npc_exact_entries_fops);
debugfs_create_file("exact_info" , 0444, rvu->rvu_dbg.npc, rvu,
&rvu_dbg_npc_exact_info_fops);
debugfs_create_file("exact_drop_cnt" , 0444, rvu->rvu_dbg.npc, rvu,
&rvu_dbg_npc_exact_drop_cnt_fops);
}
static int cpt_eng_sts_display(struct seq_file *filp, u8 eng_type)
{
struct cpt_ctx *ctx = filp->private ;
u64 busy_sts = 0, free_sts = 0;
u32 e_min = 0, e_max = 0, e, i;
u16 max_ses, max_ies, max_aes;
struct rvu *rvu = ctx->rvu;
int blkaddr = ctx->blkaddr;
u64 reg;
reg = rvu_read64(rvu, blkaddr, CPT_AF_CONSTANTS1);
max_ses = reg & 0xffff;
max_ies = (reg >> 16) & 0xffff;
max_aes = (reg >> 32) & 0xffff;
switch (eng_type) {
case CPT_AE_TYPE:
e_min = max_ses + max_ies;
e_max = max_ses + max_ies + max_aes;
break ;
case CPT_SE_TYPE:
e_min = 0;
e_max = max_ses;
break ;
case CPT_IE_TYPE:
e_min = max_ses;
e_max = max_ses + max_ies;
break ;
default :
return -EINVAL;
}
for (e = e_min, i = 0; e < e_max; e++, i++) {
reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_STS(e));
if (reg & 0x1)
busy_sts |= 1ULL << i;
if (reg & 0x2)
free_sts |= 1ULL << i;
}
seq_printf(filp, "FREE STS : 0x%016llx\n" , free_sts);
seq_printf(filp, "BUSY STS : 0x%016llx\n" , busy_sts);
return 0;
}
static int rvu_dbg_cpt_ae_sts_display(struct seq_file *filp, void *unused)
{
return cpt_eng_sts_display(filp, CPT_AE_TYPE);
}
RVU_DEBUG_SEQ_FOPS(cpt_ae_sts, cpt_ae_sts_display, NULL);
static int rvu_dbg_cpt_se_sts_display(struct seq_file *filp, void *unused)
{
return cpt_eng_sts_display(filp, CPT_SE_TYPE);
}
RVU_DEBUG_SEQ_FOPS(cpt_se_sts, cpt_se_sts_display, NULL);
static int rvu_dbg_cpt_ie_sts_display(struct seq_file *filp, void *unused)
{
return cpt_eng_sts_display(filp, CPT_IE_TYPE);
}
RVU_DEBUG_SEQ_FOPS(cpt_ie_sts, cpt_ie_sts_display, NULL);
static int rvu_dbg_cpt_engines_info_display(struct seq_file *filp, void *unused)
{
struct cpt_ctx *ctx = filp->private ;
u16 max_ses, max_ies, max_aes;
struct rvu *rvu = ctx->rvu;
int blkaddr = ctx->blkaddr;
u32 e_max, e;
u64 reg;
reg = rvu_read64(rvu, blkaddr, CPT_AF_CONSTANTS1);
max_ses = reg & 0xffff;
max_ies = (reg >> 16) & 0xffff;
max_aes = (reg >> 32) & 0xffff;
e_max = max_ses + max_ies + max_aes;
seq_puts(filp, "===========================================\n" );
for (e = 0; e < e_max; e++) {
reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL2(e));
seq_printf(filp, "CPT Engine[%u] Group Enable 0x%02llx\n" , e,
reg & 0xff);
reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_ACTIVE(e));
seq_printf(filp, "CPT Engine[%u] Active Info 0x%llx\n" , e,
reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL(e));
seq_printf(filp, "CPT Engine[%u] Control 0x%llx\n" , e,
reg);
seq_puts(filp, "===========================================\n" );
}
return 0;
}
RVU_DEBUG_SEQ_FOPS(cpt_engines_info, cpt_engines_info_display, NULL);
static int rvu_dbg_cpt_lfs_info_display(struct seq_file *filp, void *unused)
{
struct cpt_ctx *ctx = filp->private ;
int blkaddr = ctx->blkaddr;
struct rvu *rvu = ctx->rvu;
struct rvu_block *block;
struct rvu_hwinfo *hw;
u64 reg;
u32 lf;
hw = rvu->hw;
block = &hw->block[blkaddr];
if (!block->lf.bmap)
return -ENODEV;
seq_puts(filp, "===========================================\n" );
for (lf = 0; lf < block->lf.max; lf++) {
reg = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL(lf));
seq_printf(filp, "CPT Lf[%u] CTL 0x%llx\n" , lf, reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL2(lf));
seq_printf(filp, "CPT Lf[%u] CTL2 0x%llx\n" , lf, reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_LFX_PTR_CTL(lf));
seq_printf(filp, "CPT Lf[%u] PTR_CTL 0x%llx\n" , lf, reg);
reg = rvu_read64(rvu, blkaddr, block->lfcfg_reg |
(lf << block->lfshift));
seq_printf(filp, "CPT Lf[%u] CFG 0x%llx\n" , lf, reg);
seq_puts(filp, "===========================================\n" );
}
return 0;
}
RVU_DEBUG_SEQ_FOPS(cpt_lfs_info, cpt_lfs_info_display, NULL);
static int rvu_dbg_cpt_err_info_display(struct seq_file *filp, void *unused)
{
struct cpt_ctx *ctx = filp->private ;
struct rvu *rvu = ctx->rvu;
int blkaddr = ctx->blkaddr;
u64 reg0, reg1;
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(0));
reg1 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(1));
seq_printf(filp, "CPT_AF_FLTX_INT: 0x%llx 0x%llx\n" , reg0, reg1);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_PSNX_EXE(0));
reg1 = rvu_read64(rvu, blkaddr, CPT_AF_PSNX_EXE(1));
seq_printf(filp, "CPT_AF_PSNX_EXE: 0x%llx 0x%llx\n" , reg0, reg1);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_PSNX_LF(0));
seq_printf(filp, "CPT_AF_PSNX_LF: 0x%llx\n" , reg0);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_RVU_INT);
seq_printf(filp, "CPT_AF_RVU_INT: 0x%llx\n" , reg0);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_RAS_INT);
seq_printf(filp, "CPT_AF_RAS_INT: 0x%llx\n" , reg0);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_EXE_ERR_INFO);
seq_printf(filp, "CPT_AF_EXE_ERR_INFO: 0x%llx\n" , reg0);
return 0;
}
RVU_DEBUG_SEQ_FOPS(cpt_err_info, cpt_err_info_display, NULL);
static int rvu_dbg_cpt_pc_display(struct seq_file *filp, void *unused)
{
struct cpt_ctx *ctx = filp->private ;
struct rvu *rvu = ctx->rvu;
int blkaddr = ctx->blkaddr;
u64 reg;
reg = rvu_read64(rvu, blkaddr, CPT_AF_INST_REQ_PC);
seq_printf(filp, "CPT instruction requests %llu\n" , reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_INST_LATENCY_PC);
seq_printf(filp, "CPT instruction latency %llu\n" , reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_RD_REQ_PC);
seq_printf(filp, "CPT NCB read requests %llu\n" , reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_RD_LATENCY_PC);
seq_printf(filp, "CPT NCB read latency %llu\n" , reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_RD_UC_PC);
seq_printf(filp, "CPT read requests caused by UC fills %llu\n" , reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_ACTIVE_CYCLES_PC);
seq_printf(filp, "CPT active cycles pc %llu\n" , reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_CPTCLK_CNT);
seq_printf(filp, "CPT clock count pc %llu\n" , reg);
return 0;
}
RVU_DEBUG_SEQ_FOPS(cpt_pc, cpt_pc_display, NULL);
static void rvu_dbg_cpt_init(struct rvu *rvu, int blkaddr)
{
struct cpt_ctx *ctx;
if (!is_block_implemented(rvu->hw, blkaddr))
return ;
if (blkaddr == BLKADDR_CPT0) {
rvu->rvu_dbg.cpt = debugfs_create_dir("cpt" , rvu->rvu_dbg.root);
ctx = &rvu->rvu_dbg.cpt_ctx[0];
ctx->blkaddr = BLKADDR_CPT0;
ctx->rvu = rvu;
} else {
rvu->rvu_dbg.cpt = debugfs_create_dir("cpt1" ,
rvu->rvu_dbg.root);
ctx = &rvu->rvu_dbg.cpt_ctx[1];
ctx->blkaddr = BLKADDR_CPT1;
ctx->rvu = rvu;
}
debugfs_create_file("cpt_pc" , 0600, rvu->rvu_dbg.cpt, ctx,
&rvu_dbg_cpt_pc_fops);
debugfs_create_file("cpt_ae_sts" , 0600, rvu->rvu_dbg.cpt, ctx,
&rvu_dbg_cpt_ae_sts_fops);
debugfs_create_file("cpt_se_sts" , 0600, rvu->rvu_dbg.cpt, ctx,
&rvu_dbg_cpt_se_sts_fops);
debugfs_create_file("cpt_ie_sts" , 0600, rvu->rvu_dbg.cpt, ctx,
&rvu_dbg_cpt_ie_sts_fops);
debugfs_create_file("cpt_engines_info" , 0600, rvu->rvu_dbg.cpt, ctx,
&rvu_dbg_cpt_engines_info_fops);
debugfs_create_file("cpt_lfs_info" , 0600, rvu->rvu_dbg.cpt, ctx,
&rvu_dbg_cpt_lfs_info_fops);
debugfs_create_file("cpt_err_info" , 0600, rvu->rvu_dbg.cpt, ctx,
&rvu_dbg_cpt_err_info_fops);
}
static const char *rvu_get_dbg_dir_name(struct rvu *rvu)
{
if (!is_rvu_otx2(rvu))
return "cn10k" ;
else
return "octeontx2" ;
}
void rvu_dbg_init(struct rvu *rvu)
{
rvu->rvu_dbg.root = debugfs_create_dir(rvu_get_dbg_dir_name(rvu), NULL);
debugfs_create_file("rsrc_alloc" , 0444, rvu->rvu_dbg.root, rvu,
&rvu_dbg_rsrc_status_fops);
if (!is_rvu_otx2(rvu))
debugfs_create_file("lmtst_map_table" , 0444, rvu->rvu_dbg.root,
rvu, &rvu_dbg_lmtst_map_table_fops);
debugfs_create_file("rvu_fwdata" , 0444, rvu->rvu_dbg.root, rvu,
&rvu_dbg_rvu_fwdata_fops);
if (!cgx_get_cgxcnt_max())
goto create;
if (is_rvu_otx2(rvu))
debugfs_create_file("rvu_pf_cgx_map" , 0444, rvu->rvu_dbg.root,
rvu, &rvu_dbg_rvu_pf_cgx_map_fops);
else
debugfs_create_file("rvu_pf_rpm_map" , 0444, rvu->rvu_dbg.root,
rvu, &rvu_dbg_rvu_pf_cgx_map_fops);
create:
rvu_dbg_npa_init(rvu);
rvu_dbg_nix_init(rvu, BLKADDR_NIX0);
rvu_dbg_nix_init(rvu, BLKADDR_NIX1);
rvu_dbg_cgx_init(rvu);
rvu_dbg_npc_init(rvu);
rvu_dbg_cpt_init(rvu, BLKADDR_CPT0);
rvu_dbg_cpt_init(rvu, BLKADDR_CPT1);
rvu_dbg_mcs_init(rvu);
}
void rvu_dbg_exit(struct rvu *rvu)
{
debugfs_remove_recursive(rvu->rvu_dbg.root);
}
#endif /* CONFIG_DEBUG_FS */
Messung V0.5 in Prozent C=95 H=90 G=92
¤ Dauer der Verarbeitung: 0.52 Sekunden
(vorverarbeitet am 2026-04-28)
¤
*© Formatika GbR, Deutschland