162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 262306a36Sopenharmony_ci/* Copyright(c) 2018-2019 Realtek Corporation 362306a36Sopenharmony_ci */ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/debugfs.h> 662306a36Sopenharmony_ci#include <linux/seq_file.h> 762306a36Sopenharmony_ci#include "main.h" 862306a36Sopenharmony_ci#include "coex.h" 962306a36Sopenharmony_ci#include "sec.h" 1062306a36Sopenharmony_ci#include "fw.h" 1162306a36Sopenharmony_ci#include "debug.h" 1262306a36Sopenharmony_ci#include "phy.h" 1362306a36Sopenharmony_ci#include "reg.h" 1462306a36Sopenharmony_ci#include "ps.h" 1562306a36Sopenharmony_ci#include "regd.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#ifdef CONFIG_RTW88_DEBUGFS 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistruct rtw_debugfs_priv { 2062306a36Sopenharmony_ci struct rtw_dev *rtwdev; 2162306a36Sopenharmony_ci int (*cb_read)(struct seq_file *m, void *v); 2262306a36Sopenharmony_ci ssize_t (*cb_write)(struct file *filp, const char __user *buffer, 2362306a36Sopenharmony_ci size_t count, loff_t *loff); 2462306a36Sopenharmony_ci union { 2562306a36Sopenharmony_ci u32 cb_data; 2662306a36Sopenharmony_ci u8 *buf; 2762306a36Sopenharmony_ci struct { 2862306a36Sopenharmony_ci u32 page_offset; 2962306a36Sopenharmony_ci u32 page_num; 3062306a36Sopenharmony_ci } rsvd_page; 3162306a36Sopenharmony_ci struct { 3262306a36Sopenharmony_ci u8 rf_path; 3362306a36Sopenharmony_ci u32 rf_addr; 3462306a36Sopenharmony_ci u32 rf_mask; 3562306a36Sopenharmony_ci }; 3662306a36Sopenharmony_ci struct { 3762306a36Sopenharmony_ci u32 addr; 3862306a36Sopenharmony_ci u32 len; 3962306a36Sopenharmony_ci } read_reg; 4062306a36Sopenharmony_ci struct { 4162306a36Sopenharmony_ci u8 bit; 4262306a36Sopenharmony_ci } dm_cap; 4362306a36Sopenharmony_ci }; 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic const char * const rtw_dm_cap_strs[] = { 4762306a36Sopenharmony_ci [RTW_DM_CAP_NA] = "NA", 4862306a36Sopenharmony_ci [RTW_DM_CAP_TXGAPK] = "TXGAPK", 4962306a36Sopenharmony_ci}; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic int rtw_debugfs_single_show(struct seq_file *m, void *v) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return debugfs_priv->cb_read(m, v); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic ssize_t rtw_debugfs_common_write(struct file *filp, 5962306a36Sopenharmony_ci const char __user *buffer, 6062306a36Sopenharmony_ci size_t count, loff_t *loff) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci return debugfs_priv->cb_write(filp, buffer, count, loff); 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistatic ssize_t rtw_debugfs_single_write(struct file *filp, 6862306a36Sopenharmony_ci const char __user *buffer, 6962306a36Sopenharmony_ci size_t count, loff_t *loff) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 7262306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci return debugfs_priv->cb_write(filp, buffer, count, loff); 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci return single_open(filp, rtw_debugfs_single_show, inode->i_private); 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic int rtw_debugfs_close(struct inode *inode, struct file *filp) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci return 0; 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic const struct file_operations file_ops_single_r = { 8862306a36Sopenharmony_ci .owner = THIS_MODULE, 8962306a36Sopenharmony_ci .open = rtw_debugfs_single_open_rw, 9062306a36Sopenharmony_ci .read = seq_read, 9162306a36Sopenharmony_ci .llseek = seq_lseek, 9262306a36Sopenharmony_ci .release = single_release, 9362306a36Sopenharmony_ci}; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic const struct file_operations file_ops_single_rw = { 9662306a36Sopenharmony_ci .owner = THIS_MODULE, 9762306a36Sopenharmony_ci .open = rtw_debugfs_single_open_rw, 9862306a36Sopenharmony_ci .release = single_release, 9962306a36Sopenharmony_ci .read = seq_read, 10062306a36Sopenharmony_ci .llseek = seq_lseek, 10162306a36Sopenharmony_ci .write = rtw_debugfs_single_write, 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic const struct file_operations file_ops_common_write = { 10562306a36Sopenharmony_ci .owner = THIS_MODULE, 10662306a36Sopenharmony_ci .write = rtw_debugfs_common_write, 10762306a36Sopenharmony_ci .open = simple_open, 10862306a36Sopenharmony_ci .release = rtw_debugfs_close, 10962306a36Sopenharmony_ci}; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic int rtw_debugfs_get_read_reg(struct seq_file *m, void *v) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 11462306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 11562306a36Sopenharmony_ci u32 val, len, addr; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci len = debugfs_priv->read_reg.len; 11862306a36Sopenharmony_ci addr = debugfs_priv->read_reg.addr; 11962306a36Sopenharmony_ci switch (len) { 12062306a36Sopenharmony_ci case 1: 12162306a36Sopenharmony_ci val = rtw_read8(rtwdev, addr); 12262306a36Sopenharmony_ci seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val); 12362306a36Sopenharmony_ci break; 12462306a36Sopenharmony_ci case 2: 12562306a36Sopenharmony_ci val = rtw_read16(rtwdev, addr); 12662306a36Sopenharmony_ci seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val); 12762306a36Sopenharmony_ci break; 12862306a36Sopenharmony_ci case 4: 12962306a36Sopenharmony_ci val = rtw_read32(rtwdev, addr); 13062306a36Sopenharmony_ci seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val); 13162306a36Sopenharmony_ci break; 13262306a36Sopenharmony_ci } 13362306a36Sopenharmony_ci return 0; 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic int rtw_debugfs_get_rf_read(struct seq_file *m, void *v) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 13962306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 14062306a36Sopenharmony_ci u32 val, addr, mask; 14162306a36Sopenharmony_ci u8 path; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci path = debugfs_priv->rf_path; 14462306a36Sopenharmony_ci addr = debugfs_priv->rf_addr; 14562306a36Sopenharmony_ci mask = debugfs_priv->rf_mask; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 14862306a36Sopenharmony_ci val = rtw_read_rf(rtwdev, path, addr, mask); 14962306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n", 15262306a36Sopenharmony_ci path, addr, mask, val); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci return 0; 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_cistatic int rtw_debugfs_get_fix_rate(struct seq_file *m, void *v) 15862306a36Sopenharmony_ci{ 15962306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 16062306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 16162306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 16262306a36Sopenharmony_ci u8 fix_rate = dm_info->fix_rate; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci if (fix_rate >= DESC_RATE_MAX) { 16562306a36Sopenharmony_ci seq_printf(m, "Fix rate disabled, fix_rate = %u\n", fix_rate); 16662306a36Sopenharmony_ci return 0; 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci seq_printf(m, "Data frames fixed at desc rate %u\n", fix_rate); 17062306a36Sopenharmony_ci return 0; 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic int rtw_debugfs_copy_from_user(char tmp[], int size, 17462306a36Sopenharmony_ci const char __user *buffer, size_t count, 17562306a36Sopenharmony_ci int num) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci int tmp_len; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci memset(tmp, 0, size); 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci if (count < num) 18262306a36Sopenharmony_ci return -EFAULT; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci tmp_len = (count > size - 1 ? size - 1 : count); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci if (copy_from_user(tmp, buffer, tmp_len)) 18762306a36Sopenharmony_ci return -EFAULT; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci tmp[tmp_len] = '\0'; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci return 0; 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_read_reg(struct file *filp, 19562306a36Sopenharmony_ci const char __user *buffer, 19662306a36Sopenharmony_ci size_t count, loff_t *loff) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 19962306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 20062306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 20162306a36Sopenharmony_ci char tmp[32 + 1]; 20262306a36Sopenharmony_ci u32 addr, len; 20362306a36Sopenharmony_ci int num; 20462306a36Sopenharmony_ci int ret; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 20762306a36Sopenharmony_ci if (ret) 20862306a36Sopenharmony_ci return ret; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci num = sscanf(tmp, "%x %x", &addr, &len); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci if (num != 2) 21362306a36Sopenharmony_ci return -EINVAL; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci if (len != 1 && len != 2 && len != 4) { 21662306a36Sopenharmony_ci rtw_warn(rtwdev, "read reg setting wrong len\n"); 21762306a36Sopenharmony_ci return -EINVAL; 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci debugfs_priv->read_reg.addr = addr; 22062306a36Sopenharmony_ci debugfs_priv->read_reg.len = len; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci return count; 22362306a36Sopenharmony_ci} 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistatic int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 22862306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 22962306a36Sopenharmony_ci u32 val, command; 23062306a36Sopenharmony_ci u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT; 23162306a36Sopenharmony_ci u32 read_cmd = RTW_SEC_CMD_POLLING; 23262306a36Sopenharmony_ci int i; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data); 23562306a36Sopenharmony_ci seq_puts(m, "0x0 0x1 0x2 0x3 "); 23662306a36Sopenharmony_ci seq_puts(m, "0x4 0x5\n"); 23762306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 23862306a36Sopenharmony_ci for (i = 0; i <= 5; i++) { 23962306a36Sopenharmony_ci command = read_cmd | (hw_key_idx + i); 24062306a36Sopenharmony_ci rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); 24162306a36Sopenharmony_ci val = rtw_read32(rtwdev, RTW_SEC_READ_REG); 24262306a36Sopenharmony_ci seq_printf(m, "%8.8x", val); 24362306a36Sopenharmony_ci if (i < 2) 24462306a36Sopenharmony_ci seq_puts(m, " "); 24562306a36Sopenharmony_ci } 24662306a36Sopenharmony_ci seq_puts(m, "\n"); 24762306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 24862306a36Sopenharmony_ci return 0; 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistatic int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v) 25262306a36Sopenharmony_ci{ 25362306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 25462306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 25562306a36Sopenharmony_ci u8 page_size = rtwdev->chip->page_size; 25662306a36Sopenharmony_ci u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; 25762306a36Sopenharmony_ci u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; 25862306a36Sopenharmony_ci u8 *buf; 25962306a36Sopenharmony_ci int i; 26062306a36Sopenharmony_ci int ret; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci buf = vzalloc(buf_size); 26362306a36Sopenharmony_ci if (!buf) 26462306a36Sopenharmony_ci return -ENOMEM; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RSVD_PAGE, offset, 26762306a36Sopenharmony_ci buf_size, (u32 *)buf); 26862306a36Sopenharmony_ci if (ret) { 26962306a36Sopenharmony_ci rtw_err(rtwdev, "failed to dump rsvd page\n"); 27062306a36Sopenharmony_ci vfree(buf); 27162306a36Sopenharmony_ci return ret; 27262306a36Sopenharmony_ci } 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci for (i = 0 ; i < buf_size ; i += 8) { 27562306a36Sopenharmony_ci if (i % page_size == 0) 27662306a36Sopenharmony_ci seq_printf(m, "PAGE %d\n", (i + offset) / page_size); 27762306a36Sopenharmony_ci seq_printf(m, "%8ph\n", buf + i); 27862306a36Sopenharmony_ci } 27962306a36Sopenharmony_ci vfree(buf); 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci return 0; 28262306a36Sopenharmony_ci} 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_rsvd_page(struct file *filp, 28562306a36Sopenharmony_ci const char __user *buffer, 28662306a36Sopenharmony_ci size_t count, loff_t *loff) 28762306a36Sopenharmony_ci{ 28862306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 28962306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 29062306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 29162306a36Sopenharmony_ci char tmp[32 + 1]; 29262306a36Sopenharmony_ci u32 offset, page_num; 29362306a36Sopenharmony_ci int num; 29462306a36Sopenharmony_ci int ret; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); 29762306a36Sopenharmony_ci if (ret) 29862306a36Sopenharmony_ci return ret; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci num = sscanf(tmp, "%d %d", &offset, &page_num); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci if (num != 2) { 30362306a36Sopenharmony_ci rtw_warn(rtwdev, "invalid arguments\n"); 30462306a36Sopenharmony_ci return -EINVAL; 30562306a36Sopenharmony_ci } 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci debugfs_priv->rsvd_page.page_offset = offset; 30862306a36Sopenharmony_ci debugfs_priv->rsvd_page.page_num = page_num; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci return count; 31162306a36Sopenharmony_ci} 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_single_input(struct file *filp, 31462306a36Sopenharmony_ci const char __user *buffer, 31562306a36Sopenharmony_ci size_t count, loff_t *loff) 31662306a36Sopenharmony_ci{ 31762306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 31862306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 31962306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 32062306a36Sopenharmony_ci char tmp[32 + 1]; 32162306a36Sopenharmony_ci u32 input; 32262306a36Sopenharmony_ci int num; 32362306a36Sopenharmony_ci int ret; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 32662306a36Sopenharmony_ci if (ret) 32762306a36Sopenharmony_ci return ret; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci num = kstrtoint(tmp, 0, &input); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci if (num) { 33262306a36Sopenharmony_ci rtw_warn(rtwdev, "kstrtoint failed\n"); 33362306a36Sopenharmony_ci return num; 33462306a36Sopenharmony_ci } 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci debugfs_priv->cb_data = input; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci return count; 33962306a36Sopenharmony_ci} 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_write_reg(struct file *filp, 34262306a36Sopenharmony_ci const char __user *buffer, 34362306a36Sopenharmony_ci size_t count, loff_t *loff) 34462306a36Sopenharmony_ci{ 34562306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 34662306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 34762306a36Sopenharmony_ci char tmp[32 + 1]; 34862306a36Sopenharmony_ci u32 addr, val, len; 34962306a36Sopenharmony_ci int num; 35062306a36Sopenharmony_ci int ret; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 35362306a36Sopenharmony_ci if (ret) 35462306a36Sopenharmony_ci return ret; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci /* write BB/MAC register */ 35762306a36Sopenharmony_ci num = sscanf(tmp, "%x %x %x", &addr, &val, &len); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci if (num != 3) 36062306a36Sopenharmony_ci return -EINVAL; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci switch (len) { 36362306a36Sopenharmony_ci case 1: 36462306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 36562306a36Sopenharmony_ci "reg write8 0x%03x: 0x%08x\n", addr, val); 36662306a36Sopenharmony_ci rtw_write8(rtwdev, addr, (u8)val); 36762306a36Sopenharmony_ci break; 36862306a36Sopenharmony_ci case 2: 36962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 37062306a36Sopenharmony_ci "reg write16 0x%03x: 0x%08x\n", addr, val); 37162306a36Sopenharmony_ci rtw_write16(rtwdev, addr, (u16)val); 37262306a36Sopenharmony_ci break; 37362306a36Sopenharmony_ci case 4: 37462306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 37562306a36Sopenharmony_ci "reg write32 0x%03x: 0x%08x\n", addr, val); 37662306a36Sopenharmony_ci rtw_write32(rtwdev, addr, (u32)val); 37762306a36Sopenharmony_ci break; 37862306a36Sopenharmony_ci default: 37962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 38062306a36Sopenharmony_ci "error write length = %d\n", len); 38162306a36Sopenharmony_ci break; 38262306a36Sopenharmony_ci } 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci return count; 38562306a36Sopenharmony_ci} 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_h2c(struct file *filp, 38862306a36Sopenharmony_ci const char __user *buffer, 38962306a36Sopenharmony_ci size_t count, loff_t *loff) 39062306a36Sopenharmony_ci{ 39162306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 39262306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 39362306a36Sopenharmony_ci char tmp[32 + 1]; 39462306a36Sopenharmony_ci u8 param[8]; 39562306a36Sopenharmony_ci int num; 39662306a36Sopenharmony_ci int ret; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 39962306a36Sopenharmony_ci if (ret) 40062306a36Sopenharmony_ci return ret; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", 40362306a36Sopenharmony_ci ¶m[0], ¶m[1], ¶m[2], ¶m[3], 40462306a36Sopenharmony_ci ¶m[4], ¶m[5], ¶m[6], ¶m[7]); 40562306a36Sopenharmony_ci if (num != 8) { 40662306a36Sopenharmony_ci rtw_warn(rtwdev, "invalid H2C command format for debug\n"); 40762306a36Sopenharmony_ci return -EINVAL; 40862306a36Sopenharmony_ci } 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 41162306a36Sopenharmony_ci rtw_fw_h2c_cmd_dbg(rtwdev, param); 41262306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci return count; 41562306a36Sopenharmony_ci} 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_rf_write(struct file *filp, 41862306a36Sopenharmony_ci const char __user *buffer, 41962306a36Sopenharmony_ci size_t count, loff_t *loff) 42062306a36Sopenharmony_ci{ 42162306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = filp->private_data; 42262306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 42362306a36Sopenharmony_ci char tmp[32 + 1]; 42462306a36Sopenharmony_ci u32 path, addr, mask, val; 42562306a36Sopenharmony_ci int num; 42662306a36Sopenharmony_ci int ret; 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); 42962306a36Sopenharmony_ci if (ret) 43062306a36Sopenharmony_ci return ret; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci if (num != 4) { 43562306a36Sopenharmony_ci rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 43662306a36Sopenharmony_ci return -EINVAL; 43762306a36Sopenharmony_ci } 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 44062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, addr, mask, val); 44162306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 44262306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, 44362306a36Sopenharmony_ci "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", 44462306a36Sopenharmony_ci path, addr, mask, val); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci return count; 44762306a36Sopenharmony_ci} 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_rf_read(struct file *filp, 45062306a36Sopenharmony_ci const char __user *buffer, 45162306a36Sopenharmony_ci size_t count, loff_t *loff) 45262306a36Sopenharmony_ci{ 45362306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 45462306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 45562306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 45662306a36Sopenharmony_ci char tmp[32 + 1]; 45762306a36Sopenharmony_ci u32 path, addr, mask; 45862306a36Sopenharmony_ci int num; 45962306a36Sopenharmony_ci int ret; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); 46262306a36Sopenharmony_ci if (ret) 46362306a36Sopenharmony_ci return ret; 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci if (num != 3) { 46862306a36Sopenharmony_ci rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); 46962306a36Sopenharmony_ci return -EINVAL; 47062306a36Sopenharmony_ci } 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci debugfs_priv->rf_path = path; 47362306a36Sopenharmony_ci debugfs_priv->rf_addr = addr; 47462306a36Sopenharmony_ci debugfs_priv->rf_mask = mask; 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci return count; 47762306a36Sopenharmony_ci} 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_fix_rate(struct file *filp, 48062306a36Sopenharmony_ci const char __user *buffer, 48162306a36Sopenharmony_ci size_t count, loff_t *loff) 48262306a36Sopenharmony_ci{ 48362306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 48462306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 48562306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 48662306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 48762306a36Sopenharmony_ci u8 fix_rate; 48862306a36Sopenharmony_ci char tmp[32 + 1]; 48962306a36Sopenharmony_ci int ret; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 49262306a36Sopenharmony_ci if (ret) 49362306a36Sopenharmony_ci return ret; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci ret = kstrtou8(tmp, 0, &fix_rate); 49662306a36Sopenharmony_ci if (ret) { 49762306a36Sopenharmony_ci rtw_warn(rtwdev, "invalid args, [rate]\n"); 49862306a36Sopenharmony_ci return ret; 49962306a36Sopenharmony_ci } 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci dm_info->fix_rate = fix_rate; 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci return count; 50462306a36Sopenharmony_ci} 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistatic int rtw_debug_get_mac_page(struct seq_file *m, void *v) 50762306a36Sopenharmony_ci{ 50862306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 50962306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 51062306a36Sopenharmony_ci u32 page = debugfs_priv->cb_data; 51162306a36Sopenharmony_ci int i, n; 51262306a36Sopenharmony_ci int max = 0xff; 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci rtw_read32(rtwdev, debugfs_priv->cb_data); 51562306a36Sopenharmony_ci for (n = 0; n <= max; ) { 51662306a36Sopenharmony_ci seq_printf(m, "\n%8.8x ", n + page); 51762306a36Sopenharmony_ci for (i = 0; i < 4 && n <= max; i++, n += 4) 51862306a36Sopenharmony_ci seq_printf(m, "%8.8x ", 51962306a36Sopenharmony_ci rtw_read32(rtwdev, (page | n))); 52062306a36Sopenharmony_ci } 52162306a36Sopenharmony_ci seq_puts(m, "\n"); 52262306a36Sopenharmony_ci return 0; 52362306a36Sopenharmony_ci} 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_cistatic int rtw_debug_get_bb_page(struct seq_file *m, void *v) 52662306a36Sopenharmony_ci{ 52762306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 52862306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 52962306a36Sopenharmony_ci u32 page = debugfs_priv->cb_data; 53062306a36Sopenharmony_ci int i, n; 53162306a36Sopenharmony_ci int max = 0xff; 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci rtw_read32(rtwdev, debugfs_priv->cb_data); 53462306a36Sopenharmony_ci for (n = 0; n <= max; ) { 53562306a36Sopenharmony_ci seq_printf(m, "\n%8.8x ", n + page); 53662306a36Sopenharmony_ci for (i = 0; i < 4 && n <= max; i++, n += 4) 53762306a36Sopenharmony_ci seq_printf(m, "%8.8x ", 53862306a36Sopenharmony_ci rtw_read32(rtwdev, (page | n))); 53962306a36Sopenharmony_ci } 54062306a36Sopenharmony_ci seq_puts(m, "\n"); 54162306a36Sopenharmony_ci return 0; 54262306a36Sopenharmony_ci} 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_cistatic int rtw_debug_get_rf_dump(struct seq_file *m, void *v) 54562306a36Sopenharmony_ci{ 54662306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 54762306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 54862306a36Sopenharmony_ci u32 addr, offset, data; 54962306a36Sopenharmony_ci u8 path; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 55462306a36Sopenharmony_ci seq_printf(m, "RF path:%d\n", path); 55562306a36Sopenharmony_ci for (addr = 0; addr < 0x100; addr += 4) { 55662306a36Sopenharmony_ci seq_printf(m, "%8.8x ", addr); 55762306a36Sopenharmony_ci for (offset = 0; offset < 4; offset++) { 55862306a36Sopenharmony_ci data = rtw_read_rf(rtwdev, path, addr + offset, 55962306a36Sopenharmony_ci 0xffffffff); 56062306a36Sopenharmony_ci seq_printf(m, "%8.8x ", data); 56162306a36Sopenharmony_ci } 56262306a36Sopenharmony_ci seq_puts(m, "\n"); 56362306a36Sopenharmony_ci } 56462306a36Sopenharmony_ci seq_puts(m, "\n"); 56562306a36Sopenharmony_ci } 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci return 0; 57062306a36Sopenharmony_ci} 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_cistatic void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate) 57362306a36Sopenharmony_ci{ 57462306a36Sopenharmony_ci static const char * const 57562306a36Sopenharmony_ci cck_rate[] = {"1M", "2M", "5.5M", "11M"}; 57662306a36Sopenharmony_ci u8 idx = rate - DESC_RATE1M; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci seq_printf(m, " CCK_%-5s", cck_rate[idx]); 57962306a36Sopenharmony_ci} 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_cistatic void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci static const char * const 58462306a36Sopenharmony_ci ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"}; 58562306a36Sopenharmony_ci u8 idx = rate - DESC_RATE6M; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]); 58862306a36Sopenharmony_ci} 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_cistatic void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate) 59162306a36Sopenharmony_ci{ 59262306a36Sopenharmony_ci u8 mcs_n = rate - DESC_RATEMCS0; 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci seq_printf(m, " MCS%-6u", mcs_n); 59562306a36Sopenharmony_ci} 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_cistatic void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate) 59862306a36Sopenharmony_ci{ 59962306a36Sopenharmony_ci u8 idx = rate - DESC_RATEVHT1SS_MCS0; 60062306a36Sopenharmony_ci u8 n_ss, mcs_n; 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci /* n spatial stream */ 60362306a36Sopenharmony_ci n_ss = 1 + idx / 10; 60462306a36Sopenharmony_ci /* MCS n */ 60562306a36Sopenharmony_ci mcs_n = idx % 10; 60662306a36Sopenharmony_ci seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); 60762306a36Sopenharmony_ci} 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_cistatic void rtw_print_rate(struct seq_file *m, u8 rate) 61062306a36Sopenharmony_ci{ 61162306a36Sopenharmony_ci switch (rate) { 61262306a36Sopenharmony_ci case DESC_RATE1M...DESC_RATE11M: 61362306a36Sopenharmony_ci rtw_print_cck_rate_txt(m, rate); 61462306a36Sopenharmony_ci break; 61562306a36Sopenharmony_ci case DESC_RATE6M...DESC_RATE54M: 61662306a36Sopenharmony_ci rtw_print_ofdm_rate_txt(m, rate); 61762306a36Sopenharmony_ci break; 61862306a36Sopenharmony_ci case DESC_RATEMCS0...DESC_RATEMCS15: 61962306a36Sopenharmony_ci rtw_print_ht_rate_txt(m, rate); 62062306a36Sopenharmony_ci break; 62162306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: 62262306a36Sopenharmony_ci rtw_print_vht_rate_txt(m, rate); 62362306a36Sopenharmony_ci break; 62462306a36Sopenharmony_ci default: 62562306a36Sopenharmony_ci seq_printf(m, " Unknown rate=0x%x\n", rate); 62662306a36Sopenharmony_ci break; 62762306a36Sopenharmony_ci } 62862306a36Sopenharmony_ci} 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci#define case_REGD(src) \ 63162306a36Sopenharmony_ci case RTW_REGD_##src: return #src 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_cistatic const char *rtw_get_regd_string(u8 regd) 63462306a36Sopenharmony_ci{ 63562306a36Sopenharmony_ci switch (regd) { 63662306a36Sopenharmony_ci case_REGD(FCC); 63762306a36Sopenharmony_ci case_REGD(MKK); 63862306a36Sopenharmony_ci case_REGD(ETSI); 63962306a36Sopenharmony_ci case_REGD(IC); 64062306a36Sopenharmony_ci case_REGD(KCC); 64162306a36Sopenharmony_ci case_REGD(ACMA); 64262306a36Sopenharmony_ci case_REGD(CHILE); 64362306a36Sopenharmony_ci case_REGD(UKRAINE); 64462306a36Sopenharmony_ci case_REGD(MEXICO); 64562306a36Sopenharmony_ci case_REGD(CN); 64662306a36Sopenharmony_ci case_REGD(WW); 64762306a36Sopenharmony_ci default: 64862306a36Sopenharmony_ci return "Unknown"; 64962306a36Sopenharmony_ci } 65062306a36Sopenharmony_ci} 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_cistatic int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) 65362306a36Sopenharmony_ci{ 65462306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 65562306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 65662306a36Sopenharmony_ci struct rtw_hal *hal = &rtwdev->hal; 65762306a36Sopenharmony_ci u8 path, rate, bw, ch, regd; 65862306a36Sopenharmony_ci struct rtw_power_params pwr_param = {0}; 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 66162306a36Sopenharmony_ci bw = hal->current_band_width; 66262306a36Sopenharmony_ci ch = hal->current_channel; 66362306a36Sopenharmony_ci regd = rtw_regd_get(rtwdev); 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci seq_printf(m, "channel: %u\n", ch); 66662306a36Sopenharmony_ci seq_printf(m, "bandwidth: %u\n", bw); 66762306a36Sopenharmony_ci seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd)); 66862306a36Sopenharmony_ci seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n", 66962306a36Sopenharmony_ci "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem"); 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci mutex_lock(&hal->tx_power_mutex); 67262306a36Sopenharmony_ci for (path = RF_PATH_A; path <= RF_PATH_B; path++) { 67362306a36Sopenharmony_ci /* there is no CCK rates used in 5G */ 67462306a36Sopenharmony_ci if (hal->current_band_type == RTW_BAND_5G) 67562306a36Sopenharmony_ci rate = DESC_RATE6M; 67662306a36Sopenharmony_ci else 67762306a36Sopenharmony_ci rate = DESC_RATE1M; 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci /* now, not support vht 3ss and vht 4ss*/ 68062306a36Sopenharmony_ci for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) { 68162306a36Sopenharmony_ci /* now, not support ht 3ss and ht 4ss*/ 68262306a36Sopenharmony_ci if (rate > DESC_RATEMCS15 && 68362306a36Sopenharmony_ci rate < DESC_RATEVHT1SS_MCS0) 68462306a36Sopenharmony_ci continue; 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci rtw_get_tx_power_params(rtwdev, path, rate, bw, 68762306a36Sopenharmony_ci ch, regd, &pwr_param); 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci seq_printf(m, "%4c ", path + 'A'); 69062306a36Sopenharmony_ci rtw_print_rate(m, rate); 69162306a36Sopenharmony_ci seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d) %4d\n", 69262306a36Sopenharmony_ci hal->tx_pwr_tbl[path][rate], 69362306a36Sopenharmony_ci hal->tx_pwr_tbl[path][rate], 69462306a36Sopenharmony_ci pwr_param.pwr_base, 69562306a36Sopenharmony_ci min3(pwr_param.pwr_offset, 69662306a36Sopenharmony_ci pwr_param.pwr_limit, 69762306a36Sopenharmony_ci pwr_param.pwr_sar), 69862306a36Sopenharmony_ci pwr_param.pwr_offset, pwr_param.pwr_limit, 69962306a36Sopenharmony_ci pwr_param.pwr_sar, 70062306a36Sopenharmony_ci pwr_param.pwr_remnant); 70162306a36Sopenharmony_ci } 70262306a36Sopenharmony_ci } 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_ci mutex_unlock(&hal->tx_power_mutex); 70562306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci return 0; 70862306a36Sopenharmony_ci} 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_civoid rtw_debugfs_get_simple_phy_info(struct seq_file *m) 71162306a36Sopenharmony_ci{ 71262306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 71362306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 71462306a36Sopenharmony_ci struct rtw_hal *hal = &rtwdev->hal; 71562306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 71662306a36Sopenharmony_ci struct rtw_traffic_stats *stats = &rtwdev->stats; 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci seq_printf(m, "%-40s = %ddBm/ %d\n", "RSSI/ STA Channel", 71962306a36Sopenharmony_ci dm_info->rssi[RF_PATH_A] - 100, hal->current_channel); 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 72262306a36Sopenharmony_ci stats->tx_throughput, stats->rx_throughput); 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci seq_puts(m, "[Tx Rate] = "); 72562306a36Sopenharmony_ci rtw_print_rate(m, dm_info->tx_rate); 72662306a36Sopenharmony_ci seq_printf(m, "(0x%x)\n", dm_info->tx_rate); 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci seq_puts(m, "[Rx Rate] = "); 72962306a36Sopenharmony_ci rtw_print_rate(m, dm_info->curr_rx_rate); 73062306a36Sopenharmony_ci seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 73162306a36Sopenharmony_ci} 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_cistatic int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) 73462306a36Sopenharmony_ci{ 73562306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 73662306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 73762306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 73862306a36Sopenharmony_ci struct rtw_traffic_stats *stats = &rtwdev->stats; 73962306a36Sopenharmony_ci struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; 74062306a36Sopenharmony_ci struct rtw_efuse *efuse = &rtwdev->efuse; 74162306a36Sopenharmony_ci struct ewma_evm *ewma_evm = dm_info->ewma_evm; 74262306a36Sopenharmony_ci struct ewma_snr *ewma_snr = dm_info->ewma_snr; 74362306a36Sopenharmony_ci u8 ss, rate_id; 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci seq_puts(m, "==========[Common Info]========\n"); 74662306a36Sopenharmony_ci seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); 74762306a36Sopenharmony_ci seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); 74862306a36Sopenharmony_ci seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); 74962306a36Sopenharmony_ci seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); 75062306a36Sopenharmony_ci seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", 75162306a36Sopenharmony_ci stats->tx_throughput, stats->rx_throughput); 75262306a36Sopenharmony_ci seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ? 75362306a36Sopenharmony_ci 'Y' : 'N'); 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ci seq_puts(m, "==========[Tx Phy Info]========\n"); 75662306a36Sopenharmony_ci seq_puts(m, "[Tx Rate] = "); 75762306a36Sopenharmony_ci rtw_print_rate(m, dm_info->tx_rate); 75862306a36Sopenharmony_ci seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci seq_puts(m, "==========[Rx Phy Info]========\n"); 76162306a36Sopenharmony_ci seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); 76262306a36Sopenharmony_ci seq_puts(m, "[Rx Rate] = "); 76362306a36Sopenharmony_ci rtw_print_rate(m, dm_info->curr_rx_rate); 76462306a36Sopenharmony_ci seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci seq_puts(m, "[Rx Rate Count]:\n"); 76762306a36Sopenharmony_ci seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", 76862306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE1M], 76962306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE2M], 77062306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE5_5M], 77162306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE11M]); 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 77462306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE6M], 77562306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE9M], 77662306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE12M], 77762306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE18M], 77862306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE24M], 77962306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE36M], 78062306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE48M], 78162306a36Sopenharmony_ci last_cnt->num_qry_pkt[DESC_RATE54M]); 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_ci for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 78462306a36Sopenharmony_ci rate_id = DESC_RATEMCS0 + ss * 8; 78562306a36Sopenharmony_ci seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 78662306a36Sopenharmony_ci ss * 8, ss * 8 + 7, 78762306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id], 78862306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 1], 78962306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 2], 79062306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 3], 79162306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 4], 79262306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 5], 79362306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 6], 79462306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 7]); 79562306a36Sopenharmony_ci } 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 79862306a36Sopenharmony_ci rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; 79962306a36Sopenharmony_ci seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", 80062306a36Sopenharmony_ci ss + 1, 80162306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id], 80262306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 1], 80362306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 2], 80462306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 3], 80562306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 4], 80662306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 5], 80762306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 6], 80862306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 7], 80962306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 8], 81062306a36Sopenharmony_ci last_cnt->num_qry_pkt[rate_id + 9]); 81162306a36Sopenharmony_ci } 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", 81462306a36Sopenharmony_ci dm_info->rssi[RF_PATH_A] - 100, 81562306a36Sopenharmony_ci dm_info->rssi[RF_PATH_B] - 100); 81662306a36Sopenharmony_ci seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", 81762306a36Sopenharmony_ci dm_info->rx_evm_dbm[RF_PATH_A], 81862306a36Sopenharmony_ci dm_info->rx_evm_dbm[RF_PATH_B]); 81962306a36Sopenharmony_ci seq_printf(m, "[Rx SNR] = {%d, %d}\n", 82062306a36Sopenharmony_ci dm_info->rx_snr[RF_PATH_A], 82162306a36Sopenharmony_ci dm_info->rx_snr[RF_PATH_B]); 82262306a36Sopenharmony_ci seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", 82362306a36Sopenharmony_ci dm_info->cfo_tail[RF_PATH_A], 82462306a36Sopenharmony_ci dm_info->cfo_tail[RF_PATH_B]); 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci if (dm_info->curr_rx_rate >= DESC_RATE11M) { 82762306a36Sopenharmony_ci seq_puts(m, "[Rx Average Status]:\n"); 82862306a36Sopenharmony_ci seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", 82962306a36Sopenharmony_ci (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), 83062306a36Sopenharmony_ci (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); 83162306a36Sopenharmony_ci seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", 83262306a36Sopenharmony_ci (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), 83362306a36Sopenharmony_ci (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); 83462306a36Sopenharmony_ci seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", 83562306a36Sopenharmony_ci (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), 83662306a36Sopenharmony_ci (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), 83762306a36Sopenharmony_ci (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), 83862306a36Sopenharmony_ci (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); 83962306a36Sopenharmony_ci } 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci seq_puts(m, "[Rx Counter]:\n"); 84262306a36Sopenharmony_ci seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", 84362306a36Sopenharmony_ci dm_info->cck_cca_cnt, 84462306a36Sopenharmony_ci dm_info->ofdm_cca_cnt, 84562306a36Sopenharmony_ci dm_info->total_cca_cnt); 84662306a36Sopenharmony_ci seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", 84762306a36Sopenharmony_ci dm_info->cck_fa_cnt, 84862306a36Sopenharmony_ci dm_info->ofdm_fa_cnt, 84962306a36Sopenharmony_ci dm_info->total_fa_cnt); 85062306a36Sopenharmony_ci seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", 85162306a36Sopenharmony_ci dm_info->cck_ok_cnt, dm_info->cck_err_cnt); 85262306a36Sopenharmony_ci seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", 85362306a36Sopenharmony_ci dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); 85462306a36Sopenharmony_ci seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", 85562306a36Sopenharmony_ci dm_info->ht_ok_cnt, dm_info->ht_err_cnt); 85662306a36Sopenharmony_ci seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", 85762306a36Sopenharmony_ci dm_info->vht_ok_cnt, dm_info->vht_err_cnt); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci return 0; 86062306a36Sopenharmony_ci} 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_cistatic int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) 86362306a36Sopenharmony_ci{ 86462306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 86562306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 86862306a36Sopenharmony_ci rtw_coex_display_coex_info(rtwdev, m); 86962306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci return 0; 87262306a36Sopenharmony_ci} 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_coex_enable(struct file *filp, 87562306a36Sopenharmony_ci const char __user *buffer, 87662306a36Sopenharmony_ci size_t count, loff_t *loff) 87762306a36Sopenharmony_ci{ 87862306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 87962306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 88062306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 88162306a36Sopenharmony_ci struct rtw_coex *coex = &rtwdev->coex; 88262306a36Sopenharmony_ci char tmp[32 + 1]; 88362306a36Sopenharmony_ci bool enable; 88462306a36Sopenharmony_ci int ret; 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 88762306a36Sopenharmony_ci if (ret) 88862306a36Sopenharmony_ci return ret; 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci ret = kstrtobool(tmp, &enable); 89162306a36Sopenharmony_ci if (ret) { 89262306a36Sopenharmony_ci rtw_warn(rtwdev, "invalid arguments\n"); 89362306a36Sopenharmony_ci return ret; 89462306a36Sopenharmony_ci } 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 89762306a36Sopenharmony_ci coex->manual_control = !enable; 89862306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 89962306a36Sopenharmony_ci 90062306a36Sopenharmony_ci return count; 90162306a36Sopenharmony_ci} 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_cistatic int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) 90462306a36Sopenharmony_ci{ 90562306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 90662306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 90762306a36Sopenharmony_ci struct rtw_coex *coex = &rtwdev->coex; 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_ci seq_printf(m, "coex mechanism %s\n", 91062306a36Sopenharmony_ci coex->manual_control ? "disabled" : "enabled"); 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci return 0; 91362306a36Sopenharmony_ci} 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, 91662306a36Sopenharmony_ci const char __user *buffer, 91762306a36Sopenharmony_ci size_t count, loff_t *loff) 91862306a36Sopenharmony_ci{ 91962306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 92062306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 92162306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 92262306a36Sopenharmony_ci bool input; 92362306a36Sopenharmony_ci int err; 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci err = kstrtobool_from_user(buffer, count, &input); 92662306a36Sopenharmony_ci if (err) 92762306a36Sopenharmony_ci return err; 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci rtw_edcca_enabled = input; 93062306a36Sopenharmony_ci rtw_phy_adaptivity_set_mode(rtwdev); 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ci return count; 93362306a36Sopenharmony_ci} 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_cistatic int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v) 93662306a36Sopenharmony_ci{ 93762306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 93862306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 93962306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci seq_printf(m, "EDCCA %s: EDCCA mode %d\n", 94262306a36Sopenharmony_ci rtw_edcca_enabled ? "enabled" : "disabled", 94362306a36Sopenharmony_ci dm_info->edcca_mode); 94462306a36Sopenharmony_ci return 0; 94562306a36Sopenharmony_ci} 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_fw_crash(struct file *filp, 94862306a36Sopenharmony_ci const char __user *buffer, 94962306a36Sopenharmony_ci size_t count, loff_t *loff) 95062306a36Sopenharmony_ci{ 95162306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 95262306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 95362306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 95462306a36Sopenharmony_ci char tmp[32 + 1]; 95562306a36Sopenharmony_ci bool input; 95662306a36Sopenharmony_ci int ret; 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); 95962306a36Sopenharmony_ci if (ret) 96062306a36Sopenharmony_ci return ret; 96162306a36Sopenharmony_ci 96262306a36Sopenharmony_ci ret = kstrtobool(tmp, &input); 96362306a36Sopenharmony_ci if (ret) 96462306a36Sopenharmony_ci return -EINVAL; 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_ci if (!input) 96762306a36Sopenharmony_ci return -EINVAL; 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci if (test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) 97062306a36Sopenharmony_ci return -EINPROGRESS; 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 97362306a36Sopenharmony_ci rtw_leave_lps_deep(rtwdev); 97462306a36Sopenharmony_ci set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags); 97562306a36Sopenharmony_ci rtw_write8(rtwdev, REG_HRCV_MSG, 1); 97662306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci return count; 97962306a36Sopenharmony_ci} 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_cistatic int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v) 98262306a36Sopenharmony_ci{ 98362306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 98462306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci seq_printf(m, "%d\n", 98762306a36Sopenharmony_ci test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) || 98862306a36Sopenharmony_ci test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)); 98962306a36Sopenharmony_ci return 0; 99062306a36Sopenharmony_ci} 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_force_lowest_basic_rate(struct file *filp, 99362306a36Sopenharmony_ci const char __user *buffer, 99462306a36Sopenharmony_ci size_t count, loff_t *loff) 99562306a36Sopenharmony_ci{ 99662306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 99762306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 99862306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 99962306a36Sopenharmony_ci bool input; 100062306a36Sopenharmony_ci int err; 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci err = kstrtobool_from_user(buffer, count, &input); 100362306a36Sopenharmony_ci if (err) 100462306a36Sopenharmony_ci return err; 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci if (input) 100762306a36Sopenharmony_ci set_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 100862306a36Sopenharmony_ci else 100962306a36Sopenharmony_ci clear_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags); 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci return count; 101262306a36Sopenharmony_ci} 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_cistatic int rtw_debugfs_get_force_lowest_basic_rate(struct seq_file *m, void *v) 101562306a36Sopenharmony_ci{ 101662306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 101762306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci seq_printf(m, "force lowest basic rate: %d\n", 102062306a36Sopenharmony_ci test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags)); 102162306a36Sopenharmony_ci 102262306a36Sopenharmony_ci return 0; 102362306a36Sopenharmony_ci} 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_cistatic ssize_t rtw_debugfs_set_dm_cap(struct file *filp, 102662306a36Sopenharmony_ci const char __user *buffer, 102762306a36Sopenharmony_ci size_t count, loff_t *loff) 102862306a36Sopenharmony_ci{ 102962306a36Sopenharmony_ci struct seq_file *seqpriv = (struct seq_file *)filp->private_data; 103062306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; 103162306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 103262306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 103362306a36Sopenharmony_ci int bit; 103462306a36Sopenharmony_ci bool en; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci if (kstrtoint_from_user(buffer, count, 10, &bit)) 103762306a36Sopenharmony_ci return -EINVAL; 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_ci en = bit > 0; 104062306a36Sopenharmony_ci bit = abs(bit); 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ci if (bit >= RTW_DM_CAP_NUM) { 104362306a36Sopenharmony_ci rtw_warn(rtwdev, "unknown DM CAP %d\n", bit); 104462306a36Sopenharmony_ci return -EINVAL; 104562306a36Sopenharmony_ci } 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci if (en) 104862306a36Sopenharmony_ci dm_info->dm_flags &= ~BIT(bit); 104962306a36Sopenharmony_ci else 105062306a36Sopenharmony_ci dm_info->dm_flags |= BIT(bit); 105162306a36Sopenharmony_ci 105262306a36Sopenharmony_ci debugfs_priv->dm_cap.bit = bit; 105362306a36Sopenharmony_ci 105462306a36Sopenharmony_ci return count; 105562306a36Sopenharmony_ci} 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_cistatic void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) 105862306a36Sopenharmony_ci{ 105962306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 106062306a36Sopenharmony_ci struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 106162306a36Sopenharmony_ci int i, path; 106262306a36Sopenharmony_ci u32 val; 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK, 106562306a36Sopenharmony_ci dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', 106662306a36Sopenharmony_ci rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); 106762306a36Sopenharmony_ci 106862306a36Sopenharmony_ci mutex_lock(&rtwdev->mutex); 106962306a36Sopenharmony_ci 107062306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 107162306a36Sopenharmony_ci val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); 107262306a36Sopenharmony_ci seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_ci for (i = 0; i < RF_HW_OFFSET_NUM; i++) 107562306a36Sopenharmony_ci seq_printf(m, "[TXGAPK] offset %d %d\n", 107662306a36Sopenharmony_ci txgapk->rf3f_fs[path][i], i); 107762306a36Sopenharmony_ci seq_puts(m, "\n"); 107862306a36Sopenharmony_ci } 107962306a36Sopenharmony_ci mutex_unlock(&rtwdev->mutex); 108062306a36Sopenharmony_ci} 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_cistatic int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) 108362306a36Sopenharmony_ci{ 108462306a36Sopenharmony_ci struct rtw_debugfs_priv *debugfs_priv = m->private; 108562306a36Sopenharmony_ci struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 108662306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 108762306a36Sopenharmony_ci int i; 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_ci switch (debugfs_priv->dm_cap.bit) { 109062306a36Sopenharmony_ci case RTW_DM_CAP_TXGAPK: 109162306a36Sopenharmony_ci dump_gapk_status(rtwdev, m); 109262306a36Sopenharmony_ci break; 109362306a36Sopenharmony_ci default: 109462306a36Sopenharmony_ci for (i = 1; i < RTW_DM_CAP_NUM; i++) { 109562306a36Sopenharmony_ci seq_printf(m, "(%2d) %c%s\n", i, 109662306a36Sopenharmony_ci dm_info->dm_flags & BIT(i) ? '-' : '+', 109762306a36Sopenharmony_ci rtw_dm_cap_strs[i]); 109862306a36Sopenharmony_ci } 109962306a36Sopenharmony_ci break; 110062306a36Sopenharmony_ci } 110162306a36Sopenharmony_ci debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA; 110262306a36Sopenharmony_ci return 0; 110362306a36Sopenharmony_ci} 110462306a36Sopenharmony_ci 110562306a36Sopenharmony_ci#define rtw_debug_impl_mac(page, addr) \ 110662306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ 110762306a36Sopenharmony_ci .cb_read = rtw_debug_get_mac_page, \ 110862306a36Sopenharmony_ci .cb_data = addr, \ 110962306a36Sopenharmony_ci} 111062306a36Sopenharmony_ci 111162306a36Sopenharmony_cirtw_debug_impl_mac(0, 0x0000); 111262306a36Sopenharmony_cirtw_debug_impl_mac(1, 0x0100); 111362306a36Sopenharmony_cirtw_debug_impl_mac(2, 0x0200); 111462306a36Sopenharmony_cirtw_debug_impl_mac(3, 0x0300); 111562306a36Sopenharmony_cirtw_debug_impl_mac(4, 0x0400); 111662306a36Sopenharmony_cirtw_debug_impl_mac(5, 0x0500); 111762306a36Sopenharmony_cirtw_debug_impl_mac(6, 0x0600); 111862306a36Sopenharmony_cirtw_debug_impl_mac(7, 0x0700); 111962306a36Sopenharmony_cirtw_debug_impl_mac(10, 0x1000); 112062306a36Sopenharmony_cirtw_debug_impl_mac(11, 0x1100); 112162306a36Sopenharmony_cirtw_debug_impl_mac(12, 0x1200); 112262306a36Sopenharmony_cirtw_debug_impl_mac(13, 0x1300); 112362306a36Sopenharmony_cirtw_debug_impl_mac(14, 0x1400); 112462306a36Sopenharmony_cirtw_debug_impl_mac(15, 0x1500); 112562306a36Sopenharmony_cirtw_debug_impl_mac(16, 0x1600); 112662306a36Sopenharmony_cirtw_debug_impl_mac(17, 0x1700); 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci#define rtw_debug_impl_bb(page, addr) \ 112962306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \ 113062306a36Sopenharmony_ci .cb_read = rtw_debug_get_bb_page, \ 113162306a36Sopenharmony_ci .cb_data = addr, \ 113262306a36Sopenharmony_ci} 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_cirtw_debug_impl_bb(8, 0x0800); 113562306a36Sopenharmony_cirtw_debug_impl_bb(9, 0x0900); 113662306a36Sopenharmony_cirtw_debug_impl_bb(a, 0x0a00); 113762306a36Sopenharmony_cirtw_debug_impl_bb(b, 0x0b00); 113862306a36Sopenharmony_cirtw_debug_impl_bb(c, 0x0c00); 113962306a36Sopenharmony_cirtw_debug_impl_bb(d, 0x0d00); 114062306a36Sopenharmony_cirtw_debug_impl_bb(e, 0x0e00); 114162306a36Sopenharmony_cirtw_debug_impl_bb(f, 0x0f00); 114262306a36Sopenharmony_cirtw_debug_impl_bb(18, 0x1800); 114362306a36Sopenharmony_cirtw_debug_impl_bb(19, 0x1900); 114462306a36Sopenharmony_cirtw_debug_impl_bb(1a, 0x1a00); 114562306a36Sopenharmony_cirtw_debug_impl_bb(1b, 0x1b00); 114662306a36Sopenharmony_cirtw_debug_impl_bb(1c, 0x1c00); 114762306a36Sopenharmony_cirtw_debug_impl_bb(1d, 0x1d00); 114862306a36Sopenharmony_cirtw_debug_impl_bb(1e, 0x1e00); 114962306a36Sopenharmony_cirtw_debug_impl_bb(1f, 0x1f00); 115062306a36Sopenharmony_cirtw_debug_impl_bb(2c, 0x2c00); 115162306a36Sopenharmony_cirtw_debug_impl_bb(2d, 0x2d00); 115262306a36Sopenharmony_cirtw_debug_impl_bb(40, 0x4000); 115362306a36Sopenharmony_cirtw_debug_impl_bb(41, 0x4100); 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_rf_dump = { 115662306a36Sopenharmony_ci .cb_read = rtw_debug_get_rf_dump, 115762306a36Sopenharmony_ci}; 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = { 116062306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_tx_pwr_tbl, 116162306a36Sopenharmony_ci}; 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_write_reg = { 116462306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_write_reg, 116562306a36Sopenharmony_ci}; 116662306a36Sopenharmony_ci 116762306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_h2c = { 116862306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_h2c, 116962306a36Sopenharmony_ci}; 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_rf_write = { 117262306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_rf_write, 117362306a36Sopenharmony_ci}; 117462306a36Sopenharmony_ci 117562306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_rf_read = { 117662306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_rf_read, 117762306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_rf_read, 117862306a36Sopenharmony_ci}; 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_read_reg = { 118162306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_read_reg, 118262306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_read_reg, 118362306a36Sopenharmony_ci}; 118462306a36Sopenharmony_ci 118562306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_fix_rate = { 118662306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_fix_rate, 118762306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_fix_rate, 118862306a36Sopenharmony_ci}; 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_dump_cam = { 119162306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_single_input, 119262306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_dump_cam, 119362306a36Sopenharmony_ci}; 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = { 119662306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_rsvd_page, 119762306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_rsvd_page, 119862306a36Sopenharmony_ci}; 119962306a36Sopenharmony_ci 120062306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_phy_info = { 120162306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_phy_info, 120262306a36Sopenharmony_ci}; 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { 120562306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_coex_enable, 120662306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_coex_enable, 120762306a36Sopenharmony_ci}; 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_coex_info = { 121062306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_coex_info, 121162306a36Sopenharmony_ci}; 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { 121462306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_edcca_enable, 121562306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_edcca_enable, 121662306a36Sopenharmony_ci}; 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { 121962306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_fw_crash, 122062306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_fw_crash, 122162306a36Sopenharmony_ci}; 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = { 122462306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_force_lowest_basic_rate, 122562306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_force_lowest_basic_rate, 122662306a36Sopenharmony_ci}; 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_cistatic struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { 122962306a36Sopenharmony_ci .cb_write = rtw_debugfs_set_dm_cap, 123062306a36Sopenharmony_ci .cb_read = rtw_debugfs_get_dm_cap, 123162306a36Sopenharmony_ci}; 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_ci#define rtw_debugfs_add_core(name, mode, fopname, parent) \ 123462306a36Sopenharmony_ci do { \ 123562306a36Sopenharmony_ci rtw_debug_priv_ ##name.rtwdev = rtwdev; \ 123662306a36Sopenharmony_ci if (IS_ERR(debugfs_create_file(#name, mode, \ 123762306a36Sopenharmony_ci parent, &rtw_debug_priv_ ##name,\ 123862306a36Sopenharmony_ci &file_ops_ ##fopname))) \ 123962306a36Sopenharmony_ci pr_debug("Unable to initialize debugfs:%s\n", \ 124062306a36Sopenharmony_ci #name); \ 124162306a36Sopenharmony_ci } while (0) 124262306a36Sopenharmony_ci 124362306a36Sopenharmony_ci#define rtw_debugfs_add_w(name) \ 124462306a36Sopenharmony_ci rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir) 124562306a36Sopenharmony_ci#define rtw_debugfs_add_rw(name) \ 124662306a36Sopenharmony_ci rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir) 124762306a36Sopenharmony_ci#define rtw_debugfs_add_r(name) \ 124862306a36Sopenharmony_ci rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_civoid rtw_debugfs_init(struct rtw_dev *rtwdev) 125162306a36Sopenharmony_ci{ 125262306a36Sopenharmony_ci struct dentry *debugfs_topdir; 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_ci debugfs_topdir = debugfs_create_dir("rtw88", 125562306a36Sopenharmony_ci rtwdev->hw->wiphy->debugfsdir); 125662306a36Sopenharmony_ci rtw_debugfs_add_w(write_reg); 125762306a36Sopenharmony_ci rtw_debugfs_add_rw(read_reg); 125862306a36Sopenharmony_ci rtw_debugfs_add_w(rf_write); 125962306a36Sopenharmony_ci rtw_debugfs_add_rw(rf_read); 126062306a36Sopenharmony_ci rtw_debugfs_add_rw(fix_rate); 126162306a36Sopenharmony_ci rtw_debugfs_add_rw(dump_cam); 126262306a36Sopenharmony_ci rtw_debugfs_add_rw(rsvd_page); 126362306a36Sopenharmony_ci rtw_debugfs_add_r(phy_info); 126462306a36Sopenharmony_ci rtw_debugfs_add_r(coex_info); 126562306a36Sopenharmony_ci rtw_debugfs_add_rw(coex_enable); 126662306a36Sopenharmony_ci rtw_debugfs_add_w(h2c); 126762306a36Sopenharmony_ci rtw_debugfs_add_r(mac_0); 126862306a36Sopenharmony_ci rtw_debugfs_add_r(mac_1); 126962306a36Sopenharmony_ci rtw_debugfs_add_r(mac_2); 127062306a36Sopenharmony_ci rtw_debugfs_add_r(mac_3); 127162306a36Sopenharmony_ci rtw_debugfs_add_r(mac_4); 127262306a36Sopenharmony_ci rtw_debugfs_add_r(mac_5); 127362306a36Sopenharmony_ci rtw_debugfs_add_r(mac_6); 127462306a36Sopenharmony_ci rtw_debugfs_add_r(mac_7); 127562306a36Sopenharmony_ci rtw_debugfs_add_r(bb_8); 127662306a36Sopenharmony_ci rtw_debugfs_add_r(bb_9); 127762306a36Sopenharmony_ci rtw_debugfs_add_r(bb_a); 127862306a36Sopenharmony_ci rtw_debugfs_add_r(bb_b); 127962306a36Sopenharmony_ci rtw_debugfs_add_r(bb_c); 128062306a36Sopenharmony_ci rtw_debugfs_add_r(bb_d); 128162306a36Sopenharmony_ci rtw_debugfs_add_r(bb_e); 128262306a36Sopenharmony_ci rtw_debugfs_add_r(bb_f); 128362306a36Sopenharmony_ci rtw_debugfs_add_r(mac_10); 128462306a36Sopenharmony_ci rtw_debugfs_add_r(mac_11); 128562306a36Sopenharmony_ci rtw_debugfs_add_r(mac_12); 128662306a36Sopenharmony_ci rtw_debugfs_add_r(mac_13); 128762306a36Sopenharmony_ci rtw_debugfs_add_r(mac_14); 128862306a36Sopenharmony_ci rtw_debugfs_add_r(mac_15); 128962306a36Sopenharmony_ci rtw_debugfs_add_r(mac_16); 129062306a36Sopenharmony_ci rtw_debugfs_add_r(mac_17); 129162306a36Sopenharmony_ci rtw_debugfs_add_r(bb_18); 129262306a36Sopenharmony_ci rtw_debugfs_add_r(bb_19); 129362306a36Sopenharmony_ci rtw_debugfs_add_r(bb_1a); 129462306a36Sopenharmony_ci rtw_debugfs_add_r(bb_1b); 129562306a36Sopenharmony_ci rtw_debugfs_add_r(bb_1c); 129662306a36Sopenharmony_ci rtw_debugfs_add_r(bb_1d); 129762306a36Sopenharmony_ci rtw_debugfs_add_r(bb_1e); 129862306a36Sopenharmony_ci rtw_debugfs_add_r(bb_1f); 129962306a36Sopenharmony_ci if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { 130062306a36Sopenharmony_ci rtw_debugfs_add_r(bb_2c); 130162306a36Sopenharmony_ci rtw_debugfs_add_r(bb_2d); 130262306a36Sopenharmony_ci rtw_debugfs_add_r(bb_40); 130362306a36Sopenharmony_ci rtw_debugfs_add_r(bb_41); 130462306a36Sopenharmony_ci } 130562306a36Sopenharmony_ci rtw_debugfs_add_r(rf_dump); 130662306a36Sopenharmony_ci rtw_debugfs_add_r(tx_pwr_tbl); 130762306a36Sopenharmony_ci rtw_debugfs_add_rw(edcca_enable); 130862306a36Sopenharmony_ci rtw_debugfs_add_rw(fw_crash); 130962306a36Sopenharmony_ci rtw_debugfs_add_rw(force_lowest_basic_rate); 131062306a36Sopenharmony_ci rtw_debugfs_add_rw(dm_cap); 131162306a36Sopenharmony_ci} 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_ci#endif /* CONFIG_RTW88_DEBUGFS */ 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_ci#ifdef CONFIG_RTW88_DEBUG 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_civoid __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, 131862306a36Sopenharmony_ci const char *fmt, ...) 131962306a36Sopenharmony_ci{ 132062306a36Sopenharmony_ci struct va_format vaf = { 132162306a36Sopenharmony_ci .fmt = fmt, 132262306a36Sopenharmony_ci }; 132362306a36Sopenharmony_ci va_list args; 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_ci va_start(args, fmt); 132662306a36Sopenharmony_ci vaf.va = &args; 132762306a36Sopenharmony_ci 132862306a36Sopenharmony_ci if (rtw_debug_mask & mask) 132962306a36Sopenharmony_ci dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci va_end(args); 133262306a36Sopenharmony_ci} 133362306a36Sopenharmony_ciEXPORT_SYMBOL(__rtw_dbg); 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci#endif /* CONFIG_RTW88_DEBUG */ 1336