iwl-devtrace.h 12.4 KB
Newer Older
1 2
/******************************************************************************
 *
W
Wey-Yi Guy 已提交
3
 * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 *
 * The full GNU General Public License is included in this distribution in the
 * file called LICENSE.
 *
 * Contact Information:
 *  Intel Linux Wireless <ilw@linux.intel.com>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/

J
Johannes Berg 已提交
27
#if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ)
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#include <linux/skbuff.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include "iwl-trans.h"
#if !defined(__IWLWIFI_DEVICE_TRACE)
static inline bool iwl_trace_data(struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr = (void *)skb->data;

	if (ieee80211_is_data(hdr->frame_control))
		return skb->protocol != cpu_to_be16(ETH_P_PAE);
	return false;
}

static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
				      void *rxbuf, size_t len)
{
	struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32));
	struct ieee80211_hdr *hdr;

	if (cmd->cmd != trans->rx_mpdu_cmd)
		return len;

	hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) +
			trans->rx_mpdu_cmd_hdr_size);
	if (!ieee80211_is_data(hdr->frame_control))
		return len;
	/* maybe try to identify EAPOL frames? */
	return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size +
		ieee80211_hdrlen(hdr->frame_control);
}
#endif

J
Johannes Berg 已提交
61 62 63
#define __IWLWIFI_DEVICE_TRACE

#include <linux/tracepoint.h>
64
#include <linux/device.h>
65
#include "iwl-trans.h"
J
Johannes Berg 已提交
66

67

J
Johannes Berg 已提交
68 69 70 71
#if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
#undef TRACE_EVENT
#define TRACE_EVENT(name, proto, ...) \
static inline void trace_ ## name(proto) {}
J
Johannes Berg 已提交
72 73 74 75 76
#undef DECLARE_EVENT_CLASS
#define DECLARE_EVENT_CLASS(...)
#undef DEFINE_EVENT
#define DEFINE_EVENT(evt_class, name, proto, ...) \
static inline void trace_ ## name(proto) {}
J
Johannes Berg 已提交
77 78
#endif

79 80
#define DEV_ENTRY	__string(dev, dev_name(dev))
#define DEV_ASSIGN	__assign_str(dev, dev_name(dev))
J
Johannes Berg 已提交
81 82

#undef TRACE_SYSTEM
J
Johannes Berg 已提交
83
#define TRACE_SYSTEM iwlwifi_io
J
Johannes Berg 已提交
84 85

TRACE_EVENT(iwlwifi_dev_ioread32,
86 87
	TP_PROTO(const struct device *dev, u32 offs, u32 val),
	TP_ARGS(dev, offs, val),
J
Johannes Berg 已提交
88
	TP_STRUCT__entry(
89
		DEV_ENTRY
J
Johannes Berg 已提交
90 91 92 93
		__field(u32, offs)
		__field(u32, val)
	),
	TP_fast_assign(
94
		DEV_ASSIGN;
J
Johannes Berg 已提交
95 96 97
		__entry->offs = offs;
		__entry->val = val;
	),
98 99
	TP_printk("[%s] read io[%#x] = %#x",
		  __get_str(dev), __entry->offs, __entry->val)
J
Johannes Berg 已提交
100 101
);

B
Ben Cahill 已提交
102
TRACE_EVENT(iwlwifi_dev_iowrite8,
103 104
	TP_PROTO(const struct device *dev, u32 offs, u8 val),
	TP_ARGS(dev, offs, val),
B
Ben Cahill 已提交
105
	TP_STRUCT__entry(
106
		DEV_ENTRY
B
Ben Cahill 已提交
107 108 109 110
		__field(u32, offs)
		__field(u8, val)
	),
	TP_fast_assign(
111
		DEV_ASSIGN;
B
Ben Cahill 已提交
112 113 114
		__entry->offs = offs;
		__entry->val = val;
	),
115 116
	TP_printk("[%s] write io[%#x] = %#x)",
		  __get_str(dev), __entry->offs, __entry->val)
B
Ben Cahill 已提交
117 118
);

J
Johannes Berg 已提交
119
TRACE_EVENT(iwlwifi_dev_iowrite32,
120 121
	TP_PROTO(const struct device *dev, u32 offs, u32 val),
	TP_ARGS(dev, offs, val),
J
Johannes Berg 已提交
122
	TP_STRUCT__entry(
123
		DEV_ENTRY
J
Johannes Berg 已提交
124 125 126 127
		__field(u32, offs)
		__field(u32, val)
	),
	TP_fast_assign(
128
		DEV_ASSIGN;
J
Johannes Berg 已提交
129 130 131
		__entry->offs = offs;
		__entry->val = val;
	),
132 133
	TP_printk("[%s] write io[%#x] = %#x)",
		  __get_str(dev), __entry->offs, __entry->val)
J
Johannes Berg 已提交
134 135
);

J
Johannes Berg 已提交
136
TRACE_EVENT(iwlwifi_dev_irq,
137 138
	TP_PROTO(const struct device *dev),
	TP_ARGS(dev),
J
Johannes Berg 已提交
139
	TP_STRUCT__entry(
140
		DEV_ENTRY
J
Johannes Berg 已提交
141 142
	),
	TP_fast_assign(
143
		DEV_ASSIGN;
J
Johannes Berg 已提交
144 145 146 147 148 149
	),
	/* TP_printk("") doesn't compile */
	TP_printk("%d", 0)
);

TRACE_EVENT(iwlwifi_dev_ict_read,
150 151
	TP_PROTO(const struct device *dev, u32 index, u32 value),
	TP_ARGS(dev, index, value),
J
Johannes Berg 已提交
152
	TP_STRUCT__entry(
153
		DEV_ENTRY
J
Johannes Berg 已提交
154 155 156 157
		__field(u32, index)
		__field(u32, value)
	),
	TP_fast_assign(
158
		DEV_ASSIGN;
J
Johannes Berg 已提交
159 160 161
		__entry->index = index;
		__entry->value = value;
	),
162 163
	TP_printk("[%s] read ict[%d] = %#.8x",
		  __get_str(dev), __entry->index, __entry->value)
J
Johannes Berg 已提交
164 165
);

166 167 168 169
#undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi_ucode

TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
170 171
	TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
	TP_ARGS(dev, time, data, ev),
172
	TP_STRUCT__entry(
173
		DEV_ENTRY
174 175 176 177 178 179

		__field(u32, time)
		__field(u32, data)
		__field(u32, ev)
	),
	TP_fast_assign(
180
		DEV_ASSIGN;
181 182 183 184
		__entry->time = time;
		__entry->data = data;
		__entry->ev = ev;
	),
185 186
	TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
		  __get_str(dev), __entry->time, __entry->data, __entry->ev)
187 188 189
);

TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
190 191
	TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry),
	TP_ARGS(dev, wraps, n_entry, p_entry),
192
	TP_STRUCT__entry(
193
		DEV_ENTRY
194 195 196 197 198 199

		__field(u32, wraps)
		__field(u32, n_entry)
		__field(u32, p_entry)
	),
	TP_fast_assign(
200
		DEV_ASSIGN;
201 202 203 204
		__entry->wraps = wraps;
		__entry->n_entry = n_entry;
		__entry->p_entry = p_entry;
	),
205 206
	TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X",
		  __get_str(dev), __entry->wraps, __entry->n_entry,
207 208 209
		  __entry->p_entry)
);

J
Johannes Berg 已提交
210 211 212
#undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi_msg

213
#define MAX_MSG_LEN	110
J
Johannes Berg 已提交
214 215 216 217 218 219 220 221 222 223 224 225

DECLARE_EVENT_CLASS(iwlwifi_msg_event,
	TP_PROTO(struct va_format *vaf),
	TP_ARGS(vaf),
	TP_STRUCT__entry(
		__dynamic_array(char, msg, MAX_MSG_LEN)
	),
	TP_fast_assign(
		WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
				       MAX_MSG_LEN, vaf->fmt,
				       *vaf->va) >= MAX_MSG_LEN);
	),
226
	TP_printk("%s", __get_str(msg))
J
Johannes Berg 已提交
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
);

DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err,
	TP_PROTO(struct va_format *vaf),
	TP_ARGS(vaf)
);

DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn,
	TP_PROTO(struct va_format *vaf),
	TP_ARGS(vaf)
);

DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info,
	TP_PROTO(struct va_format *vaf),
	TP_ARGS(vaf)
);

DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit,
	TP_PROTO(struct va_format *vaf),
	TP_ARGS(vaf)
);

TRACE_EVENT(iwlwifi_dbg,
	TP_PROTO(u32 level, bool in_interrupt, const char *function,
		 struct va_format *vaf),
	TP_ARGS(level, in_interrupt, function, vaf),
	TP_STRUCT__entry(
		__field(u32, level)
		__field(u8, in_interrupt)
		__string(function, function)
		__dynamic_array(char, msg, MAX_MSG_LEN)
	),
	TP_fast_assign(
		__entry->level = level;
		__entry->in_interrupt = in_interrupt;
		__assign_str(function, function);
		WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
				       MAX_MSG_LEN, vaf->fmt,
				       *vaf->va) >= MAX_MSG_LEN);
	),
	TP_printk("%s", (char *)__get_dynamic_array(msg))
);

270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
#undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi_data

TRACE_EVENT(iwlwifi_dev_tx_data,
	TP_PROTO(const struct device *dev,
		 struct sk_buff *skb,
		 void *data, size_t data_len),
	TP_ARGS(dev, skb, data, data_len),
	TP_STRUCT__entry(
		DEV_ENTRY

		__dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0)
	),
	TP_fast_assign(
		DEV_ASSIGN;
		if (iwl_trace_data(skb))
			memcpy(__get_dynamic_array(data), data, data_len);
	),
	TP_printk("[%s] TX frame data", __get_str(dev))
);

TRACE_EVENT(iwlwifi_dev_rx_data,
	TP_PROTO(const struct device *dev,
		 const struct iwl_trans *trans,
		 void *rxbuf, size_t len),
	TP_ARGS(dev, trans, rxbuf, len),
	TP_STRUCT__entry(
		DEV_ENTRY

		__dynamic_array(u8, data,
				len - iwl_rx_trace_len(trans, rxbuf, len))
	),
	TP_fast_assign(
		size_t offs = iwl_rx_trace_len(trans, rxbuf, len);
		DEV_ASSIGN;
		if (offs < len)
			memcpy(__get_dynamic_array(data),
			       ((u8 *)rxbuf) + offs, len - offs);
	),
309
	TP_printk("[%s] RX frame data", __get_str(dev))
310 311
);

J
Johannes Berg 已提交
312 313 314
#undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi

J
Johannes Berg 已提交
315
TRACE_EVENT(iwlwifi_dev_hcmd,
316 317 318 319
	TP_PROTO(const struct device *dev,
		 struct iwl_host_cmd *cmd, u16 total_size,
		 const void *hdr, size_t hdr_len),
	TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
J
Johannes Berg 已提交
320
	TP_STRUCT__entry(
321
		DEV_ENTRY
322
		__dynamic_array(u8, hcmd, total_size)
J
Johannes Berg 已提交
323 324 325
		__field(u32, flags)
	),
	TP_fast_assign(
326 327
		int i, offset = hdr_len;

328
		DEV_ASSIGN;
329 330 331 332 333 334 335 336 337 338 339 340
		__entry->flags = cmd->flags;
		memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);

		for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
			if (!cmd->len[i])
				continue;
			if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
				continue;
			memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
			       cmd->data[i], cmd->len[i]);
			offset += cmd->len[i];
		}
J
Johannes Berg 已提交
341
	),
342
	TP_printk("[%s] hcmd %#.2x (%ssync)",
343
		  __get_str(dev), ((u8 *)__get_dynamic_array(hcmd))[0],
J
Johannes Berg 已提交
344 345 346 347
		  __entry->flags & CMD_ASYNC ? "a" : "")
);

TRACE_EVENT(iwlwifi_dev_rx,
348 349 350
	TP_PROTO(const struct device *dev, const struct iwl_trans *trans,
		 void *rxbuf, size_t len),
	TP_ARGS(dev, trans, rxbuf, len),
J
Johannes Berg 已提交
351
	TP_STRUCT__entry(
352
		DEV_ENTRY
353
		__dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len))
J
Johannes Berg 已提交
354 355
	),
	TP_fast_assign(
356
		DEV_ASSIGN;
357 358
		memcpy(__get_dynamic_array(rxbuf), rxbuf,
		       iwl_rx_trace_len(trans, rxbuf, len));
J
Johannes Berg 已提交
359
	),
360 361
	TP_printk("[%s] RX cmd %#.2x",
		  __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4])
J
Johannes Berg 已提交
362 363 364
);

TRACE_EVENT(iwlwifi_dev_tx,
365 366
	TP_PROTO(const struct device *dev, struct sk_buff *skb,
		 void *tfd, size_t tfdlen,
J
Johannes Berg 已提交
367 368
		 void *buf0, size_t buf0_len,
		 void *buf1, size_t buf1_len),
369
	TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
J
Johannes Berg 已提交
370
	TP_STRUCT__entry(
371
		DEV_ENTRY
J
Johannes Berg 已提交
372 373 374 375 376 377 378 379 380 381

		__field(size_t, framelen)
		__dynamic_array(u8, tfd, tfdlen)

		/*
		 * Do not insert between or below these items,
		 * we want to keep the frame together (except
		 * for the possible padding).
		 */
		__dynamic_array(u8, buf0, buf0_len)
382
		__dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len)
J
Johannes Berg 已提交
383 384
	),
	TP_fast_assign(
385
		DEV_ASSIGN;
J
Johannes Berg 已提交
386 387 388
		__entry->framelen = buf0_len + buf1_len;
		memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
		memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
389 390
		if (!iwl_trace_data(skb))
			memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
J
Johannes Berg 已提交
391
	),
392 393
	TP_printk("[%s] TX %.2x (%zu bytes)",
		  __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
J
Johannes Berg 已提交
394 395 396 397
		  __entry->framelen)
);

TRACE_EVENT(iwlwifi_dev_ucode_error,
398
	TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
J
Johannes Berg 已提交
399
		 u32 data1, u32 data2, u32 line, u32 blink1,
W
Wey-Yi Guy 已提交
400 401 402
		 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
		 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
		 u32 brd_ver),
403
	TP_ARGS(dev, desc, tsf_low, data1, data2, line,
W
Wey-Yi Guy 已提交
404 405
		blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
		gp3, ucode_ver, hw_ver, brd_ver),
J
Johannes Berg 已提交
406
	TP_STRUCT__entry(
407
		DEV_ENTRY
J
Johannes Berg 已提交
408
		__field(u32, desc)
W
Wey-Yi Guy 已提交
409
		__field(u32, tsf_low)
J
Johannes Berg 已提交
410 411 412 413 414 415 416
		__field(u32, data1)
		__field(u32, data2)
		__field(u32, line)
		__field(u32, blink1)
		__field(u32, blink2)
		__field(u32, ilink1)
		__field(u32, ilink2)
W
Wey-Yi Guy 已提交
417 418 419 420 421 422 423
		__field(u32, bcon_time)
		__field(u32, gp1)
		__field(u32, gp2)
		__field(u32, gp3)
		__field(u32, ucode_ver)
		__field(u32, hw_ver)
		__field(u32, brd_ver)
J
Johannes Berg 已提交
424 425
	),
	TP_fast_assign(
426
		DEV_ASSIGN;
J
Johannes Berg 已提交
427
		__entry->desc = desc;
W
Wey-Yi Guy 已提交
428
		__entry->tsf_low = tsf_low;
J
Johannes Berg 已提交
429 430 431 432 433 434 435
		__entry->data1 = data1;
		__entry->data2 = data2;
		__entry->line = line;
		__entry->blink1 = blink1;
		__entry->blink2 = blink2;
		__entry->ilink1 = ilink1;
		__entry->ilink2 = ilink2;
W
Wey-Yi Guy 已提交
436 437 438 439 440 441 442
		__entry->bcon_time = bcon_time;
		__entry->gp1 = gp1;
		__entry->gp2 = gp2;
		__entry->gp3 = gp3;
		__entry->ucode_ver = ucode_ver;
		__entry->hw_ver = hw_ver;
		__entry->brd_ver = brd_ver;
J
Johannes Berg 已提交
443
	),
444
	TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
W
Wey-Yi Guy 已提交
445 446 447
		  "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
		  "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X "
		  "hw 0x%08X brd 0x%08X",
448
		  __get_str(dev), __entry->desc, __entry->tsf_low,
W
Wey-Yi Guy 已提交
449
		  __entry->data1,
J
Johannes Berg 已提交
450
		  __entry->data2, __entry->line, __entry->blink1,
W
Wey-Yi Guy 已提交
451 452 453 454
		  __entry->blink2, __entry->ilink1, __entry->ilink2,
		  __entry->bcon_time, __entry->gp1, __entry->gp2,
		  __entry->gp3, __entry->ucode_ver, __entry->hw_ver,
		  __entry->brd_ver)
J
Johannes Berg 已提交
455 456 457
);

TRACE_EVENT(iwlwifi_dev_ucode_event,
458 459
	TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
	TP_ARGS(dev, time, data, ev),
J
Johannes Berg 已提交
460
	TP_STRUCT__entry(
461
		DEV_ENTRY
J
Johannes Berg 已提交
462 463 464 465 466 467

		__field(u32, time)
		__field(u32, data)
		__field(u32, ev)
	),
	TP_fast_assign(
468
		DEV_ASSIGN;
J
Johannes Berg 已提交
469 470 471 472
		__entry->time = time;
		__entry->data = data;
		__entry->ev = ev;
	),
473 474
	TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
		  __get_str(dev), __entry->time, __entry->data, __entry->ev)
J
Johannes Berg 已提交
475 476 477 478 479 480 481 482
);
#endif /* __IWLWIFI_DEVICE_TRACE */

#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE iwl-devtrace
#include <trace/define_trace.h>