/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Thunderbolt tracing support
 *
 * Copyright (C) 2024, Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 *	   Gil Fine <gil.fine@intel.com>
 */

#undef TRACE_SYSTEM
#define TRACE_SYSTEM thunderbolt

#if !defined(TB_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
#define TB_TRACE_H_

#include <linux/trace_seq.h>
#include <linux/tracepoint.h>

#include "tb_msgs.h"

#define tb_cfg_type_name(type)		{ type, #type }
#define show_type_name(val)					\
	__print_symbolic(val,					\
		tb_cfg_type_name(TB_CFG_PKG_READ),		\
		tb_cfg_type_name(TB_CFG_PKG_WRITE),		\
		tb_cfg_type_name(TB_CFG_PKG_ERROR),		\
		tb_cfg_type_name(TB_CFG_PKG_NOTIFY_ACK),	\
		tb_cfg_type_name(TB_CFG_PKG_EVENT),		\
		tb_cfg_type_name(TB_CFG_PKG_XDOMAIN_REQ),	\
		tb_cfg_type_name(TB_CFG_PKG_XDOMAIN_RESP),	\
		tb_cfg_type_name(TB_CFG_PKG_OVERRIDE),		\
		tb_cfg_type_name(TB_CFG_PKG_RESET),		\
		tb_cfg_type_name(TB_CFG_PKG_ICM_EVENT),		\
		tb_cfg_type_name(TB_CFG_PKG_ICM_CMD),		\
		tb_cfg_type_name(TB_CFG_PKG_ICM_RESP))

#ifndef TB_TRACE_HELPERS
#define TB_TRACE_HELPERS
static inline const char *show_data_read_write(struct trace_seq *p,
					       const u32 *data)
{
	const struct cfg_read_pkg *msg = (const struct cfg_read_pkg *)data;
	const char *ret = trace_seq_buffer_ptr(p);

	trace_seq_printf(p, "offset=%#x, len=%u, port=%d, config=%#x, seq=%d, ",
			 msg->addr.offset, msg->addr.length, msg->addr.port,
			 msg->addr.space, msg->addr.seq);

	return ret;
}

static inline const char *show_data_error(struct trace_seq *p, const u32 *data)
{
	const struct cfg_error_pkg *msg = (const struct cfg_error_pkg *)data;
	const char *ret = trace_seq_buffer_ptr(p);

	trace_seq_printf(p, "error=%#x, port=%d, plug=%#x, ", msg->error,
			 msg->port, msg->pg);

	return ret;
}

static inline const char *show_data_event(struct trace_seq *p, const u32 *data)
{
	const struct cfg_event_pkg *msg = (const struct cfg_event_pkg *)data;
	const char *ret = trace_seq_buffer_ptr(p);

	trace_seq_printf(p, "port=%d, unplug=%#x, ", msg->port, msg->unplug);

	return ret;
}

static inline const char *show_route(struct trace_seq *p, const u32 *data)
{
	const struct tb_cfg_header *header = (const struct tb_cfg_header *)data;
	const char *ret = trace_seq_buffer_ptr(p);

	trace_seq_printf(p, "route=%llx, ", tb_cfg_get_route(header));

	return ret;
}

static inline const char *show_data(struct trace_seq *p, u8 type,
				    const u32 *data, u32 length)
{
	const char *ret = trace_seq_buffer_ptr(p);
	const char *prefix = "";
	int i;

	show_route(p, data);

	switch (type) {
	case TB_CFG_PKG_READ:
	case TB_CFG_PKG_WRITE:
		show_data_read_write(p, data);
		break;

	case TB_CFG_PKG_ERROR:
		show_data_error(p, data);
		break;

	case TB_CFG_PKG_EVENT:
		show_data_event(p, data);
		break;

	default:
		break;
	}

	trace_seq_printf(p, "data=[");
	for (i = 0; i < length; i++) {
		trace_seq_printf(p, "%s0x%08x", prefix, data[i]);
		prefix = ", ";
	}
	trace_seq_printf(p, "]");
	trace_seq_putc(p, 0);

	return ret;
}
#endif

DECLARE_EVENT_CLASS(tb_raw,
	TP_PROTO(int index, u8 type, const void *data, size_t size),
	TP_ARGS(index, type, data, size),
	TP_STRUCT__entry(
		__field(int, index)
		__field(u8, type)
		__field(size_t, size)
		__dynamic_array(u32, data, size / 4)
	),
	TP_fast_assign(
		__entry->index = index;
		__entry->type = type;
		__entry->size = size / 4;
		memcpy(__get_dynamic_array(data), data, size);
	),
	TP_printk("type=%s, size=%zd, domain=%d, %s",
		  show_type_name(__entry->type), __entry->size, __entry->index,
		  show_data(p, __entry->type, __get_dynamic_array(data),
			    __entry->size)
	)
);

DEFINE_EVENT(tb_raw, tb_tx,
	TP_PROTO(int index, u8 type, const void *data, size_t size),
	TP_ARGS(index, type, data, size)
);

DEFINE_EVENT(tb_raw, tb_event,
	TP_PROTO(int index, u8 type, const void *data, size_t size),
	TP_ARGS(index, type, data, size)
);

TRACE_EVENT(tb_rx,
	TP_PROTO(int index, u8 type, const void *data, size_t size, bool dropped),
	TP_ARGS(index, type, data, size, dropped),
	TP_STRUCT__entry(
		__field(int, index)
		__field(u8, type)
		__field(size_t, size)
		__dynamic_array(u32, data, size / 4)
		__field(bool, dropped)
	),
	TP_fast_assign(
		__entry->index = index;
		__entry->type = type;
		__entry->size = size / 4;
		memcpy(__get_dynamic_array(data), data, size);
		__entry->dropped = dropped;
	),
	TP_printk("type=%s, dropped=%u, size=%zd, domain=%d, %s",
		  show_type_name(__entry->type), __entry->dropped,
		  __entry->size, __entry->index,
		  show_data(p, __entry->type, __get_dynamic_array(data),
			    __entry->size)
	)
);

#endif /* TB_TRACE_H_ */

#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .

#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE trace

/* This part must be outside protection */
#include <trace/define_trace.h>
