diff options
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/debug.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/fw.c | 77 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/fw.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/main.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8822b.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8822c.c | 3 |
6 files changed, 85 insertions, 18 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c index 985cf5d60615..bff6ce19345a 100644 --- a/drivers/net/wireless/realtek/rtw88/debug.c +++ b/drivers/net/wireless/realtek/rtw88/debug.c @@ -229,7 +229,8 @@ static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v) if (!buf) return -ENOMEM; - ret = rtw_dump_drv_rsvd_page(rtwdev, offset, buf_size, (u32 *)buf); + ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RSVD_PAGE, offset, + buf_size, (u32 *)buf); if (ret) { rtw_err(rtwdev, "failed to dump rsvd page\n"); vfree(buf); diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index 6a50bb993caf..042015bc8055 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -1413,29 +1413,16 @@ free: return ret; } -int rtw_dump_drv_rsvd_page(struct rtw_dev *rtwdev, - u32 offset, u32 size, u32 *buf) +static void rtw_fw_read_fifo_page(struct rtw_dev *rtwdev, u32 offset, u32 size, + u32 *buf, u32 residue, u16 start_pg) { - struct rtw_fifo_conf *fifo = &rtwdev->fifo; - u32 residue, i; - u16 start_pg; + u32 i; u16 idx = 0; u16 ctl; u8 rcr; - if (size & 0x3) { - rtw_warn(rtwdev, "should be 4-byte aligned\n"); - return -EINVAL; - } - - offset += fifo->rsvd_boundary << TX_PAGE_SIZE_SHIFT; - residue = offset & (FIFO_PAGE_SIZE - 1); - start_pg = offset >> FIFO_PAGE_SIZE_SHIFT; - start_pg += RSVD_PAGE_START_ADDR; - rcr = rtw_read8(rtwdev, REG_RCR + 2); ctl = rtw_read16(rtwdev, REG_PKTBUF_DBG_CTRL) & 0xf000; - /* disable rx clock gate */ rtw_write8(rtwdev, REG_RCR, rcr | BIT(3)); @@ -1457,6 +1444,64 @@ int rtw_dump_drv_rsvd_page(struct rtw_dev *rtwdev, out: rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, ctl); rtw_write8(rtwdev, REG_RCR + 2, rcr); +} + +static void rtw_fw_read_fifo(struct rtw_dev *rtwdev, enum rtw_fw_fifo_sel sel, + u32 offset, u32 size, u32 *buf) +{ + struct rtw_chip_info *chip = rtwdev->chip; + u32 start_pg, residue; + + if (sel >= RTW_FW_FIFO_MAX) { + rtw_dbg(rtwdev, RTW_DBG_FW, "wrong fw fifo sel\n"); + return; + } + if (sel == RTW_FW_FIFO_SEL_RSVD_PAGE) + offset += rtwdev->fifo.rsvd_boundary << TX_PAGE_SIZE_SHIFT; + residue = offset & (FIFO_PAGE_SIZE - 1); + start_pg = (offset >> FIFO_PAGE_SIZE_SHIFT) + chip->fw_fifo_addr[sel]; + + rtw_fw_read_fifo_page(rtwdev, offset, size, buf, residue, start_pg); +} + +static bool rtw_fw_dump_check_size(struct rtw_dev *rtwdev, + enum rtw_fw_fifo_sel sel, + u32 start_addr, u32 size) +{ + switch (sel) { + case RTW_FW_FIFO_SEL_TX: + case RTW_FW_FIFO_SEL_RX: + if ((start_addr + size) > rtwdev->chip->fw_fifo_addr[sel]) + return false; + /*fall through*/ + default: + return true; + } +} + +int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size, + u32 *buffer) +{ + if (!rtwdev->chip->fw_fifo_addr) { + rtw_dbg(rtwdev, RTW_DBG_FW, "chip not support dump fw fifo\n"); + return -ENOTSUPP; + } + + if (size == 0 || !buffer) + return -EINVAL; + + if (size & 0x3) { + rtw_dbg(rtwdev, RTW_DBG_FW, "not 4byte alignment\n"); + return -EINVAL; + } + + if (!rtw_fw_dump_check_size(rtwdev, fifo_sel, addr, size)) { + rtw_dbg(rtwdev, RTW_DBG_FW, "fw fifo dump size overflow\n"); + return -EINVAL; + } + + rtw_fw_read_fifo(rtwdev, fifo_sel, addr, size, buffer); + return 0; } diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index b4e3f755e8fb..9c4863c011ba 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -16,7 +16,6 @@ #define FIFO_PAGE_SIZE_SHIFT 12 #define FIFO_PAGE_SIZE 4096 -#define RSVD_PAGE_START_ADDR 0x780 #define FIFO_DUMP_ADDR 0x8000 #define DLFW_PAGE_SIZE_SHIFT_LEGACY 12 @@ -565,5 +564,7 @@ void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev, void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable); void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c); void rtw_fw_c2h_cmd_isr(struct rtw_dev *rtwdev); +int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size, + u32 *buffer); #endif diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 292336387b89..06bdc68555e7 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -1083,6 +1083,17 @@ enum rtw_wlan_cpu { RTW_WCPU_11N, }; +enum rtw_fw_fifo_sel { + RTW_FW_FIFO_SEL_TX, + RTW_FW_FIFO_SEL_RX, + RTW_FW_FIFO_SEL_RSVD_PAGE, + RTW_FW_FIFO_SEL_REPORT, + RTW_FW_FIFO_SEL_LLT, + RTW_FW_FIFO_SEL_RXBUF_FW, + + RTW_FW_FIFO_MAX, +}; + /* hardware configuration for each IC */ struct rtw_chip_info { struct rtw_chip_ops *ops; @@ -1099,6 +1110,7 @@ struct rtw_chip_info { u32 ptct_efuse_size; u32 txff_size; u32 rxff_size; + u32 fw_rxff_size; u8 band; u8 page_size; u8 csi_buf_pg_num; @@ -1109,6 +1121,8 @@ struct rtw_chip_info { bool rx_ldpc; u8 max_power_index; + u16 fw_fifo_addr[RTW_FW_FIFO_MAX]; + bool ht_supported; bool vht_supported; u8 lps_deep_mode_supported; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index b7a98dbbb09c..22d0dd640ac9 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -2442,6 +2442,7 @@ struct rtw_chip_info rtw8822b_hw_spec = { .ptct_efuse_size = 96, .txff_size = 262144, .rxff_size = 24576, + .fw_rxff_size = 12288, .txgi_factor = 1, .is_pwr_by_rate_dec = true, .max_power_index = 0x3f, @@ -2504,6 +2505,8 @@ struct rtw_chip_info rtw8822b_hw_spec = { .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b), .coex_info_hw_regs = coex_info_hw_regs_8822b, + + .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, }; EXPORT_SYMBOL(rtw8822b_hw_spec); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index dd216a23fc99..e37300e98517 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -4294,6 +4294,7 @@ struct rtw_chip_info rtw8822c_hw_spec = { .ptct_efuse_size = 124, .txff_size = 262144, .rxff_size = 24576, + .fw_rxff_size = 12288, .txgi_factor = 2, .is_pwr_by_rate_dec = false, .max_power_index = 0x7f, @@ -4364,6 +4365,8 @@ struct rtw_chip_info rtw8822c_hw_spec = { .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c), .coex_info_hw_regs = coex_info_hw_regs_8822c, + + .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, }; EXPORT_SYMBOL(rtw8822c_hw_spec); |