debugfs.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // SPDX-License-Identifier: BSD-3-Clause-Clear
  2. /* Copyright (C) 2020 MediaTek Inc. */
  3. #include "mt7921.h"
  4. static int
  5. mt7921_reg_set(void *data, u64 val)
  6. {
  7. struct mt792x_dev *dev = data;
  8. mt792x_mutex_acquire(dev);
  9. mt76_wr(dev, dev->mt76.debugfs_reg, val);
  10. mt792x_mutex_release(dev);
  11. return 0;
  12. }
  13. static int
  14. mt7921_reg_get(void *data, u64 *val)
  15. {
  16. struct mt792x_dev *dev = data;
  17. mt792x_mutex_acquire(dev);
  18. *val = mt76_rr(dev, dev->mt76.debugfs_reg);
  19. mt792x_mutex_release(dev);
  20. return 0;
  21. }
  22. DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7921_reg_get, mt7921_reg_set,
  23. "0x%08llx\n");
  24. static int
  25. mt7921_fw_debug_set(void *data, u64 val)
  26. {
  27. struct mt792x_dev *dev = data;
  28. mt792x_mutex_acquire(dev);
  29. dev->fw_debug = (u8)val;
  30. mt7921_mcu_fw_log_2_host(dev, dev->fw_debug);
  31. mt792x_mutex_release(dev);
  32. return 0;
  33. }
  34. static int
  35. mt7921_fw_debug_get(void *data, u64 *val)
  36. {
  37. struct mt792x_dev *dev = data;
  38. *val = dev->fw_debug;
  39. return 0;
  40. }
  41. DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7921_fw_debug_get,
  42. mt7921_fw_debug_set, "%lld\n");
  43. DEFINE_SHOW_ATTRIBUTE(mt792x_tx_stats);
  44. static void
  45. mt7921_seq_puts_array(struct seq_file *file, const char *str,
  46. s8 *val, int len)
  47. {
  48. int i;
  49. seq_printf(file, "%-16s:", str);
  50. for (i = 0; i < len; i++)
  51. if (val[i] == 127)
  52. seq_printf(file, " %6s", "N.A");
  53. else
  54. seq_printf(file, " %6d", val[i]);
  55. seq_puts(file, "\n");
  56. }
  57. #define mt7921_print_txpwr_entry(prefix, rate) \
  58. ({ \
  59. mt7921_seq_puts_array(s, #prefix " (user)", \
  60. txpwr.data[TXPWR_USER].rate, \
  61. ARRAY_SIZE(txpwr.data[TXPWR_USER].rate)); \
  62. mt7921_seq_puts_array(s, #prefix " (eeprom)", \
  63. txpwr.data[TXPWR_EEPROM].rate, \
  64. ARRAY_SIZE(txpwr.data[TXPWR_EEPROM].rate)); \
  65. mt7921_seq_puts_array(s, #prefix " (tmac)", \
  66. txpwr.data[TXPWR_MAC].rate, \
  67. ARRAY_SIZE(txpwr.data[TXPWR_MAC].rate)); \
  68. })
  69. static int
  70. mt7921_txpwr(struct seq_file *s, void *data)
  71. {
  72. struct mt792x_dev *dev = dev_get_drvdata(s->private);
  73. struct mt7921_txpwr txpwr;
  74. int ret;
  75. mt792x_mutex_acquire(dev);
  76. ret = mt7921_get_txpwr_info(dev, &txpwr);
  77. mt792x_mutex_release(dev);
  78. if (ret)
  79. return ret;
  80. seq_printf(s, "Tx power table (channel %d)\n", txpwr.ch);
  81. seq_printf(s, "%-16s %6s %6s %6s %6s\n",
  82. " ", "1m", "2m", "5m", "11m");
  83. mt7921_print_txpwr_entry(CCK, cck);
  84. seq_printf(s, "%-16s %6s %6s %6s %6s %6s %6s %6s %6s\n",
  85. " ", "6m", "9m", "12m", "18m", "24m", "36m",
  86. "48m", "54m");
  87. mt7921_print_txpwr_entry(OFDM, ofdm);
  88. seq_printf(s, "%-16s %6s %6s %6s %6s %6s %6s %6s %6s\n",
  89. " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5",
  90. "mcs6", "mcs7");
  91. mt7921_print_txpwr_entry(HT20, ht20);
  92. seq_printf(s, "%-16s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n",
  93. " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5",
  94. "mcs6", "mcs7", "mcs32");
  95. mt7921_print_txpwr_entry(HT40, ht40);
  96. seq_printf(s, "%-16s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n",
  97. " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5",
  98. "mcs6", "mcs7", "mcs8", "mcs9", "mcs10", "mcs11");
  99. mt7921_print_txpwr_entry(VHT20, vht20);
  100. mt7921_print_txpwr_entry(VHT40, vht40);
  101. mt7921_print_txpwr_entry(VHT80, vht80);
  102. mt7921_print_txpwr_entry(VHT160, vht160);
  103. mt7921_print_txpwr_entry(HE26, he26);
  104. mt7921_print_txpwr_entry(HE52, he52);
  105. mt7921_print_txpwr_entry(HE106, he106);
  106. mt7921_print_txpwr_entry(HE242, he242);
  107. mt7921_print_txpwr_entry(HE484, he484);
  108. mt7921_print_txpwr_entry(HE996, he996);
  109. mt7921_print_txpwr_entry(HE996x2, he996x2);
  110. return 0;
  111. }
  112. static int
  113. mt7921_pm_set(void *data, u64 val)
  114. {
  115. struct mt792x_dev *dev = data;
  116. struct mt76_connac_pm *pm = &dev->pm;
  117. if (mt76_is_usb(&dev->mt76))
  118. return -EOPNOTSUPP;
  119. mutex_lock(&dev->mt76.mutex);
  120. if (val == pm->enable_user)
  121. goto out;
  122. if (!pm->enable_user) {
  123. pm->stats.last_wake_event = jiffies;
  124. pm->stats.last_doze_event = jiffies;
  125. }
  126. /* make sure the chip is awake here and ps_work is scheduled
  127. * just at end of the this routine.
  128. */
  129. pm->enable = false;
  130. mt76_connac_pm_wake(&dev->mphy, pm);
  131. pm->enable_user = val;
  132. mt7921_set_runtime_pm(dev);
  133. mt76_connac_power_save_sched(&dev->mphy, pm);
  134. out:
  135. mutex_unlock(&dev->mt76.mutex);
  136. return 0;
  137. }
  138. static int
  139. mt7921_pm_get(void *data, u64 *val)
  140. {
  141. struct mt792x_dev *dev = data;
  142. *val = dev->pm.enable_user;
  143. return 0;
  144. }
  145. DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7921_pm_get, mt7921_pm_set, "%lld\n");
  146. static int
  147. mt7921_deep_sleep_set(void *data, u64 val)
  148. {
  149. struct mt792x_dev *dev = data;
  150. struct mt76_connac_pm *pm = &dev->pm;
  151. bool monitor = !!(dev->mphy.hw->conf.flags & IEEE80211_CONF_MONITOR);
  152. bool enable = !!val;
  153. if (mt76_is_usb(&dev->mt76))
  154. return -EOPNOTSUPP;
  155. mt792x_mutex_acquire(dev);
  156. if (pm->ds_enable_user == enable)
  157. goto out;
  158. pm->ds_enable_user = enable;
  159. pm->ds_enable = enable && !monitor;
  160. mt76_connac_mcu_set_deep_sleep(&dev->mt76, pm->ds_enable);
  161. out:
  162. mt792x_mutex_release(dev);
  163. return 0;
  164. }
  165. static int
  166. mt7921_deep_sleep_get(void *data, u64 *val)
  167. {
  168. struct mt792x_dev *dev = data;
  169. *val = dev->pm.ds_enable_user;
  170. return 0;
  171. }
  172. DEFINE_DEBUGFS_ATTRIBUTE(fops_ds, mt7921_deep_sleep_get,
  173. mt7921_deep_sleep_set, "%lld\n");
  174. DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt792x_pm_idle_timeout_get,
  175. mt792x_pm_idle_timeout_set, "%lld\n");
  176. static int mt7921_chip_reset(void *data, u64 val)
  177. {
  178. struct mt792x_dev *dev = data;
  179. int ret = 0;
  180. switch (val) {
  181. case 1:
  182. /* Reset wifisys directly. */
  183. mt792x_reset(&dev->mt76);
  184. break;
  185. default:
  186. /* Collect the core dump before reset wifisys. */
  187. mt792x_mutex_acquire(dev);
  188. ret = mt76_connac_mcu_chip_config(&dev->mt76);
  189. mt792x_mutex_release(dev);
  190. break;
  191. }
  192. return ret;
  193. }
  194. DEFINE_DEBUGFS_ATTRIBUTE(fops_reset, NULL, mt7921_chip_reset, "%lld\n");
  195. static int
  196. mt7921s_sched_quota_read(struct seq_file *s, void *data)
  197. {
  198. struct mt792x_dev *dev = dev_get_drvdata(s->private);
  199. struct mt76_sdio *sdio = &dev->mt76.sdio;
  200. seq_printf(s, "pse_data_quota\t%d\n", sdio->sched.pse_data_quota);
  201. seq_printf(s, "ple_data_quota\t%d\n", sdio->sched.ple_data_quota);
  202. seq_printf(s, "pse_mcu_quota\t%d\n", sdio->sched.pse_mcu_quota);
  203. seq_printf(s, "sched_deficit\t%d\n", sdio->sched.deficit);
  204. return 0;
  205. }
  206. int mt7921_init_debugfs(struct mt792x_dev *dev)
  207. {
  208. struct dentry *dir;
  209. dir = mt76_register_debugfs_fops(&dev->mphy, &fops_regval);
  210. if (!dir)
  211. return -ENOMEM;
  212. if (mt76_is_mmio(&dev->mt76))
  213. debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues",
  214. dir, mt792x_queues_read);
  215. else
  216. debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues",
  217. dir, mt76_queues_read);
  218. debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
  219. mt792x_queues_acq);
  220. debugfs_create_devm_seqfile(dev->mt76.dev, "txpower_sku", dir,
  221. mt7921_txpwr);
  222. debugfs_create_file("tx_stats", 0400, dir, dev, &mt792x_tx_stats_fops);
  223. debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
  224. debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm);
  225. debugfs_create_file("idle-timeout", 0600, dir, dev,
  226. &fops_pm_idle_timeout);
  227. debugfs_create_file("chip_reset", 0600, dir, dev, &fops_reset);
  228. debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir,
  229. mt792x_pm_stats);
  230. debugfs_create_file("deep-sleep", 0600, dir, dev, &fops_ds);
  231. if (mt76_is_sdio(&dev->mt76))
  232. debugfs_create_devm_seqfile(dev->mt76.dev, "sched-quota", dir,
  233. mt7921s_sched_quota_read);
  234. return 0;
  235. }