From: Ping-Ke Shih <pkshih@realtek.com>
To: Chris Vitalos <cvitalos@gmail.com>,
"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Subject: RE: rtw89_8852bte (RTL8852BE-VT): recurring SER 0x1000/0x4000/0x1001/0x1002 on fw 0.29.122.1/.2; question on rtw8852bt_fw-1.bin
Date: Mon, 2 Nov 2026 01:50:47 +0000 [thread overview]
Message-ID: <703ebc52e1d544e590874df041b4d979@realtek.com> (raw)
In-Reply-To: <CADp4rm+GmTjCoFXvT8WpiLNohnREqfR9z78PfH1m2rxs00jMUQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2859 bytes --]
Chris Vitalos <cvitalos@gmail.com> wrote:
> Hello Ping-Ke, all,
>
> This is a follow-up to the July thread "[BUG] rtw89_8852bte: Recurring
> firmware crashes (LBC watchdog / SER) on RTL8852BE-VT despite ASPM and
> PS disabled". I see the same signature on a different laptop and
> distro, and I have a question about the newer firmware format.
I sent attached debug patch to the people who created the thread, but I have
not received log.
To collect more detail info, please apply attached patch and run test.
When SER occurs, firmware will lock itself and driver dump a lot of
info for debugging.
Since we want to collect three logs at least, please reboot before collecting
2nd and 3th logs.
> Firmware tested
> - 0.29.122.1 (2ac94d05), as shipped: SER burst at 2150 s uptime.
> - 0.29.122.2 (42816c59), upstream linux-firmware, installed via
> /lib/firmware/updates: two SER bursts on one boot, at 18:39:25 and
> 19:44:31 local (boot was 17:39:31).
It means no obvious difference from the two firmware, right?
>
> Symptoms
> Every burst has the same order: SER catches error 0x1000, "firmware
> failed to ack for leaving ps mode", 0x4000, 0x1001, 0x1002, with many
> "[ERR]fw PC = 0xb898..." and "0xb892..." lines in between. On the
> 7.0.0-42 boot, disable_ps_mode is N and iw reports power save on
> (defaults).
Please turn off power save entirely by NetworkManager or iw command
iw wlan0 set power_save off
> I have not yet tested the rtw89_pci
> disable_clkreq/disable_aspm_l1/disable_aspm_l1ss options or
> disable_ps_mode on this unit; I understand the July reporter saw
> crashes with them set.
It is worth to give it a try.
>
> Impact
> - First event: connectivity (ping, DNS) failed until I restarted the
> Wi-Fi interface.
> - 18:39:25 event: Firefox browser VPN reported it could not reach its
> servers; I did not need to restart Wi-Fi.
> - wlo1 stayed associated: after the 17:56:52 resume association, the
> kernel log shows no deauth/auth/assoc lines through either burst.
> NetworkManager/wpa_supplicant logged only a DHCPv6 lease line at
> 18:40:01 between 18:38 and 18:42.
> - I do not have a measured outage duration.
Can you try another AP to see if anything different?
>
> Question
> Ubuntu's linux-firmware package ships both rtw8852bt_fw.bin and
> rtw8852bt_fw-1.bin, but the 7.0 driver declares and loads only
> rtw89/rtw8852bt_fw.bin (modinfo rtw89_8852bt shows a single firmware
> entry). Which kernel adds support for the -1 format, and does that
> firmware change the power-save-exit behavior behind SER 0x1000 with
> "firmware failed to ack for leaving ps mode"? If it might help, I can
> test a kernel that supports it.
As I know, the main purpose of -1 format is the changes of BT-coexistence,
so it might not help.
Ping-Ke
[-- Attachment #2: 20260731_00_debug_8852bt_ser_l1.patch --]
[-- Type: application/octet-stream, Size: 54701 bytes --]
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 77a0e2582dbe..0aa865b4d081 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -6721,6 +6721,14 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
rtw89_tas_fw_timer_enable(rtwdev, true);
rtwdev->ps_hang_cnt = 0;
+ {
+ extern int rtw89_mac_set_l1_dbg_mode(struct rtw89_dev *rtwdev);
+
+ rtw89_mac_set_l1_dbg_mode(rtwdev);
+
+ printk("enable L1 debug mode\n");
+ }
+
return 0;
}
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index 7e640c7166e4..91da0c882cfe 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -257,6 +257,15 @@ rtw89_debug_priv_read_reg_select(struct rtw89_dev *rtwdev,
return -EINVAL;
}
+ if (addr == 0x6789) {
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ mac->dbg_mode_dump(rtwdev);
+
+ rtw89_info(rtwdev, "do mac->dbg_mode_dump\n");
+ return count;
+ }
+
debugfs_priv->read_reg.addr = addr;
debugfs_priv->read_reg.len = len;
@@ -1879,6 +1888,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = {
.sel_msk = B_AX_PTCL_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x3F,
+ .inc_num = 1,
.rd_addr = R_AX_PTCL_DBG_INFO,
.rd_byte = 4,
.rd_msk = B_AX_PTCL_DBG_INFO_MASK
@@ -1890,6 +1900,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c1 = {
.sel_msk = B_AX_PTCL_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x3F,
+ .inc_num = 1,
.rd_addr = R_AX_PTCL_DBG_INFO_C1,
.rd_byte = 4,
.rd_msk = B_AX_PTCL_DBG_INFO_MASK
@@ -1901,6 +1912,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx0_5 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0xD,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -1912,6 +1924,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx6 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x5,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -1923,6 +1936,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx7 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x9,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -1934,6 +1948,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx8 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x3,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -1945,6 +1960,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx9_C = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x1,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -1956,6 +1972,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_txD = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -1967,6 +1984,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx0 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0xB,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -1978,6 +1996,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx1 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x4,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -1989,6 +2008,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx3 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x8,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2000,6 +2020,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx4 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x7,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2011,6 +2032,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx5_8 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x1,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2022,6 +2044,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx9 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x3,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2033,6 +2056,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_txA_C = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2044,6 +2068,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx0 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x8,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2055,6 +2080,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx1_2 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2066,6 +2092,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx3 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x6,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2077,6 +2104,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx4 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2088,6 +2116,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx5 = {
.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
.srt = 0x0,
.end = 0x0,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2099,6 +2128,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_0 = {
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x3,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2110,6 +2140,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_1 = {
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x6,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2121,6 +2152,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_2 = {
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x0,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2132,6 +2164,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p1 = {
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x8,
.end = 0xE,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2143,6 +2176,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_stf_ctrl = {
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x5,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2154,6 +2188,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_addr_ctrl = {
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x6,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2165,6 +2200,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_wde_intf = {
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0xF,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2176,17 +2212,79 @@ static const struct rtw89_mac_dbg_port_info dbg_port_dspt_ple_intf = {
.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
.srt = 0x0,
.end = 0x9,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
};
+static struct rtw89_mac_dbg_port_info dbg_port_txpktctrl_fetpkt = {
+ .sel_addr = R_AX_DBG_CTL_TXPKT,
+ .sel_byte = 4,
+ .sel_msk = B_AX_DEBUG_ST_MASK,
+ .srt = 0x0,
+ .end = 0x10001,
+ .inc_num = 0x10001,
+ .rd_addr = R_AX_TPC_DBG_OUT,
+ .rd_byte = 4,
+ .rd_msk = B_AX_DEBUG_ST_MASK
+};
+
+static struct rtw89_mac_dbg_port_info dbg_port_txpktctrl_b0_cmdpsr = {
+ .sel_addr = R_AX_DBG_CTL_TXPKT,
+ .sel_byte = 4,
+ .sel_msk = B_AX_DEBUG_ST_MASK,
+ .srt = 0x800080,
+ .end = 0x810081,
+ .inc_num = 0x10001,
+ .rd_addr = R_AX_TPC_DBG_OUT,
+ .rd_byte = 4,
+ .rd_msk = B_AX_DEBUG_ST_MASK
+};
+
+static struct rtw89_mac_dbg_port_info dbg_port_txpktctrl_b0_cmacdmaif = {
+ .sel_addr = R_AX_DBG_CTL_TXPKT,
+ .sel_byte = 4,
+ .sel_msk = B_AX_DEBUG_ST_MASK,
+ .srt = 0x880088,
+ .end = 0x880088,
+ .inc_num = 0x10001,
+ .rd_addr = R_AX_TPC_DBG_OUT,
+ .rd_byte = 4,
+ .rd_msk = B_AX_DEBUG_ST_MASK
+};
+
+static struct rtw89_mac_dbg_port_info dbg_port_txpktctrl_b0_unit0_0 = {
+ .sel_addr = R_AX_DBG_CTL_TXPKT,
+ .sel_byte = 4,
+ .sel_msk = B_AX_DEBUG_ST_MASK,
+ .srt = 0x1000100,
+ .end = 0x1020102,
+ .inc_num = 0x10001,
+ .rd_addr = R_AX_TPC_DBG_OUT,
+ .rd_byte = 4,
+ .rd_msk = B_AX_DEBUG_ST_MASK
+};
+
+static struct rtw89_mac_dbg_port_info dbg_port_txpktctrl_b0_unit0_1 = {
+ .sel_addr = R_AX_DBG_CTL_TXPKT,
+ .sel_byte = 4,
+ .sel_msk = B_AX_DEBUG_ST_MASK,
+ .srt = 0x1080108,
+ .end = 0x10D010D,
+ .inc_num = 0x10001,
+ .rd_addr = R_AX_TPC_DBG_OUT,
+ .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,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2198,6 +2296,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_sch_c0 = {
.sel_msk = B_AX_SCH_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x2F,
+ .inc_num = 1,
.rd_addr = R_AX_SCH_DBG,
.rd_byte = 4,
.rd_msk = B_AX_SCHEDULER_DBG_MASK
@@ -2209,6 +2308,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_sch_c1 = {
.sel_msk = B_AX_SCH_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x2F,
+ .inc_num = 1,
.rd_addr = R_AX_SCH_DBG_C1,
.rd_byte = 4,
.rd_msk = B_AX_SCHEDULER_DBG_MASK
@@ -2220,6 +2320,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c0 = {
.sel_msk = B_AX_DBGSEL_MACTX_MASK,
.srt = 0x00,
.end = 0x19,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2231,6 +2332,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c1 = {
.sel_msk = B_AX_DBGSEL_MACTX_MASK,
.srt = 0x00,
.end = 0x19,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2242,6 +2344,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c0 = {
.sel_msk = B_AX_DEBUG_SEL_MASK,
.srt = 0x00,
.end = 0x58,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2253,6 +2356,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c1 = {
.sel_msk = B_AX_DEBUG_SEL_MASK,
.srt = 0x00,
.end = 0x58,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2264,6 +2368,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c0 = {
.sel_msk = B_AX_STATE_SEL_MASK,
.srt = 0x00,
.end = 0x17,
+ .inc_num = 1,
.rd_addr = R_AX_RX_STATE_MONITOR,
.rd_byte = 4,
.rd_msk = B_AX_RX_STATE_MONITOR_MASK
@@ -2275,6 +2380,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c1 = {
.sel_msk = B_AX_STATE_SEL_MASK,
.srt = 0x00,
.end = 0x17,
+ .inc_num = 1,
.rd_addr = R_AX_RX_STATE_MONITOR_C1,
.rd_byte = 4,
.rd_msk = B_AX_RX_STATE_MONITOR_MASK
@@ -2286,6 +2392,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c0 = {
.sel_msk = B_AX_PCLP_MON_SEL_MASK,
.srt = 0x0,
.end = 0xF,
+ .inc_num = 1,
.rd_addr = R_AX_RMAC_PLCP_MON,
.rd_byte = 4,
.rd_msk = B_AX_RMAC_PLCP_MON_MASK
@@ -2297,6 +2404,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c1 = {
.sel_msk = B_AX_PCLP_MON_SEL_MASK,
.srt = 0x0,
.end = 0xF,
+ .inc_num = 1,
.rd_addr = R_AX_RMAC_PLCP_MON_C1,
.rd_byte = 4,
.rd_msk = B_AX_RMAC_PLCP_MON_MASK
@@ -2308,6 +2416,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c0 = {
.sel_msk = B_AX_DBGSEL_TRXPTCL_MASK,
.srt = 0x08,
.end = 0x10,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2319,6 +2428,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c1 = {
.sel_msk = B_AX_DBGSEL_TRXPTCL_MASK,
.srt = 0x08,
.end = 0x10,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2330,6 +2440,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c0 = {
.sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK,
.srt = 0x00,
.end = 0x07,
+ .inc_num = 1,
.rd_addr = R_AX_WMAC_TX_INFO0_DEBUG,
.rd_byte = 4,
.rd_msk = B_AX_TX_CTRL_INFO_P0_MASK
@@ -2341,6 +2452,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c0 = {
.sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK,
.srt = 0x00,
.end = 0x07,
+ .inc_num = 1,
.rd_addr = R_AX_WMAC_TX_INFO1_DEBUG,
.rd_byte = 4,
.rd_msk = B_AX_TX_CTRL_INFO_P1_MASK
@@ -2352,6 +2464,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c1 = {
.sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK,
.srt = 0x00,
.end = 0x07,
+ .inc_num = 1,
.rd_addr = R_AX_WMAC_TX_INFO0_DEBUG_C1,
.rd_byte = 4,
.rd_msk = B_AX_TX_CTRL_INFO_P0_MASK
@@ -2363,6 +2476,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c1 = {
.sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK,
.srt = 0x00,
.end = 0x07,
+ .inc_num = 1,
.rd_addr = R_AX_WMAC_TX_INFO1_DEBUG_C1,
.rd_byte = 4,
.rd_msk = B_AX_TX_CTRL_INFO_P1_MASK
@@ -2374,6 +2488,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c0 = {
.sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK,
.srt = 0x00,
.end = 0x04,
+ .inc_num = 1,
.rd_addr = R_AX_WMAC_TX_TF_INFO_1,
.rd_byte = 4,
.rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK
@@ -2385,6 +2500,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c0 = {
.sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK,
.srt = 0x00,
.end = 0x04,
+ .inc_num = 1,
.rd_addr = R_AX_WMAC_TX_TF_INFO_2,
.rd_byte = 4,
.rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK
@@ -2396,6 +2512,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c1 = {
.sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK,
.srt = 0x00,
.end = 0x04,
+ .inc_num = 1,
.rd_addr = R_AX_WMAC_TX_TF_INFO_1_C1,
.rd_byte = 4,
.rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK
@@ -2407,6 +2524,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c1 = {
.sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK,
.srt = 0x00,
.end = 0x04,
+ .inc_num = 1,
.rd_addr = R_AX_WMAC_TX_TF_INFO_2_C1,
.rd_byte = 4,
.rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK
@@ -2418,6 +2536,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_freepg = {
.sel_msk = B_AX_WDE_DFI_DATA_MASK,
.srt = 0x80000000,
.end = 0x80000001,
+ .inc_num = 1,
.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_WDE_DFI_DATA_MASK
@@ -2429,6 +2548,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_quota = {
.sel_msk = B_AX_WDE_DFI_DATA_MASK,
.srt = 0x80010000,
.end = 0x80010004,
+ .inc_num = 1,
.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_WDE_DFI_DATA_MASK
@@ -2440,6 +2560,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pagellt = {
.sel_msk = B_AX_WDE_DFI_DATA_MASK,
.srt = 0x80020000,
.end = 0x80020FFF,
+ .inc_num = 1,
.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_WDE_DFI_DATA_MASK
@@ -2451,6 +2572,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pktinfo = {
.sel_msk = B_AX_WDE_DFI_DATA_MASK,
.srt = 0x80030000,
.end = 0x80030FFF,
+ .inc_num = 1,
.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_WDE_DFI_DATA_MASK
@@ -2462,6 +2584,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_prepkt = {
.sel_msk = B_AX_WDE_DFI_DATA_MASK,
.srt = 0x80040000,
.end = 0x80040FFF,
+ .inc_num = 1,
.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_WDE_DFI_DATA_MASK
@@ -2473,6 +2596,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_nxtpkt = {
.sel_msk = B_AX_WDE_DFI_DATA_MASK,
.srt = 0x80050000,
.end = 0x80050FFF,
+ .inc_num = 1,
.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_WDE_DFI_DATA_MASK
@@ -2484,6 +2608,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qlnktbl = {
.sel_msk = B_AX_WDE_DFI_DATA_MASK,
.srt = 0x80060000,
.end = 0x80060453,
+ .inc_num = 1,
.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_WDE_DFI_DATA_MASK
@@ -2495,6 +2620,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qempty = {
.sel_msk = B_AX_WDE_DFI_DATA_MASK,
.srt = 0x80070000,
.end = 0x80070011,
+ .inc_num = 1,
.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_WDE_DFI_DATA_MASK
@@ -2506,6 +2632,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_freepg = {
.sel_msk = B_AX_PLE_DFI_DATA_MASK,
.srt = 0x80000000,
.end = 0x80000001,
+ .inc_num = 1,
.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_PLE_DFI_DATA_MASK
@@ -2517,6 +2644,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_quota = {
.sel_msk = B_AX_PLE_DFI_DATA_MASK,
.srt = 0x80010000,
.end = 0x8001000A,
+ .inc_num = 1,
.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_PLE_DFI_DATA_MASK
@@ -2528,6 +2656,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pagellt = {
.sel_msk = B_AX_PLE_DFI_DATA_MASK,
.srt = 0x80020000,
.end = 0x80020DBF,
+ .inc_num = 1,
.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_PLE_DFI_DATA_MASK
@@ -2539,6 +2668,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pktinfo = {
.sel_msk = B_AX_PLE_DFI_DATA_MASK,
.srt = 0x80030000,
.end = 0x80030DBF,
+ .inc_num = 1,
.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_PLE_DFI_DATA_MASK
@@ -2550,6 +2680,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_prepkt = {
.sel_msk = B_AX_PLE_DFI_DATA_MASK,
.srt = 0x80040000,
.end = 0x80040DBF,
+ .inc_num = 1,
.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_PLE_DFI_DATA_MASK
@@ -2561,6 +2692,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_nxtpkt = {
.sel_msk = B_AX_PLE_DFI_DATA_MASK,
.srt = 0x80050000,
.end = 0x80050DBF,
+ .inc_num = 1,
.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_PLE_DFI_DATA_MASK
@@ -2572,6 +2704,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qlnktbl = {
.sel_msk = B_AX_PLE_DFI_DATA_MASK,
.srt = 0x80060000,
.end = 0x80060041,
+ .inc_num = 1,
.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_PLE_DFI_DATA_MASK
@@ -2583,6 +2716,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qempty = {
.sel_msk = B_AX_PLE_DFI_DATA_MASK,
.srt = 0x80070000,
.end = 0x80070001,
+ .inc_num = 1,
.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_PLE_DFI_DATA_MASK
@@ -2594,6 +2728,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pktinfo = {
.sel_msk = B_AX_DFI_DATA_MASK,
.srt = 0x80000000,
.end = 0x8000017f,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_FUN_INTF_DATA,
.rd_byte = 4,
.rd_msk = B_AX_DFI_DATA_MASK
@@ -2605,6 +2740,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_txdma = {
.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x03,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2616,6 +2752,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_rxdma = {
.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x04,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2627,6 +2764,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cvt = {
.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x01,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2638,6 +2776,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cxpl = {
.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x05,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2649,6 +2788,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_io = {
.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x05,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2660,6 +2800,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc = {
.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
.srt = 0x00,
.end = 0x06,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -2671,6 +2812,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc2 = {
.sel_msk = B_AX_DBG_SEL0,
.srt = 0x34,
.end = 0x3C,
+ .inc_num = 1,
.rd_addr = R_AX_DBG_PORT_SEL,
.rd_byte = 4,
.rd_msk = B_AX_DEBUG_ST_MASK
@@ -3220,6 +3362,31 @@ rtw89_debug_mac_dbg_port_sel(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
p += scnprintf(p, end - p,
"Enable Dispatcher flow control dump.\n");
break;
+ case RTW89_DBG_PORT_SEL_TXPKTCTRL_FETPKT:
+ info = &dbg_port_txpktctrl_fetpkt;
+ p += scnprintf(p, end - p,
+ "Enable txpktctrl fetpkt dump.\n");
+ break;
+ case RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_CMDPSR:
+ info = &dbg_port_txpktctrl_b0_cmdpsr;
+ p += scnprintf(p, end - p,
+ "Enable txpktctrl b0 cmdpsr dump.\n");
+ break;
+ case RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_CMACDMAIF:
+ info = &dbg_port_txpktctrl_b0_cmacdmaif;
+ p += scnprintf(p, end - p,
+ "Enable txpktctrl b0 cmacdmaif dump.\n");
+ break;
+ case RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT0_0:
+ info = &dbg_port_txpktctrl_b0_unit0_0;
+ p += scnprintf(p, end - p,
+ "Enable txpktctrl b0 unit0_0 dump.\n");
+ break;
+ case RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT0_1:
+ info = &dbg_port_txpktctrl_b0_unit0_1;
+ p += scnprintf(p, end - p,
+ "Enable txpktctrl b0 unit0_1 dump.\n");
+ break;
case RTW89_DBG_PORT_SEL_PCIE_TXDMA:
info = &dbg_port_pcie_txdma;
val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
@@ -3420,6 +3587,11 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,
case_DBG_SEL(DSPT_WDE_INTF);
case_DBG_SEL(DSPT_PLE_INTF);
case_DBG_SEL(DSPT_FLOW_CTRL);
+ case_DBG_SEL(TXPKTCTRL_FETPKT);
+ case_DBG_SEL(TXPKTCTRL_B0_CMDPSR);
+ case_DBG_SEL(TXPKTCTRL_B0_CMACDMAIF);
+ case_DBG_SEL(TXPKTCTRL_B0_UNIT0_0);
+ case_DBG_SEL(TXPKTCTRL_B0_UNIT0_1);
case_DBG_SEL(PCIE_TXDMA);
case_DBG_SEL(PCIE_RXDMA);
case_DBG_SEL(PCIE_CVT);
@@ -3434,7 +3606,7 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,
p += scnprintf(p, end - p, "Sel addr = 0x%X\n", info->sel_addr);
p += scnprintf(p, end - p, "Read addr = 0x%X\n", info->rd_addr);
- for (i = info->srt; i <= info->end; i++) {
+ for (i = info->srt; i <= info->end; i += info->inc_num) {
switch (info->sel_byte) {
case 1:
default:
@@ -3503,6 +3675,40 @@ static int rtw89_debug_mac_dump_dbg_port(struct rtw89_dev *rtwdev,
return p - buf;
}
+#define CHUNK 512
+void rtw89_debug_mac_dbg_port_dump_printk(struct rtw89_dev *rtwdev)
+{
+ size_t total_len, print_len, i;
+ size_t pos = 0, n, end;
+ char tmp[CHUNK + 1];
+ char *buf, *p;
+
+ buf = kzalloc(0x100000, GFP_KERNEL);
+ p = buf;
+
+ p += rtw89_debug_mac_dump_dbg_port(rtwdev, p, buf + 0x100000 - p);
+ total_len = p - buf;
+
+ while (pos < total_len) {
+ n = min(CHUNK, total_len - pos);
+ end = pos + n;
+
+ for (i = end; i > pos; i--) {
+ if (buf[i - 1] == '\n') {
+ end = i;
+ break;
+ }
+ }
+
+ print_len = end - pos;
+ memcpy(tmp, buf + pos, print_len);
+ tmp[print_len] = '\0';
+
+ printk("%s", tmp);
+ pos = end;
+ }
+}
+
static ssize_t
rtw89_debug_priv_mac_dbg_port_dump_get(struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h
index f53d8acbd0d2..4fd77880cdb6 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.h
+++ b/drivers/net/wireless/realtek/rtw89/debug.h
@@ -99,4 +99,5 @@ static inline bool rtw89_debug_is_enabled(struct rtw89_dev *rtwdev,
}
#endif
+void rtw89_debug_mac_dbg_port_dump_printk(struct rtw89_dev *rtwdev);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 2cbff2be9bbb..7b426cafeffb 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -39,6 +39,36 @@ static const u32 rtw89_mac_mem_base_addrs_ax[RTW89_MAC_MEM_NUM] = {
[RTW89_MAC_MEM_TXD_FIFO_1_V1] = TXD_FIFO_1_BASE_ADDR_V1,
};
+static const struct rtw89_reg_dump mac_cmac_cr_ax[] = {
+ {"CMAC common", CMAC_AX_COMMON_BASE_ADDR, CMAC_AX_COMMON_MAX_ADDR},
+ {"Scheduler", CMAC_AX_SCH_BASE_ADDR, CMAC_AX_SCH_MAX_ADDR},
+ {"PTCL", CMAC_AX_PTCL_BASE_ADDR, CMAC_AX_PTCL_MAX_ADDR},
+ {"CDMA", CMAC_AX_CDMA_BASE_ADDR, CMAC_AX_CDMA_MAX_ADDR},
+ {"TMAC", CMAC_AX_TMAC_BASE_ADDR, CMAC_AX_TMAC_MAX_ADDR},
+ {"TRXPTCL", CMAC_AX_TRXPTCL_BASE_ADDR, CMAC_AX_TRXPTCL_MAX_ADDR},
+ {"RMAC", CMAC_AX_RMAC_BASE_ADDR, CMAC_AX_RMAC_MAX_ADDR},
+ {"PWR", CMAC_AX_PWR_BASE_ADDR, CMAC_AX_PWR_MAX_ADDR},
+ {"BTCOEX", CMAC_AX_BTCOEX_BASE_ADDR, CMAC_AX_BTCOEX_MAX_ADDR}
+};
+
+static const struct rtw89_reg_dump mac_dmac_cr_ax[] = {
+ {"TOP OFF", DMAC_AX_TOP_OFF_BASE_ADDR, DMAC_AX_TOP_OFF_MAX_ADDR},
+ {"WL PON", DMAC_AX_WL_PON_BASE_ADDR, DMAC_AX_WL_PON_MAX_ADDR},
+ {"COMMON", DMAC_AX_COMMON_BASE_ADDR, DMAC_AX_COMMON_MAX_ADDR},
+ {"Dispatcher", DMAC_AX_DISPATCHER_BASE_ADDR, DMAC_AX_DISPATCHER_MAX_ADDR},
+ {"WDE", DMAC_AX_WDE_BASE_ADDR, DMAC_AX_WDE_MAX_ADDR},
+ {"PLE", DMAC_AX_PLE_BASE_ADDR, DMAC_AX_PLE_MAX_ADDR},
+ {"WDRLS", DMAC_AX_WDRLS_BASE_ADDR, DMAC_AX_WDRLS_MAX_ADDR},
+ {"BBRPT", DMAC_AX_BBRPT_BASE_ADDR, DMAC_AX_BBRPT_MAX_ADDR},
+ {"CPUIO", DMAC_AX_CPUIO_BASE_ADDR, DMAC_AX_CPUIO_MAX_ADDR},
+ {"PLTIN", DMAC_AX_PKTIN_BASE_ADDR, DMAC_AX_PKTIN_MAX_ADDR},
+ {"MPDU Processor", DMAC_AX_MPDU_BASE_ADDR, DMAC_AX_MPDU_MAX_ADDR},
+ {"SEC ENG", DMAC_AX_SEC_BASE_ADDR, DMAC_AX_SEC_MAX_ADDR},
+ {"STA scheduler", DMAC_AX_SS_BASE_ADDR, DMAC_AX_SS_MAX_ADDR},
+ {"Tx packet control", DMAC_AX_TXPKTCTL_BASE_ADDR, DMAC_AX_TXPKTCTL_MAX_ADDR},
+ {"HCI Common", DMAC_AX_HCI_BASE_ADDR, DMAC_AX_HCI_MAX_ADDR}
+};
+
static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset,
u32 val, enum rtw89_mac_mem_sel sel)
{
@@ -59,6 +89,163 @@ static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset,
return rtw89_read32(rtwdev, mac->indir_access_addr);
}
+u32 rtw89_mac_get_mem_size(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_mem_sel sel)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u32 size;
+
+ switch (sel) {
+ case RTW89_MAC_MEM_AXIDMA:
+ size = AXIDMA_REG_SIZE;
+ break;
+ case RTW89_MAC_MEM_SHARED_BUF:
+ size = chip->fifo_size;
+ break;
+ case RTW89_MAC_MEM_DMAC_TBL:
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
+ size = DCTL_INFO_SIZE_V2 * RTW89_MAX_MAC_ID_NUM;
+ } else {
+ if (chip->chip_id == RTL8852C)
+ size = DCTL_INFO_SIZE_V1 * RTW89_MAX_MAC_ID_NUM;
+ else
+ size = DCTL_INFO_SIZE * RTW89_MAX_MAC_ID_NUM;
+ }
+ break;
+ case RTW89_MAC_MEM_SHCUT_MACHDR:
+ size = MACHDR_SIZE * RTW89_MAX_MAC_ID_NUM;
+ break;
+ case RTW89_MAC_MEM_STA_SCHED:
+ size = STA_SCHED_MEM_SIZE;
+ break;
+ case RTW89_MAC_MEM_RXPLD_FLTR_CAM:
+ size = RXPLD_FLTR_CAM_MEM_SIZE;
+ break;
+ case RTW89_MAC_MEM_SECURITY_CAM:
+ size = SECURITY_CAM_MEM_SIZE;
+ break;
+ case RTW89_MAC_MEM_WOW_CAM:
+ size = WOW_CAM_MEM_SIZE;
+ break;
+ case RTW89_MAC_MEM_CMAC_TBL:
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ size = CCTL_INFO_SIZE_BE * RTW89_MAX_MAC_ID_NUM;
+ else
+ size = CCTL_INFO_SIZE_AX * RTW89_MAX_MAC_ID_NUM;
+ break;
+ case RTW89_MAC_MEM_ADDR_CAM:
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ size = ADDR_CAM_MEM_SIZE_BE;
+ else
+ size = ADDR_CAM_MEM_SIZE_AX;
+ break;
+ case RTW89_MAC_MEM_BA_CAM:
+ size = BA_CAM_SIZE << BA_CAM_NUM_SH;
+ break;
+ case RTW89_MAC_MEM_BCN_IE_CAM0:
+ case RTW89_MAC_MEM_BCN_IE_CAM1:
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ size = BCN_IE_CAM_SIZE * BCN_IE_CAM_NUM_BE;
+ else
+ size = BCN_IE_CAM_SIZE * BCN_IE_CAM_NUM_AX;
+ break;
+ case RTW89_MAC_MEM_TXD_FIFO_0:
+ case RTW89_MAC_MEM_TXD_FIFO_1:
+ case RTW89_MAC_MEM_TXD_FIFO_0_V1:
+ case RTW89_MAC_MEM_TXD_FIFO_1_V1:
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ size = TXD_FIFO_SIZE_BE;
+ else
+ size = TXD_FIFO_SIZE_AX;
+ break;
+ case RTW89_MAC_MEM_TXDATA_FIFO_0:
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ size = TXDATA_FIFO_0_SIZE_BE;
+ else
+ size = TXDATA_FIFO_0_SIZE_AX;
+ break;
+ case RTW89_MAC_MEM_TXDATA_FIFO_1:
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ size = TXDATA_FIFO_1_SIZE_BE;
+ else
+ size = TXDATA_FIFO_1_SIZE_AX;
+ break;
+ default:
+ size = 0;
+ break;
+ }
+
+ return size;
+}
+
+static u32 __dump_mac_mem(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_mem_sel sel,
+ u32 offset, u32 len)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u32 base_addr, strt_pg, residue, val;
+ int cnt, i;
+ u32 filter_model_addr = mac->filter_model_addr;
+ u32 indir_access_entry = mac->indir_access_addr;
+ u32 mem_page_size = mac->mem_page_size;
+
+ if (sel >= RTW89_MAC_MEM_NUM)
+ return -ENOENT;
+
+ strt_pg = offset / mem_page_size;
+ residue = offset % mem_page_size;
+ base_addr = mac->mem_base_addrs[sel];
+ base_addr += strt_pg * mem_page_size;
+
+ cnt = 0;
+ while (cnt < len) {
+ rtw89_write32(rtwdev, filter_model_addr, base_addr);
+ for (i = indir_access_entry + residue;
+ i < indir_access_entry + mem_page_size;
+ i += 4) {
+ val = rtw89_read32(rtwdev, i);
+ rtw89_info(rtwdev, "%08x: %08x\n",
+ base_addr + i - indir_access_entry,
+ val);
+ cnt += 4;
+ if (cnt >= len)
+ break;
+ }
+
+ residue = 0;
+ base_addr += mem_page_size;
+ }
+
+ return 0;
+}
+
+u32 rtw89_mac_mem_dump(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_mem_sel sel,
+ u32 strt_addr, u32 len)
+{
+ u32 ret;
+ u32 size;
+
+ if (!IS_ALIGNED(len, 4)) {
+ rtw89_err(rtwdev, "not 4byte alignment\n");
+ return -EINVAL;
+ }
+
+ size = rtw89_mac_get_mem_size(rtwdev, sel);
+ if (len > size) {
+ rtw89_err(rtwdev, "len %d over max mem size %d\n", len, size);
+ return -EINVAL;
+ }
+
+ ret = __dump_mac_mem(rtwdev, sel, strt_addr, len);
+ if (ret) {
+ rtw89_err(rtwdev, "dump mac memory\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int rtw89_mac_check_mac_en_ax(struct rtw89_dev *rtwdev, u8 mac_idx,
enum rtw89_mac_hwmod_sel sel)
{
@@ -746,17 +933,97 @@ static void rtw89_mac_dump_cmac_err_status_ax(struct rtw89_dev *rtwdev,
rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset));
}
+u32 chk_ser_level(enum mac_ax_err_info err)
+{
+ if (err == MAC_AX_ERR_CPU_EXCEPTION ||
+ err == MAC_AX_ERR_ASSERTION ||
+ err == MAC_AX_ERR_RXI300) {
+ return MAC_AX_SER_L2;
+ } else if (err == MAC_AX_ERR_L1_ERR_DMAC ||
+ err == MAC_AX_ERR_L0_PROMOTE_TO_L1) {
+ return MAC_AX_SER_L1;
+ } else if (err == MAC_AX_ERR_L0_ERR_CMAC0 ||
+ err == MAC_AX_ERR_L0_ERR_CMAC1) {
+ return MAC_AX_SER_L0;
+ } else if (err == MAC_AX_HALT_C2H_L1_DBG_MODE ||
+ err == MAC_AX_ERR_L0_PROMOTE_TO_L1_DBG) {
+ return MAC_AX_SER_L1_DBG;
+ }
+
+ return MAC_AX_SER_LAST;
+}
+EXPORT_SYMBOL(chk_ser_level);
+
+static void rtw89_dump_cmac_cr_ax(struct rtw89_dev *rtwdev, u8 band)
+{
+ const struct rtw89_reg_dump *dump;
+ int ret, i, offset;
+ u32 base_addr;
+
+ ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
+ if (ret) {
+ rtw89_info(rtwdev, "[CMAC] : CMAC%d not enabled\n", band);
+ return;
+ }
+
+ rtw89_info(rtwdev, "Dump CMAC band %d\n", band);
+ for (i = 0; i < ARRAY_SIZE(mac_cmac_cr_ax); i++) {
+ dump = &mac_cmac_cr_ax[i];
+ rtw89_info(rtwdev, "%s\n", dump->name);
+ base_addr = dump->base_addr;
+ if (band)
+ base_addr = dump->base_addr + RTW89_MAC_AX_BAND_REG_OFFSET;
+ for (offset = 0; offset <= dump->max_addr; offset += 4)
+ rtw89_info(rtwdev, "0x186%05x = 0x%08x\n",
+ base_addr + offset,
+ rtw89_read32(rtwdev, base_addr + offset));
+ }
+}
+
+static void rtw89_dump_dmac_cr_ax(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_reg_dump *dump;
+ int i, offset;
+
+ rtw89_info(rtwdev, "Dump DMAC\n");
+ for (i = 0; i < ARRAY_SIZE(mac_dmac_cr_ax); i++) {
+ dump = &mac_dmac_cr_ax[i];
+ rtw89_info(rtwdev, "%s\n", dump->name);
+ for (offset = 0; offset <= dump->max_addr; offset += 4)
+ rtw89_info(rtwdev, "0x1860%04x = 0x%08x\n",
+ dump->base_addr + offset,
+ rtw89_read32(rtwdev, dump->base_addr + offset));
+ }
+}
+
+static void rtw89_mac_dbg_mode_dump_ax(struct rtw89_dev *rtwdev)
+{
+ u32 size;
+
+ rtw89_dump_dmac_cr_ax(rtwdev);
+ rtw89_dump_cmac_cr_ax(rtwdev, RTW89_MAC_0);
+ rtw89_dump_cmac_cr_ax(rtwdev, RTW89_MAC_1);
+
+ rtw89_info(rtwdev, "SHARE BUF DUMP:\n");
+ size = rtw89_mac_get_mem_size(rtwdev, RTW89_MAC_MEM_SHARED_BUF);
+ rtw89_mac_mem_dump(rtwdev, RTW89_MAC_MEM_SHARED_BUF, 0x0, size);
+
+ rtw89_debug_mac_dbg_port_dump_printk(rtwdev);
+
+ rtw89_write32_set(rtwdev, R_AX_UDM3, BIT(0));
+}
+
static void rtw89_mac_dump_err_status_ax(struct rtw89_dev *rtwdev,
enum mac_ax_err_info err)
{
- if (err != MAC_AX_ERR_L1_ERR_DMAC &&
- err != MAC_AX_ERR_L0_PROMOTE_TO_L1 &&
- err != MAC_AX_ERR_L0_ERR_CMAC0 &&
- err != MAC_AX_ERR_L0_ERR_CMAC1 &&
- err != MAC_AX_ERR_RXI300)
- return;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ int err_level;
rtw89_info(rtwdev, "--->\nerr=0x%x\n", err);
+ err_level = chk_ser_level(err);
+ if (err_level == MAC_AX_SER_LAST)
+ return;
+
rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n",
rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n",
@@ -775,6 +1042,11 @@ static void rtw89_mac_dump_err_status_ax(struct rtw89_dev *rtwdev,
if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1)
rtw89_mac_dump_l0_to_l1(rtwdev, err);
+ if (err_level == MAC_AX_SER_L0 ||
+ err_level == MAC_AX_SER_L1_DBG ||
+ err_level == MAC_AX_SER_L2) {
+ mac->dbg_mode_dump(rtwdev);
+ }
rtw89_info(rtwdev, "<---\n");
}
@@ -4423,7 +4695,7 @@ static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
return;
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
- CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE);
+ CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE_AX);
rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4);
rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 4, 0x400A0004);
rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 8, 0);
@@ -7447,6 +7719,36 @@ void rtw89_fwdl_secure_idmem_share_mode_ax(struct rtw89_dev *rtwdev, u8 mode)
B_AX_IDMEM_SHARE_MODE_RECORD_VALID);
}
+int rtw89_mac_set_l0_dbg_mode(struct rtw89_dev *rtwdev)
+{
+ int ret, val;
+
+ rtw89_write32_set(rtwdev, R_AX_HALT_H2C, MAC_AX_L0_DBG_MODE);
+ rtw89_write32_set(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER);
+
+ ret = read_poll_timeout(rtw89_read32, val, val == 0,
+ 50, 200, false, rtwdev, R_AX_HALT_C2H_CTRL);
+ if (ret)
+ rtw89_err(rtwdev, "[ERR]Polling FW err status fail\n");
+
+ return ret;
+}
+
+int rtw89_mac_set_l1_dbg_mode(struct rtw89_dev *rtwdev)
+{
+ int ret, val;
+
+ rtw89_write32_set(rtwdev, R_AX_HALT_H2C, MAC_AX_L1_DBG_MODE);
+ rtw89_write32_set(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER);
+
+ ret = read_poll_timeout(rtw89_read32, val, val == 0,
+ 50, 200, false, rtwdev, R_AX_HALT_C2H_CTRL);
+ if (ret)
+ rtw89_err(rtwdev, "[ERR]Polling FW err status fail\n");
+
+ return ret;
+}
+
const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET,
.filter_model_addr = R_AX_FILTER_MODEL_ADDR,
@@ -7545,5 +7847,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.scan_offload = rtw89_fw_h2c_scan_offload_ax,
.wow_config_mac = rtw89_wow_config_mac_ax,
+
+ .dbg_mode_dump = rtw89_mac_dbg_mode_dump_ax,
};
EXPORT_SYMBOL(rtw89_mac_gen_ax);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 493d2b9626a6..079d6cf6b97c 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -237,7 +237,6 @@ enum rtw89_mac_dbg_port_sel {
RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT,
RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL,
RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY,
- RTW89_DBG_PORT_SEL_PKTINFO,
/* DISPATCHER related */
RTW89_DBG_PORT_SEL_DSPT_HDT_TX0,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX1,
@@ -283,6 +282,37 @@ enum rtw89_mac_dbg_port_sel {
RTW89_DBG_PORT_SEL_DSPT_WDE_INTF,
RTW89_DBG_PORT_SEL_DSPT_PLE_INTF,
RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL,
+ /* TXPKT_CTRL related */
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_FETPKT,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_CMDPSR,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_CMACDMAIF,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_PRELD0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_PRELD1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT0_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT0_1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT1_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT1_1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT2_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT2_1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT3_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT3_1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT4_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT4_1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT5_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT5_1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT6_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT6_1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT7_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B0_UNIT7_1,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B1_CMDPSR,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B1_CMACDMAIF,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B1_UNIT0_0,
+ RTW89_DBG_PORT_SEL_TXPKTCTRL_B1_UNIT0_1,
+ RTW89_DBG_PORT_SEL_PKTINFO,
+ RTW89_DBG_PORT_SEL_MPDUINFO_B0,
+ RTW89_DBG_PORT_SEL_MPDUINFO_B1,
+ RTW89_DBG_PORT_SEL_PRELD_B0,
+ RTW89_DBG_PORT_SEL_PRELD_B1,
/* PCIE related */
RTW89_DBG_PORT_SEL_PCIE_TXDMA,
RTW89_DBG_PORT_SEL_PCIE_RXDMA,
@@ -350,7 +380,167 @@ enum rtw89_mac_dbg_port_sel {
#define TXD_FIFO_1_BASE_ADDR_BE 0x18881800
#define DCPU_LOCAL_BASE_ADDR_BE 0x19C02000
-#define CCTL_INFO_SIZE 32
+#define CCTL_INFO_SIZE_AX 32
+#define CCTL_INFO_SIZE_BE 64
+#define DCTL_INFO_SIZE 16
+#define DCTL_INFO_SIZE_V1 32
+#define DCTL_INFO_SIZE_V2 64
+#define MACHDR_SIZE 56
+#define BA_CAM_SIZE 64
+#define BA_CAM_NUM_SH 3
+#define BCN_IE_CAM_SIZE 8
+#define BCN_IE_CAM_NUM_AX 12
+#define BCN_IE_CAM_NUM_BE 24
+#define AXIDMA_REG_SIZE 0x1000
+#define STA_SCHED_MEM_SIZE 0x1200
+#define RXPLD_FLTR_CAM_MEM_SIZE 0x200
+#define SECURITY_CAM_MEM_SIZE 0x800
+#define WOW_CAM_MEM_SIZE 0x240
+#define ADDR_CAM_MEM_SIZE_AX 0x4000
+#define ADDR_CAM_MEM_SIZE_BE 0x8000
+#define TXD_FIFO_SIZE_AX 0x200
+#define TXD_FIFO_SIZE_BE 0x400
+#define TXDATA_FIFO_0_SIZE_AX 0x200
+#define TXDATA_FIFO_1_SIZE_AX 0x80
+#define TXDATA_FIFO_0_SIZE_BE 0x1000
+#define TXDATA_FIFO_1_SIZE_BE 0x800
+
+#define SHARE_BUFFER_SIZE_8852A 0x70000
+#define SHARE_BUFFER_SIZE_8852B 0x30000
+#define SHARE_BUFFER_SIZE_8852C 0x70000
+#define SHARE_BUFFER_SIZE_8851B 0x30000
+#define SHARE_BUFFER_SIZE_8922A 0x90000
+
+#define CMAC_AX_COMMON_BASE_ADDR 0xC000
+#define CMAC_AX_COMMON_BASE_ADDR_C1 0xE000
+#define CMAC_AX_COMMON_MAX_ADDR 0x1FC
+#define CMAC_AX_SCH_BASE_ADDR 0xC200
+#define CMAC_AX_SCH_BASE_ADDR_C1 0xE200
+#define CMAC_AX_SCH_MAX_ADDR 0x3FC
+#define CMAC_AX_PTCL_BASE_ADDR 0xC600
+#define CMAC_AX_PTCL_BASE_ADDR_C1 0xE600
+#define CMAC_AX_PTCL_MAX_ADDR 0x1FC
+#define CMAC_AX_CDMA_BASE_ADDR 0xC800
+#define CMAC_AX_CDMA_BASE_ADDR_C1 0xE800
+#define CMAC_AX_CDMA_MAX_ADDR 0x2FC
+#define CMAC_AX_TMAC_BASE_ADDR 0xCA00
+#define CMAC_AX_TMAC_BASE_ADDR_C1 0xEA00
+#define CMAC_AX_TMAC_MAX_ADDR 0xFC
+#define CMAC_AX_TRXPTCL_BASE_ADDR 0xCC00
+#define CMAC_AX_TRXPTCL_BASE_ADDR_C1 0xEC00
+#define CMAC_AX_TRXPTCL_MAX_ADDR 0x1FC
+#define CMAC_AX_RMAC_BASE_ADDR 0xCE00
+#define CMAC_AX_RMAC_BASE_ADDR_C1 0xEE00
+#define CMAC_AX_RMAC_MAX_ADDR 0x1FC
+#define CMAC_AX_PWR_BASE_ADDR 0xD200
+#define CMAC_AX_PWR_BASE_ADDR_C1 0xF200
+#define CMAC_AX_PWR_MAX_ADDR 0x7FC
+#define CMAC_AX_BTCOEX_BASE_ADDR 0xDA00
+#define CMAC_AX_BTCOEX_BASE_ADDR_C1 0xFA00
+#define CMAC_AX_BTCOEX_MAX_ADDR 160
+
+#define DMAC_AX_TOP_OFF_BASE_ADDR 0x7000
+#define DMAC_AX_TOP_OFF_MAX_ADDR 0x2FC
+#define DMAC_AX_WL_PON_BASE_ADDR 0x7800
+#define DMAC_AX_WL_PON_MAX_ADDR 0x154
+#define DMAC_AX_COMMON_BASE_ADDR 0x8400
+#define DMAC_AX_COMMON_MAX_ADDR 0x3FC
+#define DMAC_AX_DISPATCHER_BASE_ADDR 0x8800
+#define DMAC_AX_DISPATCHER_MAX_ADDR 0x15C
+#define DMAC_AX_WDE_BASE_ADDR 0x8C00
+#define DMAC_AX_WDE_MAX_ADDR 0x18C
+#define DMAC_AX_PLE_BASE_ADDR 0x9000
+#define DMAC_AX_PLE_MAX_ADDR 0x13C
+#define DMAC_AX_WDRLS_BASE_ADDR 0x9400
+#define DMAC_AX_WDRLS_MAX_ADDR 0x7C
+#define DMAC_AX_BBRPT_BASE_ADDR 0x9600
+#define DMAC_AX_BBRPT_MAX_ADDR 0x8C
+#define DMAC_AX_CPUIO_BASE_ADDR 0x9800
+#define DMAC_AX_CPUIO_MAX_ADDR 0x8C
+#define DMAC_AX_PKTIN_BASE_ADDR 0x9A00
+#define DMAC_AX_PKTIN_MAX_ADDR 0x48
+#define DMAC_AX_MPDU_BASE_ADDR 0x9B00
+#define DMAC_AX_MPDU_MAX_ADDR 0x1FC
+#define DMAC_AX_SEC_BASE_ADDR 0x9D00
+#define DMAC_AX_SEC_MAX_ADDR 0xFC
+#define DMAC_AX_SS_BASE_ADDR 0x9E00
+#define DMAC_AX_SS_MAX_ADDR 0xFC
+#define DMAC_AX_TXPKTCTL_BASE_ADDR 0x9F00
+#define DMAC_AX_TXPKTCTL_MAX_ADDR 0xFC
+#define DMAC_AX_HCI_BASE_ADDR 0x6000
+#define DMAC_AX_HCI_MAX_ADDR 0xFC
+
+#define CMAC_BE_COMMON_BASE_ADDR 0x10000
+#define CMAC_BE_COMMON_BASE_ADDR_C1 0x14000
+#define CMAC_BE_COMMON_MAX_ADDR 0x1FC
+#define CMAC_BE_SCH_BASE_ADDR 0x10200
+#define CMAC_BE_SCH_BASE_ADDR_C1 0x14200
+#define CMAC_BE_SCH_MAX_ADDR 0x3FC
+#define CMAC_BE_PTCL_BASE_ADDR 0x10800
+#define CMAC_BE_PTCL_BASE_ADDR_C1 0x14800
+#define CMAC_BE_PTCL_MAX_ADDR 0x3FC
+#define CMAC_BE_CDMA_BASE_ADDR 0x10C00
+#define CMAC_BE_CDMA_BASE_ADDR_C1 0x14C00
+#define CMAC_BE_CDMA_MAX_ADDR 0xF0
+#define CMAC_BE_TMAC_BASE_ADDR 0x10E00
+#define CMAC_BE_TMAC_BASE_ADDR_C1 0x14E00
+#define CMAC_BE_TMAC_MAX_ADDR 0xFC
+#define CMAC_BE_TRXPTCL_BASE_ADDR 0x11000
+#define CMAC_BE_TRXPTCL_BASE_ADDR_C1 0x15000
+#define CMAC_BE_TRXPTCL_MAX_ADDR 0x2E0
+#define CMAC_BE_RMAC_BASE_ADDR 0x11400
+#define CMAC_BE_RMAC_BASE_ADDR_C1 0x15400
+#define CMAC_BE_RMAC_MAX_ADDR 0x1FF
+#define CMAC_BE_RESP_PKTCTL_BASE_ADDR 0x11800
+#define CMAC_BE_RESP_PKTCTL_BASE_ADDR_C1 0x15800
+#define CMAC_BE_RESP_PKTCTL_MAX_ADDR 0xFC
+#define CMAC_BE_PWR_BASE_ADDR 0x11900
+#define CMAC_BE_PWR_BASE_ADDR_C1 0x15900
+#define CMAC_BE_PWR_MAX_ADDR 0x53C
+#define CMAC_BE_TXPWR_BASE_ADDR 0x12880
+#define CMAC_BE_TXPWR_BASE_ADDR_C1 0x16880
+#define CMAC_BE_TXPWR_MAX_ADDR 0x7C
+#define CMAC_BE_BTCOEX_BASE_ADDR 0xE300
+#define CMAC_BE_BTCOEX_BASE_ADDR_C1 0xE400
+#define CMAC_BE_BTCOEX_MAX_ADDR 160
+
+#define DMAC_BE_TOP_OFF_BASE_ADDR 0x7000
+#define DMAC_BE_TOP_OFF_MAX_ADDR 0x2FC
+#define DMAC_BE_WL_PON_BASE_ADDR 0x7800
+#define DMAC_BE_WL_PON_MAX_ADDR 0x154
+#define DMAC_BE_COMMON_BASE_ADDR 0x8400
+#define DMAC_BE_COMMON_MAX_ADDR 0x3FC
+#define DMAC_BE_DISPATCHER_BASE_ADDR 0x8800
+#define DMAC_BE_DISPATCHER_MAX_ADDR 0x15C
+#define DMAC_BE_WDE_BASE_ADDR 0x8C00
+#define DMAC_BE_WDE_MAX_ADDR 0x18C
+#define DMAC_BE_PLE_BASE_ADDR 0x9000
+#define DMAC_BE_PLE_MAX_ADDR 0x13C
+#define DMAC_BE_WDRLS_BASE_ADDR 0x9400
+#define DMAC_BE_WDRLS_MAX_ADDR 0x7C
+#define DMAC_BE_PLRLS_BASE_ADDR 0xA200
+#define DMAC_BE_PLRLS_MAX_ADDR 0x1C
+#define DMAC_BE_BBRPT_BASE_ADDR 0x9600
+#define DMAC_BE_BBRPT_MAX_ADDR 0x8C
+#define DMAC_BE_CPUIO_BASE_ADDR 0x9800
+#define DMAC_BE_CPUIO_MAX_ADDR 0x8C
+#define DMAC_BE_PKTIN_BASE_ADDR 0x9A00
+#define DMAC_BE_PKTIN_MAX_ADDR 0x48
+#define DMAC_BE_MPDU_BASE_ADDR 0x9B00
+#define DMAC_BE_MPDU_MAX_ADDR 0x1FC
+#define DMAC_BE_SEC_BASE_ADDR 0x9D00
+#define DMAC_BE_SEC_MAX_ADDR 0xFC
+#define DMAC_BE_SS_BASE_ADDR 0xA300
+#define DMAC_BE_SS_MAX_ADDR 0x14C
+#define DMAC_BE_TXPKTCTL_BASE_ADDR 0x9F00
+#define DMAC_BE_TXPKTCTL_MAX_ADDR 0xBC
+#define DMAC_BE_MLO_BASE_ADDR 0xA100
+#define DMAC_BE_MLO_MAX_ADDR 0xDC
+#define DMAC_BE_HCI_BASE_ADDR 0x6000
+#define DMAC_BE_HCI_MAX_ADDR 0xFC
+#define DMAC_BE_HAXIDMA_BASE_ADDR 0xB000
+#define DMAC_BE_HAXIDMA_MAX_ADDR 0x7FC
+
enum rtw89_mac_mem_sel {
RTW89_MAC_MEM_AXIDMA,
@@ -706,6 +896,7 @@ struct rtw89_mac_dbg_port_info {
u32 sel_msk;
u32 srt;
u32 end;
+ u32 inc_num;
u32 rd_addr;
u8 rd_byte;
u32 rd_msk;
@@ -770,6 +961,7 @@ enum mac_ax_err_info {
MAC_AX_ERR_L0_ERR_CMAC1 = 0x0002,
MAC_AX_ERR_L0_RESET_DONE = 0x0003,
MAC_AX_ERR_L0_PROMOTE_TO_L1 = 0x0010,
+ MAC_AX_ERR_L0_PROMOTE_TO_L1_DBG = 0x0011,
/* L1 */
MAC_AX_ERR_L1_PREERR_DMAC = 0x999,
@@ -778,6 +970,7 @@ enum mac_ax_err_info {
MAC_AX_ERR_L1_RESET_RECOVERY_DONE = 0x1002,
MAC_AX_ERR_L1_PROMOTE_TO_L2 = 0x1010,
MAC_AX_ERR_L1_RCVY_STOP_DONE = 0x1011,
+ MAC_AX_HALT_C2H_L1_DBG_MODE = 0x1012,
/* L2 */
/* address hole (master) */
@@ -922,6 +1115,26 @@ enum mac_ax_err_info {
MAC_AX_SET_ERR_MAX,
};
+enum mac_ax_ser_level {
+ MAC_AX_SER_L0 = 0x0,
+ MAC_AX_SER_L1 = 0x1,
+ MAC_AX_SER_L2 = 0x2,
+ MAC_AX_SER_L1_DBG = 0x3,
+ MAC_AX_SER_LAST = 0xF,
+};
+
+struct rtw89_reg_dump {
+ const char *name;
+ u32 base_addr;
+ u32 max_addr;
+};
+
+enum mac_ax_halt_h2c_info {
+ MAC_AX_L0_DBG_MODE = 0x10,
+ MAC_AX_L1_DBG_MODE = 0x17,
+ MAC_AX_RST_DBG_MODE = 0xff
+};
+
struct rtw89_mac_size_set {
const struct rtw89_hfc_prec_cfg hfc_preccfg_pcie;
const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c0;
@@ -1166,6 +1379,7 @@ struct rtw89_mac_gen_def {
bool wowlan);
int (*wow_config_mac)(struct rtw89_dev *rtwdev, bool enable_wow);
+ void (*dbg_mode_dump)(struct rtw89_dev *rtwdev);
};
extern const struct rtw89_mac_gen_def rtw89_mac_gen_ax;
@@ -1390,6 +1604,9 @@ static inline int rtw89_chip_reset_bb_rf(struct rtw89_dev *rtwdev)
return 0;
}
+u32 chk_ser_level(enum mac_ax_err_info err);
+int rtw89_mac_set_l0_dbg_mode(struct rtw89_dev *rtwdev);
+int rtw89_mac_set_l1_dbg_mode(struct rtw89_dev *rtwdev);
u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev);
int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err);
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
@@ -1753,6 +1970,11 @@ int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
enum rtw89_mac_dle_rsvd_qt_type type,
struct rtw89_mac_dle_rsvd_qt_cfg *cfg);
int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable);
+u32 rtw89_mac_get_mem_size(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_mem_sel sel);
+u32 rtw89_mac_mem_dump(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_mem_sel sel,
+ u32 strt_addr, u32 len);
static inline int rtw89_mac_efuse_read_ecv(struct rtw89_dev *rtwdev)
{
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index dfa0973e367c..1e38bcacf682 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -32,6 +32,41 @@ static const u32 rtw89_mac_mem_base_addrs_be[RTW89_MAC_MEM_NUM] = {
[RTW89_MAC_MEM_MLD_TBL] = MLD_TBL_BASE_ADDR_BE,
};
+static const struct rtw89_reg_dump mac_cmac_cr_be[] = {
+ {"CMAC common", CMAC_BE_COMMON_BASE_ADDR, CMAC_BE_COMMON_MAX_ADDR},
+ {"Scheduler", CMAC_BE_SCH_BASE_ADDR, CMAC_BE_SCH_MAX_ADDR},
+ {"PTCL", CMAC_BE_PTCL_BASE_ADDR, CMAC_BE_PTCL_MAX_ADDR},
+ {"CDMA", CMAC_BE_CDMA_BASE_ADDR, CMAC_BE_CDMA_MAX_ADDR},
+ {"TMAC", CMAC_BE_TMAC_BASE_ADDR, CMAC_BE_TMAC_MAX_ADDR},
+ {"TRXPTCL", CMAC_BE_TRXPTCL_BASE_ADDR, CMAC_BE_TRXPTCL_MAX_ADDR},
+ {"RMAC", CMAC_BE_RMAC_BASE_ADDR, CMAC_BE_RMAC_MAX_ADDR},
+ {"RMACRESP_PKTCTL", CMAC_BE_RESP_PKTCTL_BASE_ADDR, CMAC_BE_RESP_PKTCTL_MAX_ADDR},
+ {"PWR", CMAC_BE_PWR_BASE_ADDR, CMAC_BE_PWR_MAX_ADDR},
+ {"TXPWR_CTRL", CMAC_BE_TXPWR_BASE_ADDR, CMAC_BE_TXPWR_MAX_ADDR},
+ {"BTCOEX", CMAC_BE_BTCOEX_BASE_ADDR, CMAC_BE_BTCOEX_MAX_ADDR}
+};
+
+static const struct rtw89_reg_dump mac_dmac_cr_be[] = {
+ {"TOP OFF", DMAC_BE_TOP_OFF_BASE_ADDR, DMAC_BE_TOP_OFF_MAX_ADDR},
+ {"WL PON", DMAC_BE_WL_PON_BASE_ADDR, DMAC_BE_WL_PON_MAX_ADDR},
+ {"COMMON", DMAC_BE_COMMON_BASE_ADDR, DMAC_BE_COMMON_MAX_ADDR},
+ {"Dispatcher", DMAC_BE_DISPATCHER_BASE_ADDR, DMAC_BE_DISPATCHER_MAX_ADDR},
+ {"WDE", DMAC_BE_WDE_BASE_ADDR, DMAC_BE_WDE_MAX_ADDR},
+ {"PLE", DMAC_BE_PLE_BASE_ADDR, DMAC_BE_PLE_MAX_ADDR},
+ {"WDRLS", DMAC_BE_WDRLS_BASE_ADDR, DMAC_BE_WDRLS_MAX_ADDR},
+ {"PLRLS", DMAC_BE_PLRLS_BASE_ADDR, DMAC_BE_PLRLS_MAX_ADDR},
+ {"BBRPT", DMAC_BE_BBRPT_BASE_ADDR, DMAC_BE_BBRPT_MAX_ADDR},
+ {"CPUIO", DMAC_BE_CPUIO_BASE_ADDR, DMAC_BE_CPUIO_MAX_ADDR},
+ {"PLTIN", DMAC_BE_PKTIN_BASE_ADDR, DMAC_BE_PKTIN_MAX_ADDR},
+ {"MPDU Processor", DMAC_BE_MPDU_BASE_ADDR, DMAC_BE_MPDU_MAX_ADDR},
+ {"SEC ENG", DMAC_BE_SEC_BASE_ADDR, DMAC_BE_SEC_MAX_ADDR},
+ {"STA scheduler", DMAC_BE_SS_BASE_ADDR, DMAC_BE_SS_MAX_ADDR},
+ {"Tx packet control", DMAC_BE_TXPKTCTL_BASE_ADDR, DMAC_BE_TXPKTCTL_MAX_ADDR},
+ {"MLO", DMAC_BE_MLO_BASE_ADDR, DMAC_BE_MLO_MAX_ADDR},
+ {"HCI Common", DMAC_BE_HCI_BASE_ADDR, DMAC_BE_HCI_MAX_ADDR},
+ {"H_AXIDMA", DMAC_BE_HAXIDMA_BASE_ADDR, DMAC_BE_HAXIDMA_MAX_ADDR}
+};
+
static const struct rtw89_port_reg rtw89_port_base_be = {
.port_cfg = R_BE_PORT_CFG_P0,
.tbtt_prohib = R_BE_TBTT_PROHIB_P0,
@@ -3171,14 +3206,14 @@ static void rtw89_mac_dump_cmac_err_status_be(struct rtw89_dev *rtwdev,
static void rtw89_mac_dump_err_status_be(struct rtw89_dev *rtwdev,
enum mac_ax_err_info err)
{
- if (err != MAC_AX_ERR_L1_ERR_DMAC &&
- err != MAC_AX_ERR_L0_PROMOTE_TO_L1 &&
- err != MAC_AX_ERR_L0_ERR_CMAC0 &&
- err != MAC_AX_ERR_L0_ERR_CMAC1 &&
- err != MAC_AX_ERR_RXI300)
- return;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ int err_level;
rtw89_info(rtwdev, "--->\nerr=0x%x\n", err);
+ err_level = chk_ser_level(err);
+ if (err_level == MAC_AX_SER_LAST)
+ return;
+
rtw89_info(rtwdev, "R_BE_SER_DBG_INFO=0x%08x\n",
rtw89_read32(rtwdev, R_BE_SER_DBG_INFO));
rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT=0x%08x\n",
@@ -3221,6 +3256,15 @@ static void rtw89_mac_dump_err_status_be(struct rtw89_dev *rtwdev,
if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1)
rtw89_mac_dump_l0_to_l1(rtwdev, err);
+ if (err_level == MAC_AX_SER_L0 ||
+ err_level == MAC_AX_SER_L1_DBG ||
+ err_level == MAC_AX_SER_L2) {
+ if (err_level == MAC_AX_SER_L2)
+ rtw89_write32_set(rtwdev,
+ R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
+ mac->dbg_mode_dump(rtwdev);
+ }
+
rtw89_info(rtwdev, "<---\n");
}
@@ -3269,6 +3313,66 @@ static bool mac_is_txq_empty_be(struct rtw89_dev *rtwdev)
return (val32 & msk32) == msk32;
}
+static void rtw89_dump_cmac_cr_be(struct rtw89_dev *rtwdev, u8 band)
+{
+ const struct rtw89_reg_dump *dump;
+ int ret, i, offset;
+ u32 base_addr;
+
+ ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
+ if (ret) {
+ rtw89_info(rtwdev, "[CMAC] : CMAC%d not enabled\n", band);
+ return;
+ }
+
+ rtw89_info(rtwdev, "Dump CMAC band %d\n", band);
+ for (i = 0; i < ARRAY_SIZE(mac_cmac_cr_be); i++) {
+ dump = &mac_cmac_cr_be[i];
+ rtw89_info(rtwdev, "%s\n", dump->name);
+ base_addr = dump->base_addr;
+ if (band)
+ base_addr = dump->base_addr + RTW89_MAC_BE_BAND_REG_OFFSET;
+ for (offset = 0; offset <= dump->max_addr; offset += 4)
+ rtw89_info(rtwdev, "0x186%05x = 0x%08x\n",
+ base_addr + offset,
+ rtw89_read32(rtwdev, base_addr + offset));
+ }
+}
+
+static void rtw89_dump_dmac_cr_be(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_reg_dump *dump;
+ int i, offset;
+
+ rtw89_info(rtwdev, "Dump DMAC\n");
+ for (i = 0; i < ARRAY_SIZE(mac_dmac_cr_be); i++) {
+ dump = &mac_dmac_cr_be[i];
+ rtw89_info(rtwdev, "%s\n", dump->name);
+ for (offset = 0; offset <= dump->max_addr; offset += 4)
+ rtw89_info(rtwdev, "0x1860%04x = 0x%08x\n",
+ dump->base_addr + offset,
+ rtw89_read32(rtwdev, dump->base_addr + offset));
+ }
+}
+
+static void rtw89_mac_dbg_mode_dump_be(struct rtw89_dev *rtwdev)
+{
+ u32 sram_sel;
+ u32 size;
+
+ rtw89_dump_dmac_cr_be(rtwdev);
+ rtw89_dump_cmac_cr_be(rtwdev, RTW89_MAC_0);
+ rtw89_dump_cmac_cr_be(rtwdev, RTW89_MAC_1);
+
+ for (sram_sel = RTW89_MAC_MEM_AXIDMA;
+ sram_sel < RTW89_MAC_MEM_NUM; sram_sel++) {
+ size = rtw89_mac_get_mem_size(rtwdev, sram_sel);
+ if (size != 0)
+ rtw89_mac_mem_dump(rtwdev, sram_sel, 0x0, size);
+ }
+ rtw89_write32_set(rtwdev, R_AX_UDM3, BIT(0));
+}
+
const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.band1_offset = RTW89_MAC_BE_BAND_REG_OFFSET,
.filter_model_addr = R_BE_FILTER_MODEL_ADDR,
@@ -3367,5 +3471,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.scan_offload = rtw89_fw_h2c_scan_offload_be,
.wow_config_mac = rtw89_wow_config_mac_be,
+
+ .dbg_mode_dump = rtw89_mac_dbg_mode_dump_be,
};
EXPORT_SYMBOL(rtw89_mac_gen_be);
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 756b94dcd475..aa460b80676f 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -6120,6 +6120,14 @@
#define MPDU_INFO_B1_OFST 18
#define MPDU_INFO_TBL_FACTOR 3
+#define R_AX_DBG_CTL_TXPKT 0x9F38
+#define B_AX_TPC_DBG1_SEL_MASK GENMASK(31, 16)
+#define B_AX_TPC_DBG0_SEL_MASK GENMASK(15, 0)
+
+#define R_AX_TPC_DBG_OUT 0x9F3C
+#define B_AX_TPC_DBG1_OUT_MASK GENMASK(31, 16)
+#define B_AX_TPC_DBG0_OUT_MASK GENMASK(15, 0)
+
#define R_BE_TXPKTCTL_B0_PRELD_CFG0 0x9F48
#define B_BE_B0_PRELD_FEN BIT(31)
#define B_BE_B0_PRELD_USEMAXSZ_MASK GENMASK(25, 16)
next prev parent reply other threads:[~2026-11-02 1:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 0:43 rtw89_8852bte (RTL8852BE-VT): recurring SER 0x1000/0x4000/0x1001/0x1002 on fw 0.29.122.1/.2; question on rtw8852bt_fw-1.bin Chris Vitalos
2026-11-02 1:50 ` Ping-Ke Shih [this message]
2026-11-03 0:39 ` Chris Vitalos
2026-11-03 1:18 ` Ping-Ke Shih
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=703ebc52e1d544e590874df041b4d979@realtek.com \
--to=pkshih@realtek.com \
--cc=cvitalos@gmail.com \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox