htc_drv_debug.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. /*
  2. * Copyright (c) 2010-2011 Atheros Communications Inc.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "htc.h"
  17. static struct dentry *ath9k_debugfs_root;
  18. static int ath9k_debugfs_open(struct inode *inode, struct file *file)
  19. {
  20. file->private_data = inode->i_private;
  21. return 0;
  22. }
  23. static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
  24. size_t count, loff_t *ppos)
  25. {
  26. struct ath9k_htc_priv *priv = file->private_data;
  27. struct ath9k_htc_target_int_stats cmd_rsp;
  28. char buf[512];
  29. unsigned int len = 0;
  30. int ret = 0;
  31. memset(&cmd_rsp, 0, sizeof(cmd_rsp));
  32. WMI_CMD(WMI_INT_STATS_CMDID);
  33. if (ret)
  34. return -EINVAL;
  35. len += snprintf(buf + len, sizeof(buf) - len,
  36. "%20s : %10u\n", "RX",
  37. be32_to_cpu(cmd_rsp.rx));
  38. len += snprintf(buf + len, sizeof(buf) - len,
  39. "%20s : %10u\n", "RXORN",
  40. be32_to_cpu(cmd_rsp.rxorn));
  41. len += snprintf(buf + len, sizeof(buf) - len,
  42. "%20s : %10u\n", "RXEOL",
  43. be32_to_cpu(cmd_rsp.rxeol));
  44. len += snprintf(buf + len, sizeof(buf) - len,
  45. "%20s : %10u\n", "TXURN",
  46. be32_to_cpu(cmd_rsp.txurn));
  47. len += snprintf(buf + len, sizeof(buf) - len,
  48. "%20s : %10u\n", "TXTO",
  49. be32_to_cpu(cmd_rsp.txto));
  50. len += snprintf(buf + len, sizeof(buf) - len,
  51. "%20s : %10u\n", "CST",
  52. be32_to_cpu(cmd_rsp.cst));
  53. if (len > sizeof(buf))
  54. len = sizeof(buf);
  55. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  56. }
  57. static const struct file_operations fops_tgt_int_stats = {
  58. .read = read_file_tgt_int_stats,
  59. .open = ath9k_debugfs_open,
  60. .owner = THIS_MODULE,
  61. .llseek = default_llseek,
  62. };
  63. static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
  64. size_t count, loff_t *ppos)
  65. {
  66. struct ath9k_htc_priv *priv = file->private_data;
  67. struct ath9k_htc_target_tx_stats cmd_rsp;
  68. char buf[512];
  69. unsigned int len = 0;
  70. int ret = 0;
  71. memset(&cmd_rsp, 0, sizeof(cmd_rsp));
  72. WMI_CMD(WMI_TX_STATS_CMDID);
  73. if (ret)
  74. return -EINVAL;
  75. len += snprintf(buf + len, sizeof(buf) - len,
  76. "%20s : %10u\n", "Xretries",
  77. be32_to_cpu(cmd_rsp.xretries));
  78. len += snprintf(buf + len, sizeof(buf) - len,
  79. "%20s : %10u\n", "FifoErr",
  80. be32_to_cpu(cmd_rsp.fifoerr));
  81. len += snprintf(buf + len, sizeof(buf) - len,
  82. "%20s : %10u\n", "Filtered",
  83. be32_to_cpu(cmd_rsp.filtered));
  84. len += snprintf(buf + len, sizeof(buf) - len,
  85. "%20s : %10u\n", "TimerExp",
  86. be32_to_cpu(cmd_rsp.timer_exp));
  87. len += snprintf(buf + len, sizeof(buf) - len,
  88. "%20s : %10u\n", "ShortRetries",
  89. be32_to_cpu(cmd_rsp.shortretries));
  90. len += snprintf(buf + len, sizeof(buf) - len,
  91. "%20s : %10u\n", "LongRetries",
  92. be32_to_cpu(cmd_rsp.longretries));
  93. len += snprintf(buf + len, sizeof(buf) - len,
  94. "%20s : %10u\n", "QueueNull",
  95. be32_to_cpu(cmd_rsp.qnull));
  96. len += snprintf(buf + len, sizeof(buf) - len,
  97. "%20s : %10u\n", "EncapFail",
  98. be32_to_cpu(cmd_rsp.encap_fail));
  99. len += snprintf(buf + len, sizeof(buf) - len,
  100. "%20s : %10u\n", "NoBuf",
  101. be32_to_cpu(cmd_rsp.nobuf));
  102. if (len > sizeof(buf))
  103. len = sizeof(buf);
  104. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  105. }
  106. static const struct file_operations fops_tgt_tx_stats = {
  107. .read = read_file_tgt_tx_stats,
  108. .open = ath9k_debugfs_open,
  109. .owner = THIS_MODULE,
  110. .llseek = default_llseek,
  111. };
  112. static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
  113. size_t count, loff_t *ppos)
  114. {
  115. struct ath9k_htc_priv *priv = file->private_data;
  116. struct ath9k_htc_target_rx_stats cmd_rsp;
  117. char buf[512];
  118. unsigned int len = 0;
  119. int ret = 0;
  120. memset(&cmd_rsp, 0, sizeof(cmd_rsp));
  121. WMI_CMD(WMI_RX_STATS_CMDID);
  122. if (ret)
  123. return -EINVAL;
  124. len += snprintf(buf + len, sizeof(buf) - len,
  125. "%20s : %10u\n", "NoBuf",
  126. be32_to_cpu(cmd_rsp.nobuf));
  127. len += snprintf(buf + len, sizeof(buf) - len,
  128. "%20s : %10u\n", "HostSend",
  129. be32_to_cpu(cmd_rsp.host_send));
  130. len += snprintf(buf + len, sizeof(buf) - len,
  131. "%20s : %10u\n", "HostDone",
  132. be32_to_cpu(cmd_rsp.host_done));
  133. if (len > sizeof(buf))
  134. len = sizeof(buf);
  135. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  136. }
  137. static const struct file_operations fops_tgt_rx_stats = {
  138. .read = read_file_tgt_rx_stats,
  139. .open = ath9k_debugfs_open,
  140. .owner = THIS_MODULE,
  141. .llseek = default_llseek,
  142. };
  143. static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
  144. size_t count, loff_t *ppos)
  145. {
  146. struct ath9k_htc_priv *priv = file->private_data;
  147. char buf[512];
  148. unsigned int len = 0;
  149. len += snprintf(buf + len, sizeof(buf) - len,
  150. "%20s : %10u\n", "Buffers queued",
  151. priv->debug.tx_stats.buf_queued);
  152. len += snprintf(buf + len, sizeof(buf) - len,
  153. "%20s : %10u\n", "Buffers completed",
  154. priv->debug.tx_stats.buf_completed);
  155. len += snprintf(buf + len, sizeof(buf) - len,
  156. "%20s : %10u\n", "SKBs queued",
  157. priv->debug.tx_stats.skb_queued);
  158. len += snprintf(buf + len, sizeof(buf) - len,
  159. "%20s : %10u\n", "SKBs success",
  160. priv->debug.tx_stats.skb_success);
  161. len += snprintf(buf + len, sizeof(buf) - len,
  162. "%20s : %10u\n", "SKBs failed",
  163. priv->debug.tx_stats.skb_failed);
  164. len += snprintf(buf + len, sizeof(buf) - len,
  165. "%20s : %10u\n", "CAB queued",
  166. priv->debug.tx_stats.cab_queued);
  167. len += snprintf(buf + len, sizeof(buf) - len,
  168. "%20s : %10u\n", "BE queued",
  169. priv->debug.tx_stats.queue_stats[WME_AC_BE]);
  170. len += snprintf(buf + len, sizeof(buf) - len,
  171. "%20s : %10u\n", "BK queued",
  172. priv->debug.tx_stats.queue_stats[WME_AC_BK]);
  173. len += snprintf(buf + len, sizeof(buf) - len,
  174. "%20s : %10u\n", "VI queued",
  175. priv->debug.tx_stats.queue_stats[WME_AC_VI]);
  176. len += snprintf(buf + len, sizeof(buf) - len,
  177. "%20s : %10u\n", "VO queued",
  178. priv->debug.tx_stats.queue_stats[WME_AC_VO]);
  179. if (len > sizeof(buf))
  180. len = sizeof(buf);
  181. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  182. }
  183. static const struct file_operations fops_xmit = {
  184. .read = read_file_xmit,
  185. .open = ath9k_debugfs_open,
  186. .owner = THIS_MODULE,
  187. .llseek = default_llseek,
  188. };
  189. void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
  190. struct ath_htc_rx_status *rxs)
  191. {
  192. #define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++
  193. if (rxs->rs_status & ATH9K_RXERR_CRC)
  194. priv->debug.rx_stats.err_crc++;
  195. if (rxs->rs_status & ATH9K_RXERR_DECRYPT)
  196. priv->debug.rx_stats.err_decrypt_crc++;
  197. if (rxs->rs_status & ATH9K_RXERR_MIC)
  198. priv->debug.rx_stats.err_mic++;
  199. if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
  200. priv->debug.rx_stats.err_pre_delim++;
  201. if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST)
  202. priv->debug.rx_stats.err_post_delim++;
  203. if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY)
  204. priv->debug.rx_stats.err_decrypt_busy++;
  205. if (rxs->rs_status & ATH9K_RXERR_PHY) {
  206. priv->debug.rx_stats.err_phy++;
  207. if (rxs->rs_phyerr < ATH9K_PHYERR_MAX)
  208. RX_PHY_ERR_INC(rxs->rs_phyerr);
  209. }
  210. #undef RX_PHY_ERR_INC
  211. }
  212. static ssize_t read_file_recv(struct file *file, char __user *user_buf,
  213. size_t count, loff_t *ppos)
  214. {
  215. #define PHY_ERR(s, p) \
  216. len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \
  217. priv->debug.rx_stats.err_phy_stats[p]);
  218. struct ath9k_htc_priv *priv = file->private_data;
  219. char *buf;
  220. unsigned int len = 0, size = 1500;
  221. ssize_t retval = 0;
  222. buf = kzalloc(size, GFP_KERNEL);
  223. if (buf == NULL)
  224. return -ENOMEM;
  225. len += snprintf(buf + len, size - len,
  226. "%20s : %10u\n", "SKBs allocated",
  227. priv->debug.rx_stats.skb_allocated);
  228. len += snprintf(buf + len, size - len,
  229. "%20s : %10u\n", "SKBs completed",
  230. priv->debug.rx_stats.skb_completed);
  231. len += snprintf(buf + len, size - len,
  232. "%20s : %10u\n", "SKBs Dropped",
  233. priv->debug.rx_stats.skb_dropped);
  234. len += snprintf(buf + len, size - len,
  235. "%20s : %10u\n", "CRC ERR",
  236. priv->debug.rx_stats.err_crc);
  237. len += snprintf(buf + len, size - len,
  238. "%20s : %10u\n", "DECRYPT CRC ERR",
  239. priv->debug.rx_stats.err_decrypt_crc);
  240. len += snprintf(buf + len, size - len,
  241. "%20s : %10u\n", "MIC ERR",
  242. priv->debug.rx_stats.err_mic);
  243. len += snprintf(buf + len, size - len,
  244. "%20s : %10u\n", "PRE-DELIM CRC ERR",
  245. priv->debug.rx_stats.err_pre_delim);
  246. len += snprintf(buf + len, size - len,
  247. "%20s : %10u\n", "POST-DELIM CRC ERR",
  248. priv->debug.rx_stats.err_post_delim);
  249. len += snprintf(buf + len, size - len,
  250. "%20s : %10u\n", "DECRYPT BUSY ERR",
  251. priv->debug.rx_stats.err_decrypt_busy);
  252. len += snprintf(buf + len, size - len,
  253. "%20s : %10u\n", "TOTAL PHY ERR",
  254. priv->debug.rx_stats.err_phy);
  255. PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
  256. PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
  257. PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
  258. PHY_ERR("RATE", ATH9K_PHYERR_RATE);
  259. PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
  260. PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
  261. PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
  262. PHY_ERR("TOR", ATH9K_PHYERR_TOR);
  263. PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
  264. PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
  265. PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
  266. PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
  267. PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
  268. PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
  269. PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
  270. PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
  271. PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
  272. PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
  273. PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
  274. PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
  275. PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
  276. PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
  277. PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
  278. PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
  279. PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
  280. PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
  281. if (len > size)
  282. len = size;
  283. retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
  284. kfree(buf);
  285. return retval;
  286. #undef PHY_ERR
  287. }
  288. static const struct file_operations fops_recv = {
  289. .read = read_file_recv,
  290. .open = ath9k_debugfs_open,
  291. .owner = THIS_MODULE,
  292. .llseek = default_llseek,
  293. };
  294. static ssize_t read_file_slot(struct file *file, char __user *user_buf,
  295. size_t count, loff_t *ppos)
  296. {
  297. struct ath9k_htc_priv *priv = file->private_data;
  298. char buf[512];
  299. unsigned int len = 0;
  300. spin_lock_bh(&priv->tx.tx_lock);
  301. len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : ");
  302. len += bitmap_scnprintf(buf + len, sizeof(buf) - len,
  303. priv->tx.tx_slot, MAX_TX_BUF_NUM);
  304. len += snprintf(buf + len, sizeof(buf) - len, "\n");
  305. len += snprintf(buf + len, sizeof(buf) - len,
  306. "Used slots : %d\n",
  307. bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
  308. spin_unlock_bh(&priv->tx.tx_lock);
  309. if (len > sizeof(buf))
  310. len = sizeof(buf);
  311. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  312. }
  313. static const struct file_operations fops_slot = {
  314. .read = read_file_slot,
  315. .open = ath9k_debugfs_open,
  316. .owner = THIS_MODULE,
  317. .llseek = default_llseek,
  318. };
  319. static ssize_t read_file_queue(struct file *file, char __user *user_buf,
  320. size_t count, loff_t *ppos)
  321. {
  322. struct ath9k_htc_priv *priv = file->private_data;
  323. char buf[512];
  324. unsigned int len = 0;
  325. len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
  326. "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue));
  327. len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
  328. "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue));
  329. len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
  330. "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue));
  331. len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
  332. "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue));
  333. len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
  334. "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue));
  335. len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
  336. "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue));
  337. len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
  338. "Failed queue", skb_queue_len(&priv->tx.tx_failed));
  339. spin_lock_bh(&priv->tx.tx_lock);
  340. len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
  341. "Queued count", priv->tx.queued_cnt);
  342. spin_unlock_bh(&priv->tx.tx_lock);
  343. if (len > sizeof(buf))
  344. len = sizeof(buf);
  345. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  346. }
  347. static const struct file_operations fops_queue = {
  348. .read = read_file_queue,
  349. .open = ath9k_debugfs_open,
  350. .owner = THIS_MODULE,
  351. .llseek = default_llseek,
  352. };
  353. static ssize_t read_file_debug(struct file *file, char __user *user_buf,
  354. size_t count, loff_t *ppos)
  355. {
  356. struct ath9k_htc_priv *priv = file->private_data;
  357. struct ath_common *common = ath9k_hw_common(priv->ah);
  358. char buf[32];
  359. unsigned int len;
  360. len = sprintf(buf, "0x%08x\n", common->debug_mask);
  361. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  362. }
  363. static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
  364. size_t count, loff_t *ppos)
  365. {
  366. struct ath9k_htc_priv *priv = file->private_data;
  367. struct ath_common *common = ath9k_hw_common(priv->ah);
  368. unsigned long mask;
  369. char buf[32];
  370. ssize_t len;
  371. len = min(count, sizeof(buf) - 1);
  372. if (copy_from_user(buf, user_buf, len))
  373. return -EFAULT;
  374. buf[len] = '\0';
  375. if (strict_strtoul(buf, 0, &mask))
  376. return -EINVAL;
  377. common->debug_mask = mask;
  378. return count;
  379. }
  380. static const struct file_operations fops_debug = {
  381. .read = read_file_debug,
  382. .write = write_file_debug,
  383. .open = ath9k_debugfs_open,
  384. .owner = THIS_MODULE,
  385. .llseek = default_llseek,
  386. };
  387. int ath9k_htc_init_debug(struct ath_hw *ah)
  388. {
  389. struct ath_common *common = ath9k_hw_common(ah);
  390. struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
  391. if (!ath9k_debugfs_root)
  392. return -ENOENT;
  393. priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
  394. ath9k_debugfs_root);
  395. if (!priv->debug.debugfs_phy)
  396. goto err;
  397. priv->debug.debugfs_tgt_int_stats = debugfs_create_file("tgt_int_stats",
  398. S_IRUSR,
  399. priv->debug.debugfs_phy,
  400. priv, &fops_tgt_int_stats);
  401. if (!priv->debug.debugfs_tgt_int_stats)
  402. goto err;
  403. priv->debug.debugfs_tgt_tx_stats = debugfs_create_file("tgt_tx_stats",
  404. S_IRUSR,
  405. priv->debug.debugfs_phy,
  406. priv, &fops_tgt_tx_stats);
  407. if (!priv->debug.debugfs_tgt_tx_stats)
  408. goto err;
  409. priv->debug.debugfs_tgt_rx_stats = debugfs_create_file("tgt_rx_stats",
  410. S_IRUSR,
  411. priv->debug.debugfs_phy,
  412. priv, &fops_tgt_rx_stats);
  413. if (!priv->debug.debugfs_tgt_rx_stats)
  414. goto err;
  415. priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
  416. priv->debug.debugfs_phy,
  417. priv, &fops_xmit);
  418. if (!priv->debug.debugfs_xmit)
  419. goto err;
  420. priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
  421. priv->debug.debugfs_phy,
  422. priv, &fops_recv);
  423. if (!priv->debug.debugfs_recv)
  424. goto err;
  425. priv->debug.debugfs_slot = debugfs_create_file("slot", S_IRUSR,
  426. priv->debug.debugfs_phy,
  427. priv, &fops_slot);
  428. if (!priv->debug.debugfs_slot)
  429. goto err;
  430. priv->debug.debugfs_queue = debugfs_create_file("queue", S_IRUSR,
  431. priv->debug.debugfs_phy,
  432. priv, &fops_queue);
  433. if (!priv->debug.debugfs_queue)
  434. goto err;
  435. priv->debug.debugfs_debug = debugfs_create_file("debug",
  436. S_IRUSR | S_IWUSR,
  437. priv->debug.debugfs_phy,
  438. priv, &fops_debug);
  439. if (!priv->debug.debugfs_debug)
  440. goto err;
  441. return 0;
  442. err:
  443. ath9k_htc_exit_debug(ah);
  444. return -ENOMEM;
  445. }
  446. void ath9k_htc_exit_debug(struct ath_hw *ah)
  447. {
  448. struct ath_common *common = ath9k_hw_common(ah);
  449. struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
  450. debugfs_remove(priv->debug.debugfs_queue);
  451. debugfs_remove(priv->debug.debugfs_slot);
  452. debugfs_remove(priv->debug.debugfs_recv);
  453. debugfs_remove(priv->debug.debugfs_xmit);
  454. debugfs_remove(priv->debug.debugfs_tgt_int_stats);
  455. debugfs_remove(priv->debug.debugfs_tgt_tx_stats);
  456. debugfs_remove(priv->debug.debugfs_tgt_rx_stats);
  457. debugfs_remove(priv->debug.debugfs_debug);
  458. debugfs_remove(priv->debug.debugfs_phy);
  459. }
  460. int ath9k_htc_debug_create_root(void)
  461. {
  462. ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
  463. if (!ath9k_debugfs_root)
  464. return -ENOENT;
  465. return 0;
  466. }
  467. void ath9k_htc_debug_remove_root(void)
  468. {
  469. debugfs_remove(ath9k_debugfs_root);
  470. ath9k_debugfs_root = NULL;
  471. }