1e3037485SYan-Hsuan Chuang // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2e3037485SYan-Hsuan Chuang /* Copyright(c) 2018-2019 Realtek Corporation 3e3037485SYan-Hsuan Chuang */ 4e3037485SYan-Hsuan Chuang 5e3037485SYan-Hsuan Chuang #include <linux/debugfs.h> 6e3037485SYan-Hsuan Chuang #include <linux/seq_file.h> 7e3037485SYan-Hsuan Chuang #include "main.h" 81fe188daSYan-Hsuan Chuang #include "coex.h" 9e3037485SYan-Hsuan Chuang #include "sec.h" 10e3037485SYan-Hsuan Chuang #include "fw.h" 11e3037485SYan-Hsuan Chuang #include "debug.h" 128812022cSZong-Zhe Yang #include "phy.h" 1313ce240aSZong-Zhe Yang #include "reg.h" 147b80f3e4SZong-Zhe Yang #include "ps.h" 15f8509c38SZong-Zhe Yang #include "regd.h" 16e3037485SYan-Hsuan Chuang 17e3037485SYan-Hsuan Chuang #ifdef CONFIG_RTW88_DEBUGFS 18e3037485SYan-Hsuan Chuang 19e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv { 20e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev; 21e3037485SYan-Hsuan Chuang int (*cb_read)(struct seq_file *m, void *v); 22e3037485SYan-Hsuan Chuang ssize_t (*cb_write)(struct file *filp, const char __user *buffer, 23e3037485SYan-Hsuan Chuang size_t count, loff_t *loff); 24e3037485SYan-Hsuan Chuang union { 25e3037485SYan-Hsuan Chuang u32 cb_data; 26e3037485SYan-Hsuan Chuang u8 *buf; 27e3037485SYan-Hsuan Chuang struct { 28e3037485SYan-Hsuan Chuang u32 page_offset; 29e3037485SYan-Hsuan Chuang u32 page_num; 30e3037485SYan-Hsuan Chuang } rsvd_page; 31e3037485SYan-Hsuan Chuang struct { 32e3037485SYan-Hsuan Chuang u8 rf_path; 33e3037485SYan-Hsuan Chuang u32 rf_addr; 34e3037485SYan-Hsuan Chuang u32 rf_mask; 35e3037485SYan-Hsuan Chuang }; 36e3037485SYan-Hsuan Chuang struct { 37e3037485SYan-Hsuan Chuang u32 addr; 38e3037485SYan-Hsuan Chuang u32 len; 39e3037485SYan-Hsuan Chuang } read_reg; 403b25bac8SGuo-Feng Fan struct { 413b25bac8SGuo-Feng Fan u8 bit; 423b25bac8SGuo-Feng Fan } dm_cap; 43e3037485SYan-Hsuan Chuang }; 44e3037485SYan-Hsuan Chuang }; 45e3037485SYan-Hsuan Chuang 463b25bac8SGuo-Feng Fan static const char * const rtw_dm_cap_strs[] = { 473b25bac8SGuo-Feng Fan [RTW_DM_CAP_NA] = "NA", 483b25bac8SGuo-Feng Fan [RTW_DM_CAP_TXGAPK] = "TXGAPK", 493b25bac8SGuo-Feng Fan }; 503b25bac8SGuo-Feng Fan 51e3037485SYan-Hsuan Chuang static int rtw_debugfs_single_show(struct seq_file *m, void *v) 52e3037485SYan-Hsuan Chuang { 53e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 54e3037485SYan-Hsuan Chuang 55e3037485SYan-Hsuan Chuang return debugfs_priv->cb_read(m, v); 56e3037485SYan-Hsuan Chuang } 57e3037485SYan-Hsuan Chuang 58e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_common_write(struct file *filp, 59e3037485SYan-Hsuan Chuang const char __user *buffer, 60e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 61e3037485SYan-Hsuan Chuang { 62e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 63e3037485SYan-Hsuan Chuang 64e3037485SYan-Hsuan Chuang return debugfs_priv->cb_write(filp, buffer, count, loff); 65e3037485SYan-Hsuan Chuang } 66e3037485SYan-Hsuan Chuang 67e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_single_write(struct file *filp, 68e3037485SYan-Hsuan Chuang const char __user *buffer, 69e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 70e3037485SYan-Hsuan Chuang { 71e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 72e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 73e3037485SYan-Hsuan Chuang 74e3037485SYan-Hsuan Chuang return debugfs_priv->cb_write(filp, buffer, count, loff); 75e3037485SYan-Hsuan Chuang } 76e3037485SYan-Hsuan Chuang 77e3037485SYan-Hsuan Chuang static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp) 78e3037485SYan-Hsuan Chuang { 79e3037485SYan-Hsuan Chuang return single_open(filp, rtw_debugfs_single_show, inode->i_private); 80e3037485SYan-Hsuan Chuang } 81e3037485SYan-Hsuan Chuang 82e3037485SYan-Hsuan Chuang static int rtw_debugfs_close(struct inode *inode, struct file *filp) 83e3037485SYan-Hsuan Chuang { 84e3037485SYan-Hsuan Chuang return 0; 85e3037485SYan-Hsuan Chuang } 86e3037485SYan-Hsuan Chuang 87e3037485SYan-Hsuan Chuang static const struct file_operations file_ops_single_r = { 88e3037485SYan-Hsuan Chuang .owner = THIS_MODULE, 89e3037485SYan-Hsuan Chuang .open = rtw_debugfs_single_open_rw, 90e3037485SYan-Hsuan Chuang .read = seq_read, 91e3037485SYan-Hsuan Chuang .llseek = seq_lseek, 92eb9affaeSWei Yongjun .release = single_release, 93e3037485SYan-Hsuan Chuang }; 94e3037485SYan-Hsuan Chuang 95e3037485SYan-Hsuan Chuang static const struct file_operations file_ops_single_rw = { 96e3037485SYan-Hsuan Chuang .owner = THIS_MODULE, 97e3037485SYan-Hsuan Chuang .open = rtw_debugfs_single_open_rw, 98e3037485SYan-Hsuan Chuang .release = single_release, 99e3037485SYan-Hsuan Chuang .read = seq_read, 100e3037485SYan-Hsuan Chuang .llseek = seq_lseek, 101e3037485SYan-Hsuan Chuang .write = rtw_debugfs_single_write, 102e3037485SYan-Hsuan Chuang }; 103e3037485SYan-Hsuan Chuang 104e3037485SYan-Hsuan Chuang static const struct file_operations file_ops_common_write = { 105e3037485SYan-Hsuan Chuang .owner = THIS_MODULE, 106e3037485SYan-Hsuan Chuang .write = rtw_debugfs_common_write, 107e3037485SYan-Hsuan Chuang .open = simple_open, 108e3037485SYan-Hsuan Chuang .release = rtw_debugfs_close, 109e3037485SYan-Hsuan Chuang }; 110e3037485SYan-Hsuan Chuang 111e3037485SYan-Hsuan Chuang static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v) 112e3037485SYan-Hsuan Chuang { 113e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 114e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 115e3037485SYan-Hsuan Chuang u32 val, len, addr; 116e3037485SYan-Hsuan Chuang 117e3037485SYan-Hsuan Chuang len = debugfs_priv->read_reg.len; 118e3037485SYan-Hsuan Chuang addr = debugfs_priv->read_reg.addr; 119e3037485SYan-Hsuan Chuang switch (len) { 120e3037485SYan-Hsuan Chuang case 1: 121e3037485SYan-Hsuan Chuang val = rtw_read8(rtwdev, addr); 122e3037485SYan-Hsuan Chuang seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val); 123e3037485SYan-Hsuan Chuang break; 124e3037485SYan-Hsuan Chuang case 2: 125e3037485SYan-Hsuan Chuang val = rtw_read16(rtwdev, addr); 126e3037485SYan-Hsuan Chuang seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val); 127e3037485SYan-Hsuan Chuang break; 128e3037485SYan-Hsuan Chuang case 4: 129e3037485SYan-Hsuan Chuang val = rtw_read32(rtwdev, addr); 130e3037485SYan-Hsuan Chuang seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val); 131e3037485SYan-Hsuan Chuang break; 132e3037485SYan-Hsuan Chuang } 133e3037485SYan-Hsuan Chuang return 0; 134e3037485SYan-Hsuan Chuang } 135e3037485SYan-Hsuan Chuang 136e3037485SYan-Hsuan Chuang static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v) 137e3037485SYan-Hsuan Chuang { 138e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 139e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 140e3037485SYan-Hsuan Chuang u32 val, addr, mask; 141e3037485SYan-Hsuan Chuang u8 path; 142e3037485SYan-Hsuan Chuang 143e3037485SYan-Hsuan Chuang path = debugfs_priv->rf_path; 144e3037485SYan-Hsuan Chuang addr = debugfs_priv->rf_addr; 145e3037485SYan-Hsuan Chuang mask = debugfs_priv->rf_mask; 146e3037485SYan-Hsuan Chuang 147d57ca103SSascha Hauer mutex_lock(&rtwdev->mutex); 148e3037485SYan-Hsuan Chuang val = rtw_read_rf(rtwdev, path, addr, mask); 149d57ca103SSascha Hauer mutex_unlock(&rtwdev->mutex); 150e3037485SYan-Hsuan Chuang 151e3037485SYan-Hsuan Chuang seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n", 152e3037485SYan-Hsuan Chuang path, addr, mask, val); 153e3037485SYan-Hsuan Chuang 154e3037485SYan-Hsuan Chuang return 0; 155e3037485SYan-Hsuan Chuang } 156e3037485SYan-Hsuan Chuang 1571379e620SYan-Hsuan Chuang static int rtw_debugfs_get_fix_rate(struct seq_file *m, void *v) 1581379e620SYan-Hsuan Chuang { 1591379e620SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 1601379e620SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 1611379e620SYan-Hsuan Chuang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1621379e620SYan-Hsuan Chuang u8 fix_rate = dm_info->fix_rate; 1631379e620SYan-Hsuan Chuang 1641379e620SYan-Hsuan Chuang if (fix_rate >= DESC_RATE_MAX) { 1651379e620SYan-Hsuan Chuang seq_printf(m, "Fix rate disabled, fix_rate = %u\n", fix_rate); 1661379e620SYan-Hsuan Chuang return 0; 1671379e620SYan-Hsuan Chuang } 1681379e620SYan-Hsuan Chuang 1691379e620SYan-Hsuan Chuang seq_printf(m, "Data frames fixed at desc rate %u\n", fix_rate); 1701379e620SYan-Hsuan Chuang return 0; 1711379e620SYan-Hsuan Chuang } 1721379e620SYan-Hsuan Chuang 173e3037485SYan-Hsuan Chuang static int rtw_debugfs_copy_from_user(char tmp[], int size, 174e3037485SYan-Hsuan Chuang const char __user *buffer, size_t count, 175e3037485SYan-Hsuan Chuang int num) 176e3037485SYan-Hsuan Chuang { 177e3037485SYan-Hsuan Chuang int tmp_len; 178e3037485SYan-Hsuan Chuang 17974a8c816SDan Carpenter memset(tmp, 0, size); 18074a8c816SDan Carpenter 181e3037485SYan-Hsuan Chuang if (count < num) 182e3037485SYan-Hsuan Chuang return -EFAULT; 183e3037485SYan-Hsuan Chuang 184e3037485SYan-Hsuan Chuang tmp_len = (count > size - 1 ? size - 1 : count); 185e3037485SYan-Hsuan Chuang 18622562225SZhang Shurong if (copy_from_user(tmp, buffer, tmp_len)) 18722562225SZhang Shurong return -EFAULT; 188e3037485SYan-Hsuan Chuang 189e3037485SYan-Hsuan Chuang tmp[tmp_len] = '\0'; 190e3037485SYan-Hsuan Chuang 191e3037485SYan-Hsuan Chuang return 0; 192e3037485SYan-Hsuan Chuang } 193e3037485SYan-Hsuan Chuang 194e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_read_reg(struct file *filp, 195e3037485SYan-Hsuan Chuang const char __user *buffer, 196e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 197e3037485SYan-Hsuan Chuang { 198e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 199e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 200e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 201e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 202e3037485SYan-Hsuan Chuang u32 addr, len; 203e3037485SYan-Hsuan Chuang int num; 204*77005533SZhang Shurong int ret; 205e3037485SYan-Hsuan Chuang 206*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 207*77005533SZhang Shurong if (ret) 208*77005533SZhang Shurong return ret; 209e3037485SYan-Hsuan Chuang 210e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x", &addr, &len); 211e3037485SYan-Hsuan Chuang 212e3037485SYan-Hsuan Chuang if (num != 2) 213*77005533SZhang Shurong return -EINVAL; 214e3037485SYan-Hsuan Chuang 215e3037485SYan-Hsuan Chuang if (len != 1 && len != 2 && len != 4) { 216e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "read reg setting wrong len\n"); 217e3037485SYan-Hsuan Chuang return -EINVAL; 218e3037485SYan-Hsuan Chuang } 219e3037485SYan-Hsuan Chuang debugfs_priv->read_reg.addr = addr; 220e3037485SYan-Hsuan Chuang debugfs_priv->read_reg.len = len; 221e3037485SYan-Hsuan Chuang 222e3037485SYan-Hsuan Chuang return count; 223e3037485SYan-Hsuan Chuang } 224e3037485SYan-Hsuan Chuang 225e3037485SYan-Hsuan Chuang static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v) 226e3037485SYan-Hsuan Chuang { 227e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 228e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 229e3037485SYan-Hsuan Chuang u32 val, command; 230e3037485SYan-Hsuan Chuang u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT; 231e3037485SYan-Hsuan Chuang u32 read_cmd = RTW_SEC_CMD_POLLING; 232e3037485SYan-Hsuan Chuang int i; 233e3037485SYan-Hsuan Chuang 234e3037485SYan-Hsuan Chuang seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data); 235e3037485SYan-Hsuan Chuang seq_puts(m, "0x0 0x1 0x2 0x3 "); 236e3037485SYan-Hsuan Chuang seq_puts(m, "0x4 0x5\n"); 237e3037485SYan-Hsuan Chuang mutex_lock(&rtwdev->mutex); 238e3037485SYan-Hsuan Chuang for (i = 0; i <= 5; i++) { 239e3037485SYan-Hsuan Chuang command = read_cmd | (hw_key_idx + i); 240e3037485SYan-Hsuan Chuang rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); 241e3037485SYan-Hsuan Chuang val = rtw_read32(rtwdev, RTW_SEC_READ_REG); 242e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x", val); 243e3037485SYan-Hsuan Chuang if (i < 2) 244e3037485SYan-Hsuan Chuang seq_puts(m, " "); 245e3037485SYan-Hsuan Chuang } 246e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 247e3037485SYan-Hsuan Chuang mutex_unlock(&rtwdev->mutex); 248e3037485SYan-Hsuan Chuang return 0; 249e3037485SYan-Hsuan Chuang } 250e3037485SYan-Hsuan Chuang 251e3037485SYan-Hsuan Chuang static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v) 252e3037485SYan-Hsuan Chuang { 253e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 254e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 255e3037485SYan-Hsuan Chuang u8 page_size = rtwdev->chip->page_size; 256e3037485SYan-Hsuan Chuang u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; 257e3037485SYan-Hsuan Chuang u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; 258e3037485SYan-Hsuan Chuang u8 *buf; 259e3037485SYan-Hsuan Chuang int i; 260e3037485SYan-Hsuan Chuang int ret; 261e3037485SYan-Hsuan Chuang 262e3037485SYan-Hsuan Chuang buf = vzalloc(buf_size); 263e3037485SYan-Hsuan Chuang if (!buf) 264e3037485SYan-Hsuan Chuang return -ENOMEM; 265e3037485SYan-Hsuan Chuang 2660fbc2f0fSTzu-En Huang ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RSVD_PAGE, offset, 2670fbc2f0fSTzu-En Huang buf_size, (u32 *)buf); 268e3037485SYan-Hsuan Chuang if (ret) { 269e3037485SYan-Hsuan Chuang rtw_err(rtwdev, "failed to dump rsvd page\n"); 270e3037485SYan-Hsuan Chuang vfree(buf); 271e3037485SYan-Hsuan Chuang return ret; 272e3037485SYan-Hsuan Chuang } 273e3037485SYan-Hsuan Chuang 274e3037485SYan-Hsuan Chuang for (i = 0 ; i < buf_size ; i += 8) { 275e3037485SYan-Hsuan Chuang if (i % page_size == 0) 276e3037485SYan-Hsuan Chuang seq_printf(m, "PAGE %d\n", (i + offset) / page_size); 277d38c9df5SAndy Shevchenko seq_printf(m, "%8ph\n", buf + i); 278e3037485SYan-Hsuan Chuang } 279e3037485SYan-Hsuan Chuang vfree(buf); 280e3037485SYan-Hsuan Chuang 281e3037485SYan-Hsuan Chuang return 0; 282e3037485SYan-Hsuan Chuang } 283e3037485SYan-Hsuan Chuang 284e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp, 285e3037485SYan-Hsuan Chuang const char __user *buffer, 286e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 287e3037485SYan-Hsuan Chuang { 288e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 289e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 290e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 291e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 292e3037485SYan-Hsuan Chuang u32 offset, page_num; 293e3037485SYan-Hsuan Chuang int num; 294*77005533SZhang Shurong int ret; 295e3037485SYan-Hsuan Chuang 296*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 297*77005533SZhang Shurong if (ret) 298*77005533SZhang Shurong return ret; 299e3037485SYan-Hsuan Chuang 300e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%d %d", &offset, &page_num); 301e3037485SYan-Hsuan Chuang 302e3037485SYan-Hsuan Chuang if (num != 2) { 303e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid arguments\n"); 304c9eaee0cSDan Carpenter return -EINVAL; 305e3037485SYan-Hsuan Chuang } 306e3037485SYan-Hsuan Chuang 307e3037485SYan-Hsuan Chuang debugfs_priv->rsvd_page.page_offset = offset; 308e3037485SYan-Hsuan Chuang debugfs_priv->rsvd_page.page_num = page_num; 309e3037485SYan-Hsuan Chuang 310e3037485SYan-Hsuan Chuang return count; 311e3037485SYan-Hsuan Chuang } 312e3037485SYan-Hsuan Chuang 313e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_single_input(struct file *filp, 314e3037485SYan-Hsuan Chuang const char __user *buffer, 315e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 316e3037485SYan-Hsuan Chuang { 317e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 318e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 319e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 320e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 321e3037485SYan-Hsuan Chuang u32 input; 322e3037485SYan-Hsuan Chuang int num; 323*77005533SZhang Shurong int ret; 324e3037485SYan-Hsuan Chuang 325*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 326*77005533SZhang Shurong if (ret) 327*77005533SZhang Shurong return ret; 328e3037485SYan-Hsuan Chuang 329e3037485SYan-Hsuan Chuang num = kstrtoint(tmp, 0, &input); 330e3037485SYan-Hsuan Chuang 331e3037485SYan-Hsuan Chuang if (num) { 332e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "kstrtoint failed\n"); 333e3037485SYan-Hsuan Chuang return num; 334e3037485SYan-Hsuan Chuang } 335e3037485SYan-Hsuan Chuang 336e3037485SYan-Hsuan Chuang debugfs_priv->cb_data = input; 337e3037485SYan-Hsuan Chuang 338e3037485SYan-Hsuan Chuang return count; 339e3037485SYan-Hsuan Chuang } 340e3037485SYan-Hsuan Chuang 341e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_write_reg(struct file *filp, 342e3037485SYan-Hsuan Chuang const char __user *buffer, 343e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 344e3037485SYan-Hsuan Chuang { 345e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 346e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 347e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 348e3037485SYan-Hsuan Chuang u32 addr, val, len; 349e3037485SYan-Hsuan Chuang int num; 350*77005533SZhang Shurong int ret; 351e3037485SYan-Hsuan Chuang 352*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 353*77005533SZhang Shurong if (ret) 354*77005533SZhang Shurong return ret; 355e3037485SYan-Hsuan Chuang 356e3037485SYan-Hsuan Chuang /* write BB/MAC register */ 357e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x", &addr, &val, &len); 358e3037485SYan-Hsuan Chuang 359e3037485SYan-Hsuan Chuang if (num != 3) 360*77005533SZhang Shurong return -EINVAL; 361e3037485SYan-Hsuan Chuang 362e3037485SYan-Hsuan Chuang switch (len) { 363e3037485SYan-Hsuan Chuang case 1: 364e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 365e3037485SYan-Hsuan Chuang "reg write8 0x%03x: 0x%08x\n", addr, val); 366e3037485SYan-Hsuan Chuang rtw_write8(rtwdev, addr, (u8)val); 367e3037485SYan-Hsuan Chuang break; 368e3037485SYan-Hsuan Chuang case 2: 369e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 370e3037485SYan-Hsuan Chuang "reg write16 0x%03x: 0x%08x\n", addr, val); 371e3037485SYan-Hsuan Chuang rtw_write16(rtwdev, addr, (u16)val); 372e3037485SYan-Hsuan Chuang break; 373e3037485SYan-Hsuan Chuang case 4: 374e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 375e3037485SYan-Hsuan Chuang "reg write32 0x%03x: 0x%08x\n", addr, val); 376e3037485SYan-Hsuan Chuang rtw_write32(rtwdev, addr, (u32)val); 377e3037485SYan-Hsuan Chuang break; 378e3037485SYan-Hsuan Chuang default: 379e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 380e3037485SYan-Hsuan Chuang "error write length = %d\n", len); 381e3037485SYan-Hsuan Chuang break; 382e3037485SYan-Hsuan Chuang } 383e3037485SYan-Hsuan Chuang 384e3037485SYan-Hsuan Chuang return count; 385e3037485SYan-Hsuan Chuang } 386e3037485SYan-Hsuan Chuang 387c376c1fcSTzu-En Huang static ssize_t rtw_debugfs_set_h2c(struct file *filp, 388c376c1fcSTzu-En Huang const char __user *buffer, 389c376c1fcSTzu-En Huang size_t count, loff_t *loff) 390c376c1fcSTzu-En Huang { 391c376c1fcSTzu-En Huang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 392c376c1fcSTzu-En Huang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 393c376c1fcSTzu-En Huang char tmp[32 + 1]; 394c376c1fcSTzu-En Huang u8 param[8]; 395c376c1fcSTzu-En Huang int num; 396*77005533SZhang Shurong int ret; 397c376c1fcSTzu-En Huang 398*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 399*77005533SZhang Shurong if (ret) 400*77005533SZhang Shurong return ret; 401c376c1fcSTzu-En Huang 402c376c1fcSTzu-En Huang num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", 403c376c1fcSTzu-En Huang ¶m[0], ¶m[1], ¶m[2], ¶m[3], 404c376c1fcSTzu-En Huang ¶m[4], ¶m[5], ¶m[6], ¶m[7]); 405c376c1fcSTzu-En Huang if (num != 8) { 406a0061be4SPing-Ke Shih rtw_warn(rtwdev, "invalid H2C command format for debug\n"); 407c376c1fcSTzu-En Huang return -EINVAL; 408c376c1fcSTzu-En Huang } 409c376c1fcSTzu-En Huang 4101e2701f4SSascha Hauer mutex_lock(&rtwdev->mutex); 411c376c1fcSTzu-En Huang rtw_fw_h2c_cmd_dbg(rtwdev, param); 4121e2701f4SSascha Hauer mutex_unlock(&rtwdev->mutex); 413c376c1fcSTzu-En Huang 414c376c1fcSTzu-En Huang return count; 415c376c1fcSTzu-En Huang } 416c376c1fcSTzu-En Huang 417e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rf_write(struct file *filp, 418e3037485SYan-Hsuan Chuang const char __user *buffer, 419e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 420e3037485SYan-Hsuan Chuang { 421e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 422e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 423e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 424e3037485SYan-Hsuan Chuang u32 path, addr, mask, val; 425e3037485SYan-Hsuan Chuang int num; 426*77005533SZhang Shurong int ret; 427e3037485SYan-Hsuan Chuang 428*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); 429*77005533SZhang Shurong if (ret) 430*77005533SZhang Shurong return ret; 431e3037485SYan-Hsuan Chuang 432e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); 433e3037485SYan-Hsuan Chuang 434e3037485SYan-Hsuan Chuang if (num != 4) { 435e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 436*77005533SZhang Shurong return -EINVAL; 437e3037485SYan-Hsuan Chuang } 438e3037485SYan-Hsuan Chuang 439d57ca103SSascha Hauer mutex_lock(&rtwdev->mutex); 440e3037485SYan-Hsuan Chuang rtw_write_rf(rtwdev, path, addr, mask, val); 441d57ca103SSascha Hauer mutex_unlock(&rtwdev->mutex); 442e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 443e3037485SYan-Hsuan Chuang "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", 444e3037485SYan-Hsuan Chuang path, addr, mask, val); 445e3037485SYan-Hsuan Chuang 446e3037485SYan-Hsuan Chuang return count; 447e3037485SYan-Hsuan Chuang } 448e3037485SYan-Hsuan Chuang 449e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rf_read(struct file *filp, 450e3037485SYan-Hsuan Chuang const char __user *buffer, 451e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 452e3037485SYan-Hsuan Chuang { 453e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 454e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 455e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 456e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 457e3037485SYan-Hsuan Chuang u32 path, addr, mask; 458e3037485SYan-Hsuan Chuang int num; 459*77005533SZhang Shurong int ret; 460e3037485SYan-Hsuan Chuang 461*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 462*77005533SZhang Shurong if (ret) 463*77005533SZhang Shurong return ret; 464e3037485SYan-Hsuan Chuang 465e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); 466e3037485SYan-Hsuan Chuang 467e3037485SYan-Hsuan Chuang if (num != 3) { 468e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 469*77005533SZhang Shurong return -EINVAL; 470e3037485SYan-Hsuan Chuang } 471e3037485SYan-Hsuan Chuang 472e3037485SYan-Hsuan Chuang debugfs_priv->rf_path = path; 473e3037485SYan-Hsuan Chuang debugfs_priv->rf_addr = addr; 474e3037485SYan-Hsuan Chuang debugfs_priv->rf_mask = mask; 475e3037485SYan-Hsuan Chuang 476e3037485SYan-Hsuan Chuang return count; 477e3037485SYan-Hsuan Chuang } 478e3037485SYan-Hsuan Chuang 4791379e620SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_fix_rate(struct file *filp, 4801379e620SYan-Hsuan Chuang const char __user *buffer, 4811379e620SYan-Hsuan Chuang size_t count, loff_t *loff) 4821379e620SYan-Hsuan Chuang { 4831379e620SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 4841379e620SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 4851379e620SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 4861379e620SYan-Hsuan Chuang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 4871379e620SYan-Hsuan Chuang u8 fix_rate; 4881379e620SYan-Hsuan Chuang char tmp[32 + 1]; 4891379e620SYan-Hsuan Chuang int ret; 4901379e620SYan-Hsuan Chuang 491*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 492*77005533SZhang Shurong if (ret) 493*77005533SZhang Shurong return ret; 4941379e620SYan-Hsuan Chuang 4951379e620SYan-Hsuan Chuang ret = kstrtou8(tmp, 0, &fix_rate); 4961379e620SYan-Hsuan Chuang if (ret) { 4971379e620SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [rate]\n"); 4981379e620SYan-Hsuan Chuang return ret; 4991379e620SYan-Hsuan Chuang } 5001379e620SYan-Hsuan Chuang 5011379e620SYan-Hsuan Chuang dm_info->fix_rate = fix_rate; 5021379e620SYan-Hsuan Chuang 5031379e620SYan-Hsuan Chuang return count; 5041379e620SYan-Hsuan Chuang } 5051379e620SYan-Hsuan Chuang 506e3037485SYan-Hsuan Chuang static int rtw_debug_get_mac_page(struct seq_file *m, void *v) 507e3037485SYan-Hsuan Chuang { 508e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 509e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 510e3037485SYan-Hsuan Chuang u32 page = debugfs_priv->cb_data; 511e3037485SYan-Hsuan Chuang int i, n; 512e3037485SYan-Hsuan Chuang int max = 0xff; 513e3037485SYan-Hsuan Chuang 5140e25262bSLee Jones rtw_read32(rtwdev, debugfs_priv->cb_data); 515e3037485SYan-Hsuan Chuang for (n = 0; n <= max; ) { 516e3037485SYan-Hsuan Chuang seq_printf(m, "\n%8.8x ", n + page); 517e3037485SYan-Hsuan Chuang for (i = 0; i < 4 && n <= max; i++, n += 4) 518e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", 519e3037485SYan-Hsuan Chuang rtw_read32(rtwdev, (page | n))); 520e3037485SYan-Hsuan Chuang } 521e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 522e3037485SYan-Hsuan Chuang return 0; 523e3037485SYan-Hsuan Chuang } 524e3037485SYan-Hsuan Chuang 525e3037485SYan-Hsuan Chuang static int rtw_debug_get_bb_page(struct seq_file *m, void *v) 526e3037485SYan-Hsuan Chuang { 527e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 528e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 529e3037485SYan-Hsuan Chuang u32 page = debugfs_priv->cb_data; 530e3037485SYan-Hsuan Chuang int i, n; 531e3037485SYan-Hsuan Chuang int max = 0xff; 532e3037485SYan-Hsuan Chuang 5330e25262bSLee Jones rtw_read32(rtwdev, debugfs_priv->cb_data); 534e3037485SYan-Hsuan Chuang for (n = 0; n <= max; ) { 535e3037485SYan-Hsuan Chuang seq_printf(m, "\n%8.8x ", n + page); 536e3037485SYan-Hsuan Chuang for (i = 0; i < 4 && n <= max; i++, n += 4) 537e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", 538e3037485SYan-Hsuan Chuang rtw_read32(rtwdev, (page | n))); 539e3037485SYan-Hsuan Chuang } 540e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 541e3037485SYan-Hsuan Chuang return 0; 542e3037485SYan-Hsuan Chuang } 543e3037485SYan-Hsuan Chuang 544e3037485SYan-Hsuan Chuang static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) 545e3037485SYan-Hsuan Chuang { 546e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 547e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 548e3037485SYan-Hsuan Chuang u32 addr, offset, data; 549e3037485SYan-Hsuan Chuang u8 path; 550e3037485SYan-Hsuan Chuang 551d57ca103SSascha Hauer mutex_lock(&rtwdev->mutex); 552d57ca103SSascha Hauer 553e3037485SYan-Hsuan Chuang for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 554e3037485SYan-Hsuan Chuang seq_printf(m, "RF path:%d\n", path); 555e3037485SYan-Hsuan Chuang for (addr = 0; addr < 0x100; addr += 4) { 556e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", addr); 557e3037485SYan-Hsuan Chuang for (offset = 0; offset < 4; offset++) { 558e3037485SYan-Hsuan Chuang data = rtw_read_rf(rtwdev, path, addr + offset, 559e3037485SYan-Hsuan Chuang 0xffffffff); 560e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", data); 561e3037485SYan-Hsuan Chuang } 562e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 563e3037485SYan-Hsuan Chuang } 564e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 565e3037485SYan-Hsuan Chuang } 566e3037485SYan-Hsuan Chuang 567d57ca103SSascha Hauer mutex_unlock(&rtwdev->mutex); 568d57ca103SSascha Hauer 569e3037485SYan-Hsuan Chuang return 0; 570e3037485SYan-Hsuan Chuang } 571e3037485SYan-Hsuan Chuang 5728812022cSZong-Zhe Yang static void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate) 5738812022cSZong-Zhe Yang { 5748812022cSZong-Zhe Yang static const char * const 5758812022cSZong-Zhe Yang cck_rate[] = {"1M", "2M", "5.5M", "11M"}; 5768812022cSZong-Zhe Yang u8 idx = rate - DESC_RATE1M; 5778812022cSZong-Zhe Yang 5788812022cSZong-Zhe Yang seq_printf(m, " CCK_%-5s", cck_rate[idx]); 5798812022cSZong-Zhe Yang } 5808812022cSZong-Zhe Yang 5818812022cSZong-Zhe Yang static void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate) 5828812022cSZong-Zhe Yang { 5838812022cSZong-Zhe Yang static const char * const 5848812022cSZong-Zhe Yang ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"}; 5858812022cSZong-Zhe Yang u8 idx = rate - DESC_RATE6M; 5868812022cSZong-Zhe Yang 5878812022cSZong-Zhe Yang seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]); 5888812022cSZong-Zhe Yang } 5898812022cSZong-Zhe Yang 5908812022cSZong-Zhe Yang static void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate) 5918812022cSZong-Zhe Yang { 5928812022cSZong-Zhe Yang u8 mcs_n = rate - DESC_RATEMCS0; 5938812022cSZong-Zhe Yang 5948812022cSZong-Zhe Yang seq_printf(m, " MCS%-6u", mcs_n); 5958812022cSZong-Zhe Yang } 5968812022cSZong-Zhe Yang 5978812022cSZong-Zhe Yang static void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate) 5988812022cSZong-Zhe Yang { 5998812022cSZong-Zhe Yang u8 idx = rate - DESC_RATEVHT1SS_MCS0; 6008812022cSZong-Zhe Yang u8 n_ss, mcs_n; 6018812022cSZong-Zhe Yang 6028812022cSZong-Zhe Yang /* n spatial stream */ 6038812022cSZong-Zhe Yang n_ss = 1 + idx / 10; 6048812022cSZong-Zhe Yang /* MCS n */ 6058812022cSZong-Zhe Yang mcs_n = idx % 10; 6068812022cSZong-Zhe Yang seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); 6078812022cSZong-Zhe Yang } 6088812022cSZong-Zhe Yang 609082a36dcSTsang-Shian Lin static void rtw_print_rate(struct seq_file *m, u8 rate) 610082a36dcSTsang-Shian Lin { 611082a36dcSTsang-Shian Lin switch (rate) { 612082a36dcSTsang-Shian Lin case DESC_RATE1M...DESC_RATE11M: 613082a36dcSTsang-Shian Lin rtw_print_cck_rate_txt(m, rate); 614082a36dcSTsang-Shian Lin break; 615082a36dcSTsang-Shian Lin case DESC_RATE6M...DESC_RATE54M: 616082a36dcSTsang-Shian Lin rtw_print_ofdm_rate_txt(m, rate); 617082a36dcSTsang-Shian Lin break; 618082a36dcSTsang-Shian Lin case DESC_RATEMCS0...DESC_RATEMCS15: 619082a36dcSTsang-Shian Lin rtw_print_ht_rate_txt(m, rate); 620082a36dcSTsang-Shian Lin break; 621082a36dcSTsang-Shian Lin case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: 622082a36dcSTsang-Shian Lin rtw_print_vht_rate_txt(m, rate); 623082a36dcSTsang-Shian Lin break; 624082a36dcSTsang-Shian Lin default: 625082a36dcSTsang-Shian Lin seq_printf(m, " Unknown rate=0x%x\n", rate); 626082a36dcSTsang-Shian Lin break; 627082a36dcSTsang-Shian Lin } 628082a36dcSTsang-Shian Lin } 629082a36dcSTsang-Shian Lin 630fada0931STzu-En Huang #define case_REGD(src) \ 631fada0931STzu-En Huang case RTW_REGD_##src: return #src 632fada0931STzu-En Huang 633fada0931STzu-En Huang static const char *rtw_get_regd_string(u8 regd) 634fada0931STzu-En Huang { 635fada0931STzu-En Huang switch (regd) { 636fada0931STzu-En Huang case_REGD(FCC); 637fada0931STzu-En Huang case_REGD(MKK); 638fada0931STzu-En Huang case_REGD(ETSI); 639fada0931STzu-En Huang case_REGD(IC); 640fada0931STzu-En Huang case_REGD(KCC); 641fada0931STzu-En Huang case_REGD(ACMA); 642fada0931STzu-En Huang case_REGD(CHILE); 643fada0931STzu-En Huang case_REGD(UKRAINE); 644fada0931STzu-En Huang case_REGD(MEXICO); 645fada0931STzu-En Huang case_REGD(CN); 646fada0931STzu-En Huang case_REGD(WW); 647fada0931STzu-En Huang default: 648fada0931STzu-En Huang return "Unknown"; 649fada0931STzu-En Huang } 650fada0931STzu-En Huang } 651fada0931STzu-En Huang 6528812022cSZong-Zhe Yang static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) 6538812022cSZong-Zhe Yang { 6548812022cSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 6558812022cSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6568812022cSZong-Zhe Yang struct rtw_hal *hal = &rtwdev->hal; 657685b474bSChih-Kang Chang u8 path, rate, bw, ch, regd; 6588812022cSZong-Zhe Yang struct rtw_power_params pwr_param = {0}; 659685b474bSChih-Kang Chang 660685b474bSChih-Kang Chang mutex_lock(&rtwdev->mutex); 661685b474bSChih-Kang Chang bw = hal->current_band_width; 662685b474bSChih-Kang Chang ch = hal->current_channel; 663685b474bSChih-Kang Chang regd = rtw_regd_get(rtwdev); 6648812022cSZong-Zhe Yang 66515728937SZong-Zhe Yang seq_printf(m, "channel: %u\n", ch); 66615728937SZong-Zhe Yang seq_printf(m, "bandwidth: %u\n", bw); 667fada0931STzu-En Huang seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd)); 6688704d0beSZong-Zhe Yang seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n", 6698704d0beSZong-Zhe Yang "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem"); 6708812022cSZong-Zhe Yang 6718812022cSZong-Zhe Yang mutex_lock(&hal->tx_power_mutex); 6728812022cSZong-Zhe Yang for (path = RF_PATH_A; path <= RF_PATH_B; path++) { 6738812022cSZong-Zhe Yang /* there is no CCK rates used in 5G */ 6748812022cSZong-Zhe Yang if (hal->current_band_type == RTW_BAND_5G) 6758812022cSZong-Zhe Yang rate = DESC_RATE6M; 6768812022cSZong-Zhe Yang else 6778812022cSZong-Zhe Yang rate = DESC_RATE1M; 6788812022cSZong-Zhe Yang 6798812022cSZong-Zhe Yang /* now, not support vht 3ss and vht 4ss*/ 6808812022cSZong-Zhe Yang for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) { 6818812022cSZong-Zhe Yang /* now, not support ht 3ss and ht 4ss*/ 6828812022cSZong-Zhe Yang if (rate > DESC_RATEMCS15 && 6838812022cSZong-Zhe Yang rate < DESC_RATEVHT1SS_MCS0) 6848812022cSZong-Zhe Yang continue; 6858812022cSZong-Zhe Yang 6868812022cSZong-Zhe Yang rtw_get_tx_power_params(rtwdev, path, rate, bw, 6878812022cSZong-Zhe Yang ch, regd, &pwr_param); 6888812022cSZong-Zhe Yang 6898812022cSZong-Zhe Yang seq_printf(m, "%4c ", path + 'A'); 690082a36dcSTsang-Shian Lin rtw_print_rate(m, rate); 6918704d0beSZong-Zhe Yang seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d) %4d\n", 6928812022cSZong-Zhe Yang hal->tx_pwr_tbl[path][rate], 6938812022cSZong-Zhe Yang hal->tx_pwr_tbl[path][rate], 6948812022cSZong-Zhe Yang pwr_param.pwr_base, 6958704d0beSZong-Zhe Yang min3(pwr_param.pwr_offset, 6968704d0beSZong-Zhe Yang pwr_param.pwr_limit, 6978704d0beSZong-Zhe Yang pwr_param.pwr_sar), 698608d2a08SPing-Ke Shih pwr_param.pwr_offset, pwr_param.pwr_limit, 6998704d0beSZong-Zhe Yang pwr_param.pwr_sar, 700608d2a08SPing-Ke Shih pwr_param.pwr_remnant); 7018812022cSZong-Zhe Yang } 7028812022cSZong-Zhe Yang } 7038812022cSZong-Zhe Yang 7048812022cSZong-Zhe Yang mutex_unlock(&hal->tx_power_mutex); 705685b474bSChih-Kang Chang mutex_unlock(&rtwdev->mutex); 7068812022cSZong-Zhe Yang 7078812022cSZong-Zhe Yang return 0; 7088812022cSZong-Zhe Yang } 7098812022cSZong-Zhe Yang 7101a589bd5SChing-Te Ku void rtw_debugfs_get_simple_phy_info(struct seq_file *m) 7111a589bd5SChing-Te Ku { 7121a589bd5SChing-Te Ku struct rtw_debugfs_priv *debugfs_priv = m->private; 7131a589bd5SChing-Te Ku struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 7141a589bd5SChing-Te Ku struct rtw_hal *hal = &rtwdev->hal; 7151a589bd5SChing-Te Ku struct rtw_dm_info *dm_info = &rtwdev->dm_info; 7161a589bd5SChing-Te Ku struct rtw_traffic_stats *stats = &rtwdev->stats; 7171a589bd5SChing-Te Ku 7181a589bd5SChing-Te Ku seq_printf(m, "%-40s = %ddBm/ %d\n", "RSSI/ STA Channel", 7191a589bd5SChing-Te Ku dm_info->rssi[RF_PATH_A] - 100, hal->current_channel); 7201a589bd5SChing-Te Ku 7211a589bd5SChing-Te Ku seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 7221a589bd5SChing-Te Ku stats->tx_throughput, stats->rx_throughput); 7231a589bd5SChing-Te Ku 7241a589bd5SChing-Te Ku seq_puts(m, "[Tx Rate] = "); 7251a589bd5SChing-Te Ku rtw_print_rate(m, dm_info->tx_rate); 7261a589bd5SChing-Te Ku seq_printf(m, "(0x%x)\n", dm_info->tx_rate); 7271a589bd5SChing-Te Ku 7281a589bd5SChing-Te Ku seq_puts(m, "[Rx Rate] = "); 7291a589bd5SChing-Te Ku rtw_print_rate(m, dm_info->curr_rx_rate); 7301a589bd5SChing-Te Ku seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 7311a589bd5SChing-Te Ku } 7321a589bd5SChing-Te Ku 733082a36dcSTsang-Shian Lin static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) 734082a36dcSTsang-Shian Lin { 735082a36dcSTsang-Shian Lin struct rtw_debugfs_priv *debugfs_priv = m->private; 736082a36dcSTsang-Shian Lin struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 737082a36dcSTsang-Shian Lin struct rtw_dm_info *dm_info = &rtwdev->dm_info; 738082a36dcSTsang-Shian Lin struct rtw_traffic_stats *stats = &rtwdev->stats; 739082a36dcSTsang-Shian Lin struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; 740082a36dcSTsang-Shian Lin struct rtw_efuse *efuse = &rtwdev->efuse; 741082a36dcSTsang-Shian Lin struct ewma_evm *ewma_evm = dm_info->ewma_evm; 742082a36dcSTsang-Shian Lin struct ewma_snr *ewma_snr = dm_info->ewma_snr; 743082a36dcSTsang-Shian Lin u8 ss, rate_id; 744082a36dcSTsang-Shian Lin 745082a36dcSTsang-Shian Lin seq_puts(m, "==========[Common Info]========\n"); 746082a36dcSTsang-Shian Lin seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); 747082a36dcSTsang-Shian Lin seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); 748082a36dcSTsang-Shian Lin seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); 749082a36dcSTsang-Shian Lin seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); 75004e00ac9SChin-Yen Lee seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 751082a36dcSTsang-Shian Lin stats->tx_throughput, stats->rx_throughput); 75204e00ac9SChin-Yen Lee seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ? 75304e00ac9SChin-Yen Lee 'Y' : 'N'); 754082a36dcSTsang-Shian Lin 755082a36dcSTsang-Shian Lin seq_puts(m, "==========[Tx Phy Info]========\n"); 756082a36dcSTsang-Shian Lin seq_puts(m, "[Tx Rate] = "); 757082a36dcSTsang-Shian Lin rtw_print_rate(m, dm_info->tx_rate); 758082a36dcSTsang-Shian Lin seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); 759082a36dcSTsang-Shian Lin 760082a36dcSTsang-Shian Lin seq_puts(m, "==========[Rx Phy Info]========\n"); 761082a36dcSTsang-Shian Lin seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); 762082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Rate] = "); 763082a36dcSTsang-Shian Lin rtw_print_rate(m, dm_info->curr_rx_rate); 764082a36dcSTsang-Shian Lin seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 765082a36dcSTsang-Shian Lin 766082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Rate Count]:\n"); 767082a36dcSTsang-Shian Lin seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", 768082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE1M], 769082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE2M], 770082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE5_5M], 771082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE11M]); 772082a36dcSTsang-Shian Lin 773082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 774082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE6M], 775082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE9M], 776082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE12M], 777082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE18M], 778082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE24M], 779082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE36M], 780082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE48M], 781082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE54M]); 782082a36dcSTsang-Shian Lin 783082a36dcSTsang-Shian Lin for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 784082a36dcSTsang-Shian Lin rate_id = DESC_RATEMCS0 + ss * 8; 785082a36dcSTsang-Shian Lin seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 786082a36dcSTsang-Shian Lin ss * 8, ss * 8 + 7, 787082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id], 788082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 1], 789082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 2], 790082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 3], 791082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 4], 792082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 5], 793082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 6], 794082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 7]); 795082a36dcSTsang-Shian Lin } 796082a36dcSTsang-Shian Lin 797082a36dcSTsang-Shian Lin for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 798082a36dcSTsang-Shian Lin rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; 799082a36dcSTsang-Shian Lin seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", 800082a36dcSTsang-Shian Lin ss + 1, 801082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id], 802082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 1], 803082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 2], 804082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 3], 805082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 4], 806082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 5], 807082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 6], 808082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 7], 809082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 8], 810082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 9]); 811082a36dcSTsang-Shian Lin } 812082a36dcSTsang-Shian Lin 813082a36dcSTsang-Shian Lin seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", 814082a36dcSTsang-Shian Lin dm_info->rssi[RF_PATH_A] - 100, 815082a36dcSTsang-Shian Lin dm_info->rssi[RF_PATH_B] - 100); 816082a36dcSTsang-Shian Lin seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", 817082a36dcSTsang-Shian Lin dm_info->rx_evm_dbm[RF_PATH_A], 818082a36dcSTsang-Shian Lin dm_info->rx_evm_dbm[RF_PATH_B]); 819082a36dcSTsang-Shian Lin seq_printf(m, "[Rx SNR] = {%d, %d}\n", 820082a36dcSTsang-Shian Lin dm_info->rx_snr[RF_PATH_A], 821082a36dcSTsang-Shian Lin dm_info->rx_snr[RF_PATH_B]); 822082a36dcSTsang-Shian Lin seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", 823082a36dcSTsang-Shian Lin dm_info->cfo_tail[RF_PATH_A], 824082a36dcSTsang-Shian Lin dm_info->cfo_tail[RF_PATH_B]); 825082a36dcSTsang-Shian Lin 826082a36dcSTsang-Shian Lin if (dm_info->curr_rx_rate >= DESC_RATE11M) { 827082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Average Status]:\n"); 828082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", 829082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), 830082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); 831082a36dcSTsang-Shian Lin seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", 832082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), 833082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); 834082a36dcSTsang-Shian Lin seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", 835082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), 836082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), 837082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), 838082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); 839082a36dcSTsang-Shian Lin } 840082a36dcSTsang-Shian Lin 841082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Counter]:\n"); 842082a36dcSTsang-Shian Lin seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", 843082a36dcSTsang-Shian Lin dm_info->cck_cca_cnt, 844082a36dcSTsang-Shian Lin dm_info->ofdm_cca_cnt, 845082a36dcSTsang-Shian Lin dm_info->total_cca_cnt); 846082a36dcSTsang-Shian Lin seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", 847082a36dcSTsang-Shian Lin dm_info->cck_fa_cnt, 848082a36dcSTsang-Shian Lin dm_info->ofdm_fa_cnt, 849082a36dcSTsang-Shian Lin dm_info->total_fa_cnt); 850082a36dcSTsang-Shian Lin seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", 851082a36dcSTsang-Shian Lin dm_info->cck_ok_cnt, dm_info->cck_err_cnt); 852082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", 853082a36dcSTsang-Shian Lin dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); 854082a36dcSTsang-Shian Lin seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", 855082a36dcSTsang-Shian Lin dm_info->ht_ok_cnt, dm_info->ht_err_cnt); 856082a36dcSTsang-Shian Lin seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", 857082a36dcSTsang-Shian Lin dm_info->vht_ok_cnt, dm_info->vht_err_cnt); 8581fe188daSYan-Hsuan Chuang 8591fe188daSYan-Hsuan Chuang return 0; 8601fe188daSYan-Hsuan Chuang } 8611fe188daSYan-Hsuan Chuang 8621fe188daSYan-Hsuan Chuang static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) 8631fe188daSYan-Hsuan Chuang { 8641fe188daSYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 8651fe188daSYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8661fe188daSYan-Hsuan Chuang 8678647f7f0SSascha Hauer mutex_lock(&rtwdev->mutex); 8681fe188daSYan-Hsuan Chuang rtw_coex_display_coex_info(rtwdev, m); 8698647f7f0SSascha Hauer mutex_unlock(&rtwdev->mutex); 8701fe188daSYan-Hsuan Chuang 871082a36dcSTsang-Shian Lin return 0; 872082a36dcSTsang-Shian Lin } 873082a36dcSTsang-Shian Lin 874d0555093SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, 875d0555093SYan-Hsuan Chuang const char __user *buffer, 876d0555093SYan-Hsuan Chuang size_t count, loff_t *loff) 877d0555093SYan-Hsuan Chuang { 878d0555093SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 879d0555093SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 880d0555093SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 881d0555093SYan-Hsuan Chuang struct rtw_coex *coex = &rtwdev->coex; 882d0555093SYan-Hsuan Chuang char tmp[32 + 1]; 883d0555093SYan-Hsuan Chuang bool enable; 884d0555093SYan-Hsuan Chuang int ret; 885d0555093SYan-Hsuan Chuang 886*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 887*77005533SZhang Shurong if (ret) 888*77005533SZhang Shurong return ret; 889d0555093SYan-Hsuan Chuang 890d0555093SYan-Hsuan Chuang ret = kstrtobool(tmp, &enable); 891d0555093SYan-Hsuan Chuang if (ret) { 892d0555093SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid arguments\n"); 893d0555093SYan-Hsuan Chuang return ret; 894d0555093SYan-Hsuan Chuang } 895d0555093SYan-Hsuan Chuang 896d0555093SYan-Hsuan Chuang mutex_lock(&rtwdev->mutex); 897d3a78c7aSYANG LI coex->manual_control = !enable; 898d0555093SYan-Hsuan Chuang mutex_unlock(&rtwdev->mutex); 899d0555093SYan-Hsuan Chuang 900d0555093SYan-Hsuan Chuang return count; 901d0555093SYan-Hsuan Chuang } 902d0555093SYan-Hsuan Chuang 903d0555093SYan-Hsuan Chuang static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) 904d0555093SYan-Hsuan Chuang { 905d0555093SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 906d0555093SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 907d0555093SYan-Hsuan Chuang struct rtw_coex *coex = &rtwdev->coex; 908d0555093SYan-Hsuan Chuang 909d0555093SYan-Hsuan Chuang seq_printf(m, "coex mechanism %s\n", 91032c3a8c7SChing-Te Ku coex->manual_control ? "disabled" : "enabled"); 911d0555093SYan-Hsuan Chuang 912d0555093SYan-Hsuan Chuang return 0; 913d0555093SYan-Hsuan Chuang } 914d0555093SYan-Hsuan Chuang 9157285eb96SZong-Zhe Yang static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, 9167285eb96SZong-Zhe Yang const char __user *buffer, 9177285eb96SZong-Zhe Yang size_t count, loff_t *loff) 9187285eb96SZong-Zhe Yang { 9197285eb96SZong-Zhe Yang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 9207285eb96SZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 9217285eb96SZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9227285eb96SZong-Zhe Yang bool input; 9237285eb96SZong-Zhe Yang int err; 9247285eb96SZong-Zhe Yang 9257285eb96SZong-Zhe Yang err = kstrtobool_from_user(buffer, count, &input); 9267285eb96SZong-Zhe Yang if (err) 9277285eb96SZong-Zhe Yang return err; 9287285eb96SZong-Zhe Yang 9297285eb96SZong-Zhe Yang rtw_edcca_enabled = input; 9307285eb96SZong-Zhe Yang rtw_phy_adaptivity_set_mode(rtwdev); 9317285eb96SZong-Zhe Yang 9327285eb96SZong-Zhe Yang return count; 9337285eb96SZong-Zhe Yang } 9347285eb96SZong-Zhe Yang 9357285eb96SZong-Zhe Yang static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v) 9367285eb96SZong-Zhe Yang { 9377285eb96SZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 9387285eb96SZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9397285eb96SZong-Zhe Yang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 9407285eb96SZong-Zhe Yang 9417285eb96SZong-Zhe Yang seq_printf(m, "EDCCA %s: EDCCA mode %d\n", 9427285eb96SZong-Zhe Yang rtw_edcca_enabled ? "enabled" : "disabled", 9437285eb96SZong-Zhe Yang dm_info->edcca_mode); 9447285eb96SZong-Zhe Yang return 0; 9457285eb96SZong-Zhe Yang } 9467285eb96SZong-Zhe Yang 94713ce240aSZong-Zhe Yang static ssize_t rtw_debugfs_set_fw_crash(struct file *filp, 94813ce240aSZong-Zhe Yang const char __user *buffer, 94913ce240aSZong-Zhe Yang size_t count, loff_t *loff) 95013ce240aSZong-Zhe Yang { 95113ce240aSZong-Zhe Yang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 95213ce240aSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 95313ce240aSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 95413ce240aSZong-Zhe Yang char tmp[32 + 1]; 95513ce240aSZong-Zhe Yang bool input; 95613ce240aSZong-Zhe Yang int ret; 95713ce240aSZong-Zhe Yang 958*77005533SZhang Shurong ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 959*77005533SZhang Shurong if (ret) 960*77005533SZhang Shurong return ret; 96113ce240aSZong-Zhe Yang 96213ce240aSZong-Zhe Yang ret = kstrtobool(tmp, &input); 96313ce240aSZong-Zhe Yang if (ret) 96413ce240aSZong-Zhe Yang return -EINVAL; 96513ce240aSZong-Zhe Yang 96613ce240aSZong-Zhe Yang if (!input) 96713ce240aSZong-Zhe Yang return -EINVAL; 96813ce240aSZong-Zhe Yang 9697b80f3e4SZong-Zhe Yang if (test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) 9707b80f3e4SZong-Zhe Yang return -EINPROGRESS; 9717b80f3e4SZong-Zhe Yang 9727b80f3e4SZong-Zhe Yang mutex_lock(&rtwdev->mutex); 9737b80f3e4SZong-Zhe Yang rtw_leave_lps_deep(rtwdev); 9746cd4b59dSZong-Zhe Yang set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags); 97513ce240aSZong-Zhe Yang rtw_write8(rtwdev, REG_HRCV_MSG, 1); 9767b80f3e4SZong-Zhe Yang mutex_unlock(&rtwdev->mutex); 97713ce240aSZong-Zhe Yang 97813ce240aSZong-Zhe Yang return count; 97913ce240aSZong-Zhe Yang } 98013ce240aSZong-Zhe Yang 98113ce240aSZong-Zhe Yang static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v) 98213ce240aSZong-Zhe Yang { 98313ce240aSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 98413ce240aSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 98513ce240aSZong-Zhe Yang 9866cd4b59dSZong-Zhe Yang seq_printf(m, "%d\n", 9876cd4b59dSZong-Zhe Yang test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) || 9886cd4b59dSZong-Zhe Yang test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)); 98913ce240aSZong-Zhe Yang return 0; 99013ce240aSZong-Zhe Yang } 99113ce240aSZong-Zhe Yang 992272cda71SYu-Yen Ting static ssize_t rtw_debugfs_set_force_lowest_basic_rate(struct file *filp, 993272cda71SYu-Yen Ting const char __user *buffer, 994272cda71SYu-Yen Ting size_t count, loff_t *loff) 995272cda71SYu-Yen Ting { 996272cda71SYu-Yen Ting struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 997272cda71SYu-Yen Ting struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 998272cda71SYu-Yen Ting struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 999272cda71SYu-Yen Ting bool input; 1000272cda71SYu-Yen Ting int err; 1001272cda71SYu-Yen Ting 1002272cda71SYu-Yen Ting err = kstrtobool_from_user(buffer, count, &input); 1003272cda71SYu-Yen Ting if (err) 1004272cda71SYu-Yen Ting return err; 1005272cda71SYu-Yen Ting 1006272cda71SYu-Yen Ting if (input) 1007272cda71SYu-Yen Ting set_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 1008272cda71SYu-Yen Ting else 1009272cda71SYu-Yen Ting clear_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 1010272cda71SYu-Yen Ting 1011272cda71SYu-Yen Ting return count; 1012272cda71SYu-Yen Ting } 1013272cda71SYu-Yen Ting 1014272cda71SYu-Yen Ting static int rtw_debugfs_get_force_lowest_basic_rate(struct seq_file *m, void *v) 1015272cda71SYu-Yen Ting { 1016272cda71SYu-Yen Ting struct rtw_debugfs_priv *debugfs_priv = m->private; 1017272cda71SYu-Yen Ting struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 1018272cda71SYu-Yen Ting 1019272cda71SYu-Yen Ting seq_printf(m, "force lowest basic rate: %d\n", 1020272cda71SYu-Yen Ting test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags)); 1021272cda71SYu-Yen Ting 1022272cda71SYu-Yen Ting return 0; 1023272cda71SYu-Yen Ting } 1024272cda71SYu-Yen Ting 10253b25bac8SGuo-Feng Fan static ssize_t rtw_debugfs_set_dm_cap(struct file *filp, 10263b25bac8SGuo-Feng Fan const char __user *buffer, 10273b25bac8SGuo-Feng Fan size_t count, loff_t *loff) 10283b25bac8SGuo-Feng Fan { 10293b25bac8SGuo-Feng Fan struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 10303b25bac8SGuo-Feng Fan struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 10313b25bac8SGuo-Feng Fan struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 10323b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10333b25bac8SGuo-Feng Fan int bit; 10343b25bac8SGuo-Feng Fan bool en; 10353b25bac8SGuo-Feng Fan 10363b25bac8SGuo-Feng Fan if (kstrtoint_from_user(buffer, count, 10, &bit)) 10373b25bac8SGuo-Feng Fan return -EINVAL; 10383b25bac8SGuo-Feng Fan 10393b25bac8SGuo-Feng Fan en = bit > 0; 10403b25bac8SGuo-Feng Fan bit = abs(bit); 10413b25bac8SGuo-Feng Fan 10423b25bac8SGuo-Feng Fan if (bit >= RTW_DM_CAP_NUM) { 10433b25bac8SGuo-Feng Fan rtw_warn(rtwdev, "unknown DM CAP %d\n", bit); 10443b25bac8SGuo-Feng Fan return -EINVAL; 10453b25bac8SGuo-Feng Fan } 10463b25bac8SGuo-Feng Fan 10473b25bac8SGuo-Feng Fan if (en) 10483b25bac8SGuo-Feng Fan dm_info->dm_flags &= ~BIT(bit); 10493b25bac8SGuo-Feng Fan else 10503b25bac8SGuo-Feng Fan dm_info->dm_flags |= BIT(bit); 10513b25bac8SGuo-Feng Fan 10523b25bac8SGuo-Feng Fan debugfs_priv->dm_cap.bit = bit; 10533b25bac8SGuo-Feng Fan 10543b25bac8SGuo-Feng Fan return count; 10553b25bac8SGuo-Feng Fan } 10563b25bac8SGuo-Feng Fan 10573b25bac8SGuo-Feng Fan static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) 10583b25bac8SGuo-Feng Fan { 10593b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10603b25bac8SGuo-Feng Fan struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 10613b25bac8SGuo-Feng Fan int i, path; 10623b25bac8SGuo-Feng Fan u32 val; 10633b25bac8SGuo-Feng Fan 10643b25bac8SGuo-Feng Fan seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK, 10653b25bac8SGuo-Feng Fan dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', 10663b25bac8SGuo-Feng Fan rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); 10673b25bac8SGuo-Feng Fan 1068d57ca103SSascha Hauer mutex_lock(&rtwdev->mutex); 1069d57ca103SSascha Hauer 10703b25bac8SGuo-Feng Fan for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 10713b25bac8SGuo-Feng Fan val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); 10723b25bac8SGuo-Feng Fan seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); 10733b25bac8SGuo-Feng Fan 10743b25bac8SGuo-Feng Fan for (i = 0; i < RF_HW_OFFSET_NUM; i++) 10753b25bac8SGuo-Feng Fan seq_printf(m, "[TXGAPK] offset %d %d\n", 10763b25bac8SGuo-Feng Fan txgapk->rf3f_fs[path][i], i); 10773b25bac8SGuo-Feng Fan seq_puts(m, "\n"); 10783b25bac8SGuo-Feng Fan } 1079d57ca103SSascha Hauer mutex_unlock(&rtwdev->mutex); 10803b25bac8SGuo-Feng Fan } 10813b25bac8SGuo-Feng Fan 10823b25bac8SGuo-Feng Fan static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) 10833b25bac8SGuo-Feng Fan { 10843b25bac8SGuo-Feng Fan struct rtw_debugfs_priv *debugfs_priv = m->private; 10853b25bac8SGuo-Feng Fan struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 10863b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10873b25bac8SGuo-Feng Fan int i; 10883b25bac8SGuo-Feng Fan 10893b25bac8SGuo-Feng Fan switch (debugfs_priv->dm_cap.bit) { 10903b25bac8SGuo-Feng Fan case RTW_DM_CAP_TXGAPK: 10913b25bac8SGuo-Feng Fan dump_gapk_status(rtwdev, m); 10923b25bac8SGuo-Feng Fan break; 10933b25bac8SGuo-Feng Fan default: 10943b25bac8SGuo-Feng Fan for (i = 1; i < RTW_DM_CAP_NUM; i++) { 10953b25bac8SGuo-Feng Fan seq_printf(m, "(%2d) %c%s\n", i, 10963b25bac8SGuo-Feng Fan dm_info->dm_flags & BIT(i) ? '-' : '+', 10973b25bac8SGuo-Feng Fan rtw_dm_cap_strs[i]); 10983b25bac8SGuo-Feng Fan } 10993b25bac8SGuo-Feng Fan break; 11003b25bac8SGuo-Feng Fan } 11013b25bac8SGuo-Feng Fan debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA; 11023b25bac8SGuo-Feng Fan return 0; 11033b25bac8SGuo-Feng Fan } 11043b25bac8SGuo-Feng Fan 1105e3037485SYan-Hsuan Chuang #define rtw_debug_impl_mac(page, addr) \ 1106e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ 1107e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_mac_page, \ 1108e3037485SYan-Hsuan Chuang .cb_data = addr, \ 1109e3037485SYan-Hsuan Chuang } 1110e3037485SYan-Hsuan Chuang 1111e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(0, 0x0000); 1112e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(1, 0x0100); 1113e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(2, 0x0200); 1114e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(3, 0x0300); 1115e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(4, 0x0400); 1116e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(5, 0x0500); 1117e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(6, 0x0600); 1118e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(7, 0x0700); 1119e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(10, 0x1000); 1120e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(11, 0x1100); 1121e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(12, 0x1200); 1122e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(13, 0x1300); 1123e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(14, 0x1400); 1124e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(15, 0x1500); 1125e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(16, 0x1600); 1126e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(17, 0x1700); 1127e3037485SYan-Hsuan Chuang 1128e3037485SYan-Hsuan Chuang #define rtw_debug_impl_bb(page, addr) \ 1129e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \ 1130e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_bb_page, \ 1131e3037485SYan-Hsuan Chuang .cb_data = addr, \ 1132e3037485SYan-Hsuan Chuang } 1133e3037485SYan-Hsuan Chuang 1134e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(8, 0x0800); 1135e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(9, 0x0900); 1136e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(a, 0x0a00); 1137e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(b, 0x0b00); 1138e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(c, 0x0c00); 1139e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(d, 0x0d00); 1140e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(e, 0x0e00); 1141e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(f, 0x0f00); 1142e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(18, 0x1800); 1143e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(19, 0x1900); 1144e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1a, 0x1a00); 1145e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1b, 0x1b00); 1146e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1c, 0x1c00); 1147e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1d, 0x1d00); 1148e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1e, 0x1e00); 1149e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1f, 0x1f00); 1150e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(2c, 0x2c00); 1151e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(2d, 0x2d00); 1152e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(40, 0x4000); 1153e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(41, 0x4100); 1154e3037485SYan-Hsuan Chuang 1155e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = { 1156e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_rf_dump, 1157e3037485SYan-Hsuan Chuang }; 1158e3037485SYan-Hsuan Chuang 11598812022cSZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = { 11608812022cSZong-Zhe Yang .cb_read = rtw_debugfs_get_tx_pwr_tbl, 11618812022cSZong-Zhe Yang }; 11628812022cSZong-Zhe Yang 1163e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_write_reg = { 1164e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_write_reg, 1165e3037485SYan-Hsuan Chuang }; 1166e3037485SYan-Hsuan Chuang 1167c376c1fcSTzu-En Huang static struct rtw_debugfs_priv rtw_debug_priv_h2c = { 1168c376c1fcSTzu-En Huang .cb_write = rtw_debugfs_set_h2c, 1169c376c1fcSTzu-En Huang }; 1170c376c1fcSTzu-En Huang 1171e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_write = { 1172e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rf_write, 1173e3037485SYan-Hsuan Chuang }; 1174e3037485SYan-Hsuan Chuang 1175e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_read = { 1176e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rf_read, 1177e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_rf_read, 1178e3037485SYan-Hsuan Chuang }; 1179e3037485SYan-Hsuan Chuang 1180e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_read_reg = { 1181e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_read_reg, 1182e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_read_reg, 1183e3037485SYan-Hsuan Chuang }; 1184e3037485SYan-Hsuan Chuang 11851379e620SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = { 11861379e620SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_fix_rate, 11871379e620SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_fix_rate, 11881379e620SYan-Hsuan Chuang }; 11891379e620SYan-Hsuan Chuang 1190e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = { 1191e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_single_input, 1192e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_dump_cam, 1193e3037485SYan-Hsuan Chuang }; 1194e3037485SYan-Hsuan Chuang 1195e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = { 1196e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rsvd_page, 1197e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_rsvd_page, 1198e3037485SYan-Hsuan Chuang }; 1199e3037485SYan-Hsuan Chuang 1200082a36dcSTsang-Shian Lin static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { 1201082a36dcSTsang-Shian Lin .cb_read = rtw_debugfs_get_phy_info, 1202082a36dcSTsang-Shian Lin }; 1203082a36dcSTsang-Shian Lin 1204d0555093SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { 1205d0555093SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_coex_enable, 1206d0555093SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_coex_enable, 1207d0555093SYan-Hsuan Chuang }; 1208d0555093SYan-Hsuan Chuang 12091fe188daSYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { 12101fe188daSYan-Hsuan Chuang .cb_read = rtw_debugfs_get_coex_info, 12111fe188daSYan-Hsuan Chuang }; 12121fe188daSYan-Hsuan Chuang 12137285eb96SZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { 12147285eb96SZong-Zhe Yang .cb_write = rtw_debugfs_set_edcca_enable, 12157285eb96SZong-Zhe Yang .cb_read = rtw_debugfs_get_edcca_enable, 12167285eb96SZong-Zhe Yang }; 12177285eb96SZong-Zhe Yang 121813ce240aSZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { 121913ce240aSZong-Zhe Yang .cb_write = rtw_debugfs_set_fw_crash, 122013ce240aSZong-Zhe Yang .cb_read = rtw_debugfs_get_fw_crash, 122113ce240aSZong-Zhe Yang }; 122213ce240aSZong-Zhe Yang 1223272cda71SYu-Yen Ting static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = { 1224272cda71SYu-Yen Ting .cb_write = rtw_debugfs_set_force_lowest_basic_rate, 1225272cda71SYu-Yen Ting .cb_read = rtw_debugfs_get_force_lowest_basic_rate, 1226272cda71SYu-Yen Ting }; 1227272cda71SYu-Yen Ting 12283b25bac8SGuo-Feng Fan static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { 12293b25bac8SGuo-Feng Fan .cb_write = rtw_debugfs_set_dm_cap, 12303b25bac8SGuo-Feng Fan .cb_read = rtw_debugfs_get_dm_cap, 12313b25bac8SGuo-Feng Fan }; 12323b25bac8SGuo-Feng Fan 1233e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_core(name, mode, fopname, parent) \ 1234e3037485SYan-Hsuan Chuang do { \ 1235e3037485SYan-Hsuan Chuang rtw_debug_priv_ ##name.rtwdev = rtwdev; \ 1236e3037485SYan-Hsuan Chuang if (!debugfs_create_file(#name, mode, \ 1237e3037485SYan-Hsuan Chuang parent, &rtw_debug_priv_ ##name,\ 1238e3037485SYan-Hsuan Chuang &file_ops_ ##fopname)) \ 1239e3037485SYan-Hsuan Chuang pr_debug("Unable to initialize debugfs:%s\n", \ 1240e3037485SYan-Hsuan Chuang #name); \ 1241e3037485SYan-Hsuan Chuang } while (0) 1242e3037485SYan-Hsuan Chuang 1243e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_w(name) \ 1244e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir) 1245e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_rw(name) \ 1246e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir) 1247e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_r(name) \ 1248e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) 1249e3037485SYan-Hsuan Chuang 1250e3037485SYan-Hsuan Chuang void rtw_debugfs_init(struct rtw_dev *rtwdev) 1251e3037485SYan-Hsuan Chuang { 12529f7d65fbSColin Ian King struct dentry *debugfs_topdir; 1253e3037485SYan-Hsuan Chuang 1254e3037485SYan-Hsuan Chuang debugfs_topdir = debugfs_create_dir("rtw88", 1255e3037485SYan-Hsuan Chuang rtwdev->hw->wiphy->debugfsdir); 1256e3037485SYan-Hsuan Chuang rtw_debugfs_add_w(write_reg); 1257e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(read_reg); 1258e3037485SYan-Hsuan Chuang rtw_debugfs_add_w(rf_write); 1259e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(rf_read); 12601379e620SYan-Hsuan Chuang rtw_debugfs_add_rw(fix_rate); 1261e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(dump_cam); 1262e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(rsvd_page); 1263082a36dcSTsang-Shian Lin rtw_debugfs_add_r(phy_info); 12641fe188daSYan-Hsuan Chuang rtw_debugfs_add_r(coex_info); 1265d0555093SYan-Hsuan Chuang rtw_debugfs_add_rw(coex_enable); 1266c376c1fcSTzu-En Huang rtw_debugfs_add_w(h2c); 1267e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_0); 1268e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_1); 1269e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_2); 1270e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_3); 1271e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_4); 1272e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_5); 1273e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_6); 1274e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_7); 1275e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_8); 1276e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_9); 1277e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_a); 1278e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_b); 1279e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_c); 1280e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_d); 1281e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_e); 1282e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_f); 1283e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_10); 1284e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_11); 1285e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_12); 1286e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_13); 1287e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_14); 1288e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_15); 1289e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_16); 1290e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_17); 1291e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_18); 1292e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_19); 1293e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1a); 1294e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1b); 1295e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1c); 1296e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1d); 1297e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1e); 1298e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1f); 1299e3037485SYan-Hsuan Chuang if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { 1300e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_2c); 1301e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_2d); 1302e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_40); 1303e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_41); 1304e3037485SYan-Hsuan Chuang } 1305e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(rf_dump); 13068812022cSZong-Zhe Yang rtw_debugfs_add_r(tx_pwr_tbl); 13077285eb96SZong-Zhe Yang rtw_debugfs_add_rw(edcca_enable); 130813ce240aSZong-Zhe Yang rtw_debugfs_add_rw(fw_crash); 1309272cda71SYu-Yen Ting rtw_debugfs_add_rw(force_lowest_basic_rate); 13103b25bac8SGuo-Feng Fan rtw_debugfs_add_rw(dm_cap); 1311e3037485SYan-Hsuan Chuang } 1312e3037485SYan-Hsuan Chuang 1313e3037485SYan-Hsuan Chuang #endif /* CONFIG_RTW88_DEBUGFS */ 1314e3037485SYan-Hsuan Chuang 1315e3037485SYan-Hsuan Chuang #ifdef CONFIG_RTW88_DEBUG 1316e3037485SYan-Hsuan Chuang 1317e3037485SYan-Hsuan Chuang void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, 1318e3037485SYan-Hsuan Chuang const char *fmt, ...) 1319e3037485SYan-Hsuan Chuang { 1320e3037485SYan-Hsuan Chuang struct va_format vaf = { 1321e3037485SYan-Hsuan Chuang .fmt = fmt, 1322e3037485SYan-Hsuan Chuang }; 1323e3037485SYan-Hsuan Chuang va_list args; 1324e3037485SYan-Hsuan Chuang 1325e3037485SYan-Hsuan Chuang va_start(args, fmt); 1326e3037485SYan-Hsuan Chuang vaf.va = &args; 1327e3037485SYan-Hsuan Chuang 1328e3037485SYan-Hsuan Chuang if (rtw_debug_mask & mask) 1329e3037485SYan-Hsuan Chuang dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); 1330e3037485SYan-Hsuan Chuang 1331e3037485SYan-Hsuan Chuang va_end(args); 1332e3037485SYan-Hsuan Chuang } 1333e3037485SYan-Hsuan Chuang EXPORT_SYMBOL(__rtw_dbg); 1334e3037485SYan-Hsuan Chuang 1335e3037485SYan-Hsuan Chuang #endif /* CONFIG_RTW88_DEBUG */ 1336