netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V3 net-next 0/2] net: wwan: debugfs support for wwan device logging
@ 2021-11-20 16:21 M Chetan Kumar
  2021-11-20 16:21 ` [PATCH V3 net-next 1/2] net: wwan: common debugfs base dir for wwan device M Chetan Kumar
  2021-11-20 16:21 ` [PATCH V3 net-next 2/2] net: wwan: iosm: device trace collection using relayfs M Chetan Kumar
  0 siblings, 2 replies; 5+ messages in thread
From: M Chetan Kumar @ 2021-11-20 16:21 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain,
	krishna.c.sudi, m.chetan.kumar, m.chetan.kumar, linuxwwan

This patch series brings in
1) A common debugfs base directory i.e. /sys/kernel/debugfs/wwan/
in WWAN Subsystem for a WWAN device instance.

2) And support for Device trace collection in IOSM Diver using relayfs
interface.

Changes since v2:
PATCH1:
  * Removed unnecessary checks & empty lines before error checks.
PATCH2:
  * Removed empty lines before error checks.

Changes since v1:
PATCH1:
  * Changes in WWAN Subsystem to support common debugfs base directory.
PATCH2:
  * IOSM Driver adaption to get WWAN device dentry.
  * Removed unnecessary checks.

M Chetan Kumar (2):
  net: wwan: common debugfs base dir for wwan device
  net: wwan: iosm: device trace collection using relayfs

 drivers/net/wwan/iosm/Makefile            |   3 +-
 drivers/net/wwan/iosm/iosm_ipc_imem.c     |  13 ++
 drivers/net/wwan/iosm/iosm_ipc_imem.h     |   2 +
 drivers/net/wwan/iosm/iosm_ipc_imem_ops.c |  31 +++-
 drivers/net/wwan/iosm/iosm_ipc_imem_ops.h |   9 +-
 drivers/net/wwan/iosm/iosm_ipc_port.c     |   2 +-
 drivers/net/wwan/iosm/iosm_ipc_trace.c    | 173 ++++++++++++++++++++++
 drivers/net/wwan/iosm/iosm_ipc_trace.h    |  51 +++++++
 drivers/net/wwan/wwan_core.c              |  31 +++-
 include/linux/wwan.h                      |   2 +
 10 files changed, 302 insertions(+), 15 deletions(-)
 create mode 100644 drivers/net/wwan/iosm/iosm_ipc_trace.c
 create mode 100644 drivers/net/wwan/iosm/iosm_ipc_trace.h

--
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH V3 net-next 1/2] net: wwan: common debugfs base dir for wwan device
  2021-11-20 16:21 [PATCH V3 net-next 0/2] net: wwan: debugfs support for wwan device logging M Chetan Kumar
@ 2021-11-20 16:21 ` M Chetan Kumar
  2021-11-22  8:55   ` Loic Poulain
  2021-11-28 16:53   ` Sergey Ryazanov
  2021-11-20 16:21 ` [PATCH V3 net-next 2/2] net: wwan: iosm: device trace collection using relayfs M Chetan Kumar
  1 sibling, 2 replies; 5+ messages in thread
From: M Chetan Kumar @ 2021-11-20 16:21 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain,
	krishna.c.sudi, m.chetan.kumar, m.chetan.kumar, linuxwwan

This patch set brings in a common debugfs base directory
i.e. /sys/kernel/debugfs/wwan/ in WWAN Subsystem for a
WWAN device instance. So that it avoids driver polluting
debugfs root with unrelated directories & possible name
collusion.

Having a common debugfs base directory for WWAN drivers
eases user to match control devices with debugfs entries.

WWAN Subsystem creates dentry (/sys/kernel/debugfs/wwan)
on module load & removes dentry on module unload.

When driver registers a new wwan device, dentry (wwanX)
is created for WWAN device instance & on driver unregister
dentry is removed.

New API is introduced to return the wwan device instance
dentry so that driver can create debugfs entries under it.

Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
---
v3:
* Removed unnecessary checks & empty lines before error checks.
---
 drivers/net/wwan/wwan_core.c | 31 +++++++++++++++++++++++++++++--
 include/linux/wwan.h         |  2 ++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c
index d293ab688044..aa9c1f7c944f 100644
--- a/drivers/net/wwan/wwan_core.c
+++ b/drivers/net/wwan/wwan_core.c
@@ -3,6 +3,7 @@

 #include <linux/err.h>
 #include <linux/errno.h>
+#include <linux/debugfs.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/idr.h>
@@ -25,6 +26,7 @@ static DEFINE_IDA(minors); /* minors for WWAN port chardevs */
 static DEFINE_IDA(wwan_dev_ids); /* for unique WWAN device IDs */
 static struct class *wwan_class;
 static int wwan_major;
+static struct dentry *wwan_debugfs_dir;

 #define to_wwan_dev(d) container_of(d, struct wwan_device, dev)
 #define to_wwan_port(d) container_of(d, struct wwan_port, dev)
@@ -40,6 +42,7 @@ static int wwan_major;
  * @port_id: Current available port ID to pick.
  * @ops: wwan device ops
  * @ops_ctxt: context to pass to ops
+ * @debugfs_dir:  WWAN device debugfs dir
  */
 struct wwan_device {
 	unsigned int id;
@@ -47,6 +50,7 @@ struct wwan_device {
 	atomic_t port_id;
 	const struct wwan_ops *ops;
 	void *ops_ctxt;
+	struct dentry *debugfs_dir;
 };

 /**
@@ -142,6 +146,18 @@ static struct wwan_device *wwan_dev_get_by_name(const char *name)
 	return to_wwan_dev(dev);
 }

+struct dentry *wwan_get_debugfs_dir(struct device *parent)
+{
+	struct wwan_device *wwandev;
+
+	wwandev = wwan_dev_get_by_parent(parent);
+	if (IS_ERR(wwandev))
+		return ERR_CAST(wwandev);
+
+	return wwandev->debugfs_dir;
+}
+EXPORT_SYMBOL_GPL(wwan_get_debugfs_dir);
+
 /* This function allocates and registers a new WWAN device OR if a WWAN device
  * already exist for the given parent, it gets a reference and return it.
  * This function is not exported (for now), it is called indirectly via
@@ -150,6 +166,7 @@ static struct wwan_device *wwan_dev_get_by_name(const char *name)
 static struct wwan_device *wwan_create_dev(struct device *parent)
 {
 	struct wwan_device *wwandev;
+	const char *wwandev_name;
 	int err, id;

 	/* The 'find-alloc-register' operation must be protected against
@@ -189,6 +206,10 @@ static struct wwan_device *wwan_create_dev(struct device *parent)
 		goto done_unlock;
 	}

+	wwandev_name = kobject_name(&wwandev->dev.kobj);
+	wwandev->debugfs_dir = debugfs_create_dir(wwandev_name,
+						  wwan_debugfs_dir);
+
 done_unlock:
 	mutex_unlock(&wwan_register_lock);

@@ -218,10 +236,12 @@ static void wwan_remove_dev(struct wwan_device *wwandev)
 	else
 		ret = device_for_each_child(&wwandev->dev, NULL, is_wwan_child);

-	if (!ret)
+	if (!ret) {
+		debugfs_remove_recursive(wwandev->debugfs_dir);
 		device_unregister(&wwandev->dev);
-	else
+	} else {
 		put_device(&wwandev->dev);
+	}

 	mutex_unlock(&wwan_register_lock);
 }
@@ -1117,6 +1140,8 @@ static int __init wwan_init(void)
 		goto destroy;
 	}

+	wwan_debugfs_dir = debugfs_create_dir("wwan", NULL);
+
 	return 0;

 destroy:
@@ -1128,6 +1153,7 @@ static int __init wwan_init(void)

 static void __exit wwan_exit(void)
 {
+	debugfs_remove_recursive(wwan_debugfs_dir);
 	__unregister_chrdev(wwan_major, 0, WWAN_MAX_MINORS, "wwan_port");
 	rtnl_link_unregister(&wwan_rtnl_link_ops);
 	class_destroy(wwan_class);
diff --git a/include/linux/wwan.h b/include/linux/wwan.h
index 9fac819f92e3..1646aa3e6779 100644
--- a/include/linux/wwan.h
+++ b/include/linux/wwan.h
@@ -171,4 +171,6 @@ int wwan_register_ops(struct device *parent, const struct wwan_ops *ops,

 void wwan_unregister_ops(struct device *parent);

+struct dentry *wwan_get_debugfs_dir(struct device *parent);
+
 #endif /* __WWAN_H */
--
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH V3 net-next 2/2] net: wwan: iosm: device trace collection using relayfs
  2021-11-20 16:21 [PATCH V3 net-next 0/2] net: wwan: debugfs support for wwan device logging M Chetan Kumar
  2021-11-20 16:21 ` [PATCH V3 net-next 1/2] net: wwan: common debugfs base dir for wwan device M Chetan Kumar
@ 2021-11-20 16:21 ` M Chetan Kumar
  1 sibling, 0 replies; 5+ messages in thread
From: M Chetan Kumar @ 2021-11-20 16:21 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain,
	krishna.c.sudi, m.chetan.kumar, m.chetan.kumar, linuxwwan

This patch brings in support for device trace collection.
It implements relayfs interface for pushing device trace
from kernel space to user space.

Driver gets the debugfs base directory associated to WWAN
Device and creates trace_control and trace debugfs for
device tracing. Both trace_control & trace debugfs are
created under /sys/kernel/debug/wwan/wwan0/.

In order to collect device trace on trace0 interface, user
need to write 1 to trace_ctl interface.

Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
---
v3:
* Removed empty lines before error checks.
v2:
* IOSM Driver adaption to get WWAN device dentry.
* Removed unnecessary checks.
---
 drivers/net/wwan/iosm/Makefile            |   3 +-
 drivers/net/wwan/iosm/iosm_ipc_imem.c     |  13 ++
 drivers/net/wwan/iosm/iosm_ipc_imem.h     |   2 +
 drivers/net/wwan/iosm/iosm_ipc_imem_ops.c |  31 +++-
 drivers/net/wwan/iosm/iosm_ipc_imem_ops.h |   9 +-
 drivers/net/wwan/iosm/iosm_ipc_port.c     |   2 +-
 drivers/net/wwan/iosm/iosm_ipc_trace.c    | 173 ++++++++++++++++++++++
 drivers/net/wwan/iosm/iosm_ipc_trace.h    |  51 +++++++
 8 files changed, 271 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/wwan/iosm/iosm_ipc_trace.c
 create mode 100644 drivers/net/wwan/iosm/iosm_ipc_trace.h

diff --git a/drivers/net/wwan/iosm/Makefile b/drivers/net/wwan/iosm/Makefile
index b838034bb120..5c2528beca2a 100644
--- a/drivers/net/wwan/iosm/Makefile
+++ b/drivers/net/wwan/iosm/Makefile
@@ -21,6 +21,7 @@ iosm-y = \
 	iosm_ipc_mux_codec.o		\
 	iosm_ipc_devlink.o		\
 	iosm_ipc_flash.o		\
-	iosm_ipc_coredump.o
+	iosm_ipc_coredump.o		\
+	iosm_ipc_trace.o

 obj-$(CONFIG_IOSM) := iosm.o
diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem.c b/drivers/net/wwan/iosm/iosm_ipc_imem.c
index cff3b43ca4d7..1be07114c85d 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_imem.c
+++ b/drivers/net/wwan/iosm/iosm_ipc_imem.c
@@ -10,6 +10,7 @@
 #include "iosm_ipc_flash.h"
 #include "iosm_ipc_imem.h"
 #include "iosm_ipc_port.h"
+#include "iosm_ipc_trace.h"

 /* Check the wwan ips if it is valid with Channel as input. */
 static int ipc_imem_check_wwan_ips(struct ipc_mem_channel *chnl)
@@ -265,9 +266,14 @@ static void ipc_imem_dl_skb_process(struct iosm_imem *ipc_imem,
 	switch (pipe->channel->ctype) {
 	case IPC_CTYPE_CTRL:
 		port_id = pipe->channel->channel_id;
+		ipc_pcie_addr_unmap(ipc_imem->pcie, IPC_CB(skb)->len,
+				    IPC_CB(skb)->mapping,
+				    IPC_CB(skb)->direction);
 		if (port_id == IPC_MEM_CTRL_CHL_ID_7)
 			ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink,
 						       skb);
+		else if (port_id == ipc_imem->trace->chl_id)
+			ipc_trace_port_rx(ipc_imem->trace, skb);
 		else
 			wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port,
 				     skb);
@@ -548,6 +554,12 @@ static void ipc_imem_run_state_worker(struct work_struct *instance)
 		ctrl_chl_idx++;
 	}

+	ipc_imem->trace = ipc_imem_trace_channel_init(ipc_imem);
+	if (!ipc_imem->trace) {
+		dev_err(ipc_imem->dev, "trace channel init failed");
+		return;
+	}
+
 	ipc_task_queue_send_task(ipc_imem, ipc_imem_send_mdm_rdy_cb, 0, NULL, 0,
 				 false);

@@ -1163,6 +1175,7 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem)

 	if (test_and_clear_bit(FULLY_FUNCTIONAL, &ipc_imem->flag)) {
 		ipc_mux_deinit(ipc_imem->mux);
+		ipc_trace_deinit(ipc_imem->trace);
 		ipc_wwan_deinit(ipc_imem->wwan);
 		ipc_port_deinit(ipc_imem->ipc_port);
 	}
diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem.h b/drivers/net/wwan/iosm/iosm_ipc_imem.h
index 6be6708b4eec..cec38009c44a 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_imem.h
+++ b/drivers/net/wwan/iosm/iosm_ipc_imem.h
@@ -304,6 +304,7 @@ enum ipc_phase {
  * @sio:			IPC SIO data structure pointer
  * @ipc_port:			IPC PORT data structure pointer
  * @pcie:			IPC PCIe
+ * @trace:			IPC trace data structure pointer
  * @dev:			Pointer to device structure
  * @ipc_requested_state:	Expected IPC state on CP.
  * @channels:			Channel list with UL/DL pipe pairs.
@@ -349,6 +350,7 @@ struct iosm_imem {
 	struct iosm_mux *mux;
 	struct iosm_cdev *ipc_port[IPC_MEM_MAX_CHANNELS];
 	struct iosm_pcie *pcie;
+	struct iosm_trace *trace;
 	struct device *dev;
 	enum ipc_mem_device_ipc_state ipc_requested_state;
 	struct ipc_mem_channel channels[IPC_MEM_MAX_CHANNELS];
diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c b/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
index 825e8e5ffb2a..43f1796a8984 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
+++ b/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
@@ -11,6 +11,7 @@
 #include "iosm_ipc_imem_ops.h"
 #include "iosm_ipc_port.h"
 #include "iosm_ipc_task_queue.h"
+#include "iosm_ipc_trace.h"

 /* Open a packet data online channel between the network layer and CP. */
 int ipc_imem_sys_wwan_open(struct iosm_imem *ipc_imem, int if_id)
@@ -107,6 +108,23 @@ void ipc_imem_wwan_channel_init(struct iosm_imem *ipc_imem,
 			"failed to register the ipc_wwan interfaces");
 }

+/**
+ * ipc_imem_trace_channel_init - Initializes trace channel.
+ * @ipc_imem:          Pointer to iosm_imem struct.
+ *
+ * Returns: Pointer to trace instance on success else NULL
+ */
+struct iosm_trace *ipc_imem_trace_channel_init(struct iosm_imem *ipc_imem)
+{
+	struct ipc_chnl_cfg chnl_cfg = { 0 };
+
+	ipc_chnl_cfg_get(&chnl_cfg, IPC_MEM_CTRL_CHL_ID_3);
+	ipc_imem_channel_init(ipc_imem, IPC_CTYPE_CTRL, chnl_cfg,
+			      IRQ_MOD_OFF);
+
+	return ipc_trace_init(ipc_imem);
+}
+
 /* Map SKB to DMA for transfer */
 static int ipc_imem_map_skb_to_dma(struct iosm_imem *ipc_imem,
 				   struct sk_buff *skb)
@@ -182,11 +200,14 @@ static bool ipc_imem_is_channel_active(struct iosm_imem *ipc_imem,
 	return false;
 }

-/* Release a sio link to CP. */
-void ipc_imem_sys_cdev_close(struct iosm_cdev *ipc_cdev)
+/**
+ * ipc_imem_sys_port_close - Release a sio link to CP.
+ * @ipc_imem:          Imem instance.
+ * @channel:           Channel instance.
+ */
+void ipc_imem_sys_port_close(struct iosm_imem *ipc_imem,
+			     struct ipc_mem_channel *channel)
 {
-	struct iosm_imem *ipc_imem = ipc_cdev->ipc_imem;
-	struct ipc_mem_channel *channel = ipc_cdev->channel;
 	enum ipc_phase curr_phase;
 	int status = 0;
 	u32 tail = 0;
@@ -643,6 +664,6 @@ int ipc_imem_sys_devlink_read(struct iosm_devlink *devlink, u8 *data,
 	memcpy(data, skb->data, skb->len);

 devlink_read_fail:
-	ipc_pcie_kfree_skb(devlink->pcie, skb);
+	dev_kfree_skb(skb);
 	return rc;
 }
diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem_ops.h b/drivers/net/wwan/iosm/iosm_ipc_imem_ops.h
index f0c88ac5643c..e36ee2782629 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_imem_ops.h
+++ b/drivers/net/wwan/iosm/iosm_ipc_imem_ops.h
@@ -43,12 +43,8 @@
  */
 struct ipc_mem_channel *ipc_imem_sys_port_open(struct iosm_imem *ipc_imem,
 					       int chl_id, int hp_id);
-
-/**
- * ipc_imem_sys_cdev_close - Release a sio link to CP.
- * @ipc_cdev:		iosm sio instance.
- */
-void ipc_imem_sys_cdev_close(struct iosm_cdev *ipc_cdev);
+void ipc_imem_sys_port_close(struct iosm_imem *ipc_imem,
+			     struct ipc_mem_channel *channel);

 /**
  * ipc_imem_sys_cdev_write - Route the uplink buffer to CP.
@@ -145,4 +141,5 @@ int ipc_imem_sys_devlink_read(struct iosm_devlink *ipc_devlink, u8 *data,
  */
 int ipc_imem_sys_devlink_write(struct iosm_devlink *ipc_devlink,
 			       unsigned char *buf, int count);
+struct iosm_trace *ipc_imem_trace_channel_init(struct iosm_imem *ipc_imem);
 #endif
diff --git a/drivers/net/wwan/iosm/iosm_ipc_port.c b/drivers/net/wwan/iosm/iosm_ipc_port.c
index beb944847398..b6d81c627277 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_port.c
+++ b/drivers/net/wwan/iosm/iosm_ipc_port.c
@@ -27,7 +27,7 @@ static void ipc_port_ctrl_stop(struct wwan_port *port)
 {
 	struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);

-	ipc_imem_sys_cdev_close(ipc_port);
+	ipc_imem_sys_port_close(ipc_port->ipc_imem, ipc_port->channel);
 }

 /* transfer control data to modem */
diff --git a/drivers/net/wwan/iosm/iosm_ipc_trace.c b/drivers/net/wwan/iosm/iosm_ipc_trace.c
new file mode 100644
index 000000000000..c5fa12599c2b
--- /dev/null
+++ b/drivers/net/wwan/iosm/iosm_ipc_trace.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020-2021 Intel Corporation.
+ */
+
+#include <linux/wwan.h>
+#include "iosm_ipc_trace.h"
+
+/* sub buffer size and number of sub buffer */
+#define IOSM_TRC_SUB_BUFF_SIZE 131072
+#define IOSM_TRC_N_SUB_BUFF 32
+
+#define IOSM_TRC_FILE_PERM 0600
+
+#define IOSM_TRC_DEBUGFS_TRACE "trace"
+#define IOSM_TRC_DEBUGFS_TRACE_CTRL "trace_ctrl"
+
+/**
+ * ipc_trace_port_rx - Receive trace packet from cp and write to relay buffer
+ * @ipc_trace:  Pointer to the ipc trace data-struct
+ * @skb:        Pointer to struct sk_buff
+ */
+void ipc_trace_port_rx(struct iosm_trace *ipc_trace, struct sk_buff *skb)
+{
+	if (ipc_trace->ipc_rchan)
+		relay_write(ipc_trace->ipc_rchan, skb->data, skb->len);
+
+	dev_kfree_skb(skb);
+}
+
+/* Creates relay file in debugfs. */
+static struct dentry *
+ipc_trace_create_buf_file_handler(const char *filename,
+				  struct dentry *parent,
+				  umode_t mode,
+				  struct rchan_buf *buf,
+				  int *is_global)
+{
+	*is_global = 1;
+	return debugfs_create_file(filename, mode, parent, buf,
+				   &relay_file_operations);
+}
+
+/* Removes relay file from debugfs. */
+static int ipc_trace_remove_buf_file_handler(struct dentry *dentry)
+{
+	debugfs_remove(dentry);
+	return 0;
+}
+
+static int ipc_trace_subbuf_start_handler(struct rchan_buf *buf, void *subbuf,
+					  void *prev_subbuf,
+					  size_t prev_padding)
+{
+	if (relay_buf_full(buf)) {
+		pr_err_ratelimited("Relay_buf full dropping traces");
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Relay interface callbacks */
+static struct rchan_callbacks relay_callbacks = {
+	.subbuf_start = ipc_trace_subbuf_start_handler,
+	.create_buf_file = ipc_trace_create_buf_file_handler,
+	.remove_buf_file = ipc_trace_remove_buf_file_handler,
+};
+
+/* Copy the trace control mode to user buffer */
+static ssize_t ipc_trace_ctrl_file_read(struct file *filp, char __user *buffer,
+					size_t count, loff_t *ppos)
+{
+	struct iosm_trace *ipc_trace = filp->private_data;
+	char buf[16];
+	int len;
+
+	mutex_lock(&ipc_trace->trc_mutex);
+	len = snprintf(buf, sizeof(buf), "%d\n", ipc_trace->mode);
+	mutex_unlock(&ipc_trace->trc_mutex);
+
+	return simple_read_from_buffer(buffer, count, ppos, buf, len);
+}
+
+/* Open and close the trace channel depending on user input */
+static ssize_t ipc_trace_ctrl_file_write(struct file *filp,
+					 const char __user *buffer,
+					 size_t count, loff_t *ppos)
+{
+	struct iosm_trace *ipc_trace = filp->private_data;
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul_from_user(buffer, count, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&ipc_trace->trc_mutex);
+	if (val == TRACE_ENABLE && ipc_trace->mode != TRACE_ENABLE) {
+		ipc_trace->channel = ipc_imem_sys_port_open(ipc_trace->ipc_imem,
+							    ipc_trace->chl_id,
+							    IPC_HP_CDEV_OPEN);
+		if (!ipc_trace->channel) {
+			ret = -EIO;
+			goto unlock;
+		}
+		ipc_trace->mode = TRACE_ENABLE;
+	} else if (val == TRACE_DISABLE && ipc_trace->mode != TRACE_DISABLE) {
+		ipc_trace->mode = TRACE_DISABLE;
+		/* close trace channel */
+		ipc_imem_sys_port_close(ipc_trace->ipc_imem,
+					ipc_trace->channel);
+		relay_flush(ipc_trace->ipc_rchan);
+	}
+	ret = count;
+unlock:
+	mutex_unlock(&ipc_trace->trc_mutex);
+	return ret;
+}
+
+static const struct file_operations ipc_trace_fops = {
+	.open = simple_open,
+	.write = ipc_trace_ctrl_file_write,
+	.read  = ipc_trace_ctrl_file_read,
+};
+
+/**
+ * ipc_trace_init - Create trace interface & debugfs entries
+ * @ipc_imem:   Pointer to iosm_imem structure
+ *
+ * Returns: Pointer to trace instance on success else NULL
+ */
+struct iosm_trace *ipc_trace_init(struct iosm_imem *ipc_imem)
+{
+	struct iosm_trace *ipc_trace = kzalloc(sizeof(*ipc_trace), GFP_KERNEL);
+	struct dentry *debugfs_pdev;
+
+	if (!ipc_trace)
+		return NULL;
+
+	ipc_trace->mode = TRACE_DISABLE;
+	ipc_trace->dev = ipc_imem->dev;
+	ipc_trace->ipc_imem = ipc_imem;
+	ipc_trace->chl_id = IPC_MEM_CTRL_CHL_ID_3;
+
+	mutex_init(&ipc_trace->trc_mutex);
+	debugfs_pdev = wwan_get_debugfs_dir(ipc_imem->dev);
+
+	ipc_trace->ctrl_file = debugfs_create_file(IOSM_TRC_DEBUGFS_TRACE_CTRL,
+						   IOSM_TRC_FILE_PERM,
+						   debugfs_pdev,
+						   ipc_trace, &ipc_trace_fops);
+
+	ipc_trace->ipc_rchan = relay_open(IOSM_TRC_DEBUGFS_TRACE,
+					  debugfs_pdev,
+					  IOSM_TRC_SUB_BUFF_SIZE,
+					  IOSM_TRC_N_SUB_BUFF,
+					  &relay_callbacks, NULL);
+
+	return ipc_trace;
+}
+
+/**
+ * ipc_trace_deinit - Closing relayfs, removing debugfs entries
+ * @ipc_trace: Pointer to the iosm_trace data struct
+ */
+void ipc_trace_deinit(struct iosm_trace *ipc_trace)
+{
+	debugfs_remove(ipc_trace->ctrl_file);
+	relay_close(ipc_trace->ipc_rchan);
+	mutex_destroy(&ipc_trace->trc_mutex);
+	kfree(ipc_trace);
+}
diff --git a/drivers/net/wwan/iosm/iosm_ipc_trace.h b/drivers/net/wwan/iosm/iosm_ipc_trace.h
new file mode 100644
index 000000000000..53346183af9c
--- /dev/null
+++ b/drivers/net/wwan/iosm/iosm_ipc_trace.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2020-2021 Intel Corporation.
+ */
+
+#ifndef IOSM_IPC_TRACE_H
+#define IOSM_IPC_TRACE_H
+
+#include <linux/debugfs.h>
+#include <linux/relay.h>
+
+#include "iosm_ipc_chnl_cfg.h"
+#include "iosm_ipc_imem_ops.h"
+
+/**
+ * enum trace_ctrl_mode - State of trace channel
+ * @TRACE_DISABLE:	mode for disable trace
+ * @TRACE_ENABLE:	mode for enable trace
+ */
+enum trace_ctrl_mode {
+	TRACE_DISABLE = 0,
+	TRACE_ENABLE,
+};
+
+/**
+ * struct iosm_trace - Struct for trace interface
+ * @ipc_rchan:		Pointer to relay channel
+ * @ctrl_file:		Pointer to trace control file
+ * @ipc_imem:		Imem instance
+ * @dev:		Pointer to device struct
+ * @channel:		Channel instance
+ * @chl_id:		Channel Indentifier
+ * @trc_mutex:		Mutex used for read and write mode
+ * @mode:		Mode for enable and disable trace
+ */
+
+struct iosm_trace {
+	struct rchan *ipc_rchan;
+	struct dentry *ctrl_file;
+	struct iosm_imem *ipc_imem;
+	struct device *dev;
+	struct ipc_mem_channel *channel;
+	enum ipc_channel_id chl_id;
+	struct mutex trc_mutex;	/* Mutex used for read and write mode */
+	enum trace_ctrl_mode mode;
+};
+
+struct iosm_trace *ipc_trace_init(struct iosm_imem *ipc_imem);
+void ipc_trace_deinit(struct iosm_trace *ipc_trace);
+void ipc_trace_port_rx(struct iosm_trace *ipc_trace, struct sk_buff *skb);
+#endif
--
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH V3 net-next 1/2] net: wwan: common debugfs base dir for wwan device
  2021-11-20 16:21 ` [PATCH V3 net-next 1/2] net: wwan: common debugfs base dir for wwan device M Chetan Kumar
@ 2021-11-22  8:55   ` Loic Poulain
  2021-11-28 16:53   ` Sergey Ryazanov
  1 sibling, 0 replies; 5+ messages in thread
From: Loic Poulain @ 2021-11-22  8:55 UTC (permalink / raw)
  To: M Chetan Kumar
  Cc: netdev, kuba, davem, johannes, ryazanov.s.a, krishna.c.sudi,
	m.chetan.kumar, linuxwwan

On Sat, 20 Nov 2021 at 17:14, M Chetan Kumar
<m.chetan.kumar@linux.intel.com> wrote:
>
> This patch set brings in a common debugfs base directory
> i.e. /sys/kernel/debugfs/wwan/ in WWAN Subsystem for a
> WWAN device instance. So that it avoids driver polluting
> debugfs root with unrelated directories & possible name
> collusion.
>
> Having a common debugfs base directory for WWAN drivers
> eases user to match control devices with debugfs entries.
>
> WWAN Subsystem creates dentry (/sys/kernel/debugfs/wwan)
> on module load & removes dentry on module unload.
>
> When driver registers a new wwan device, dentry (wwanX)
> is created for WWAN device instance & on driver unregister
> dentry is removed.
>
> New API is introduced to return the wwan device instance
> dentry so that driver can create debugfs entries under it.
>
> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>

Reviewed-by: Loic Poulain <loic.poulain@linaro.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH V3 net-next 1/2] net: wwan: common debugfs base dir for wwan device
  2021-11-20 16:21 ` [PATCH V3 net-next 1/2] net: wwan: common debugfs base dir for wwan device M Chetan Kumar
  2021-11-22  8:55   ` Loic Poulain
@ 2021-11-28 16:53   ` Sergey Ryazanov
  1 sibling, 0 replies; 5+ messages in thread
From: Sergey Ryazanov @ 2021-11-28 16:53 UTC (permalink / raw)
  To: M Chetan Kumar
  Cc: netdev, Jakub Kicinski, David Miller, Johannes Berg,
	Loic Poulain, krishna.c.sudi, M Chetan Kumar, Intel Corporation

Hello,

On Sat, Nov 20, 2021 at 7:14 PM M Chetan Kumar
<m.chetan.kumar@linux.intel.com> wrote:
> This patch set brings in a common debugfs base directory
> i.e. /sys/kernel/debugfs/wwan/ in WWAN Subsystem for a
> WWAN device instance. So that it avoids driver polluting
> debugfs root with unrelated directories & possible name
> collusion.
>
> Having a common debugfs base directory for WWAN drivers
> eases user to match control devices with debugfs entries.
>
> WWAN Subsystem creates dentry (/sys/kernel/debugfs/wwan)
> on module load & removes dentry on module unload.
>
> When driver registers a new wwan device, dentry (wwanX)
> is created for WWAN device instance & on driver unregister
> dentry is removed.
>
> New API is introduced to return the wwan device instance
> dentry so that driver can create debugfs entries under it.

Thank you for taking care of the debugfs implementation for the WWAN core.

Please find my follow-up series that tweak the IOSM/WWAN debugfs
interface a bit:
https://lore.kernel.org/all/20211128125522.23357-1-ryazanov.s.a@gmail.com

-- 
Sergey

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-11-28 16:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-20 16:21 [PATCH V3 net-next 0/2] net: wwan: debugfs support for wwan device logging M Chetan Kumar
2021-11-20 16:21 ` [PATCH V3 net-next 1/2] net: wwan: common debugfs base dir for wwan device M Chetan Kumar
2021-11-22  8:55   ` Loic Poulain
2021-11-28 16:53   ` Sergey Ryazanov
2021-11-20 16:21 ` [PATCH V3 net-next 2/2] net: wwan: iosm: device trace collection using relayfs M Chetan Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).