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 186e3037485SYan-Hsuan Chuang if (!buffer || copy_from_user(tmp, buffer, tmp_len)) 187e3037485SYan-Hsuan Chuang return count; 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; 204e3037485SYan-Hsuan Chuang 205e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 206e3037485SYan-Hsuan Chuang 207e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x", &addr, &len); 208e3037485SYan-Hsuan Chuang 209e3037485SYan-Hsuan Chuang if (num != 2) 210e3037485SYan-Hsuan Chuang return count; 211e3037485SYan-Hsuan Chuang 212e3037485SYan-Hsuan Chuang if (len != 1 && len != 2 && len != 4) { 213e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "read reg setting wrong len\n"); 214e3037485SYan-Hsuan Chuang return -EINVAL; 215e3037485SYan-Hsuan Chuang } 216e3037485SYan-Hsuan Chuang debugfs_priv->read_reg.addr = addr; 217e3037485SYan-Hsuan Chuang debugfs_priv->read_reg.len = len; 218e3037485SYan-Hsuan Chuang 219e3037485SYan-Hsuan Chuang return count; 220e3037485SYan-Hsuan Chuang } 221e3037485SYan-Hsuan Chuang 222e3037485SYan-Hsuan Chuang static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v) 223e3037485SYan-Hsuan Chuang { 224e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 225e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 226e3037485SYan-Hsuan Chuang u32 val, command; 227e3037485SYan-Hsuan Chuang u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT; 228e3037485SYan-Hsuan Chuang u32 read_cmd = RTW_SEC_CMD_POLLING; 229e3037485SYan-Hsuan Chuang int i; 230e3037485SYan-Hsuan Chuang 231e3037485SYan-Hsuan Chuang seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data); 232e3037485SYan-Hsuan Chuang seq_puts(m, "0x0 0x1 0x2 0x3 "); 233e3037485SYan-Hsuan Chuang seq_puts(m, "0x4 0x5\n"); 234e3037485SYan-Hsuan Chuang mutex_lock(&rtwdev->mutex); 235e3037485SYan-Hsuan Chuang for (i = 0; i <= 5; i++) { 236e3037485SYan-Hsuan Chuang command = read_cmd | (hw_key_idx + i); 237e3037485SYan-Hsuan Chuang rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); 238e3037485SYan-Hsuan Chuang val = rtw_read32(rtwdev, RTW_SEC_READ_REG); 239e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x", val); 240e3037485SYan-Hsuan Chuang if (i < 2) 241e3037485SYan-Hsuan Chuang seq_puts(m, " "); 242e3037485SYan-Hsuan Chuang } 243e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 244e3037485SYan-Hsuan Chuang mutex_unlock(&rtwdev->mutex); 245e3037485SYan-Hsuan Chuang return 0; 246e3037485SYan-Hsuan Chuang } 247e3037485SYan-Hsuan Chuang 248e3037485SYan-Hsuan Chuang static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v) 249e3037485SYan-Hsuan Chuang { 250e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 251e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 252e3037485SYan-Hsuan Chuang u8 page_size = rtwdev->chip->page_size; 253e3037485SYan-Hsuan Chuang u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; 254e3037485SYan-Hsuan Chuang u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; 255e3037485SYan-Hsuan Chuang u8 *buf; 256e3037485SYan-Hsuan Chuang int i; 257e3037485SYan-Hsuan Chuang int ret; 258e3037485SYan-Hsuan Chuang 259e3037485SYan-Hsuan Chuang buf = vzalloc(buf_size); 260e3037485SYan-Hsuan Chuang if (!buf) 261e3037485SYan-Hsuan Chuang return -ENOMEM; 262e3037485SYan-Hsuan Chuang 2630fbc2f0fSTzu-En Huang ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RSVD_PAGE, offset, 2640fbc2f0fSTzu-En Huang buf_size, (u32 *)buf); 265e3037485SYan-Hsuan Chuang if (ret) { 266e3037485SYan-Hsuan Chuang rtw_err(rtwdev, "failed to dump rsvd page\n"); 267e3037485SYan-Hsuan Chuang vfree(buf); 268e3037485SYan-Hsuan Chuang return ret; 269e3037485SYan-Hsuan Chuang } 270e3037485SYan-Hsuan Chuang 271e3037485SYan-Hsuan Chuang for (i = 0 ; i < buf_size ; i += 8) { 272e3037485SYan-Hsuan Chuang if (i % page_size == 0) 273e3037485SYan-Hsuan Chuang seq_printf(m, "PAGE %d\n", (i + offset) / page_size); 274d38c9df5SAndy Shevchenko seq_printf(m, "%8ph\n", buf + i); 275e3037485SYan-Hsuan Chuang } 276e3037485SYan-Hsuan Chuang vfree(buf); 277e3037485SYan-Hsuan Chuang 278e3037485SYan-Hsuan Chuang return 0; 279e3037485SYan-Hsuan Chuang } 280e3037485SYan-Hsuan Chuang 281e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp, 282e3037485SYan-Hsuan Chuang const char __user *buffer, 283e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 284e3037485SYan-Hsuan Chuang { 285e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 286e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 287e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 288e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 289e3037485SYan-Hsuan Chuang u32 offset, page_num; 290e3037485SYan-Hsuan Chuang int num; 291e3037485SYan-Hsuan Chuang 292e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 293e3037485SYan-Hsuan Chuang 294e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%d %d", &offset, &page_num); 295e3037485SYan-Hsuan Chuang 296e3037485SYan-Hsuan Chuang if (num != 2) { 297e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid arguments\n"); 298c9eaee0cSDan Carpenter return -EINVAL; 299e3037485SYan-Hsuan Chuang } 300e3037485SYan-Hsuan Chuang 301e3037485SYan-Hsuan Chuang debugfs_priv->rsvd_page.page_offset = offset; 302e3037485SYan-Hsuan Chuang debugfs_priv->rsvd_page.page_num = page_num; 303e3037485SYan-Hsuan Chuang 304e3037485SYan-Hsuan Chuang return count; 305e3037485SYan-Hsuan Chuang } 306e3037485SYan-Hsuan Chuang 307e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_single_input(struct file *filp, 308e3037485SYan-Hsuan Chuang const char __user *buffer, 309e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 310e3037485SYan-Hsuan Chuang { 311e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 312e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 313e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 314e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 315e3037485SYan-Hsuan Chuang u32 input; 316e3037485SYan-Hsuan Chuang int num; 317e3037485SYan-Hsuan Chuang 318e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 319e3037485SYan-Hsuan Chuang 320e3037485SYan-Hsuan Chuang num = kstrtoint(tmp, 0, &input); 321e3037485SYan-Hsuan Chuang 322e3037485SYan-Hsuan Chuang if (num) { 323e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "kstrtoint failed\n"); 324e3037485SYan-Hsuan Chuang return num; 325e3037485SYan-Hsuan Chuang } 326e3037485SYan-Hsuan Chuang 327e3037485SYan-Hsuan Chuang debugfs_priv->cb_data = input; 328e3037485SYan-Hsuan Chuang 329e3037485SYan-Hsuan Chuang return count; 330e3037485SYan-Hsuan Chuang } 331e3037485SYan-Hsuan Chuang 332e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_write_reg(struct file *filp, 333e3037485SYan-Hsuan Chuang const char __user *buffer, 334e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 335e3037485SYan-Hsuan Chuang { 336e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 337e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 338e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 339e3037485SYan-Hsuan Chuang u32 addr, val, len; 340e3037485SYan-Hsuan Chuang int num; 341e3037485SYan-Hsuan Chuang 342e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 343e3037485SYan-Hsuan Chuang 344e3037485SYan-Hsuan Chuang /* write BB/MAC register */ 345e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x", &addr, &val, &len); 346e3037485SYan-Hsuan Chuang 347e3037485SYan-Hsuan Chuang if (num != 3) 348e3037485SYan-Hsuan Chuang return count; 349e3037485SYan-Hsuan Chuang 350e3037485SYan-Hsuan Chuang switch (len) { 351e3037485SYan-Hsuan Chuang case 1: 352e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 353e3037485SYan-Hsuan Chuang "reg write8 0x%03x: 0x%08x\n", addr, val); 354e3037485SYan-Hsuan Chuang rtw_write8(rtwdev, addr, (u8)val); 355e3037485SYan-Hsuan Chuang break; 356e3037485SYan-Hsuan Chuang case 2: 357e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 358e3037485SYan-Hsuan Chuang "reg write16 0x%03x: 0x%08x\n", addr, val); 359e3037485SYan-Hsuan Chuang rtw_write16(rtwdev, addr, (u16)val); 360e3037485SYan-Hsuan Chuang break; 361e3037485SYan-Hsuan Chuang case 4: 362e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 363e3037485SYan-Hsuan Chuang "reg write32 0x%03x: 0x%08x\n", addr, val); 364e3037485SYan-Hsuan Chuang rtw_write32(rtwdev, addr, (u32)val); 365e3037485SYan-Hsuan Chuang break; 366e3037485SYan-Hsuan Chuang default: 367e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 368e3037485SYan-Hsuan Chuang "error write length = %d\n", len); 369e3037485SYan-Hsuan Chuang break; 370e3037485SYan-Hsuan Chuang } 371e3037485SYan-Hsuan Chuang 372e3037485SYan-Hsuan Chuang return count; 373e3037485SYan-Hsuan Chuang } 374e3037485SYan-Hsuan Chuang 375c376c1fcSTzu-En Huang static ssize_t rtw_debugfs_set_h2c(struct file *filp, 376c376c1fcSTzu-En Huang const char __user *buffer, 377c376c1fcSTzu-En Huang size_t count, loff_t *loff) 378c376c1fcSTzu-En Huang { 379c376c1fcSTzu-En Huang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 380c376c1fcSTzu-En Huang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 381c376c1fcSTzu-En Huang char tmp[32 + 1]; 382c376c1fcSTzu-En Huang u8 param[8]; 383c376c1fcSTzu-En Huang int num; 384c376c1fcSTzu-En Huang 385c376c1fcSTzu-En Huang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 386c376c1fcSTzu-En Huang 387c376c1fcSTzu-En Huang num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", 388c376c1fcSTzu-En Huang ¶m[0], ¶m[1], ¶m[2], ¶m[3], 389c376c1fcSTzu-En Huang ¶m[4], ¶m[5], ¶m[6], ¶m[7]); 390c376c1fcSTzu-En Huang if (num != 8) { 391a0061be4SPing-Ke Shih rtw_warn(rtwdev, "invalid H2C command format for debug\n"); 392c376c1fcSTzu-En Huang return -EINVAL; 393c376c1fcSTzu-En Huang } 394c376c1fcSTzu-En Huang 395*1e2701f4SSascha Hauer mutex_lock(&rtwdev->mutex); 396c376c1fcSTzu-En Huang rtw_fw_h2c_cmd_dbg(rtwdev, param); 397*1e2701f4SSascha Hauer mutex_unlock(&rtwdev->mutex); 398c376c1fcSTzu-En Huang 399c376c1fcSTzu-En Huang return count; 400c376c1fcSTzu-En Huang } 401c376c1fcSTzu-En Huang 402e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rf_write(struct file *filp, 403e3037485SYan-Hsuan Chuang const char __user *buffer, 404e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 405e3037485SYan-Hsuan Chuang { 406e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 407e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 408e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 409e3037485SYan-Hsuan Chuang u32 path, addr, mask, val; 410e3037485SYan-Hsuan Chuang int num; 411e3037485SYan-Hsuan Chuang 412e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); 413e3037485SYan-Hsuan Chuang 414e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); 415e3037485SYan-Hsuan Chuang 416e3037485SYan-Hsuan Chuang if (num != 4) { 417e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 418e3037485SYan-Hsuan Chuang return count; 419e3037485SYan-Hsuan Chuang } 420e3037485SYan-Hsuan Chuang 421d57ca103SSascha Hauer mutex_lock(&rtwdev->mutex); 422e3037485SYan-Hsuan Chuang rtw_write_rf(rtwdev, path, addr, mask, val); 423d57ca103SSascha Hauer mutex_unlock(&rtwdev->mutex); 424e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 425e3037485SYan-Hsuan Chuang "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", 426e3037485SYan-Hsuan Chuang path, addr, mask, val); 427e3037485SYan-Hsuan Chuang 428e3037485SYan-Hsuan Chuang return count; 429e3037485SYan-Hsuan Chuang } 430e3037485SYan-Hsuan Chuang 431e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rf_read(struct file *filp, 432e3037485SYan-Hsuan Chuang const char __user *buffer, 433e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 434e3037485SYan-Hsuan Chuang { 435e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 436e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 437e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 438e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 439e3037485SYan-Hsuan Chuang u32 path, addr, mask; 440e3037485SYan-Hsuan Chuang int num; 441e3037485SYan-Hsuan Chuang 442e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 443e3037485SYan-Hsuan Chuang 444e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); 445e3037485SYan-Hsuan Chuang 446e3037485SYan-Hsuan Chuang if (num != 3) { 447e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 448e3037485SYan-Hsuan Chuang return count; 449e3037485SYan-Hsuan Chuang } 450e3037485SYan-Hsuan Chuang 451e3037485SYan-Hsuan Chuang debugfs_priv->rf_path = path; 452e3037485SYan-Hsuan Chuang debugfs_priv->rf_addr = addr; 453e3037485SYan-Hsuan Chuang debugfs_priv->rf_mask = mask; 454e3037485SYan-Hsuan Chuang 455e3037485SYan-Hsuan Chuang return count; 456e3037485SYan-Hsuan Chuang } 457e3037485SYan-Hsuan Chuang 4581379e620SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_fix_rate(struct file *filp, 4591379e620SYan-Hsuan Chuang const char __user *buffer, 4601379e620SYan-Hsuan Chuang size_t count, loff_t *loff) 4611379e620SYan-Hsuan Chuang { 4621379e620SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 4631379e620SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 4641379e620SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 4651379e620SYan-Hsuan Chuang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 4661379e620SYan-Hsuan Chuang u8 fix_rate; 4671379e620SYan-Hsuan Chuang char tmp[32 + 1]; 4681379e620SYan-Hsuan Chuang int ret; 4691379e620SYan-Hsuan Chuang 4701379e620SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 4711379e620SYan-Hsuan Chuang 4721379e620SYan-Hsuan Chuang ret = kstrtou8(tmp, 0, &fix_rate); 4731379e620SYan-Hsuan Chuang if (ret) { 4741379e620SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [rate]\n"); 4751379e620SYan-Hsuan Chuang return ret; 4761379e620SYan-Hsuan Chuang } 4771379e620SYan-Hsuan Chuang 4781379e620SYan-Hsuan Chuang dm_info->fix_rate = fix_rate; 4791379e620SYan-Hsuan Chuang 4801379e620SYan-Hsuan Chuang return count; 4811379e620SYan-Hsuan Chuang } 4821379e620SYan-Hsuan Chuang 483e3037485SYan-Hsuan Chuang static int rtw_debug_get_mac_page(struct seq_file *m, void *v) 484e3037485SYan-Hsuan Chuang { 485e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 486e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 487e3037485SYan-Hsuan Chuang u32 page = debugfs_priv->cb_data; 488e3037485SYan-Hsuan Chuang int i, n; 489e3037485SYan-Hsuan Chuang int max = 0xff; 490e3037485SYan-Hsuan Chuang 4910e25262bSLee Jones rtw_read32(rtwdev, debugfs_priv->cb_data); 492e3037485SYan-Hsuan Chuang for (n = 0; n <= max; ) { 493e3037485SYan-Hsuan Chuang seq_printf(m, "\n%8.8x ", n + page); 494e3037485SYan-Hsuan Chuang for (i = 0; i < 4 && n <= max; i++, n += 4) 495e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", 496e3037485SYan-Hsuan Chuang rtw_read32(rtwdev, (page | n))); 497e3037485SYan-Hsuan Chuang } 498e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 499e3037485SYan-Hsuan Chuang return 0; 500e3037485SYan-Hsuan Chuang } 501e3037485SYan-Hsuan Chuang 502e3037485SYan-Hsuan Chuang static int rtw_debug_get_bb_page(struct seq_file *m, void *v) 503e3037485SYan-Hsuan Chuang { 504e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 505e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 506e3037485SYan-Hsuan Chuang u32 page = debugfs_priv->cb_data; 507e3037485SYan-Hsuan Chuang int i, n; 508e3037485SYan-Hsuan Chuang int max = 0xff; 509e3037485SYan-Hsuan Chuang 5100e25262bSLee Jones rtw_read32(rtwdev, debugfs_priv->cb_data); 511e3037485SYan-Hsuan Chuang for (n = 0; n <= max; ) { 512e3037485SYan-Hsuan Chuang seq_printf(m, "\n%8.8x ", n + page); 513e3037485SYan-Hsuan Chuang for (i = 0; i < 4 && n <= max; i++, n += 4) 514e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", 515e3037485SYan-Hsuan Chuang rtw_read32(rtwdev, (page | n))); 516e3037485SYan-Hsuan Chuang } 517e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 518e3037485SYan-Hsuan Chuang return 0; 519e3037485SYan-Hsuan Chuang } 520e3037485SYan-Hsuan Chuang 521e3037485SYan-Hsuan Chuang static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) 522e3037485SYan-Hsuan Chuang { 523e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 524e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 525e3037485SYan-Hsuan Chuang u32 addr, offset, data; 526e3037485SYan-Hsuan Chuang u8 path; 527e3037485SYan-Hsuan Chuang 528d57ca103SSascha Hauer mutex_lock(&rtwdev->mutex); 529d57ca103SSascha Hauer 530e3037485SYan-Hsuan Chuang for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 531e3037485SYan-Hsuan Chuang seq_printf(m, "RF path:%d\n", path); 532e3037485SYan-Hsuan Chuang for (addr = 0; addr < 0x100; addr += 4) { 533e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", addr); 534e3037485SYan-Hsuan Chuang for (offset = 0; offset < 4; offset++) { 535e3037485SYan-Hsuan Chuang data = rtw_read_rf(rtwdev, path, addr + offset, 536e3037485SYan-Hsuan Chuang 0xffffffff); 537e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", data); 538e3037485SYan-Hsuan Chuang } 539e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 540e3037485SYan-Hsuan Chuang } 541e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 542e3037485SYan-Hsuan Chuang } 543e3037485SYan-Hsuan Chuang 544d57ca103SSascha Hauer mutex_unlock(&rtwdev->mutex); 545d57ca103SSascha Hauer 546e3037485SYan-Hsuan Chuang return 0; 547e3037485SYan-Hsuan Chuang } 548e3037485SYan-Hsuan Chuang 5498812022cSZong-Zhe Yang static void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate) 5508812022cSZong-Zhe Yang { 5518812022cSZong-Zhe Yang static const char * const 5528812022cSZong-Zhe Yang cck_rate[] = {"1M", "2M", "5.5M", "11M"}; 5538812022cSZong-Zhe Yang u8 idx = rate - DESC_RATE1M; 5548812022cSZong-Zhe Yang 5558812022cSZong-Zhe Yang seq_printf(m, " CCK_%-5s", cck_rate[idx]); 5568812022cSZong-Zhe Yang } 5578812022cSZong-Zhe Yang 5588812022cSZong-Zhe Yang static void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate) 5598812022cSZong-Zhe Yang { 5608812022cSZong-Zhe Yang static const char * const 5618812022cSZong-Zhe Yang ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"}; 5628812022cSZong-Zhe Yang u8 idx = rate - DESC_RATE6M; 5638812022cSZong-Zhe Yang 5648812022cSZong-Zhe Yang seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]); 5658812022cSZong-Zhe Yang } 5668812022cSZong-Zhe Yang 5678812022cSZong-Zhe Yang static void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate) 5688812022cSZong-Zhe Yang { 5698812022cSZong-Zhe Yang u8 mcs_n = rate - DESC_RATEMCS0; 5708812022cSZong-Zhe Yang 5718812022cSZong-Zhe Yang seq_printf(m, " MCS%-6u", mcs_n); 5728812022cSZong-Zhe Yang } 5738812022cSZong-Zhe Yang 5748812022cSZong-Zhe Yang static void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate) 5758812022cSZong-Zhe Yang { 5768812022cSZong-Zhe Yang u8 idx = rate - DESC_RATEVHT1SS_MCS0; 5778812022cSZong-Zhe Yang u8 n_ss, mcs_n; 5788812022cSZong-Zhe Yang 5798812022cSZong-Zhe Yang /* n spatial stream */ 5808812022cSZong-Zhe Yang n_ss = 1 + idx / 10; 5818812022cSZong-Zhe Yang /* MCS n */ 5828812022cSZong-Zhe Yang mcs_n = idx % 10; 5838812022cSZong-Zhe Yang seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); 5848812022cSZong-Zhe Yang } 5858812022cSZong-Zhe Yang 586082a36dcSTsang-Shian Lin static void rtw_print_rate(struct seq_file *m, u8 rate) 587082a36dcSTsang-Shian Lin { 588082a36dcSTsang-Shian Lin switch (rate) { 589082a36dcSTsang-Shian Lin case DESC_RATE1M...DESC_RATE11M: 590082a36dcSTsang-Shian Lin rtw_print_cck_rate_txt(m, rate); 591082a36dcSTsang-Shian Lin break; 592082a36dcSTsang-Shian Lin case DESC_RATE6M...DESC_RATE54M: 593082a36dcSTsang-Shian Lin rtw_print_ofdm_rate_txt(m, rate); 594082a36dcSTsang-Shian Lin break; 595082a36dcSTsang-Shian Lin case DESC_RATEMCS0...DESC_RATEMCS15: 596082a36dcSTsang-Shian Lin rtw_print_ht_rate_txt(m, rate); 597082a36dcSTsang-Shian Lin break; 598082a36dcSTsang-Shian Lin case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: 599082a36dcSTsang-Shian Lin rtw_print_vht_rate_txt(m, rate); 600082a36dcSTsang-Shian Lin break; 601082a36dcSTsang-Shian Lin default: 602082a36dcSTsang-Shian Lin seq_printf(m, " Unknown rate=0x%x\n", rate); 603082a36dcSTsang-Shian Lin break; 604082a36dcSTsang-Shian Lin } 605082a36dcSTsang-Shian Lin } 606082a36dcSTsang-Shian Lin 607fada0931STzu-En Huang #define case_REGD(src) \ 608fada0931STzu-En Huang case RTW_REGD_##src: return #src 609fada0931STzu-En Huang 610fada0931STzu-En Huang static const char *rtw_get_regd_string(u8 regd) 611fada0931STzu-En Huang { 612fada0931STzu-En Huang switch (regd) { 613fada0931STzu-En Huang case_REGD(FCC); 614fada0931STzu-En Huang case_REGD(MKK); 615fada0931STzu-En Huang case_REGD(ETSI); 616fada0931STzu-En Huang case_REGD(IC); 617fada0931STzu-En Huang case_REGD(KCC); 618fada0931STzu-En Huang case_REGD(ACMA); 619fada0931STzu-En Huang case_REGD(CHILE); 620fada0931STzu-En Huang case_REGD(UKRAINE); 621fada0931STzu-En Huang case_REGD(MEXICO); 622fada0931STzu-En Huang case_REGD(CN); 623fada0931STzu-En Huang case_REGD(WW); 624fada0931STzu-En Huang default: 625fada0931STzu-En Huang return "Unknown"; 626fada0931STzu-En Huang } 627fada0931STzu-En Huang } 628fada0931STzu-En Huang 6298812022cSZong-Zhe Yang static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) 6308812022cSZong-Zhe Yang { 6318812022cSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 6328812022cSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6338812022cSZong-Zhe Yang struct rtw_hal *hal = &rtwdev->hal; 634685b474bSChih-Kang Chang u8 path, rate, bw, ch, regd; 6358812022cSZong-Zhe Yang struct rtw_power_params pwr_param = {0}; 636685b474bSChih-Kang Chang 637685b474bSChih-Kang Chang mutex_lock(&rtwdev->mutex); 638685b474bSChih-Kang Chang bw = hal->current_band_width; 639685b474bSChih-Kang Chang ch = hal->current_channel; 640685b474bSChih-Kang Chang regd = rtw_regd_get(rtwdev); 6418812022cSZong-Zhe Yang 64215728937SZong-Zhe Yang seq_printf(m, "channel: %u\n", ch); 64315728937SZong-Zhe Yang seq_printf(m, "bandwidth: %u\n", bw); 644fada0931STzu-En Huang seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd)); 6458704d0beSZong-Zhe Yang seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n", 6468704d0beSZong-Zhe Yang "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem"); 6478812022cSZong-Zhe Yang 6488812022cSZong-Zhe Yang mutex_lock(&hal->tx_power_mutex); 6498812022cSZong-Zhe Yang for (path = RF_PATH_A; path <= RF_PATH_B; path++) { 6508812022cSZong-Zhe Yang /* there is no CCK rates used in 5G */ 6518812022cSZong-Zhe Yang if (hal->current_band_type == RTW_BAND_5G) 6528812022cSZong-Zhe Yang rate = DESC_RATE6M; 6538812022cSZong-Zhe Yang else 6548812022cSZong-Zhe Yang rate = DESC_RATE1M; 6558812022cSZong-Zhe Yang 6568812022cSZong-Zhe Yang /* now, not support vht 3ss and vht 4ss*/ 6578812022cSZong-Zhe Yang for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) { 6588812022cSZong-Zhe Yang /* now, not support ht 3ss and ht 4ss*/ 6598812022cSZong-Zhe Yang if (rate > DESC_RATEMCS15 && 6608812022cSZong-Zhe Yang rate < DESC_RATEVHT1SS_MCS0) 6618812022cSZong-Zhe Yang continue; 6628812022cSZong-Zhe Yang 6638812022cSZong-Zhe Yang rtw_get_tx_power_params(rtwdev, path, rate, bw, 6648812022cSZong-Zhe Yang ch, regd, &pwr_param); 6658812022cSZong-Zhe Yang 6668812022cSZong-Zhe Yang seq_printf(m, "%4c ", path + 'A'); 667082a36dcSTsang-Shian Lin rtw_print_rate(m, rate); 6688704d0beSZong-Zhe Yang seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d) %4d\n", 6698812022cSZong-Zhe Yang hal->tx_pwr_tbl[path][rate], 6708812022cSZong-Zhe Yang hal->tx_pwr_tbl[path][rate], 6718812022cSZong-Zhe Yang pwr_param.pwr_base, 6728704d0beSZong-Zhe Yang min3(pwr_param.pwr_offset, 6738704d0beSZong-Zhe Yang pwr_param.pwr_limit, 6748704d0beSZong-Zhe Yang pwr_param.pwr_sar), 675608d2a08SPing-Ke Shih pwr_param.pwr_offset, pwr_param.pwr_limit, 6768704d0beSZong-Zhe Yang pwr_param.pwr_sar, 677608d2a08SPing-Ke Shih pwr_param.pwr_remnant); 6788812022cSZong-Zhe Yang } 6798812022cSZong-Zhe Yang } 6808812022cSZong-Zhe Yang 6818812022cSZong-Zhe Yang mutex_unlock(&hal->tx_power_mutex); 682685b474bSChih-Kang Chang mutex_unlock(&rtwdev->mutex); 6838812022cSZong-Zhe Yang 6848812022cSZong-Zhe Yang return 0; 6858812022cSZong-Zhe Yang } 6868812022cSZong-Zhe Yang 6871a589bd5SChing-Te Ku void rtw_debugfs_get_simple_phy_info(struct seq_file *m) 6881a589bd5SChing-Te Ku { 6891a589bd5SChing-Te Ku struct rtw_debugfs_priv *debugfs_priv = m->private; 6901a589bd5SChing-Te Ku struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6911a589bd5SChing-Te Ku struct rtw_hal *hal = &rtwdev->hal; 6921a589bd5SChing-Te Ku struct rtw_dm_info *dm_info = &rtwdev->dm_info; 6931a589bd5SChing-Te Ku struct rtw_traffic_stats *stats = &rtwdev->stats; 6941a589bd5SChing-Te Ku 6951a589bd5SChing-Te Ku seq_printf(m, "%-40s = %ddBm/ %d\n", "RSSI/ STA Channel", 6961a589bd5SChing-Te Ku dm_info->rssi[RF_PATH_A] - 100, hal->current_channel); 6971a589bd5SChing-Te Ku 6981a589bd5SChing-Te Ku seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 6991a589bd5SChing-Te Ku stats->tx_throughput, stats->rx_throughput); 7001a589bd5SChing-Te Ku 7011a589bd5SChing-Te Ku seq_puts(m, "[Tx Rate] = "); 7021a589bd5SChing-Te Ku rtw_print_rate(m, dm_info->tx_rate); 7031a589bd5SChing-Te Ku seq_printf(m, "(0x%x)\n", dm_info->tx_rate); 7041a589bd5SChing-Te Ku 7051a589bd5SChing-Te Ku seq_puts(m, "[Rx Rate] = "); 7061a589bd5SChing-Te Ku rtw_print_rate(m, dm_info->curr_rx_rate); 7071a589bd5SChing-Te Ku seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 7081a589bd5SChing-Te Ku } 7091a589bd5SChing-Te Ku 710082a36dcSTsang-Shian Lin static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) 711082a36dcSTsang-Shian Lin { 712082a36dcSTsang-Shian Lin struct rtw_debugfs_priv *debugfs_priv = m->private; 713082a36dcSTsang-Shian Lin struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 714082a36dcSTsang-Shian Lin struct rtw_dm_info *dm_info = &rtwdev->dm_info; 715082a36dcSTsang-Shian Lin struct rtw_traffic_stats *stats = &rtwdev->stats; 716082a36dcSTsang-Shian Lin struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; 717082a36dcSTsang-Shian Lin struct rtw_efuse *efuse = &rtwdev->efuse; 718082a36dcSTsang-Shian Lin struct ewma_evm *ewma_evm = dm_info->ewma_evm; 719082a36dcSTsang-Shian Lin struct ewma_snr *ewma_snr = dm_info->ewma_snr; 720082a36dcSTsang-Shian Lin u8 ss, rate_id; 721082a36dcSTsang-Shian Lin 722082a36dcSTsang-Shian Lin seq_puts(m, "==========[Common Info]========\n"); 723082a36dcSTsang-Shian Lin seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); 724082a36dcSTsang-Shian Lin seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); 725082a36dcSTsang-Shian Lin seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); 726082a36dcSTsang-Shian Lin seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); 72704e00ac9SChin-Yen Lee seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 728082a36dcSTsang-Shian Lin stats->tx_throughput, stats->rx_throughput); 72904e00ac9SChin-Yen Lee seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ? 73004e00ac9SChin-Yen Lee 'Y' : 'N'); 731082a36dcSTsang-Shian Lin 732082a36dcSTsang-Shian Lin seq_puts(m, "==========[Tx Phy Info]========\n"); 733082a36dcSTsang-Shian Lin seq_puts(m, "[Tx Rate] = "); 734082a36dcSTsang-Shian Lin rtw_print_rate(m, dm_info->tx_rate); 735082a36dcSTsang-Shian Lin seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); 736082a36dcSTsang-Shian Lin 737082a36dcSTsang-Shian Lin seq_puts(m, "==========[Rx Phy Info]========\n"); 738082a36dcSTsang-Shian Lin seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); 739082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Rate] = "); 740082a36dcSTsang-Shian Lin rtw_print_rate(m, dm_info->curr_rx_rate); 741082a36dcSTsang-Shian Lin seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 742082a36dcSTsang-Shian Lin 743082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Rate Count]:\n"); 744082a36dcSTsang-Shian Lin seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", 745082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE1M], 746082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE2M], 747082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE5_5M], 748082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE11M]); 749082a36dcSTsang-Shian Lin 750082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 751082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE6M], 752082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE9M], 753082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE12M], 754082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE18M], 755082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE24M], 756082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE36M], 757082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE48M], 758082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE54M]); 759082a36dcSTsang-Shian Lin 760082a36dcSTsang-Shian Lin for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 761082a36dcSTsang-Shian Lin rate_id = DESC_RATEMCS0 + ss * 8; 762082a36dcSTsang-Shian Lin seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 763082a36dcSTsang-Shian Lin ss * 8, ss * 8 + 7, 764082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id], 765082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 1], 766082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 2], 767082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 3], 768082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 4], 769082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 5], 770082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 6], 771082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 7]); 772082a36dcSTsang-Shian Lin } 773082a36dcSTsang-Shian Lin 774082a36dcSTsang-Shian Lin for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 775082a36dcSTsang-Shian Lin rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; 776082a36dcSTsang-Shian Lin seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", 777082a36dcSTsang-Shian Lin ss + 1, 778082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id], 779082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 1], 780082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 2], 781082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 3], 782082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 4], 783082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 5], 784082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 6], 785082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 7], 786082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 8], 787082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 9]); 788082a36dcSTsang-Shian Lin } 789082a36dcSTsang-Shian Lin 790082a36dcSTsang-Shian Lin seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", 791082a36dcSTsang-Shian Lin dm_info->rssi[RF_PATH_A] - 100, 792082a36dcSTsang-Shian Lin dm_info->rssi[RF_PATH_B] - 100); 793082a36dcSTsang-Shian Lin seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", 794082a36dcSTsang-Shian Lin dm_info->rx_evm_dbm[RF_PATH_A], 795082a36dcSTsang-Shian Lin dm_info->rx_evm_dbm[RF_PATH_B]); 796082a36dcSTsang-Shian Lin seq_printf(m, "[Rx SNR] = {%d, %d}\n", 797082a36dcSTsang-Shian Lin dm_info->rx_snr[RF_PATH_A], 798082a36dcSTsang-Shian Lin dm_info->rx_snr[RF_PATH_B]); 799082a36dcSTsang-Shian Lin seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", 800082a36dcSTsang-Shian Lin dm_info->cfo_tail[RF_PATH_A], 801082a36dcSTsang-Shian Lin dm_info->cfo_tail[RF_PATH_B]); 802082a36dcSTsang-Shian Lin 803082a36dcSTsang-Shian Lin if (dm_info->curr_rx_rate >= DESC_RATE11M) { 804082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Average Status]:\n"); 805082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", 806082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), 807082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); 808082a36dcSTsang-Shian Lin seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", 809082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), 810082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); 811082a36dcSTsang-Shian Lin seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", 812082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), 813082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), 814082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), 815082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); 816082a36dcSTsang-Shian Lin } 817082a36dcSTsang-Shian Lin 818082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Counter]:\n"); 819082a36dcSTsang-Shian Lin seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", 820082a36dcSTsang-Shian Lin dm_info->cck_cca_cnt, 821082a36dcSTsang-Shian Lin dm_info->ofdm_cca_cnt, 822082a36dcSTsang-Shian Lin dm_info->total_cca_cnt); 823082a36dcSTsang-Shian Lin seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", 824082a36dcSTsang-Shian Lin dm_info->cck_fa_cnt, 825082a36dcSTsang-Shian Lin dm_info->ofdm_fa_cnt, 826082a36dcSTsang-Shian Lin dm_info->total_fa_cnt); 827082a36dcSTsang-Shian Lin seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", 828082a36dcSTsang-Shian Lin dm_info->cck_ok_cnt, dm_info->cck_err_cnt); 829082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", 830082a36dcSTsang-Shian Lin dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); 831082a36dcSTsang-Shian Lin seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", 832082a36dcSTsang-Shian Lin dm_info->ht_ok_cnt, dm_info->ht_err_cnt); 833082a36dcSTsang-Shian Lin seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", 834082a36dcSTsang-Shian Lin dm_info->vht_ok_cnt, dm_info->vht_err_cnt); 8351fe188daSYan-Hsuan Chuang 8361fe188daSYan-Hsuan Chuang return 0; 8371fe188daSYan-Hsuan Chuang } 8381fe188daSYan-Hsuan Chuang 8391fe188daSYan-Hsuan Chuang static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) 8401fe188daSYan-Hsuan Chuang { 8411fe188daSYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 8421fe188daSYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8431fe188daSYan-Hsuan Chuang 8441fe188daSYan-Hsuan Chuang rtw_coex_display_coex_info(rtwdev, m); 8451fe188daSYan-Hsuan Chuang 846082a36dcSTsang-Shian Lin return 0; 847082a36dcSTsang-Shian Lin } 848082a36dcSTsang-Shian Lin 849d0555093SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, 850d0555093SYan-Hsuan Chuang const char __user *buffer, 851d0555093SYan-Hsuan Chuang size_t count, loff_t *loff) 852d0555093SYan-Hsuan Chuang { 853d0555093SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 854d0555093SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 855d0555093SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 856d0555093SYan-Hsuan Chuang struct rtw_coex *coex = &rtwdev->coex; 857d0555093SYan-Hsuan Chuang char tmp[32 + 1]; 858d0555093SYan-Hsuan Chuang bool enable; 859d0555093SYan-Hsuan Chuang int ret; 860d0555093SYan-Hsuan Chuang 861d0555093SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 862d0555093SYan-Hsuan Chuang 863d0555093SYan-Hsuan Chuang ret = kstrtobool(tmp, &enable); 864d0555093SYan-Hsuan Chuang if (ret) { 865d0555093SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid arguments\n"); 866d0555093SYan-Hsuan Chuang return ret; 867d0555093SYan-Hsuan Chuang } 868d0555093SYan-Hsuan Chuang 869d0555093SYan-Hsuan Chuang mutex_lock(&rtwdev->mutex); 870d3a78c7aSYANG LI coex->manual_control = !enable; 871d0555093SYan-Hsuan Chuang mutex_unlock(&rtwdev->mutex); 872d0555093SYan-Hsuan Chuang 873d0555093SYan-Hsuan Chuang return count; 874d0555093SYan-Hsuan Chuang } 875d0555093SYan-Hsuan Chuang 876d0555093SYan-Hsuan Chuang static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) 877d0555093SYan-Hsuan Chuang { 878d0555093SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 879d0555093SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 880d0555093SYan-Hsuan Chuang struct rtw_coex *coex = &rtwdev->coex; 881d0555093SYan-Hsuan Chuang 882d0555093SYan-Hsuan Chuang seq_printf(m, "coex mechanism %s\n", 88332c3a8c7SChing-Te Ku coex->manual_control ? "disabled" : "enabled"); 884d0555093SYan-Hsuan Chuang 885d0555093SYan-Hsuan Chuang return 0; 886d0555093SYan-Hsuan Chuang } 887d0555093SYan-Hsuan Chuang 8887285eb96SZong-Zhe Yang static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, 8897285eb96SZong-Zhe Yang const char __user *buffer, 8907285eb96SZong-Zhe Yang size_t count, loff_t *loff) 8917285eb96SZong-Zhe Yang { 8927285eb96SZong-Zhe Yang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 8937285eb96SZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 8947285eb96SZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8957285eb96SZong-Zhe Yang bool input; 8967285eb96SZong-Zhe Yang int err; 8977285eb96SZong-Zhe Yang 8987285eb96SZong-Zhe Yang err = kstrtobool_from_user(buffer, count, &input); 8997285eb96SZong-Zhe Yang if (err) 9007285eb96SZong-Zhe Yang return err; 9017285eb96SZong-Zhe Yang 9027285eb96SZong-Zhe Yang rtw_edcca_enabled = input; 9037285eb96SZong-Zhe Yang rtw_phy_adaptivity_set_mode(rtwdev); 9047285eb96SZong-Zhe Yang 9057285eb96SZong-Zhe Yang return count; 9067285eb96SZong-Zhe Yang } 9077285eb96SZong-Zhe Yang 9087285eb96SZong-Zhe Yang static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v) 9097285eb96SZong-Zhe Yang { 9107285eb96SZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 9117285eb96SZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9127285eb96SZong-Zhe Yang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 9137285eb96SZong-Zhe Yang 9147285eb96SZong-Zhe Yang seq_printf(m, "EDCCA %s: EDCCA mode %d\n", 9157285eb96SZong-Zhe Yang rtw_edcca_enabled ? "enabled" : "disabled", 9167285eb96SZong-Zhe Yang dm_info->edcca_mode); 9177285eb96SZong-Zhe Yang return 0; 9187285eb96SZong-Zhe Yang } 9197285eb96SZong-Zhe Yang 92013ce240aSZong-Zhe Yang static ssize_t rtw_debugfs_set_fw_crash(struct file *filp, 92113ce240aSZong-Zhe Yang const char __user *buffer, 92213ce240aSZong-Zhe Yang size_t count, loff_t *loff) 92313ce240aSZong-Zhe Yang { 92413ce240aSZong-Zhe Yang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 92513ce240aSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 92613ce240aSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 92713ce240aSZong-Zhe Yang char tmp[32 + 1]; 92813ce240aSZong-Zhe Yang bool input; 92913ce240aSZong-Zhe Yang int ret; 93013ce240aSZong-Zhe Yang 93113ce240aSZong-Zhe Yang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 93213ce240aSZong-Zhe Yang 93313ce240aSZong-Zhe Yang ret = kstrtobool(tmp, &input); 93413ce240aSZong-Zhe Yang if (ret) 93513ce240aSZong-Zhe Yang return -EINVAL; 93613ce240aSZong-Zhe Yang 93713ce240aSZong-Zhe Yang if (!input) 93813ce240aSZong-Zhe Yang return -EINVAL; 93913ce240aSZong-Zhe Yang 9407b80f3e4SZong-Zhe Yang if (test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) 9417b80f3e4SZong-Zhe Yang return -EINPROGRESS; 9427b80f3e4SZong-Zhe Yang 9437b80f3e4SZong-Zhe Yang mutex_lock(&rtwdev->mutex); 9447b80f3e4SZong-Zhe Yang rtw_leave_lps_deep(rtwdev); 9456cd4b59dSZong-Zhe Yang set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags); 94613ce240aSZong-Zhe Yang rtw_write8(rtwdev, REG_HRCV_MSG, 1); 9477b80f3e4SZong-Zhe Yang mutex_unlock(&rtwdev->mutex); 94813ce240aSZong-Zhe Yang 94913ce240aSZong-Zhe Yang return count; 95013ce240aSZong-Zhe Yang } 95113ce240aSZong-Zhe Yang 95213ce240aSZong-Zhe Yang static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v) 95313ce240aSZong-Zhe Yang { 95413ce240aSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 95513ce240aSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 95613ce240aSZong-Zhe Yang 9576cd4b59dSZong-Zhe Yang seq_printf(m, "%d\n", 9586cd4b59dSZong-Zhe Yang test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) || 9596cd4b59dSZong-Zhe Yang test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)); 96013ce240aSZong-Zhe Yang return 0; 96113ce240aSZong-Zhe Yang } 96213ce240aSZong-Zhe Yang 963272cda71SYu-Yen Ting static ssize_t rtw_debugfs_set_force_lowest_basic_rate(struct file *filp, 964272cda71SYu-Yen Ting const char __user *buffer, 965272cda71SYu-Yen Ting size_t count, loff_t *loff) 966272cda71SYu-Yen Ting { 967272cda71SYu-Yen Ting struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 968272cda71SYu-Yen Ting struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 969272cda71SYu-Yen Ting struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 970272cda71SYu-Yen Ting bool input; 971272cda71SYu-Yen Ting int err; 972272cda71SYu-Yen Ting 973272cda71SYu-Yen Ting err = kstrtobool_from_user(buffer, count, &input); 974272cda71SYu-Yen Ting if (err) 975272cda71SYu-Yen Ting return err; 976272cda71SYu-Yen Ting 977272cda71SYu-Yen Ting if (input) 978272cda71SYu-Yen Ting set_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 979272cda71SYu-Yen Ting else 980272cda71SYu-Yen Ting clear_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 981272cda71SYu-Yen Ting 982272cda71SYu-Yen Ting return count; 983272cda71SYu-Yen Ting } 984272cda71SYu-Yen Ting 985272cda71SYu-Yen Ting static int rtw_debugfs_get_force_lowest_basic_rate(struct seq_file *m, void *v) 986272cda71SYu-Yen Ting { 987272cda71SYu-Yen Ting struct rtw_debugfs_priv *debugfs_priv = m->private; 988272cda71SYu-Yen Ting struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 989272cda71SYu-Yen Ting 990272cda71SYu-Yen Ting seq_printf(m, "force lowest basic rate: %d\n", 991272cda71SYu-Yen Ting test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags)); 992272cda71SYu-Yen Ting 993272cda71SYu-Yen Ting return 0; 994272cda71SYu-Yen Ting } 995272cda71SYu-Yen Ting 9963b25bac8SGuo-Feng Fan static ssize_t rtw_debugfs_set_dm_cap(struct file *filp, 9973b25bac8SGuo-Feng Fan const char __user *buffer, 9983b25bac8SGuo-Feng Fan size_t count, loff_t *loff) 9993b25bac8SGuo-Feng Fan { 10003b25bac8SGuo-Feng Fan struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 10013b25bac8SGuo-Feng Fan struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 10023b25bac8SGuo-Feng Fan struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 10033b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10043b25bac8SGuo-Feng Fan int bit; 10053b25bac8SGuo-Feng Fan bool en; 10063b25bac8SGuo-Feng Fan 10073b25bac8SGuo-Feng Fan if (kstrtoint_from_user(buffer, count, 10, &bit)) 10083b25bac8SGuo-Feng Fan return -EINVAL; 10093b25bac8SGuo-Feng Fan 10103b25bac8SGuo-Feng Fan en = bit > 0; 10113b25bac8SGuo-Feng Fan bit = abs(bit); 10123b25bac8SGuo-Feng Fan 10133b25bac8SGuo-Feng Fan if (bit >= RTW_DM_CAP_NUM) { 10143b25bac8SGuo-Feng Fan rtw_warn(rtwdev, "unknown DM CAP %d\n", bit); 10153b25bac8SGuo-Feng Fan return -EINVAL; 10163b25bac8SGuo-Feng Fan } 10173b25bac8SGuo-Feng Fan 10183b25bac8SGuo-Feng Fan if (en) 10193b25bac8SGuo-Feng Fan dm_info->dm_flags &= ~BIT(bit); 10203b25bac8SGuo-Feng Fan else 10213b25bac8SGuo-Feng Fan dm_info->dm_flags |= BIT(bit); 10223b25bac8SGuo-Feng Fan 10233b25bac8SGuo-Feng Fan debugfs_priv->dm_cap.bit = bit; 10243b25bac8SGuo-Feng Fan 10253b25bac8SGuo-Feng Fan return count; 10263b25bac8SGuo-Feng Fan } 10273b25bac8SGuo-Feng Fan 10283b25bac8SGuo-Feng Fan static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) 10293b25bac8SGuo-Feng Fan { 10303b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10313b25bac8SGuo-Feng Fan struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 10323b25bac8SGuo-Feng Fan int i, path; 10333b25bac8SGuo-Feng Fan u32 val; 10343b25bac8SGuo-Feng Fan 10353b25bac8SGuo-Feng Fan seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK, 10363b25bac8SGuo-Feng Fan dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', 10373b25bac8SGuo-Feng Fan rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); 10383b25bac8SGuo-Feng Fan 1039d57ca103SSascha Hauer mutex_lock(&rtwdev->mutex); 1040d57ca103SSascha Hauer 10413b25bac8SGuo-Feng Fan for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 10423b25bac8SGuo-Feng Fan val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); 10433b25bac8SGuo-Feng Fan seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); 10443b25bac8SGuo-Feng Fan 10453b25bac8SGuo-Feng Fan for (i = 0; i < RF_HW_OFFSET_NUM; i++) 10463b25bac8SGuo-Feng Fan seq_printf(m, "[TXGAPK] offset %d %d\n", 10473b25bac8SGuo-Feng Fan txgapk->rf3f_fs[path][i], i); 10483b25bac8SGuo-Feng Fan seq_puts(m, "\n"); 10493b25bac8SGuo-Feng Fan } 1050d57ca103SSascha Hauer mutex_unlock(&rtwdev->mutex); 10513b25bac8SGuo-Feng Fan } 10523b25bac8SGuo-Feng Fan 10533b25bac8SGuo-Feng Fan static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) 10543b25bac8SGuo-Feng Fan { 10553b25bac8SGuo-Feng Fan struct rtw_debugfs_priv *debugfs_priv = m->private; 10563b25bac8SGuo-Feng Fan struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 10573b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10583b25bac8SGuo-Feng Fan int i; 10593b25bac8SGuo-Feng Fan 10603b25bac8SGuo-Feng Fan switch (debugfs_priv->dm_cap.bit) { 10613b25bac8SGuo-Feng Fan case RTW_DM_CAP_TXGAPK: 10623b25bac8SGuo-Feng Fan dump_gapk_status(rtwdev, m); 10633b25bac8SGuo-Feng Fan break; 10643b25bac8SGuo-Feng Fan default: 10653b25bac8SGuo-Feng Fan for (i = 1; i < RTW_DM_CAP_NUM; i++) { 10663b25bac8SGuo-Feng Fan seq_printf(m, "(%2d) %c%s\n", i, 10673b25bac8SGuo-Feng Fan dm_info->dm_flags & BIT(i) ? '-' : '+', 10683b25bac8SGuo-Feng Fan rtw_dm_cap_strs[i]); 10693b25bac8SGuo-Feng Fan } 10703b25bac8SGuo-Feng Fan break; 10713b25bac8SGuo-Feng Fan } 10723b25bac8SGuo-Feng Fan debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA; 10733b25bac8SGuo-Feng Fan return 0; 10743b25bac8SGuo-Feng Fan } 10753b25bac8SGuo-Feng Fan 1076e3037485SYan-Hsuan Chuang #define rtw_debug_impl_mac(page, addr) \ 1077e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ 1078e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_mac_page, \ 1079e3037485SYan-Hsuan Chuang .cb_data = addr, \ 1080e3037485SYan-Hsuan Chuang } 1081e3037485SYan-Hsuan Chuang 1082e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(0, 0x0000); 1083e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(1, 0x0100); 1084e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(2, 0x0200); 1085e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(3, 0x0300); 1086e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(4, 0x0400); 1087e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(5, 0x0500); 1088e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(6, 0x0600); 1089e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(7, 0x0700); 1090e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(10, 0x1000); 1091e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(11, 0x1100); 1092e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(12, 0x1200); 1093e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(13, 0x1300); 1094e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(14, 0x1400); 1095e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(15, 0x1500); 1096e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(16, 0x1600); 1097e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(17, 0x1700); 1098e3037485SYan-Hsuan Chuang 1099e3037485SYan-Hsuan Chuang #define rtw_debug_impl_bb(page, addr) \ 1100e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \ 1101e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_bb_page, \ 1102e3037485SYan-Hsuan Chuang .cb_data = addr, \ 1103e3037485SYan-Hsuan Chuang } 1104e3037485SYan-Hsuan Chuang 1105e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(8, 0x0800); 1106e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(9, 0x0900); 1107e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(a, 0x0a00); 1108e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(b, 0x0b00); 1109e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(c, 0x0c00); 1110e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(d, 0x0d00); 1111e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(e, 0x0e00); 1112e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(f, 0x0f00); 1113e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(18, 0x1800); 1114e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(19, 0x1900); 1115e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1a, 0x1a00); 1116e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1b, 0x1b00); 1117e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1c, 0x1c00); 1118e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1d, 0x1d00); 1119e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1e, 0x1e00); 1120e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1f, 0x1f00); 1121e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(2c, 0x2c00); 1122e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(2d, 0x2d00); 1123e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(40, 0x4000); 1124e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(41, 0x4100); 1125e3037485SYan-Hsuan Chuang 1126e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = { 1127e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_rf_dump, 1128e3037485SYan-Hsuan Chuang }; 1129e3037485SYan-Hsuan Chuang 11308812022cSZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = { 11318812022cSZong-Zhe Yang .cb_read = rtw_debugfs_get_tx_pwr_tbl, 11328812022cSZong-Zhe Yang }; 11338812022cSZong-Zhe Yang 1134e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_write_reg = { 1135e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_write_reg, 1136e3037485SYan-Hsuan Chuang }; 1137e3037485SYan-Hsuan Chuang 1138c376c1fcSTzu-En Huang static struct rtw_debugfs_priv rtw_debug_priv_h2c = { 1139c376c1fcSTzu-En Huang .cb_write = rtw_debugfs_set_h2c, 1140c376c1fcSTzu-En Huang }; 1141c376c1fcSTzu-En Huang 1142e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_write = { 1143e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rf_write, 1144e3037485SYan-Hsuan Chuang }; 1145e3037485SYan-Hsuan Chuang 1146e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_read = { 1147e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rf_read, 1148e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_rf_read, 1149e3037485SYan-Hsuan Chuang }; 1150e3037485SYan-Hsuan Chuang 1151e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_read_reg = { 1152e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_read_reg, 1153e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_read_reg, 1154e3037485SYan-Hsuan Chuang }; 1155e3037485SYan-Hsuan Chuang 11561379e620SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = { 11571379e620SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_fix_rate, 11581379e620SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_fix_rate, 11591379e620SYan-Hsuan Chuang }; 11601379e620SYan-Hsuan Chuang 1161e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = { 1162e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_single_input, 1163e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_dump_cam, 1164e3037485SYan-Hsuan Chuang }; 1165e3037485SYan-Hsuan Chuang 1166e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = { 1167e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rsvd_page, 1168e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_rsvd_page, 1169e3037485SYan-Hsuan Chuang }; 1170e3037485SYan-Hsuan Chuang 1171082a36dcSTsang-Shian Lin static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { 1172082a36dcSTsang-Shian Lin .cb_read = rtw_debugfs_get_phy_info, 1173082a36dcSTsang-Shian Lin }; 1174082a36dcSTsang-Shian Lin 1175d0555093SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { 1176d0555093SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_coex_enable, 1177d0555093SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_coex_enable, 1178d0555093SYan-Hsuan Chuang }; 1179d0555093SYan-Hsuan Chuang 11801fe188daSYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { 11811fe188daSYan-Hsuan Chuang .cb_read = rtw_debugfs_get_coex_info, 11821fe188daSYan-Hsuan Chuang }; 11831fe188daSYan-Hsuan Chuang 11847285eb96SZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { 11857285eb96SZong-Zhe Yang .cb_write = rtw_debugfs_set_edcca_enable, 11867285eb96SZong-Zhe Yang .cb_read = rtw_debugfs_get_edcca_enable, 11877285eb96SZong-Zhe Yang }; 11887285eb96SZong-Zhe Yang 118913ce240aSZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { 119013ce240aSZong-Zhe Yang .cb_write = rtw_debugfs_set_fw_crash, 119113ce240aSZong-Zhe Yang .cb_read = rtw_debugfs_get_fw_crash, 119213ce240aSZong-Zhe Yang }; 119313ce240aSZong-Zhe Yang 1194272cda71SYu-Yen Ting static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = { 1195272cda71SYu-Yen Ting .cb_write = rtw_debugfs_set_force_lowest_basic_rate, 1196272cda71SYu-Yen Ting .cb_read = rtw_debugfs_get_force_lowest_basic_rate, 1197272cda71SYu-Yen Ting }; 1198272cda71SYu-Yen Ting 11993b25bac8SGuo-Feng Fan static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { 12003b25bac8SGuo-Feng Fan .cb_write = rtw_debugfs_set_dm_cap, 12013b25bac8SGuo-Feng Fan .cb_read = rtw_debugfs_get_dm_cap, 12023b25bac8SGuo-Feng Fan }; 12033b25bac8SGuo-Feng Fan 1204e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_core(name, mode, fopname, parent) \ 1205e3037485SYan-Hsuan Chuang do { \ 1206e3037485SYan-Hsuan Chuang rtw_debug_priv_ ##name.rtwdev = rtwdev; \ 1207e3037485SYan-Hsuan Chuang if (!debugfs_create_file(#name, mode, \ 1208e3037485SYan-Hsuan Chuang parent, &rtw_debug_priv_ ##name,\ 1209e3037485SYan-Hsuan Chuang &file_ops_ ##fopname)) \ 1210e3037485SYan-Hsuan Chuang pr_debug("Unable to initialize debugfs:%s\n", \ 1211e3037485SYan-Hsuan Chuang #name); \ 1212e3037485SYan-Hsuan Chuang } while (0) 1213e3037485SYan-Hsuan Chuang 1214e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_w(name) \ 1215e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir) 1216e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_rw(name) \ 1217e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir) 1218e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_r(name) \ 1219e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) 1220e3037485SYan-Hsuan Chuang 1221e3037485SYan-Hsuan Chuang void rtw_debugfs_init(struct rtw_dev *rtwdev) 1222e3037485SYan-Hsuan Chuang { 12239f7d65fbSColin Ian King struct dentry *debugfs_topdir; 1224e3037485SYan-Hsuan Chuang 1225e3037485SYan-Hsuan Chuang debugfs_topdir = debugfs_create_dir("rtw88", 1226e3037485SYan-Hsuan Chuang rtwdev->hw->wiphy->debugfsdir); 1227e3037485SYan-Hsuan Chuang rtw_debugfs_add_w(write_reg); 1228e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(read_reg); 1229e3037485SYan-Hsuan Chuang rtw_debugfs_add_w(rf_write); 1230e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(rf_read); 12311379e620SYan-Hsuan Chuang rtw_debugfs_add_rw(fix_rate); 1232e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(dump_cam); 1233e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(rsvd_page); 1234082a36dcSTsang-Shian Lin rtw_debugfs_add_r(phy_info); 12351fe188daSYan-Hsuan Chuang rtw_debugfs_add_r(coex_info); 1236d0555093SYan-Hsuan Chuang rtw_debugfs_add_rw(coex_enable); 1237c376c1fcSTzu-En Huang rtw_debugfs_add_w(h2c); 1238e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_0); 1239e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_1); 1240e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_2); 1241e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_3); 1242e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_4); 1243e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_5); 1244e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_6); 1245e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_7); 1246e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_8); 1247e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_9); 1248e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_a); 1249e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_b); 1250e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_c); 1251e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_d); 1252e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_e); 1253e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_f); 1254e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_10); 1255e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_11); 1256e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_12); 1257e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_13); 1258e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_14); 1259e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_15); 1260e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_16); 1261e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_17); 1262e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_18); 1263e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_19); 1264e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1a); 1265e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1b); 1266e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1c); 1267e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1d); 1268e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1e); 1269e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1f); 1270e3037485SYan-Hsuan Chuang if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { 1271e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_2c); 1272e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_2d); 1273e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_40); 1274e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_41); 1275e3037485SYan-Hsuan Chuang } 1276e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(rf_dump); 12778812022cSZong-Zhe Yang rtw_debugfs_add_r(tx_pwr_tbl); 12787285eb96SZong-Zhe Yang rtw_debugfs_add_rw(edcca_enable); 127913ce240aSZong-Zhe Yang rtw_debugfs_add_rw(fw_crash); 1280272cda71SYu-Yen Ting rtw_debugfs_add_rw(force_lowest_basic_rate); 12813b25bac8SGuo-Feng Fan rtw_debugfs_add_rw(dm_cap); 1282e3037485SYan-Hsuan Chuang } 1283e3037485SYan-Hsuan Chuang 1284e3037485SYan-Hsuan Chuang #endif /* CONFIG_RTW88_DEBUGFS */ 1285e3037485SYan-Hsuan Chuang 1286e3037485SYan-Hsuan Chuang #ifdef CONFIG_RTW88_DEBUG 1287e3037485SYan-Hsuan Chuang 1288e3037485SYan-Hsuan Chuang void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, 1289e3037485SYan-Hsuan Chuang const char *fmt, ...) 1290e3037485SYan-Hsuan Chuang { 1291e3037485SYan-Hsuan Chuang struct va_format vaf = { 1292e3037485SYan-Hsuan Chuang .fmt = fmt, 1293e3037485SYan-Hsuan Chuang }; 1294e3037485SYan-Hsuan Chuang va_list args; 1295e3037485SYan-Hsuan Chuang 1296e3037485SYan-Hsuan Chuang va_start(args, fmt); 1297e3037485SYan-Hsuan Chuang vaf.va = &args; 1298e3037485SYan-Hsuan Chuang 1299e3037485SYan-Hsuan Chuang if (rtw_debug_mask & mask) 1300e3037485SYan-Hsuan Chuang dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); 1301e3037485SYan-Hsuan Chuang 1302e3037485SYan-Hsuan Chuang va_end(args); 1303e3037485SYan-Hsuan Chuang } 1304e3037485SYan-Hsuan Chuang EXPORT_SYMBOL(__rtw_dbg); 1305e3037485SYan-Hsuan Chuang 1306e3037485SYan-Hsuan Chuang #endif /* CONFIG_RTW88_DEBUG */ 1307