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 147e3037485SYan-Hsuan Chuang val = rtw_read_rf(rtwdev, path, addr, mask); 148e3037485SYan-Hsuan Chuang 149e3037485SYan-Hsuan Chuang seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n", 150e3037485SYan-Hsuan Chuang path, addr, mask, val); 151e3037485SYan-Hsuan Chuang 152e3037485SYan-Hsuan Chuang return 0; 153e3037485SYan-Hsuan Chuang } 154e3037485SYan-Hsuan Chuang 1551379e620SYan-Hsuan Chuang static int rtw_debugfs_get_fix_rate(struct seq_file *m, void *v) 1561379e620SYan-Hsuan Chuang { 1571379e620SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 1581379e620SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 1591379e620SYan-Hsuan Chuang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1601379e620SYan-Hsuan Chuang u8 fix_rate = dm_info->fix_rate; 1611379e620SYan-Hsuan Chuang 1621379e620SYan-Hsuan Chuang if (fix_rate >= DESC_RATE_MAX) { 1631379e620SYan-Hsuan Chuang seq_printf(m, "Fix rate disabled, fix_rate = %u\n", fix_rate); 1641379e620SYan-Hsuan Chuang return 0; 1651379e620SYan-Hsuan Chuang } 1661379e620SYan-Hsuan Chuang 1671379e620SYan-Hsuan Chuang seq_printf(m, "Data frames fixed at desc rate %u\n", fix_rate); 1681379e620SYan-Hsuan Chuang return 0; 1691379e620SYan-Hsuan Chuang } 1701379e620SYan-Hsuan Chuang 171e3037485SYan-Hsuan Chuang static int rtw_debugfs_copy_from_user(char tmp[], int size, 172e3037485SYan-Hsuan Chuang const char __user *buffer, size_t count, 173e3037485SYan-Hsuan Chuang int num) 174e3037485SYan-Hsuan Chuang { 175e3037485SYan-Hsuan Chuang int tmp_len; 176e3037485SYan-Hsuan Chuang 17774a8c816SDan Carpenter memset(tmp, 0, size); 17874a8c816SDan Carpenter 179e3037485SYan-Hsuan Chuang if (count < num) 180e3037485SYan-Hsuan Chuang return -EFAULT; 181e3037485SYan-Hsuan Chuang 182e3037485SYan-Hsuan Chuang tmp_len = (count > size - 1 ? size - 1 : count); 183e3037485SYan-Hsuan Chuang 184e3037485SYan-Hsuan Chuang if (!buffer || copy_from_user(tmp, buffer, tmp_len)) 185e3037485SYan-Hsuan Chuang return count; 186e3037485SYan-Hsuan Chuang 187e3037485SYan-Hsuan Chuang tmp[tmp_len] = '\0'; 188e3037485SYan-Hsuan Chuang 189e3037485SYan-Hsuan Chuang return 0; 190e3037485SYan-Hsuan Chuang } 191e3037485SYan-Hsuan Chuang 192e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_read_reg(struct file *filp, 193e3037485SYan-Hsuan Chuang const char __user *buffer, 194e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 195e3037485SYan-Hsuan Chuang { 196e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 197e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 198e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 199e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 200e3037485SYan-Hsuan Chuang u32 addr, len; 201e3037485SYan-Hsuan Chuang int num; 202e3037485SYan-Hsuan Chuang 203e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 204e3037485SYan-Hsuan Chuang 205e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x", &addr, &len); 206e3037485SYan-Hsuan Chuang 207e3037485SYan-Hsuan Chuang if (num != 2) 208e3037485SYan-Hsuan Chuang return count; 209e3037485SYan-Hsuan Chuang 210e3037485SYan-Hsuan Chuang if (len != 1 && len != 2 && len != 4) { 211e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "read reg setting wrong len\n"); 212e3037485SYan-Hsuan Chuang return -EINVAL; 213e3037485SYan-Hsuan Chuang } 214e3037485SYan-Hsuan Chuang debugfs_priv->read_reg.addr = addr; 215e3037485SYan-Hsuan Chuang debugfs_priv->read_reg.len = len; 216e3037485SYan-Hsuan Chuang 217e3037485SYan-Hsuan Chuang return count; 218e3037485SYan-Hsuan Chuang } 219e3037485SYan-Hsuan Chuang 220e3037485SYan-Hsuan Chuang static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v) 221e3037485SYan-Hsuan Chuang { 222e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 223e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 224e3037485SYan-Hsuan Chuang u32 val, command; 225e3037485SYan-Hsuan Chuang u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT; 226e3037485SYan-Hsuan Chuang u32 read_cmd = RTW_SEC_CMD_POLLING; 227e3037485SYan-Hsuan Chuang int i; 228e3037485SYan-Hsuan Chuang 229e3037485SYan-Hsuan Chuang seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data); 230e3037485SYan-Hsuan Chuang seq_puts(m, "0x0 0x1 0x2 0x3 "); 231e3037485SYan-Hsuan Chuang seq_puts(m, "0x4 0x5\n"); 232e3037485SYan-Hsuan Chuang mutex_lock(&rtwdev->mutex); 233e3037485SYan-Hsuan Chuang for (i = 0; i <= 5; i++) { 234e3037485SYan-Hsuan Chuang command = read_cmd | (hw_key_idx + i); 235e3037485SYan-Hsuan Chuang rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); 236e3037485SYan-Hsuan Chuang val = rtw_read32(rtwdev, RTW_SEC_READ_REG); 237e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x", val); 238e3037485SYan-Hsuan Chuang if (i < 2) 239e3037485SYan-Hsuan Chuang seq_puts(m, " "); 240e3037485SYan-Hsuan Chuang } 241e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 242e3037485SYan-Hsuan Chuang mutex_unlock(&rtwdev->mutex); 243e3037485SYan-Hsuan Chuang return 0; 244e3037485SYan-Hsuan Chuang } 245e3037485SYan-Hsuan Chuang 246e3037485SYan-Hsuan Chuang static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v) 247e3037485SYan-Hsuan Chuang { 248e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 249e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 250e3037485SYan-Hsuan Chuang u8 page_size = rtwdev->chip->page_size; 251e3037485SYan-Hsuan Chuang u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; 252e3037485SYan-Hsuan Chuang u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; 253e3037485SYan-Hsuan Chuang u8 *buf; 254e3037485SYan-Hsuan Chuang int i; 255e3037485SYan-Hsuan Chuang int ret; 256e3037485SYan-Hsuan Chuang 257e3037485SYan-Hsuan Chuang buf = vzalloc(buf_size); 258e3037485SYan-Hsuan Chuang if (!buf) 259e3037485SYan-Hsuan Chuang return -ENOMEM; 260e3037485SYan-Hsuan Chuang 2610fbc2f0fSTzu-En Huang ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RSVD_PAGE, offset, 2620fbc2f0fSTzu-En Huang buf_size, (u32 *)buf); 263e3037485SYan-Hsuan Chuang if (ret) { 264e3037485SYan-Hsuan Chuang rtw_err(rtwdev, "failed to dump rsvd page\n"); 265e3037485SYan-Hsuan Chuang vfree(buf); 266e3037485SYan-Hsuan Chuang return ret; 267e3037485SYan-Hsuan Chuang } 268e3037485SYan-Hsuan Chuang 269e3037485SYan-Hsuan Chuang for (i = 0 ; i < buf_size ; i += 8) { 270e3037485SYan-Hsuan Chuang if (i % page_size == 0) 271e3037485SYan-Hsuan Chuang seq_printf(m, "PAGE %d\n", (i + offset) / page_size); 272d38c9df5SAndy Shevchenko seq_printf(m, "%8ph\n", buf + i); 273e3037485SYan-Hsuan Chuang } 274e3037485SYan-Hsuan Chuang vfree(buf); 275e3037485SYan-Hsuan Chuang 276e3037485SYan-Hsuan Chuang return 0; 277e3037485SYan-Hsuan Chuang } 278e3037485SYan-Hsuan Chuang 279e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp, 280e3037485SYan-Hsuan Chuang const char __user *buffer, 281e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 282e3037485SYan-Hsuan Chuang { 283e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 284e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 285e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 286e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 287e3037485SYan-Hsuan Chuang u32 offset, page_num; 288e3037485SYan-Hsuan Chuang int num; 289e3037485SYan-Hsuan Chuang 290e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 291e3037485SYan-Hsuan Chuang 292e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%d %d", &offset, &page_num); 293e3037485SYan-Hsuan Chuang 294e3037485SYan-Hsuan Chuang if (num != 2) { 295e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid arguments\n"); 296c9eaee0cSDan Carpenter return -EINVAL; 297e3037485SYan-Hsuan Chuang } 298e3037485SYan-Hsuan Chuang 299e3037485SYan-Hsuan Chuang debugfs_priv->rsvd_page.page_offset = offset; 300e3037485SYan-Hsuan Chuang debugfs_priv->rsvd_page.page_num = page_num; 301e3037485SYan-Hsuan Chuang 302e3037485SYan-Hsuan Chuang return count; 303e3037485SYan-Hsuan Chuang } 304e3037485SYan-Hsuan Chuang 305e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_single_input(struct file *filp, 306e3037485SYan-Hsuan Chuang const char __user *buffer, 307e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 308e3037485SYan-Hsuan Chuang { 309e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 310e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 311e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 312e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 313e3037485SYan-Hsuan Chuang u32 input; 314e3037485SYan-Hsuan Chuang int num; 315e3037485SYan-Hsuan Chuang 316e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 317e3037485SYan-Hsuan Chuang 318e3037485SYan-Hsuan Chuang num = kstrtoint(tmp, 0, &input); 319e3037485SYan-Hsuan Chuang 320e3037485SYan-Hsuan Chuang if (num) { 321e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "kstrtoint failed\n"); 322e3037485SYan-Hsuan Chuang return num; 323e3037485SYan-Hsuan Chuang } 324e3037485SYan-Hsuan Chuang 325e3037485SYan-Hsuan Chuang debugfs_priv->cb_data = input; 326e3037485SYan-Hsuan Chuang 327e3037485SYan-Hsuan Chuang return count; 328e3037485SYan-Hsuan Chuang } 329e3037485SYan-Hsuan Chuang 330e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_write_reg(struct file *filp, 331e3037485SYan-Hsuan Chuang const char __user *buffer, 332e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 333e3037485SYan-Hsuan Chuang { 334e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 335e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 336e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 337e3037485SYan-Hsuan Chuang u32 addr, val, len; 338e3037485SYan-Hsuan Chuang int num; 339e3037485SYan-Hsuan Chuang 340e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 341e3037485SYan-Hsuan Chuang 342e3037485SYan-Hsuan Chuang /* write BB/MAC register */ 343e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x", &addr, &val, &len); 344e3037485SYan-Hsuan Chuang 345e3037485SYan-Hsuan Chuang if (num != 3) 346e3037485SYan-Hsuan Chuang return count; 347e3037485SYan-Hsuan Chuang 348e3037485SYan-Hsuan Chuang switch (len) { 349e3037485SYan-Hsuan Chuang case 1: 350e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 351e3037485SYan-Hsuan Chuang "reg write8 0x%03x: 0x%08x\n", addr, val); 352e3037485SYan-Hsuan Chuang rtw_write8(rtwdev, addr, (u8)val); 353e3037485SYan-Hsuan Chuang break; 354e3037485SYan-Hsuan Chuang case 2: 355e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 356e3037485SYan-Hsuan Chuang "reg write16 0x%03x: 0x%08x\n", addr, val); 357e3037485SYan-Hsuan Chuang rtw_write16(rtwdev, addr, (u16)val); 358e3037485SYan-Hsuan Chuang break; 359e3037485SYan-Hsuan Chuang case 4: 360e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 361e3037485SYan-Hsuan Chuang "reg write32 0x%03x: 0x%08x\n", addr, val); 362e3037485SYan-Hsuan Chuang rtw_write32(rtwdev, addr, (u32)val); 363e3037485SYan-Hsuan Chuang break; 364e3037485SYan-Hsuan Chuang default: 365e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 366e3037485SYan-Hsuan Chuang "error write length = %d\n", len); 367e3037485SYan-Hsuan Chuang break; 368e3037485SYan-Hsuan Chuang } 369e3037485SYan-Hsuan Chuang 370e3037485SYan-Hsuan Chuang return count; 371e3037485SYan-Hsuan Chuang } 372e3037485SYan-Hsuan Chuang 373c376c1fcSTzu-En Huang static ssize_t rtw_debugfs_set_h2c(struct file *filp, 374c376c1fcSTzu-En Huang const char __user *buffer, 375c376c1fcSTzu-En Huang size_t count, loff_t *loff) 376c376c1fcSTzu-En Huang { 377c376c1fcSTzu-En Huang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 378c376c1fcSTzu-En Huang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 379c376c1fcSTzu-En Huang char tmp[32 + 1]; 380c376c1fcSTzu-En Huang u8 param[8]; 381c376c1fcSTzu-En Huang int num; 382c376c1fcSTzu-En Huang 383c376c1fcSTzu-En Huang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 384c376c1fcSTzu-En Huang 385c376c1fcSTzu-En Huang num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", 386c376c1fcSTzu-En Huang ¶m[0], ¶m[1], ¶m[2], ¶m[3], 387c376c1fcSTzu-En Huang ¶m[4], ¶m[5], ¶m[6], ¶m[7]); 388c376c1fcSTzu-En Huang if (num != 8) { 389a0061be4SPing-Ke Shih rtw_warn(rtwdev, "invalid H2C command format for debug\n"); 390c376c1fcSTzu-En Huang return -EINVAL; 391c376c1fcSTzu-En Huang } 392c376c1fcSTzu-En Huang 393c376c1fcSTzu-En Huang rtw_fw_h2c_cmd_dbg(rtwdev, param); 394c376c1fcSTzu-En Huang 395c376c1fcSTzu-En Huang return count; 396c376c1fcSTzu-En Huang } 397c376c1fcSTzu-En Huang 398e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rf_write(struct file *filp, 399e3037485SYan-Hsuan Chuang const char __user *buffer, 400e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 401e3037485SYan-Hsuan Chuang { 402e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 403e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 404e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 405e3037485SYan-Hsuan Chuang u32 path, addr, mask, val; 406e3037485SYan-Hsuan Chuang int num; 407e3037485SYan-Hsuan Chuang 408e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); 409e3037485SYan-Hsuan Chuang 410e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); 411e3037485SYan-Hsuan Chuang 412e3037485SYan-Hsuan Chuang if (num != 4) { 413e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 414e3037485SYan-Hsuan Chuang return count; 415e3037485SYan-Hsuan Chuang } 416e3037485SYan-Hsuan Chuang 417e3037485SYan-Hsuan Chuang rtw_write_rf(rtwdev, path, addr, mask, val); 418e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 419e3037485SYan-Hsuan Chuang "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", 420e3037485SYan-Hsuan Chuang path, addr, mask, val); 421e3037485SYan-Hsuan Chuang 422e3037485SYan-Hsuan Chuang return count; 423e3037485SYan-Hsuan Chuang } 424e3037485SYan-Hsuan Chuang 425e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rf_read(struct file *filp, 426e3037485SYan-Hsuan Chuang const char __user *buffer, 427e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 428e3037485SYan-Hsuan Chuang { 429e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 430e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 431e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 432e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 433e3037485SYan-Hsuan Chuang u32 path, addr, mask; 434e3037485SYan-Hsuan Chuang int num; 435e3037485SYan-Hsuan Chuang 436e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 437e3037485SYan-Hsuan Chuang 438e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); 439e3037485SYan-Hsuan Chuang 440e3037485SYan-Hsuan Chuang if (num != 3) { 441e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 442e3037485SYan-Hsuan Chuang return count; 443e3037485SYan-Hsuan Chuang } 444e3037485SYan-Hsuan Chuang 445e3037485SYan-Hsuan Chuang debugfs_priv->rf_path = path; 446e3037485SYan-Hsuan Chuang debugfs_priv->rf_addr = addr; 447e3037485SYan-Hsuan Chuang debugfs_priv->rf_mask = mask; 448e3037485SYan-Hsuan Chuang 449e3037485SYan-Hsuan Chuang return count; 450e3037485SYan-Hsuan Chuang } 451e3037485SYan-Hsuan Chuang 4521379e620SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_fix_rate(struct file *filp, 4531379e620SYan-Hsuan Chuang const char __user *buffer, 4541379e620SYan-Hsuan Chuang size_t count, loff_t *loff) 4551379e620SYan-Hsuan Chuang { 4561379e620SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 4571379e620SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 4581379e620SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 4591379e620SYan-Hsuan Chuang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 4601379e620SYan-Hsuan Chuang u8 fix_rate; 4611379e620SYan-Hsuan Chuang char tmp[32 + 1]; 4621379e620SYan-Hsuan Chuang int ret; 4631379e620SYan-Hsuan Chuang 4641379e620SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 4651379e620SYan-Hsuan Chuang 4661379e620SYan-Hsuan Chuang ret = kstrtou8(tmp, 0, &fix_rate); 4671379e620SYan-Hsuan Chuang if (ret) { 4681379e620SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [rate]\n"); 4691379e620SYan-Hsuan Chuang return ret; 4701379e620SYan-Hsuan Chuang } 4711379e620SYan-Hsuan Chuang 4721379e620SYan-Hsuan Chuang dm_info->fix_rate = fix_rate; 4731379e620SYan-Hsuan Chuang 4741379e620SYan-Hsuan Chuang return count; 4751379e620SYan-Hsuan Chuang } 4761379e620SYan-Hsuan Chuang 477e3037485SYan-Hsuan Chuang static int rtw_debug_get_mac_page(struct seq_file *m, void *v) 478e3037485SYan-Hsuan Chuang { 479e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 480e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 481e3037485SYan-Hsuan Chuang u32 page = debugfs_priv->cb_data; 482e3037485SYan-Hsuan Chuang int i, n; 483e3037485SYan-Hsuan Chuang int max = 0xff; 484e3037485SYan-Hsuan Chuang 4850e25262bSLee Jones rtw_read32(rtwdev, debugfs_priv->cb_data); 486e3037485SYan-Hsuan Chuang for (n = 0; n <= max; ) { 487e3037485SYan-Hsuan Chuang seq_printf(m, "\n%8.8x ", n + page); 488e3037485SYan-Hsuan Chuang for (i = 0; i < 4 && n <= max; i++, n += 4) 489e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", 490e3037485SYan-Hsuan Chuang rtw_read32(rtwdev, (page | n))); 491e3037485SYan-Hsuan Chuang } 492e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 493e3037485SYan-Hsuan Chuang return 0; 494e3037485SYan-Hsuan Chuang } 495e3037485SYan-Hsuan Chuang 496e3037485SYan-Hsuan Chuang static int rtw_debug_get_bb_page(struct seq_file *m, void *v) 497e3037485SYan-Hsuan Chuang { 498e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 499e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 500e3037485SYan-Hsuan Chuang u32 page = debugfs_priv->cb_data; 501e3037485SYan-Hsuan Chuang int i, n; 502e3037485SYan-Hsuan Chuang int max = 0xff; 503e3037485SYan-Hsuan Chuang 5040e25262bSLee Jones rtw_read32(rtwdev, debugfs_priv->cb_data); 505e3037485SYan-Hsuan Chuang for (n = 0; n <= max; ) { 506e3037485SYan-Hsuan Chuang seq_printf(m, "\n%8.8x ", n + page); 507e3037485SYan-Hsuan Chuang for (i = 0; i < 4 && n <= max; i++, n += 4) 508e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", 509e3037485SYan-Hsuan Chuang rtw_read32(rtwdev, (page | n))); 510e3037485SYan-Hsuan Chuang } 511e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 512e3037485SYan-Hsuan Chuang return 0; 513e3037485SYan-Hsuan Chuang } 514e3037485SYan-Hsuan Chuang 515e3037485SYan-Hsuan Chuang static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) 516e3037485SYan-Hsuan Chuang { 517e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 518e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 519e3037485SYan-Hsuan Chuang u32 addr, offset, data; 520e3037485SYan-Hsuan Chuang u8 path; 521e3037485SYan-Hsuan Chuang 522e3037485SYan-Hsuan Chuang for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 523e3037485SYan-Hsuan Chuang seq_printf(m, "RF path:%d\n", path); 524e3037485SYan-Hsuan Chuang for (addr = 0; addr < 0x100; addr += 4) { 525e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", addr); 526e3037485SYan-Hsuan Chuang for (offset = 0; offset < 4; offset++) { 527e3037485SYan-Hsuan Chuang data = rtw_read_rf(rtwdev, path, addr + offset, 528e3037485SYan-Hsuan Chuang 0xffffffff); 529e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", data); 530e3037485SYan-Hsuan Chuang } 531e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 532e3037485SYan-Hsuan Chuang } 533e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 534e3037485SYan-Hsuan Chuang } 535e3037485SYan-Hsuan Chuang 536e3037485SYan-Hsuan Chuang return 0; 537e3037485SYan-Hsuan Chuang } 538e3037485SYan-Hsuan Chuang 5398812022cSZong-Zhe Yang static void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate) 5408812022cSZong-Zhe Yang { 5418812022cSZong-Zhe Yang static const char * const 5428812022cSZong-Zhe Yang cck_rate[] = {"1M", "2M", "5.5M", "11M"}; 5438812022cSZong-Zhe Yang u8 idx = rate - DESC_RATE1M; 5448812022cSZong-Zhe Yang 5458812022cSZong-Zhe Yang seq_printf(m, " CCK_%-5s", cck_rate[idx]); 5468812022cSZong-Zhe Yang } 5478812022cSZong-Zhe Yang 5488812022cSZong-Zhe Yang static void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate) 5498812022cSZong-Zhe Yang { 5508812022cSZong-Zhe Yang static const char * const 5518812022cSZong-Zhe Yang ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"}; 5528812022cSZong-Zhe Yang u8 idx = rate - DESC_RATE6M; 5538812022cSZong-Zhe Yang 5548812022cSZong-Zhe Yang seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]); 5558812022cSZong-Zhe Yang } 5568812022cSZong-Zhe Yang 5578812022cSZong-Zhe Yang static void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate) 5588812022cSZong-Zhe Yang { 5598812022cSZong-Zhe Yang u8 mcs_n = rate - DESC_RATEMCS0; 5608812022cSZong-Zhe Yang 5618812022cSZong-Zhe Yang seq_printf(m, " MCS%-6u", mcs_n); 5628812022cSZong-Zhe Yang } 5638812022cSZong-Zhe Yang 5648812022cSZong-Zhe Yang static void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate) 5658812022cSZong-Zhe Yang { 5668812022cSZong-Zhe Yang u8 idx = rate - DESC_RATEVHT1SS_MCS0; 5678812022cSZong-Zhe Yang u8 n_ss, mcs_n; 5688812022cSZong-Zhe Yang 5698812022cSZong-Zhe Yang /* n spatial stream */ 5708812022cSZong-Zhe Yang n_ss = 1 + idx / 10; 5718812022cSZong-Zhe Yang /* MCS n */ 5728812022cSZong-Zhe Yang mcs_n = idx % 10; 5738812022cSZong-Zhe Yang seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); 5748812022cSZong-Zhe Yang } 5758812022cSZong-Zhe Yang 576082a36dcSTsang-Shian Lin static void rtw_print_rate(struct seq_file *m, u8 rate) 577082a36dcSTsang-Shian Lin { 578082a36dcSTsang-Shian Lin switch (rate) { 579082a36dcSTsang-Shian Lin case DESC_RATE1M...DESC_RATE11M: 580082a36dcSTsang-Shian Lin rtw_print_cck_rate_txt(m, rate); 581082a36dcSTsang-Shian Lin break; 582082a36dcSTsang-Shian Lin case DESC_RATE6M...DESC_RATE54M: 583082a36dcSTsang-Shian Lin rtw_print_ofdm_rate_txt(m, rate); 584082a36dcSTsang-Shian Lin break; 585082a36dcSTsang-Shian Lin case DESC_RATEMCS0...DESC_RATEMCS15: 586082a36dcSTsang-Shian Lin rtw_print_ht_rate_txt(m, rate); 587082a36dcSTsang-Shian Lin break; 588082a36dcSTsang-Shian Lin case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: 589082a36dcSTsang-Shian Lin rtw_print_vht_rate_txt(m, rate); 590082a36dcSTsang-Shian Lin break; 591082a36dcSTsang-Shian Lin default: 592082a36dcSTsang-Shian Lin seq_printf(m, " Unknown rate=0x%x\n", rate); 593082a36dcSTsang-Shian Lin break; 594082a36dcSTsang-Shian Lin } 595082a36dcSTsang-Shian Lin } 596082a36dcSTsang-Shian Lin 597fada0931STzu-En Huang #define case_REGD(src) \ 598fada0931STzu-En Huang case RTW_REGD_##src: return #src 599fada0931STzu-En Huang 600fada0931STzu-En Huang static const char *rtw_get_regd_string(u8 regd) 601fada0931STzu-En Huang { 602fada0931STzu-En Huang switch (regd) { 603fada0931STzu-En Huang case_REGD(FCC); 604fada0931STzu-En Huang case_REGD(MKK); 605fada0931STzu-En Huang case_REGD(ETSI); 606fada0931STzu-En Huang case_REGD(IC); 607fada0931STzu-En Huang case_REGD(KCC); 608fada0931STzu-En Huang case_REGD(ACMA); 609fada0931STzu-En Huang case_REGD(CHILE); 610fada0931STzu-En Huang case_REGD(UKRAINE); 611fada0931STzu-En Huang case_REGD(MEXICO); 612fada0931STzu-En Huang case_REGD(CN); 613fada0931STzu-En Huang case_REGD(WW); 614fada0931STzu-En Huang default: 615fada0931STzu-En Huang return "Unknown"; 616fada0931STzu-En Huang } 617fada0931STzu-En Huang } 618fada0931STzu-En Huang 6198812022cSZong-Zhe Yang static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) 6208812022cSZong-Zhe Yang { 6218812022cSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 6228812022cSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6238812022cSZong-Zhe Yang struct rtw_hal *hal = &rtwdev->hal; 624*685b474bSChih-Kang Chang u8 path, rate, bw, ch, regd; 6258812022cSZong-Zhe Yang struct rtw_power_params pwr_param = {0}; 626*685b474bSChih-Kang Chang 627*685b474bSChih-Kang Chang mutex_lock(&rtwdev->mutex); 628*685b474bSChih-Kang Chang bw = hal->current_band_width; 629*685b474bSChih-Kang Chang ch = hal->current_channel; 630*685b474bSChih-Kang Chang regd = rtw_regd_get(rtwdev); 6318812022cSZong-Zhe Yang 63215728937SZong-Zhe Yang seq_printf(m, "channel: %u\n", ch); 63315728937SZong-Zhe Yang seq_printf(m, "bandwidth: %u\n", bw); 634fada0931STzu-En Huang seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd)); 6358704d0beSZong-Zhe Yang seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n", 6368704d0beSZong-Zhe Yang "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem"); 6378812022cSZong-Zhe Yang 6388812022cSZong-Zhe Yang mutex_lock(&hal->tx_power_mutex); 6398812022cSZong-Zhe Yang for (path = RF_PATH_A; path <= RF_PATH_B; path++) { 6408812022cSZong-Zhe Yang /* there is no CCK rates used in 5G */ 6418812022cSZong-Zhe Yang if (hal->current_band_type == RTW_BAND_5G) 6428812022cSZong-Zhe Yang rate = DESC_RATE6M; 6438812022cSZong-Zhe Yang else 6448812022cSZong-Zhe Yang rate = DESC_RATE1M; 6458812022cSZong-Zhe Yang 6468812022cSZong-Zhe Yang /* now, not support vht 3ss and vht 4ss*/ 6478812022cSZong-Zhe Yang for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) { 6488812022cSZong-Zhe Yang /* now, not support ht 3ss and ht 4ss*/ 6498812022cSZong-Zhe Yang if (rate > DESC_RATEMCS15 && 6508812022cSZong-Zhe Yang rate < DESC_RATEVHT1SS_MCS0) 6518812022cSZong-Zhe Yang continue; 6528812022cSZong-Zhe Yang 6538812022cSZong-Zhe Yang rtw_get_tx_power_params(rtwdev, path, rate, bw, 6548812022cSZong-Zhe Yang ch, regd, &pwr_param); 6558812022cSZong-Zhe Yang 6568812022cSZong-Zhe Yang seq_printf(m, "%4c ", path + 'A'); 657082a36dcSTsang-Shian Lin rtw_print_rate(m, rate); 6588704d0beSZong-Zhe Yang seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d) %4d\n", 6598812022cSZong-Zhe Yang hal->tx_pwr_tbl[path][rate], 6608812022cSZong-Zhe Yang hal->tx_pwr_tbl[path][rate], 6618812022cSZong-Zhe Yang pwr_param.pwr_base, 6628704d0beSZong-Zhe Yang min3(pwr_param.pwr_offset, 6638704d0beSZong-Zhe Yang pwr_param.pwr_limit, 6648704d0beSZong-Zhe Yang pwr_param.pwr_sar), 665608d2a08SPing-Ke Shih pwr_param.pwr_offset, pwr_param.pwr_limit, 6668704d0beSZong-Zhe Yang pwr_param.pwr_sar, 667608d2a08SPing-Ke Shih pwr_param.pwr_remnant); 6688812022cSZong-Zhe Yang } 6698812022cSZong-Zhe Yang } 6708812022cSZong-Zhe Yang 6718812022cSZong-Zhe Yang mutex_unlock(&hal->tx_power_mutex); 672*685b474bSChih-Kang Chang mutex_unlock(&rtwdev->mutex); 6738812022cSZong-Zhe Yang 6748812022cSZong-Zhe Yang return 0; 6758812022cSZong-Zhe Yang } 6768812022cSZong-Zhe Yang 6771a589bd5SChing-Te Ku void rtw_debugfs_get_simple_phy_info(struct seq_file *m) 6781a589bd5SChing-Te Ku { 6791a589bd5SChing-Te Ku struct rtw_debugfs_priv *debugfs_priv = m->private; 6801a589bd5SChing-Te Ku struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6811a589bd5SChing-Te Ku struct rtw_hal *hal = &rtwdev->hal; 6821a589bd5SChing-Te Ku struct rtw_dm_info *dm_info = &rtwdev->dm_info; 6831a589bd5SChing-Te Ku struct rtw_traffic_stats *stats = &rtwdev->stats; 6841a589bd5SChing-Te Ku 6851a589bd5SChing-Te Ku seq_printf(m, "%-40s = %ddBm/ %d\n", "RSSI/ STA Channel", 6861a589bd5SChing-Te Ku dm_info->rssi[RF_PATH_A] - 100, hal->current_channel); 6871a589bd5SChing-Te Ku 6881a589bd5SChing-Te Ku seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 6891a589bd5SChing-Te Ku stats->tx_throughput, stats->rx_throughput); 6901a589bd5SChing-Te Ku 6911a589bd5SChing-Te Ku seq_puts(m, "[Tx Rate] = "); 6921a589bd5SChing-Te Ku rtw_print_rate(m, dm_info->tx_rate); 6931a589bd5SChing-Te Ku seq_printf(m, "(0x%x)\n", dm_info->tx_rate); 6941a589bd5SChing-Te Ku 6951a589bd5SChing-Te Ku seq_puts(m, "[Rx Rate] = "); 6961a589bd5SChing-Te Ku rtw_print_rate(m, dm_info->curr_rx_rate); 6971a589bd5SChing-Te Ku seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 6981a589bd5SChing-Te Ku } 6991a589bd5SChing-Te Ku 700082a36dcSTsang-Shian Lin static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) 701082a36dcSTsang-Shian Lin { 702082a36dcSTsang-Shian Lin struct rtw_debugfs_priv *debugfs_priv = m->private; 703082a36dcSTsang-Shian Lin struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 704082a36dcSTsang-Shian Lin struct rtw_dm_info *dm_info = &rtwdev->dm_info; 705082a36dcSTsang-Shian Lin struct rtw_traffic_stats *stats = &rtwdev->stats; 706082a36dcSTsang-Shian Lin struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; 707082a36dcSTsang-Shian Lin struct rtw_efuse *efuse = &rtwdev->efuse; 708082a36dcSTsang-Shian Lin struct ewma_evm *ewma_evm = dm_info->ewma_evm; 709082a36dcSTsang-Shian Lin struct ewma_snr *ewma_snr = dm_info->ewma_snr; 710082a36dcSTsang-Shian Lin u8 ss, rate_id; 711082a36dcSTsang-Shian Lin 712082a36dcSTsang-Shian Lin seq_puts(m, "==========[Common Info]========\n"); 713082a36dcSTsang-Shian Lin seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); 714082a36dcSTsang-Shian Lin seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); 715082a36dcSTsang-Shian Lin seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); 716082a36dcSTsang-Shian Lin seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); 71704e00ac9SChin-Yen Lee seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 718082a36dcSTsang-Shian Lin stats->tx_throughput, stats->rx_throughput); 71904e00ac9SChin-Yen Lee seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ? 72004e00ac9SChin-Yen Lee 'Y' : 'N'); 721082a36dcSTsang-Shian Lin 722082a36dcSTsang-Shian Lin seq_puts(m, "==========[Tx Phy Info]========\n"); 723082a36dcSTsang-Shian Lin seq_puts(m, "[Tx Rate] = "); 724082a36dcSTsang-Shian Lin rtw_print_rate(m, dm_info->tx_rate); 725082a36dcSTsang-Shian Lin seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); 726082a36dcSTsang-Shian Lin 727082a36dcSTsang-Shian Lin seq_puts(m, "==========[Rx Phy Info]========\n"); 728082a36dcSTsang-Shian Lin seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); 729082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Rate] = "); 730082a36dcSTsang-Shian Lin rtw_print_rate(m, dm_info->curr_rx_rate); 731082a36dcSTsang-Shian Lin seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 732082a36dcSTsang-Shian Lin 733082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Rate Count]:\n"); 734082a36dcSTsang-Shian Lin seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", 735082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE1M], 736082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE2M], 737082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE5_5M], 738082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE11M]); 739082a36dcSTsang-Shian Lin 740082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 741082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE6M], 742082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE9M], 743082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE12M], 744082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE18M], 745082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE24M], 746082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE36M], 747082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE48M], 748082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE54M]); 749082a36dcSTsang-Shian Lin 750082a36dcSTsang-Shian Lin for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 751082a36dcSTsang-Shian Lin rate_id = DESC_RATEMCS0 + ss * 8; 752082a36dcSTsang-Shian Lin seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 753082a36dcSTsang-Shian Lin ss * 8, ss * 8 + 7, 754082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id], 755082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 1], 756082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 2], 757082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 3], 758082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 4], 759082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 5], 760082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 6], 761082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 7]); 762082a36dcSTsang-Shian Lin } 763082a36dcSTsang-Shian Lin 764082a36dcSTsang-Shian Lin for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 765082a36dcSTsang-Shian Lin rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; 766082a36dcSTsang-Shian Lin seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", 767082a36dcSTsang-Shian Lin ss + 1, 768082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id], 769082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 1], 770082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 2], 771082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 3], 772082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 4], 773082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 5], 774082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 6], 775082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 7], 776082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 8], 777082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 9]); 778082a36dcSTsang-Shian Lin } 779082a36dcSTsang-Shian Lin 780082a36dcSTsang-Shian Lin seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", 781082a36dcSTsang-Shian Lin dm_info->rssi[RF_PATH_A] - 100, 782082a36dcSTsang-Shian Lin dm_info->rssi[RF_PATH_B] - 100); 783082a36dcSTsang-Shian Lin seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", 784082a36dcSTsang-Shian Lin dm_info->rx_evm_dbm[RF_PATH_A], 785082a36dcSTsang-Shian Lin dm_info->rx_evm_dbm[RF_PATH_B]); 786082a36dcSTsang-Shian Lin seq_printf(m, "[Rx SNR] = {%d, %d}\n", 787082a36dcSTsang-Shian Lin dm_info->rx_snr[RF_PATH_A], 788082a36dcSTsang-Shian Lin dm_info->rx_snr[RF_PATH_B]); 789082a36dcSTsang-Shian Lin seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", 790082a36dcSTsang-Shian Lin dm_info->cfo_tail[RF_PATH_A], 791082a36dcSTsang-Shian Lin dm_info->cfo_tail[RF_PATH_B]); 792082a36dcSTsang-Shian Lin 793082a36dcSTsang-Shian Lin if (dm_info->curr_rx_rate >= DESC_RATE11M) { 794082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Average Status]:\n"); 795082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", 796082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), 797082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); 798082a36dcSTsang-Shian Lin seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", 799082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), 800082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); 801082a36dcSTsang-Shian Lin seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", 802082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), 803082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), 804082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), 805082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); 806082a36dcSTsang-Shian Lin } 807082a36dcSTsang-Shian Lin 808082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Counter]:\n"); 809082a36dcSTsang-Shian Lin seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", 810082a36dcSTsang-Shian Lin dm_info->cck_cca_cnt, 811082a36dcSTsang-Shian Lin dm_info->ofdm_cca_cnt, 812082a36dcSTsang-Shian Lin dm_info->total_cca_cnt); 813082a36dcSTsang-Shian Lin seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", 814082a36dcSTsang-Shian Lin dm_info->cck_fa_cnt, 815082a36dcSTsang-Shian Lin dm_info->ofdm_fa_cnt, 816082a36dcSTsang-Shian Lin dm_info->total_fa_cnt); 817082a36dcSTsang-Shian Lin seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", 818082a36dcSTsang-Shian Lin dm_info->cck_ok_cnt, dm_info->cck_err_cnt); 819082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", 820082a36dcSTsang-Shian Lin dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); 821082a36dcSTsang-Shian Lin seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", 822082a36dcSTsang-Shian Lin dm_info->ht_ok_cnt, dm_info->ht_err_cnt); 823082a36dcSTsang-Shian Lin seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", 824082a36dcSTsang-Shian Lin dm_info->vht_ok_cnt, dm_info->vht_err_cnt); 8251fe188daSYan-Hsuan Chuang 8261fe188daSYan-Hsuan Chuang return 0; 8271fe188daSYan-Hsuan Chuang } 8281fe188daSYan-Hsuan Chuang 8291fe188daSYan-Hsuan Chuang static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) 8301fe188daSYan-Hsuan Chuang { 8311fe188daSYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 8321fe188daSYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8331fe188daSYan-Hsuan Chuang 8341fe188daSYan-Hsuan Chuang rtw_coex_display_coex_info(rtwdev, m); 8351fe188daSYan-Hsuan Chuang 836082a36dcSTsang-Shian Lin return 0; 837082a36dcSTsang-Shian Lin } 838082a36dcSTsang-Shian Lin 839d0555093SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, 840d0555093SYan-Hsuan Chuang const char __user *buffer, 841d0555093SYan-Hsuan Chuang size_t count, loff_t *loff) 842d0555093SYan-Hsuan Chuang { 843d0555093SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 844d0555093SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 845d0555093SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 846d0555093SYan-Hsuan Chuang struct rtw_coex *coex = &rtwdev->coex; 847d0555093SYan-Hsuan Chuang char tmp[32 + 1]; 848d0555093SYan-Hsuan Chuang bool enable; 849d0555093SYan-Hsuan Chuang int ret; 850d0555093SYan-Hsuan Chuang 851d0555093SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 852d0555093SYan-Hsuan Chuang 853d0555093SYan-Hsuan Chuang ret = kstrtobool(tmp, &enable); 854d0555093SYan-Hsuan Chuang if (ret) { 855d0555093SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid arguments\n"); 856d0555093SYan-Hsuan Chuang return ret; 857d0555093SYan-Hsuan Chuang } 858d0555093SYan-Hsuan Chuang 859d0555093SYan-Hsuan Chuang mutex_lock(&rtwdev->mutex); 860d3a78c7aSYANG LI coex->manual_control = !enable; 861d0555093SYan-Hsuan Chuang mutex_unlock(&rtwdev->mutex); 862d0555093SYan-Hsuan Chuang 863d0555093SYan-Hsuan Chuang return count; 864d0555093SYan-Hsuan Chuang } 865d0555093SYan-Hsuan Chuang 866d0555093SYan-Hsuan Chuang static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) 867d0555093SYan-Hsuan Chuang { 868d0555093SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 869d0555093SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 870d0555093SYan-Hsuan Chuang struct rtw_coex *coex = &rtwdev->coex; 871d0555093SYan-Hsuan Chuang 872d0555093SYan-Hsuan Chuang seq_printf(m, "coex mechanism %s\n", 87332c3a8c7SChing-Te Ku coex->manual_control ? "disabled" : "enabled"); 874d0555093SYan-Hsuan Chuang 875d0555093SYan-Hsuan Chuang return 0; 876d0555093SYan-Hsuan Chuang } 877d0555093SYan-Hsuan Chuang 8787285eb96SZong-Zhe Yang static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, 8797285eb96SZong-Zhe Yang const char __user *buffer, 8807285eb96SZong-Zhe Yang size_t count, loff_t *loff) 8817285eb96SZong-Zhe Yang { 8827285eb96SZong-Zhe Yang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 8837285eb96SZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 8847285eb96SZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8857285eb96SZong-Zhe Yang bool input; 8867285eb96SZong-Zhe Yang int err; 8877285eb96SZong-Zhe Yang 8887285eb96SZong-Zhe Yang err = kstrtobool_from_user(buffer, count, &input); 8897285eb96SZong-Zhe Yang if (err) 8907285eb96SZong-Zhe Yang return err; 8917285eb96SZong-Zhe Yang 8927285eb96SZong-Zhe Yang rtw_edcca_enabled = input; 8937285eb96SZong-Zhe Yang rtw_phy_adaptivity_set_mode(rtwdev); 8947285eb96SZong-Zhe Yang 8957285eb96SZong-Zhe Yang return count; 8967285eb96SZong-Zhe Yang } 8977285eb96SZong-Zhe Yang 8987285eb96SZong-Zhe Yang static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v) 8997285eb96SZong-Zhe Yang { 9007285eb96SZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 9017285eb96SZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9027285eb96SZong-Zhe Yang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 9037285eb96SZong-Zhe Yang 9047285eb96SZong-Zhe Yang seq_printf(m, "EDCCA %s: EDCCA mode %d\n", 9057285eb96SZong-Zhe Yang rtw_edcca_enabled ? "enabled" : "disabled", 9067285eb96SZong-Zhe Yang dm_info->edcca_mode); 9077285eb96SZong-Zhe Yang return 0; 9087285eb96SZong-Zhe Yang } 9097285eb96SZong-Zhe Yang 91013ce240aSZong-Zhe Yang static ssize_t rtw_debugfs_set_fw_crash(struct file *filp, 91113ce240aSZong-Zhe Yang const char __user *buffer, 91213ce240aSZong-Zhe Yang size_t count, loff_t *loff) 91313ce240aSZong-Zhe Yang { 91413ce240aSZong-Zhe Yang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 91513ce240aSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 91613ce240aSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 91713ce240aSZong-Zhe Yang char tmp[32 + 1]; 91813ce240aSZong-Zhe Yang bool input; 91913ce240aSZong-Zhe Yang int ret; 92013ce240aSZong-Zhe Yang 92113ce240aSZong-Zhe Yang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 92213ce240aSZong-Zhe Yang 92313ce240aSZong-Zhe Yang ret = kstrtobool(tmp, &input); 92413ce240aSZong-Zhe Yang if (ret) 92513ce240aSZong-Zhe Yang return -EINVAL; 92613ce240aSZong-Zhe Yang 92713ce240aSZong-Zhe Yang if (!input) 92813ce240aSZong-Zhe Yang return -EINVAL; 92913ce240aSZong-Zhe Yang 9307b80f3e4SZong-Zhe Yang if (test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) 9317b80f3e4SZong-Zhe Yang return -EINPROGRESS; 9327b80f3e4SZong-Zhe Yang 9337b80f3e4SZong-Zhe Yang mutex_lock(&rtwdev->mutex); 9347b80f3e4SZong-Zhe Yang rtw_leave_lps_deep(rtwdev); 9356cd4b59dSZong-Zhe Yang set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags); 93613ce240aSZong-Zhe Yang rtw_write8(rtwdev, REG_HRCV_MSG, 1); 9377b80f3e4SZong-Zhe Yang mutex_unlock(&rtwdev->mutex); 93813ce240aSZong-Zhe Yang 93913ce240aSZong-Zhe Yang return count; 94013ce240aSZong-Zhe Yang } 94113ce240aSZong-Zhe Yang 94213ce240aSZong-Zhe Yang static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v) 94313ce240aSZong-Zhe Yang { 94413ce240aSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 94513ce240aSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 94613ce240aSZong-Zhe Yang 9476cd4b59dSZong-Zhe Yang seq_printf(m, "%d\n", 9486cd4b59dSZong-Zhe Yang test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) || 9496cd4b59dSZong-Zhe Yang test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)); 95013ce240aSZong-Zhe Yang return 0; 95113ce240aSZong-Zhe Yang } 95213ce240aSZong-Zhe Yang 953272cda71SYu-Yen Ting static ssize_t rtw_debugfs_set_force_lowest_basic_rate(struct file *filp, 954272cda71SYu-Yen Ting const char __user *buffer, 955272cda71SYu-Yen Ting size_t count, loff_t *loff) 956272cda71SYu-Yen Ting { 957272cda71SYu-Yen Ting struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 958272cda71SYu-Yen Ting struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 959272cda71SYu-Yen Ting struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 960272cda71SYu-Yen Ting bool input; 961272cda71SYu-Yen Ting int err; 962272cda71SYu-Yen Ting 963272cda71SYu-Yen Ting err = kstrtobool_from_user(buffer, count, &input); 964272cda71SYu-Yen Ting if (err) 965272cda71SYu-Yen Ting return err; 966272cda71SYu-Yen Ting 967272cda71SYu-Yen Ting if (input) 968272cda71SYu-Yen Ting set_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 969272cda71SYu-Yen Ting else 970272cda71SYu-Yen Ting clear_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 971272cda71SYu-Yen Ting 972272cda71SYu-Yen Ting return count; 973272cda71SYu-Yen Ting } 974272cda71SYu-Yen Ting 975272cda71SYu-Yen Ting static int rtw_debugfs_get_force_lowest_basic_rate(struct seq_file *m, void *v) 976272cda71SYu-Yen Ting { 977272cda71SYu-Yen Ting struct rtw_debugfs_priv *debugfs_priv = m->private; 978272cda71SYu-Yen Ting struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 979272cda71SYu-Yen Ting 980272cda71SYu-Yen Ting seq_printf(m, "force lowest basic rate: %d\n", 981272cda71SYu-Yen Ting test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags)); 982272cda71SYu-Yen Ting 983272cda71SYu-Yen Ting return 0; 984272cda71SYu-Yen Ting } 985272cda71SYu-Yen Ting 9863b25bac8SGuo-Feng Fan static ssize_t rtw_debugfs_set_dm_cap(struct file *filp, 9873b25bac8SGuo-Feng Fan const char __user *buffer, 9883b25bac8SGuo-Feng Fan size_t count, loff_t *loff) 9893b25bac8SGuo-Feng Fan { 9903b25bac8SGuo-Feng Fan struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 9913b25bac8SGuo-Feng Fan struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 9923b25bac8SGuo-Feng Fan struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9933b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 9943b25bac8SGuo-Feng Fan int bit; 9953b25bac8SGuo-Feng Fan bool en; 9963b25bac8SGuo-Feng Fan 9973b25bac8SGuo-Feng Fan if (kstrtoint_from_user(buffer, count, 10, &bit)) 9983b25bac8SGuo-Feng Fan return -EINVAL; 9993b25bac8SGuo-Feng Fan 10003b25bac8SGuo-Feng Fan en = bit > 0; 10013b25bac8SGuo-Feng Fan bit = abs(bit); 10023b25bac8SGuo-Feng Fan 10033b25bac8SGuo-Feng Fan if (bit >= RTW_DM_CAP_NUM) { 10043b25bac8SGuo-Feng Fan rtw_warn(rtwdev, "unknown DM CAP %d\n", bit); 10053b25bac8SGuo-Feng Fan return -EINVAL; 10063b25bac8SGuo-Feng Fan } 10073b25bac8SGuo-Feng Fan 10083b25bac8SGuo-Feng Fan if (en) 10093b25bac8SGuo-Feng Fan dm_info->dm_flags &= ~BIT(bit); 10103b25bac8SGuo-Feng Fan else 10113b25bac8SGuo-Feng Fan dm_info->dm_flags |= BIT(bit); 10123b25bac8SGuo-Feng Fan 10133b25bac8SGuo-Feng Fan debugfs_priv->dm_cap.bit = bit; 10143b25bac8SGuo-Feng Fan 10153b25bac8SGuo-Feng Fan return count; 10163b25bac8SGuo-Feng Fan } 10173b25bac8SGuo-Feng Fan 10183b25bac8SGuo-Feng Fan static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) 10193b25bac8SGuo-Feng Fan { 10203b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10213b25bac8SGuo-Feng Fan struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 10223b25bac8SGuo-Feng Fan int i, path; 10233b25bac8SGuo-Feng Fan u32 val; 10243b25bac8SGuo-Feng Fan 10253b25bac8SGuo-Feng Fan seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK, 10263b25bac8SGuo-Feng Fan dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', 10273b25bac8SGuo-Feng Fan rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); 10283b25bac8SGuo-Feng Fan 10293b25bac8SGuo-Feng Fan for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 10303b25bac8SGuo-Feng Fan val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); 10313b25bac8SGuo-Feng Fan seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); 10323b25bac8SGuo-Feng Fan 10333b25bac8SGuo-Feng Fan for (i = 0; i < RF_HW_OFFSET_NUM; i++) 10343b25bac8SGuo-Feng Fan seq_printf(m, "[TXGAPK] offset %d %d\n", 10353b25bac8SGuo-Feng Fan txgapk->rf3f_fs[path][i], i); 10363b25bac8SGuo-Feng Fan seq_puts(m, "\n"); 10373b25bac8SGuo-Feng Fan } 10383b25bac8SGuo-Feng Fan } 10393b25bac8SGuo-Feng Fan 10403b25bac8SGuo-Feng Fan static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) 10413b25bac8SGuo-Feng Fan { 10423b25bac8SGuo-Feng Fan struct rtw_debugfs_priv *debugfs_priv = m->private; 10433b25bac8SGuo-Feng Fan struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 10443b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10453b25bac8SGuo-Feng Fan int i; 10463b25bac8SGuo-Feng Fan 10473b25bac8SGuo-Feng Fan switch (debugfs_priv->dm_cap.bit) { 10483b25bac8SGuo-Feng Fan case RTW_DM_CAP_TXGAPK: 10493b25bac8SGuo-Feng Fan dump_gapk_status(rtwdev, m); 10503b25bac8SGuo-Feng Fan break; 10513b25bac8SGuo-Feng Fan default: 10523b25bac8SGuo-Feng Fan for (i = 1; i < RTW_DM_CAP_NUM; i++) { 10533b25bac8SGuo-Feng Fan seq_printf(m, "(%2d) %c%s\n", i, 10543b25bac8SGuo-Feng Fan dm_info->dm_flags & BIT(i) ? '-' : '+', 10553b25bac8SGuo-Feng Fan rtw_dm_cap_strs[i]); 10563b25bac8SGuo-Feng Fan } 10573b25bac8SGuo-Feng Fan break; 10583b25bac8SGuo-Feng Fan } 10593b25bac8SGuo-Feng Fan debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA; 10603b25bac8SGuo-Feng Fan return 0; 10613b25bac8SGuo-Feng Fan } 10623b25bac8SGuo-Feng Fan 1063e3037485SYan-Hsuan Chuang #define rtw_debug_impl_mac(page, addr) \ 1064e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ 1065e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_mac_page, \ 1066e3037485SYan-Hsuan Chuang .cb_data = addr, \ 1067e3037485SYan-Hsuan Chuang } 1068e3037485SYan-Hsuan Chuang 1069e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(0, 0x0000); 1070e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(1, 0x0100); 1071e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(2, 0x0200); 1072e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(3, 0x0300); 1073e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(4, 0x0400); 1074e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(5, 0x0500); 1075e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(6, 0x0600); 1076e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(7, 0x0700); 1077e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(10, 0x1000); 1078e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(11, 0x1100); 1079e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(12, 0x1200); 1080e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(13, 0x1300); 1081e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(14, 0x1400); 1082e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(15, 0x1500); 1083e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(16, 0x1600); 1084e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(17, 0x1700); 1085e3037485SYan-Hsuan Chuang 1086e3037485SYan-Hsuan Chuang #define rtw_debug_impl_bb(page, addr) \ 1087e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \ 1088e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_bb_page, \ 1089e3037485SYan-Hsuan Chuang .cb_data = addr, \ 1090e3037485SYan-Hsuan Chuang } 1091e3037485SYan-Hsuan Chuang 1092e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(8, 0x0800); 1093e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(9, 0x0900); 1094e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(a, 0x0a00); 1095e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(b, 0x0b00); 1096e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(c, 0x0c00); 1097e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(d, 0x0d00); 1098e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(e, 0x0e00); 1099e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(f, 0x0f00); 1100e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(18, 0x1800); 1101e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(19, 0x1900); 1102e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1a, 0x1a00); 1103e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1b, 0x1b00); 1104e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1c, 0x1c00); 1105e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1d, 0x1d00); 1106e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1e, 0x1e00); 1107e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1f, 0x1f00); 1108e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(2c, 0x2c00); 1109e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(2d, 0x2d00); 1110e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(40, 0x4000); 1111e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(41, 0x4100); 1112e3037485SYan-Hsuan Chuang 1113e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = { 1114e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_rf_dump, 1115e3037485SYan-Hsuan Chuang }; 1116e3037485SYan-Hsuan Chuang 11178812022cSZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = { 11188812022cSZong-Zhe Yang .cb_read = rtw_debugfs_get_tx_pwr_tbl, 11198812022cSZong-Zhe Yang }; 11208812022cSZong-Zhe Yang 1121e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_write_reg = { 1122e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_write_reg, 1123e3037485SYan-Hsuan Chuang }; 1124e3037485SYan-Hsuan Chuang 1125c376c1fcSTzu-En Huang static struct rtw_debugfs_priv rtw_debug_priv_h2c = { 1126c376c1fcSTzu-En Huang .cb_write = rtw_debugfs_set_h2c, 1127c376c1fcSTzu-En Huang }; 1128c376c1fcSTzu-En Huang 1129e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_write = { 1130e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rf_write, 1131e3037485SYan-Hsuan Chuang }; 1132e3037485SYan-Hsuan Chuang 1133e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_read = { 1134e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rf_read, 1135e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_rf_read, 1136e3037485SYan-Hsuan Chuang }; 1137e3037485SYan-Hsuan Chuang 1138e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_read_reg = { 1139e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_read_reg, 1140e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_read_reg, 1141e3037485SYan-Hsuan Chuang }; 1142e3037485SYan-Hsuan Chuang 11431379e620SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = { 11441379e620SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_fix_rate, 11451379e620SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_fix_rate, 11461379e620SYan-Hsuan Chuang }; 11471379e620SYan-Hsuan Chuang 1148e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = { 1149e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_single_input, 1150e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_dump_cam, 1151e3037485SYan-Hsuan Chuang }; 1152e3037485SYan-Hsuan Chuang 1153e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = { 1154e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rsvd_page, 1155e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_rsvd_page, 1156e3037485SYan-Hsuan Chuang }; 1157e3037485SYan-Hsuan Chuang 1158082a36dcSTsang-Shian Lin static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { 1159082a36dcSTsang-Shian Lin .cb_read = rtw_debugfs_get_phy_info, 1160082a36dcSTsang-Shian Lin }; 1161082a36dcSTsang-Shian Lin 1162d0555093SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { 1163d0555093SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_coex_enable, 1164d0555093SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_coex_enable, 1165d0555093SYan-Hsuan Chuang }; 1166d0555093SYan-Hsuan Chuang 11671fe188daSYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { 11681fe188daSYan-Hsuan Chuang .cb_read = rtw_debugfs_get_coex_info, 11691fe188daSYan-Hsuan Chuang }; 11701fe188daSYan-Hsuan Chuang 11717285eb96SZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { 11727285eb96SZong-Zhe Yang .cb_write = rtw_debugfs_set_edcca_enable, 11737285eb96SZong-Zhe Yang .cb_read = rtw_debugfs_get_edcca_enable, 11747285eb96SZong-Zhe Yang }; 11757285eb96SZong-Zhe Yang 117613ce240aSZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { 117713ce240aSZong-Zhe Yang .cb_write = rtw_debugfs_set_fw_crash, 117813ce240aSZong-Zhe Yang .cb_read = rtw_debugfs_get_fw_crash, 117913ce240aSZong-Zhe Yang }; 118013ce240aSZong-Zhe Yang 1181272cda71SYu-Yen Ting static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = { 1182272cda71SYu-Yen Ting .cb_write = rtw_debugfs_set_force_lowest_basic_rate, 1183272cda71SYu-Yen Ting .cb_read = rtw_debugfs_get_force_lowest_basic_rate, 1184272cda71SYu-Yen Ting }; 1185272cda71SYu-Yen Ting 11863b25bac8SGuo-Feng Fan static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { 11873b25bac8SGuo-Feng Fan .cb_write = rtw_debugfs_set_dm_cap, 11883b25bac8SGuo-Feng Fan .cb_read = rtw_debugfs_get_dm_cap, 11893b25bac8SGuo-Feng Fan }; 11903b25bac8SGuo-Feng Fan 1191e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_core(name, mode, fopname, parent) \ 1192e3037485SYan-Hsuan Chuang do { \ 1193e3037485SYan-Hsuan Chuang rtw_debug_priv_ ##name.rtwdev = rtwdev; \ 1194e3037485SYan-Hsuan Chuang if (!debugfs_create_file(#name, mode, \ 1195e3037485SYan-Hsuan Chuang parent, &rtw_debug_priv_ ##name,\ 1196e3037485SYan-Hsuan Chuang &file_ops_ ##fopname)) \ 1197e3037485SYan-Hsuan Chuang pr_debug("Unable to initialize debugfs:%s\n", \ 1198e3037485SYan-Hsuan Chuang #name); \ 1199e3037485SYan-Hsuan Chuang } while (0) 1200e3037485SYan-Hsuan Chuang 1201e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_w(name) \ 1202e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir) 1203e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_rw(name) \ 1204e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir) 1205e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_r(name) \ 1206e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) 1207e3037485SYan-Hsuan Chuang 1208e3037485SYan-Hsuan Chuang void rtw_debugfs_init(struct rtw_dev *rtwdev) 1209e3037485SYan-Hsuan Chuang { 12109f7d65fbSColin Ian King struct dentry *debugfs_topdir; 1211e3037485SYan-Hsuan Chuang 1212e3037485SYan-Hsuan Chuang debugfs_topdir = debugfs_create_dir("rtw88", 1213e3037485SYan-Hsuan Chuang rtwdev->hw->wiphy->debugfsdir); 1214e3037485SYan-Hsuan Chuang rtw_debugfs_add_w(write_reg); 1215e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(read_reg); 1216e3037485SYan-Hsuan Chuang rtw_debugfs_add_w(rf_write); 1217e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(rf_read); 12181379e620SYan-Hsuan Chuang rtw_debugfs_add_rw(fix_rate); 1219e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(dump_cam); 1220e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(rsvd_page); 1221082a36dcSTsang-Shian Lin rtw_debugfs_add_r(phy_info); 12221fe188daSYan-Hsuan Chuang rtw_debugfs_add_r(coex_info); 1223d0555093SYan-Hsuan Chuang rtw_debugfs_add_rw(coex_enable); 1224c376c1fcSTzu-En Huang rtw_debugfs_add_w(h2c); 1225e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_0); 1226e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_1); 1227e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_2); 1228e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_3); 1229e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_4); 1230e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_5); 1231e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_6); 1232e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_7); 1233e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_8); 1234e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_9); 1235e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_a); 1236e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_b); 1237e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_c); 1238e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_d); 1239e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_e); 1240e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_f); 1241e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_10); 1242e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_11); 1243e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_12); 1244e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_13); 1245e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_14); 1246e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_15); 1247e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_16); 1248e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_17); 1249e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_18); 1250e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_19); 1251e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1a); 1252e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1b); 1253e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1c); 1254e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1d); 1255e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1e); 1256e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1f); 1257e3037485SYan-Hsuan Chuang if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { 1258e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_2c); 1259e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_2d); 1260e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_40); 1261e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_41); 1262e3037485SYan-Hsuan Chuang } 1263e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(rf_dump); 12648812022cSZong-Zhe Yang rtw_debugfs_add_r(tx_pwr_tbl); 12657285eb96SZong-Zhe Yang rtw_debugfs_add_rw(edcca_enable); 126613ce240aSZong-Zhe Yang rtw_debugfs_add_rw(fw_crash); 1267272cda71SYu-Yen Ting rtw_debugfs_add_rw(force_lowest_basic_rate); 12683b25bac8SGuo-Feng Fan rtw_debugfs_add_rw(dm_cap); 1269e3037485SYan-Hsuan Chuang } 1270e3037485SYan-Hsuan Chuang 1271e3037485SYan-Hsuan Chuang #endif /* CONFIG_RTW88_DEBUGFS */ 1272e3037485SYan-Hsuan Chuang 1273e3037485SYan-Hsuan Chuang #ifdef CONFIG_RTW88_DEBUG 1274e3037485SYan-Hsuan Chuang 1275e3037485SYan-Hsuan Chuang void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, 1276e3037485SYan-Hsuan Chuang const char *fmt, ...) 1277e3037485SYan-Hsuan Chuang { 1278e3037485SYan-Hsuan Chuang struct va_format vaf = { 1279e3037485SYan-Hsuan Chuang .fmt = fmt, 1280e3037485SYan-Hsuan Chuang }; 1281e3037485SYan-Hsuan Chuang va_list args; 1282e3037485SYan-Hsuan Chuang 1283e3037485SYan-Hsuan Chuang va_start(args, fmt); 1284e3037485SYan-Hsuan Chuang vaf.va = &args; 1285e3037485SYan-Hsuan Chuang 1286e3037485SYan-Hsuan Chuang if (rtw_debug_mask & mask) 1287e3037485SYan-Hsuan Chuang dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); 1288e3037485SYan-Hsuan Chuang 1289e3037485SYan-Hsuan Chuang va_end(args); 1290e3037485SYan-Hsuan Chuang } 1291e3037485SYan-Hsuan Chuang EXPORT_SYMBOL(__rtw_dbg); 1292e3037485SYan-Hsuan Chuang 1293e3037485SYan-Hsuan Chuang #endif /* CONFIG_RTW88_DEBUG */ 1294