summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw88/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtw88/debug.c')
-rw-r--r--drivers/net/wireless/realtek/rtw88/debug.c134
1 files changed, 133 insertions, 1 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index 948cb79050ea..18ab472ea46c 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -10,6 +10,7 @@
#include "fw.h"
#include "debug.h"
#include "phy.h"
+#include "reg.h"
#ifdef CONFIG_RTW88_DEBUGFS
@@ -34,9 +35,17 @@ struct rtw_debugfs_priv {
u32 addr;
u32 len;
} read_reg;
+ struct {
+ u8 bit;
+ } dm_cap;
};
};
+static const char * const rtw_dm_cap_strs[] = {
+ [RTW_DM_CAP_NA] = "NA",
+ [RTW_DM_CAP_TXGAPK] = "TXGAPK",
+};
+
static int rtw_debugfs_single_show(struct seq_file *m, void *v)
{
struct rtw_debugfs_priv *debugfs_priv = m->private;
@@ -270,7 +279,7 @@ static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp,
if (num != 2) {
rtw_warn(rtwdev, "invalid arguments\n");
- return num;
+ return -EINVAL;
}
debugfs_priv->rsvd_page.page_offset = offset;
@@ -818,6 +827,117 @@ static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v)
return 0;
}
+static ssize_t rtw_debugfs_set_fw_crash(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *loff)
+{
+ struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
+ struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
+ struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+ char tmp[32 + 1];
+ bool input;
+ int ret;
+
+ rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1);
+
+ ret = kstrtobool(tmp, &input);
+ if (ret)
+ return -EINVAL;
+
+ if (!input)
+ return -EINVAL;
+
+ rtw_write8(rtwdev, REG_HRCV_MSG, 1);
+
+ return count;
+}
+
+static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v)
+{
+ struct rtw_debugfs_priv *debugfs_priv = m->private;
+ struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+
+ seq_printf(m, "%d\n", test_bit(RTW_FLAG_RESTARTING, rtwdev->flags));
+ return 0;
+}
+
+static ssize_t rtw_debugfs_set_dm_cap(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *loff)
+{
+ struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
+ struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
+ struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ int bit;
+ bool en;
+
+ if (kstrtoint_from_user(buffer, count, 10, &bit))
+ return -EINVAL;
+
+ en = bit > 0;
+ bit = abs(bit);
+
+ if (bit >= RTW_DM_CAP_NUM) {
+ rtw_warn(rtwdev, "unknown DM CAP %d\n", bit);
+ return -EINVAL;
+ }
+
+ if (en)
+ dm_info->dm_flags &= ~BIT(bit);
+ else
+ dm_info->dm_flags |= BIT(bit);
+
+ debugfs_priv->dm_cap.bit = bit;
+
+ return count;
+}
+
+static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk;
+ int i, path;
+ u32 val;
+
+ seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK,
+ dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+',
+ rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]);
+
+ for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
+ val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK);
+ seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val);
+
+ for (i = 0; i < RF_HW_OFFSET_NUM; i++)
+ seq_printf(m, "[TXGAPK] offset %d %d\n",
+ txgapk->rf3f_fs[path][i], i);
+ seq_puts(m, "\n");
+ }
+}
+
+static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v)
+{
+ struct rtw_debugfs_priv *debugfs_priv = m->private;
+ struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ int i;
+
+ switch (debugfs_priv->dm_cap.bit) {
+ case RTW_DM_CAP_TXGAPK:
+ dump_gapk_status(rtwdev, m);
+ break;
+ default:
+ for (i = 1; i < RTW_DM_CAP_NUM; i++) {
+ seq_printf(m, "(%2d) %c%s\n", i,
+ dm_info->dm_flags & BIT(i) ? '-' : '+',
+ rtw_dm_cap_strs[i]);
+ }
+ break;
+ }
+ debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA;
+ return 0;
+}
+
#define rtw_debug_impl_mac(page, addr) \
static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \
.cb_read = rtw_debug_get_mac_page, \
@@ -921,6 +1041,16 @@ static struct rtw_debugfs_priv rtw_debug_priv_coex_info = {
.cb_read = rtw_debugfs_get_coex_info,
};
+static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = {
+ .cb_write = rtw_debugfs_set_fw_crash,
+ .cb_read = rtw_debugfs_get_fw_crash,
+};
+
+static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
+ .cb_write = rtw_debugfs_set_dm_cap,
+ .cb_read = rtw_debugfs_get_dm_cap,
+};
+
#define rtw_debugfs_add_core(name, mode, fopname, parent) \
do { \
rtw_debug_priv_ ##name.rtwdev = rtwdev; \
@@ -994,6 +1124,8 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
}
rtw_debugfs_add_r(rf_dump);
rtw_debugfs_add_r(tx_pwr_tbl);
+ rtw_debugfs_add_rw(fw_crash);
+ rtw_debugfs_add_rw(dm_cap);
}
#endif /* CONFIG_RTW88_DEBUGFS */