summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2015-06-20 18:42:31 +0200
committerDavid S. Miller <davem@davemloft.net>2015-06-23 06:33:41 -0700
commit532c7a353fce6b1866865cd52691934b4630cccd (patch)
treeffd0df90aeafe6af02ba64c59cd7386192c5a279
parent80c4627b2719da6b90891d8f83251528416900e7 (diff)
downloadop-kernel-dev-532c7a353fce6b1866865cd52691934b4630cccd.zip
op-kernel-dev-532c7a353fce6b1866865cd52691934b4630cccd.tar.gz
dsa: mv88x6xxx: Add debugfs interface for statistics
Allow the contents of the statistics counters to be shown in debugfs. This is particularly useful for the cpu and dsa ports, which cannot be seen using ethtools -S. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/dsa/mv88e6xxx.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 43c1515..fc5d4fd 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1730,6 +1730,62 @@ static const struct file_operations mv88e6xxx_atu_fops = {
.owner = THIS_MODULE,
};
+static void mv88e6xxx_stats_show_header(struct seq_file *s,
+ struct mv88e6xxx_priv_state *ps)
+{
+ int port;
+
+ seq_puts(s, " Statistic ");
+ for (port = 0 ; port < ps->num_ports; port++)
+ seq_printf(s, "Port %2d ", port);
+ seq_puts(s, "\n");
+}
+
+static int mv88e6xxx_stats_show(struct seq_file *s, void *p)
+{
+ struct dsa_switch *ds = s->private;
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ struct mv88e6xxx_hw_stat *stats = mv88e6xxx_hw_stats;
+ int port, stat, max_stats;
+ uint64_t value;
+
+ if (have_sw_in_discards(ds))
+ max_stats = ARRAY_SIZE(mv88e6xxx_hw_stats);
+ else
+ max_stats = ARRAY_SIZE(mv88e6xxx_hw_stats) - 3;
+
+ mv88e6xxx_stats_show_header(s, ps);
+
+ mutex_lock(&ps->smi_mutex);
+
+ for (stat = 0; stat < max_stats; stat++) {
+ seq_printf(s, "%19s: ", stats[stat].string);
+ for (port = 0 ; port < ps->num_ports; port++) {
+ _mv88e6xxx_stats_snapshot(ds, port);
+ value = _mv88e6xxx_get_ethtool_stat(ds, stat, stats,
+ port);
+ seq_printf(s, "%8llu ", value);
+ }
+ seq_puts(s, "\n");
+ }
+ mutex_unlock(&ps->smi_mutex);
+
+ return 0;
+}
+
+static int mv88e6xxx_stats_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mv88e6xxx_stats_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_stats_fops = {
+ .open = mv88e6xxx_stats_open,
+ .read = seq_read,
+ .llseek = no_llseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
int mv88e6xxx_setup_common(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -1753,6 +1809,9 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
debugfs_create_file("atu", S_IRUGO, ps->dbgfs, ds,
&mv88e6xxx_atu_fops);
+ debugfs_create_file("stats", S_IRUGO, ps->dbgfs, ds,
+ &mv88e6xxx_stats_fops);
+
return 0;
}
OpenPOWER on IntegriCloud