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