debug.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright(c) 2009-2012 Realtek Corporation.*/
  3. #include "wifi.h"
  4. #include "cam.h"
  5. #include <linux/moduleparam.h>
  6. #include <linux/vmalloc.h>
  7. #ifdef CONFIG_RTLWIFI_DEBUG
  8. void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
  9. const char *fmt, ...)
  10. {
  11. if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
  12. level <= rtlpriv->cfg->mod_params->debug_level)) {
  13. struct va_format vaf;
  14. va_list args;
  15. va_start(args, fmt);
  16. vaf.fmt = fmt;
  17. vaf.va = &args;
  18. pr_info("%pV", &vaf);
  19. va_end(args);
  20. }
  21. }
  22. EXPORT_SYMBOL_GPL(_rtl_dbg_print);
  23. void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
  24. const char *titlestring,
  25. const void *hexdata, int hexdatalen)
  26. {
  27. if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) &&
  28. ((level) <= rtlpriv->cfg->mod_params->debug_level))) {
  29. pr_info("In process \"%s\" (pid %i): %s\n",
  30. current->comm, current->pid, titlestring);
  31. print_hex_dump_bytes("", DUMP_PREFIX_NONE,
  32. hexdata, hexdatalen);
  33. }
  34. }
  35. EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);
  36. struct rtl_debugfs_priv {
  37. struct rtl_priv *rtlpriv;
  38. int (*cb_read)(struct seq_file *m, void *v);
  39. ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
  40. size_t count, loff_t *loff);
  41. u32 cb_data;
  42. };
  43. static struct dentry *debugfs_topdir;
  44. static int rtl_debug_get_common(struct seq_file *m, void *v)
  45. {
  46. struct rtl_debugfs_priv *debugfs_priv = m->private;
  47. return debugfs_priv->cb_read(m, v);
  48. }
  49. static int dl_debug_open_common(struct inode *inode, struct file *file)
  50. {
  51. return single_open(file, rtl_debug_get_common, inode->i_private);
  52. }
  53. static const struct file_operations file_ops_common = {
  54. .open = dl_debug_open_common,
  55. .read = seq_read,
  56. .llseek = seq_lseek,
  57. .release = single_release,
  58. };
  59. static int rtl_debug_get_mac_page(struct seq_file *m, void *v)
  60. {
  61. struct rtl_debugfs_priv *debugfs_priv = m->private;
  62. struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
  63. u32 page = debugfs_priv->cb_data;
  64. int i, n;
  65. int max = 0xff;
  66. for (n = 0; n <= max; ) {
  67. seq_printf(m, "\n%8.8x ", n + page);
  68. for (i = 0; i < 4 && n <= max; i++, n += 4)
  69. seq_printf(m, "%8.8x ",
  70. rtl_read_dword(rtlpriv, (page | n)));
  71. }
  72. seq_puts(m, "\n");
  73. return 0;
  74. }
  75. #define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \
  76. static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \
  77. .cb_read = rtl_debug_get_mac_page, \
  78. .cb_data = addr, \
  79. }
  80. RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
  81. RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
  82. RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
  83. RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
  84. RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
  85. RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
  86. RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
  87. RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
  88. RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
  89. RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
  90. RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
  91. RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
  92. RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
  93. RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
  94. RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
  95. RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);
  96. static int rtl_debug_get_bb_page(struct seq_file *m, void *v)
  97. {
  98. struct rtl_debugfs_priv *debugfs_priv = m->private;
  99. struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
  100. struct ieee80211_hw *hw = rtlpriv->hw;
  101. u32 page = debugfs_priv->cb_data;
  102. int i, n;
  103. int max = 0xff;
  104. for (n = 0; n <= max; ) {
  105. seq_printf(m, "\n%8.8x ", n + page);
  106. for (i = 0; i < 4 && n <= max; i++, n += 4)
  107. seq_printf(m, "%8.8x ",
  108. rtl_get_bbreg(hw, (page | n), 0xffffffff));
  109. }
  110. seq_puts(m, "\n");
  111. return 0;
  112. }
  113. #define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \
  114. static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \
  115. .cb_read = rtl_debug_get_bb_page, \
  116. .cb_data = addr, \
  117. }
  118. RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
  119. RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
  120. RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00);
  121. RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00);
  122. RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00);
  123. RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00);
  124. RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00);
  125. RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00);
  126. RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
  127. RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
  128. RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00);
  129. RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00);
  130. RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00);
  131. RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00);
  132. RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00);
  133. RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00);
  134. static int rtl_debug_get_reg_rf(struct seq_file *m, void *v)
  135. {
  136. struct rtl_debugfs_priv *debugfs_priv = m->private;
  137. struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
  138. struct ieee80211_hw *hw = rtlpriv->hw;
  139. enum radio_path rfpath = debugfs_priv->cb_data;
  140. int i, n;
  141. int max = 0x40;
  142. if (IS_HARDWARE_TYPE_8822B(rtlpriv))
  143. max = 0xff;
  144. seq_printf(m, "\nPATH(%d)", rfpath);
  145. for (n = 0; n <= max; ) {
  146. seq_printf(m, "\n%8.8x ", n);
  147. for (i = 0; i < 4 && n <= max; n += 1, i++)
  148. seq_printf(m, "%8.8x ",
  149. rtl_get_rfreg(hw, rfpath, n, 0xffffffff));
  150. }
  151. seq_puts(m, "\n");
  152. return 0;
  153. }
  154. #define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \
  155. static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \
  156. .cb_read = rtl_debug_get_reg_rf, \
  157. .cb_data = addr, \
  158. }
  159. RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A);
  160. RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B);
  161. static int rtl_debug_get_cam_register(struct seq_file *m, void *v)
  162. {
  163. struct rtl_debugfs_priv *debugfs_priv = m->private;
  164. struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
  165. int start = debugfs_priv->cb_data;
  166. u32 target_cmd = 0;
  167. u32 target_val = 0;
  168. u8 entry_i = 0;
  169. u32 ulstatus;
  170. int i = 100, j = 0;
  171. int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11);
  172. /* This dump the current register page */
  173. seq_printf(m,
  174. "\n#################### SECURITY CAM (%d-%d) ##################\n",
  175. start, end - 1);
  176. for (j = start; j < end; j++) {
  177. seq_printf(m, "\nD: %2x > ", j);
  178. for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
  179. /* polling bit, and No Write enable, and address */
  180. target_cmd = entry_i + CAM_CONTENT_COUNT * j;
  181. target_cmd = target_cmd | BIT(31);
  182. /* Check polling bit is clear */
  183. while ((i--) >= 0) {
  184. ulstatus =
  185. rtl_read_dword(rtlpriv,
  186. rtlpriv->cfg->maps[RWCAM]);
  187. if (ulstatus & BIT(31))
  188. continue;
  189. else
  190. break;
  191. }
  192. rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
  193. target_cmd);
  194. target_val = rtl_read_dword(rtlpriv,
  195. rtlpriv->cfg->maps[RCAMO]);
  196. seq_printf(m, "%8.8x ", target_val);
  197. }
  198. }
  199. seq_puts(m, "\n");
  200. return 0;
  201. }
  202. #define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \
  203. static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \
  204. .cb_read = rtl_debug_get_cam_register, \
  205. .cb_data = addr, \
  206. }
  207. RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
  208. RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
  209. RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
  210. static int rtl_debug_get_btcoex(struct seq_file *m, void *v)
  211. {
  212. struct rtl_debugfs_priv *debugfs_priv = m->private;
  213. struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
  214. if (rtlpriv->cfg->ops->get_btc_status())
  215. rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv,
  216. m);
  217. seq_puts(m, "\n");
  218. return 0;
  219. }
  220. static struct rtl_debugfs_priv rtl_debug_priv_btcoex = {
  221. .cb_read = rtl_debug_get_btcoex,
  222. .cb_data = 0,
  223. };
  224. static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
  225. const char __user *buffer,
  226. size_t count, loff_t *loff)
  227. {
  228. struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
  229. struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
  230. char tmp[32 + 1];
  231. int tmp_len;
  232. u32 addr, val, len;
  233. int num;
  234. if (count < 3)
  235. return -EFAULT;
  236. tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
  237. if (copy_from_user(tmp, buffer, tmp_len))
  238. return -EFAULT;
  239. tmp[tmp_len] = '\0';
  240. /* write BB/MAC register */
  241. num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
  242. if (num != 3)
  243. return -EINVAL;
  244. switch (len) {
  245. case 1:
  246. rtl_write_byte(rtlpriv, addr, (u8)val);
  247. break;
  248. case 2:
  249. rtl_write_word(rtlpriv, addr, (u16)val);
  250. break;
  251. case 4:
  252. rtl_write_dword(rtlpriv, addr, val);
  253. break;
  254. default:
  255. /*printk("error write length=%d", len);*/
  256. break;
  257. }
  258. return count;
  259. }
  260. static struct rtl_debugfs_priv rtl_debug_priv_write_reg = {
  261. .cb_write = rtl_debugfs_set_write_reg,
  262. };
  263. static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
  264. const char __user *buffer,
  265. size_t count, loff_t *loff)
  266. {
  267. struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
  268. struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
  269. struct ieee80211_hw *hw = rtlpriv->hw;
  270. char tmp[32 + 1];
  271. int tmp_len;
  272. u8 h2c_len, h2c_data_packed[8];
  273. int h2c_data[8]; /* idx 0: cmd */
  274. int i;
  275. if (count < 3)
  276. return -EFAULT;
  277. tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
  278. if (copy_from_user(tmp, buffer, tmp_len))
  279. return -EFAULT;
  280. tmp[tmp_len] = '\0';
  281. h2c_len = sscanf(tmp, "%X %X %X %X %X %X %X %X",
  282. &h2c_data[0], &h2c_data[1],
  283. &h2c_data[2], &h2c_data[3],
  284. &h2c_data[4], &h2c_data[5],
  285. &h2c_data[6], &h2c_data[7]);
  286. if (h2c_len == 0)
  287. return -EINVAL;
  288. for (i = 0; i < h2c_len; i++)
  289. h2c_data_packed[i] = (u8)h2c_data[i];
  290. rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0],
  291. h2c_len - 1,
  292. &h2c_data_packed[1]);
  293. return count;
  294. }
  295. static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = {
  296. .cb_write = rtl_debugfs_set_write_h2c,
  297. };
  298. static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
  299. const char __user *buffer,
  300. size_t count, loff_t *loff)
  301. {
  302. struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
  303. struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
  304. struct ieee80211_hw *hw = rtlpriv->hw;
  305. char tmp[32 + 1];
  306. int tmp_len;
  307. int num;
  308. int path;
  309. u32 addr, bitmask, data;
  310. if (count < 3)
  311. return -EFAULT;
  312. tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
  313. if (copy_from_user(tmp, buffer, tmp_len))
  314. return -EFAULT;
  315. tmp[tmp_len] = '\0';
  316. num = sscanf(tmp, "%X %X %X %X",
  317. &path, &addr, &bitmask, &data);
  318. if (num != 4) {
  319. rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
  320. "Format is <path> <addr> <mask> <data>\n");
  321. return -EINVAL;
  322. }
  323. rtl_set_rfreg(hw, path, addr, bitmask, data);
  324. return count;
  325. }
  326. static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = {
  327. .cb_write = rtl_debugfs_set_write_rfreg,
  328. };
  329. static int rtl_debugfs_close(struct inode *inode, struct file *filp)
  330. {
  331. return 0;
  332. }
  333. static ssize_t rtl_debugfs_common_write(struct file *filp,
  334. const char __user *buffer,
  335. size_t count, loff_t *loff)
  336. {
  337. struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
  338. return debugfs_priv->cb_write(filp, buffer, count, loff);
  339. }
  340. static const struct file_operations file_ops_common_write = {
  341. .owner = THIS_MODULE,
  342. .write = rtl_debugfs_common_write,
  343. .open = simple_open,
  344. .release = rtl_debugfs_close,
  345. };
  346. #define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \
  347. do { \
  348. rtl_debug_priv_ ##name.rtlpriv = rtlpriv; \
  349. debugfs_create_file(#name, mode, parent, \
  350. &rtl_debug_priv_ ##name, \
  351. &file_ops_ ##fopname); \
  352. } while (0)
  353. #define RTL_DEBUGFS_ADD(name) \
  354. RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common)
  355. #define RTL_DEBUGFS_ADD_W(name) \
  356. RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write)
  357. void rtl_debug_add_one(struct ieee80211_hw *hw)
  358. {
  359. struct rtl_priv *rtlpriv = rtl_priv(hw);
  360. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  361. struct dentry *parent;
  362. snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr);
  363. rtlpriv->dbg.debugfs_dir =
  364. debugfs_create_dir(rtlpriv->dbg.debugfs_name, debugfs_topdir);
  365. parent = rtlpriv->dbg.debugfs_dir;
  366. RTL_DEBUGFS_ADD(mac_0);
  367. RTL_DEBUGFS_ADD(mac_1);
  368. RTL_DEBUGFS_ADD(mac_2);
  369. RTL_DEBUGFS_ADD(mac_3);
  370. RTL_DEBUGFS_ADD(mac_4);
  371. RTL_DEBUGFS_ADD(mac_5);
  372. RTL_DEBUGFS_ADD(mac_6);
  373. RTL_DEBUGFS_ADD(mac_7);
  374. RTL_DEBUGFS_ADD(bb_8);
  375. RTL_DEBUGFS_ADD(bb_9);
  376. RTL_DEBUGFS_ADD(bb_a);
  377. RTL_DEBUGFS_ADD(bb_b);
  378. RTL_DEBUGFS_ADD(bb_c);
  379. RTL_DEBUGFS_ADD(bb_d);
  380. RTL_DEBUGFS_ADD(bb_e);
  381. RTL_DEBUGFS_ADD(bb_f);
  382. RTL_DEBUGFS_ADD(mac_10);
  383. RTL_DEBUGFS_ADD(mac_11);
  384. RTL_DEBUGFS_ADD(mac_12);
  385. RTL_DEBUGFS_ADD(mac_13);
  386. RTL_DEBUGFS_ADD(mac_14);
  387. RTL_DEBUGFS_ADD(mac_15);
  388. RTL_DEBUGFS_ADD(mac_16);
  389. RTL_DEBUGFS_ADD(mac_17);
  390. RTL_DEBUGFS_ADD(bb_18);
  391. RTL_DEBUGFS_ADD(bb_19);
  392. RTL_DEBUGFS_ADD(bb_1a);
  393. RTL_DEBUGFS_ADD(bb_1b);
  394. RTL_DEBUGFS_ADD(bb_1c);
  395. RTL_DEBUGFS_ADD(bb_1d);
  396. RTL_DEBUGFS_ADD(bb_1e);
  397. RTL_DEBUGFS_ADD(bb_1f);
  398. RTL_DEBUGFS_ADD(rf_a);
  399. RTL_DEBUGFS_ADD(rf_b);
  400. RTL_DEBUGFS_ADD(cam_1);
  401. RTL_DEBUGFS_ADD(cam_2);
  402. RTL_DEBUGFS_ADD(cam_3);
  403. RTL_DEBUGFS_ADD(btcoex);
  404. RTL_DEBUGFS_ADD_W(write_reg);
  405. RTL_DEBUGFS_ADD_W(write_h2c);
  406. RTL_DEBUGFS_ADD_W(write_rfreg);
  407. }
  408. EXPORT_SYMBOL_GPL(rtl_debug_add_one);
  409. void rtl_debug_remove_one(struct ieee80211_hw *hw)
  410. {
  411. struct rtl_priv *rtlpriv = rtl_priv(hw);
  412. debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir);
  413. rtlpriv->dbg.debugfs_dir = NULL;
  414. }
  415. EXPORT_SYMBOL_GPL(rtl_debug_remove_one);
  416. void rtl_debugfs_add_topdir(void)
  417. {
  418. debugfs_topdir = debugfs_create_dir("rtlwifi", NULL);
  419. }
  420. void rtl_debugfs_remove_topdir(void)
  421. {
  422. debugfs_remove_recursive(debugfs_topdir);
  423. }
  424. #endif