iwl-devtrace.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009 - 2012 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_irq,
  122. TP_PROTO(const struct device *dev),
  123. TP_ARGS(dev),
  124. TP_STRUCT__entry(
  125. DEV_ENTRY
  126. ),
  127. TP_fast_assign(
  128. DEV_ASSIGN;
  129. ),
  130. /* TP_printk("") doesn't compile */
  131. TP_printk("%d", 0)
  132. );
  133. TRACE_EVENT(iwlwifi_dev_ict_read,
  134. TP_PROTO(const struct device *dev, u32 index, u32 value),
  135. TP_ARGS(dev, index, value),
  136. TP_STRUCT__entry(
  137. DEV_ENTRY
  138. __field(u32, index)
  139. __field(u32, value)
  140. ),
  141. TP_fast_assign(
  142. DEV_ASSIGN;
  143. __entry->index = index;
  144. __entry->value = value;
  145. ),
  146. TP_printk("[%s] read ict[%d] = %#.8x",
  147. __get_str(dev), __entry->index, __entry->value)
  148. );
  149. #undef TRACE_SYSTEM
  150. #define TRACE_SYSTEM iwlwifi_ucode
  151. TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
  152. TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
  153. TP_ARGS(dev, time, data, ev),
  154. TP_STRUCT__entry(
  155. DEV_ENTRY
  156. __field(u32, time)
  157. __field(u32, data)
  158. __field(u32, ev)
  159. ),
  160. TP_fast_assign(
  161. DEV_ASSIGN;
  162. __entry->time = time;
  163. __entry->data = data;
  164. __entry->ev = ev;
  165. ),
  166. TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
  167. __get_str(dev), __entry->time, __entry->data, __entry->ev)
  168. );
  169. TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
  170. TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry),
  171. TP_ARGS(dev, wraps, n_entry, p_entry),
  172. TP_STRUCT__entry(
  173. DEV_ENTRY
  174. __field(u32, wraps)
  175. __field(u32, n_entry)
  176. __field(u32, p_entry)
  177. ),
  178. TP_fast_assign(
  179. DEV_ASSIGN;
  180. __entry->wraps = wraps;
  181. __entry->n_entry = n_entry;
  182. __entry->p_entry = p_entry;
  183. ),
  184. TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X",
  185. __get_str(dev), __entry->wraps, __entry->n_entry,
  186. __entry->p_entry)
  187. );
  188. #undef TRACE_SYSTEM
  189. #define TRACE_SYSTEM iwlwifi_msg
  190. #define MAX_MSG_LEN 110
  191. DECLARE_EVENT_CLASS(iwlwifi_msg_event,
  192. TP_PROTO(struct va_format *vaf),
  193. TP_ARGS(vaf),
  194. TP_STRUCT__entry(
  195. __dynamic_array(char, msg, MAX_MSG_LEN)
  196. ),
  197. TP_fast_assign(
  198. WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
  199. MAX_MSG_LEN, vaf->fmt,
  200. *vaf->va) >= MAX_MSG_LEN);
  201. ),
  202. TP_printk("%s", __get_str(msg))
  203. );
  204. DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err,
  205. TP_PROTO(struct va_format *vaf),
  206. TP_ARGS(vaf)
  207. );
  208. DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn,
  209. TP_PROTO(struct va_format *vaf),
  210. TP_ARGS(vaf)
  211. );
  212. DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info,
  213. TP_PROTO(struct va_format *vaf),
  214. TP_ARGS(vaf)
  215. );
  216. DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit,
  217. TP_PROTO(struct va_format *vaf),
  218. TP_ARGS(vaf)
  219. );
  220. TRACE_EVENT(iwlwifi_dbg,
  221. TP_PROTO(u32 level, bool in_interrupt, const char *function,
  222. struct va_format *vaf),
  223. TP_ARGS(level, in_interrupt, function, vaf),
  224. TP_STRUCT__entry(
  225. __field(u32, level)
  226. __field(u8, in_interrupt)
  227. __string(function, function)
  228. __dynamic_array(char, msg, MAX_MSG_LEN)
  229. ),
  230. TP_fast_assign(
  231. __entry->level = level;
  232. __entry->in_interrupt = in_interrupt;
  233. __assign_str(function, function);
  234. WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
  235. MAX_MSG_LEN, vaf->fmt,
  236. *vaf->va) >= MAX_MSG_LEN);
  237. ),
  238. TP_printk("%s", (char *)__get_dynamic_array(msg))
  239. );
  240. #undef TRACE_SYSTEM
  241. #define TRACE_SYSTEM iwlwifi_data
  242. TRACE_EVENT(iwlwifi_dev_tx_data,
  243. TP_PROTO(const struct device *dev,
  244. struct sk_buff *skb,
  245. void *data, size_t data_len),
  246. TP_ARGS(dev, skb, data, data_len),
  247. TP_STRUCT__entry(
  248. DEV_ENTRY
  249. __dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0)
  250. ),
  251. TP_fast_assign(
  252. DEV_ASSIGN;
  253. if (iwl_trace_data(skb))
  254. memcpy(__get_dynamic_array(data), data, data_len);
  255. ),
  256. TP_printk("[%s] TX frame data", __get_str(dev))
  257. );
  258. TRACE_EVENT(iwlwifi_dev_rx_data,
  259. TP_PROTO(const struct device *dev,
  260. const struct iwl_trans *trans,
  261. void *rxbuf, size_t len),
  262. TP_ARGS(dev, trans, rxbuf, len),
  263. TP_STRUCT__entry(
  264. DEV_ENTRY
  265. __dynamic_array(u8, data,
  266. len - iwl_rx_trace_len(trans, rxbuf, len))
  267. ),
  268. TP_fast_assign(
  269. size_t offs = iwl_rx_trace_len(trans, rxbuf, len);
  270. DEV_ASSIGN;
  271. if (offs < len)
  272. memcpy(__get_dynamic_array(data),
  273. ((u8 *)rxbuf) + offs, len - offs);
  274. ),
  275. TP_printk("[%s] TX frame data", __get_str(dev))
  276. );
  277. #undef TRACE_SYSTEM
  278. #define TRACE_SYSTEM iwlwifi
  279. TRACE_EVENT(iwlwifi_dev_hcmd,
  280. TP_PROTO(const struct device *dev,
  281. struct iwl_host_cmd *cmd, u16 total_size,
  282. const void *hdr, size_t hdr_len),
  283. TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
  284. TP_STRUCT__entry(
  285. DEV_ENTRY
  286. __dynamic_array(u8, hcmd, total_size)
  287. __field(u32, flags)
  288. ),
  289. TP_fast_assign(
  290. int i, offset = hdr_len;
  291. DEV_ASSIGN;
  292. __entry->flags = cmd->flags;
  293. memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);
  294. for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
  295. if (!cmd->len[i])
  296. continue;
  297. if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
  298. continue;
  299. memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
  300. cmd->data[i], cmd->len[i]);
  301. offset += cmd->len[i];
  302. }
  303. ),
  304. TP_printk("[%s] hcmd %#.2x (%ssync)",
  305. __get_str(dev), ((u8 *)__get_dynamic_array(hcmd))[0],
  306. __entry->flags & CMD_ASYNC ? "a" : "")
  307. );
  308. TRACE_EVENT(iwlwifi_dev_rx,
  309. TP_PROTO(const struct device *dev, const struct iwl_trans *trans,
  310. void *rxbuf, size_t len),
  311. TP_ARGS(dev, trans, rxbuf, len),
  312. TP_STRUCT__entry(
  313. DEV_ENTRY
  314. __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len))
  315. ),
  316. TP_fast_assign(
  317. DEV_ASSIGN;
  318. memcpy(__get_dynamic_array(rxbuf), rxbuf,
  319. iwl_rx_trace_len(trans, rxbuf, len));
  320. ),
  321. TP_printk("[%s] RX cmd %#.2x",
  322. __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4])
  323. );
  324. TRACE_EVENT(iwlwifi_dev_tx,
  325. TP_PROTO(const struct device *dev, struct sk_buff *skb,
  326. void *tfd, size_t tfdlen,
  327. void *buf0, size_t buf0_len,
  328. void *buf1, size_t buf1_len),
  329. TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
  330. TP_STRUCT__entry(
  331. DEV_ENTRY
  332. __field(size_t, framelen)
  333. __dynamic_array(u8, tfd, tfdlen)
  334. /*
  335. * Do not insert between or below these items,
  336. * we want to keep the frame together (except
  337. * for the possible padding).
  338. */
  339. __dynamic_array(u8, buf0, buf0_len)
  340. __dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len)
  341. ),
  342. TP_fast_assign(
  343. DEV_ASSIGN;
  344. __entry->framelen = buf0_len + buf1_len;
  345. memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
  346. memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
  347. if (!iwl_trace_data(skb))
  348. memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
  349. ),
  350. TP_printk("[%s] TX %.2x (%zu bytes)",
  351. __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
  352. __entry->framelen)
  353. );
  354. TRACE_EVENT(iwlwifi_dev_ucode_error,
  355. TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
  356. u32 data1, u32 data2, u32 line, u32 blink1,
  357. u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
  358. u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
  359. u32 brd_ver),
  360. TP_ARGS(dev, desc, tsf_low, data1, data2, line,
  361. blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
  362. gp3, ucode_ver, hw_ver, brd_ver),
  363. TP_STRUCT__entry(
  364. DEV_ENTRY
  365. __field(u32, desc)
  366. __field(u32, tsf_low)
  367. __field(u32, data1)
  368. __field(u32, data2)
  369. __field(u32, line)
  370. __field(u32, blink1)
  371. __field(u32, blink2)
  372. __field(u32, ilink1)
  373. __field(u32, ilink2)
  374. __field(u32, bcon_time)
  375. __field(u32, gp1)
  376. __field(u32, gp2)
  377. __field(u32, gp3)
  378. __field(u32, ucode_ver)
  379. __field(u32, hw_ver)
  380. __field(u32, brd_ver)
  381. ),
  382. TP_fast_assign(
  383. DEV_ASSIGN;
  384. __entry->desc = desc;
  385. __entry->tsf_low = tsf_low;
  386. __entry->data1 = data1;
  387. __entry->data2 = data2;
  388. __entry->line = line;
  389. __entry->blink1 = blink1;
  390. __entry->blink2 = blink2;
  391. __entry->ilink1 = ilink1;
  392. __entry->ilink2 = ilink2;
  393. __entry->bcon_time = bcon_time;
  394. __entry->gp1 = gp1;
  395. __entry->gp2 = gp2;
  396. __entry->gp3 = gp3;
  397. __entry->ucode_ver = ucode_ver;
  398. __entry->hw_ver = hw_ver;
  399. __entry->brd_ver = brd_ver;
  400. ),
  401. TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
  402. "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
  403. "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X "
  404. "hw 0x%08X brd 0x%08X",
  405. __get_str(dev), __entry->desc, __entry->tsf_low,
  406. __entry->data1,
  407. __entry->data2, __entry->line, __entry->blink1,
  408. __entry->blink2, __entry->ilink1, __entry->ilink2,
  409. __entry->bcon_time, __entry->gp1, __entry->gp2,
  410. __entry->gp3, __entry->ucode_ver, __entry->hw_ver,
  411. __entry->brd_ver)
  412. );
  413. TRACE_EVENT(iwlwifi_dev_ucode_event,
  414. TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
  415. TP_ARGS(dev, time, data, ev),
  416. TP_STRUCT__entry(
  417. DEV_ENTRY
  418. __field(u32, time)
  419. __field(u32, data)
  420. __field(u32, ev)
  421. ),
  422. TP_fast_assign(
  423. DEV_ASSIGN;
  424. __entry->time = time;
  425. __entry->data = data;
  426. __entry->ev = ev;
  427. ),
  428. TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
  429. __get_str(dev), __entry->time, __entry->data, __entry->ev)
  430. );
  431. #endif /* __IWLWIFI_DEVICE_TRACE */
  432. #undef TRACE_INCLUDE_PATH
  433. #define TRACE_INCLUDE_PATH .
  434. #undef TRACE_INCLUDE_FILE
  435. #define TRACE_INCLUDE_FILE iwl-devtrace
  436. #include <trace/define_trace.h>