Add a debug filesystem "regs" entry to query a port's hardware registers through the .get_regs_len and .get_regs_len switch operations.
This is very convenient because it allows one to dump the registers of DSA links, which are not exposed to userspace. Here are the registers of a zii-rev-b CPU and DSA ports: # pr -mt switch0/port{5,6}/regs 0: 4e07 0: 4d04 1: 403e 1: 003d 2: 0000 2: 0000 3: 3521 3: 3521 4: 0533 4: 373f 5: 8000 5: 0000 6: 005f 6: 003f 7: 002a 7: 002a 8: 2080 8: 2080 9: 0001 9: 0001 10: 0000 10: 0000 11: 0020 11: 0000 12: 0000 12: 0000 13: 0000 13: 0000 14: 0000 14: 0000 15: 9100 15: dada 16: 0000 16: 0000 17: 0000 17: 0000 18: 0000 18: 0000 19: 0000 19: 00d8 20: 0000 20: 0000 21: 0000 21: 0000 22: 0022 22: 0000 23: 0000 23: 0000 24: 3210 24: 3210 25: 7654 25: 7654 26: 0000 26: 0000 27: 8000 27: 8000 28: 0000 28: 0000 29: 0000 29: 0000 30: 0000 30: 0000 31: 0000 31: 0000 Signed-off-by: Vivien Didelot <vivien.dide...@savoirfairelinux.com> Reviewed-by: Florian Fainelli <f.faine...@gmail.com> Reviewed-by: Andrew Lunn <and...@lunn.ch> --- net/dsa/debugfs.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/net/dsa/debugfs.c b/net/dsa/debugfs.c index 997bbc8eb502..7b299c9d9892 100644 --- a/net/dsa/debugfs.c +++ b/net/dsa/debugfs.c @@ -109,6 +109,40 @@ static int dsa_debugfs_create_file(struct dsa_switch *ds, struct dentry *dir, return 0; } +static void dsa_debugfs_regs_read_count(struct dsa_switch *ds, int id, + struct seq_file *seq, int count) +{ + u16 data[count * ETH_GSTRING_LEN]; + struct ethtool_regs regs; + int i; + + ds->ops->get_regs(ds, id, ®s, data); + + for (i = 0; i < count / 2; i++) + seq_printf(seq, "%2d: %04x\n", i, data[i]); +} + +static int dsa_debugfs_regs_read(struct dsa_switch *ds, int id, + struct seq_file *seq) +{ + int count; + + if (!ds->ops->get_regs_len || !ds->ops->get_regs) + return -EOPNOTSUPP; + + count = ds->ops->get_regs_len(ds, id); + if (count < 0) + return count; + + dsa_debugfs_regs_read_count(ds, id, seq, count); + + return 0; +} + +static const struct dsa_debugfs_ops dsa_debugfs_regs_ops = { + .read = dsa_debugfs_regs_read, +}; + static void dsa_debugfs_stats_read_count(struct dsa_switch *ds, int id, struct seq_file *seq, int count) { @@ -188,6 +222,11 @@ static int dsa_debugfs_create_port(struct dsa_switch *ds, int port) if (IS_ERR_OR_NULL(dir)) return -EFAULT; + err = dsa_debugfs_create_file(ds, dir, "regs", port, + &dsa_debugfs_regs_ops); + if (err) + return err; + err = dsa_debugfs_create_file(ds, dir, "stats", port, &dsa_debugfs_stats_ops); if (err) -- 2.14.1