debugfs.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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. struct aqm_info {
  62. struct ieee80211_local *local;
  63. size_t size;
  64. size_t len;
  65. unsigned char buf[0];
  66. };
  67. #define AQM_HDR_LEN 200
  68. #define AQM_HW_ENTRY_LEN 40
  69. #define AQM_TXQ_ENTRY_LEN 110
  70. static int aqm_open(struct inode *inode, struct file *file)
  71. {
  72. struct ieee80211_local *local = inode->i_private;
  73. struct ieee80211_sub_if_data *sdata;
  74. struct sta_info *sta;
  75. struct txq_info *txqi;
  76. struct fq *fq = &local->fq;
  77. struct aqm_info *info = NULL;
  78. int len = 0;
  79. int i;
  80. if (!local->ops->wake_tx_queue)
  81. return -EOPNOTSUPP;
  82. len += AQM_HDR_LEN;
  83. len += 6 * AQM_HW_ENTRY_LEN;
  84. rcu_read_lock();
  85. list_for_each_entry_rcu(sdata, &local->interfaces, list)
  86. len += AQM_TXQ_ENTRY_LEN;
  87. list_for_each_entry_rcu(sta, &local->sta_list, list)
  88. len += AQM_TXQ_ENTRY_LEN * ARRAY_SIZE(sta->sta.txq);
  89. rcu_read_unlock();
  90. info = vmalloc(len);
  91. if (!info)
  92. return -ENOMEM;
  93. spin_lock_bh(&local->fq.lock);
  94. rcu_read_lock();
  95. file->private_data = info;
  96. info->local = local;
  97. info->size = len;
  98. len = 0;
  99. len += scnprintf(info->buf + len, info->size - len,
  100. "* hw\n"
  101. "access name value\n"
  102. "R fq_flows_cnt %u\n"
  103. "R fq_backlog %u\n"
  104. "R fq_overlimit %u\n"
  105. "R fq_collisions %u\n"
  106. "RW fq_limit %u\n"
  107. "RW fq_quantum %u\n",
  108. fq->flows_cnt,
  109. fq->backlog,
  110. fq->overlimit,
  111. fq->collisions,
  112. fq->limit,
  113. fq->quantum);
  114. len += scnprintf(info->buf + len,
  115. info->size - len,
  116. "* vif\n"
  117. "ifname addr ac backlog-bytes backlog-packets flows overlimit collisions tx-bytes tx-packets\n");
  118. list_for_each_entry_rcu(sdata, &local->interfaces, list) {
  119. txqi = to_txq_info(sdata->vif.txq);
  120. len += scnprintf(info->buf + len, info->size - len,
  121. "%s %pM %u %u %u %u %u %u %u %u\n",
  122. sdata->name,
  123. sdata->vif.addr,
  124. txqi->txq.ac,
  125. txqi->tin.backlog_bytes,
  126. txqi->tin.backlog_packets,
  127. txqi->tin.flows,
  128. txqi->tin.overlimit,
  129. txqi->tin.collisions,
  130. txqi->tin.tx_bytes,
  131. txqi->tin.tx_packets);
  132. }
  133. len += scnprintf(info->buf + len,
  134. info->size - len,
  135. "* sta\n"
  136. "ifname addr tid ac backlog-bytes backlog-packets flows overlimit collisions tx-bytes tx-packets\n");
  137. list_for_each_entry_rcu(sta, &local->sta_list, list) {
  138. sdata = sta->sdata;
  139. for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
  140. txqi = to_txq_info(sta->sta.txq[i]);
  141. len += scnprintf(info->buf + len, info->size - len,
  142. "%s %pM %d %d %u %u %u %u %u %u %u\n",
  143. sdata->name,
  144. sta->sta.addr,
  145. txqi->txq.tid,
  146. txqi->txq.ac,
  147. txqi->tin.backlog_bytes,
  148. txqi->tin.backlog_packets,
  149. txqi->tin.flows,
  150. txqi->tin.overlimit,
  151. txqi->tin.collisions,
  152. txqi->tin.tx_bytes,
  153. txqi->tin.tx_packets);
  154. }
  155. }
  156. info->len = len;
  157. rcu_read_unlock();
  158. spin_unlock_bh(&local->fq.lock);
  159. return 0;
  160. }
  161. static int aqm_release(struct inode *inode, struct file *file)
  162. {
  163. vfree(file->private_data);
  164. return 0;
  165. }
  166. static ssize_t aqm_read(struct file *file,
  167. char __user *user_buf,
  168. size_t count,
  169. loff_t *ppos)
  170. {
  171. struct aqm_info *info = file->private_data;
  172. return simple_read_from_buffer(user_buf, count, ppos,
  173. info->buf, info->len);
  174. }
  175. static ssize_t aqm_write(struct file *file,
  176. const char __user *user_buf,
  177. size_t count,
  178. loff_t *ppos)
  179. {
  180. struct aqm_info *info = file->private_data;
  181. struct ieee80211_local *local = info->local;
  182. char buf[100];
  183. size_t len;
  184. if (count > sizeof(buf))
  185. return -EINVAL;
  186. if (copy_from_user(buf, user_buf, count))
  187. return -EFAULT;
  188. buf[sizeof(buf) - 1] = '\0';
  189. len = strlen(buf);
  190. if (len > 0 && buf[len-1] == '\n')
  191. buf[len-1] = 0;
  192. if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1)
  193. return count;
  194. else if (sscanf(buf, "fq_quantum %u", &local->fq.quantum) == 1)
  195. return count;
  196. return -EINVAL;
  197. }
  198. static const struct file_operations aqm_ops = {
  199. .write = aqm_write,
  200. .read = aqm_read,
  201. .open = aqm_open,
  202. .release = aqm_release,
  203. .llseek = default_llseek,
  204. };
  205. #ifdef CONFIG_PM
  206. static ssize_t reset_write(struct file *file, const char __user *user_buf,
  207. size_t count, loff_t *ppos)
  208. {
  209. struct ieee80211_local *local = file->private_data;
  210. rtnl_lock();
  211. __ieee80211_suspend(&local->hw, NULL);
  212. __ieee80211_resume(&local->hw);
  213. rtnl_unlock();
  214. return count;
  215. }
  216. static const struct file_operations reset_ops = {
  217. .write = reset_write,
  218. .open = simple_open,
  219. .llseek = noop_llseek,
  220. };
  221. #endif
  222. static const char *hw_flag_names[] = {
  223. #define FLAG(F) [IEEE80211_HW_##F] = #F
  224. FLAG(HAS_RATE_CONTROL),
  225. FLAG(RX_INCLUDES_FCS),
  226. FLAG(HOST_BROADCAST_PS_BUFFERING),
  227. FLAG(SIGNAL_UNSPEC),
  228. FLAG(SIGNAL_DBM),
  229. FLAG(NEED_DTIM_BEFORE_ASSOC),
  230. FLAG(SPECTRUM_MGMT),
  231. FLAG(AMPDU_AGGREGATION),
  232. FLAG(SUPPORTS_PS),
  233. FLAG(PS_NULLFUNC_STACK),
  234. FLAG(SUPPORTS_DYNAMIC_PS),
  235. FLAG(MFP_CAPABLE),
  236. FLAG(WANT_MONITOR_VIF),
  237. FLAG(NO_AUTO_VIF),
  238. FLAG(SW_CRYPTO_CONTROL),
  239. FLAG(SUPPORT_FAST_XMIT),
  240. FLAG(REPORTS_TX_ACK_STATUS),
  241. FLAG(CONNECTION_MONITOR),
  242. FLAG(QUEUE_CONTROL),
  243. FLAG(SUPPORTS_PER_STA_GTK),
  244. FLAG(AP_LINK_PS),
  245. FLAG(TX_AMPDU_SETUP_IN_HW),
  246. FLAG(SUPPORTS_RC_TABLE),
  247. FLAG(P2P_DEV_ADDR_FOR_INTF),
  248. FLAG(TIMING_BEACON_ONLY),
  249. FLAG(SUPPORTS_HT_CCK_RATES),
  250. FLAG(CHANCTX_STA_CSA),
  251. FLAG(SUPPORTS_CLONED_SKBS),
  252. FLAG(SINGLE_SCAN_ON_ALL_BANDS),
  253. FLAG(TDLS_WIDER_BW),
  254. FLAG(SUPPORTS_AMSDU_IN_AMPDU),
  255. FLAG(BEACON_TX_STATUS),
  256. FLAG(NEEDS_UNIQUE_STA_ADDR),
  257. FLAG(SUPPORTS_REORDERING_BUFFER),
  258. FLAG(USES_RSS),
  259. FLAG(TX_AMSDU),
  260. FLAG(TX_FRAG_LIST),
  261. #undef FLAG
  262. };
  263. static ssize_t hwflags_read(struct file *file, char __user *user_buf,
  264. size_t count, loff_t *ppos)
  265. {
  266. struct ieee80211_local *local = file->private_data;
  267. size_t bufsz = 30 * NUM_IEEE80211_HW_FLAGS;
  268. char *buf = kzalloc(bufsz, GFP_KERNEL);
  269. char *pos = buf, *end = buf + bufsz - 1;
  270. ssize_t rv;
  271. int i;
  272. if (!buf)
  273. return -ENOMEM;
  274. /* fail compilation if somebody adds or removes
  275. * a flag without updating the name array above
  276. */
  277. BUILD_BUG_ON(ARRAY_SIZE(hw_flag_names) != NUM_IEEE80211_HW_FLAGS);
  278. for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
  279. if (test_bit(i, local->hw.flags))
  280. pos += scnprintf(pos, end - pos, "%s\n",
  281. hw_flag_names[i]);
  282. }
  283. rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
  284. kfree(buf);
  285. return rv;
  286. }
  287. static ssize_t queues_read(struct file *file, char __user *user_buf,
  288. size_t count, loff_t *ppos)
  289. {
  290. struct ieee80211_local *local = file->private_data;
  291. unsigned long flags;
  292. char buf[IEEE80211_MAX_QUEUES * 20];
  293. int q, res = 0;
  294. spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
  295. for (q = 0; q < local->hw.queues; q++)
  296. res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
  297. local->queue_stop_reasons[q],
  298. skb_queue_len(&local->pending[q]));
  299. spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
  300. return simple_read_from_buffer(user_buf, count, ppos, buf, res);
  301. }
  302. DEBUGFS_READONLY_FILE_OPS(hwflags);
  303. DEBUGFS_READONLY_FILE_OPS(queues);
  304. /* statistics stuff */
  305. static ssize_t format_devstat_counter(struct ieee80211_local *local,
  306. char __user *userbuf,
  307. size_t count, loff_t *ppos,
  308. int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf,
  309. int buflen))
  310. {
  311. struct ieee80211_low_level_stats stats;
  312. char buf[20];
  313. int res;
  314. rtnl_lock();
  315. res = drv_get_stats(local, &stats);
  316. rtnl_unlock();
  317. if (res)
  318. return res;
  319. res = printvalue(&stats, buf, sizeof(buf));
  320. return simple_read_from_buffer(userbuf, count, ppos, buf, res);
  321. }
  322. #define DEBUGFS_DEVSTATS_FILE(name) \
  323. static int print_devstats_##name(struct ieee80211_low_level_stats *stats,\
  324. char *buf, int buflen) \
  325. { \
  326. return scnprintf(buf, buflen, "%u\n", stats->name); \
  327. } \
  328. static ssize_t stats_ ##name## _read(struct file *file, \
  329. char __user *userbuf, \
  330. size_t count, loff_t *ppos) \
  331. { \
  332. return format_devstat_counter(file->private_data, \
  333. userbuf, \
  334. count, \
  335. ppos, \
  336. print_devstats_##name); \
  337. } \
  338. \
  339. static const struct file_operations stats_ ##name## _ops = { \
  340. .read = stats_ ##name## _read, \
  341. .open = simple_open, \
  342. .llseek = generic_file_llseek, \
  343. };
  344. #define DEBUGFS_STATS_ADD(name) \
  345. debugfs_create_u32(#name, 0400, statsd, &local->name);
  346. #define DEBUGFS_DEVSTATS_ADD(name) \
  347. debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops);
  348. DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
  349. DEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount);
  350. DEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount);
  351. DEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount);
  352. void debugfs_hw_add(struct ieee80211_local *local)
  353. {
  354. struct dentry *phyd = local->hw.wiphy->debugfsdir;
  355. struct dentry *statsd;
  356. if (!phyd)
  357. return;
  358. local->debugfs.keys = debugfs_create_dir("keys", phyd);
  359. DEBUGFS_ADD(total_ps_buffered);
  360. DEBUGFS_ADD(wep_iv);
  361. DEBUGFS_ADD(queues);
  362. #ifdef CONFIG_PM
  363. DEBUGFS_ADD_MODE(reset, 0200);
  364. #endif
  365. DEBUGFS_ADD(hwflags);
  366. DEBUGFS_ADD(user_power);
  367. DEBUGFS_ADD(power);
  368. DEBUGFS_ADD_MODE(aqm, 0600);
  369. statsd = debugfs_create_dir("statistics", phyd);
  370. /* if the dir failed, don't put all the other things into the root! */
  371. if (!statsd)
  372. return;
  373. #ifdef CONFIG_MAC80211_DEBUG_COUNTERS
  374. DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount);
  375. DEBUGFS_STATS_ADD(dot11MulticastTransmittedFrameCount);
  376. DEBUGFS_STATS_ADD(dot11FailedCount);
  377. DEBUGFS_STATS_ADD(dot11RetryCount);
  378. DEBUGFS_STATS_ADD(dot11MultipleRetryCount);
  379. DEBUGFS_STATS_ADD(dot11FrameDuplicateCount);
  380. DEBUGFS_STATS_ADD(dot11ReceivedFragmentCount);
  381. DEBUGFS_STATS_ADD(dot11MulticastReceivedFrameCount);
  382. DEBUGFS_STATS_ADD(dot11TransmittedFrameCount);
  383. DEBUGFS_STATS_ADD(tx_handlers_drop);
  384. DEBUGFS_STATS_ADD(tx_handlers_queued);
  385. DEBUGFS_STATS_ADD(tx_handlers_drop_wep);
  386. DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc);
  387. DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port);
  388. DEBUGFS_STATS_ADD(rx_handlers_drop);
  389. DEBUGFS_STATS_ADD(rx_handlers_queued);
  390. DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc);
  391. DEBUGFS_STATS_ADD(rx_handlers_drop_defrag);
  392. DEBUGFS_STATS_ADD(tx_expand_skb_head);
  393. DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned);
  394. DEBUGFS_STATS_ADD(rx_expand_skb_head_defrag);
  395. DEBUGFS_STATS_ADD(rx_handlers_fragments);
  396. DEBUGFS_STATS_ADD(tx_status_drop);
  397. #endif
  398. DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount);
  399. DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
  400. DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
  401. DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
  402. }