Commit 00ef3256 authored by M Chetan Kumar's avatar M Chetan Kumar Committed by David S. Miller
Browse files

net: wwan: iosm: device trace collection using relayfs



This patch brings in support for device trace collection.
It implements relayfs interface for pushing device trace
from kernel space to user space.

Driver gets the debugfs base directory associated to WWAN
Device and creates trace_control and trace debugfs for
device tracing. Both trace_control & trace debugfs are
created under /sys/kernel/debug/wwan/wwan0/.

In order to collect device trace on trace0 interface, user
need to write 1 to trace_ctl interface.

Signed-off-by: default avatarM Chetan Kumar <m.chetan.kumar@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c4804670
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ iosm-y = \
	iosm_ipc_mux_codec.o		\
	iosm_ipc_devlink.o		\
	iosm_ipc_flash.o		\
	iosm_ipc_coredump.o
	iosm_ipc_coredump.o		\
	iosm_ipc_trace.o

obj-$(CONFIG_IOSM) := iosm.o
+13 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include "iosm_ipc_flash.h"
#include "iosm_ipc_imem.h"
#include "iosm_ipc_port.h"
#include "iosm_ipc_trace.h"

/* Check the wwan ips if it is valid with Channel as input. */
static int ipc_imem_check_wwan_ips(struct ipc_mem_channel *chnl)
@@ -265,9 +266,14 @@ static void ipc_imem_dl_skb_process(struct iosm_imem *ipc_imem,
	switch (pipe->channel->ctype) {
	case IPC_CTYPE_CTRL:
		port_id = pipe->channel->channel_id;
		ipc_pcie_addr_unmap(ipc_imem->pcie, IPC_CB(skb)->len,
				    IPC_CB(skb)->mapping,
				    IPC_CB(skb)->direction);
		if (port_id == IPC_MEM_CTRL_CHL_ID_7)
			ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink,
						       skb);
		else if (port_id == ipc_imem->trace->chl_id)
			ipc_trace_port_rx(ipc_imem->trace, skb);
		else
			wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port,
				     skb);
@@ -548,6 +554,12 @@ static void ipc_imem_run_state_worker(struct work_struct *instance)
		ctrl_chl_idx++;
	}

	ipc_imem->trace = ipc_imem_trace_channel_init(ipc_imem);
	if (!ipc_imem->trace) {
		dev_err(ipc_imem->dev, "trace channel init failed");
		return;
	}

	ipc_task_queue_send_task(ipc_imem, ipc_imem_send_mdm_rdy_cb, 0, NULL, 0,
				 false);

@@ -1163,6 +1175,7 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem)

	if (test_and_clear_bit(FULLY_FUNCTIONAL, &ipc_imem->flag)) {
		ipc_mux_deinit(ipc_imem->mux);
		ipc_trace_deinit(ipc_imem->trace);
		ipc_wwan_deinit(ipc_imem->wwan);
		ipc_port_deinit(ipc_imem->ipc_port);
	}
+2 −0
Original line number Diff line number Diff line
@@ -304,6 +304,7 @@ enum ipc_phase {
 * @sio:			IPC SIO data structure pointer
 * @ipc_port:			IPC PORT data structure pointer
 * @pcie:			IPC PCIe
 * @trace:			IPC trace data structure pointer
 * @dev:			Pointer to device structure
 * @ipc_requested_state:	Expected IPC state on CP.
 * @channels:			Channel list with UL/DL pipe pairs.
@@ -349,6 +350,7 @@ struct iosm_imem {
	struct iosm_mux *mux;
	struct iosm_cdev *ipc_port[IPC_MEM_MAX_CHANNELS];
	struct iosm_pcie *pcie;
	struct iosm_trace *trace;
	struct device *dev;
	enum ipc_mem_device_ipc_state ipc_requested_state;
	struct ipc_mem_channel channels[IPC_MEM_MAX_CHANNELS];
+26 −5
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "iosm_ipc_imem_ops.h"
#include "iosm_ipc_port.h"
#include "iosm_ipc_task_queue.h"
#include "iosm_ipc_trace.h"

/* Open a packet data online channel between the network layer and CP. */
int ipc_imem_sys_wwan_open(struct iosm_imem *ipc_imem, int if_id)
@@ -107,6 +108,23 @@ void ipc_imem_wwan_channel_init(struct iosm_imem *ipc_imem,
			"failed to register the ipc_wwan interfaces");
}

/**
 * ipc_imem_trace_channel_init - Initializes trace channel.
 * @ipc_imem:          Pointer to iosm_imem struct.
 *
 * Returns: Pointer to trace instance on success else NULL
 */
struct iosm_trace *ipc_imem_trace_channel_init(struct iosm_imem *ipc_imem)
{
	struct ipc_chnl_cfg chnl_cfg = { 0 };

	ipc_chnl_cfg_get(&chnl_cfg, IPC_MEM_CTRL_CHL_ID_3);
	ipc_imem_channel_init(ipc_imem, IPC_CTYPE_CTRL, chnl_cfg,
			      IRQ_MOD_OFF);

	return ipc_trace_init(ipc_imem);
}

/* Map SKB to DMA for transfer */
static int ipc_imem_map_skb_to_dma(struct iosm_imem *ipc_imem,
				   struct sk_buff *skb)
@@ -182,11 +200,14 @@ static bool ipc_imem_is_channel_active(struct iosm_imem *ipc_imem,
	return false;
}

/* Release a sio link to CP. */
void ipc_imem_sys_cdev_close(struct iosm_cdev *ipc_cdev)
/**
 * ipc_imem_sys_port_close - Release a sio link to CP.
 * @ipc_imem:          Imem instance.
 * @channel:           Channel instance.
 */
void ipc_imem_sys_port_close(struct iosm_imem *ipc_imem,
			     struct ipc_mem_channel *channel)
{
	struct iosm_imem *ipc_imem = ipc_cdev->ipc_imem;
	struct ipc_mem_channel *channel = ipc_cdev->channel;
	enum ipc_phase curr_phase;
	int status = 0;
	u32 tail = 0;
@@ -643,6 +664,6 @@ int ipc_imem_sys_devlink_read(struct iosm_devlink *devlink, u8 *data,
	memcpy(data, skb->data, skb->len);

devlink_read_fail:
	ipc_pcie_kfree_skb(devlink->pcie, skb);
	dev_kfree_skb(skb);
	return rc;
}
+3 −6
Original line number Diff line number Diff line
@@ -43,12 +43,8 @@
 */
struct ipc_mem_channel *ipc_imem_sys_port_open(struct iosm_imem *ipc_imem,
					       int chl_id, int hp_id);

/**
 * ipc_imem_sys_cdev_close - Release a sio link to CP.
 * @ipc_cdev:		iosm sio instance.
 */
void ipc_imem_sys_cdev_close(struct iosm_cdev *ipc_cdev);
void ipc_imem_sys_port_close(struct iosm_imem *ipc_imem,
			     struct ipc_mem_channel *channel);

/**
 * ipc_imem_sys_cdev_write - Route the uplink buffer to CP.
@@ -145,4 +141,5 @@ int ipc_imem_sys_devlink_read(struct iosm_devlink *ipc_devlink, u8 *data,
 */
int ipc_imem_sys_devlink_write(struct iosm_devlink *ipc_devlink,
			       unsigned char *buf, int count);
struct iosm_trace *ipc_imem_trace_channel_init(struct iosm_imem *ipc_imem);
#endif
Loading