All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kurt Kanzenbach <kurt@linutronix.de>
To: Andrew Lunn <andrew@lunn.ch>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	netdev@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
	devicetree@vger.kernel.org,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Richard Cochran <richardcochran@gmail.com>,
	Kamil Alkhouri <kamil.alkhouri@hs-offenburg.de>,
	ilias.apalodimas@linaro.org, Kurt Kanzenbach <kurt@linutronix.de>
Subject: [RFC PATCH 6/9] net: dsa: hellcreek: Add debugging mechanisms
Date: Thu, 18 Jun 2020 08:40:26 +0200	[thread overview]
Message-ID: <20200618064029.32168-7-kurt@linutronix.de> (raw)
In-Reply-To: <20200618064029.32168-1-kurt@linutronix.de>

The switch has registers which are useful for debugging issues:

 * Trace registers

   This can be helpful to trace why packets have been filtered or dropped or if
   there any other serious problems.

 * Memory registers

   These registers provide the current switch internal RAM
   utilization. Especially a unexpected workload with an not appropriate queue
   setup packets might be dropped due to memory exhaustion.

Expose that registers via debugfs.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
---
 drivers/net/dsa/hirschmann/hellcreek.c | 207 ++++++++++++++++++++++++-
 drivers/net/dsa/hirschmann/hellcreek.h |   1 +
 2 files changed, 205 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c
index 7e678b298f99..a56df65ae486 100644
--- a/drivers/net/dsa/hirschmann/hellcreek.c
+++ b/drivers/net/dsa/hirschmann/hellcreek.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/ktime.h>
 #include <linux/time.h>
+#include <linux/debugfs.h>
 #include <net/dsa.h>
 #include <net/pkt_sched.h>
 
@@ -1371,6 +1372,195 @@ static int hellcreek_port_setup_tc(struct dsa_switch *ds, int port,
 	return hellcreek_port_del_schedule(ds, port);
 }
 
+static ssize_t hellcreek_dbg_swtrc_cfg_write(struct file *filp,
+					     const char __user *buffer,
+					     size_t count, loff_t *ppos)
+{
+	struct hellcreek *hellcreek = filp->private_data;
+	int ret;
+	u16 reg;
+
+	ret = kstrtou16_from_user(buffer, count, 16, &reg);
+	if (ret)
+		return ret;
+
+	hellcreek_write(hellcreek, reg, HR_SWTRC_CFG);
+
+	return count;
+}
+
+static ssize_t hellcreek_dbg_swtrc0_write(struct file *filp,
+					  const char __user *buffer,
+					  size_t count, loff_t *ppos)
+{
+	struct hellcreek *hellcreek = filp->private_data;
+	int ret;
+	u16 reg;
+
+	ret = kstrtou16_from_user(buffer, count, 16, &reg);
+	if (ret)
+		return ret;
+
+	hellcreek_write(hellcreek, reg, HR_SWTRC0);
+
+	return count;
+}
+
+static ssize_t hellcreek_dbg_swtrc1_write(struct file *filp,
+					  const char __user *buffer,
+					  size_t count, loff_t *ppos)
+{
+	struct hellcreek *hellcreek = filp->private_data;
+	int ret;
+	u16 reg;
+
+	ret = kstrtou16_from_user(buffer, count, 16, &reg);
+	if (ret)
+		return ret;
+
+	hellcreek_write(hellcreek, reg, HR_SWTRC1);
+
+	return count;
+}
+
+static ssize_t hellcreek_dbg_swtrc0_read(struct file *filp,
+					 char __user *buffer,
+					 size_t count, loff_t *ppos)
+{
+	struct hellcreek *hellcreek = filp->private_data;
+	char buf[32];
+	ssize_t desc = 0;
+	u16 reg;
+
+	reg = hellcreek_read(hellcreek, HR_SWTRC0);
+
+	desc += snprintf(buf, sizeof(buf), "0x%04x\n", reg);
+
+	return simple_read_from_buffer(buffer, count, ppos, buf, desc);
+}
+
+static ssize_t hellcreek_dbg_swtrc1_read(struct file *filp,
+					 char __user *buffer,
+					 size_t count, loff_t *ppos)
+{
+	struct hellcreek *hellcreek = filp->private_data;
+	char buf[32];
+	ssize_t desc = 0;
+	u16 reg;
+
+	reg = hellcreek_read(hellcreek, HR_SWTRC1);
+
+	desc += snprintf(buf, sizeof(buf), "0x%04x\n", reg);
+
+	return simple_read_from_buffer(buffer, count, ppos, buf, desc);
+}
+
+static ssize_t hellcreek_dbg_mfree_read(struct file *filp,
+					char __user *buffer,
+					size_t count, loff_t *ppos)
+{
+	struct hellcreek *hellcreek = filp->private_data;
+	char buf[32];
+	ssize_t desc = 0;
+	u16 reg;
+
+	reg = hellcreek_read(hellcreek, HR_MFREE);
+
+	desc += snprintf(buf, sizeof(buf), "0x%04x\n", reg);
+
+	return simple_read_from_buffer(buffer, count, ppos, buf, desc);
+}
+
+static ssize_t hellcreek_dbg_pfree_read(struct file *filp,
+					char __user *buffer,
+					size_t count, loff_t *ppos)
+{
+	struct hellcreek *hellcreek = filp->private_data;
+	char buf[32];
+	ssize_t desc = 0;
+	u16 reg;
+
+	reg = hellcreek_read(hellcreek, HR_PFREE);
+
+	desc += snprintf(buf, sizeof(buf), "0x%04x\n", reg);
+
+	return simple_read_from_buffer(buffer, count, ppos, buf, desc);
+}
+
+static const struct file_operations hellcreek_dbg_swtrc_cfg_fops = {
+	.owner = THIS_MODULE,
+	.open  = simple_open,
+	.write = hellcreek_dbg_swtrc_cfg_write,
+};
+
+static const struct file_operations hellcreek_dbg_swtrc0_fops = {
+	.owner = THIS_MODULE,
+	.open  = simple_open,
+	.read  = hellcreek_dbg_swtrc0_read,
+	.write = hellcreek_dbg_swtrc0_write,
+};
+
+static const struct file_operations hellcreek_dbg_swtrc1_fops = {
+	.owner = THIS_MODULE,
+	.open  = simple_open,
+	.read  = hellcreek_dbg_swtrc1_read,
+	.write = hellcreek_dbg_swtrc1_write,
+};
+
+static const struct file_operations hellcreek_dbg_pfree_fops = {
+	.owner = THIS_MODULE,
+	.open  = simple_open,
+	.read  = hellcreek_dbg_pfree_read,
+};
+
+static const struct file_operations hellcreek_dbg_mfree_fops = {
+	.owner = THIS_MODULE,
+	.open  = simple_open,
+	.read  = hellcreek_dbg_mfree_read,
+};
+
+static int hellcreek_debugfs_init(struct hellcreek *hellcreek)
+{
+	struct dentry *file;
+
+	hellcreek->debug_dir = debugfs_create_dir(dev_name(hellcreek->dev),
+						  NULL);
+	if (!hellcreek->debug_dir)
+		return -ENOMEM;
+
+	file = debugfs_create_file("swtrc_cfg", 0200, hellcreek->debug_dir,
+				   hellcreek, &hellcreek_dbg_swtrc_cfg_fops);
+	if (!file)
+		return -ENOMEM;
+
+	file = debugfs_create_file("swtrc0", 0600, hellcreek->debug_dir,
+				   hellcreek, &hellcreek_dbg_swtrc0_fops);
+	if (!file)
+		return -ENOMEM;
+
+	file = debugfs_create_file("swtrc1", 0600, hellcreek->debug_dir,
+				   hellcreek, &hellcreek_dbg_swtrc1_fops);
+	if (!file)
+		return -ENOMEM;
+
+	file = debugfs_create_file("pfree", 0400, hellcreek->debug_dir,
+				   hellcreek, &hellcreek_dbg_pfree_fops);
+	if (!file)
+		return -ENOMEM;
+
+	file = debugfs_create_file("mfree", 0400, hellcreek->debug_dir,
+				   hellcreek, &hellcreek_dbg_mfree_fops);
+	if (!file)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void hellcreek_debugfs_exit(struct hellcreek *hellcreek)
+{
+	debugfs_remove_recursive(hellcreek->debug_dir);
+}
+
 static const struct dsa_switch_ops hellcreek_ds_ops = {
 	.get_tag_protocol    = hellcreek_get_tag_protocol,
 	.setup		     = hellcreek_setup,
@@ -1475,9 +1665,17 @@ static int hellcreek_probe(struct platform_device *pdev)
 
 	hellcreek_feature_detect(hellcreek);
 
+	ret = hellcreek_debugfs_init(hellcreek);
+	if (ret) {
+		dev_err(dev, "Failed to initialize debugfs!\n");
+		goto err_debugfs;
+	}
+
 	hellcreek->ds = devm_kzalloc(dev, sizeof(*hellcreek->ds), GFP_KERNEL);
-	if (!hellcreek->ds)
-		return -ENOMEM;
+	if (!hellcreek->ds) {
+		ret = -ENOMEM;
+		goto err_debugfs;
+	}
 
 	hellcreek->ds->dev	     = dev;
 	hellcreek->ds->priv	     = hellcreek;
@@ -1488,7 +1686,7 @@ static int hellcreek_probe(struct platform_device *pdev)
 	ret = dsa_register_switch(hellcreek->ds);
 	if (ret) {
 		dev_err(dev, "Unable to register switch\n");
-		return ret;
+		goto err_debugfs;
 	}
 
 	ret = hellcreek_ptp_setup(hellcreek);
@@ -1511,6 +1709,8 @@ static int hellcreek_probe(struct platform_device *pdev)
 	hellcreek_ptp_free(hellcreek);
 err_ptp_setup:
 	dsa_unregister_switch(hellcreek->ds);
+err_debugfs:
+	hellcreek_debugfs_exit(hellcreek);
 
 	return ret;
 }
@@ -1519,6 +1719,7 @@ static int hellcreek_remove(struct platform_device *pdev)
 {
 	struct hellcreek *hellcreek = platform_get_drvdata(pdev);
 
+	hellcreek_debugfs_exit(hellcreek);
 	hellcreek_hwtstamp_free(hellcreek);
 	hellcreek_ptp_free(hellcreek);
 	dsa_unregister_switch(hellcreek->ds);
diff --git a/drivers/net/dsa/hirschmann/hellcreek.h b/drivers/net/dsa/hirschmann/hellcreek.h
index d3d1a1144857..59cc7b59ff2c 100644
--- a/drivers/net/dsa/hirschmann/hellcreek.h
+++ b/drivers/net/dsa/hirschmann/hellcreek.h
@@ -280,6 +280,7 @@ struct hellcreek {
 	struct ptp_clock_info ptp_clock_info;
 	struct hellcreek_port ports[4];
 	struct delayed_work overflow_work;
+	struct dentry *debug_dir;
 	spinlock_t reg_lock;	/* Switch IP register lock */
 	spinlock_t ptp_lock;	/* PTP IP register lock */
 	void __iomem *base;
-- 
2.20.1


  parent reply	other threads:[~2020-06-18  6:41 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-18  6:40 [RFC PATCH 0/9] Hirschmann Hellcreek DSA driver Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 1/9] net: dsa: Add tag handling for Hirschmann Hellcreek switches Kurt Kanzenbach
2020-06-18 13:42   ` Andrew Lunn
2020-06-18  6:40 ` [RFC PATCH 2/9] net: dsa: Add DSA driver " Kurt Kanzenbach
2020-06-18 15:22   ` Andrew Lunn
2020-06-19  8:12     ` Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 3/9] net: dsa: hellcreek: Add PTP clock support Kurt Kanzenbach
2020-06-18 15:46   ` Jakub Kicinski
2020-06-19  8:13     ` Kurt Kanzenbach
2020-06-18 17:23   ` Andrew Lunn
2020-06-19  8:26     ` Kurt Kanzenbach
2020-06-19 13:40       ` Andrew Lunn
2020-06-22 11:52         ` Kurt Kanzenbach
2020-06-24 13:03   ` Richard Cochran
2020-06-25  7:08     ` Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 4/9] net: dsa: hellcreek: Add support for hardware timestamping Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 5/9] net: dsa: hellcreek: Add TAPRIO offloading support Kurt Kanzenbach
2020-06-18  6:40 ` Kurt Kanzenbach [this message]
2020-06-18 17:34   ` [RFC PATCH 6/9] net: dsa: hellcreek: Add debugging mechanisms Andrew Lunn
2020-06-19  8:36     ` Kurt Kanzenbach
2020-06-19 13:42       ` Andrew Lunn
2020-06-22 12:32         ` Kurt Kanzenbach
2020-06-22 13:55           ` Andrew Lunn
2020-06-23  6:07             ` Kurt Kanzenbach
2020-06-22 14:14           ` Vladimir Oltean
2020-06-23  6:04             ` Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 7/9] net: dsa: hellcreek: Add PTP status LEDs Kurt Kanzenbach
2020-06-18 17:46   ` Andrew Lunn
2020-06-19  8:45     ` Kurt Kanzenbach
2020-06-19 13:52       ` Andrew Lunn
2020-06-18  6:40 ` [RFC PATCH 8/9] dt-bindings: Add vendor prefix for Hirschmann Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 9/9] dt-bindings: net: dsa: Add documentation for Hellcreek switches Kurt Kanzenbach
2020-06-18 13:47   ` Andrew Lunn
2020-06-19  8:47     ` Kurt Kanzenbach
2020-06-19 13:56       ` Andrew Lunn
2020-06-22 12:02         ` Kurt Kanzenbach
2020-06-22 13:49           ` Andrew Lunn
2020-06-23  6:09             ` Kurt Kanzenbach
2020-06-18 17:40   ` Florian Fainelli
2020-06-19  8:48     ` Kurt Kanzenbach
2020-06-22 12:05       ` Kurt Kanzenbach
2020-06-26 17:11         ` Florian Fainelli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200618064029.32168-7-kurt@linutronix.de \
    --to=kurt@linutronix.de \
    --cc=andrew@lunn.ch \
    --cc=bigeasy@linutronix.de \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=kamil.alkhouri@hs-offenburg.de \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=richardcochran@gmail.com \
    --cc=robh+dt@kernel.org \
    --cc=vivien.didelot@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.