dsa: mv88x6xxx: Add debugfs interface for statistics
authorAndrew Lunn <andrew@lunn.ch>
Sat, 20 Jun 2015 16:42:31 +0000 (18:42 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 23 Jun 2015 13:33:41 +0000 (06:33 -0700)
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>
drivers/net/dsa/mv88e6xxx.c

index 43c1515..fc5d4fd 100644 (file)
@@ -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;
 }