diff options
author | M Chetan Kumar <m.chetan.kumar@linux.intel.com> | 2022-10-28 18:35:34 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-11-02 14:39:49 +0300 |
commit | 3349e4a48acb0923fa98d2beac82a833a76116cb (patch) | |
tree | f0c3b962cbbe2bc31f8797b5055160f13607d422 /drivers | |
parent | fece7a8c65d1476b901b969a07b2979e1b459e66 (diff) | |
download | linux-3349e4a48acb0923fa98d2beac82a833a76116cb.tar.xz |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wwan/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_hif_cldma.c | 2 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_pci.h | 3 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_port.h | 3 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_port_proxy.c | 12 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_port_proxy.h | 4 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_port_trace.c | 116 |
8 files changed, 144 insertions, 0 deletions
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 6ff30cb8eb16..aec3a18d44bd 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_pci.h b/drivers/net/wwan/t7xx/t7xx_pci.h index 50b37056ce5a..112efa534eac 100644 --- 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 { diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h index fbc6d724b7c2..8ea9079af997 100644 --- 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; }; }; diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index d4de047ff0d4..894b1d11b2c9 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, 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..6a3f36385865 --- /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, +}; |