12774f206SBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 22774f206SBjoern A. Zeeb /* Copyright(c) 2018-2019 Realtek Corporation 32774f206SBjoern A. Zeeb */ 42774f206SBjoern A. Zeeb 52774f206SBjoern A. Zeeb #include <linux/debugfs.h> 62774f206SBjoern A. Zeeb #include <linux/seq_file.h> 72774f206SBjoern A. Zeeb #include "main.h" 82774f206SBjoern A. Zeeb #include "coex.h" 92774f206SBjoern A. Zeeb #include "sec.h" 102774f206SBjoern A. Zeeb #include "fw.h" 112774f206SBjoern A. Zeeb #include "debug.h" 122774f206SBjoern A. Zeeb #include "phy.h" 132774f206SBjoern A. Zeeb #include "reg.h" 142774f206SBjoern A. Zeeb #include "ps.h" 152774f206SBjoern A. Zeeb #include "regd.h" 162774f206SBjoern A. Zeeb 172774f206SBjoern A. Zeeb #ifdef CONFIG_RTW88_DEBUGFS 182774f206SBjoern A. Zeeb 192774f206SBjoern A. Zeeb struct rtw_debugfs_priv { 202774f206SBjoern A. Zeeb struct rtw_dev *rtwdev; 212774f206SBjoern A. Zeeb int (*cb_read)(struct seq_file *m, void *v); 222774f206SBjoern A. Zeeb ssize_t (*cb_write)(struct file *filp, const char __user *buffer, 232774f206SBjoern A. Zeeb size_t count, loff_t *loff); 242774f206SBjoern A. Zeeb union { 252774f206SBjoern A. Zeeb u32 cb_data; 262774f206SBjoern A. Zeeb u8 *buf; 272774f206SBjoern A. Zeeb struct { 282774f206SBjoern A. Zeeb u32 page_offset; 292774f206SBjoern A. Zeeb u32 page_num; 302774f206SBjoern A. Zeeb } rsvd_page; 312774f206SBjoern A. Zeeb struct { 322774f206SBjoern A. Zeeb u8 rf_path; 332774f206SBjoern A. Zeeb u32 rf_addr; 342774f206SBjoern A. Zeeb u32 rf_mask; 352774f206SBjoern A. Zeeb }; 362774f206SBjoern A. Zeeb struct { 372774f206SBjoern A. Zeeb u32 addr; 382774f206SBjoern A. Zeeb u32 len; 392774f206SBjoern A. Zeeb } read_reg; 402774f206SBjoern A. Zeeb struct { 412774f206SBjoern A. Zeeb u8 bit; 422774f206SBjoern A. Zeeb } dm_cap; 432774f206SBjoern A. Zeeb }; 442774f206SBjoern A. Zeeb }; 452774f206SBjoern A. Zeeb 462774f206SBjoern A. Zeeb static const char * const rtw_dm_cap_strs[] = { 472774f206SBjoern A. Zeeb [RTW_DM_CAP_NA] = "NA", 482774f206SBjoern A. Zeeb [RTW_DM_CAP_TXGAPK] = "TXGAPK", 492774f206SBjoern A. Zeeb }; 502774f206SBjoern A. Zeeb 512774f206SBjoern A. Zeeb static int rtw_debugfs_single_show(struct seq_file *m, void *v) 522774f206SBjoern A. Zeeb { 532774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 542774f206SBjoern A. Zeeb 552774f206SBjoern A. Zeeb return debugfs_priv->cb_read(m, v); 562774f206SBjoern A. Zeeb } 572774f206SBjoern A. Zeeb 582774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_common_write(struct file *filp, 592774f206SBjoern A. Zeeb const char __user *buffer, 602774f206SBjoern A. Zeeb size_t count, loff_t *loff) 612774f206SBjoern A. Zeeb { 622774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 632774f206SBjoern A. Zeeb 642774f206SBjoern A. Zeeb return debugfs_priv->cb_write(filp, buffer, count, loff); 652774f206SBjoern A. Zeeb } 662774f206SBjoern A. Zeeb 672774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_single_write(struct file *filp, 682774f206SBjoern A. Zeeb const char __user *buffer, 692774f206SBjoern A. Zeeb size_t count, loff_t *loff) 702774f206SBjoern A. Zeeb { 712774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 722774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 732774f206SBjoern A. Zeeb 742774f206SBjoern A. Zeeb return debugfs_priv->cb_write(filp, buffer, count, loff); 752774f206SBjoern A. Zeeb } 762774f206SBjoern A. Zeeb 772774f206SBjoern A. Zeeb static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp) 782774f206SBjoern A. Zeeb { 792774f206SBjoern A. Zeeb return single_open(filp, rtw_debugfs_single_show, inode->i_private); 802774f206SBjoern A. Zeeb } 812774f206SBjoern A. Zeeb 822774f206SBjoern A. Zeeb static int rtw_debugfs_close(struct inode *inode, struct file *filp) 832774f206SBjoern A. Zeeb { 842774f206SBjoern A. Zeeb return 0; 852774f206SBjoern A. Zeeb } 862774f206SBjoern A. Zeeb 872774f206SBjoern A. Zeeb static const struct file_operations file_ops_single_r = { 882774f206SBjoern A. Zeeb .owner = THIS_MODULE, 892774f206SBjoern A. Zeeb .open = rtw_debugfs_single_open_rw, 902774f206SBjoern A. Zeeb .read = seq_read, 912774f206SBjoern A. Zeeb .llseek = seq_lseek, 922774f206SBjoern A. Zeeb .release = single_release, 932774f206SBjoern A. Zeeb }; 942774f206SBjoern A. Zeeb 952774f206SBjoern A. Zeeb static const struct file_operations file_ops_single_rw = { 962774f206SBjoern A. Zeeb .owner = THIS_MODULE, 972774f206SBjoern A. Zeeb .open = rtw_debugfs_single_open_rw, 982774f206SBjoern A. Zeeb .release = single_release, 992774f206SBjoern A. Zeeb .read = seq_read, 1002774f206SBjoern A. Zeeb .llseek = seq_lseek, 1012774f206SBjoern A. Zeeb .write = rtw_debugfs_single_write, 1022774f206SBjoern A. Zeeb }; 1032774f206SBjoern A. Zeeb 1042774f206SBjoern A. Zeeb static const struct file_operations file_ops_common_write = { 1052774f206SBjoern A. Zeeb .owner = THIS_MODULE, 1062774f206SBjoern A. Zeeb .write = rtw_debugfs_common_write, 1072774f206SBjoern A. Zeeb .open = simple_open, 1082774f206SBjoern A. Zeeb .release = rtw_debugfs_close, 1092774f206SBjoern A. Zeeb }; 1102774f206SBjoern A. Zeeb 1112774f206SBjoern A. Zeeb static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v) 1122774f206SBjoern A. Zeeb { 1132774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 1142774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 1152774f206SBjoern A. Zeeb u32 val, len, addr; 1162774f206SBjoern A. Zeeb 1172774f206SBjoern A. Zeeb len = debugfs_priv->read_reg.len; 1182774f206SBjoern A. Zeeb addr = debugfs_priv->read_reg.addr; 1192774f206SBjoern A. Zeeb switch (len) { 1202774f206SBjoern A. Zeeb case 1: 1212774f206SBjoern A. Zeeb val = rtw_read8(rtwdev, addr); 1222774f206SBjoern A. Zeeb seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val); 1232774f206SBjoern A. Zeeb break; 1242774f206SBjoern A. Zeeb case 2: 1252774f206SBjoern A. Zeeb val = rtw_read16(rtwdev, addr); 1262774f206SBjoern A. Zeeb seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val); 1272774f206SBjoern A. Zeeb break; 1282774f206SBjoern A. Zeeb case 4: 1292774f206SBjoern A. Zeeb val = rtw_read32(rtwdev, addr); 1302774f206SBjoern A. Zeeb seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val); 1312774f206SBjoern A. Zeeb break; 1322774f206SBjoern A. Zeeb } 1332774f206SBjoern A. Zeeb return 0; 1342774f206SBjoern A. Zeeb } 1352774f206SBjoern A. Zeeb 1362774f206SBjoern A. Zeeb static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v) 1372774f206SBjoern A. Zeeb { 1382774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 1392774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 1402774f206SBjoern A. Zeeb u32 val, addr, mask; 1412774f206SBjoern A. Zeeb u8 path; 1422774f206SBjoern A. Zeeb 1432774f206SBjoern A. Zeeb path = debugfs_priv->rf_path; 1442774f206SBjoern A. Zeeb addr = debugfs_priv->rf_addr; 1452774f206SBjoern A. Zeeb mask = debugfs_priv->rf_mask; 1462774f206SBjoern A. Zeeb 14790aac0d8SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 1482774f206SBjoern A. Zeeb val = rtw_read_rf(rtwdev, path, addr, mask); 14990aac0d8SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 1502774f206SBjoern A. Zeeb 1512774f206SBjoern A. Zeeb seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n", 1522774f206SBjoern A. Zeeb path, addr, mask, val); 1532774f206SBjoern A. Zeeb 1542774f206SBjoern A. Zeeb return 0; 1552774f206SBjoern A. Zeeb } 1562774f206SBjoern A. Zeeb 1572774f206SBjoern A. Zeeb static int rtw_debugfs_get_fix_rate(struct seq_file *m, void *v) 1582774f206SBjoern A. Zeeb { 1592774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 1602774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 1612774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1622774f206SBjoern A. Zeeb u8 fix_rate = dm_info->fix_rate; 1632774f206SBjoern A. Zeeb 1642774f206SBjoern A. Zeeb if (fix_rate >= DESC_RATE_MAX) { 1652774f206SBjoern A. Zeeb seq_printf(m, "Fix rate disabled, fix_rate = %u\n", fix_rate); 1662774f206SBjoern A. Zeeb return 0; 1672774f206SBjoern A. Zeeb } 1682774f206SBjoern A. Zeeb 1692774f206SBjoern A. Zeeb seq_printf(m, "Data frames fixed at desc rate %u\n", fix_rate); 1702774f206SBjoern A. Zeeb return 0; 1712774f206SBjoern A. Zeeb } 1722774f206SBjoern A. Zeeb 1732774f206SBjoern A. Zeeb static int rtw_debugfs_copy_from_user(char tmp[], int size, 1742774f206SBjoern A. Zeeb const char __user *buffer, size_t count, 1752774f206SBjoern A. Zeeb int num) 1762774f206SBjoern A. Zeeb { 1772774f206SBjoern A. Zeeb int tmp_len; 1782774f206SBjoern A. Zeeb 1792774f206SBjoern A. Zeeb memset(tmp, 0, size); 1802774f206SBjoern A. Zeeb 1812774f206SBjoern A. Zeeb if (count < num) 1822774f206SBjoern A. Zeeb return -EFAULT; 1832774f206SBjoern A. Zeeb 1842774f206SBjoern A. Zeeb tmp_len = (count > size - 1 ? size - 1 : count); 1852774f206SBjoern A. Zeeb 18690aac0d8SBjoern A. Zeeb if (copy_from_user(tmp, buffer, tmp_len)) 18790aac0d8SBjoern A. Zeeb return -EFAULT; 1882774f206SBjoern A. Zeeb 1892774f206SBjoern A. Zeeb tmp[tmp_len] = '\0'; 1902774f206SBjoern A. Zeeb 1912774f206SBjoern A. Zeeb return 0; 1922774f206SBjoern A. Zeeb } 1932774f206SBjoern A. Zeeb 1942774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_read_reg(struct file *filp, 1952774f206SBjoern A. Zeeb const char __user *buffer, 1962774f206SBjoern A. Zeeb size_t count, loff_t *loff) 1972774f206SBjoern A. Zeeb { 1982774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 1992774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 2002774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 2012774f206SBjoern A. Zeeb char tmp[32 + 1]; 2022774f206SBjoern A. Zeeb u32 addr, len; 2032774f206SBjoern A. Zeeb int num; 20490aac0d8SBjoern A. Zeeb int ret; 2052774f206SBjoern A. Zeeb 20690aac0d8SBjoern A. Zeeb ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 20790aac0d8SBjoern A. Zeeb if (ret) 20890aac0d8SBjoern A. Zeeb return ret; 2092774f206SBjoern A. Zeeb 2102774f206SBjoern A. Zeeb num = sscanf(tmp, "%x %x", &addr, &len); 2112774f206SBjoern A. Zeeb 2122774f206SBjoern A. Zeeb if (num != 2) 21390aac0d8SBjoern A. Zeeb return -EINVAL; 2142774f206SBjoern A. Zeeb 2152774f206SBjoern A. Zeeb if (len != 1 && len != 2 && len != 4) { 2162774f206SBjoern A. Zeeb rtw_warn(rtwdev, "read reg setting wrong len\n"); 2172774f206SBjoern A. Zeeb return -EINVAL; 2182774f206SBjoern A. Zeeb } 2192774f206SBjoern A. Zeeb debugfs_priv->read_reg.addr = addr; 2202774f206SBjoern A. Zeeb debugfs_priv->read_reg.len = len; 2212774f206SBjoern A. Zeeb 2222774f206SBjoern A. Zeeb return count; 2232774f206SBjoern A. Zeeb } 2242774f206SBjoern A. Zeeb 2252774f206SBjoern A. Zeeb static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v) 2262774f206SBjoern A. Zeeb { 2272774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 2282774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 2292774f206SBjoern A. Zeeb u32 val, command; 2302774f206SBjoern A. Zeeb u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT; 2312774f206SBjoern A. Zeeb u32 read_cmd = RTW_SEC_CMD_POLLING; 2322774f206SBjoern A. Zeeb int i; 2332774f206SBjoern A. Zeeb 2342774f206SBjoern A. Zeeb seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data); 2352774f206SBjoern A. Zeeb seq_puts(m, "0x0 0x1 0x2 0x3 "); 2362774f206SBjoern A. Zeeb seq_puts(m, "0x4 0x5\n"); 2372774f206SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 2382774f206SBjoern A. Zeeb for (i = 0; i <= 5; i++) { 2392774f206SBjoern A. Zeeb command = read_cmd | (hw_key_idx + i); 2402774f206SBjoern A. Zeeb rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); 2412774f206SBjoern A. Zeeb val = rtw_read32(rtwdev, RTW_SEC_READ_REG); 2422774f206SBjoern A. Zeeb seq_printf(m, "%8.8x", val); 2432774f206SBjoern A. Zeeb if (i < 2) 2442774f206SBjoern A. Zeeb seq_puts(m, " "); 2452774f206SBjoern A. Zeeb } 2462774f206SBjoern A. Zeeb seq_puts(m, "\n"); 2472774f206SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 2482774f206SBjoern A. Zeeb return 0; 2492774f206SBjoern A. Zeeb } 2502774f206SBjoern A. Zeeb 2512774f206SBjoern A. Zeeb static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v) 2522774f206SBjoern A. Zeeb { 2532774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 2542774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 2552774f206SBjoern A. Zeeb u8 page_size = rtwdev->chip->page_size; 2562774f206SBjoern A. Zeeb u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; 2572774f206SBjoern A. Zeeb u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; 2582774f206SBjoern A. Zeeb u8 *buf; 2592774f206SBjoern A. Zeeb int i; 2602774f206SBjoern A. Zeeb int ret; 2612774f206SBjoern A. Zeeb 2622774f206SBjoern A. Zeeb buf = vzalloc(buf_size); 2632774f206SBjoern A. Zeeb if (!buf) 2642774f206SBjoern A. Zeeb return -ENOMEM; 2652774f206SBjoern A. Zeeb 2662774f206SBjoern A. Zeeb ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RSVD_PAGE, offset, 2672774f206SBjoern A. Zeeb buf_size, (u32 *)buf); 2682774f206SBjoern A. Zeeb if (ret) { 2692774f206SBjoern A. Zeeb rtw_err(rtwdev, "failed to dump rsvd page\n"); 2702774f206SBjoern A. Zeeb vfree(buf); 2712774f206SBjoern A. Zeeb return ret; 2722774f206SBjoern A. Zeeb } 2732774f206SBjoern A. Zeeb 2742774f206SBjoern A. Zeeb for (i = 0 ; i < buf_size ; i += 8) { 2752774f206SBjoern A. Zeeb if (i % page_size == 0) 2762774f206SBjoern A. Zeeb seq_printf(m, "PAGE %d\n", (i + offset) / page_size); 2779c951734SBjoern A. Zeeb seq_printf(m, "%8ph\n", buf + i); 2782774f206SBjoern A. Zeeb } 2792774f206SBjoern A. Zeeb vfree(buf); 2802774f206SBjoern A. Zeeb 2812774f206SBjoern A. Zeeb return 0; 2822774f206SBjoern A. Zeeb } 2832774f206SBjoern A. Zeeb 2842774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp, 2852774f206SBjoern A. Zeeb const char __user *buffer, 2862774f206SBjoern A. Zeeb size_t count, loff_t *loff) 2872774f206SBjoern A. Zeeb { 2882774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 2892774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 2902774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 2912774f206SBjoern A. Zeeb char tmp[32 + 1]; 2922774f206SBjoern A. Zeeb u32 offset, page_num; 2932774f206SBjoern A. Zeeb int num; 29490aac0d8SBjoern A. Zeeb int ret; 2952774f206SBjoern A. Zeeb 29690aac0d8SBjoern A. Zeeb ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 29790aac0d8SBjoern A. Zeeb if (ret) 29890aac0d8SBjoern A. Zeeb return ret; 2992774f206SBjoern A. Zeeb 3002774f206SBjoern A. Zeeb num = sscanf(tmp, "%d %d", &offset, &page_num); 3012774f206SBjoern A. Zeeb 3022774f206SBjoern A. Zeeb if (num != 2) { 3032774f206SBjoern A. Zeeb rtw_warn(rtwdev, "invalid arguments\n"); 3042774f206SBjoern A. Zeeb return -EINVAL; 3052774f206SBjoern A. Zeeb } 3062774f206SBjoern A. Zeeb 3072774f206SBjoern A. Zeeb debugfs_priv->rsvd_page.page_offset = offset; 3082774f206SBjoern A. Zeeb debugfs_priv->rsvd_page.page_num = page_num; 3092774f206SBjoern A. Zeeb 3102774f206SBjoern A. Zeeb return count; 3112774f206SBjoern A. Zeeb } 3122774f206SBjoern A. Zeeb 3132774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_single_input(struct file *filp, 3142774f206SBjoern A. Zeeb const char __user *buffer, 3152774f206SBjoern A. Zeeb size_t count, loff_t *loff) 3162774f206SBjoern A. Zeeb { 3172774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 3182774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 3192774f206SBjoern A. Zeeb u32 input; 32090aac0d8SBjoern A. Zeeb int ret; 3212774f206SBjoern A. Zeeb 322*11c53278SBjoern A. Zeeb ret = kstrtou32_from_user(buffer, count, 0, &input); 32390aac0d8SBjoern A. Zeeb if (ret) 32490aac0d8SBjoern A. Zeeb return ret; 3252774f206SBjoern A. Zeeb 3262774f206SBjoern A. Zeeb debugfs_priv->cb_data = input; 3272774f206SBjoern A. Zeeb 3282774f206SBjoern A. Zeeb return count; 3292774f206SBjoern A. Zeeb } 3302774f206SBjoern A. Zeeb 3312774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_write_reg(struct file *filp, 3322774f206SBjoern A. Zeeb const char __user *buffer, 3332774f206SBjoern A. Zeeb size_t count, loff_t *loff) 3342774f206SBjoern A. Zeeb { 3352774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 3362774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 3372774f206SBjoern A. Zeeb char tmp[32 + 1]; 3382774f206SBjoern A. Zeeb u32 addr, val, len; 3392774f206SBjoern A. Zeeb int num; 34090aac0d8SBjoern A. Zeeb int ret; 3412774f206SBjoern A. Zeeb 34290aac0d8SBjoern A. Zeeb ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 34390aac0d8SBjoern A. Zeeb if (ret) 34490aac0d8SBjoern A. Zeeb return ret; 3452774f206SBjoern A. Zeeb 3462774f206SBjoern A. Zeeb /* write BB/MAC register */ 3472774f206SBjoern A. Zeeb num = sscanf(tmp, "%x %x %x", &addr, &val, &len); 3482774f206SBjoern A. Zeeb 3492774f206SBjoern A. Zeeb if (num != 3) 35090aac0d8SBjoern A. Zeeb return -EINVAL; 3512774f206SBjoern A. Zeeb 3522774f206SBjoern A. Zeeb switch (len) { 3532774f206SBjoern A. Zeeb case 1: 3542774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 3552774f206SBjoern A. Zeeb "reg write8 0x%03x: 0x%08x\n", addr, val); 3562774f206SBjoern A. Zeeb rtw_write8(rtwdev, addr, (u8)val); 3572774f206SBjoern A. Zeeb break; 3582774f206SBjoern A. Zeeb case 2: 3592774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 3602774f206SBjoern A. Zeeb "reg write16 0x%03x: 0x%08x\n", addr, val); 3612774f206SBjoern A. Zeeb rtw_write16(rtwdev, addr, (u16)val); 3622774f206SBjoern A. Zeeb break; 3632774f206SBjoern A. Zeeb case 4: 3642774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 3652774f206SBjoern A. Zeeb "reg write32 0x%03x: 0x%08x\n", addr, val); 3662774f206SBjoern A. Zeeb rtw_write32(rtwdev, addr, (u32)val); 3672774f206SBjoern A. Zeeb break; 3682774f206SBjoern A. Zeeb default: 3692774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 3702774f206SBjoern A. Zeeb "error write length = %d\n", len); 3712774f206SBjoern A. Zeeb break; 3722774f206SBjoern A. Zeeb } 3732774f206SBjoern A. Zeeb 3742774f206SBjoern A. Zeeb return count; 3752774f206SBjoern A. Zeeb } 3762774f206SBjoern A. Zeeb 3772774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_h2c(struct file *filp, 3782774f206SBjoern A. Zeeb const char __user *buffer, 3792774f206SBjoern A. Zeeb size_t count, loff_t *loff) 3802774f206SBjoern A. Zeeb { 3812774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 3822774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 3832774f206SBjoern A. Zeeb char tmp[32 + 1]; 3842774f206SBjoern A. Zeeb u8 param[8]; 3852774f206SBjoern A. Zeeb int num; 38690aac0d8SBjoern A. Zeeb int ret; 3872774f206SBjoern A. Zeeb 38890aac0d8SBjoern A. Zeeb ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 38990aac0d8SBjoern A. Zeeb if (ret) 39090aac0d8SBjoern A. Zeeb return ret; 3912774f206SBjoern A. Zeeb 3922774f206SBjoern A. Zeeb num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", 3932774f206SBjoern A. Zeeb ¶m[0], ¶m[1], ¶m[2], ¶m[3], 3942774f206SBjoern A. Zeeb ¶m[4], ¶m[5], ¶m[6], ¶m[7]); 3952774f206SBjoern A. Zeeb if (num != 8) { 3969c951734SBjoern A. Zeeb rtw_warn(rtwdev, "invalid H2C command format for debug\n"); 3972774f206SBjoern A. Zeeb return -EINVAL; 3982774f206SBjoern A. Zeeb } 3992774f206SBjoern A. Zeeb 40090aac0d8SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 4012774f206SBjoern A. Zeeb rtw_fw_h2c_cmd_dbg(rtwdev, param); 40290aac0d8SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 4032774f206SBjoern A. Zeeb 4042774f206SBjoern A. Zeeb return count; 4052774f206SBjoern A. Zeeb } 4062774f206SBjoern A. Zeeb 4072774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_rf_write(struct file *filp, 4082774f206SBjoern A. Zeeb const char __user *buffer, 4092774f206SBjoern A. Zeeb size_t count, loff_t *loff) 4102774f206SBjoern A. Zeeb { 4112774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 4122774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 4132774f206SBjoern A. Zeeb char tmp[32 + 1]; 4142774f206SBjoern A. Zeeb u32 path, addr, mask, val; 4152774f206SBjoern A. Zeeb int num; 41690aac0d8SBjoern A. Zeeb int ret; 4172774f206SBjoern A. Zeeb 41890aac0d8SBjoern A. Zeeb ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); 41990aac0d8SBjoern A. Zeeb if (ret) 42090aac0d8SBjoern A. Zeeb return ret; 4212774f206SBjoern A. Zeeb 4222774f206SBjoern A. Zeeb num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); 4232774f206SBjoern A. Zeeb 4242774f206SBjoern A. Zeeb if (num != 4) { 4252774f206SBjoern A. Zeeb rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 42690aac0d8SBjoern A. Zeeb return -EINVAL; 4272774f206SBjoern A. Zeeb } 4282774f206SBjoern A. Zeeb 42990aac0d8SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 4302774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, addr, mask, val); 43190aac0d8SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 4322774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 4332774f206SBjoern A. Zeeb "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", 4342774f206SBjoern A. Zeeb path, addr, mask, val); 4352774f206SBjoern A. Zeeb 4362774f206SBjoern A. Zeeb return count; 4372774f206SBjoern A. Zeeb } 4382774f206SBjoern A. Zeeb 4392774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_rf_read(struct file *filp, 4402774f206SBjoern A. Zeeb const char __user *buffer, 4412774f206SBjoern A. Zeeb size_t count, loff_t *loff) 4422774f206SBjoern A. Zeeb { 4432774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 4442774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 4452774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 4462774f206SBjoern A. Zeeb char tmp[32 + 1]; 4472774f206SBjoern A. Zeeb u32 path, addr, mask; 4482774f206SBjoern A. Zeeb int num; 44990aac0d8SBjoern A. Zeeb int ret; 4502774f206SBjoern A. Zeeb 45190aac0d8SBjoern A. Zeeb ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 45290aac0d8SBjoern A. Zeeb if (ret) 45390aac0d8SBjoern A. Zeeb return ret; 4542774f206SBjoern A. Zeeb 4552774f206SBjoern A. Zeeb num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); 4562774f206SBjoern A. Zeeb 4572774f206SBjoern A. Zeeb if (num != 3) { 4582774f206SBjoern A. Zeeb rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 45990aac0d8SBjoern A. Zeeb return -EINVAL; 4602774f206SBjoern A. Zeeb } 4612774f206SBjoern A. Zeeb 4622774f206SBjoern A. Zeeb debugfs_priv->rf_path = path; 4632774f206SBjoern A. Zeeb debugfs_priv->rf_addr = addr; 4642774f206SBjoern A. Zeeb debugfs_priv->rf_mask = mask; 4652774f206SBjoern A. Zeeb 4662774f206SBjoern A. Zeeb return count; 4672774f206SBjoern A. Zeeb } 4682774f206SBjoern A. Zeeb 4692774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_fix_rate(struct file *filp, 4702774f206SBjoern A. Zeeb const char __user *buffer, 4712774f206SBjoern A. Zeeb size_t count, loff_t *loff) 4722774f206SBjoern A. Zeeb { 4732774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 4742774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 4752774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 4762774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 4772774f206SBjoern A. Zeeb u8 fix_rate; 4782774f206SBjoern A. Zeeb int ret; 4792774f206SBjoern A. Zeeb 480*11c53278SBjoern A. Zeeb ret = kstrtou8_from_user(buffer, count, 0, &fix_rate); 48190aac0d8SBjoern A. Zeeb if (ret) 48290aac0d8SBjoern A. Zeeb return ret; 4832774f206SBjoern A. Zeeb 4842774f206SBjoern A. Zeeb dm_info->fix_rate = fix_rate; 4852774f206SBjoern A. Zeeb 4862774f206SBjoern A. Zeeb return count; 4872774f206SBjoern A. Zeeb } 4882774f206SBjoern A. Zeeb 4892774f206SBjoern A. Zeeb static int rtw_debug_get_mac_page(struct seq_file *m, void *v) 4902774f206SBjoern A. Zeeb { 4912774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 4922774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 4932774f206SBjoern A. Zeeb u32 page = debugfs_priv->cb_data; 4942774f206SBjoern A. Zeeb int i, n; 4952774f206SBjoern A. Zeeb int max = 0xff; 4962774f206SBjoern A. Zeeb 4972774f206SBjoern A. Zeeb rtw_read32(rtwdev, debugfs_priv->cb_data); 4982774f206SBjoern A. Zeeb for (n = 0; n <= max; ) { 4992774f206SBjoern A. Zeeb seq_printf(m, "\n%8.8x ", n + page); 5002774f206SBjoern A. Zeeb for (i = 0; i < 4 && n <= max; i++, n += 4) 5012774f206SBjoern A. Zeeb seq_printf(m, "%8.8x ", 5022774f206SBjoern A. Zeeb rtw_read32(rtwdev, (page | n))); 5032774f206SBjoern A. Zeeb } 5042774f206SBjoern A. Zeeb seq_puts(m, "\n"); 5052774f206SBjoern A. Zeeb return 0; 5062774f206SBjoern A. Zeeb } 5072774f206SBjoern A. Zeeb 5082774f206SBjoern A. Zeeb static int rtw_debug_get_bb_page(struct seq_file *m, void *v) 5092774f206SBjoern A. Zeeb { 5102774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 5112774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 5122774f206SBjoern A. Zeeb u32 page = debugfs_priv->cb_data; 5132774f206SBjoern A. Zeeb int i, n; 5142774f206SBjoern A. Zeeb int max = 0xff; 5152774f206SBjoern A. Zeeb 5162774f206SBjoern A. Zeeb rtw_read32(rtwdev, debugfs_priv->cb_data); 5172774f206SBjoern A. Zeeb for (n = 0; n <= max; ) { 5182774f206SBjoern A. Zeeb seq_printf(m, "\n%8.8x ", n + page); 5192774f206SBjoern A. Zeeb for (i = 0; i < 4 && n <= max; i++, n += 4) 5202774f206SBjoern A. Zeeb seq_printf(m, "%8.8x ", 5212774f206SBjoern A. Zeeb rtw_read32(rtwdev, (page | n))); 5222774f206SBjoern A. Zeeb } 5232774f206SBjoern A. Zeeb seq_puts(m, "\n"); 5242774f206SBjoern A. Zeeb return 0; 5252774f206SBjoern A. Zeeb } 5262774f206SBjoern A. Zeeb 5272774f206SBjoern A. Zeeb static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) 5282774f206SBjoern A. Zeeb { 5292774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 5302774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 5312774f206SBjoern A. Zeeb u32 addr, offset, data; 5322774f206SBjoern A. Zeeb u8 path; 5332774f206SBjoern A. Zeeb 53490aac0d8SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 53590aac0d8SBjoern A. Zeeb 5362774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 5372774f206SBjoern A. Zeeb seq_printf(m, "RF path:%d\n", path); 5382774f206SBjoern A. Zeeb for (addr = 0; addr < 0x100; addr += 4) { 5392774f206SBjoern A. Zeeb seq_printf(m, "%8.8x ", addr); 5402774f206SBjoern A. Zeeb for (offset = 0; offset < 4; offset++) { 5412774f206SBjoern A. Zeeb data = rtw_read_rf(rtwdev, path, addr + offset, 5422774f206SBjoern A. Zeeb 0xffffffff); 5432774f206SBjoern A. Zeeb seq_printf(m, "%8.8x ", data); 5442774f206SBjoern A. Zeeb } 5452774f206SBjoern A. Zeeb seq_puts(m, "\n"); 5462774f206SBjoern A. Zeeb } 5472774f206SBjoern A. Zeeb seq_puts(m, "\n"); 5482774f206SBjoern A. Zeeb } 5492774f206SBjoern A. Zeeb 55090aac0d8SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 55190aac0d8SBjoern A. Zeeb 5522774f206SBjoern A. Zeeb return 0; 5532774f206SBjoern A. Zeeb } 5542774f206SBjoern A. Zeeb 5552774f206SBjoern A. Zeeb static void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate) 5562774f206SBjoern A. Zeeb { 5572774f206SBjoern A. Zeeb static const char * const 5582774f206SBjoern A. Zeeb cck_rate[] = {"1M", "2M", "5.5M", "11M"}; 5592774f206SBjoern A. Zeeb u8 idx = rate - DESC_RATE1M; 5602774f206SBjoern A. Zeeb 5612774f206SBjoern A. Zeeb seq_printf(m, " CCK_%-5s", cck_rate[idx]); 5622774f206SBjoern A. Zeeb } 5632774f206SBjoern A. Zeeb 5642774f206SBjoern A. Zeeb static void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate) 5652774f206SBjoern A. Zeeb { 5662774f206SBjoern A. Zeeb static const char * const 5672774f206SBjoern A. Zeeb ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"}; 5682774f206SBjoern A. Zeeb u8 idx = rate - DESC_RATE6M; 5692774f206SBjoern A. Zeeb 5702774f206SBjoern A. Zeeb seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]); 5712774f206SBjoern A. Zeeb } 5722774f206SBjoern A. Zeeb 5732774f206SBjoern A. Zeeb static void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate) 5742774f206SBjoern A. Zeeb { 5752774f206SBjoern A. Zeeb u8 mcs_n = rate - DESC_RATEMCS0; 5762774f206SBjoern A. Zeeb 5772774f206SBjoern A. Zeeb seq_printf(m, " MCS%-6u", mcs_n); 5782774f206SBjoern A. Zeeb } 5792774f206SBjoern A. Zeeb 5802774f206SBjoern A. Zeeb static void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate) 5812774f206SBjoern A. Zeeb { 5822774f206SBjoern A. Zeeb u8 idx = rate - DESC_RATEVHT1SS_MCS0; 5832774f206SBjoern A. Zeeb u8 n_ss, mcs_n; 5842774f206SBjoern A. Zeeb 5852774f206SBjoern A. Zeeb /* n spatial stream */ 5862774f206SBjoern A. Zeeb n_ss = 1 + idx / 10; 5872774f206SBjoern A. Zeeb /* MCS n */ 5882774f206SBjoern A. Zeeb mcs_n = idx % 10; 5892774f206SBjoern A. Zeeb seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); 5902774f206SBjoern A. Zeeb } 5912774f206SBjoern A. Zeeb 5922774f206SBjoern A. Zeeb static void rtw_print_rate(struct seq_file *m, u8 rate) 5932774f206SBjoern A. Zeeb { 5942774f206SBjoern A. Zeeb switch (rate) { 5952774f206SBjoern A. Zeeb case DESC_RATE1M...DESC_RATE11M: 5962774f206SBjoern A. Zeeb rtw_print_cck_rate_txt(m, rate); 5972774f206SBjoern A. Zeeb break; 5982774f206SBjoern A. Zeeb case DESC_RATE6M...DESC_RATE54M: 5992774f206SBjoern A. Zeeb rtw_print_ofdm_rate_txt(m, rate); 6002774f206SBjoern A. Zeeb break; 6012774f206SBjoern A. Zeeb case DESC_RATEMCS0...DESC_RATEMCS15: 6022774f206SBjoern A. Zeeb rtw_print_ht_rate_txt(m, rate); 6032774f206SBjoern A. Zeeb break; 6042774f206SBjoern A. Zeeb case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: 6052774f206SBjoern A. Zeeb rtw_print_vht_rate_txt(m, rate); 6062774f206SBjoern A. Zeeb break; 6072774f206SBjoern A. Zeeb default: 6082774f206SBjoern A. Zeeb seq_printf(m, " Unknown rate=0x%x\n", rate); 6092774f206SBjoern A. Zeeb break; 6102774f206SBjoern A. Zeeb } 6112774f206SBjoern A. Zeeb } 6122774f206SBjoern A. Zeeb 6132774f206SBjoern A. Zeeb #define case_REGD(src) \ 6142774f206SBjoern A. Zeeb case RTW_REGD_##src: return #src 6152774f206SBjoern A. Zeeb 6162774f206SBjoern A. Zeeb static const char *rtw_get_regd_string(u8 regd) 6172774f206SBjoern A. Zeeb { 6182774f206SBjoern A. Zeeb switch (regd) { 6192774f206SBjoern A. Zeeb case_REGD(FCC); 6202774f206SBjoern A. Zeeb case_REGD(MKK); 6212774f206SBjoern A. Zeeb case_REGD(ETSI); 6222774f206SBjoern A. Zeeb case_REGD(IC); 6232774f206SBjoern A. Zeeb case_REGD(KCC); 6242774f206SBjoern A. Zeeb case_REGD(ACMA); 6252774f206SBjoern A. Zeeb case_REGD(CHILE); 6262774f206SBjoern A. Zeeb case_REGD(UKRAINE); 6272774f206SBjoern A. Zeeb case_REGD(MEXICO); 6282774f206SBjoern A. Zeeb case_REGD(CN); 6292774f206SBjoern A. Zeeb case_REGD(WW); 6302774f206SBjoern A. Zeeb default: 6312774f206SBjoern A. Zeeb return "Unknown"; 6322774f206SBjoern A. Zeeb } 6332774f206SBjoern A. Zeeb } 6342774f206SBjoern A. Zeeb 6352774f206SBjoern A. Zeeb static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) 6362774f206SBjoern A. Zeeb { 6372774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 6382774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6392774f206SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 64090aac0d8SBjoern A. Zeeb u8 path, rate, bw, ch, regd; 6412774f206SBjoern A. Zeeb struct rtw_power_params pwr_param = {0}; 64290aac0d8SBjoern A. Zeeb 64390aac0d8SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 64490aac0d8SBjoern A. Zeeb bw = hal->current_band_width; 64590aac0d8SBjoern A. Zeeb ch = hal->current_channel; 64690aac0d8SBjoern A. Zeeb regd = rtw_regd_get(rtwdev); 6472774f206SBjoern A. Zeeb 6482774f206SBjoern A. Zeeb seq_printf(m, "channel: %u\n", ch); 6492774f206SBjoern A. Zeeb seq_printf(m, "bandwidth: %u\n", bw); 6502774f206SBjoern A. Zeeb seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd)); 6512774f206SBjoern A. Zeeb seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n", 6522774f206SBjoern A. Zeeb "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem"); 6532774f206SBjoern A. Zeeb 6542774f206SBjoern A. Zeeb mutex_lock(&hal->tx_power_mutex); 6552774f206SBjoern A. Zeeb for (path = RF_PATH_A; path <= RF_PATH_B; path++) { 6562774f206SBjoern A. Zeeb /* there is no CCK rates used in 5G */ 6572774f206SBjoern A. Zeeb if (hal->current_band_type == RTW_BAND_5G) 6582774f206SBjoern A. Zeeb rate = DESC_RATE6M; 6592774f206SBjoern A. Zeeb else 6602774f206SBjoern A. Zeeb rate = DESC_RATE1M; 6612774f206SBjoern A. Zeeb 6622774f206SBjoern A. Zeeb /* now, not support vht 3ss and vht 4ss*/ 6632774f206SBjoern A. Zeeb for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) { 6642774f206SBjoern A. Zeeb /* now, not support ht 3ss and ht 4ss*/ 6652774f206SBjoern A. Zeeb if (rate > DESC_RATEMCS15 && 6662774f206SBjoern A. Zeeb rate < DESC_RATEVHT1SS_MCS0) 6672774f206SBjoern A. Zeeb continue; 6682774f206SBjoern A. Zeeb 6692774f206SBjoern A. Zeeb rtw_get_tx_power_params(rtwdev, path, rate, bw, 6702774f206SBjoern A. Zeeb ch, regd, &pwr_param); 6712774f206SBjoern A. Zeeb 6722774f206SBjoern A. Zeeb seq_printf(m, "%4c ", path + 'A'); 6732774f206SBjoern A. Zeeb rtw_print_rate(m, rate); 6742774f206SBjoern A. Zeeb seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d) %4d\n", 6752774f206SBjoern A. Zeeb hal->tx_pwr_tbl[path][rate], 6762774f206SBjoern A. Zeeb hal->tx_pwr_tbl[path][rate], 6772774f206SBjoern A. Zeeb pwr_param.pwr_base, 6782774f206SBjoern A. Zeeb min3(pwr_param.pwr_offset, 6792774f206SBjoern A. Zeeb pwr_param.pwr_limit, 6802774f206SBjoern A. Zeeb pwr_param.pwr_sar), 6812774f206SBjoern A. Zeeb pwr_param.pwr_offset, pwr_param.pwr_limit, 6822774f206SBjoern A. Zeeb pwr_param.pwr_sar, 6832774f206SBjoern A. Zeeb pwr_param.pwr_remnant); 6842774f206SBjoern A. Zeeb } 6852774f206SBjoern A. Zeeb } 6862774f206SBjoern A. Zeeb 6872774f206SBjoern A. Zeeb mutex_unlock(&hal->tx_power_mutex); 68890aac0d8SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 6892774f206SBjoern A. Zeeb 6902774f206SBjoern A. Zeeb return 0; 6912774f206SBjoern A. Zeeb } 6922774f206SBjoern A. Zeeb 6932774f206SBjoern A. Zeeb void rtw_debugfs_get_simple_phy_info(struct seq_file *m) 6942774f206SBjoern A. Zeeb { 6952774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 6962774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6972774f206SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 6982774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 6992774f206SBjoern A. Zeeb struct rtw_traffic_stats *stats = &rtwdev->stats; 7002774f206SBjoern A. Zeeb 7012774f206SBjoern A. Zeeb seq_printf(m, "%-40s = %ddBm/ %d\n", "RSSI/ STA Channel", 7022774f206SBjoern A. Zeeb dm_info->rssi[RF_PATH_A] - 100, hal->current_channel); 7032774f206SBjoern A. Zeeb 7042774f206SBjoern A. Zeeb seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 7052774f206SBjoern A. Zeeb stats->tx_throughput, stats->rx_throughput); 7062774f206SBjoern A. Zeeb 7072774f206SBjoern A. Zeeb seq_puts(m, "[Tx Rate] = "); 7082774f206SBjoern A. Zeeb rtw_print_rate(m, dm_info->tx_rate); 7092774f206SBjoern A. Zeeb seq_printf(m, "(0x%x)\n", dm_info->tx_rate); 7102774f206SBjoern A. Zeeb 7112774f206SBjoern A. Zeeb seq_puts(m, "[Rx Rate] = "); 7122774f206SBjoern A. Zeeb rtw_print_rate(m, dm_info->curr_rx_rate); 7132774f206SBjoern A. Zeeb seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 7142774f206SBjoern A. Zeeb } 7152774f206SBjoern A. Zeeb 7162774f206SBjoern A. Zeeb static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) 7172774f206SBjoern A. Zeeb { 7182774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 7192774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 7202774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 7212774f206SBjoern A. Zeeb struct rtw_traffic_stats *stats = &rtwdev->stats; 7222774f206SBjoern A. Zeeb struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; 7232774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 7242774f206SBjoern A. Zeeb struct ewma_evm *ewma_evm = dm_info->ewma_evm; 7252774f206SBjoern A. Zeeb struct ewma_snr *ewma_snr = dm_info->ewma_snr; 7262774f206SBjoern A. Zeeb u8 ss, rate_id; 7272774f206SBjoern A. Zeeb 7282774f206SBjoern A. Zeeb seq_puts(m, "==========[Common Info]========\n"); 7292774f206SBjoern A. Zeeb seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); 7302774f206SBjoern A. Zeeb seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); 7312774f206SBjoern A. Zeeb seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); 7322774f206SBjoern A. Zeeb seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); 7339c951734SBjoern A. Zeeb seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 7342774f206SBjoern A. Zeeb stats->tx_throughput, stats->rx_throughput); 7359c951734SBjoern A. Zeeb seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ? 7369c951734SBjoern A. Zeeb 'Y' : 'N'); 7372774f206SBjoern A. Zeeb 7382774f206SBjoern A. Zeeb seq_puts(m, "==========[Tx Phy Info]========\n"); 7392774f206SBjoern A. Zeeb seq_puts(m, "[Tx Rate] = "); 7402774f206SBjoern A. Zeeb rtw_print_rate(m, dm_info->tx_rate); 7412774f206SBjoern A. Zeeb seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); 7422774f206SBjoern A. Zeeb 7432774f206SBjoern A. Zeeb seq_puts(m, "==========[Rx Phy Info]========\n"); 7442774f206SBjoern A. Zeeb seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); 7452774f206SBjoern A. Zeeb seq_puts(m, "[Rx Rate] = "); 7462774f206SBjoern A. Zeeb rtw_print_rate(m, dm_info->curr_rx_rate); 7472774f206SBjoern A. Zeeb seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 7482774f206SBjoern A. Zeeb 7492774f206SBjoern A. Zeeb seq_puts(m, "[Rx Rate Count]:\n"); 7502774f206SBjoern A. Zeeb seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", 7512774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE1M], 7522774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE2M], 7532774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE5_5M], 7542774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE11M]); 7552774f206SBjoern A. Zeeb 7562774f206SBjoern A. Zeeb seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 7572774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE6M], 7582774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE9M], 7592774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE12M], 7602774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE18M], 7612774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE24M], 7622774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE36M], 7632774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE48M], 7642774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[DESC_RATE54M]); 7652774f206SBjoern A. Zeeb 7662774f206SBjoern A. Zeeb for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 7672774f206SBjoern A. Zeeb rate_id = DESC_RATEMCS0 + ss * 8; 7682774f206SBjoern A. Zeeb seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 7692774f206SBjoern A. Zeeb ss * 8, ss * 8 + 7, 7702774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id], 7712774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 1], 7722774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 2], 7732774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 3], 7742774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 4], 7752774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 5], 7762774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 6], 7772774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 7]); 7782774f206SBjoern A. Zeeb } 7792774f206SBjoern A. Zeeb 7802774f206SBjoern A. Zeeb for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 7812774f206SBjoern A. Zeeb rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; 7822774f206SBjoern A. Zeeb seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", 7832774f206SBjoern A. Zeeb ss + 1, 7842774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id], 7852774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 1], 7862774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 2], 7872774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 3], 7882774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 4], 7892774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 5], 7902774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 6], 7912774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 7], 7922774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 8], 7932774f206SBjoern A. Zeeb last_cnt->num_qry_pkt[rate_id + 9]); 7942774f206SBjoern A. Zeeb } 7952774f206SBjoern A. Zeeb 7962774f206SBjoern A. Zeeb seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", 7972774f206SBjoern A. Zeeb dm_info->rssi[RF_PATH_A] - 100, 7982774f206SBjoern A. Zeeb dm_info->rssi[RF_PATH_B] - 100); 7992774f206SBjoern A. Zeeb seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", 8002774f206SBjoern A. Zeeb dm_info->rx_evm_dbm[RF_PATH_A], 8012774f206SBjoern A. Zeeb dm_info->rx_evm_dbm[RF_PATH_B]); 8022774f206SBjoern A. Zeeb seq_printf(m, "[Rx SNR] = {%d, %d}\n", 8032774f206SBjoern A. Zeeb dm_info->rx_snr[RF_PATH_A], 8042774f206SBjoern A. Zeeb dm_info->rx_snr[RF_PATH_B]); 8052774f206SBjoern A. Zeeb seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", 8062774f206SBjoern A. Zeeb dm_info->cfo_tail[RF_PATH_A], 8072774f206SBjoern A. Zeeb dm_info->cfo_tail[RF_PATH_B]); 8082774f206SBjoern A. Zeeb 8092774f206SBjoern A. Zeeb if (dm_info->curr_rx_rate >= DESC_RATE11M) { 8102774f206SBjoern A. Zeeb seq_puts(m, "[Rx Average Status]:\n"); 8112774f206SBjoern A. Zeeb seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", 8122774f206SBjoern A. Zeeb (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), 8132774f206SBjoern A. Zeeb (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); 8142774f206SBjoern A. Zeeb seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", 8152774f206SBjoern A. Zeeb (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), 8162774f206SBjoern A. Zeeb (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); 8172774f206SBjoern A. Zeeb seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", 8182774f206SBjoern A. Zeeb (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), 8192774f206SBjoern A. Zeeb (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), 8202774f206SBjoern A. Zeeb (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), 8212774f206SBjoern A. Zeeb (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); 8222774f206SBjoern A. Zeeb } 8232774f206SBjoern A. Zeeb 8242774f206SBjoern A. Zeeb seq_puts(m, "[Rx Counter]:\n"); 8252774f206SBjoern A. Zeeb seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", 8262774f206SBjoern A. Zeeb dm_info->cck_cca_cnt, 8272774f206SBjoern A. Zeeb dm_info->ofdm_cca_cnt, 8282774f206SBjoern A. Zeeb dm_info->total_cca_cnt); 8292774f206SBjoern A. Zeeb seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", 8302774f206SBjoern A. Zeeb dm_info->cck_fa_cnt, 8312774f206SBjoern A. Zeeb dm_info->ofdm_fa_cnt, 8322774f206SBjoern A. Zeeb dm_info->total_fa_cnt); 8332774f206SBjoern A. Zeeb seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", 8342774f206SBjoern A. Zeeb dm_info->cck_ok_cnt, dm_info->cck_err_cnt); 8352774f206SBjoern A. Zeeb seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", 8362774f206SBjoern A. Zeeb dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); 8372774f206SBjoern A. Zeeb seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", 8382774f206SBjoern A. Zeeb dm_info->ht_ok_cnt, dm_info->ht_err_cnt); 8392774f206SBjoern A. Zeeb seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", 8402774f206SBjoern A. Zeeb dm_info->vht_ok_cnt, dm_info->vht_err_cnt); 8412774f206SBjoern A. Zeeb 8422774f206SBjoern A. Zeeb return 0; 8432774f206SBjoern A. Zeeb } 8442774f206SBjoern A. Zeeb 8452774f206SBjoern A. Zeeb static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) 8462774f206SBjoern A. Zeeb { 8472774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 8482774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8492774f206SBjoern A. Zeeb 85090aac0d8SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 8512774f206SBjoern A. Zeeb rtw_coex_display_coex_info(rtwdev, m); 85290aac0d8SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 8532774f206SBjoern A. Zeeb 8542774f206SBjoern A. Zeeb return 0; 8552774f206SBjoern A. Zeeb } 8562774f206SBjoern A. Zeeb 8572774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, 8582774f206SBjoern A. Zeeb const char __user *buffer, 8592774f206SBjoern A. Zeeb size_t count, loff_t *loff) 8602774f206SBjoern A. Zeeb { 8612774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 8622774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 8632774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8642774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 8652774f206SBjoern A. Zeeb bool enable; 8662774f206SBjoern A. Zeeb int ret; 8672774f206SBjoern A. Zeeb 868*11c53278SBjoern A. Zeeb ret = kstrtobool_from_user(buffer, count, &enable); 86990aac0d8SBjoern A. Zeeb if (ret) 87090aac0d8SBjoern A. Zeeb return ret; 8712774f206SBjoern A. Zeeb 8722774f206SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 8732774f206SBjoern A. Zeeb coex->manual_control = !enable; 8742774f206SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 8752774f206SBjoern A. Zeeb 8762774f206SBjoern A. Zeeb return count; 8772774f206SBjoern A. Zeeb } 8782774f206SBjoern A. Zeeb 8792774f206SBjoern A. Zeeb static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) 8802774f206SBjoern A. Zeeb { 8812774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 8822774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8832774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 8842774f206SBjoern A. Zeeb 8852774f206SBjoern A. Zeeb seq_printf(m, "coex mechanism %s\n", 8862774f206SBjoern A. Zeeb coex->manual_control ? "disabled" : "enabled"); 8872774f206SBjoern A. Zeeb 8882774f206SBjoern A. Zeeb return 0; 8892774f206SBjoern A. Zeeb } 8902774f206SBjoern A. Zeeb 8912774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, 8922774f206SBjoern A. Zeeb const char __user *buffer, 8932774f206SBjoern A. Zeeb size_t count, loff_t *loff) 8942774f206SBjoern A. Zeeb { 8952774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 8962774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 8972774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8982774f206SBjoern A. Zeeb bool input; 8992774f206SBjoern A. Zeeb int err; 9002774f206SBjoern A. Zeeb 9012774f206SBjoern A. Zeeb err = kstrtobool_from_user(buffer, count, &input); 9022774f206SBjoern A. Zeeb if (err) 9032774f206SBjoern A. Zeeb return err; 9042774f206SBjoern A. Zeeb 9052774f206SBjoern A. Zeeb rtw_edcca_enabled = input; 9062774f206SBjoern A. Zeeb rtw_phy_adaptivity_set_mode(rtwdev); 9072774f206SBjoern A. Zeeb 9082774f206SBjoern A. Zeeb return count; 9092774f206SBjoern A. Zeeb } 9102774f206SBjoern A. Zeeb 9112774f206SBjoern A. Zeeb static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v) 9122774f206SBjoern A. Zeeb { 9132774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 9142774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9152774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 9162774f206SBjoern A. Zeeb 9172774f206SBjoern A. Zeeb seq_printf(m, "EDCCA %s: EDCCA mode %d\n", 9182774f206SBjoern A. Zeeb rtw_edcca_enabled ? "enabled" : "disabled", 9192774f206SBjoern A. Zeeb dm_info->edcca_mode); 9202774f206SBjoern A. Zeeb return 0; 9212774f206SBjoern A. Zeeb } 9222774f206SBjoern A. Zeeb 9232774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_fw_crash(struct file *filp, 9242774f206SBjoern A. Zeeb const char __user *buffer, 9252774f206SBjoern A. Zeeb size_t count, loff_t *loff) 9262774f206SBjoern A. Zeeb { 9272774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 9282774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 9292774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9302774f206SBjoern A. Zeeb bool input; 9312774f206SBjoern A. Zeeb int ret; 9322774f206SBjoern A. Zeeb 933*11c53278SBjoern A. Zeeb ret = kstrtobool_from_user(buffer, count, &input); 93490aac0d8SBjoern A. Zeeb if (ret) 93590aac0d8SBjoern A. Zeeb return ret; 9362774f206SBjoern A. Zeeb 9372774f206SBjoern A. Zeeb if (!input) 9382774f206SBjoern A. Zeeb return -EINVAL; 9392774f206SBjoern A. Zeeb 9402774f206SBjoern A. Zeeb if (test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) 9412774f206SBjoern A. Zeeb return -EINPROGRESS; 9422774f206SBjoern A. Zeeb 9432774f206SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 9442774f206SBjoern A. Zeeb rtw_leave_lps_deep(rtwdev); 9452774f206SBjoern A. Zeeb set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags); 9462774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_HRCV_MSG, 1); 9472774f206SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 9482774f206SBjoern A. Zeeb 9492774f206SBjoern A. Zeeb return count; 9502774f206SBjoern A. Zeeb } 9512774f206SBjoern A. Zeeb 9522774f206SBjoern A. Zeeb static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v) 9532774f206SBjoern A. Zeeb { 9542774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 9552774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9562774f206SBjoern A. Zeeb 9572774f206SBjoern A. Zeeb seq_printf(m, "%d\n", 9582774f206SBjoern A. Zeeb test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) || 9592774f206SBjoern A. Zeeb test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)); 9602774f206SBjoern A. Zeeb return 0; 9612774f206SBjoern A. Zeeb } 9622774f206SBjoern A. Zeeb 9632774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_force_lowest_basic_rate(struct file *filp, 9642774f206SBjoern A. Zeeb const char __user *buffer, 9652774f206SBjoern A. Zeeb size_t count, loff_t *loff) 9662774f206SBjoern A. Zeeb { 9672774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 9682774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 9692774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9702774f206SBjoern A. Zeeb bool input; 9712774f206SBjoern A. Zeeb int err; 9722774f206SBjoern A. Zeeb 9732774f206SBjoern A. Zeeb err = kstrtobool_from_user(buffer, count, &input); 9742774f206SBjoern A. Zeeb if (err) 9752774f206SBjoern A. Zeeb return err; 9762774f206SBjoern A. Zeeb 9772774f206SBjoern A. Zeeb if (input) 9782774f206SBjoern A. Zeeb set_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 9792774f206SBjoern A. Zeeb else 9802774f206SBjoern A. Zeeb clear_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 9812774f206SBjoern A. Zeeb 9822774f206SBjoern A. Zeeb return count; 9832774f206SBjoern A. Zeeb } 9842774f206SBjoern A. Zeeb 9852774f206SBjoern A. Zeeb static int rtw_debugfs_get_force_lowest_basic_rate(struct seq_file *m, void *v) 9862774f206SBjoern A. Zeeb { 9872774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 9882774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9892774f206SBjoern A. Zeeb 9902774f206SBjoern A. Zeeb seq_printf(m, "force lowest basic rate: %d\n", 9912774f206SBjoern A. Zeeb test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags)); 9922774f206SBjoern A. Zeeb 9932774f206SBjoern A. Zeeb return 0; 9942774f206SBjoern A. Zeeb } 9952774f206SBjoern A. Zeeb 9962774f206SBjoern A. Zeeb static ssize_t rtw_debugfs_set_dm_cap(struct file *filp, 9972774f206SBjoern A. Zeeb const char __user *buffer, 9982774f206SBjoern A. Zeeb size_t count, loff_t *loff) 9992774f206SBjoern A. Zeeb { 10002774f206SBjoern A. Zeeb struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 10012774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 10022774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 10032774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1004*11c53278SBjoern A. Zeeb int ret, bit; 10052774f206SBjoern A. Zeeb bool en; 10062774f206SBjoern A. Zeeb 1007*11c53278SBjoern A. Zeeb ret = kstrtoint_from_user(buffer, count, 10, &bit); 1008*11c53278SBjoern A. Zeeb if (ret) 1009*11c53278SBjoern A. Zeeb return ret; 10102774f206SBjoern A. Zeeb 10112774f206SBjoern A. Zeeb en = bit > 0; 10122774f206SBjoern A. Zeeb bit = abs(bit); 10132774f206SBjoern A. Zeeb 10142774f206SBjoern A. Zeeb if (bit >= RTW_DM_CAP_NUM) { 10152774f206SBjoern A. Zeeb rtw_warn(rtwdev, "unknown DM CAP %d\n", bit); 10162774f206SBjoern A. Zeeb return -EINVAL; 10172774f206SBjoern A. Zeeb } 10182774f206SBjoern A. Zeeb 10192774f206SBjoern A. Zeeb if (en) 10202774f206SBjoern A. Zeeb dm_info->dm_flags &= ~BIT(bit); 10212774f206SBjoern A. Zeeb else 10222774f206SBjoern A. Zeeb dm_info->dm_flags |= BIT(bit); 10232774f206SBjoern A. Zeeb 10242774f206SBjoern A. Zeeb debugfs_priv->dm_cap.bit = bit; 10252774f206SBjoern A. Zeeb 10262774f206SBjoern A. Zeeb return count; 10272774f206SBjoern A. Zeeb } 10282774f206SBjoern A. Zeeb 10292774f206SBjoern A. Zeeb static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) 10302774f206SBjoern A. Zeeb { 10312774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10322774f206SBjoern A. Zeeb struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 10332774f206SBjoern A. Zeeb int i, path; 10342774f206SBjoern A. Zeeb u32 val; 10352774f206SBjoern A. Zeeb 10362774f206SBjoern A. Zeeb seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK, 10372774f206SBjoern A. Zeeb dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', 10382774f206SBjoern A. Zeeb rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); 10392774f206SBjoern A. Zeeb 104090aac0d8SBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 104190aac0d8SBjoern A. Zeeb 10422774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 10432774f206SBjoern A. Zeeb val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); 10442774f206SBjoern A. Zeeb seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); 10452774f206SBjoern A. Zeeb 10462774f206SBjoern A. Zeeb for (i = 0; i < RF_HW_OFFSET_NUM; i++) 10472774f206SBjoern A. Zeeb seq_printf(m, "[TXGAPK] offset %d %d\n", 10482774f206SBjoern A. Zeeb txgapk->rf3f_fs[path][i], i); 10492774f206SBjoern A. Zeeb seq_puts(m, "\n"); 10502774f206SBjoern A. Zeeb } 105190aac0d8SBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 10522774f206SBjoern A. Zeeb } 10532774f206SBjoern A. Zeeb 10542774f206SBjoern A. Zeeb static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) 10552774f206SBjoern A. Zeeb { 10562774f206SBjoern A. Zeeb struct rtw_debugfs_priv *debugfs_priv = m->private; 10572774f206SBjoern A. Zeeb struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 10582774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10592774f206SBjoern A. Zeeb int i; 10602774f206SBjoern A. Zeeb 10612774f206SBjoern A. Zeeb switch (debugfs_priv->dm_cap.bit) { 10622774f206SBjoern A. Zeeb case RTW_DM_CAP_TXGAPK: 10632774f206SBjoern A. Zeeb dump_gapk_status(rtwdev, m); 10642774f206SBjoern A. Zeeb break; 10652774f206SBjoern A. Zeeb default: 10662774f206SBjoern A. Zeeb for (i = 1; i < RTW_DM_CAP_NUM; i++) { 10672774f206SBjoern A. Zeeb seq_printf(m, "(%2d) %c%s\n", i, 10682774f206SBjoern A. Zeeb dm_info->dm_flags & BIT(i) ? '-' : '+', 10692774f206SBjoern A. Zeeb rtw_dm_cap_strs[i]); 10702774f206SBjoern A. Zeeb } 10712774f206SBjoern A. Zeeb break; 10722774f206SBjoern A. Zeeb } 10732774f206SBjoern A. Zeeb debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA; 10742774f206SBjoern A. Zeeb return 0; 10752774f206SBjoern A. Zeeb } 10762774f206SBjoern A. Zeeb 10772774f206SBjoern A. Zeeb #define rtw_debug_impl_mac(page, addr) \ 10782774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ 10792774f206SBjoern A. Zeeb .cb_read = rtw_debug_get_mac_page, \ 10802774f206SBjoern A. Zeeb .cb_data = addr, \ 10812774f206SBjoern A. Zeeb } 10822774f206SBjoern A. Zeeb 10832774f206SBjoern A. Zeeb rtw_debug_impl_mac(0, 0x0000); 10842774f206SBjoern A. Zeeb rtw_debug_impl_mac(1, 0x0100); 10852774f206SBjoern A. Zeeb rtw_debug_impl_mac(2, 0x0200); 10862774f206SBjoern A. Zeeb rtw_debug_impl_mac(3, 0x0300); 10872774f206SBjoern A. Zeeb rtw_debug_impl_mac(4, 0x0400); 10882774f206SBjoern A. Zeeb rtw_debug_impl_mac(5, 0x0500); 10892774f206SBjoern A. Zeeb rtw_debug_impl_mac(6, 0x0600); 10902774f206SBjoern A. Zeeb rtw_debug_impl_mac(7, 0x0700); 10912774f206SBjoern A. Zeeb rtw_debug_impl_mac(10, 0x1000); 10922774f206SBjoern A. Zeeb rtw_debug_impl_mac(11, 0x1100); 10932774f206SBjoern A. Zeeb rtw_debug_impl_mac(12, 0x1200); 10942774f206SBjoern A. Zeeb rtw_debug_impl_mac(13, 0x1300); 10952774f206SBjoern A. Zeeb rtw_debug_impl_mac(14, 0x1400); 10962774f206SBjoern A. Zeeb rtw_debug_impl_mac(15, 0x1500); 10972774f206SBjoern A. Zeeb rtw_debug_impl_mac(16, 0x1600); 10982774f206SBjoern A. Zeeb rtw_debug_impl_mac(17, 0x1700); 10992774f206SBjoern A. Zeeb 11002774f206SBjoern A. Zeeb #define rtw_debug_impl_bb(page, addr) \ 11012774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \ 11022774f206SBjoern A. Zeeb .cb_read = rtw_debug_get_bb_page, \ 11032774f206SBjoern A. Zeeb .cb_data = addr, \ 11042774f206SBjoern A. Zeeb } 11052774f206SBjoern A. Zeeb 11062774f206SBjoern A. Zeeb rtw_debug_impl_bb(8, 0x0800); 11072774f206SBjoern A. Zeeb rtw_debug_impl_bb(9, 0x0900); 11082774f206SBjoern A. Zeeb rtw_debug_impl_bb(a, 0x0a00); 11092774f206SBjoern A. Zeeb rtw_debug_impl_bb(b, 0x0b00); 11102774f206SBjoern A. Zeeb rtw_debug_impl_bb(c, 0x0c00); 11112774f206SBjoern A. Zeeb rtw_debug_impl_bb(d, 0x0d00); 11122774f206SBjoern A. Zeeb rtw_debug_impl_bb(e, 0x0e00); 11132774f206SBjoern A. Zeeb rtw_debug_impl_bb(f, 0x0f00); 11142774f206SBjoern A. Zeeb rtw_debug_impl_bb(18, 0x1800); 11152774f206SBjoern A. Zeeb rtw_debug_impl_bb(19, 0x1900); 11162774f206SBjoern A. Zeeb rtw_debug_impl_bb(1a, 0x1a00); 11172774f206SBjoern A. Zeeb rtw_debug_impl_bb(1b, 0x1b00); 11182774f206SBjoern A. Zeeb rtw_debug_impl_bb(1c, 0x1c00); 11192774f206SBjoern A. Zeeb rtw_debug_impl_bb(1d, 0x1d00); 11202774f206SBjoern A. Zeeb rtw_debug_impl_bb(1e, 0x1e00); 11212774f206SBjoern A. Zeeb rtw_debug_impl_bb(1f, 0x1f00); 11222774f206SBjoern A. Zeeb rtw_debug_impl_bb(2c, 0x2c00); 11232774f206SBjoern A. Zeeb rtw_debug_impl_bb(2d, 0x2d00); 11242774f206SBjoern A. Zeeb rtw_debug_impl_bb(40, 0x4000); 11252774f206SBjoern A. Zeeb rtw_debug_impl_bb(41, 0x4100); 11262774f206SBjoern A. Zeeb 11272774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = { 11282774f206SBjoern A. Zeeb .cb_read = rtw_debug_get_rf_dump, 11292774f206SBjoern A. Zeeb }; 11302774f206SBjoern A. Zeeb 11312774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = { 11322774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_tx_pwr_tbl, 11332774f206SBjoern A. Zeeb }; 11342774f206SBjoern A. Zeeb 11352774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_write_reg = { 11362774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_write_reg, 11372774f206SBjoern A. Zeeb }; 11382774f206SBjoern A. Zeeb 11392774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_h2c = { 11402774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_h2c, 11412774f206SBjoern A. Zeeb }; 11422774f206SBjoern A. Zeeb 11432774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_rf_write = { 11442774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_rf_write, 11452774f206SBjoern A. Zeeb }; 11462774f206SBjoern A. Zeeb 11472774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_rf_read = { 11482774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_rf_read, 11492774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_rf_read, 11502774f206SBjoern A. Zeeb }; 11512774f206SBjoern A. Zeeb 11522774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_read_reg = { 11532774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_read_reg, 11542774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_read_reg, 11552774f206SBjoern A. Zeeb }; 11562774f206SBjoern A. Zeeb 11572774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = { 11582774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_fix_rate, 11592774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_fix_rate, 11602774f206SBjoern A. Zeeb }; 11612774f206SBjoern A. Zeeb 11622774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = { 11632774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_single_input, 11642774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_dump_cam, 11652774f206SBjoern A. Zeeb }; 11662774f206SBjoern A. Zeeb 11672774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = { 11682774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_rsvd_page, 11692774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_rsvd_page, 11702774f206SBjoern A. Zeeb }; 11712774f206SBjoern A. Zeeb 11722774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { 11732774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_phy_info, 11742774f206SBjoern A. Zeeb }; 11752774f206SBjoern A. Zeeb 11762774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { 11772774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_coex_enable, 11782774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_coex_enable, 11792774f206SBjoern A. Zeeb }; 11802774f206SBjoern A. Zeeb 11812774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { 11822774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_coex_info, 11832774f206SBjoern A. Zeeb }; 11842774f206SBjoern A. Zeeb 11852774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { 11862774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_edcca_enable, 11872774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_edcca_enable, 11882774f206SBjoern A. Zeeb }; 11892774f206SBjoern A. Zeeb 11902774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { 11912774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_fw_crash, 11922774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_fw_crash, 11932774f206SBjoern A. Zeeb }; 11942774f206SBjoern A. Zeeb 11952774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = { 11962774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_force_lowest_basic_rate, 11972774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_force_lowest_basic_rate, 11982774f206SBjoern A. Zeeb }; 11992774f206SBjoern A. Zeeb 12002774f206SBjoern A. Zeeb static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { 12012774f206SBjoern A. Zeeb .cb_write = rtw_debugfs_set_dm_cap, 12022774f206SBjoern A. Zeeb .cb_read = rtw_debugfs_get_dm_cap, 12032774f206SBjoern A. Zeeb }; 12042774f206SBjoern A. Zeeb 12052774f206SBjoern A. Zeeb #define rtw_debugfs_add_core(name, mode, fopname, parent) \ 12062774f206SBjoern A. Zeeb do { \ 12072774f206SBjoern A. Zeeb rtw_debug_priv_ ##name.rtwdev = rtwdev; \ 1208*11c53278SBjoern A. Zeeb if (IS_ERR(debugfs_create_file(#name, mode, \ 12092774f206SBjoern A. Zeeb parent, &rtw_debug_priv_ ##name,\ 1210*11c53278SBjoern A. Zeeb &file_ops_ ##fopname))) \ 12112774f206SBjoern A. Zeeb pr_debug("Unable to initialize debugfs:%s\n", \ 12122774f206SBjoern A. Zeeb #name); \ 12132774f206SBjoern A. Zeeb } while (0) 12142774f206SBjoern A. Zeeb 12152774f206SBjoern A. Zeeb #define rtw_debugfs_add_w(name) \ 12162774f206SBjoern A. Zeeb rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir) 12172774f206SBjoern A. Zeeb #define rtw_debugfs_add_rw(name) \ 12182774f206SBjoern A. Zeeb rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir) 12192774f206SBjoern A. Zeeb #define rtw_debugfs_add_r(name) \ 12202774f206SBjoern A. Zeeb rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) 12212774f206SBjoern A. Zeeb 12222774f206SBjoern A. Zeeb void rtw_debugfs_init(struct rtw_dev *rtwdev) 12232774f206SBjoern A. Zeeb { 12242774f206SBjoern A. Zeeb struct dentry *debugfs_topdir; 12252774f206SBjoern A. Zeeb 12262774f206SBjoern A. Zeeb debugfs_topdir = debugfs_create_dir("rtw88", 12272774f206SBjoern A. Zeeb rtwdev->hw->wiphy->debugfsdir); 12282774f206SBjoern A. Zeeb rtw_debugfs_add_w(write_reg); 12292774f206SBjoern A. Zeeb rtw_debugfs_add_rw(read_reg); 12302774f206SBjoern A. Zeeb rtw_debugfs_add_w(rf_write); 12312774f206SBjoern A. Zeeb rtw_debugfs_add_rw(rf_read); 12322774f206SBjoern A. Zeeb rtw_debugfs_add_rw(fix_rate); 12332774f206SBjoern A. Zeeb rtw_debugfs_add_rw(dump_cam); 12342774f206SBjoern A. Zeeb rtw_debugfs_add_rw(rsvd_page); 12352774f206SBjoern A. Zeeb rtw_debugfs_add_r(phy_info); 12362774f206SBjoern A. Zeeb rtw_debugfs_add_r(coex_info); 12372774f206SBjoern A. Zeeb rtw_debugfs_add_rw(coex_enable); 12382774f206SBjoern A. Zeeb rtw_debugfs_add_w(h2c); 12392774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_0); 12402774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_1); 12412774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_2); 12422774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_3); 12432774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_4); 12442774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_5); 12452774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_6); 12462774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_7); 12472774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_8); 12482774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_9); 12492774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_a); 12502774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_b); 12512774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_c); 12522774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_d); 12532774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_e); 12542774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_f); 12552774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_10); 12562774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_11); 12572774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_12); 12582774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_13); 12592774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_14); 12602774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_15); 12612774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_16); 12622774f206SBjoern A. Zeeb rtw_debugfs_add_r(mac_17); 12632774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_18); 12642774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_19); 12652774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_1a); 12662774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_1b); 12672774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_1c); 12682774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_1d); 12692774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_1e); 12702774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_1f); 12712774f206SBjoern A. Zeeb if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { 12722774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_2c); 12732774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_2d); 12742774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_40); 12752774f206SBjoern A. Zeeb rtw_debugfs_add_r(bb_41); 12762774f206SBjoern A. Zeeb } 12772774f206SBjoern A. Zeeb rtw_debugfs_add_r(rf_dump); 12782774f206SBjoern A. Zeeb rtw_debugfs_add_r(tx_pwr_tbl); 12792774f206SBjoern A. Zeeb rtw_debugfs_add_rw(edcca_enable); 12802774f206SBjoern A. Zeeb rtw_debugfs_add_rw(fw_crash); 12812774f206SBjoern A. Zeeb rtw_debugfs_add_rw(force_lowest_basic_rate); 12822774f206SBjoern A. Zeeb rtw_debugfs_add_rw(dm_cap); 12832774f206SBjoern A. Zeeb } 12842774f206SBjoern A. Zeeb 12852774f206SBjoern A. Zeeb #endif /* CONFIG_RTW88_DEBUGFS */ 12862774f206SBjoern A. Zeeb 12872774f206SBjoern A. Zeeb #ifdef CONFIG_RTW88_DEBUG 12882774f206SBjoern A. Zeeb 1289*11c53278SBjoern A. Zeeb void rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, 12902774f206SBjoern A. Zeeb const char *fmt, ...) 12912774f206SBjoern A. Zeeb { 12922774f206SBjoern A. Zeeb struct va_format vaf = { 12932774f206SBjoern A. Zeeb .fmt = fmt, 12942774f206SBjoern A. Zeeb }; 12952774f206SBjoern A. Zeeb va_list args; 12962774f206SBjoern A. Zeeb 12972774f206SBjoern A. Zeeb va_start(args, fmt); 12982774f206SBjoern A. Zeeb vaf.va = &args; 12992774f206SBjoern A. Zeeb 13002774f206SBjoern A. Zeeb if (rtw_debug_mask & mask) 13012774f206SBjoern A. Zeeb #if defined(__linux__) 13022774f206SBjoern A. Zeeb dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); 13032774f206SBjoern A. Zeeb #elif defined(__FreeBSD__) 1304f621b087SBjoern A. Zeeb vlog(LOG_DEBUG, vaf.fmt, args); 13052774f206SBjoern A. Zeeb #endif 13062774f206SBjoern A. Zeeb 13072774f206SBjoern A. Zeeb va_end(args); 13082774f206SBjoern A. Zeeb } 1309*11c53278SBjoern A. Zeeb EXPORT_SYMBOL(rtw_dbg); 13102774f206SBjoern A. Zeeb 13112774f206SBjoern A. Zeeb #endif /* CONFIG_RTW88_DEBUG */ 1312