238 lines
7.0 KiB
Diff
238 lines
7.0 KiB
Diff
From 3349e4a48acb0923fa98d2beac82a833a76116cb Mon Sep 17 00:00:00 2001
|
|
From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
|
|
Date: Fri, 28 Oct 2022 21:05:34 +0530
|
|
Subject: [PATCH] net: wwan: t7xx: Add port for modem logging
|
|
|
|
The Modem Logging (MDL) port provides an interface to collect modem
|
|
logs for debugging purposes. MDL is supported by the relay interface,
|
|
and the mtk_t7xx port infrastructure. MDL allows user-space apps to
|
|
control logging via mbim command 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>
|
|
Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
|
|
Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
|
|
Acked-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
|
|
Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
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_pci.h | 3 +
|
|
drivers/net/wwan/t7xx/t7xx_port.h | 3 +
|
|
drivers/net/wwan/t7xx/t7xx_port_proxy.c | 12 +++
|
|
drivers/net/wwan/t7xx/t7xx_port_proxy.h | 4 +
|
|
drivers/net/wwan/t7xx/t7xx_port_trace.c | 116 ++++++++++++++++++++++++
|
|
8 files changed, 144 insertions(+)
|
|
create mode 100644 drivers/net/wwan/t7xx/t7xx_port_trace.c
|
|
|
|
--- a/drivers/net/wwan/Kconfig
|
|
+++ b/drivers/net/wwan/Kconfig
|
|
@@ -82,6 +82,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
|
|
--- 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 \
|
|
--- 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 c
|
|
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++) {
|
|
--- a/drivers/net/wwan/t7xx/t7xx_pci.h
|
|
+++ b/drivers/net/wwan/t7xx/t7xx_pci.h
|
|
@@ -78,6 +78,9 @@ struct t7xx_pci_dev {
|
|
spinlock_t md_pm_lock; /* Protects PCI resource lock */
|
|
unsigned int sleep_disable_count;
|
|
struct completion sleep_lock_acquire;
|
|
+#ifdef CONFIG_WWAN_DEBUGFS
|
|
+ struct dentry *debugfs_dir;
|
|
+#endif
|
|
};
|
|
|
|
enum t7xx_pm_id {
|
|
--- a/drivers/net/wwan/t7xx/t7xx_port.h
|
|
+++ b/drivers/net/wwan/t7xx/t7xx_port.h
|
|
@@ -125,6 +125,9 @@ struct t7xx_port {
|
|
struct {
|
|
struct wwan_port *wwan_port;
|
|
} wwan;
|
|
+ struct {
|
|
+ struct rchan *relaych;
|
|
+ } log;
|
|
};
|
|
};
|
|
|
|
--- 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_
|
|
.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,
|
|
--- 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);
|
|
--- /dev/null
|
|
+++ b/drivers/net/wwan/t7xx/t7xx_port_trace.c
|
|
@@ -0,0 +1,116 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-only
|
|
+/*
|
|
+ * Copyright (C) 2022 Intel Corporation.
|
|
+ */
|
|
+
|
|
+#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
|
|
+
|
|
+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 void t7xx_trace_port_uninit(struct t7xx_port *port)
|
|
+{
|
|
+ struct dentry *debugfs_dir = port->t7xx_dev->debugfs_dir;
|
|
+ struct rchan *relaych = port->log.relaych;
|
|
+
|
|
+ if (!relaych)
|
|
+ return;
|
|
+
|
|
+ relay_close(relaych);
|
|
+ debugfs_remove_recursive(debugfs_dir);
|
|
+}
|
|
+
|
|
+static int t7xx_trace_port_recv_skb(struct t7xx_port *port, struct sk_buff *skb)
|
|
+{
|
|
+ struct rchan *relaych = port->log.relaych;
|
|
+
|
|
+ if (!relaych)
|
|
+ return -EINVAL;
|
|
+
|
|
+ relay_write(relaych, skb->data, skb->len);
|
|
+ dev_kfree_skb(skb);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void t7xx_port_trace_md_state_notify(struct t7xx_port *port, unsigned int state)
|
|
+{
|
|
+ struct rchan *relaych = port->log.relaych;
|
|
+ struct dentry *debugfs_wwan_dir;
|
|
+ struct dentry *debugfs_dir;
|
|
+
|
|
+ if (state != MD_STATE_READY || relaych)
|
|
+ return;
|
|
+
|
|
+ debugfs_wwan_dir = wwan_get_debugfs_dir(port->dev);
|
|
+ if (IS_ERR(debugfs_wwan_dir))
|
|
+ return;
|
|
+
|
|
+ debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, debugfs_wwan_dir);
|
|
+ if (IS_ERR_OR_NULL(debugfs_dir)) {
|
|
+ wwan_put_debugfs_dir(debugfs_wwan_dir);
|
|
+ dev_err(port->dev, "Unable to create debugfs for trace");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ relaych = relay_open("relay_ch", debugfs_dir, T7XX_TRC_SUB_BUFF_SIZE,
|
|
+ T7XX_TRC_N_SUB_BUFF, &relay_callbacks, NULL);
|
|
+ if (!relaych)
|
|
+ goto err_rm_debugfs_dir;
|
|
+
|
|
+ wwan_put_debugfs_dir(debugfs_wwan_dir);
|
|
+ port->log.relaych = relaych;
|
|
+ port->t7xx_dev->debugfs_dir = debugfs_dir;
|
|
+ return;
|
|
+
|
|
+err_rm_debugfs_dir:
|
|
+ debugfs_remove_recursive(debugfs_dir);
|
|
+ wwan_put_debugfs_dir(debugfs_wwan_dir);
|
|
+ dev_err(port->dev, "Unable to create trace port %s", port->port_conf->name);
|
|
+}
|
|
+
|
|
+struct port_ops t7xx_trace_port_ops = {
|
|
+ .recv_skb = t7xx_trace_port_recv_skb,
|
|
+ .uninit = t7xx_trace_port_uninit,
|
|
+ .md_state_notify = t7xx_port_trace_md_state_notify,
|
|
+};
|