]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
net: wwan: t7xx: Add port for modem logging
authorM Chetan Kumar <m.chetan.kumar@linux.intel.com>
Fri, 28 Oct 2022 15:35:34 +0000 (21:05 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 Nov 2022 11:39:49 +0000 (11:39 +0000)
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
drivers/net/wwan/t7xx/Makefile
drivers/net/wwan/t7xx/t7xx_hif_cldma.c
drivers/net/wwan/t7xx/t7xx_pci.h
drivers/net/wwan/t7xx/t7xx_port.h
drivers/net/wwan/t7xx/t7xx_port_proxy.c
drivers/net/wwan/t7xx/t7xx_port_proxy.h
drivers/net/wwan/t7xx/t7xx_port_trace.c [new file with mode: 0644]

index 3486ffe94ac4604608a3dd6ccaf55c441ba04580..32149029c891e11a5d33d6088c75d6be89e5d3f9 100644 (file)
@@ -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
index dc6a7d682c159ec4b3899ab9f0efcce2c808f570..268ff9e87e5b3069af67858dd762283d1199c8a1 100644 (file)
@@ -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 \
index 6ff30cb8eb16ff269135dddf1eb95d9db6c219d3..aec3a18d44bde61c6343d0ed16697a96c2465011 100644 (file)
@@ -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++) {
index 50b37056ce5a40b075e1403fca5946d37ba84198..112efa534eaceffb47a8b049d5126eae79c971e3 100644 (file)
@@ -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 {
index fbc6d724b7c286b6ce260f3ae0df46f295225c1f..8ea9079af997b0f1262fc087bdadd9bbc08570fc 100644 (file)
@@ -125,6 +125,9 @@ struct t7xx_port {
                struct {
                        struct wwan_port                *wwan_port;
                } wwan;
+               struct {
+                       struct rchan                    *relaych;
+               } log;
        };
 };
 
index d4de047ff0d49d782b3d5d74274d017fc478f531..894b1d11b2c9c1d80d012eaba6716549becc50b8 100644 (file)
@@ -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,
index bc1ff5c6c7005be5d99e2b3af36e967b12ff020f..81d059fbc0fb4667bf0a5ec1f5f807c8a76a3e2e 100644 (file)
@@ -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 (file)
index 0000000..6a3f363
--- /dev/null
@@ -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,
+};