debugfs.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. * mac80211 debugfs for wireless PHYs
  3. *
  4. * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
  5. * Copyright 2013-2014 Intel Mobile Communications GmbH
  6. *
  7. * GPLv2
  8. *
  9. */
  10. #include <linux/debugfs.h>
  11. #include <linux/rtnetlink.h>
  12. #include <linux/vmalloc.h>
  13. #include "ieee80211_i.h"
  14. #include "driver-ops.h"
  15. #include "rate.h"
  16. #include "debugfs.h"
  17. #define DEBUGFS_FORMAT_BUFFER_SIZE 100
  18. int mac80211_format_buffer(char __user *userbuf, size_t count,
  19. loff_t *ppos, char *fmt, ...)
  20. {
  21. va_list args;
  22. char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
  23. int res;
  24. va_start(args, fmt);
  25. res = vscnprintf(buf, sizeof(buf), fmt, args);
  26. va_end(args);
  27. return simple_read_from_buffer(userbuf, count, ppos, buf, res);
  28. }
  29. #define DEBUGFS_READONLY_FILE_FN(name, fmt, value...) \
  30. static ssize_t name## _read(struct file *file, char __user *userbuf, \
  31. size_t count, loff_t *ppos) \
  32. { \
  33. struct ieee80211_local *local = file->private_data; \
  34. \
  35. return mac80211_format_buffer(userbuf, count, ppos, \
  36. fmt "\n", ##value); \
  37. }
  38. #define DEBUGFS_READONLY_FILE_OPS(name) \
  39. static const struct file_operations name## _ops = { \
  40. .read = name## _read, \
  41. .open = simple_open, \
  42. .llseek = generic_file_llseek, \
  43. };
  44. #define DEBUGFS_READONLY_FILE(name, fmt, value...) \
  45. DEBUGFS_READONLY_FILE_FN(name, fmt, value) \
  46. DEBUGFS_READONLY_FILE_OPS(name)
  47. #define DEBUGFS_ADD(name) \
  48. debugfs_create_file(#name, 0400, phyd, local, &name## _ops);
  49. #define DEBUGFS_ADD_MODE(name, mode) \
  50. debugfs_create_file(#name, mode, phyd, local, &name## _ops);
  51. DEBUGFS_READONLY_FILE(user_power, "%d",
  52. local->user_power_level);
  53. DEBUGFS_READONLY_FILE(power, "%d",
  54. local->hw.conf.power_level);
  55. DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
  56. local->total_ps_buffered);
  57. DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
  58. local->wep_iv & 0xffffff);
  59. DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
  60. local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
  61. static ssize_t aqm_read(struct file *file,
  62. char __user *user_buf,
  63. size_t count,
  64. loff_t *ppos)
  65. {
  66. struct ieee80211_local *local = file->private_data;
  67. struct fq *fq = &local->fq;
  68. char buf[200];
  69. int len = 0;
  70. spin_lock_bh(&local->fq.lock);
  71. rcu_read_lock();
  72. len = scnprintf(buf, sizeof(buf),
  73. "access name value\n"
  74. "R fq_flows_cnt %u\n"
  75. "R fq_backlog %u\n"
  76. "R fq_overlimit %u\n"
  77. "R fq_overmemory %u\n"
  78. "R fq_collisions %u\n"
  79. "R fq_memory_usage %u\n"
  80. "RW fq_memory_limit %u\n"
  81. "RW fq_limit %u\n"
  82. "RW fq_quantum %u\n",
  83. fq->flows_cnt,
  84. fq->backlog,
  85. fq->overmemory,
  86. fq->overlimit,
  87. fq->collisions,
  88. fq->memory_usage,
  89. fq->memory_limit,
  90. fq->limit,
  91. fq->quantum);
  92. rcu_read_unlock();
  93. spin_unlock_bh(&local->fq.lock);
  94. return simple_read_from_buffer(user_buf, count, ppos,
  95. buf, len);
  96. }
  97. static ssize_t aqm_write(struct file *file,
  98. const char __user *user_buf,
  99. size_t count,
  100. loff_t *ppos)
  101. {
  102. struct ieee80211_local *local = file->private_data;
  103. char buf[100];
  104. size_t len;
  105. if (count > sizeof(buf))
  106. return -EINVAL;
  107. if (copy_from_user(buf, user_buf, count))
  108. return -EFAULT;
  109. buf[sizeof(buf) - 1] = '\0';
  110. len = strlen(buf);
  111. if (len > 0 && buf[len-1] == '\n')
  112. buf[len-1] = 0;
  113. if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1)
  114. return count;
  115. else if (sscanf(buf, "fq_memory_limit %u", &local->fq.memory_limit) == 1)
  116. return count;
  117. else if (sscanf(buf, "fq_quantum %u", &local->fq.quantum) == 1)
  118. return count;
  119. return -EINVAL;
  120. }
  121. static const struct file_operations aqm_ops = {
  122. .write = aqm_write,
  123. .read = aqm_read,
  124. .open = simple_open,
  125. .llseek = default_llseek,
  126. };
  127. #ifdef CONFIG_PM
  128. static ssize_t reset_write(struct file *file, const char __user *user_buf,
  129. size_t count, loff_t *ppos)
  130. {
  131. struct ieee80211_local *local = file->private_data;
  132. rtnl_lock();
  133. __ieee80211_suspend(&local->hw, NULL);
  134. __ieee80211_resume(&local->hw);
  135. rtnl_unlock();
  136. return count;
  137. }
  138. static const struct file_operations reset_ops = {
  139. .write = reset_write,
  140. .open = simple_open,
  141. .llseek = noop_llseek,
  142. };
  143. #endif
  144. static const char *hw_flag_names[] = {
  145. #define FLAG(F) [IEEE80211_HW_##F] = #F
  146. FLAG(HAS_RATE_CONTROL),
  147. FLAG(RX_INCLUDES_FCS),
  148. FLAG(HOST_BROADCAST_PS_BUFFERING),
  149. FLAG(SIGNAL_UNSPEC),
  150. FLAG(SIGNAL_DBM),
  151. FLAG(NEED_DTIM_BEFORE_ASSOC),
  152. FLAG(SPECTRUM_MGMT),
  153. FLAG(AMPDU_AGGREGATION),
  154. FLAG(SUPPORTS_PS),
  155. FLAG(PS_NULLFUNC_STACK),
  156. FLAG(SUPPORTS_DYNAMIC_PS),
  157. FLAG(MFP_CAPABLE),
  158. FLAG(WANT_MONITOR_VIF),
  159. FLAG(NO_AUTO_VIF),
  160. FLAG(SW_CRYPTO_CONTROL),
  161. FLAG(SUPPORT_FAST_XMIT),
  162. FLAG(REPORTS_TX_ACK_STATUS),
  163. FLAG(CONNECTION_MONITOR),
  164. FLAG(QUEUE_CONTROL),
  165. FLAG(SUPPORTS_PER_STA_GTK),
  166. FLAG(AP_LINK_PS),
  167. FLAG(TX_AMPDU_SETUP_IN_HW),
  168. FLAG(SUPPORTS_RC_TABLE),
  169. FLAG(P2P_DEV_ADDR_FOR_INTF),
  170. FLAG(TIMING_BEACON_ONLY),
  171. FLAG(SUPPORTS_HT_CCK_RATES),
  172. FLAG(CHANCTX_STA_CSA),
  173. FLAG(SUPPORTS_CLONED_SKBS),
  174. FLAG(SINGLE_SCAN_ON_ALL_BANDS),
  175. FLAG(TDLS_WIDER_BW),
  176. FLAG(SUPPORTS_AMSDU_IN_AMPDU),
  177. FLAG(BEACON_TX_STATUS),
  178. FLAG(NEEDS_UNIQUE_STA_ADDR),
  179. FLAG(SUPPORTS_REORDERING_BUFFER),
  180. FLAG(USES_RSS),
  181. FLAG(TX_AMSDU),
  182. FLAG(TX_FRAG_LIST),
  183. FLAG(REPORTS_LOW_ACK),
  184. FLAG(SUPPORTS_TX_FRAG),
  185. FLAG(SUPPORTS_TDLS_BUFFER_STA),
  186. FLAG(DEAUTH_NEED_MGD_TX_PREP),
  187. FLAG(DOESNT_SUPPORT_QOS_NDP),
  188. #undef FLAG
  189. };
  190. static ssize_t hwflags_read(struct file *file, char __user *user_buf,
  191. size_t count, loff_t *ppos)
  192. {
  193. struct ieee80211_local *local = file->private_data;
  194. size_t bufsz = 30 * NUM_IEEE80211_HW_FLAGS;
  195. char *buf = kzalloc(bufsz, GFP_KERNEL);
  196. char *pos = buf, *end = buf + bufsz - 1;
  197. ssize_t rv;
  198. int i;
  199. if (!buf)
  200. return -ENOMEM;
  201. /* fail compilation if somebody adds or removes
  202. * a flag without updating the name array above
  203. */
  204. BUILD_BUG_ON(ARRAY_SIZE(hw_flag_names) != NUM_IEEE80211_HW_FLAGS);
  205. for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
  206. if (test_bit(i, local->hw.flags))
  207. pos += scnprintf(pos, end - pos, "%s\n",
  208. hw_flag_names[i]);
  209. }
  210. rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
  211. kfree(buf);
  212. return rv;
  213. }
  214. static ssize_t misc_read(struct file *file, char __user *user_buf,
  215. size_t count, loff_t *ppos)
  216. {
  217. struct ieee80211_local *local = file->private_data;
  218. /* Max len of each line is 16 characters, plus 9 for 'pending:\n' */
  219. size_t bufsz = IEEE80211_MAX_QUEUES * 16 + 9;
  220. char *buf;
  221. char *pos, *end;
  222. ssize_t rv;
  223. int i;
  224. int ln;
  225. buf = kzalloc(bufsz, GFP_KERNEL);
  226. if (!buf)
  227. return -ENOMEM;
  228. pos = buf;
  229. end = buf + bufsz - 1;
  230. pos += scnprintf(pos, end - pos, "pending:\n");
  231. for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
  232. ln = skb_queue_len(&local->pending[i]);
  233. pos += scnprintf(pos, end - pos, "[%i] %d\n",
  234. i, ln);
  235. }
  236. rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
  237. kfree(buf);
  238. return rv;
  239. }
  240. static ssize_t queues_read(struct file *file, char __user *user_buf,
  241. size_t count, loff_t *ppos)
  242. {
  243. struct ieee80211_local *local = file->private_data;
  244. unsigned long flags;
  245. char buf[IEEE80211_MAX_QUEUES * 20];
  246. int q, res = 0;
  247. spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
  248. for (q = 0; q < local->hw.queues; q++)
  249. res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
  250. local->queue_stop_reasons[q],
  251. skb_queue_len(&local->pending[q]));
  252. spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
  253. return simple_read_from_buffer(user_buf, count, ppos, buf, res);
  254. }
  255. DEBUGFS_READONLY_FILE_OPS(hwflags);
  256. DEBUGFS_READONLY_FILE_OPS(queues);
  257. DEBUGFS_READONLY_FILE_OPS(misc);
  258. /* statistics stuff */
  259. static ssize_t format_devstat_counter(struct ieee80211_local *local,
  260. char __user *userbuf,
  261. size_t count, loff_t *ppos,
  262. int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf,
  263. int buflen))
  264. {
  265. struct ieee80211_low_level_stats stats;
  266. char buf[20];
  267. int res;
  268. rtnl_lock();
  269. res = drv_get_stats(local, &stats);
  270. rtnl_unlock();
  271. if (res)
  272. return res;
  273. res = printvalue(&stats, buf, sizeof(buf));
  274. return simple_read_from_buffer(userbuf, count, ppos, buf, res);
  275. }
  276. #define DEBUGFS_DEVSTATS_FILE(name) \
  277. static int print_devstats_##name(struct ieee80211_low_level_stats *stats,\
  278. char *buf, int buflen) \
  279. { \
  280. return scnprintf(buf, buflen, "%u\n", stats->name); \
  281. } \
  282. static ssize_t stats_ ##name## _read(struct file *file, \
  283. char __user *userbuf, \
  284. size_t count, loff_t *ppos) \
  285. { \
  286. return format_devstat_counter(file->private_data, \
  287. userbuf, \
  288. count, \
  289. ppos, \
  290. print_devstats_##name); \
  291. } \
  292. \
  293. static const struct file_operations stats_ ##name## _ops = { \
  294. .read = stats_ ##name## _read, \
  295. .open = simple_open, \
  296. .llseek = generic_file_llseek, \
  297. };
  298. #define DEBUGFS_STATS_ADD(name) \
  299. debugfs_create_u32(#name, 0400, statsd, &local->name);
  300. #define DEBUGFS_DEVSTATS_ADD(name) \
  301. debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops);
  302. DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
  303. DEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount);
  304. DEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount);
  305. DEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount);
  306. void debugfs_hw_add(struct ieee80211_local *local)
  307. {
  308. struct dentry *phyd = local->hw.wiphy->debugfsdir;
  309. struct dentry *statsd;
  310. if (!phyd)
  311. return;
  312. local->debugfs.keys = debugfs_create_dir("keys", phyd);
  313. DEBUGFS_ADD(total_ps_buffered);
  314. DEBUGFS_ADD(wep_iv);
  315. DEBUGFS_ADD(rate_ctrl_alg);
  316. DEBUGFS_ADD(queues);
  317. DEBUGFS_ADD(misc);
  318. #ifdef CONFIG_PM
  319. DEBUGFS_ADD_MODE(reset, 0200);
  320. #endif
  321. DEBUGFS_ADD(hwflags);
  322. DEBUGFS_ADD(user_power);
  323. DEBUGFS_ADD(power);
  324. if (local->ops->wake_tx_queue)
  325. DEBUGFS_ADD_MODE(aqm, 0600);
  326. statsd = debugfs_create_dir("statistics", phyd);
  327. /* if the dir failed, don't put all the other things into the root! */
  328. if (!statsd)
  329. return;
  330. #ifdef CONFIG_MAC80211_DEBUG_COUNTERS
  331. DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount);
  332. DEBUGFS_STATS_ADD(dot11MulticastTransmittedFrameCount);
  333. DEBUGFS_STATS_ADD(dot11FailedCount);
  334. DEBUGFS_STATS_ADD(dot11RetryCount);
  335. DEBUGFS_STATS_ADD(dot11MultipleRetryCount);
  336. DEBUGFS_STATS_ADD(dot11FrameDuplicateCount);
  337. DEBUGFS_STATS_ADD(dot11ReceivedFragmentCount);
  338. DEBUGFS_STATS_ADD(dot11MulticastReceivedFrameCount);
  339. DEBUGFS_STATS_ADD(dot11TransmittedFrameCount);
  340. DEBUGFS_STATS_ADD(tx_handlers_drop);
  341. DEBUGFS_STATS_ADD(tx_handlers_queued);
  342. DEBUGFS_STATS_ADD(tx_handlers_drop_wep);
  343. DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc);
  344. DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port);
  345. DEBUGFS_STATS_ADD(rx_handlers_drop);
  346. DEBUGFS_STATS_ADD(rx_handlers_queued);
  347. DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc);
  348. DEBUGFS_STATS_ADD(rx_handlers_drop_defrag);
  349. DEBUGFS_STATS_ADD(tx_expand_skb_head);
  350. DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned);
  351. DEBUGFS_STATS_ADD(rx_expand_skb_head_defrag);
  352. DEBUGFS_STATS_ADD(rx_handlers_fragments);
  353. DEBUGFS_STATS_ADD(tx_status_drop);
  354. #endif
  355. DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount);
  356. DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
  357. DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
  358. DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
  359. }