Commit 60168f6c authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo

wifi: rtw89: mac: generalize code to indirectly access WiFi internal memory

To diagnose abnormal behavior, we need to dump certain internal memory.
For example, dump security CAM when debugging encryption/decryption
problems, or dump BA CAM when debugging abnormal BlockAck.

Since the indirect address and internal memory base address are different
between WiFi 6 and 7 chips, add fields to reuse codes.

Also, only WiFi 6 chips initialize DMAC and CMAC tables via this indirect
interface, so no need to change the constant register address, and
new firmware will help to initialize these tables.
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230822125822.23817-3-pkshih@realtek.com
parent c220d08e
...@@ -795,6 +795,9 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m, ...@@ -795,6 +795,9 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m,
struct rtw89_dev *rtwdev, struct rtw89_dev *rtwdev,
u8 sel, u32 start_addr, u32 len) 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 base_addr, start_page, residue; u32 base_addr, start_page, residue;
u32 i, j, p, pages; u32 i, j, p, pages;
u32 dump_len, remain; u32 dump_len, remain;
...@@ -804,17 +807,17 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m, ...@@ -804,17 +807,17 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m,
pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1; pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1;
start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE;
residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE;
base_addr = rtw89_mac_mem_base_addrs[sel]; base_addr = mac->mem_base_addrs[sel];
base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE;
for (p = 0; p < pages; p++) { for (p = 0; p < pages; p++) {
dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE); dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE);
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, base_addr); rtw89_write32(rtwdev, filter_model_addr, base_addr);
for (i = R_AX_INDIR_ACCESS_ENTRY + residue; for (i = indir_access_addr + residue;
i < R_AX_INDIR_ACCESS_ENTRY + dump_len;) { i < indir_access_addr + dump_len;) {
seq_printf(m, "%08xh:", i); seq_printf(m, "%08xh:", i);
for (j = 0; for (j = 0;
j < 4 && i < R_AX_INDIR_ACCESS_ENTRY + dump_len; j < 4 && i < indir_access_addr + dump_len;
j++, i += 4) { j++, i += 4) {
val = rtw89_read32(rtwdev, i); val = rtw89_read32(rtwdev, i);
seq_printf(m, " %08x", val); seq_printf(m, " %08x", val);
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "reg.h" #include "reg.h"
#include "util.h" #include "util.h"
const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_NUM] = { static const u32 rtw89_mac_mem_base_addrs_ax[RTW89_MAC_MEM_NUM] = {
[RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR, [RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR,
[RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR, [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR,
[RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR, [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR,
...@@ -39,19 +39,21 @@ const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_NUM] = { ...@@ -39,19 +39,21 @@ const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_NUM] = {
static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset, static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset,
u32 val, enum rtw89_mac_mem_sel sel) u32 val, enum rtw89_mac_mem_sel sel)
{ {
u32 addr = rtw89_mac_mem_base_addrs[sel] + offset; const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 addr = mac->mem_base_addrs[sel] + offset;
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, addr); rtw89_write32(rtwdev, mac->filter_model_addr, addr);
rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, val); rtw89_write32(rtwdev, mac->indir_access_addr, val);
} }
static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset, static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset,
enum rtw89_mac_mem_sel sel) enum rtw89_mac_mem_sel sel)
{ {
u32 addr = rtw89_mac_mem_base_addrs[sel] + offset; const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 addr = mac->mem_base_addrs[sel] + offset;
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, addr); rtw89_write32(rtwdev, mac->filter_model_addr, addr);
return rtw89_read32(rtwdev, R_AX_INDIR_ACCESS_ENTRY); return rtw89_read32(rtwdev, mac->indir_access_addr);
} }
int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx, int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx,
...@@ -3661,6 +3663,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) ...@@ -3661,6 +3663,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{ {
u8 i; u8 i;
if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
return;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
DMAC_TBL_BASE_ADDR + (macid << 4) + (i << 2)); DMAC_TBL_BASE_ADDR + (macid << 4) + (i << 2));
...@@ -3670,6 +3675,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) ...@@ -3670,6 +3675,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{ {
if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
return;
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE); CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE);
rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4); rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4);
...@@ -5678,5 +5686,8 @@ int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, ...@@ -5678,5 +5686,8 @@ int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
const struct rtw89_mac_gen_def rtw89_mac_gen_ax = { const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET, .band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET,
.filter_model_addr = R_AX_FILTER_MODEL_ADDR,
.indir_access_addr = R_AX_INDIR_ACCESS_ENTRY,
.mem_base_addrs = rtw89_mac_mem_base_addrs_ax,
}; };
EXPORT_SYMBOL(rtw89_mac_gen_ax); EXPORT_SYMBOL(rtw89_mac_gen_ax);
...@@ -327,8 +327,6 @@ enum rtw89_mac_mem_sel { ...@@ -327,8 +327,6 @@ enum rtw89_mac_mem_sel {
RTW89_MAC_MEM_NUM, RTW89_MAC_MEM_NUM,
}; };
extern const u32 rtw89_mac_mem_base_addrs[];
enum rtw89_rpwm_req_pwr_state { enum rtw89_rpwm_req_pwr_state {
RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE = 0, RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE = 0,
RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFON = 1, RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFON = 1,
...@@ -829,6 +827,9 @@ extern const struct rtw89_mac_size_set rtw89_mac_size; ...@@ -829,6 +827,9 @@ extern const struct rtw89_mac_size_set rtw89_mac_size;
struct rtw89_mac_gen_def { struct rtw89_mac_gen_def {
u32 band1_offset; u32 band1_offset;
u32 filter_model_addr;
u32 indir_access_addr;
const u32 *mem_base_addrs;
}; };
extern const struct rtw89_mac_gen_def rtw89_mac_gen_ax; extern const struct rtw89_mac_gen_def rtw89_mac_gen_ax;
......
...@@ -529,6 +529,9 @@ static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt) ...@@ -529,6 +529,9 @@ static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt)
static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf, static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf,
u8 sel, u32 start_addr, u32 len) 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 *ptr = (u32 *)buf; u32 *ptr = (u32 *)buf;
u32 base_addr, start_page, residue; u32 base_addr, start_page, residue;
u32 cnt = 0; u32 cnt = 0;
...@@ -536,14 +539,14 @@ static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf, ...@@ -536,14 +539,14 @@ static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf,
start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE;
residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE;
base_addr = rtw89_mac_mem_base_addrs[sel]; base_addr = mac->mem_base_addrs[sel];
base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE;
while (cnt < len) { while (cnt < len) {
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, base_addr); rtw89_write32(rtwdev, filter_model_addr, base_addr);
for (i = R_AX_INDIR_ACCESS_ENTRY + residue; for (i = indir_access_addr + residue;
i < R_AX_INDIR_ACCESS_ENTRY + MAC_MEM_DUMP_PAGE_SIZE; i < indir_access_addr + MAC_MEM_DUMP_PAGE_SIZE;
i += 4, ptr++) { i += 4, ptr++) {
*ptr = rtw89_read32(rtwdev, i); *ptr = rtw89_read32(rtwdev, i);
cnt += 4; cnt += 4;
...@@ -585,6 +588,9 @@ static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf, ...@@ -585,6 +588,9 @@ static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf,
const struct __fw_backtrace_entry *ent) const struct __fw_backtrace_entry *ent)
{ {
struct __fw_backtrace_info *ptr = (struct __fw_backtrace_info *)buf; struct __fw_backtrace_info *ptr = (struct __fw_backtrace_info *)buf;
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 fwbt_addr = ent->wcpu_addr & RTW89_WCPU_BASE_MASK; u32 fwbt_addr = ent->wcpu_addr & RTW89_WCPU_BASE_MASK;
u32 fwbt_size = ent->size; u32 fwbt_size = ent->size;
u32 fwbt_key = ent->key; u32 fwbt_key = ent->key;
...@@ -610,10 +616,10 @@ static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf, ...@@ -610,10 +616,10 @@ static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf,
} }
rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace start\n"); rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace start\n");
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, fwbt_addr); rtw89_write32(rtwdev, filter_model_addr, fwbt_addr);
for (i = R_AX_INDIR_ACCESS_ENTRY; for (i = indir_access_addr;
i < R_AX_INDIR_ACCESS_ENTRY + fwbt_size; i < indir_access_addr + fwbt_size;
i += RTW89_FW_BACKTRACE_INFO_SIZE, ptr++) { i += RTW89_FW_BACKTRACE_INFO_SIZE, ptr++) {
*ptr = (struct __fw_backtrace_info){ *ptr = (struct __fw_backtrace_info){
.ra = rtw89_read32(rtwdev, i), .ra = rtw89_read32(rtwdev, i),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment