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		     &param[0], &param[1], &param[2], &param[3],
40462306a36Sopenharmony_ci		     &param[4], &param[5], &param[6], &param[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