Skip to content

Commit

Permalink
net: wwan: t7xx: Add port for modem logging
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
M Chetan Kumar authored and David S. Miller committed Nov 2, 2022
1 parent fece7a8 commit 3349e4a
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/net/wwan/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wwan/t7xx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
2 changes: 2 additions & 0 deletions drivers/net/wwan/t7xx/t7xx_hif_cldma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wwan/t7xx/t7xx_pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wwan/t7xx/t7xx_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ struct t7xx_port {
struct {
struct wwan_port *wwan_port;
} wwan;
struct {
struct rchan *relaych;
} log;
};
};

Expand Down
12 changes: 12 additions & 0 deletions drivers/net/wwan/t7xx/t7xx_port_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/wwan/t7xx/t7xx_port_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
116 changes: 116 additions & 0 deletions drivers/net/wwan/t7xx/t7xx_port_trace.c
Original file line number Diff line number Diff line change
@@ -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,
};

0 comments on commit 3349e4a

Please sign in to comment.