Message ID | E1kyYPT-0004fo-W5@rmk-PC.armlinux.org.uk |
---|---|
State | New |
Headers | show |
Series | [RESEND] net: sfp: add debugfs support | expand |
Hi, This should've had net-next in the subject line! I'll re-send. On Sun, Jan 10, 2021 at 10:57:23AM +0000, Russell King wrote: > Add debugfs support to SFP so that the internal state of the SFP state > machines and hardware signal state can be viewed from userspace, rather > than having to compile a debug kernel to view state state transitions > in the kernel log. The 'state' output looks like: > > Module state: empty > Module probe attempts: 0 0 > Device state: up > Main state: down > Fault recovery remaining retries: 5 > PHY probe remaining retries: 12 > moddef0: 0 > rx_los: 1 > tx_fault: 1 > tx_disable: 1 > > Reviewed-by: Andrew Lunn <andrew@lunn.ch> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> > --- > drivers/net/phy/sfp.c | 55 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 55 insertions(+) > > diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c > index 91d74c1a920a..374351de2063 100644 > --- a/drivers/net/phy/sfp.c > +++ b/drivers/net/phy/sfp.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0 > #include <linux/acpi.h> > #include <linux/ctype.h> > +#include <linux/debugfs.h> > #include <linux/delay.h> > #include <linux/gpio/consumer.h> > #include <linux/hwmon.h> > @@ -258,6 +259,9 @@ struct sfp { > char *hwmon_name; > #endif > > +#if IS_ENABLED(CONFIG_DEBUG_FS) > + struct dentry *debugfs_dir; > +#endif > }; > > static bool sff_module_supported(const struct sfp_eeprom_id *id) > @@ -1390,6 +1394,54 @@ static void sfp_module_tx_enable(struct sfp *sfp) > sfp_set_state(sfp, sfp->state); > } > > +#if IS_ENABLED(CONFIG_DEBUG_FS) > +static int sfp_debug_state_show(struct seq_file *s, void *data) > +{ > + struct sfp *sfp = s->private; > + > + seq_printf(s, "Module state: %s\n", > + mod_state_to_str(sfp->sm_mod_state)); > + seq_printf(s, "Module probe attempts: %d %d\n", > + R_PROBE_RETRY_INIT - sfp->sm_mod_tries_init, > + R_PROBE_RETRY_SLOW - sfp->sm_mod_tries); > + seq_printf(s, "Device state: %s\n", > + dev_state_to_str(sfp->sm_dev_state)); > + seq_printf(s, "Main state: %s\n", > + sm_state_to_str(sfp->sm_state)); > + seq_printf(s, "Fault recovery remaining retries: %d\n", > + sfp->sm_fault_retries); > + seq_printf(s, "PHY probe remaining retries: %d\n", > + sfp->sm_phy_retries); > + seq_printf(s, "moddef0: %d\n", !!(sfp->state & SFP_F_PRESENT)); > + seq_printf(s, "rx_los: %d\n", !!(sfp->state & SFP_F_LOS)); > + seq_printf(s, "tx_fault: %d\n", !!(sfp->state & SFP_F_TX_FAULT)); > + seq_printf(s, "tx_disable: %d\n", !!(sfp->state & SFP_F_TX_DISABLE)); > + return 0; > +} > +DEFINE_SHOW_ATTRIBUTE(sfp_debug_state); > + > +static void sfp_debugfs_init(struct sfp *sfp) > +{ > + sfp->debugfs_dir = debugfs_create_dir(dev_name(sfp->dev), NULL); > + > + debugfs_create_file("state", 0600, sfp->debugfs_dir, sfp, > + &sfp_debug_state_fops); > +} > + > +static void sfp_debugfs_exit(struct sfp *sfp) > +{ > + debugfs_remove_recursive(sfp->debugfs_dir); > +} > +#else > +static void sfp_debugfs_init(struct sfp *sfp) > +{ > +} > + > +static void sfp_debugfs_exit(struct sfp *sfp) > +{ > +} > +#endif > + > static void sfp_module_tx_fault_reset(struct sfp *sfp) > { > unsigned int state = sfp->state; > @@ -2483,6 +2535,8 @@ static int sfp_probe(struct platform_device *pdev) > if (!sfp->sfp_bus) > return -ENOMEM; > > + sfp_debugfs_init(sfp); > + > return 0; > } > > @@ -2490,6 +2544,7 @@ static int sfp_remove(struct platform_device *pdev) > { > struct sfp *sfp = platform_get_drvdata(pdev); > > + sfp_debugfs_exit(sfp); > sfp_unregister_socket(sfp->sfp_bus); > > rtnl_lock(); > -- > 2.20.1 > >
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 91d74c1a920a..374351de2063 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/acpi.h> #include <linux/ctype.h> +#include <linux/debugfs.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/hwmon.h> @@ -258,6 +259,9 @@ struct sfp { char *hwmon_name; #endif +#if IS_ENABLED(CONFIG_DEBUG_FS) + struct dentry *debugfs_dir; +#endif }; static bool sff_module_supported(const struct sfp_eeprom_id *id) @@ -1390,6 +1394,54 @@ static void sfp_module_tx_enable(struct sfp *sfp) sfp_set_state(sfp, sfp->state); } +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int sfp_debug_state_show(struct seq_file *s, void *data) +{ + struct sfp *sfp = s->private; + + seq_printf(s, "Module state: %s\n", + mod_state_to_str(sfp->sm_mod_state)); + seq_printf(s, "Module probe attempts: %d %d\n", + R_PROBE_RETRY_INIT - sfp->sm_mod_tries_init, + R_PROBE_RETRY_SLOW - sfp->sm_mod_tries); + seq_printf(s, "Device state: %s\n", + dev_state_to_str(sfp->sm_dev_state)); + seq_printf(s, "Main state: %s\n", + sm_state_to_str(sfp->sm_state)); + seq_printf(s, "Fault recovery remaining retries: %d\n", + sfp->sm_fault_retries); + seq_printf(s, "PHY probe remaining retries: %d\n", + sfp->sm_phy_retries); + seq_printf(s, "moddef0: %d\n", !!(sfp->state & SFP_F_PRESENT)); + seq_printf(s, "rx_los: %d\n", !!(sfp->state & SFP_F_LOS)); + seq_printf(s, "tx_fault: %d\n", !!(sfp->state & SFP_F_TX_FAULT)); + seq_printf(s, "tx_disable: %d\n", !!(sfp->state & SFP_F_TX_DISABLE)); + return 0; +} +DEFINE_SHOW_ATTRIBUTE(sfp_debug_state); + +static void sfp_debugfs_init(struct sfp *sfp) +{ + sfp->debugfs_dir = debugfs_create_dir(dev_name(sfp->dev), NULL); + + debugfs_create_file("state", 0600, sfp->debugfs_dir, sfp, + &sfp_debug_state_fops); +} + +static void sfp_debugfs_exit(struct sfp *sfp) +{ + debugfs_remove_recursive(sfp->debugfs_dir); +} +#else +static void sfp_debugfs_init(struct sfp *sfp) +{ +} + +static void sfp_debugfs_exit(struct sfp *sfp) +{ +} +#endif + static void sfp_module_tx_fault_reset(struct sfp *sfp) { unsigned int state = sfp->state; @@ -2483,6 +2535,8 @@ static int sfp_probe(struct platform_device *pdev) if (!sfp->sfp_bus) return -ENOMEM; + sfp_debugfs_init(sfp); + return 0; } @@ -2490,6 +2544,7 @@ static int sfp_remove(struct platform_device *pdev) { struct sfp *sfp = platform_get_drvdata(pdev); + sfp_debugfs_exit(sfp); sfp_unregister_socket(sfp->sfp_bus); rtnl_lock();