netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Moises Veleta <moises.veleta@linux.intel.com>
To: netdev@vger.kernel.org
Cc: kuba@kernel.org, davem@davemloft.net, johannes@sipsolutions.net,
	ryazanov.s.a@gmail.com, loic.poulain@linaro.org,
	m.chetan.kumar@intel.com, chandrashekar.devegowda@intel.com,
	linuxwwan@intel.com, haijun.liu@mediatek.com,
	andriy.shevchenko@linux.intel.com, ilpo.jarvinen@linux.intel.com,
	ricardo.martinez@linux.intel.com, sreehari.kancharla@intel.com,
	dinesh.sharma@intel.com,
	Moises Veleta <moises.veleta@linux.intel.com>
Subject: [PATCH net-next 1/1] net: wwan: t7xx: Add port for modem logging
Date: Thu, 19 May 2022 11:27:03 -0700	[thread overview]
Message-ID: <20220519182703.27056-1-moises.veleta@linux.intel.com> (raw)

The Modem Logging (MDL) port provides an interface to collect modem
logs for debugging purposes. MDL is supported by debugfs, the relay
interface, and the mtk_t7xx port infrastructure. MDL allows user-space
applications to control logging via debugfs and to collect logs via
the relay interface, while port infrastructure facilitates
communication between the driver and the modem.

Signed-off-by: Moises Veleta <moises.veleta@linux.intel.com>
Acked-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
---
 drivers/net/wwan/Kconfig                |   1 +
 drivers/net/wwan/t7xx/Makefile          |   3 +
 drivers/net/wwan/t7xx/t7xx_hif_cldma.c  |   2 +
 drivers/net/wwan/t7xx/t7xx_port.h       |   5 +
 drivers/net/wwan/t7xx/t7xx_port_proxy.c |  22 +++
 drivers/net/wwan/t7xx/t7xx_port_proxy.h |   4 +
 drivers/net/wwan/t7xx/t7xx_port_trace.c | 174 ++++++++++++++++++++++++
 7 files changed, 211 insertions(+)
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_trace.c

diff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig
index 3486ffe94ac4..32149029c891 100644
--- a/drivers/net/wwan/Kconfig
+++ b/drivers/net/wwan/Kconfig
@@ -108,6 +108,7 @@ config IOSM
 config MTK_T7XX
 	tristate "MediaTek PCIe 5G WWAN modem T7xx device"
 	depends on PCI
+	select RELAY if WWAN_DEBUGFS
 	help
 	  Enables MediaTek PCIe based 5G WWAN modem (T7xx series) device.
 	  Adapts WWAN framework and provides network interface like wwan0
diff --git a/drivers/net/wwan/t7xx/Makefile b/drivers/net/wwan/t7xx/Makefile
index dc6a7d682c15..268ff9e87e5b 100644
--- a/drivers/net/wwan/t7xx/Makefile
+++ b/drivers/net/wwan/t7xx/Makefile
@@ -18,3 +18,6 @@ mtk_t7xx-y:=	t7xx_pci.o \
 		t7xx_hif_dpmaif_rx.o  \
 		t7xx_dpmaif.o \
 		t7xx_netdev.o
+
+mtk_t7xx-$(CONFIG_WWAN_DEBUGFS) += \
+		t7xx_port_trace.o \
diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
index 0c52801ed0de..dcd480720edf 100644
--- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
+++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
@@ -1018,6 +1018,8 @@ static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl)
 			dev_err(md_ctrl->dev, "control TX ring init fail\n");
 			goto err_free_tx_ring;
 		}
+
+		md_ctrl->tx_ring[i].pkt_size = CLDMA_MTU;
 	}
 
 	for (j = 0; j < CLDMA_RXQ_NUM; j++) {
diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h
index dc4133eb433a..e35efb18ea09 100644
--- a/drivers/net/wwan/t7xx/t7xx_port.h
+++ b/drivers/net/wwan/t7xx/t7xx_port.h
@@ -122,10 +122,15 @@ struct t7xx_port {
 	int				rx_length_th;
 	bool				chan_enable;
 	struct task_struct		*thread;
+#ifdef CONFIG_WWAN_DEBUGFS
+	struct t7xx_trace		*trace;
+	struct dentry			*debugfs_dir;
+#endif
 };
 
 struct sk_buff *t7xx_port_alloc_skb(int payload);
 struct sk_buff *t7xx_ctrl_alloc_skb(int payload);
+int t7xx_port_mtu(struct t7xx_port *port);
 int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb);
 int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header,
 		       unsigned int ex_msg);
diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c
index 7d2c0e81e33d..fb9d057d6a84 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c
+++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c
@@ -70,6 +70,18 @@ static const struct t7xx_port_conf t7xx_md_port_conf[] = {
 		.name = "MBIM",
 		.port_type = WWAN_PORT_MBIM,
 	}, {
+#ifdef CONFIG_WWAN_DEBUGFS
+		.tx_ch = PORT_CH_MD_LOG_TX,
+		.rx_ch = PORT_CH_MD_LOG_RX,
+		.txq_index = 7,
+		.rxq_index = 7,
+		.txq_exp_index = 7,
+		.rxq_exp_index = 7,
+		.path_id = CLDMA_ID_MD,
+		.ops = &t7xx_trace_port_ops,
+		.name = "mdlog",
+	}, {
+#endif
 		.tx_ch = PORT_CH_CONTROL_TX,
 		.rx_ch = PORT_CH_CONTROL_RX,
 		.txq_index = Q_IDX_CTRL,
@@ -194,6 +206,16 @@ int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb)
 	return 0;
 }
 
+int t7xx_port_mtu(struct t7xx_port *port)
+{
+	enum cldma_id path_id = port->port_conf->path_id;
+	int tx_qno = t7xx_port_get_queue_no(port);
+	struct cldma_ctrl *md_ctrl;
+
+	md_ctrl = port->t7xx_dev->md->md_ctrl[path_id];
+	return md_ctrl->tx_ring[tx_qno].pkt_size;
+}
+
 static int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb)
 {
 	enum cldma_id path_id = port->port_conf->path_id;
diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.h b/drivers/net/wwan/t7xx/t7xx_port_proxy.h
index bc1ff5c6c700..81d059fbc0fb 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h
+++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h
@@ -87,6 +87,10 @@ struct ctrl_msg_header {
 extern struct port_ops wwan_sub_port_ops;
 extern struct port_ops ctl_port_ops;
 
+#ifdef CONFIG_WWAN_DEBUGFS
+extern struct port_ops t7xx_trace_port_ops;
+#endif
+
 void t7xx_port_proxy_reset(struct port_proxy *port_prox);
 void t7xx_port_proxy_uninit(struct port_proxy *port_prox);
 int t7xx_port_proxy_init(struct t7xx_modem *md);
diff --git a/drivers/net/wwan/t7xx/t7xx_port_trace.c b/drivers/net/wwan/t7xx/t7xx_port_trace.c
new file mode 100644
index 000000000000..87529316b183
--- /dev/null
+++ b/drivers/net/wwan/t7xx/t7xx_port_trace.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Intel Corporation.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/debugfs.h>
+#include <linux/relay.h>
+#include <linux/skbuff.h>
+#include <linux/wwan.h>
+
+#include "t7xx_port.h"
+#include "t7xx_port_proxy.h"
+#include "t7xx_state_monitor.h"
+
+#define T7XX_TRC_SUB_BUFF_SIZE		131072
+#define T7XX_TRC_N_SUB_BUFF		32
+#define T7XX_TRC_FILE_PERM		0600
+
+struct t7xx_trace {
+	struct rchan			*t7xx_rchan;
+	struct dentry			*ctrl_file;
+};
+
+static struct dentry *t7xx_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);
+}
+
+static int t7xx_trace_remove_buf_file_handler(struct dentry *dentry)
+{
+	debugfs_remove(dentry);
+	return 0;
+}
+
+static int t7xx_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;
+}
+
+static struct rchan_callbacks relay_callbacks = {
+	.subbuf_start = t7xx_trace_subbuf_start_handler,
+	.create_buf_file = t7xx_trace_create_buf_file_handler,
+	.remove_buf_file = t7xx_trace_remove_buf_file_handler,
+};
+
+static ssize_t t7xx_port_trace_write(struct file *file, const char __user *buf,
+				     size_t len, loff_t *ppos)
+{
+	struct t7xx_port *port = file->private_data;
+	size_t actual_len, alloc_size, txq_mtu;
+	const struct t7xx_port_conf *port_conf;
+	enum md_state md_state;
+	struct sk_buff *skb;
+	int ret;
+
+	port_conf = port->port_conf;
+	md_state = t7xx_fsm_get_md_state(port->t7xx_dev->md->fsm_ctl);
+	if (md_state == MD_STATE_WAITING_FOR_HS1 || md_state == MD_STATE_WAITING_FOR_HS2) {
+		dev_warn(port->dev, "port: %s ch: %d, write fail when md_state: %d\n",
+			 port_conf->name, port_conf->tx_ch, md_state);
+		return -ENODEV;
+	}
+
+	txq_mtu = t7xx_port_mtu(port);
+	alloc_size = min_t(size_t, txq_mtu, len + sizeof(struct ccci_header));
+	actual_len = alloc_size - sizeof(struct ccci_header);
+	skb = t7xx_port_alloc_skb(alloc_size);
+	if (!skb) {
+		ret = -ENOMEM;
+		goto err_out;
+	}
+
+	ret = copy_from_user(skb_put(skb, actual_len), buf, actual_len);
+	if (ret) {
+		ret = -EFAULT;
+		goto err_out;
+	}
+
+	ret = t7xx_port_send_skb(port, skb, 0, 0);
+	if (ret)
+		goto err_out;
+
+	return actual_len;
+
+err_out:
+	dev_err(port->dev, "write error done on %s, size: %zu, ret: %d\n",
+		port_conf->name, actual_len, ret);
+	dev_kfree_skb(skb);
+	return ret;
+}
+
+static const struct file_operations t7xx_trace_fops = {
+	.owner = THIS_MODULE,
+	.open = simple_open,
+	.write = t7xx_port_trace_write,
+};
+
+static int t7xx_trace_port_init(struct t7xx_port *port)
+{
+	struct dentry *debugfs_pdev = wwan_get_debugfs_dir(port->dev);
+
+	if (IS_ERR(debugfs_pdev))
+		debugfs_pdev = NULL;
+
+	port->debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, debugfs_pdev);
+	if (IS_ERR_OR_NULL(port->debugfs_dir))
+		return -ENOMEM;
+
+	port->trace = devm_kzalloc(port->dev, sizeof(*port->trace), GFP_KERNEL);
+	if (!port->trace)
+		goto err_debugfs_dir;
+
+	port->trace->ctrl_file = debugfs_create_file("mdlog_ctrl",
+						     T7XX_TRC_FILE_PERM,
+						     port->debugfs_dir,
+						     port,
+						     &t7xx_trace_fops);
+	if (!port->trace->ctrl_file)
+		goto err_debugfs_dir;
+
+	port->trace->t7xx_rchan = relay_open("relay_ch",
+					     port->debugfs_dir,
+					     T7XX_TRC_SUB_BUFF_SIZE,
+					     T7XX_TRC_N_SUB_BUFF,
+					     &relay_callbacks, NULL);
+	if (!port->trace->t7xx_rchan)
+		goto err_debugfs_dir;
+
+	return 0;
+
+err_debugfs_dir:
+	debugfs_remove_recursive(port->debugfs_dir);
+	return -ENOMEM;
+}
+
+static void t7xx_trace_port_uninit(struct t7xx_port *port)
+{
+	struct t7xx_trace *trace = port->trace;
+
+	relay_close(trace->t7xx_rchan);
+	debugfs_remove_recursive(port->debugfs_dir);
+}
+
+static int t7xx_trace_port_recv_skb(struct t7xx_port *port, struct sk_buff *skb)
+{
+	struct t7xx_trace *t7xx_trace = port->trace;
+
+	if (!t7xx_trace->t7xx_rchan)
+		return -EINVAL;
+
+	relay_write(t7xx_trace->t7xx_rchan, skb->data, skb->len);
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+struct port_ops t7xx_trace_port_ops = {
+	.init =	t7xx_trace_port_init,
+	.recv_skb = t7xx_trace_port_recv_skb,
+	.uninit = t7xx_trace_port_uninit,
+};
-- 
2.17.1


             reply	other threads:[~2022-05-19 18:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-19 18:27 Moises Veleta [this message]
2022-05-20  8:33 ` [PATCH net-next 1/1] net: wwan: t7xx: Add port for modem logging Kumar, M Chetan
2022-05-20 20:37   ` moises.veleta
2022-05-20 17:37 ` Jakub Kicinski
2022-05-20 17:42   ` moises.veleta
2022-05-20 17:48     ` Jakub Kicinski
2022-05-20 18:01       ` moises.veleta
2022-05-20 18:15         ` Jakub Kicinski
     [not found]           ` <dc07d0a9-793b-5b76-cf10-d8fad77c04ea@linux.intel.com>
     [not found]             ` <20220520144630.56841d21@kernel.org>
2022-05-20 22:00               ` moises.veleta
2022-05-24  5:11                 ` moises.veleta
2022-05-24 18:04                   ` Jakub Kicinski

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=20220519182703.27056-1-moises.veleta@linux.intel.com \
    --to=moises.veleta@linux.intel.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=chandrashekar.devegowda@intel.com \
    --cc=davem@davemloft.net \
    --cc=dinesh.sharma@intel.com \
    --cc=haijun.liu@mediatek.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=johannes@sipsolutions.net \
    --cc=kuba@kernel.org \
    --cc=linuxwwan@intel.com \
    --cc=loic.poulain@linaro.org \
    --cc=m.chetan.kumar@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=ricardo.martinez@linux.intel.com \
    --cc=ryazanov.s.a@gmail.com \
    --cc=sreehari.kancharla@intel.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 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).