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

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
......@@ -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
......
......@@ -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);
......
......@@ -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,
......
......@@ -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;
}
......@@ -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 @@ static void rvu_dbg_npa_init(struct rvu *rvu)
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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment