// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#include <linux/vmalloc.h>
#include "coex.h"
#include "debug.h"
#include "fw.h"
#include "mac.h"
#include "pci.h"
#include "phy.h"
#include "ps.h"
#include "reg.h"
#include "sar.h"
#include "util.h"
#ifdef CONFIG_RTW89_DEBUGMSG
unsigned int rtw89_debug_mask;
EXPORT_SYMBOL(rtw89_debug_mask);
module_param_named(debug_mask, rtw89_debug_mask, uint, 0644);
MODULE_PARM_DESC(debug_mask,
"Debugging mask");
#endif
#ifdef CONFIG_RTW89_DEBUGFS
struct rtw89_debugfs_priv_opt {
bool rlock:1;
bool wlock:1;
size_t rsize;
};
struct rtw89_debugfs_priv {
struct rtw89_dev *rtwdev;
ssize_t (*cb_read)(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
char *buf, size_t bufsz);
ssize_t (*cb_write)(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
const char *buf, size_t count);
struct rtw89_debugfs_priv_opt opt;
union {
u32 cb_data;
struct {
u32 addr;
u32 len;
} read_reg;
struct {
u32 addr;
u32 mask;
u8 path;
} read_rf;
struct {
u8 ss_dbg:1;
u8 dle_dbg:1;
u8 dmac_dbg:1;
u8 cmac_dbg:1;
u8 dbg_port:1;
} dbgpkg_en;
struct {
u32 start;
u32 len;
u8 sel;
} mac_mem;
};
ssize_t rused;
char *rbuf;
};
struct rtw89_debugfs {
struct rtw89_debugfs_priv read_reg;
struct rtw89_debugfs_priv write_reg;
struct rtw89_debugfs_priv read_rf;
struct rtw89_debugfs_priv write_rf;
struct rtw89_debugfs_priv rf_reg_dump;
struct rtw89_debugfs_priv txpwr_table;
struct rtw89_debugfs_priv mac_reg_dump;
struct rtw89_debugfs_priv mac_mem_dump;
struct rtw89_debugfs_priv mac_dbg_port_dump;
struct rtw89_debugfs_priv send_h2c;
struct rtw89_debugfs_priv early_h2c;
struct rtw89_debugfs_priv fw_crash;
struct rtw89_debugfs_priv btc_info;
struct rtw89_debugfs_priv btc_manual;
struct rtw89_debugfs_priv fw_log_manual;
struct rtw89_debugfs_priv phy_info;
struct rtw89_debugfs_priv stations;
struct rtw89_debugfs_priv disable_dm;
struct rtw89_debugfs_priv mlo_mode;
};
struct rtw89_debugfs_iter_data {
char *buf;
size_t bufsz;
int written_sz;
};
static void rtw89_debugfs_iter_data_setup(
struct rtw89_debugfs_iter_data *iter_data,
char *buf, size_t bufsz)
{
iter_data->buf = buf;
iter_data->bufsz = bufsz;
iter_data->written_sz = 0;
}
static void rtw89_debugfs_iter_data_next(
struct rtw89_debugfs_iter_data *iter_data,
char *buf, size_t bufsz,
int written_sz)
{
iter_data->buf = buf;
iter_data->bufsz = bufsz;
iter_data->written_sz += written_sz;
}
static const u16 rtw89_rate_info_bw_to_mhz_map[] = {
[RATE_INFO_BW_20] = 20,
[RATE_INFO_BW_40] = 40,
[RATE_INFO_BW_80] = 80,
[RATE_INFO_BW_160] = 160,
[RATE_INFO_BW_320] = 320,
};
static u16 rtw89_rate_info_bw_to_mhz(
enum rate_info_bw bw)
{
if (bw < ARRAY_SIZE(rtw89_rate_info_bw_to_mhz_map))
return rtw89_rate_info_bw_to_mhz_map[bw];
return 0;
}
static ssize_t rtw89_debugfs_file_read_helper(
struct wiphy *wiphy,
struct file *file,
char *buf, size_t bufsz,
void *data)
{
struct rtw89_debugfs_priv *debugfs_priv = data;
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
ssize_t n;
n = debugfs_priv->cb_read(rtwdev, debugfs_priv, buf, bufsz);
rtw89_might_trailing_ellipsis(buf, bufsz, n);
return n;
}
static ssize_t rtw89_debugfs_file_read(
struct file *file,
char __user *userbuf,
size_t count, loff_t *ppos)
{
struct rtw89_debugfs_priv *debugfs_priv = file->private_data;
struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt;
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
size_t bufsz = opt->rsize ? opt->rsize : PAGE_SIZE;
char *buf;
ssize_t n;
if (!debugfs_priv->rbuf)
debugfs_priv->rbuf = devm_kzalloc(rtwdev->dev, bufsz, GFP_KERNEL);
buf = debugfs_priv->rbuf;
if (!buf)
return -ENOMEM;
if (*ppos) {
n = debugfs_priv->rused;
goto out;
}
if (opt->rlock) {
n = wiphy_locked_debugfs_read(rtwdev->hw->wiphy, file, buf, bufsz,
userbuf, count, ppos,
rtw89_debugfs_file_read_helper,
debugfs_priv);
debugfs_priv->rused = n;
return n;
}
n = rtw89_debugfs_file_read_helper(rtwdev->hw->wiphy, file, buf, bufsz,
debugfs_priv);
debugfs_priv->rused = n;
out:
return simple_read_from_buffer(userbuf, count, ppos, buf, n);
}
static ssize_t rtw89_debugfs_file_write_helper(
struct wiphy *wiphy,
struct file *file,
char *buf, size_t count,
void *data)
{
struct rtw89_debugfs_priv *debugfs_priv = data;
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count);
}
static ssize_t rtw89_debugfs_file_write(
struct file *file,
const char __user *userbuf,
size_t count, loff_t *loff)
{
struct rtw89_debugfs_priv *debugfs_priv = file->private_data;
struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt;
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
char *buf __free(kfree) = kmalloc(count + 1, GFP_KERNEL);
ssize_t n;
if (!buf)
return -ENOMEM;
if (opt->wlock) {
n = wiphy_locked_debugfs_write(rtwdev->hw->wiphy,
file, buf, count + 1,
userbuf, count,
rtw89_debugfs_file_write_helper,
debugfs_priv);
return n;
}
if (copy_from_user(buf, userbuf, count))
return -EFAULT;
buf[count] =
'\0';
return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count);
}
static const struct debugfs_short_fops file_ops_single_r = {
.read = rtw89_debugfs_file_read,
.llseek = generic_file_llseek,
};
static const struct debugfs_short_fops file_ops_common_rw = {
.read = rtw89_debugfs_file_read,
.write = rtw89_debugfs_file_write,
.llseek = generic_file_llseek,
};
static const struct debugfs_short_fops file_ops_single_w = {
.write = rtw89_debugfs_file_write,
.llseek = generic_file_llseek,
};
static ssize_t
rtw89_debug_priv_read_reg_select(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
const char *buf, size_t count)
{
u32 addr, len;
int num;
num = sscanf(buf,
"%x %x", &addr, &len);
if (num != 2) {
rtw89_info(rtwdev,
"invalid format: \n");
return -EINVAL;
}
debugfs_priv->read_reg.addr = addr;
debugfs_priv->read_reg.len = len;
rtw89_info(rtwdev,
"select read %d bytes from 0x%08x\n", len, addr);
return count;
}
static
ssize_t rtw89_debug_priv_read_reg_get(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
char *buf, size_t bufsz)
{
char *p = buf, *end = buf + bufsz;
u32 addr, addr_end, data, k;
u32 len;
len = debugfs_priv->read_reg.len;
addr = debugfs_priv->read_reg.addr;
if (len > 4)
goto ndata;
switch (len) {
case 1:
data = rtw89_read8(rtwdev, addr);
break;
case 2:
data = rtw89_read16(rtwdev, addr);
break;
case 4:
data = rtw89_read32(rtwdev, addr);
break;
default:
rtw89_info(rtwdev,
"invalid read reg len %d\n", len);
return -EINVAL;
}
p += scnprintf(p, end - p,
"get %d bytes at 0x%08x=0x%08x\n", len,
addr, data);
return p - buf;
ndata:
addr_end = addr + len;
for (; addr < addr_end; addr += 16) {
p += scnprintf(p, end - p,
"%08xh : ", 0x18600000 + addr);
for (k = 0; k < 16; k += 4) {
data = rtw89_read32(rtwdev, addr + k);
p += scnprintf(p, end - p,
"%08x ", data);
}
p += scnprintf(p, end - p,
"\n");
}
return p - buf;
}
static
ssize_t rtw89_debug_priv_write_reg_set(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
const char *buf, size_t count)
{
u32 addr, val, len;
int num;
num = sscanf(buf,
"%x %x %x", &addr, &val, &len);
if (num != 3) {
rtw89_info(rtwdev,
"invalid format: \n");
return -EINVAL;
}
switch (len) {
case 1:
rtw89_info(rtwdev,
"reg write8 0x%08x: 0x%02x\n", addr, val);
rtw89_write8(rtwdev, addr, (u8)val);
break;
case 2:
rtw89_info(rtwdev,
"reg write16 0x%08x: 0x%04x\n", addr, val);
rtw89_write16(rtwdev, addr, (u16)val);
break;
case 4:
rtw89_info(rtwdev,
"reg write32 0x%08x: 0x%08x\n", addr, val);
rtw89_write32(rtwdev, addr, (u32)val);
break;
default:
rtw89_info(rtwdev,
"invalid read write len %d\n", len);
break;
}
return count;
}
static ssize_t
rtw89_debug_priv_read_rf_select(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
const char *buf, size_t count)
{
u32 addr, mask;
u8 path;
int num;
num = sscanf(buf,
"%hhd %x %x", &path, &addr, &mask);
if (num != 3) {
rtw89_info(rtwdev,
"invalid format: \n");
return -EINVAL;
}
if (path >= rtwdev->chip->rf_path_num) {
rtw89_info(rtwdev,
"wrong rf path\n");
return -EINVAL;
}
debugfs_priv->read_rf.addr = addr;
debugfs_priv->read_rf.mask = mask;
debugfs_priv->read_rf.path = path;
rtw89_info(rtwdev,
"select read rf path %d from 0x%08x\n", path, addr);
return count;
}
static
ssize_t rtw89_debug_priv_read_rf_get(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
char *buf, size_t bufsz)
{
char *p = buf, *end = buf + bufsz;
u32 addr, data, mask;
u8 path;
addr = debugfs_priv->read_rf.addr;
mask = debugfs_priv->read_rf.mask;
path = debugfs_priv->read_rf.path;
data = rtw89_read_rf(rtwdev, path, addr, mask);
p += scnprintf(p, end - p,
"path %d, rf register 0x%08x=0x%08x\n",
path, addr, data);
return p - buf;
}
static
ssize_t rtw89_debug_priv_write_rf_set(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
const char *buf, size_t count)
{
u32 addr, val, mask;
u8 path;
int num;
num = sscanf(buf,
"%hhd %x %x %x", &path, &addr, &mask, &val);
if (num != 4) {
rtw89_info(rtwdev,
"invalid format: \n");
return -EINVAL;
}
if (path >= rtwdev->chip->rf_path_num) {
rtw89_info(rtwdev,
"wrong rf path\n");
return -EINVAL;
}
rtw89_info(rtwdev,
"path %d, rf register write 0x%08x=0x%08x (mask = 0x%08x)\n",
path, addr, val, mask);
rtw89_write_rf(rtwdev, path, addr, mask, val);
return count;
}
static
ssize_t rtw89_debug_priv_rf_reg_dump_get(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
char *buf, size_t bufsz)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
char *p = buf, *end = buf + bufsz;
u32 addr, offset, data;
u8 path;
for (path = 0; path < chip->rf_path_num; path++) {
p += scnprintf(p, end - p,
"RF path %d:\n\n", path);
for (addr = 0; addr < 0x100; addr += 4) {
p += scnprintf(p, end - p,
"0x%08x: ", addr);
for (offset = 0; offset < 4; offset++) {
data = rtw89_read_rf(rtwdev, path,
addr + offset, RFREG_MASK);
p += scnprintf(p, end - p,
"0x%05x ", data);
}
p += scnprintf(p, end - p,
"\n");
}
p += scnprintf(p, end - p,
"\n");
}
return p - buf;
}
struct txpwr_ent {
bool nested;
union {
const char *txt;
const struct txpwr_ent *ptr;
};
u8 len;
};
struct txpwr_map {
const struct txpwr_ent *ent;
u8 size;
u32 addr_from;
u32 addr_to;
u32 addr_to_1ss;
};
#define __GEN_TXPWR_ENT_NESTED(_e) \
{ .nested =
true, .ptr = __txpwr_ent_
##_e, \
.len = ARRAY_SIZE(__txpwr_ent_
##_e) }
#define __GEN_TXPWR_ENT0(_t) { .len = 0, .txt = _t }
#define __GEN_TXPWR_ENT2(_t, _e0, _e1) \
{ .len = 2, .txt = _t
"\t- " _e0
" " _e1 }
#define __GEN_TXPWR_ENT4(_t, _e0, _e1, _e2, _e3) \
{ .len = 4, .txt = _t
"\t- " _e0
" " _e1
" " _e2
" " _e3 }
#define __GEN_TXPWR_ENT8(_t, _e0, _e1, _e2, _e3, _e4, _e5, _e6, _e7) \
{ .len = 8, .txt = _t
"\t- " \
_e0
" " _e1
" " _e2
" " _e3
" " \
_e4
" " _e5
" " _e6
" " _e7 }
static const struct txpwr_ent __txpwr_ent_byr_ax[] = {
__GEN_TXPWR_ENT4(
"CCK ",
"1M ",
"2M ",
"5.5M ",
"11M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"6M ",
"9M ",
"12M ",
"18M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"24M ",
"36M ",
"48M ",
"54M "),
/* 1NSS */
__GEN_TXPWR_ENT4(
"MCS_1NSS ",
"MCS0 ",
"MCS1 ",
"MCS2 ",
"MCS3 "),
__GEN_TXPWR_ENT4(
"MCS_1NSS ",
"MCS4 ",
"MCS5 ",
"MCS6 ",
"MCS7 "),
__GEN_TXPWR_ENT4(
"MCS_1NSS ",
"MCS8 ",
"MCS9 ",
"MCS10",
"MCS11"),
__GEN_TXPWR_ENT4(
"HEDCM_1NSS",
"MCS0 ",
"MCS1 ",
"MCS3 ",
"MCS4 "),
/* 2NSS */
__GEN_TXPWR_ENT4(
"MCS_2NSS ",
"MCS0 ",
"MCS1 ",
"MCS2 ",
"MCS3 "),
__GEN_TXPWR_ENT4(
"MCS_2NSS ",
"MCS4 ",
"MCS5 ",
"MCS6 ",
"MCS7 "),
__GEN_TXPWR_ENT4(
"MCS_2NSS ",
"MCS8 ",
"MCS9 ",
"MCS10",
"MCS11"),
__GEN_TXPWR_ENT4(
"HEDCM_2NSS",
"MCS0 ",
"MCS1 ",
"MCS3 ",
"MCS4 "),
};
static_assert((ARRAY_SIZE(__txpwr_ent_byr_ax) * 4) ==
(R_AX_PWR_BY_RATE_MAX - R_AX_PWR_BY_RATE + 4));
static const struct txpwr_map __txpwr_map_byr_ax = {
.ent = __txpwr_ent_byr_ax,
.size = ARRAY_SIZE(__txpwr_ent_byr_ax),
.addr_from = R_AX_PWR_BY_RATE,
.addr_to = R_AX_PWR_BY_RATE_MAX,
.addr_to_1ss = R_AX_PWR_BY_RATE_1SS_MAX,
};
static const struct txpwr_ent __txpwr_ent_lmt_ax[] = {
/* 1TX */
__GEN_TXPWR_ENT2(
"CCK_1TX_20M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"CCK_1TX_40M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"OFDM_1TX ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_20M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_20M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_20M_2 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_20M_3 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_20M_4 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_20M_5 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_20M_6 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_20M_7 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_40M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_40M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_40M_2 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_40M_3 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_80M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_80M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_160M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_40M_0p5",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_1TX_40M_2p5",
"NON_BF",
"BF"),
/* 2TX */
__GEN_TXPWR_ENT2(
"CCK_2TX_20M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"CCK_2TX_40M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"OFDM_2TX ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_20M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_20M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_20M_2 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_20M_3 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_20M_4 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_20M_5 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_20M_6 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_20M_7 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_40M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_40M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_40M_2 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_40M_3 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_80M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_80M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_160M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_40M_0p5",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_2TX_40M_2p5",
"NON_BF",
"BF"),
};
static_assert((ARRAY_SIZE(__txpwr_ent_lmt_ax) * 2) ==
(R_AX_PWR_LMT_MAX - R_AX_PWR_LMT + 4));
static const struct txpwr_map __txpwr_map_lmt_ax = {
.ent = __txpwr_ent_lmt_ax,
.size = ARRAY_SIZE(__txpwr_ent_lmt_ax),
.addr_from = R_AX_PWR_LMT,
.addr_to = R_AX_PWR_LMT_MAX,
.addr_to_1ss = R_AX_PWR_LMT_1SS_MAX,
};
static const struct txpwr_ent __txpwr_ent_lmt_ru_ax[] = {
/* 1TX */
__GEN_TXPWR_ENT8(
"1TX",
"RU26__0",
"RU26__1",
"RU26__2",
"RU26__3",
"RU26__4",
"RU26__5",
"RU26__6",
"RU26__7"),
__GEN_TXPWR_ENT8(
"1TX",
"RU52__0",
"RU52__1",
"RU52__2",
"RU52__3",
"RU52__4",
"RU52__5",
"RU52__6",
"RU52__7"),
__GEN_TXPWR_ENT8(
"1TX",
"RU106_0",
"RU106_1",
"RU106_2",
"RU106_3",
"RU106_4",
"RU106_5",
"RU106_6",
"RU106_7"),
/* 2TX */
__GEN_TXPWR_ENT8(
"2TX",
"RU26__0",
"RU26__1",
"RU26__2",
"RU26__3",
"RU26__4",
"RU26__5",
"RU26__6",
"RU26__7"),
__GEN_TXPWR_ENT8(
"2TX",
"RU52__0",
"RU52__1",
"RU52__2",
"RU52__3",
"RU52__4",
"RU52__5",
"RU52__6",
"RU52__7"),
__GEN_TXPWR_ENT8(
"2TX",
"RU106_0",
"RU106_1",
"RU106_2",
"RU106_3",
"RU106_4",
"RU106_5",
"RU106_6",
"RU106_7"),
};
static_assert((ARRAY_SIZE(__txpwr_ent_lmt_ru_ax) * 8) ==
(R_AX_PWR_RU_LMT_MAX - R_AX_PWR_RU_LMT + 4));
static const struct txpwr_map __txpwr_map_lmt_ru_ax = {
.ent = __txpwr_ent_lmt_ru_ax,
.size = ARRAY_SIZE(__txpwr_ent_lmt_ru_ax),
.addr_from = R_AX_PWR_RU_LMT,
.addr_to = R_AX_PWR_RU_LMT_MAX,
.addr_to_1ss = R_AX_PWR_RU_LMT_1SS_MAX,
};
static const struct txpwr_ent __txpwr_ent_byr_mcs_be[] = {
__GEN_TXPWR_ENT4(
"MCS_1SS ",
"MCS0 ",
"MCS1 ",
"MCS2 ",
"MCS3 "),
__GEN_TXPWR_ENT4(
"MCS_1SS ",
"MCS4 ",
"MCS5 ",
"MCS6 ",
"MCS7 "),
__GEN_TXPWR_ENT4(
"MCS_1SS ",
"MCS8 ",
"MCS9 ",
"MCS10",
"MCS11"),
__GEN_TXPWR_ENT2(
"MCS_1SS ",
"MCS12 ",
"MCS13 \t"),
__GEN_TXPWR_ENT4(
"HEDCM_1SS ",
"MCS0 ",
"MCS1 ",
"MCS3 ",
"MCS4 "),
__GEN_TXPWR_ENT4(
"DLRU_MCS_1SS ",
"MCS0 ",
"MCS1 ",
"MCS2 ",
"MCS3 "),
__GEN_TXPWR_ENT4(
"DLRU_MCS_1SS ",
"MCS4 ",
"MCS5 ",
"MCS6 ",
"MCS7 "),
__GEN_TXPWR_ENT4(
"DLRU_MCS_1SS ",
"MCS8 ",
"MCS9 ",
"MCS10",
"MCS11"),
__GEN_TXPWR_ENT2(
"DLRU_MCS_1SS ",
"MCS12 ",
"MCS13 \t"),
__GEN_TXPWR_ENT4(
"DLRU_HEDCM_1SS",
"MCS0 ",
"MCS1 ",
"MCS3 ",
"MCS4 "),
__GEN_TXPWR_ENT4(
"MCS_2SS ",
"MCS0 ",
"MCS1 ",
"MCS2 ",
"MCS3 "),
__GEN_TXPWR_ENT4(
"MCS_2SS ",
"MCS4 ",
"MCS5 ",
"MCS6 ",
"MCS7 "),
__GEN_TXPWR_ENT4(
"MCS_2SS ",
"MCS8 ",
"MCS9 ",
"MCS10",
"MCS11"),
__GEN_TXPWR_ENT2(
"MCS_2SS ",
"MCS12 ",
"MCS13 \t"),
__GEN_TXPWR_ENT4(
"HEDCM_2SS ",
"MCS0 ",
"MCS1 ",
"MCS3 ",
"MCS4 "),
__GEN_TXPWR_ENT4(
"DLRU_MCS_2SS ",
"MCS0 ",
"MCS1 ",
"MCS2 ",
"MCS3 "),
__GEN_TXPWR_ENT4(
"DLRU_MCS_2SS ",
"MCS4 ",
"MCS5 ",
"MCS6 ",
"MCS7 "),
__GEN_TXPWR_ENT4(
"DLRU_MCS_2SS ",
"MCS8 ",
"MCS9 ",
"MCS10",
"MCS11"),
__GEN_TXPWR_ENT2(
"DLRU_MCS_2SS ",
"MCS12 ",
"MCS13 \t"),
__GEN_TXPWR_ENT4(
"DLRU_HEDCM_2SS",
"MCS0 ",
"MCS1 ",
"MCS3 ",
"MCS4 "),
};
static const struct txpwr_ent __txpwr_ent_byr_be[] = {
__GEN_TXPWR_ENT0(
"BW20"),
__GEN_TXPWR_ENT4(
"CCK ",
"1M ",
"2M ",
"5.5M ",
"11M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"6M ",
"9M ",
"12M ",
"18M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"24M ",
"36M ",
"48M ",
"54M "),
__GEN_TXPWR_ENT2(
"EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT2(
"DLRU_EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
__GEN_TXPWR_ENT0(
"BW40"),
__GEN_TXPWR_ENT4(
"CCK ",
"1M ",
"2M ",
"5.5M ",
"11M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"6M ",
"9M ",
"12M ",
"18M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"24M ",
"36M ",
"48M ",
"54M "),
__GEN_TXPWR_ENT2(
"EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT2(
"DLRU_EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
/* there is no CCK section after BW80 */
__GEN_TXPWR_ENT0(
"BW80"),
__GEN_TXPWR_ENT4(
"LEGACY ",
"6M ",
"9M ",
"12M ",
"18M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"24M ",
"36M ",
"48M ",
"54M "),
__GEN_TXPWR_ENT2(
"EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT2(
"DLRU_EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
__GEN_TXPWR_ENT0(
"BW160"),
__GEN_TXPWR_ENT4(
"LEGACY ",
"6M ",
"9M ",
"12M ",
"18M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"24M ",
"36M ",
"48M ",
"54M "),
__GEN_TXPWR_ENT2(
"EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT2(
"DLRU_EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
__GEN_TXPWR_ENT0(
"BW320"),
__GEN_TXPWR_ENT4(
"LEGACY ",
"6M ",
"9M ",
"12M ",
"18M "),
__GEN_TXPWR_ENT4(
"LEGACY ",
"24M ",
"36M ",
"48M ",
"54M "),
__GEN_TXPWR_ENT2(
"EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT2(
"DLRU_EHT ",
"MCS14 ",
"MCS15 \t"),
__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
};
static const struct txpwr_map __txpwr_map_byr_be = {
.ent = __txpwr_ent_byr_be,
.size = ARRAY_SIZE(__txpwr_ent_byr_be),
.addr_from = R_BE_PWR_BY_RATE,
.addr_to = R_BE_PWR_BY_RATE_MAX,
.addr_to_1ss = 0,
/* not support */
};
static const struct txpwr_ent __txpwr_ent_lmt_mcs_be[] = {
__GEN_TXPWR_ENT2(
"MCS_20M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_2 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_3 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_4 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_5 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_6 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_7 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_8 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_9 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_10 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_11 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_12 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_13 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_14 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_20M_15 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_2 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_3 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_4 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_5 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_6 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_7 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_80M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_80M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_80M_2 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_80M_3 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_160M_0 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_160M_1 ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_320M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_0p5",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_2p5",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_4p5",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"MCS_40M_6p5",
"NON_BF",
"BF"),
};
static const struct txpwr_ent __txpwr_ent_lmt_be[] = {
__GEN_TXPWR_ENT0(
"1TX"),
__GEN_TXPWR_ENT2(
"CCK_20M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"CCK_40M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"OFDM ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT_NESTED(lmt_mcs_be),
__GEN_TXPWR_ENT0(
"2TX"),
__GEN_TXPWR_ENT2(
"CCK_20M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"CCK_40M ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT2(
"OFDM ",
"NON_BF",
"BF"),
__GEN_TXPWR_ENT_NESTED(lmt_mcs_be),
};
static const struct txpwr_map __txpwr_map_lmt_be = {
.ent = __txpwr_ent_lmt_be,
.size = ARRAY_SIZE(__txpwr_ent_lmt_be),
.addr_from = R_BE_PWR_LMT,
.addr_to = R_BE_PWR_LMT_MAX,
.addr_to_1ss = 0,
/* not support */
};
static const struct txpwr_ent __txpwr_ent_lmt_ru_indexes_be[] = {
__GEN_TXPWR_ENT8(
"RU26 ",
"IDX_0 ",
"IDX_1 ",
"IDX_2 ",
"IDX_3 ",
"IDX_4 ",
"IDX_5 ",
"IDX_6 ",
"IDX_7 "),
__GEN_TXPWR_ENT8(
"RU26 ",
"IDX_8 ",
"IDX_9 ",
"IDX_10",
"IDX_11",
"IDX_12",
"IDX_13",
"IDX_14",
"IDX_15"),
__GEN_TXPWR_ENT8(
"RU52 ",
"IDX_0 ",
"IDX_1 ",
"IDX_2 ",
"IDX_3 ",
"IDX_4 ",
"IDX_5 ",
"IDX_6 ",
"IDX_7 "),
__GEN_TXPWR_ENT8(
"RU52 ",
"IDX_8 ",
"IDX_9 ",
"IDX_10",
"IDX_11",
"IDX_12",
"IDX_13",
"IDX_14",
"IDX_15"),
__GEN_TXPWR_ENT8(
"RU106 ",
"IDX_0 ",
"IDX_1 ",
"IDX_2 ",
"IDX_3 ",
"IDX_4 ",
"IDX_5 ",
"IDX_6 ",
"IDX_7 "),
__GEN_TXPWR_ENT8(
"RU106 ",
"IDX_8 ",
"IDX_9 ",
"IDX_10",
"IDX_11",
"IDX_12",
"IDX_13",
"IDX_14",
"IDX_15"),
__GEN_TXPWR_ENT8(
"RU52_26 ",
"IDX_0 ",
"IDX_1 ",
"IDX_2 ",
"IDX_3 ",
"IDX_4 ",
"IDX_5 ",
"IDX_6 ",
"IDX_7 "),
__GEN_TXPWR_ENT8(
"RU52_26 ",
"IDX_8 ",
"IDX_9 ",
"IDX_10",
"IDX_11",
"IDX_12",
"IDX_13",
"IDX_14",
"IDX_15"),
__GEN_TXPWR_ENT8(
"RU106_26",
"IDX_0 ",
"IDX_1 ",
"IDX_2 ",
"IDX_3 ",
"IDX_4 ",
"IDX_5 ",
"IDX_6 ",
"IDX_7 "),
__GEN_TXPWR_ENT8(
"RU106_26",
"IDX_8 ",
"IDX_9 ",
"IDX_10",
"IDX_11",
"IDX_12",
"IDX_13",
"IDX_14",
"IDX_15"),
};
static const struct txpwr_ent __txpwr_ent_lmt_ru_be[] = {
__GEN_TXPWR_ENT0(
"1TX"),
__GEN_TXPWR_ENT_NESTED(lmt_ru_indexes_be),
__GEN_TXPWR_ENT0(
"2TX"),
__GEN_TXPWR_ENT_NESTED(lmt_ru_indexes_be),
};
static const struct txpwr_map __txpwr_map_lmt_ru_be = {
.ent = __txpwr_ent_lmt_ru_be,
.size = ARRAY_SIZE(__txpwr_ent_lmt_ru_be),
.addr_from = R_BE_PWR_RU_LMT,
.addr_to = R_BE_PWR_RU_LMT_MAX,
.addr_to_1ss = 0,
/* not support */
};
static unsigned int
__print_txpwr_ent(
char *buf, size_t bufsz,
const struct txpwr_ent *ent,
const s8 *bufp,
const unsigned int cur,
unsigned int *ate)
{
char *p = buf, *end = buf + bufsz;
unsigned int cnt, i;
unsigned int eaten;
char *fmt;
if (ent->nested) {
for (cnt = 0, i = 0; i < ent->len; i++, cnt += eaten)
p += __print_txpwr_ent(p, end - p, ent->ptr + i, bufp,
cur + cnt, &eaten);
*ate = cnt;
goto out;
}
switch (ent->len) {
case 0:
p += scnprintf(p, end - p,
"\t<< %s >>\n", ent->txt);
*ate = 0;
goto out;
case 2:
fmt =
"%s\t| %3d, %3d,\t\tdBm\n";
p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur],
bufp[cur + 1]);
*ate = 2;
goto out;
case 4:
fmt =
"%s\t| %3d, %3d, %3d, %3d,\tdBm\n";
p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur],
bufp[cur + 1],
bufp[cur + 2], bufp[cur + 3]);
*ate = 4;
goto out;
case 8:
fmt =
"%s\t| %3d, %3d, %3d, %3d, %3d, %3d, %3d, %3d,\tdBm\n";
p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur],
bufp[cur + 1],
bufp[cur + 2], bufp[cur + 3], bufp[cur + 4],
bufp[cur + 5], bufp[cur + 6], bufp[cur + 7]);
*ate = 8;
goto out;
default:
return 0;
}
out:
return p - buf;
}
static ssize_t __print_txpwr_map(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz,
const struct txpwr_map *map)
{
u8 fct = rtwdev->chip->txpwr_factor_mac;
u8 path_num = rtwdev->chip->rf_path_num;
char *p = buf, *end = buf + bufsz;
unsigned int cur, i;
unsigned int eaten;
u32 max_valid_addr;
u32 val, addr;
s8 *bufp, tmp;
int ret;
bufp = vzalloc(map->addr_to - map->addr_from + 4);
if (!bufp)
return -ENOMEM;
if (path_num == 1)
max_valid_addr = map->addr_to_1ss;
else
max_valid_addr = map->addr_to;
if (max_valid_addr == 0)
return -EOPNOTSUPP;
for (addr = map->addr_from; addr <= max_valid_addr; addr += 4) {
ret = rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, addr, &val);
if (ret)
val = MASKDWORD;
cur = addr - map->addr_from;
for (i = 0; i < 4; i++, val >>= 8) {
/* signed 7 bits, and reserved BIT(7) */
tmp = sign_extend32(val, 6);
bufp[cur + i] = tmp >> fct;
}
}
for (cur = 0, i = 0; i < map->size; i++, cur += eaten)
p += __print_txpwr_ent(p, end - p, &map->ent[i], bufp, cur, &eaten);
vfree(bufp);
return p - buf;
}
static int __print_regd(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz,
const struct rtw89_chan *chan)
{
const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
char *p = buf, *end = buf + bufsz;
u8 band = chan->band_type;
u8 regd = rtw89_regd_get(rtwdev, band);
p += scnprintf(p, end - p,
"%s\n", rtw89_regd_get_string(regd));
p += scnprintf(p, end - p,
"\t(txpwr UK follow ETSI: %s)\n",
str_yes_no(regulatory->txpwr_uk_follow_etsi));
return p - buf;
}
struct dbgfs_txpwr_table {
const struct txpwr_map *byr;
const struct txpwr_map *lmt;
const struct txpwr_map *lmt_ru;
};
static const struct dbgfs_txpwr_table dbgfs_txpwr_table_ax = {
.byr = &__txpwr_map_byr_ax,
.lmt = &__txpwr_map_lmt_ax,
.lmt_ru = &__txpwr_map_lmt_ru_ax,
};
static const struct dbgfs_txpwr_table dbgfs_txpwr_table_be = {
.byr = &__txpwr_map_byr_be,
.lmt = &__txpwr_map_lmt_be,
.lmt_ru = &__txpwr_map_lmt_ru_be,
};
static const struct dbgfs_txpwr_table *dbgfs_txpwr_tables[RTW89_CHIP_GEN_NUM] = {
[RTW89_CHIP_AX] = &dbgfs_txpwr_table_ax,
[RTW89_CHIP_BE] = &dbgfs_txpwr_table_be,
};
static
int rtw89_debug_priv_txpwr_table_get_regd(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz,
const struct rtw89_chan *chan)
{
const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_reg_6ghz_tpe *tpe6 = ®ulatory->reg_6ghz_tpe;
char *p = buf, *end = buf + bufsz;
p += scnprintf(p, end - p,
"[Chanctx] band %u, ch %u, bw %u\n",
chan->band_type, chan->channel, chan->band_width);
p += scnprintf(p, end - p,
"[Regulatory] ");
p += __print_regd(rtwdev, p, end - p, chan);
if (chan->band_type == RTW89_BAND_6G) {
p += scnprintf(p, end - p,
"[reg6_pwr_type] %u\n",
regulatory->reg_6ghz_power);
if (tpe6->valid)
p += scnprintf(p, end - p,
"[TPE] %d dBm\n",
tpe6->constraint);
}
return p - buf;
}
static
ssize_t rtw89_debug_priv_txpwr_table_get(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
char *buf, size_t bufsz)
{
enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
struct rtw89_sar_parm sar_parm = {};
const struct dbgfs_txpwr_table *tbl;
const struct rtw89_chan *chan;
char *p = buf, *end = buf + bufsz;
ssize_t n;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
rtw89_leave_ps_mode(rtwdev);
chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
sar_parm.center_freq = chan->freq;
p += rtw89_debug_priv_txpwr_table_get_regd(rtwdev, p, end - p, chan);
p += scnprintf(p, end - p,
"[SAR]\n");
p += rtw89_print_sar(rtwdev, p, end - p, &sar_parm);
p += scnprintf(p, end - p,
"[TAS]\n");
p += rtw89_print_tas(rtwdev, p, end - p);
p += scnprintf(p, end - p,
"[DAG]\n");
p += rtw89_print_ant_gain(rtwdev, p, end - p, chan);
tbl = dbgfs_txpwr_tables[chip_gen];
if (!tbl)
return -EOPNOTSUPP;
p += scnprintf(p, end - p,
"\n[TX power byrate]\n");
n = __print_txpwr_map(rtwdev, p, end - p, tbl->byr);
if (n < 0)
return n;
p += n;
p += scnprintf(p, end - p,
"\n[TX power limit]\n");
n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt);
if (n < 0)
return n;
p += n;
p += scnprintf(p, end - p,
"\n[TX power limit_ru]\n");
n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt_ru);
if (n < 0)
return n;
p += n;
return p - buf;
}
static ssize_t
rtw89_debug_priv_mac_reg_dump_select(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
const char *buf, size_t count)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
int sel;
int ret;
ret = kstrtoint(buf, 0, &sel);
if (ret)
return ret;
if (sel < RTW89_DBG_SEL_MAC_00 || sel > RTW89_DBG_SEL_RFC) {
rtw89_info(rtwdev,
"invalid args: %d\n", sel);
return -EINVAL;
}
if (sel == RTW89_DBG_SEL_MAC_30 && chip->chip_id != RTL8852C) {
rtw89_info(rtwdev,
"sel %d is address hole on chip %d\n", sel,
chip->chip_id);
return -EINVAL;
}
debugfs_priv->cb_data = sel;
rtw89_info(rtwdev,
"select mac page dump %d\n", debugfs_priv->cb_data);
return count;
}
#define RTW89_MAC_PAGE_SIZE 0x100
static
ssize_t rtw89_debug_priv_mac_reg_dump_get(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
char *buf, size_t bufsz)
{
enum rtw89_debug_mac_reg_sel reg_sel = debugfs_priv->cb_data;
char *p = buf, *end = buf + bufsz;
u32 start, end_addr;
u32 i, j, k, page;
u32 val;
switch (reg_sel) {
case RTW89_DBG_SEL_MAC_00:
p += scnprintf(p, end - p,
"Debug selected MAC page 0x00\n");
start = 0x000;
end_addr = 0x014;
break;
case RTW89_DBG_SEL_MAC_30:
p += scnprintf(p, end - p,
"Debug selected MAC page 0x30\n");
start = 0x030;
end_addr = 0x033;
break;
case RTW89_DBG_SEL_MAC_40:
p += scnprintf(p, end - p,
"Debug selected MAC page 0x40\n");
start = 0x040;
end_addr = 0x07f;
break;
case RTW89_DBG_SEL_MAC_80:
p += scnprintf(p, end - p,
"Debug selected MAC page 0x80\n");
start = 0x080;
end_addr = 0x09f;
break;
case RTW89_DBG_SEL_MAC_C0:
p += scnprintf(p, end - p,
"Debug selected MAC page 0xc0\n");
start = 0x0c0;
end_addr = 0x0df;
break;
case RTW89_DBG_SEL_MAC_E0:
p += scnprintf(p, end - p,
"Debug selected MAC page 0xe0\n");
start = 0x0e0;
end_addr = 0x0ff;
break;
case RTW89_DBG_SEL_BB:
p += scnprintf(p, end - p,
"Debug selected BB register\n");
start = 0x100;
end_addr = 0x17f;
break;
case RTW89_DBG_SEL_IQK:
p += scnprintf(p, end - p,
"Debug selected IQK register\n");
start = 0x180;
end_addr = 0x1bf;
break;
case RTW89_DBG_SEL_RFC:
p += scnprintf(p, end - p,
"Debug selected RFC register\n");
start = 0x1c0;
end_addr = 0x1ff;
break;
default:
p += scnprintf(p, end - p,
"Selected invalid register page\n");
return -EINVAL;
}
for (i = start; i <= end_addr; i++) {
page = i << 8;
for (j = page; j < page + RTW89_MAC_PAGE_SIZE; j += 16) {
p += scnprintf(p, end - p,
"%08xh : ", 0x18600000 + j);
for (k = 0; k < 4; k++) {
val = rtw89_read32(rtwdev, j + (k << 2));
p += scnprintf(p, end - p,
"%08x ", val);
}
p += scnprintf(p, end - p,
"\n");
}
}
return p - buf;
}
static ssize_t
rtw89_debug_priv_mac_mem_dump_select(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
const char *buf, size_t count)
{
u32 sel, start_addr, len;
int num;
num = sscanf(buf,
"%x %x %x", &sel, &start_addr, &len);
if (num != 3) {
rtw89_info(rtwdev,
"invalid format: \n");
return -EINVAL;
}
debugfs_priv->mac_mem.sel = sel;
debugfs_priv->mac_mem.start = start_addr;
debugfs_priv->mac_mem.len = len;
rtw89_info(rtwdev,
"select mem %d start %d len %d\n",
sel, start_addr, len);
return count;
}
static int rtw89_debug_dump_mac_mem(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz,
u8 sel, u32 start_addr, u32 len)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 filter_model_addr = mac->filter_model_addr;
u32 indir_access_addr = mac->indir_access_addr;
u32 mem_page_size = mac->mem_page_size;
u32 base_addr, start_page, residue;
char *p = buf, *end = buf + bufsz;
u32 i, j, pp, pages;
u32 dump_len, remain;
u32 val;
remain = len;
pages = len / mem_page_size + 1;
start_page = start_addr / mem_page_size;
residue = start_addr % mem_page_size;
base_addr = mac->mem_base_addrs[sel];
base_addr += start_page * mem_page_size;
for (pp = 0; pp < pages; pp++) {
dump_len = min_t(u32, remain, mem_page_size);
rtw89_write32(rtwdev, filter_model_addr, base_addr);
for (i = indir_access_addr + residue;
i < indir_access_addr + dump_len;) {
p += scnprintf(p, end - p,
"%08xh:", i);
for (j = 0;
j < 4 && i < indir_access_addr + dump_len;
j++, i += 4) {
val = rtw89_read32(rtwdev, i);
p += scnprintf(p, end - p,
" %08x", val);
remain -= 4;
}
p += scnprintf(p, end - p,
"\n");
}
base_addr += mem_page_size;
}
return p - buf;
}
static ssize_t
rtw89_debug_priv_mac_mem_dump_get(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
char *buf, size_t bufsz)
{
char *p = buf, *end = buf + bufsz;
bool grant_read =
false;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (debugfs_priv->mac_mem.sel >= RTW89_MAC_MEM_NUM)
return -ENOENT;
if (rtwdev->chip->chip_id == RTL8852C) {
switch (debugfs_priv->mac_mem.sel) {
case RTW89_MAC_MEM_TXD_FIFO_0_V1:
case RTW89_MAC_MEM_TXD_FIFO_1_V1:
case RTW89_MAC_MEM_TXDATA_FIFO_0:
case RTW89_MAC_MEM_TXDATA_FIFO_1:
grant_read =
true;
break;
default:
break;
}
}
rtw89_leave_ps_mode(rtwdev);
if (grant_read)
rtw89_write32_set(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO);
p += rtw89_debug_dump_mac_mem(rtwdev, p, end - p,
debugfs_priv->mac_mem.sel,
debugfs_priv->mac_mem.start,
debugfs_priv->mac_mem.len);
if (grant_read)
rtw89_write32_clr(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO);
return p - buf;
}
static ssize_t
rtw89_debug_priv_mac_dbg_port_dump_select(
struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
const char *buf, size_t count)
{
int sel, set;
int num;
bool enable;
num = sscanf(buf,
"%d %d", &sel, &set);
if (num != 2) {
rtw89_info(rtwdev,
"invalid format: \n");
return -EINVAL;
}
enable = set != 0;
switch (sel) {
case 0:
debugfs_priv->dbgpkg_en.ss_dbg = enable;
break;
case 1:
debugfs_priv->dbgpkg_en.dle_dbg = enable;
break;
case 2:
debugfs_priv->dbgpkg_en.dmac_dbg = enable;
break;
case 3:
debugfs_priv->dbgpkg_en.cmac_dbg = enable;
break;
case 4:
debugfs_priv->dbgpkg_en.dbg_port = enable;
break;
default:
rtw89_info(rtwdev,
"invalid args: sel %d set %d\n", sel, set);
return -EINVAL;
}
rtw89_info(rtwdev,
"%s debug port dump %d\n",
enable ?
"Enable" :
"Disable", sel);
return count;
}
static int rtw89_debug_mac_dump_ss_dbg(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz)
{
return 0;
}
static int rtw89_debug_mac_dump_dle_dbg(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz)
{
#define DLE_DFI_DUMP(__type, __target, __sel) \
({ \
u32 __ctrl; \
u32 __reg_ctrl = R_AX_
##__type
##_DBG_FUN_INTF_CTL; \
u32 __reg_data = R_AX_
##__type
##_DBG_FUN_INTF_DATA; \
u32 __data, __val32; \
int __ret; \
\
__ctrl = FIELD_PREP(B_AX_
##__type
##_DFI_TRGSEL_MASK, \
DLE_DFI_TYPE_
##__target) | \
FIELD_PREP(B_AX_
##__type
##_DFI_ADDR_MASK, __sel) | \
B_AX_WDE_DFI_ACTIVE; \
rtw89_write32(rtwdev, __reg_ctrl, __ctrl); \
__ret = read_poll_timeout(rtw89_read32, __val32, \
!(__val32 & B_AX_
##__type
##_DFI_ACTIVE), \
1000, 50000,
false, \
rtwdev, __reg_ctrl); \
if (__ret) { \
rtw89_err(rtwdev,
"failed to dump DLE %s %s %d\n", \
#__type,
#__target, __sel); \
return __ret; \
} \
\
__data = rtw89_read32(rtwdev, __reg_data); \
__data; \
})
#define DLE_DFI_FREE_PAGE_DUMP(__p, __end, __type) \
({ \
u32 __freepg, __pubpg; \
u32 __freepg_head, __freepg_tail, __pubpg_num; \
\
__freepg = DLE_DFI_DUMP(__type, FREEPG, 0); \
__pubpg = DLE_DFI_DUMP(__type, FREEPG, 1); \
__freepg_head = FIELD_GET(B_AX_DLE_FREE_HEADPG, __freepg); \
__freepg_tail = FIELD_GET(B_AX_DLE_FREE_TAILPG, __freepg); \
__pubpg_num = FIELD_GET(B_AX_DLE_PUB_PGNUM, __pubpg); \
__p += scnprintf(__p, __end - __p,
"[%s] freepg head: %d\n", \
#__type, __freepg_head); \
__p += scnprintf(__p, __end - __p,
"[%s] freepg tail: %d\n", \
#__type, __freepg_tail); \
__p += scnprintf(__p, __end - __p,
"[%s] pubpg num : %d\n", \
#__type, __pubpg_num); \
})
#define case_QUOTA(__p, __end, __type, __id) \
case __type
##_QTAID_
##__id: \
val32 = DLE_DFI_DUMP(__type, QUOTA, __type
##_QTAID_
##__id); \
rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, val32); \
use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, val32); \
__p += scnprintf(__p, __end - __p,
"[%s][%s] rsv_pgnum: %d\n", \
#__type,
#__id, rsv_pgnum); \
__p += scnprintf(__p, __end - __p,
"[%s][%s] use_pgnum: %d\n", \
#__type,
#__id, use_pgnum); \
break
char *p = buf, *end = buf + bufsz;
u32 quota_id;
u32 val32;
u16 rsv_pgnum, use_pgnum;
int ret;
ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
if (ret) {
p += scnprintf(p, end - p,
"[DLE] : DMAC not enabled\n");
goto out;
}
DLE_DFI_FREE_PAGE_DUMP(p, end, WDE);
DLE_DFI_FREE_PAGE_DUMP(p, end, PLE);
for (quota_id = 0; quota_id <= WDE_QTAID_CPUIO; quota_id++) {
switch (quota_id) {
case_QUOTA(p, end, WDE, HOST_IF);
case_QUOTA(p, end, WDE, WLAN_CPU);
case_QUOTA(p, end, WDE, DATA_CPU);
case_QUOTA(p, end, WDE, PKTIN);
case_QUOTA(p, end, WDE, CPUIO);
}
}
for (quota_id = 0; quota_id <= PLE_QTAID_CPUIO; quota_id++) {
switch (quota_id) {
case_QUOTA(p, end, PLE, B0_TXPL);
case_QUOTA(p, end, PLE, B1_TXPL);
case_QUOTA(p, end, PLE, C2H);
case_QUOTA(p, end, PLE, H2C);
case_QUOTA(p, end, PLE, WLAN_CPU);
case_QUOTA(p, end, PLE, MPDU);
case_QUOTA(p, end, PLE, CMAC0_RX);
case_QUOTA(p, end, PLE, CMAC1_RX);
case_QUOTA(p, end, PLE, CMAC1_BBRPT);
case_QUOTA(p, end, PLE, WDRLS);
case_QUOTA(p, end, PLE, CPUIO);
}
}
out:
return p - buf;
#undef case_QUOTA
#undef DLE_DFI_DUMP
#undef DLE_DFI_FREE_PAGE_DUMP
}
static int rtw89_debug_mac_dump_dmac_dbg(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
char *p = buf, *end = buf + bufsz;
u32 dmac_err;
int i, ret;
ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
if (ret) {
p += scnprintf(p, end - p,
"[DMAC] : DMAC not enabled\n");
goto out;
}
dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR);
p += scnprintf(p, end - p,
"R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err);
p += scnprintf(p, end - p,
"R_AX_DMAC_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR));
if (dmac_err) {
p += scnprintf(p, end - p,
"R_AX_WDE_ERR_FLAG_CFG=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1));
p += scnprintf(p, end - p,
"R_AX_PLE_ERR_FLAG_CFG=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1));
if (chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_PLE_ERRFLAG_MSG=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG));
p += scnprintf(p, end - p,
"R_AX_WDE_ERRFLAG_MSG=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG));
p += scnprintf(p, end - p,
"R_AX_PLE_DBGERR_LOCKEN=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN));
p += scnprintf(p, end - p,
"R_AX_PLE_DBGERR_STS=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS));
}
}
if (dmac_err & B_AX_WDRLS_ERR_FLAG) {
p += scnprintf(p, end - p,
"R_AX_WDRLS_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_WDRLS_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR));
if (chip->chip_id == RTL8852C)
p += scnprintf(p, end - p,
"R_AX_RPQ_RXBD_IDX=0x%08x\n",
rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1));
else
p += scnprintf(p, end - p,
"R_AX_RPQ_RXBD_IDX=0x%08x\n",
rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));
}
if (dmac_err & B_AX_WSEC_ERR_FLAG) {
if (chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_SEC_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR));
p += scnprintf(p, end - p,
"R_AX_SEC_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG));
p += scnprintf(p, end - p,
"R_AX_SEC_ENG_CTRL=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
p += scnprintf(p, end - p,
"R_AX_SEC_MPDU_PROC=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
p += scnprintf(p, end - p,
"R_AX_SEC_CAM_ACCESS=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
p += scnprintf(p, end - p,
"R_AX_SEC_CAM_RDATA=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
p += scnprintf(p, end - p,
"R_AX_SEC_DEBUG1=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_DEBUG1));
p += scnprintf(p, end - p,
"R_AX_SEC_TX_DEBUG=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
p += scnprintf(p, end - p,
"R_AX_SEC_RX_DEBUG=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
B_AX_DBG_SEL0, 0x8B);
rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
B_AX_DBG_SEL1, 0x8B);
rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1,
B_AX_SEL_0XC0_MASK, 1);
for (i = 0; i < 0x10; i++) {
rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL,
B_AX_SEC_DBG_PORT_FIELD_MASK, i);
p += scnprintf(p, end - p,
"sel=%x,R_AX_SEC_DEBUG2=0x%08x\n",
i,
rtw89_read32(rtwdev, R_AX_SEC_DEBUG2));
}
}
else {
p += scnprintf(p, end - p,
"R_AX_SEC_ERR_IMR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_DEBUG));
p += scnprintf(p, end - p,
"R_AX_SEC_ENG_CTRL=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
p += scnprintf(p, end - p,
"R_AX_SEC_MPDU_PROC=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
p += scnprintf(p, end - p,
"R_AX_SEC_CAM_ACCESS=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
p += scnprintf(p, end - p,
"R_AX_SEC_CAM_RDATA=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
p += scnprintf(p, end - p,
"R_AX_SEC_CAM_WDATA=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA));
p += scnprintf(p, end - p,
"R_AX_SEC_TX_DEBUG=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
p += scnprintf(p, end - p,
"R_AX_SEC_RX_DEBUG=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
p += scnprintf(p, end - p,
"R_AX_SEC_TRX_PKT_CNT=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT));
p += scnprintf(p, end - p,
"R_AX_SEC_TRX_BLK_CNT=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT));
}
}
if (dmac_err & B_AX_MPDU_ERR_FLAG) {
p += scnprintf(p, end - p,
"R_AX_MPDU_TX_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_MPDU_TX_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR));
p += scnprintf(p, end - p,
"R_AX_MPDU_RX_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_MPDU_RX_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR));
}
if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) {
p += scnprintf(p, end - p,
"R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));
}
if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) {
p += scnprintf(p, end - p,
"R_AX_WDE_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_WDE_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
p += scnprintf(p, end - p,
"R_AX_PLE_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
}
if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) {
if (chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR));
p += scnprintf(p, end - p,
"R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR));
p += scnprintf(p, end - p,
"R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR));
p += scnprintf(p, end - p,
"R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR));
}
else {
p += scnprintf(p, end - p,
"R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR));
p += scnprintf(p, end - p,
"R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n",
rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1));
}
}
if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) {
p += scnprintf(p, end - p,
"R_AX_WDE_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_WDE_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
p += scnprintf(p, end - p,
"R_AX_PLE_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
p += scnprintf(p, end - p,
"R_AX_WD_CPUQ_OP_0=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0));
p += scnprintf(p, end - p,
"R_AX_WD_CPUQ_OP_1=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1));
p += scnprintf(p, end - p,
"R_AX_WD_CPUQ_OP_2=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2));
p += scnprintf(p, end - p,
"R_AX_WD_CPUQ_OP_STATUS=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS));
p += scnprintf(p, end - p,
"R_AX_PL_CPUQ_OP_0=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0));
p += scnprintf(p, end - p,
"R_AX_PL_CPUQ_OP_1=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1));
p += scnprintf(p, end - p,
"R_AX_PL_CPUQ_OP_2=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2));
p += scnprintf(p, end - p,
"R_AX_PL_CPUQ_OP_STATUS=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));
if (chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_RX_CTRL0=0x%08x\n",
rtw89_read32(rtwdev, R_AX_RX_CTRL0));
p += scnprintf(p, end - p,
"R_AX_RX_CTRL1=0x%08x\n",
rtw89_read32(rtwdev, R_AX_RX_CTRL1));
p += scnprintf(p, end - p,
"R_AX_RX_CTRL2=0x%08x\n",
rtw89_read32(rtwdev, R_AX_RX_CTRL2));
}
else {
p += scnprintf(p, end - p,
"R_AX_RXDMA_PKT_INFO_0=0x%08x\n",
rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0));
p += scnprintf(p, end - p,
"R_AX_RXDMA_PKT_INFO_1=0x%08x\n",
rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1));
p += scnprintf(p, end - p,
"R_AX_RXDMA_PKT_INFO_2=0x%08x\n",
rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));
}
}
if (dmac_err & B_AX_PKTIN_ERR_FLAG) {
p += scnprintf(p, end - p,
"R_AX_PKTIN_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_PKTIN_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR));
}
if (dmac_err & B_AX_DISPATCH_ERR_FLAG) {
p += scnprintf(p, end - p,
"R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
p += scnprintf(p, end - p,
"R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
p += scnprintf(p, end - p,
"R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
}
if (dmac_err & B_AX_BBRPT_ERR_FLAG) {
if (chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_BBRPT_COM_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_COM_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
}
else {
p += scnprintf(p, end - p,
"R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
p += scnprintf(p, end - p,
"R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
}
}
if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_HAXIDMA_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK));
p += scnprintf(p, end - p,
"R_AX_HAXIDMA_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_HAXI_IDCT));
}
out:
return p - buf;
}
static int rtw89_debug_mac_dump_cmac_err(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz,
enum rtw89_mac_idx band)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
char *p = buf, *end = buf + bufsz;
u32 offset = 0;
u32 cmac_err;
int ret;
ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
if (ret) {
if (band)
p += scnprintf(p, end - p,
"[CMAC] : CMAC1 not enabled\n");
else
p += scnprintf(p, end - p,
"[CMAC] : CMAC0 not enabled\n");
goto out;
}
if (band)
offset = RTW89_MAC_AX_BAND_REG_OFFSET;
cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset);
p += scnprintf(p, end - p,
"R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset));
p += scnprintf(p, end - p,
"R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset));
p += scnprintf(p, end - p,
"R_AX_CK_EN [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_CK_EN + offset));
if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) {
p += scnprintf(p, end - p,
"R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset));
p += scnprintf(p, end - p,
"R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset));
}
if (cmac_err & B_AX_PTCL_TOP_ERR_IND) {
p += scnprintf(p, end - p,
"R_AX_PTCL_IMR0 [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset));
p += scnprintf(p, end - p,
"R_AX_PTCL_ISR0 [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset));
}
if (cmac_err & B_AX_DMA_TOP_ERR_IND) {
if (chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset));
p += scnprintf(p, end - p,
"R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset));
}
else {
p += scnprintf(p, end - p,
"R_AX_DLE_CTRL [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset));
}
}
if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) {
if (chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset));
p += scnprintf(p, end - p,
"R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
}
else {
p += scnprintf(p, end - p,
"R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
}
}
if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) {
p += scnprintf(p, end - p,
"R_AX_TXPWR_IMR [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset));
p += scnprintf(p, end - p,
"R_AX_TXPWR_ISR [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset));
}
if (cmac_err & B_AX_WMAC_TX_ERR_IND) {
if (chip->chip_id == RTL8852C) {
p += scnprintf(p, end - p,
"R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev,
R_AX_TRXPTCL_ERROR_INDICA + offset));
p += scnprintf(p, end - p,
"R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev,
R_AX_TRXPTCL_ERROR_INDICA_MASK + offset));
}
else {
p += scnprintf(p, end - p,
"R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n",
band,
rtw89_read32(rtwdev,
R_AX_TMAC_ERR_IMR_ISR + offset));
}
p += scnprintf(p, end - p,
"R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset));
}
p += scnprintf(p, end - p,
"R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band,
rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset));
out:
return p - buf;
}
static int rtw89_debug_mac_dump_cmac_dbg(
struct rtw89_dev *rtwdev,
char *buf, size_t bufsz)
{
char *p = buf, *end = buf + bufsz;
p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_0);
if (rtwdev->dbcc_en)
p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_1);
return p - buf;
}
static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = {
.sel_addr = R_AX_PTCL_DBG,
.sel_byte = 1,
.sel_msk = B_AX_PTCL_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x3F,
.rd_addr = R_AX_PTCL_DBG_INFO,
.rd_byte = 4,
.rd_msk = B_AX_PTCL_DBG_INFO_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c1 = {
.sel_addr = R_AX_PTCL_DBG_C1,
.sel_byte = 1,
.sel_msk = B_AX_PTCL_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x3F,
.rd_addr = R_AX_PTCL_DBG_INFO_C1,
.rd_byte = 4,
.rd_msk = B_AX_PTCL_DBG_INFO_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx0_5 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0xD,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx6 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x5,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx7 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x9,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx8 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x3,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx9_C = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_txD = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx0 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0xB,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx1 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x4,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx3 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x8,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx4 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x7,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx5_8 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx9 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x3,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_txA_C = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx0 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x8,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx1_2 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx3 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x6,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx4 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx5 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 2,
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_0 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x3,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_1 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x6,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_2 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x0,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p1 = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x8,
.end = 0xE,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_stf_ctrl = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x5,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_addr_ctrl = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x6,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_wde_intf = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0xF,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_ple_intf = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x9,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_dspt_flow_ctrl = {
.sel_addr = R_AX_DISPATCHER_DBG_PORT,
.sel_byte = 1,
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x3,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_sch_c0 = {
.sel_addr = R_AX_SCH_DBG_SEL,
.sel_byte = 1,
.sel_msk = B_AX_SCH_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x2F,
.rd_addr = R_AX_SCH_DBG,
.rd_byte = 4,
.rd_msk = B_AX_SCHEDULER_DBG_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_sch_c1 = {
.sel_addr = R_AX_SCH_DBG_SEL_C1,
.sel_byte = 1,
.sel_msk = B_AX_SCH_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x2F,
.rd_addr = R_AX_SCH_DBG_C1,
.rd_byte = 4,
.rd_msk = B_AX_SCHEDULER_DBG_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c0 = {
.sel_addr = R_AX_MACTX_DBG_SEL_CNT,
.sel_byte = 1,
.sel_msk = B_AX_DBGSEL_MACTX_MASK,
.srt = 0x00,
.end = 0x19,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c1 = {
.sel_addr = R_AX_MACTX_DBG_SEL_CNT_C1,
.sel_byte = 1,
.sel_msk = B_AX_DBGSEL_MACTX_MASK,
.srt = 0x00,
--> --------------------
--> maximum size reached
--> --------------------