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); 272e3037485SYan-Hsuan Chuang seq_printf(m, "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", 273e3037485SYan-Hsuan Chuang *(buf + i), *(buf + i + 1), 274e3037485SYan-Hsuan Chuang *(buf + i + 2), *(buf + i + 3), 275e3037485SYan-Hsuan Chuang *(buf + i + 4), *(buf + i + 5), 276e3037485SYan-Hsuan Chuang *(buf + i + 6), *(buf + i + 7)); 277e3037485SYan-Hsuan Chuang } 278e3037485SYan-Hsuan Chuang vfree(buf); 279e3037485SYan-Hsuan Chuang 280e3037485SYan-Hsuan Chuang return 0; 281e3037485SYan-Hsuan Chuang } 282e3037485SYan-Hsuan Chuang 283e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp, 284e3037485SYan-Hsuan Chuang const char __user *buffer, 285e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 286e3037485SYan-Hsuan Chuang { 287e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 288e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 289e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 290e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 291e3037485SYan-Hsuan Chuang u32 offset, page_num; 292e3037485SYan-Hsuan Chuang int num; 293e3037485SYan-Hsuan Chuang 294e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 295e3037485SYan-Hsuan Chuang 296e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%d %d", &offset, &page_num); 297e3037485SYan-Hsuan Chuang 298e3037485SYan-Hsuan Chuang if (num != 2) { 299e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid arguments\n"); 300c9eaee0cSDan Carpenter return -EINVAL; 301e3037485SYan-Hsuan Chuang } 302e3037485SYan-Hsuan Chuang 303e3037485SYan-Hsuan Chuang debugfs_priv->rsvd_page.page_offset = offset; 304e3037485SYan-Hsuan Chuang debugfs_priv->rsvd_page.page_num = page_num; 305e3037485SYan-Hsuan Chuang 306e3037485SYan-Hsuan Chuang return count; 307e3037485SYan-Hsuan Chuang } 308e3037485SYan-Hsuan Chuang 309e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_single_input(struct file *filp, 310e3037485SYan-Hsuan Chuang const char __user *buffer, 311e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 312e3037485SYan-Hsuan Chuang { 313e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 314e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 315e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 316e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 317e3037485SYan-Hsuan Chuang u32 input; 318e3037485SYan-Hsuan Chuang int num; 319e3037485SYan-Hsuan Chuang 320e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 321e3037485SYan-Hsuan Chuang 322e3037485SYan-Hsuan Chuang num = kstrtoint(tmp, 0, &input); 323e3037485SYan-Hsuan Chuang 324e3037485SYan-Hsuan Chuang if (num) { 325e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "kstrtoint failed\n"); 326e3037485SYan-Hsuan Chuang return num; 327e3037485SYan-Hsuan Chuang } 328e3037485SYan-Hsuan Chuang 329e3037485SYan-Hsuan Chuang debugfs_priv->cb_data = input; 330e3037485SYan-Hsuan Chuang 331e3037485SYan-Hsuan Chuang return count; 332e3037485SYan-Hsuan Chuang } 333e3037485SYan-Hsuan Chuang 334e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_write_reg(struct file *filp, 335e3037485SYan-Hsuan Chuang const char __user *buffer, 336e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 337e3037485SYan-Hsuan Chuang { 338e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 339e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 340e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 341e3037485SYan-Hsuan Chuang u32 addr, val, len; 342e3037485SYan-Hsuan Chuang int num; 343e3037485SYan-Hsuan Chuang 344e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 345e3037485SYan-Hsuan Chuang 346e3037485SYan-Hsuan Chuang /* write BB/MAC register */ 347e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x", &addr, &val, &len); 348e3037485SYan-Hsuan Chuang 349e3037485SYan-Hsuan Chuang if (num != 3) 350e3037485SYan-Hsuan Chuang return count; 351e3037485SYan-Hsuan Chuang 352e3037485SYan-Hsuan Chuang switch (len) { 353e3037485SYan-Hsuan Chuang case 1: 354e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 355e3037485SYan-Hsuan Chuang "reg write8 0x%03x: 0x%08x\n", addr, val); 356e3037485SYan-Hsuan Chuang rtw_write8(rtwdev, addr, (u8)val); 357e3037485SYan-Hsuan Chuang break; 358e3037485SYan-Hsuan Chuang case 2: 359e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 360e3037485SYan-Hsuan Chuang "reg write16 0x%03x: 0x%08x\n", addr, val); 361e3037485SYan-Hsuan Chuang rtw_write16(rtwdev, addr, (u16)val); 362e3037485SYan-Hsuan Chuang break; 363e3037485SYan-Hsuan Chuang case 4: 364e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 365e3037485SYan-Hsuan Chuang "reg write32 0x%03x: 0x%08x\n", addr, val); 366e3037485SYan-Hsuan Chuang rtw_write32(rtwdev, addr, (u32)val); 367e3037485SYan-Hsuan Chuang break; 368e3037485SYan-Hsuan Chuang default: 369e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 370e3037485SYan-Hsuan Chuang "error write length = %d\n", len); 371e3037485SYan-Hsuan Chuang break; 372e3037485SYan-Hsuan Chuang } 373e3037485SYan-Hsuan Chuang 374e3037485SYan-Hsuan Chuang return count; 375e3037485SYan-Hsuan Chuang } 376e3037485SYan-Hsuan Chuang 377c376c1fcSTzu-En Huang static ssize_t rtw_debugfs_set_h2c(struct file *filp, 378c376c1fcSTzu-En Huang const char __user *buffer, 379c376c1fcSTzu-En Huang size_t count, loff_t *loff) 380c376c1fcSTzu-En Huang { 381c376c1fcSTzu-En Huang struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 382c376c1fcSTzu-En Huang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 383c376c1fcSTzu-En Huang char tmp[32 + 1]; 384c376c1fcSTzu-En Huang u8 param[8]; 385c376c1fcSTzu-En Huang int num; 386c376c1fcSTzu-En Huang 387c376c1fcSTzu-En Huang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 388c376c1fcSTzu-En Huang 389c376c1fcSTzu-En Huang num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", 390c376c1fcSTzu-En Huang ¶m[0], ¶m[1], ¶m[2], ¶m[3], 391c376c1fcSTzu-En Huang ¶m[4], ¶m[5], ¶m[6], ¶m[7]); 392c376c1fcSTzu-En Huang if (num != 8) { 393c376c1fcSTzu-En Huang rtw_info(rtwdev, "invalid H2C command format for debug\n"); 394c376c1fcSTzu-En Huang return -EINVAL; 395c376c1fcSTzu-En Huang } 396c376c1fcSTzu-En Huang 397c376c1fcSTzu-En Huang rtw_fw_h2c_cmd_dbg(rtwdev, param); 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 421e3037485SYan-Hsuan Chuang rtw_write_rf(rtwdev, path, addr, mask, val); 422e3037485SYan-Hsuan Chuang rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 423e3037485SYan-Hsuan Chuang "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", 424e3037485SYan-Hsuan Chuang path, addr, mask, val); 425e3037485SYan-Hsuan Chuang 426e3037485SYan-Hsuan Chuang return count; 427e3037485SYan-Hsuan Chuang } 428e3037485SYan-Hsuan Chuang 429e3037485SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_rf_read(struct file *filp, 430e3037485SYan-Hsuan Chuang const char __user *buffer, 431e3037485SYan-Hsuan Chuang size_t count, loff_t *loff) 432e3037485SYan-Hsuan Chuang { 433e3037485SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 434e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 435e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 436e3037485SYan-Hsuan Chuang char tmp[32 + 1]; 437e3037485SYan-Hsuan Chuang u32 path, addr, mask; 438e3037485SYan-Hsuan Chuang int num; 439e3037485SYan-Hsuan Chuang 440e3037485SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 441e3037485SYan-Hsuan Chuang 442e3037485SYan-Hsuan Chuang num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); 443e3037485SYan-Hsuan Chuang 444e3037485SYan-Hsuan Chuang if (num != 3) { 445e3037485SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 446e3037485SYan-Hsuan Chuang return count; 447e3037485SYan-Hsuan Chuang } 448e3037485SYan-Hsuan Chuang 449e3037485SYan-Hsuan Chuang debugfs_priv->rf_path = path; 450e3037485SYan-Hsuan Chuang debugfs_priv->rf_addr = addr; 451e3037485SYan-Hsuan Chuang debugfs_priv->rf_mask = mask; 452e3037485SYan-Hsuan Chuang 453e3037485SYan-Hsuan Chuang return count; 454e3037485SYan-Hsuan Chuang } 455e3037485SYan-Hsuan Chuang 4561379e620SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_fix_rate(struct file *filp, 4571379e620SYan-Hsuan Chuang const char __user *buffer, 4581379e620SYan-Hsuan Chuang size_t count, loff_t *loff) 4591379e620SYan-Hsuan Chuang { 4601379e620SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 4611379e620SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 4621379e620SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 4631379e620SYan-Hsuan Chuang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 4641379e620SYan-Hsuan Chuang u8 fix_rate; 4651379e620SYan-Hsuan Chuang char tmp[32 + 1]; 4661379e620SYan-Hsuan Chuang int ret; 4671379e620SYan-Hsuan Chuang 4681379e620SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 4691379e620SYan-Hsuan Chuang 4701379e620SYan-Hsuan Chuang ret = kstrtou8(tmp, 0, &fix_rate); 4711379e620SYan-Hsuan Chuang if (ret) { 4721379e620SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid args, [rate]\n"); 4731379e620SYan-Hsuan Chuang return ret; 4741379e620SYan-Hsuan Chuang } 4751379e620SYan-Hsuan Chuang 4761379e620SYan-Hsuan Chuang dm_info->fix_rate = fix_rate; 4771379e620SYan-Hsuan Chuang 4781379e620SYan-Hsuan Chuang return count; 4791379e620SYan-Hsuan Chuang } 4801379e620SYan-Hsuan Chuang 481e3037485SYan-Hsuan Chuang static int rtw_debug_get_mac_page(struct seq_file *m, void *v) 482e3037485SYan-Hsuan Chuang { 483e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 484e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 485e3037485SYan-Hsuan Chuang u32 page = debugfs_priv->cb_data; 486e3037485SYan-Hsuan Chuang int i, n; 487e3037485SYan-Hsuan Chuang int max = 0xff; 488e3037485SYan-Hsuan Chuang 4890e25262bSLee Jones rtw_read32(rtwdev, debugfs_priv->cb_data); 490e3037485SYan-Hsuan Chuang for (n = 0; n <= max; ) { 491e3037485SYan-Hsuan Chuang seq_printf(m, "\n%8.8x ", n + page); 492e3037485SYan-Hsuan Chuang for (i = 0; i < 4 && n <= max; i++, n += 4) 493e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", 494e3037485SYan-Hsuan Chuang rtw_read32(rtwdev, (page | n))); 495e3037485SYan-Hsuan Chuang } 496e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 497e3037485SYan-Hsuan Chuang return 0; 498e3037485SYan-Hsuan Chuang } 499e3037485SYan-Hsuan Chuang 500e3037485SYan-Hsuan Chuang static int rtw_debug_get_bb_page(struct seq_file *m, void *v) 501e3037485SYan-Hsuan Chuang { 502e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 503e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 504e3037485SYan-Hsuan Chuang u32 page = debugfs_priv->cb_data; 505e3037485SYan-Hsuan Chuang int i, n; 506e3037485SYan-Hsuan Chuang int max = 0xff; 507e3037485SYan-Hsuan Chuang 5080e25262bSLee Jones rtw_read32(rtwdev, debugfs_priv->cb_data); 509e3037485SYan-Hsuan Chuang for (n = 0; n <= max; ) { 510e3037485SYan-Hsuan Chuang seq_printf(m, "\n%8.8x ", n + page); 511e3037485SYan-Hsuan Chuang for (i = 0; i < 4 && n <= max; i++, n += 4) 512e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", 513e3037485SYan-Hsuan Chuang rtw_read32(rtwdev, (page | n))); 514e3037485SYan-Hsuan Chuang } 515e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 516e3037485SYan-Hsuan Chuang return 0; 517e3037485SYan-Hsuan Chuang } 518e3037485SYan-Hsuan Chuang 519e3037485SYan-Hsuan Chuang static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) 520e3037485SYan-Hsuan Chuang { 521e3037485SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 522e3037485SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 523e3037485SYan-Hsuan Chuang u32 addr, offset, data; 524e3037485SYan-Hsuan Chuang u8 path; 525e3037485SYan-Hsuan Chuang 526e3037485SYan-Hsuan Chuang for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 527e3037485SYan-Hsuan Chuang seq_printf(m, "RF path:%d\n", path); 528e3037485SYan-Hsuan Chuang for (addr = 0; addr < 0x100; addr += 4) { 529e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", addr); 530e3037485SYan-Hsuan Chuang for (offset = 0; offset < 4; offset++) { 531e3037485SYan-Hsuan Chuang data = rtw_read_rf(rtwdev, path, addr + offset, 532e3037485SYan-Hsuan Chuang 0xffffffff); 533e3037485SYan-Hsuan Chuang seq_printf(m, "%8.8x ", data); 534e3037485SYan-Hsuan Chuang } 535e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 536e3037485SYan-Hsuan Chuang } 537e3037485SYan-Hsuan Chuang seq_puts(m, "\n"); 538e3037485SYan-Hsuan Chuang } 539e3037485SYan-Hsuan Chuang 540e3037485SYan-Hsuan Chuang return 0; 541e3037485SYan-Hsuan Chuang } 542e3037485SYan-Hsuan Chuang 5438812022cSZong-Zhe Yang static void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate) 5448812022cSZong-Zhe Yang { 5458812022cSZong-Zhe Yang static const char * const 5468812022cSZong-Zhe Yang cck_rate[] = {"1M", "2M", "5.5M", "11M"}; 5478812022cSZong-Zhe Yang u8 idx = rate - DESC_RATE1M; 5488812022cSZong-Zhe Yang 5498812022cSZong-Zhe Yang seq_printf(m, " CCK_%-5s", cck_rate[idx]); 5508812022cSZong-Zhe Yang } 5518812022cSZong-Zhe Yang 5528812022cSZong-Zhe Yang static void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate) 5538812022cSZong-Zhe Yang { 5548812022cSZong-Zhe Yang static const char * const 5558812022cSZong-Zhe Yang ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"}; 5568812022cSZong-Zhe Yang u8 idx = rate - DESC_RATE6M; 5578812022cSZong-Zhe Yang 5588812022cSZong-Zhe Yang seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]); 5598812022cSZong-Zhe Yang } 5608812022cSZong-Zhe Yang 5618812022cSZong-Zhe Yang static void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate) 5628812022cSZong-Zhe Yang { 5638812022cSZong-Zhe Yang u8 mcs_n = rate - DESC_RATEMCS0; 5648812022cSZong-Zhe Yang 5658812022cSZong-Zhe Yang seq_printf(m, " MCS%-6u", mcs_n); 5668812022cSZong-Zhe Yang } 5678812022cSZong-Zhe Yang 5688812022cSZong-Zhe Yang static void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate) 5698812022cSZong-Zhe Yang { 5708812022cSZong-Zhe Yang u8 idx = rate - DESC_RATEVHT1SS_MCS0; 5718812022cSZong-Zhe Yang u8 n_ss, mcs_n; 5728812022cSZong-Zhe Yang 5738812022cSZong-Zhe Yang /* n spatial stream */ 5748812022cSZong-Zhe Yang n_ss = 1 + idx / 10; 5758812022cSZong-Zhe Yang /* MCS n */ 5768812022cSZong-Zhe Yang mcs_n = idx % 10; 5778812022cSZong-Zhe Yang seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); 5788812022cSZong-Zhe Yang } 5798812022cSZong-Zhe Yang 580082a36dcSTsang-Shian Lin static void rtw_print_rate(struct seq_file *m, u8 rate) 581082a36dcSTsang-Shian Lin { 582082a36dcSTsang-Shian Lin switch (rate) { 583082a36dcSTsang-Shian Lin case DESC_RATE1M...DESC_RATE11M: 584082a36dcSTsang-Shian Lin rtw_print_cck_rate_txt(m, rate); 585082a36dcSTsang-Shian Lin break; 586082a36dcSTsang-Shian Lin case DESC_RATE6M...DESC_RATE54M: 587082a36dcSTsang-Shian Lin rtw_print_ofdm_rate_txt(m, rate); 588082a36dcSTsang-Shian Lin break; 589082a36dcSTsang-Shian Lin case DESC_RATEMCS0...DESC_RATEMCS15: 590082a36dcSTsang-Shian Lin rtw_print_ht_rate_txt(m, rate); 591082a36dcSTsang-Shian Lin break; 592082a36dcSTsang-Shian Lin case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: 593082a36dcSTsang-Shian Lin rtw_print_vht_rate_txt(m, rate); 594082a36dcSTsang-Shian Lin break; 595082a36dcSTsang-Shian Lin default: 596082a36dcSTsang-Shian Lin seq_printf(m, " Unknown rate=0x%x\n", rate); 597082a36dcSTsang-Shian Lin break; 598082a36dcSTsang-Shian Lin } 599082a36dcSTsang-Shian Lin } 600082a36dcSTsang-Shian Lin 601fada0931STzu-En Huang #define case_REGD(src) \ 602fada0931STzu-En Huang case RTW_REGD_##src: return #src 603fada0931STzu-En Huang 604fada0931STzu-En Huang static const char *rtw_get_regd_string(u8 regd) 605fada0931STzu-En Huang { 606fada0931STzu-En Huang switch (regd) { 607fada0931STzu-En Huang case_REGD(FCC); 608fada0931STzu-En Huang case_REGD(MKK); 609fada0931STzu-En Huang case_REGD(ETSI); 610fada0931STzu-En Huang case_REGD(IC); 611fada0931STzu-En Huang case_REGD(KCC); 612fada0931STzu-En Huang case_REGD(ACMA); 613fada0931STzu-En Huang case_REGD(CHILE); 614fada0931STzu-En Huang case_REGD(UKRAINE); 615fada0931STzu-En Huang case_REGD(MEXICO); 616fada0931STzu-En Huang case_REGD(CN); 617fada0931STzu-En Huang case_REGD(WW); 618fada0931STzu-En Huang default: 619fada0931STzu-En Huang return "Unknown"; 620fada0931STzu-En Huang } 621fada0931STzu-En Huang } 622fada0931STzu-En Huang 6238812022cSZong-Zhe Yang static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) 6248812022cSZong-Zhe Yang { 6258812022cSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 6268812022cSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6278812022cSZong-Zhe Yang struct rtw_hal *hal = &rtwdev->hal; 6288812022cSZong-Zhe Yang u8 path, rate; 6298812022cSZong-Zhe Yang struct rtw_power_params pwr_param = {0}; 6308812022cSZong-Zhe Yang u8 bw = hal->current_band_width; 6318812022cSZong-Zhe Yang u8 ch = hal->current_channel; 632f8509c38SZong-Zhe Yang u8 regd = rtw_regd_get(rtwdev); 6338812022cSZong-Zhe Yang 634*15728937SZong-Zhe Yang seq_printf(m, "channel: %u\n", ch); 635*15728937SZong-Zhe Yang seq_printf(m, "bandwidth: %u\n", bw); 636fada0931STzu-En Huang seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd)); 637608d2a08SPing-Ke Shih seq_printf(m, "%-4s %-10s %-3s%6s %-4s %4s (%-4s %-4s) %-4s\n", 638608d2a08SPing-Ke Shih "path", "rate", "pwr", "", "base", "", "byr", "lmt", "rem"); 6398812022cSZong-Zhe Yang 6408812022cSZong-Zhe Yang mutex_lock(&hal->tx_power_mutex); 6418812022cSZong-Zhe Yang for (path = RF_PATH_A; path <= RF_PATH_B; path++) { 6428812022cSZong-Zhe Yang /* there is no CCK rates used in 5G */ 6438812022cSZong-Zhe Yang if (hal->current_band_type == RTW_BAND_5G) 6448812022cSZong-Zhe Yang rate = DESC_RATE6M; 6458812022cSZong-Zhe Yang else 6468812022cSZong-Zhe Yang rate = DESC_RATE1M; 6478812022cSZong-Zhe Yang 6488812022cSZong-Zhe Yang /* now, not support vht 3ss and vht 4ss*/ 6498812022cSZong-Zhe Yang for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) { 6508812022cSZong-Zhe Yang /* now, not support ht 3ss and ht 4ss*/ 6518812022cSZong-Zhe Yang if (rate > DESC_RATEMCS15 && 6528812022cSZong-Zhe Yang rate < DESC_RATEVHT1SS_MCS0) 6538812022cSZong-Zhe Yang continue; 6548812022cSZong-Zhe Yang 6558812022cSZong-Zhe Yang rtw_get_tx_power_params(rtwdev, path, rate, bw, 6568812022cSZong-Zhe Yang ch, regd, &pwr_param); 6578812022cSZong-Zhe Yang 6588812022cSZong-Zhe Yang seq_printf(m, "%4c ", path + 'A'); 659082a36dcSTsang-Shian Lin rtw_print_rate(m, rate); 660608d2a08SPing-Ke Shih seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d) %4d\n", 6618812022cSZong-Zhe Yang hal->tx_pwr_tbl[path][rate], 6628812022cSZong-Zhe Yang hal->tx_pwr_tbl[path][rate], 6638812022cSZong-Zhe Yang pwr_param.pwr_base, 6648812022cSZong-Zhe Yang min_t(s8, pwr_param.pwr_offset, 6658812022cSZong-Zhe Yang pwr_param.pwr_limit), 666608d2a08SPing-Ke Shih pwr_param.pwr_offset, pwr_param.pwr_limit, 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); 6728812022cSZong-Zhe Yang 6738812022cSZong-Zhe Yang return 0; 6748812022cSZong-Zhe Yang } 6758812022cSZong-Zhe Yang 6761a589bd5SChing-Te Ku void rtw_debugfs_get_simple_phy_info(struct seq_file *m) 6771a589bd5SChing-Te Ku { 6781a589bd5SChing-Te Ku struct rtw_debugfs_priv *debugfs_priv = m->private; 6791a589bd5SChing-Te Ku struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 6801a589bd5SChing-Te Ku struct rtw_hal *hal = &rtwdev->hal; 6811a589bd5SChing-Te Ku struct rtw_dm_info *dm_info = &rtwdev->dm_info; 6821a589bd5SChing-Te Ku struct rtw_traffic_stats *stats = &rtwdev->stats; 6831a589bd5SChing-Te Ku 6841a589bd5SChing-Te Ku seq_printf(m, "%-40s = %ddBm/ %d\n", "RSSI/ STA Channel", 6851a589bd5SChing-Te Ku dm_info->rssi[RF_PATH_A] - 100, hal->current_channel); 6861a589bd5SChing-Te Ku 6871a589bd5SChing-Te Ku seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 6881a589bd5SChing-Te Ku stats->tx_throughput, stats->rx_throughput); 6891a589bd5SChing-Te Ku 6901a589bd5SChing-Te Ku seq_puts(m, "[Tx Rate] = "); 6911a589bd5SChing-Te Ku rtw_print_rate(m, dm_info->tx_rate); 6921a589bd5SChing-Te Ku seq_printf(m, "(0x%x)\n", dm_info->tx_rate); 6931a589bd5SChing-Te Ku 6941a589bd5SChing-Te Ku seq_puts(m, "[Rx Rate] = "); 6951a589bd5SChing-Te Ku rtw_print_rate(m, dm_info->curr_rx_rate); 6961a589bd5SChing-Te Ku seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 6971a589bd5SChing-Te Ku } 6981a589bd5SChing-Te Ku 699082a36dcSTsang-Shian Lin static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) 700082a36dcSTsang-Shian Lin { 701082a36dcSTsang-Shian Lin struct rtw_debugfs_priv *debugfs_priv = m->private; 702082a36dcSTsang-Shian Lin struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 703082a36dcSTsang-Shian Lin struct rtw_dm_info *dm_info = &rtwdev->dm_info; 704082a36dcSTsang-Shian Lin struct rtw_traffic_stats *stats = &rtwdev->stats; 705082a36dcSTsang-Shian Lin struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; 706082a36dcSTsang-Shian Lin struct rtw_efuse *efuse = &rtwdev->efuse; 707082a36dcSTsang-Shian Lin struct ewma_evm *ewma_evm = dm_info->ewma_evm; 708082a36dcSTsang-Shian Lin struct ewma_snr *ewma_snr = dm_info->ewma_snr; 709082a36dcSTsang-Shian Lin u8 ss, rate_id; 710082a36dcSTsang-Shian Lin 711082a36dcSTsang-Shian Lin seq_puts(m, "==========[Common Info]========\n"); 712082a36dcSTsang-Shian Lin seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); 713082a36dcSTsang-Shian Lin seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); 714082a36dcSTsang-Shian Lin seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); 715082a36dcSTsang-Shian Lin seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); 716082a36dcSTsang-Shian Lin seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n\n", 717082a36dcSTsang-Shian Lin stats->tx_throughput, stats->rx_throughput); 718082a36dcSTsang-Shian Lin 719082a36dcSTsang-Shian Lin seq_puts(m, "==========[Tx Phy Info]========\n"); 720082a36dcSTsang-Shian Lin seq_puts(m, "[Tx Rate] = "); 721082a36dcSTsang-Shian Lin rtw_print_rate(m, dm_info->tx_rate); 722082a36dcSTsang-Shian Lin seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); 723082a36dcSTsang-Shian Lin 724082a36dcSTsang-Shian Lin seq_puts(m, "==========[Rx Phy Info]========\n"); 725082a36dcSTsang-Shian Lin seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); 726082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Rate] = "); 727082a36dcSTsang-Shian Lin rtw_print_rate(m, dm_info->curr_rx_rate); 728082a36dcSTsang-Shian Lin seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 729082a36dcSTsang-Shian Lin 730082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Rate Count]:\n"); 731082a36dcSTsang-Shian Lin seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", 732082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE1M], 733082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE2M], 734082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE5_5M], 735082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE11M]); 736082a36dcSTsang-Shian Lin 737082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 738082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE6M], 739082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE9M], 740082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE12M], 741082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE18M], 742082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE24M], 743082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE36M], 744082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE48M], 745082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[DESC_RATE54M]); 746082a36dcSTsang-Shian Lin 747082a36dcSTsang-Shian Lin for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 748082a36dcSTsang-Shian Lin rate_id = DESC_RATEMCS0 + ss * 8; 749082a36dcSTsang-Shian Lin seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 750082a36dcSTsang-Shian Lin ss * 8, ss * 8 + 7, 751082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id], 752082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 1], 753082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 2], 754082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 3], 755082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 4], 756082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 5], 757082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 6], 758082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 7]); 759082a36dcSTsang-Shian Lin } 760082a36dcSTsang-Shian Lin 761082a36dcSTsang-Shian Lin for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 762082a36dcSTsang-Shian Lin rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; 763082a36dcSTsang-Shian Lin seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", 764082a36dcSTsang-Shian Lin ss + 1, 765082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id], 766082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 1], 767082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 2], 768082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 3], 769082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 4], 770082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 5], 771082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 6], 772082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 7], 773082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 8], 774082a36dcSTsang-Shian Lin last_cnt->num_qry_pkt[rate_id + 9]); 775082a36dcSTsang-Shian Lin } 776082a36dcSTsang-Shian Lin 777082a36dcSTsang-Shian Lin seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", 778082a36dcSTsang-Shian Lin dm_info->rssi[RF_PATH_A] - 100, 779082a36dcSTsang-Shian Lin dm_info->rssi[RF_PATH_B] - 100); 780082a36dcSTsang-Shian Lin seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", 781082a36dcSTsang-Shian Lin dm_info->rx_evm_dbm[RF_PATH_A], 782082a36dcSTsang-Shian Lin dm_info->rx_evm_dbm[RF_PATH_B]); 783082a36dcSTsang-Shian Lin seq_printf(m, "[Rx SNR] = {%d, %d}\n", 784082a36dcSTsang-Shian Lin dm_info->rx_snr[RF_PATH_A], 785082a36dcSTsang-Shian Lin dm_info->rx_snr[RF_PATH_B]); 786082a36dcSTsang-Shian Lin seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", 787082a36dcSTsang-Shian Lin dm_info->cfo_tail[RF_PATH_A], 788082a36dcSTsang-Shian Lin dm_info->cfo_tail[RF_PATH_B]); 789082a36dcSTsang-Shian Lin 790082a36dcSTsang-Shian Lin if (dm_info->curr_rx_rate >= DESC_RATE11M) { 791082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Average Status]:\n"); 792082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", 793082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), 794082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); 795082a36dcSTsang-Shian Lin seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", 796082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), 797082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); 798082a36dcSTsang-Shian Lin seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", 799082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), 800082a36dcSTsang-Shian Lin (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), 801082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), 802082a36dcSTsang-Shian Lin (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); 803082a36dcSTsang-Shian Lin } 804082a36dcSTsang-Shian Lin 805082a36dcSTsang-Shian Lin seq_puts(m, "[Rx Counter]:\n"); 806082a36dcSTsang-Shian Lin seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", 807082a36dcSTsang-Shian Lin dm_info->cck_cca_cnt, 808082a36dcSTsang-Shian Lin dm_info->ofdm_cca_cnt, 809082a36dcSTsang-Shian Lin dm_info->total_cca_cnt); 810082a36dcSTsang-Shian Lin seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", 811082a36dcSTsang-Shian Lin dm_info->cck_fa_cnt, 812082a36dcSTsang-Shian Lin dm_info->ofdm_fa_cnt, 813082a36dcSTsang-Shian Lin dm_info->total_fa_cnt); 814082a36dcSTsang-Shian Lin seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", 815082a36dcSTsang-Shian Lin dm_info->cck_ok_cnt, dm_info->cck_err_cnt); 816082a36dcSTsang-Shian Lin seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", 817082a36dcSTsang-Shian Lin dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); 818082a36dcSTsang-Shian Lin seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", 819082a36dcSTsang-Shian Lin dm_info->ht_ok_cnt, dm_info->ht_err_cnt); 820082a36dcSTsang-Shian Lin seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", 821082a36dcSTsang-Shian Lin dm_info->vht_ok_cnt, dm_info->vht_err_cnt); 8221fe188daSYan-Hsuan Chuang 8231fe188daSYan-Hsuan Chuang return 0; 8241fe188daSYan-Hsuan Chuang } 8251fe188daSYan-Hsuan Chuang 8261fe188daSYan-Hsuan Chuang static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) 8271fe188daSYan-Hsuan Chuang { 8281fe188daSYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 8291fe188daSYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8301fe188daSYan-Hsuan Chuang 8311fe188daSYan-Hsuan Chuang rtw_coex_display_coex_info(rtwdev, m); 8321fe188daSYan-Hsuan Chuang 833082a36dcSTsang-Shian Lin return 0; 834082a36dcSTsang-Shian Lin } 835082a36dcSTsang-Shian Lin 836d0555093SYan-Hsuan Chuang static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, 837d0555093SYan-Hsuan Chuang const char __user *buffer, 838d0555093SYan-Hsuan Chuang size_t count, loff_t *loff) 839d0555093SYan-Hsuan Chuang { 840d0555093SYan-Hsuan Chuang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 841d0555093SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 842d0555093SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 843d0555093SYan-Hsuan Chuang struct rtw_coex *coex = &rtwdev->coex; 844d0555093SYan-Hsuan Chuang char tmp[32 + 1]; 845d0555093SYan-Hsuan Chuang bool enable; 846d0555093SYan-Hsuan Chuang int ret; 847d0555093SYan-Hsuan Chuang 848d0555093SYan-Hsuan Chuang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 849d0555093SYan-Hsuan Chuang 850d0555093SYan-Hsuan Chuang ret = kstrtobool(tmp, &enable); 851d0555093SYan-Hsuan Chuang if (ret) { 852d0555093SYan-Hsuan Chuang rtw_warn(rtwdev, "invalid arguments\n"); 853d0555093SYan-Hsuan Chuang return ret; 854d0555093SYan-Hsuan Chuang } 855d0555093SYan-Hsuan Chuang 856d0555093SYan-Hsuan Chuang mutex_lock(&rtwdev->mutex); 857d3a78c7aSYANG LI coex->manual_control = !enable; 858d0555093SYan-Hsuan Chuang mutex_unlock(&rtwdev->mutex); 859d0555093SYan-Hsuan Chuang 860d0555093SYan-Hsuan Chuang return count; 861d0555093SYan-Hsuan Chuang } 862d0555093SYan-Hsuan Chuang 863d0555093SYan-Hsuan Chuang static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) 864d0555093SYan-Hsuan Chuang { 865d0555093SYan-Hsuan Chuang struct rtw_debugfs_priv *debugfs_priv = m->private; 866d0555093SYan-Hsuan Chuang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 867d0555093SYan-Hsuan Chuang struct rtw_coex *coex = &rtwdev->coex; 868d0555093SYan-Hsuan Chuang 869d0555093SYan-Hsuan Chuang seq_printf(m, "coex mechanism %s\n", 87032c3a8c7SChing-Te Ku coex->manual_control ? "disabled" : "enabled"); 871d0555093SYan-Hsuan Chuang 872d0555093SYan-Hsuan Chuang return 0; 873d0555093SYan-Hsuan Chuang } 874d0555093SYan-Hsuan Chuang 8757285eb96SZong-Zhe Yang static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, 8767285eb96SZong-Zhe Yang const char __user *buffer, 8777285eb96SZong-Zhe Yang size_t count, loff_t *loff) 8787285eb96SZong-Zhe Yang { 8797285eb96SZong-Zhe Yang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 8807285eb96SZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 8817285eb96SZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8827285eb96SZong-Zhe Yang bool input; 8837285eb96SZong-Zhe Yang int err; 8847285eb96SZong-Zhe Yang 8857285eb96SZong-Zhe Yang err = kstrtobool_from_user(buffer, count, &input); 8867285eb96SZong-Zhe Yang if (err) 8877285eb96SZong-Zhe Yang return err; 8887285eb96SZong-Zhe Yang 8897285eb96SZong-Zhe Yang rtw_edcca_enabled = input; 8907285eb96SZong-Zhe Yang rtw_phy_adaptivity_set_mode(rtwdev); 8917285eb96SZong-Zhe Yang 8927285eb96SZong-Zhe Yang return count; 8937285eb96SZong-Zhe Yang } 8947285eb96SZong-Zhe Yang 8957285eb96SZong-Zhe Yang static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v) 8967285eb96SZong-Zhe Yang { 8977285eb96SZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 8987285eb96SZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 8997285eb96SZong-Zhe Yang struct rtw_dm_info *dm_info = &rtwdev->dm_info; 9007285eb96SZong-Zhe Yang 9017285eb96SZong-Zhe Yang seq_printf(m, "EDCCA %s: EDCCA mode %d\n", 9027285eb96SZong-Zhe Yang rtw_edcca_enabled ? "enabled" : "disabled", 9037285eb96SZong-Zhe Yang dm_info->edcca_mode); 9047285eb96SZong-Zhe Yang return 0; 9057285eb96SZong-Zhe Yang } 9067285eb96SZong-Zhe Yang 90713ce240aSZong-Zhe Yang static ssize_t rtw_debugfs_set_fw_crash(struct file *filp, 90813ce240aSZong-Zhe Yang const char __user *buffer, 90913ce240aSZong-Zhe Yang size_t count, loff_t *loff) 91013ce240aSZong-Zhe Yang { 91113ce240aSZong-Zhe Yang struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 91213ce240aSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 91313ce240aSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 91413ce240aSZong-Zhe Yang char tmp[32 + 1]; 91513ce240aSZong-Zhe Yang bool input; 91613ce240aSZong-Zhe Yang int ret; 91713ce240aSZong-Zhe Yang 91813ce240aSZong-Zhe Yang rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 91913ce240aSZong-Zhe Yang 92013ce240aSZong-Zhe Yang ret = kstrtobool(tmp, &input); 92113ce240aSZong-Zhe Yang if (ret) 92213ce240aSZong-Zhe Yang return -EINVAL; 92313ce240aSZong-Zhe Yang 92413ce240aSZong-Zhe Yang if (!input) 92513ce240aSZong-Zhe Yang return -EINVAL; 92613ce240aSZong-Zhe Yang 9277b80f3e4SZong-Zhe Yang if (test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) 9287b80f3e4SZong-Zhe Yang return -EINPROGRESS; 9297b80f3e4SZong-Zhe Yang 9307b80f3e4SZong-Zhe Yang mutex_lock(&rtwdev->mutex); 9317b80f3e4SZong-Zhe Yang rtw_leave_lps_deep(rtwdev); 9326cd4b59dSZong-Zhe Yang set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags); 93313ce240aSZong-Zhe Yang rtw_write8(rtwdev, REG_HRCV_MSG, 1); 9347b80f3e4SZong-Zhe Yang mutex_unlock(&rtwdev->mutex); 93513ce240aSZong-Zhe Yang 93613ce240aSZong-Zhe Yang return count; 93713ce240aSZong-Zhe Yang } 93813ce240aSZong-Zhe Yang 93913ce240aSZong-Zhe Yang static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v) 94013ce240aSZong-Zhe Yang { 94113ce240aSZong-Zhe Yang struct rtw_debugfs_priv *debugfs_priv = m->private; 94213ce240aSZong-Zhe Yang struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 94313ce240aSZong-Zhe Yang 9446cd4b59dSZong-Zhe Yang seq_printf(m, "%d\n", 9456cd4b59dSZong-Zhe Yang test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) || 9466cd4b59dSZong-Zhe Yang test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)); 94713ce240aSZong-Zhe Yang return 0; 94813ce240aSZong-Zhe Yang } 94913ce240aSZong-Zhe Yang 950272cda71SYu-Yen Ting static ssize_t rtw_debugfs_set_force_lowest_basic_rate(struct file *filp, 951272cda71SYu-Yen Ting const char __user *buffer, 952272cda71SYu-Yen Ting size_t count, loff_t *loff) 953272cda71SYu-Yen Ting { 954272cda71SYu-Yen Ting struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 955272cda71SYu-Yen Ting struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 956272cda71SYu-Yen Ting struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 957272cda71SYu-Yen Ting bool input; 958272cda71SYu-Yen Ting int err; 959272cda71SYu-Yen Ting 960272cda71SYu-Yen Ting err = kstrtobool_from_user(buffer, count, &input); 961272cda71SYu-Yen Ting if (err) 962272cda71SYu-Yen Ting return err; 963272cda71SYu-Yen Ting 964272cda71SYu-Yen Ting if (input) 965272cda71SYu-Yen Ting set_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 966272cda71SYu-Yen Ting else 967272cda71SYu-Yen Ting clear_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 968272cda71SYu-Yen Ting 969272cda71SYu-Yen Ting return count; 970272cda71SYu-Yen Ting } 971272cda71SYu-Yen Ting 972272cda71SYu-Yen Ting static int rtw_debugfs_get_force_lowest_basic_rate(struct seq_file *m, void *v) 973272cda71SYu-Yen Ting { 974272cda71SYu-Yen Ting struct rtw_debugfs_priv *debugfs_priv = m->private; 975272cda71SYu-Yen Ting struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 976272cda71SYu-Yen Ting 977272cda71SYu-Yen Ting seq_printf(m, "force lowest basic rate: %d\n", 978272cda71SYu-Yen Ting test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags)); 979272cda71SYu-Yen Ting 980272cda71SYu-Yen Ting return 0; 981272cda71SYu-Yen Ting } 982272cda71SYu-Yen Ting 9833b25bac8SGuo-Feng Fan static ssize_t rtw_debugfs_set_dm_cap(struct file *filp, 9843b25bac8SGuo-Feng Fan const char __user *buffer, 9853b25bac8SGuo-Feng Fan size_t count, loff_t *loff) 9863b25bac8SGuo-Feng Fan { 9873b25bac8SGuo-Feng Fan struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 9883b25bac8SGuo-Feng Fan struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 9893b25bac8SGuo-Feng Fan struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 9903b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 9913b25bac8SGuo-Feng Fan int bit; 9923b25bac8SGuo-Feng Fan bool en; 9933b25bac8SGuo-Feng Fan 9943b25bac8SGuo-Feng Fan if (kstrtoint_from_user(buffer, count, 10, &bit)) 9953b25bac8SGuo-Feng Fan return -EINVAL; 9963b25bac8SGuo-Feng Fan 9973b25bac8SGuo-Feng Fan en = bit > 0; 9983b25bac8SGuo-Feng Fan bit = abs(bit); 9993b25bac8SGuo-Feng Fan 10003b25bac8SGuo-Feng Fan if (bit >= RTW_DM_CAP_NUM) { 10013b25bac8SGuo-Feng Fan rtw_warn(rtwdev, "unknown DM CAP %d\n", bit); 10023b25bac8SGuo-Feng Fan return -EINVAL; 10033b25bac8SGuo-Feng Fan } 10043b25bac8SGuo-Feng Fan 10053b25bac8SGuo-Feng Fan if (en) 10063b25bac8SGuo-Feng Fan dm_info->dm_flags &= ~BIT(bit); 10073b25bac8SGuo-Feng Fan else 10083b25bac8SGuo-Feng Fan dm_info->dm_flags |= BIT(bit); 10093b25bac8SGuo-Feng Fan 10103b25bac8SGuo-Feng Fan debugfs_priv->dm_cap.bit = bit; 10113b25bac8SGuo-Feng Fan 10123b25bac8SGuo-Feng Fan return count; 10133b25bac8SGuo-Feng Fan } 10143b25bac8SGuo-Feng Fan 10153b25bac8SGuo-Feng Fan static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) 10163b25bac8SGuo-Feng Fan { 10173b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10183b25bac8SGuo-Feng Fan struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 10193b25bac8SGuo-Feng Fan int i, path; 10203b25bac8SGuo-Feng Fan u32 val; 10213b25bac8SGuo-Feng Fan 10223b25bac8SGuo-Feng Fan seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK, 10233b25bac8SGuo-Feng Fan dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', 10243b25bac8SGuo-Feng Fan rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); 10253b25bac8SGuo-Feng Fan 10263b25bac8SGuo-Feng Fan for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 10273b25bac8SGuo-Feng Fan val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); 10283b25bac8SGuo-Feng Fan seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); 10293b25bac8SGuo-Feng Fan 10303b25bac8SGuo-Feng Fan for (i = 0; i < RF_HW_OFFSET_NUM; i++) 10313b25bac8SGuo-Feng Fan seq_printf(m, "[TXGAPK] offset %d %d\n", 10323b25bac8SGuo-Feng Fan txgapk->rf3f_fs[path][i], i); 10333b25bac8SGuo-Feng Fan seq_puts(m, "\n"); 10343b25bac8SGuo-Feng Fan } 10353b25bac8SGuo-Feng Fan } 10363b25bac8SGuo-Feng Fan 10373b25bac8SGuo-Feng Fan static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) 10383b25bac8SGuo-Feng Fan { 10393b25bac8SGuo-Feng Fan struct rtw_debugfs_priv *debugfs_priv = m->private; 10403b25bac8SGuo-Feng Fan struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 10413b25bac8SGuo-Feng Fan struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10423b25bac8SGuo-Feng Fan int i; 10433b25bac8SGuo-Feng Fan 10443b25bac8SGuo-Feng Fan switch (debugfs_priv->dm_cap.bit) { 10453b25bac8SGuo-Feng Fan case RTW_DM_CAP_TXGAPK: 10463b25bac8SGuo-Feng Fan dump_gapk_status(rtwdev, m); 10473b25bac8SGuo-Feng Fan break; 10483b25bac8SGuo-Feng Fan default: 10493b25bac8SGuo-Feng Fan for (i = 1; i < RTW_DM_CAP_NUM; i++) { 10503b25bac8SGuo-Feng Fan seq_printf(m, "(%2d) %c%s\n", i, 10513b25bac8SGuo-Feng Fan dm_info->dm_flags & BIT(i) ? '-' : '+', 10523b25bac8SGuo-Feng Fan rtw_dm_cap_strs[i]); 10533b25bac8SGuo-Feng Fan } 10543b25bac8SGuo-Feng Fan break; 10553b25bac8SGuo-Feng Fan } 10563b25bac8SGuo-Feng Fan debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA; 10573b25bac8SGuo-Feng Fan return 0; 10583b25bac8SGuo-Feng Fan } 10593b25bac8SGuo-Feng Fan 1060e3037485SYan-Hsuan Chuang #define rtw_debug_impl_mac(page, addr) \ 1061e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ 1062e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_mac_page, \ 1063e3037485SYan-Hsuan Chuang .cb_data = addr, \ 1064e3037485SYan-Hsuan Chuang } 1065e3037485SYan-Hsuan Chuang 1066e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(0, 0x0000); 1067e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(1, 0x0100); 1068e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(2, 0x0200); 1069e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(3, 0x0300); 1070e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(4, 0x0400); 1071e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(5, 0x0500); 1072e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(6, 0x0600); 1073e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(7, 0x0700); 1074e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(10, 0x1000); 1075e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(11, 0x1100); 1076e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(12, 0x1200); 1077e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(13, 0x1300); 1078e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(14, 0x1400); 1079e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(15, 0x1500); 1080e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(16, 0x1600); 1081e3037485SYan-Hsuan Chuang rtw_debug_impl_mac(17, 0x1700); 1082e3037485SYan-Hsuan Chuang 1083e3037485SYan-Hsuan Chuang #define rtw_debug_impl_bb(page, addr) \ 1084e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \ 1085e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_bb_page, \ 1086e3037485SYan-Hsuan Chuang .cb_data = addr, \ 1087e3037485SYan-Hsuan Chuang } 1088e3037485SYan-Hsuan Chuang 1089e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(8, 0x0800); 1090e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(9, 0x0900); 1091e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(a, 0x0a00); 1092e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(b, 0x0b00); 1093e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(c, 0x0c00); 1094e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(d, 0x0d00); 1095e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(e, 0x0e00); 1096e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(f, 0x0f00); 1097e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(18, 0x1800); 1098e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(19, 0x1900); 1099e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1a, 0x1a00); 1100e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1b, 0x1b00); 1101e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1c, 0x1c00); 1102e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1d, 0x1d00); 1103e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1e, 0x1e00); 1104e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(1f, 0x1f00); 1105e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(2c, 0x2c00); 1106e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(2d, 0x2d00); 1107e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(40, 0x4000); 1108e3037485SYan-Hsuan Chuang rtw_debug_impl_bb(41, 0x4100); 1109e3037485SYan-Hsuan Chuang 1110e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = { 1111e3037485SYan-Hsuan Chuang .cb_read = rtw_debug_get_rf_dump, 1112e3037485SYan-Hsuan Chuang }; 1113e3037485SYan-Hsuan Chuang 11148812022cSZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = { 11158812022cSZong-Zhe Yang .cb_read = rtw_debugfs_get_tx_pwr_tbl, 11168812022cSZong-Zhe Yang }; 11178812022cSZong-Zhe Yang 1118e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_write_reg = { 1119e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_write_reg, 1120e3037485SYan-Hsuan Chuang }; 1121e3037485SYan-Hsuan Chuang 1122c376c1fcSTzu-En Huang static struct rtw_debugfs_priv rtw_debug_priv_h2c = { 1123c376c1fcSTzu-En Huang .cb_write = rtw_debugfs_set_h2c, 1124c376c1fcSTzu-En Huang }; 1125c376c1fcSTzu-En Huang 1126e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_write = { 1127e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rf_write, 1128e3037485SYan-Hsuan Chuang }; 1129e3037485SYan-Hsuan Chuang 1130e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rf_read = { 1131e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rf_read, 1132e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_rf_read, 1133e3037485SYan-Hsuan Chuang }; 1134e3037485SYan-Hsuan Chuang 1135e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_read_reg = { 1136e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_read_reg, 1137e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_read_reg, 1138e3037485SYan-Hsuan Chuang }; 1139e3037485SYan-Hsuan Chuang 11401379e620SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = { 11411379e620SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_fix_rate, 11421379e620SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_fix_rate, 11431379e620SYan-Hsuan Chuang }; 11441379e620SYan-Hsuan Chuang 1145e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = { 1146e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_single_input, 1147e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_dump_cam, 1148e3037485SYan-Hsuan Chuang }; 1149e3037485SYan-Hsuan Chuang 1150e3037485SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = { 1151e3037485SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_rsvd_page, 1152e3037485SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_rsvd_page, 1153e3037485SYan-Hsuan Chuang }; 1154e3037485SYan-Hsuan Chuang 1155082a36dcSTsang-Shian Lin static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { 1156082a36dcSTsang-Shian Lin .cb_read = rtw_debugfs_get_phy_info, 1157082a36dcSTsang-Shian Lin }; 1158082a36dcSTsang-Shian Lin 1159d0555093SYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { 1160d0555093SYan-Hsuan Chuang .cb_write = rtw_debugfs_set_coex_enable, 1161d0555093SYan-Hsuan Chuang .cb_read = rtw_debugfs_get_coex_enable, 1162d0555093SYan-Hsuan Chuang }; 1163d0555093SYan-Hsuan Chuang 11641fe188daSYan-Hsuan Chuang static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { 11651fe188daSYan-Hsuan Chuang .cb_read = rtw_debugfs_get_coex_info, 11661fe188daSYan-Hsuan Chuang }; 11671fe188daSYan-Hsuan Chuang 11687285eb96SZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { 11697285eb96SZong-Zhe Yang .cb_write = rtw_debugfs_set_edcca_enable, 11707285eb96SZong-Zhe Yang .cb_read = rtw_debugfs_get_edcca_enable, 11717285eb96SZong-Zhe Yang }; 11727285eb96SZong-Zhe Yang 117313ce240aSZong-Zhe Yang static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { 117413ce240aSZong-Zhe Yang .cb_write = rtw_debugfs_set_fw_crash, 117513ce240aSZong-Zhe Yang .cb_read = rtw_debugfs_get_fw_crash, 117613ce240aSZong-Zhe Yang }; 117713ce240aSZong-Zhe Yang 1178272cda71SYu-Yen Ting static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = { 1179272cda71SYu-Yen Ting .cb_write = rtw_debugfs_set_force_lowest_basic_rate, 1180272cda71SYu-Yen Ting .cb_read = rtw_debugfs_get_force_lowest_basic_rate, 1181272cda71SYu-Yen Ting }; 1182272cda71SYu-Yen Ting 11833b25bac8SGuo-Feng Fan static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { 11843b25bac8SGuo-Feng Fan .cb_write = rtw_debugfs_set_dm_cap, 11853b25bac8SGuo-Feng Fan .cb_read = rtw_debugfs_get_dm_cap, 11863b25bac8SGuo-Feng Fan }; 11873b25bac8SGuo-Feng Fan 1188e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_core(name, mode, fopname, parent) \ 1189e3037485SYan-Hsuan Chuang do { \ 1190e3037485SYan-Hsuan Chuang rtw_debug_priv_ ##name.rtwdev = rtwdev; \ 1191e3037485SYan-Hsuan Chuang if (!debugfs_create_file(#name, mode, \ 1192e3037485SYan-Hsuan Chuang parent, &rtw_debug_priv_ ##name,\ 1193e3037485SYan-Hsuan Chuang &file_ops_ ##fopname)) \ 1194e3037485SYan-Hsuan Chuang pr_debug("Unable to initialize debugfs:%s\n", \ 1195e3037485SYan-Hsuan Chuang #name); \ 1196e3037485SYan-Hsuan Chuang } while (0) 1197e3037485SYan-Hsuan Chuang 1198e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_w(name) \ 1199e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir) 1200e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_rw(name) \ 1201e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir) 1202e3037485SYan-Hsuan Chuang #define rtw_debugfs_add_r(name) \ 1203e3037485SYan-Hsuan Chuang rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) 1204e3037485SYan-Hsuan Chuang 1205e3037485SYan-Hsuan Chuang void rtw_debugfs_init(struct rtw_dev *rtwdev) 1206e3037485SYan-Hsuan Chuang { 12079f7d65fbSColin Ian King struct dentry *debugfs_topdir; 1208e3037485SYan-Hsuan Chuang 1209e3037485SYan-Hsuan Chuang debugfs_topdir = debugfs_create_dir("rtw88", 1210e3037485SYan-Hsuan Chuang rtwdev->hw->wiphy->debugfsdir); 1211e3037485SYan-Hsuan Chuang rtw_debugfs_add_w(write_reg); 1212e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(read_reg); 1213e3037485SYan-Hsuan Chuang rtw_debugfs_add_w(rf_write); 1214e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(rf_read); 12151379e620SYan-Hsuan Chuang rtw_debugfs_add_rw(fix_rate); 1216e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(dump_cam); 1217e3037485SYan-Hsuan Chuang rtw_debugfs_add_rw(rsvd_page); 1218082a36dcSTsang-Shian Lin rtw_debugfs_add_r(phy_info); 12191fe188daSYan-Hsuan Chuang rtw_debugfs_add_r(coex_info); 1220d0555093SYan-Hsuan Chuang rtw_debugfs_add_rw(coex_enable); 1221c376c1fcSTzu-En Huang rtw_debugfs_add_w(h2c); 1222e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_0); 1223e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_1); 1224e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_2); 1225e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_3); 1226e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_4); 1227e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_5); 1228e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_6); 1229e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_7); 1230e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_8); 1231e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_9); 1232e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_a); 1233e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_b); 1234e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_c); 1235e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_d); 1236e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_e); 1237e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_f); 1238e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_10); 1239e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_11); 1240e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_12); 1241e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_13); 1242e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_14); 1243e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_15); 1244e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_16); 1245e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(mac_17); 1246e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_18); 1247e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_19); 1248e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1a); 1249e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1b); 1250e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1c); 1251e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1d); 1252e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1e); 1253e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_1f); 1254e3037485SYan-Hsuan Chuang if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { 1255e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_2c); 1256e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_2d); 1257e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_40); 1258e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(bb_41); 1259e3037485SYan-Hsuan Chuang } 1260e3037485SYan-Hsuan Chuang rtw_debugfs_add_r(rf_dump); 12618812022cSZong-Zhe Yang rtw_debugfs_add_r(tx_pwr_tbl); 12627285eb96SZong-Zhe Yang rtw_debugfs_add_rw(edcca_enable); 126313ce240aSZong-Zhe Yang rtw_debugfs_add_rw(fw_crash); 1264272cda71SYu-Yen Ting rtw_debugfs_add_rw(force_lowest_basic_rate); 12653b25bac8SGuo-Feng Fan rtw_debugfs_add_rw(dm_cap); 1266e3037485SYan-Hsuan Chuang } 1267e3037485SYan-Hsuan Chuang 1268e3037485SYan-Hsuan Chuang #endif /* CONFIG_RTW88_DEBUGFS */ 1269e3037485SYan-Hsuan Chuang 1270e3037485SYan-Hsuan Chuang #ifdef CONFIG_RTW88_DEBUG 1271e3037485SYan-Hsuan Chuang 1272e3037485SYan-Hsuan Chuang void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, 1273e3037485SYan-Hsuan Chuang const char *fmt, ...) 1274e3037485SYan-Hsuan Chuang { 1275e3037485SYan-Hsuan Chuang struct va_format vaf = { 1276e3037485SYan-Hsuan Chuang .fmt = fmt, 1277e3037485SYan-Hsuan Chuang }; 1278e3037485SYan-Hsuan Chuang va_list args; 1279e3037485SYan-Hsuan Chuang 1280e3037485SYan-Hsuan Chuang va_start(args, fmt); 1281e3037485SYan-Hsuan Chuang vaf.va = &args; 1282e3037485SYan-Hsuan Chuang 1283e3037485SYan-Hsuan Chuang if (rtw_debug_mask & mask) 1284e3037485SYan-Hsuan Chuang dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); 1285e3037485SYan-Hsuan Chuang 1286e3037485SYan-Hsuan Chuang va_end(args); 1287e3037485SYan-Hsuan Chuang } 1288e3037485SYan-Hsuan Chuang EXPORT_SYMBOL(__rtw_dbg); 1289e3037485SYan-Hsuan Chuang 1290e3037485SYan-Hsuan Chuang #endif /* CONFIG_RTW88_DEBUG */ 1291