xref: /linux/drivers/thunderbolt/trace.h (revision 36ec807b627b4c0a0a382f0ae48eac7187d14b2b)
1a0c45b0bSGil Fine /* SPDX-License-Identifier: GPL-2.0 */
2a0c45b0bSGil Fine /*
3a0c45b0bSGil Fine  * Thunderbolt tracing support
4a0c45b0bSGil Fine  *
5a0c45b0bSGil Fine  * Copyright (C) 2024, Intel Corporation
6a0c45b0bSGil Fine  * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
7a0c45b0bSGil Fine  *	   Gil Fine <gil.fine@intel.com>
8a0c45b0bSGil Fine  */
9a0c45b0bSGil Fine 
10a0c45b0bSGil Fine #undef TRACE_SYSTEM
11a0c45b0bSGil Fine #define TRACE_SYSTEM thunderbolt
12a0c45b0bSGil Fine 
13a0c45b0bSGil Fine #if !defined(TB_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
14a0c45b0bSGil Fine #define TB_TRACE_H_
15a0c45b0bSGil Fine 
16a0c45b0bSGil Fine #include <linux/trace_seq.h>
17a0c45b0bSGil Fine #include <linux/tracepoint.h>
18a0c45b0bSGil Fine 
19a0c45b0bSGil Fine #include "tb_msgs.h"
20a0c45b0bSGil Fine 
21a0c45b0bSGil Fine #define tb_cfg_type_name(type)		{ type, #type }
22a0c45b0bSGil Fine #define show_type_name(val)					\
23a0c45b0bSGil Fine 	__print_symbolic(val,					\
24a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_READ),		\
25a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_WRITE),		\
26a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_ERROR),		\
27a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_NOTIFY_ACK),	\
28a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_EVENT),		\
29a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_XDOMAIN_REQ),	\
30a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_XDOMAIN_RESP),	\
31a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_OVERRIDE),		\
32a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_RESET),		\
33a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_ICM_EVENT),		\
34a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_ICM_CMD),		\
35a0c45b0bSGil Fine 		tb_cfg_type_name(TB_CFG_PKG_ICM_RESP))
36a0c45b0bSGil Fine 
37a0c45b0bSGil Fine #ifndef TB_TRACE_HELPERS
38a0c45b0bSGil Fine #define TB_TRACE_HELPERS
39a0c45b0bSGil Fine static inline const char *show_data_read_write(struct trace_seq *p,
40a0c45b0bSGil Fine 					       const u32 *data)
41a0c45b0bSGil Fine {
42a0c45b0bSGil Fine 	const struct cfg_read_pkg *msg = (const struct cfg_read_pkg *)data;
43a0c45b0bSGil Fine 	const char *ret = trace_seq_buffer_ptr(p);
44a0c45b0bSGil Fine 
45a0c45b0bSGil Fine 	trace_seq_printf(p, "offset=%#x, len=%u, port=%d, config=%#x, seq=%d, ",
46a0c45b0bSGil Fine 			 msg->addr.offset, msg->addr.length, msg->addr.port,
47a0c45b0bSGil Fine 			 msg->addr.space, msg->addr.seq);
48a0c45b0bSGil Fine 
49a0c45b0bSGil Fine 	return ret;
50a0c45b0bSGil Fine }
51a0c45b0bSGil Fine 
52a0c45b0bSGil Fine static inline const char *show_data_error(struct trace_seq *p, const u32 *data)
53a0c45b0bSGil Fine {
54a0c45b0bSGil Fine 	const struct cfg_error_pkg *msg = (const struct cfg_error_pkg *)data;
55a0c45b0bSGil Fine 	const char *ret = trace_seq_buffer_ptr(p);
56a0c45b0bSGil Fine 
57a0c45b0bSGil Fine 	trace_seq_printf(p, "error=%#x, port=%d, plug=%#x, ", msg->error,
58a0c45b0bSGil Fine 			 msg->port, msg->pg);
59a0c45b0bSGil Fine 
60a0c45b0bSGil Fine 	return ret;
61a0c45b0bSGil Fine }
62a0c45b0bSGil Fine 
63a0c45b0bSGil Fine static inline const char *show_data_event(struct trace_seq *p, const u32 *data)
64a0c45b0bSGil Fine {
65a0c45b0bSGil Fine 	const struct cfg_event_pkg *msg = (const struct cfg_event_pkg *)data;
66a0c45b0bSGil Fine 	const char *ret = trace_seq_buffer_ptr(p);
67a0c45b0bSGil Fine 
68a0c45b0bSGil Fine 	trace_seq_printf(p, "port=%d, unplug=%#x, ", msg->port, msg->unplug);
69a0c45b0bSGil Fine 
70a0c45b0bSGil Fine 	return ret;
71a0c45b0bSGil Fine }
72a0c45b0bSGil Fine 
73a0c45b0bSGil Fine static inline const char *show_route(struct trace_seq *p, const u32 *data)
74a0c45b0bSGil Fine {
75a0c45b0bSGil Fine 	const struct tb_cfg_header *header = (const struct tb_cfg_header *)data;
76a0c45b0bSGil Fine 	const char *ret = trace_seq_buffer_ptr(p);
77a0c45b0bSGil Fine 
78a0c45b0bSGil Fine 	trace_seq_printf(p, "route=%llx, ", tb_cfg_get_route(header));
79a0c45b0bSGil Fine 
80a0c45b0bSGil Fine 	return ret;
81a0c45b0bSGil Fine }
82a0c45b0bSGil Fine 
83a0c45b0bSGil Fine static inline const char *show_data(struct trace_seq *p, u8 type,
84a0c45b0bSGil Fine 				    const u32 *data, u32 length)
85a0c45b0bSGil Fine {
86a0c45b0bSGil Fine 	const char *ret = trace_seq_buffer_ptr(p);
87a0c45b0bSGil Fine 	const char *prefix = "";
88a0c45b0bSGil Fine 	int i;
89a0c45b0bSGil Fine 
90a0c45b0bSGil Fine 	switch (type) {
91a0c45b0bSGil Fine 	case TB_CFG_PKG_READ:
92a0c45b0bSGil Fine 	case TB_CFG_PKG_WRITE:
93*a3dc6d82SMika Westerberg 		show_route(p, data);
94a0c45b0bSGil Fine 		show_data_read_write(p, data);
95a0c45b0bSGil Fine 		break;
96a0c45b0bSGil Fine 
97a0c45b0bSGil Fine 	case TB_CFG_PKG_ERROR:
98*a3dc6d82SMika Westerberg 		show_route(p, data);
99a0c45b0bSGil Fine 		show_data_error(p, data);
100a0c45b0bSGil Fine 		break;
101a0c45b0bSGil Fine 
102a0c45b0bSGil Fine 	case TB_CFG_PKG_EVENT:
103*a3dc6d82SMika Westerberg 		show_route(p, data);
104a0c45b0bSGil Fine 		show_data_event(p, data);
105a0c45b0bSGil Fine 		break;
106a0c45b0bSGil Fine 
107*a3dc6d82SMika Westerberg 	case TB_CFG_PKG_ICM_EVENT:
108*a3dc6d82SMika Westerberg 	case TB_CFG_PKG_ICM_CMD:
109*a3dc6d82SMika Westerberg 	case TB_CFG_PKG_ICM_RESP:
110*a3dc6d82SMika Westerberg 		/* ICM messages always target the host router */
111*a3dc6d82SMika Westerberg 		trace_seq_puts(p, "route=0, ");
112*a3dc6d82SMika Westerberg 		break;
113*a3dc6d82SMika Westerberg 
114a0c45b0bSGil Fine 	default:
115*a3dc6d82SMika Westerberg 		show_route(p, data);
116a0c45b0bSGil Fine 		break;
117a0c45b0bSGil Fine 	}
118a0c45b0bSGil Fine 
119a0c45b0bSGil Fine 	trace_seq_printf(p, "data=[");
120a0c45b0bSGil Fine 	for (i = 0; i < length; i++) {
121a0c45b0bSGil Fine 		trace_seq_printf(p, "%s0x%08x", prefix, data[i]);
122a0c45b0bSGil Fine 		prefix = ", ";
123a0c45b0bSGil Fine 	}
124a0c45b0bSGil Fine 	trace_seq_printf(p, "]");
125a0c45b0bSGil Fine 	trace_seq_putc(p, 0);
126a0c45b0bSGil Fine 
127a0c45b0bSGil Fine 	return ret;
128a0c45b0bSGil Fine }
129a0c45b0bSGil Fine #endif
130a0c45b0bSGil Fine 
131a0c45b0bSGil Fine DECLARE_EVENT_CLASS(tb_raw,
132a0c45b0bSGil Fine 	TP_PROTO(int index, u8 type, const void *data, size_t size),
133a0c45b0bSGil Fine 	TP_ARGS(index, type, data, size),
134a0c45b0bSGil Fine 	TP_STRUCT__entry(
135a0c45b0bSGil Fine 		__field(int, index)
136a0c45b0bSGil Fine 		__field(u8, type)
137a0c45b0bSGil Fine 		__field(size_t, size)
138a0c45b0bSGil Fine 		__dynamic_array(u32, data, size / 4)
139a0c45b0bSGil Fine 	),
140a0c45b0bSGil Fine 	TP_fast_assign(
141a0c45b0bSGil Fine 		__entry->index = index;
142a0c45b0bSGil Fine 		__entry->type = type;
143a0c45b0bSGil Fine 		__entry->size = size / 4;
144a0c45b0bSGil Fine 		memcpy(__get_dynamic_array(data), data, size);
145a0c45b0bSGil Fine 	),
146a0c45b0bSGil Fine 	TP_printk("type=%s, size=%zd, domain=%d, %s",
147a0c45b0bSGil Fine 		  show_type_name(__entry->type), __entry->size, __entry->index,
148a0c45b0bSGil Fine 		  show_data(p, __entry->type, __get_dynamic_array(data),
149a0c45b0bSGil Fine 			    __entry->size)
150a0c45b0bSGil Fine 	)
151a0c45b0bSGil Fine );
152a0c45b0bSGil Fine 
153a0c45b0bSGil Fine DEFINE_EVENT(tb_raw, tb_tx,
154a0c45b0bSGil Fine 	TP_PROTO(int index, u8 type, const void *data, size_t size),
155a0c45b0bSGil Fine 	TP_ARGS(index, type, data, size)
156a0c45b0bSGil Fine );
157a0c45b0bSGil Fine 
158a0c45b0bSGil Fine DEFINE_EVENT(tb_raw, tb_event,
159a0c45b0bSGil Fine 	TP_PROTO(int index, u8 type, const void *data, size_t size),
160a0c45b0bSGil Fine 	TP_ARGS(index, type, data, size)
161a0c45b0bSGil Fine );
162a0c45b0bSGil Fine 
163a0c45b0bSGil Fine TRACE_EVENT(tb_rx,
164a0c45b0bSGil Fine 	TP_PROTO(int index, u8 type, const void *data, size_t size, bool dropped),
165a0c45b0bSGil Fine 	TP_ARGS(index, type, data, size, dropped),
166a0c45b0bSGil Fine 	TP_STRUCT__entry(
167a0c45b0bSGil Fine 		__field(int, index)
168a0c45b0bSGil Fine 		__field(u8, type)
169a0c45b0bSGil Fine 		__field(size_t, size)
170a0c45b0bSGil Fine 		__dynamic_array(u32, data, size / 4)
171a0c45b0bSGil Fine 		__field(bool, dropped)
172a0c45b0bSGil Fine 	),
173a0c45b0bSGil Fine 	TP_fast_assign(
174a0c45b0bSGil Fine 		__entry->index = index;
175a0c45b0bSGil Fine 		__entry->type = type;
176a0c45b0bSGil Fine 		__entry->size = size / 4;
177a0c45b0bSGil Fine 		memcpy(__get_dynamic_array(data), data, size);
178a0c45b0bSGil Fine 		__entry->dropped = dropped;
179a0c45b0bSGil Fine 	),
180a0c45b0bSGil Fine 	TP_printk("type=%s, dropped=%u, size=%zd, domain=%d, %s",
181a0c45b0bSGil Fine 		  show_type_name(__entry->type), __entry->dropped,
182a0c45b0bSGil Fine 		  __entry->size, __entry->index,
183a0c45b0bSGil Fine 		  show_data(p, __entry->type, __get_dynamic_array(data),
184a0c45b0bSGil Fine 			    __entry->size)
185a0c45b0bSGil Fine 	)
186a0c45b0bSGil Fine );
187a0c45b0bSGil Fine 
188a0c45b0bSGil Fine #endif /* TB_TRACE_H_ */
189a0c45b0bSGil Fine 
190a0c45b0bSGil Fine #undef TRACE_INCLUDE_PATH
191a0c45b0bSGil Fine #define TRACE_INCLUDE_PATH .
192a0c45b0bSGil Fine 
193a0c45b0bSGil Fine #undef TRACE_INCLUDE_FILE
194a0c45b0bSGil Fine #define TRACE_INCLUDE_FILE trace
195a0c45b0bSGil Fine 
196a0c45b0bSGil Fine /* This part must be outside protection */
197a0c45b0bSGil Fine #include <trace/define_trace.h>
198