Commit f967488d authored by Linu Cherian's avatar Linu Cherian Committed by David S. Miller
Browse files

octeontx2-af: Add per CGX port level NIX Rx/Tx counters



A CGX port is shared by a RVU PF and it's VFs. These per
CGX port level NIX Rx/Tx counters are cumilative stats of
all NIXLFs sharing this port. These stats when compared
to CGX Rx/Tx stats helps in identifying pkts dropped within
the system, if any.

Signed-off-by: default avatarLinu Cherian <lcherian@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c57211b5
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -138,6 +138,16 @@ void *cgx_get_pdata(int cgx_id)
}
EXPORT_SYMBOL(cgx_get_pdata);

int cgx_get_cgxid(void *cgxd)
{
	struct cgx *cgx = cgxd;

	if (!cgx)
		return -EINVAL;

	return cgx->cgx_id;
}

/* Ensure the required lock for event queue(where asynchronous events are
 * posted) is acquired before calling this API. Else an asynchronous event(with
 * latest link status) can reach the destination before this function returns
+6 −0
Original line number Diff line number Diff line
@@ -63,6 +63,11 @@
#define CGX_NVEC			37
#define CGX_LMAC_FWI			0

enum  cgx_nix_stat_type {
	NIX_STATS_RX,
	NIX_STATS_TX,
};

enum LMAC_TYPE {
	LMAC_MODE_SGMII		= 0,
	LMAC_MODE_XAUI		= 1,
@@ -96,6 +101,7 @@ struct cgx_event_cb {
extern struct pci_driver cgx_driver;

int cgx_get_cgxcnt_max(void);
int cgx_get_cgxid(void *cgxd);
int cgx_get_lmac_cnt(void *cgxd);
void *cgx_get_pdata(int cgx_id);
int cgx_set_pkind(void *cgxd, u8 lmac_id, int pkind);
+2 −0
Original line number Diff line number Diff line
@@ -374,6 +374,8 @@ int rvu_cgx_init(struct rvu *rvu);
int rvu_cgx_exit(struct rvu *rvu);
void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu);
int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start);
int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id, int index,
			   int rxtxflag, u64 *stat);
int rvu_mbox_handler_cgx_start_rxtx(struct rvu *rvu, struct msg_req *req,
				    struct msg_rsp *rsp);
int rvu_mbox_handler_cgx_stop_rxtx(struct rvu *rvu, struct msg_req *req,
+60 −2
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

#include "rvu.h"
#include "cgx.h"
#include "rvu_reg.h"

struct cgx_evq_entry {
	struct list_head evq_node;
@@ -40,12 +41,25 @@ MBOX_UP_CGX_MESSAGES
#undef M

/* Returns bitmap of mapped PFs */
static inline u16 cgxlmac_to_pfmap(struct rvu *rvu, u8 cgx_id, u8 lmac_id)
static u16 cgxlmac_to_pfmap(struct rvu *rvu, u8 cgx_id, u8 lmac_id)
{
	return rvu->cgxlmac2pf_map[CGX_OFFSET(cgx_id) + lmac_id];
}

static inline u8 cgxlmac_id_to_bmap(u8 cgx_id, u8 lmac_id)
static int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id)
{
	unsigned long pfmap;

	pfmap = cgxlmac_to_pfmap(rvu, cgx_id, lmac_id);

	/* Assumes only one pf mapped to a cgx lmac port */
	if (!pfmap)
		return -ENODEV;
	else
		return find_first_bit(&pfmap, 16);
}

static u8 cgxlmac_id_to_bmap(u8 cgx_id, u8 lmac_id)
{
	return ((cgx_id & 0xF) << 4) | (lmac_id & 0xF);
}
@@ -562,3 +576,47 @@ int rvu_mbox_handler_cgx_intlbk_disable(struct rvu *rvu, struct msg_req *req,
	rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, false);
	return 0;
}

/* Finds cumulative status of NIX rx/tx counters from LF of a PF and those
 * from its VFs as well. ie. NIX rx/tx counters at the CGX port level
 */
int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id,
			   int index, int rxtxflag, u64 *stat)
{
	struct rvu_block *block;
	int blkaddr;
	u16 pcifunc;
	int pf, lf;

	if (!cgxd || !rvu)
		return -EINVAL;

	pf = cgxlmac_to_pf(rvu, cgx_get_cgxid(cgxd), lmac_id);
	if (pf < 0)
		return pf;

	/* Assumes LF of a PF and all of its VF belongs to the same
	 * NIX block
	 */
	pcifunc = pf << RVU_PFVF_PF_SHIFT;
	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
	if (blkaddr < 0)
		return 0;
	block = &rvu->hw->block[blkaddr];

	*stat = 0;
	for (lf = 0; lf < block->lf.max; lf++) {
		/* Check if a lf is attached to this PF or one of its VFs */
		if (!((block->fn_map[lf] & ~RVU_PFVF_FUNC_MASK) == (pcifunc &
			 ~RVU_PFVF_FUNC_MASK)))
			continue;
		if (rxtxflag == NIX_STATS_RX)
			*stat += rvu_read64(rvu, blkaddr,
					    NIX_AF_LFX_RX_STATX(lf, index));
		else
			*stat += rvu_read64(rvu, blkaddr,
					    NIX_AF_LFX_TX_STATX(lf, index));
	}

	return 0;
}
+95 −0
Original line number Diff line number Diff line
@@ -44,6 +44,33 @@ enum {
	CGX_STAT18,
};

/* NIX TX stats */
enum nix_stat_lf_tx {
	TX_UCAST	= 0x0,
	TX_BCAST	= 0x1,
	TX_MCAST	= 0x2,
	TX_DROP		= 0x3,
	TX_OCTS		= 0x4,
	TX_STATS_ENUM_LAST,
};

/* NIX RX stats */
enum nix_stat_lf_rx {
	RX_OCTS		= 0x0,
	RX_UCAST	= 0x1,
	RX_BCAST	= 0x2,
	RX_MCAST	= 0x3,
	RX_DROP		= 0x4,
	RX_DROP_OCTS	= 0x5,
	RX_FCS		= 0x6,
	RX_ERR		= 0x7,
	RX_DRP_BCAST	= 0x8,
	RX_DRP_MCAST	= 0x9,
	RX_DRP_L3BCAST	= 0xa,
	RX_DRP_L3MCAST	= 0xb,
	RX_STATS_ENUM_LAST,
};

static char *cgx_rx_stats_fields[] = {
	[CGX_STAT0]	= "Received packets",
	[CGX_STAT1]	= "Octets of received packets",
@@ -1329,12 +1356,39 @@ create_failed:
	debugfs_remove_recursive(rvu->rvu_dbg.npa);
}

#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;
	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;

	/* Link status */
	seq_puts(s, "\n=======Link Status======\n\n");
@@ -1344,6 +1398,47 @@ static int cgx_print_stats(struct seq_file *s, int lmac_id)
	seq_printf(s, "\nLink is %s %d Mbps\n\n",
		   linfo.link_up ? "UP" : "DOWN", linfo.speed);

	/* Rx stats */
	seq_puts(s, "\n=======NIX RX_STATS(CGX port level)======\n\n");
	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_puts(s, "\n=======NIX TX_STATS(CGX port level)======\n\n");
	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_puts(s, "\n=======CGX RX_STATS======\n\n");
	while (stat < CGX_RX_STATS_COUNT) {