iwl-devtrace.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009 - 2013 Intel Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. * The full GNU General Public License is included in this distribution in the
  19. * file called LICENSE.
  20. *
  21. * Contact Information:
  22. * Intel Linux Wireless <ilw@linux.intel.com>
  23. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  24. *
  25. *****************************************************************************/
  26. #if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ)
  27. #include <linux/skbuff.h>
  28. #include <linux/ieee80211.h>
  29. #include <net/cfg80211.h>
  30. #include "iwl-trans.h"
  31. #if !defined(__IWLWIFI_DEVICE_TRACE)
  32. static inline bool iwl_trace_data(struct sk_buff *skb)
  33. {
  34. struct ieee80211_hdr *hdr = (void *)skb->data;
  35. if (ieee80211_is_data(hdr->frame_control))
  36. return skb->protocol != cpu_to_be16(ETH_P_PAE);
  37. return false;
  38. }
  39. static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
  40. void *rxbuf, size_t len)
  41. {
  42. struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32));
  43. struct ieee80211_hdr *hdr;
  44. if (cmd->cmd != trans->rx_mpdu_cmd)
  45. return len;
  46. hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) +
  47. trans->rx_mpdu_cmd_hdr_size);
  48. if (!ieee80211_is_data(hdr->frame_control))
  49. return len;
  50. /* maybe try to identify EAPOL frames? */
  51. return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size +
  52. ieee80211_hdrlen(hdr->frame_control);
  53. }
  54. #endif
  55. #define __IWLWIFI_DEVICE_TRACE
  56. #include <linux/tracepoint.h>
  57. #include <linux/device.h>
  58. #include "iwl-trans.h"
  59. #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
  60. #undef TRACE_EVENT
  61. #define TRACE_EVENT(name, proto, ...) \
  62. static inline void trace_ ## name(proto) {}
  63. #undef DECLARE_EVENT_CLASS
  64. #define DECLARE_EVENT_CLASS(...)
  65. #undef DEFINE_EVENT
  66. #define DEFINE_EVENT(evt_class, name, proto, ...) \
  67. static inline void trace_ ## name(proto) {}
  68. #endif
  69. #define DEV_ENTRY __string(dev, dev_name(dev))
  70. #define DEV_ASSIGN __assign_str(dev, dev_name(dev))
  71. #undef TRACE_SYSTEM
  72. #define TRACE_SYSTEM iwlwifi_io
  73. TRACE_EVENT(iwlwifi_dev_ioread32,
  74. TP_PROTO(const struct device *dev, u32 offs, u32 val),
  75. TP_ARGS(dev, offs, val),
  76. TP_STRUCT__entry(
  77. DEV_ENTRY
  78. __field(u32, offs)
  79. __field(u32, val)
  80. ),
  81. TP_fast_assign(
  82. DEV_ASSIGN;
  83. __entry->offs = offs;
  84. __entry->val = val;
  85. ),
  86. TP_printk("[%s] read io[%#x] = %#x",
  87. __get_str(dev), __entry->offs, __entry->val)
  88. );
  89. TRACE_EVENT(iwlwifi_dev_iowrite8,
  90. TP_PROTO(const struct device *dev, u32 offs, u8 val),
  91. TP_ARGS(dev, offs, val),
  92. TP_STRUCT__entry(
  93. DEV_ENTRY
  94. __field(u32, offs)
  95. __field(u8, val)
  96. ),
  97. TP_fast_assign(
  98. DEV_ASSIGN;
  99. __entry->offs = offs;
  100. __entry->val = val;
  101. ),
  102. TP_printk("[%s] write io[%#x] = %#x)",
  103. __get_str(dev), __entry->offs, __entry->val)
  104. );
  105. TRACE_EVENT(iwlwifi_dev_iowrite32,
  106. TP_PROTO(const struct device *dev, u32 offs, u32 val),
  107. TP_ARGS(dev, offs, val),
  108. TP_STRUCT__entry(
  109. DEV_ENTRY
  110. __field(u32, offs)
  111. __field(u32, val)
  112. ),
  113. TP_fast_assign(
  114. DEV_ASSIGN;
  115. __entry->offs = offs;
  116. __entry->val = val;
  117. ),
  118. TP_printk("[%s] write io[%#x] = %#x)",
  119. __get_str(dev), __entry->offs, __entry->val)
  120. );
  121. TRACE_EVENT(iwlwifi_dev_iowrite_prph32,
  122. TP_PROTO(const struct device *dev, u32 offs, u32 val),
  123. TP_ARGS(dev, offs, val),
  124. TP_STRUCT__entry(
  125. DEV_ENTRY
  126. __field(u32, offs)
  127. __field(u32, val)
  128. ),
  129. TP_fast_assign(
  130. DEV_ASSIGN;
  131. __entry->offs = offs;
  132. __entry->val = val;
  133. ),
  134. TP_printk("[%s] write PRPH[%#x] = %#x)",
  135. __get_str(dev), __entry->offs, __entry->val)
  136. );
  137. TRACE_EVENT(iwlwifi_dev_ioread_prph32,
  138. TP_PROTO(const struct device *dev, u32 offs, u32 val),
  139. TP_ARGS(dev, offs, val),
  140. TP_STRUCT__entry(
  141. DEV_ENTRY
  142. __field(u32, offs)
  143. __field(u32, val)
  144. ),
  145. TP_fast_assign(
  146. DEV_ASSIGN;
  147. __entry->offs = offs;
  148. __entry->val = val;
  149. ),
  150. TP_printk("[%s] read PRPH[%#x] = %#x",
  151. __get_str(dev), __entry->offs, __entry->val)
  152. );
  153. TRACE_EVENT(iwlwifi_dev_irq,
  154. TP_PROTO(const struct device *dev),
  155. TP_ARGS(dev),
  156. TP_STRUCT__entry(
  157. DEV_ENTRY
  158. ),
  159. TP_fast_assign(
  160. DEV_ASSIGN;
  161. ),
  162. /* TP_printk("") doesn't compile */
  163. TP_printk("%d", 0)
  164. );
  165. TRACE_EVENT(iwlwifi_dev_ict_read,
  166. TP_PROTO(const struct device *dev, u32 index, u32 value),
  167. TP_ARGS(dev, index, value),
  168. TP_STRUCT__entry(
  169. DEV_ENTRY
  170. __field(u32, index)
  171. __field(u32, value)
  172. ),
  173. TP_fast_assign(
  174. DEV_ASSIGN;
  175. __entry->index = index;
  176. __entry->value = value;
  177. ),
  178. TP_printk("[%s] read ict[%d] = %#.8x",
  179. __get_str(dev), __entry->index, __entry->value)
  180. );
  181. #undef TRACE_SYSTEM
  182. #define TRACE_SYSTEM iwlwifi_ucode
  183. TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
  184. TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
  185. TP_ARGS(dev, time, data, ev),
  186. TP_STRUCT__entry(
  187. DEV_ENTRY
  188. __field(u32, time)
  189. __field(u32, data)
  190. __field(u32, ev)
  191. ),
  192. TP_fast_assign(
  193. DEV_ASSIGN;
  194. __entry->time = time;
  195. __entry->data = data;
  196. __entry->ev = ev;
  197. ),
  198. TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
  199. __get_str(dev), __entry->time, __entry->data, __entry->ev)
  200. );
  201. TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
  202. TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry),
  203. TP_ARGS(dev, wraps, n_entry, p_entry),
  204. TP_STRUCT__entry(
  205. DEV_ENTRY
  206. __field(u32, wraps)
  207. __field(u32, n_entry)
  208. __field(u32, p_entry)
  209. ),
  210. TP_fast_assign(
  211. DEV_ASSIGN;
  212. __entry->wraps = wraps;
  213. __entry->n_entry = n_entry;
  214. __entry->p_entry = p_entry;
  215. ),
  216. TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X",
  217. __get_str(dev), __entry->wraps, __entry->n_entry,
  218. __entry->p_entry)
  219. );
  220. #undef TRACE_SYSTEM
  221. #define TRACE_SYSTEM iwlwifi_msg
  222. #define MAX_MSG_LEN 110
  223. DECLARE_EVENT_CLASS(iwlwifi_msg_event,
  224. TP_PROTO(struct va_format *vaf),
  225. TP_ARGS(vaf),
  226. TP_STRUCT__entry(
  227. __dynamic_array(char, msg, MAX_MSG_LEN)
  228. ),
  229. TP_fast_assign(
  230. WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
  231. MAX_MSG_LEN, vaf->fmt,
  232. *vaf->va) >= MAX_MSG_LEN);
  233. ),
  234. TP_printk("%s", __get_str(msg))
  235. );
  236. DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err,
  237. TP_PROTO(struct va_format *vaf),
  238. TP_ARGS(vaf)
  239. );
  240. DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn,
  241. TP_PROTO(struct va_format *vaf),
  242. TP_ARGS(vaf)
  243. );
  244. DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info,
  245. TP_PROTO(struct va_format *vaf),
  246. TP_ARGS(vaf)
  247. );
  248. DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit,
  249. TP_PROTO(struct va_format *vaf),
  250. TP_ARGS(vaf)
  251. );
  252. TRACE_EVENT(iwlwifi_dbg,
  253. TP_PROTO(u32 level, bool in_interrupt, const char *function,
  254. struct va_format *vaf),
  255. TP_ARGS(level, in_interrupt, function, vaf),
  256. TP_STRUCT__entry(
  257. __field(u32, level)
  258. __field(u8, in_interrupt)
  259. __string(function, function)
  260. __dynamic_array(char, msg, MAX_MSG_LEN)
  261. ),
  262. TP_fast_assign(
  263. __entry->level = level;
  264. __entry->in_interrupt = in_interrupt;
  265. __assign_str(function, function);
  266. WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
  267. MAX_MSG_LEN, vaf->fmt,
  268. *vaf->va) >= MAX_MSG_LEN);
  269. ),
  270. TP_printk("%s", (char *)__get_dynamic_array(msg))
  271. );
  272. #undef TRACE_SYSTEM
  273. #define TRACE_SYSTEM iwlwifi_data
  274. TRACE_EVENT(iwlwifi_dev_tx_data,
  275. TP_PROTO(const struct device *dev,
  276. struct sk_buff *skb,
  277. void *data, size_t data_len),
  278. TP_ARGS(dev, skb, data, data_len),
  279. TP_STRUCT__entry(
  280. DEV_ENTRY
  281. __dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0)
  282. ),
  283. TP_fast_assign(
  284. DEV_ASSIGN;
  285. if (iwl_trace_data(skb))
  286. memcpy(__get_dynamic_array(data), data, data_len);
  287. ),
  288. TP_printk("[%s] TX frame data", __get_str(dev))
  289. );
  290. TRACE_EVENT(iwlwifi_dev_rx_data,
  291. TP_PROTO(const struct device *dev,
  292. const struct iwl_trans *trans,
  293. void *rxbuf, size_t len),
  294. TP_ARGS(dev, trans, rxbuf, len),
  295. TP_STRUCT__entry(
  296. DEV_ENTRY
  297. __dynamic_array(u8, data,
  298. len - iwl_rx_trace_len(trans, rxbuf, len))
  299. ),
  300. TP_fast_assign(
  301. size_t offs = iwl_rx_trace_len(trans, rxbuf, len);
  302. DEV_ASSIGN;
  303. if (offs < len)
  304. memcpy(__get_dynamic_array(data),
  305. ((u8 *)rxbuf) + offs, len - offs);
  306. ),
  307. TP_printk("[%s] RX frame data", __get_str(dev))
  308. );
  309. #undef TRACE_SYSTEM
  310. #define TRACE_SYSTEM iwlwifi
  311. TRACE_EVENT(iwlwifi_dev_hcmd,
  312. TP_PROTO(const struct device *dev,
  313. struct iwl_host_cmd *cmd, u16 total_size,
  314. struct iwl_cmd_header *hdr),
  315. TP_ARGS(dev, cmd, total_size, hdr),
  316. TP_STRUCT__entry(
  317. DEV_ENTRY
  318. __dynamic_array(u8, hcmd, total_size)
  319. __field(u32, flags)
  320. ),
  321. TP_fast_assign(
  322. int i, offset = sizeof(*hdr);
  323. DEV_ASSIGN;
  324. __entry->flags = cmd->flags;
  325. memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
  326. for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
  327. if (!cmd->len[i])
  328. continue;
  329. memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
  330. cmd->data[i], cmd->len[i]);
  331. offset += cmd->len[i];
  332. }
  333. ),
  334. TP_printk("[%s] hcmd %#.2x (%ssync)",
  335. __get_str(dev), ((u8 *)__get_dynamic_array(hcmd))[0],
  336. __entry->flags & CMD_ASYNC ? "a" : "")
  337. );
  338. TRACE_EVENT(iwlwifi_dev_rx,
  339. TP_PROTO(const struct device *dev, const struct iwl_trans *trans,
  340. void *rxbuf, size_t len),
  341. TP_ARGS(dev, trans, rxbuf, len),
  342. TP_STRUCT__entry(
  343. DEV_ENTRY
  344. __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len))
  345. ),
  346. TP_fast_assign(
  347. DEV_ASSIGN;
  348. memcpy(__get_dynamic_array(rxbuf), rxbuf,
  349. iwl_rx_trace_len(trans, rxbuf, len));
  350. ),
  351. TP_printk("[%s] RX cmd %#.2x",
  352. __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4])
  353. );
  354. TRACE_EVENT(iwlwifi_dev_tx,
  355. TP_PROTO(const struct device *dev, struct sk_buff *skb,
  356. void *tfd, size_t tfdlen,
  357. void *buf0, size_t buf0_len,
  358. void *buf1, size_t buf1_len),
  359. TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
  360. TP_STRUCT__entry(
  361. DEV_ENTRY
  362. __field(size_t, framelen)
  363. __dynamic_array(u8, tfd, tfdlen)
  364. /*
  365. * Do not insert between or below these items,
  366. * we want to keep the frame together (except
  367. * for the possible padding).
  368. */
  369. __dynamic_array(u8, buf0, buf0_len)
  370. __dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len)
  371. ),
  372. TP_fast_assign(
  373. DEV_ASSIGN;
  374. __entry->framelen = buf0_len + buf1_len;
  375. memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
  376. memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
  377. if (!iwl_trace_data(skb))
  378. memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
  379. ),
  380. TP_printk("[%s] TX %.2x (%zu bytes)",
  381. __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
  382. __entry->framelen)
  383. );
  384. TRACE_EVENT(iwlwifi_dev_ucode_error,
  385. TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
  386. u32 data1, u32 data2, u32 line, u32 blink1,
  387. u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
  388. u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
  389. u32 brd_ver),
  390. TP_ARGS(dev, desc, tsf_low, data1, data2, line,
  391. blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
  392. gp3, ucode_ver, hw_ver, brd_ver),
  393. TP_STRUCT__entry(
  394. DEV_ENTRY
  395. __field(u32, desc)
  396. __field(u32, tsf_low)
  397. __field(u32, data1)
  398. __field(u32, data2)
  399. __field(u32, line)
  400. __field(u32, blink1)
  401. __field(u32, blink2)
  402. __field(u32, ilink1)
  403. __field(u32, ilink2)
  404. __field(u32, bcon_time)
  405. __field(u32, gp1)
  406. __field(u32, gp2)
  407. __field(u32, gp3)
  408. __field(u32, ucode_ver)
  409. __field(u32, hw_ver)
  410. __field(u32, brd_ver)
  411. ),
  412. TP_fast_assign(
  413. DEV_ASSIGN;
  414. __entry->desc = desc;
  415. __entry->tsf_low = tsf_low;
  416. __entry->data1 = data1;
  417. __entry->data2 = data2;
  418. __entry->line = line;
  419. __entry->blink1 = blink1;
  420. __entry->blink2 = blink2;
  421. __entry->ilink1 = ilink1;
  422. __entry->ilink2 = ilink2;
  423. __entry->bcon_time = bcon_time;
  424. __entry->gp1 = gp1;
  425. __entry->gp2 = gp2;
  426. __entry->gp3 = gp3;
  427. __entry->ucode_ver = ucode_ver;
  428. __entry->hw_ver = hw_ver;
  429. __entry->brd_ver = brd_ver;
  430. ),
  431. TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
  432. "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
  433. "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X "
  434. "hw 0x%08X brd 0x%08X",
  435. __get_str(dev), __entry->desc, __entry->tsf_low,
  436. __entry->data1,
  437. __entry->data2, __entry->line, __entry->blink1,
  438. __entry->blink2, __entry->ilink1, __entry->ilink2,
  439. __entry->bcon_time, __entry->gp1, __entry->gp2,
  440. __entry->gp3, __entry->ucode_ver, __entry->hw_ver,
  441. __entry->brd_ver)
  442. );
  443. TRACE_EVENT(iwlwifi_dev_ucode_event,
  444. TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
  445. TP_ARGS(dev, time, data, ev),
  446. TP_STRUCT__entry(
  447. DEV_ENTRY
  448. __field(u32, time)
  449. __field(u32, data)
  450. __field(u32, ev)
  451. ),
  452. TP_fast_assign(
  453. DEV_ASSIGN;
  454. __entry->time = time;
  455. __entry->data = data;
  456. __entry->ev = ev;
  457. ),
  458. TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
  459. __get_str(dev), __entry->time, __entry->data, __entry->ev)
  460. );
  461. #endif /* __IWLWIFI_DEVICE_TRACE */
  462. #undef TRACE_INCLUDE_PATH
  463. #define TRACE_INCLUDE_PATH .
  464. #undef TRACE_INCLUDE_FILE
  465. #define TRACE_INCLUDE_FILE iwl-devtrace
  466. #include <trace/define_trace.h>