198 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Thunderbolt tracing support4 *5 * Copyright (C) 2024, Intel Corporation6 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>7 * Gil Fine <gil.fine@intel.com>8 */9 10#undef TRACE_SYSTEM11#define TRACE_SYSTEM thunderbolt12 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_HELPERS38#define TB_TRACE_HELPERS39static 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 52static 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 63static 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 73static 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 83static 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#endif130 131DECLARE_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 153DEFINE_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 158DEFINE_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 163TRACE_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_PATH191#define TRACE_INCLUDE_PATH .192 193#undef TRACE_INCLUDE_FILE194#define TRACE_INCLUDE_FILE trace195 196/* This part must be outside protection */197#include <trace/define_trace.h>198