Commit d720cca7 authored by Zong-Zhe Yang's avatar Zong-Zhe Yang Committed by Kalle Valo

wifi: rtw89: pci: stop/start DMA for level 1 recovery according to chip gen

Level 1 recovery is to recover TX/RX rings, so it needs PCI to stop/start
DMA. But, different chip gen have different implementations, either
register address/mask or function flow. So, configure callback of
stop/start DMA by chip gen.
Signed-off-by: default avatarZong-Zhe Yang <kevin_yang@realtek.com>
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/20231110012319.12727-3-pkshih@realtek.com
parent d5d717a7
......@@ -1755,7 +1755,7 @@ static void rtw89_pci_ctrl_dma_io(struct rtw89_dev *rtwdev, bool enable)
rtw89_write32_set(rtwdev, reg->addr, reg->mask);
}
static void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable)
void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable)
{
rtw89_pci_ctrl_dma_io(rtwdev, enable);
rtw89_pci_ctrl_dma_trx(rtwdev, enable);
......@@ -3640,7 +3640,7 @@ static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev)
rtw89_pci_l1ss_set(rtwdev, true);
}
static int rtw89_pci_poll_io_idle(struct rtw89_dev *rtwdev)
static int rtw89_pci_poll_io_idle_ax(struct rtw89_dev *rtwdev)
{
int ret = 0;
u32 sts;
......@@ -3657,7 +3657,7 @@ static int rtw89_pci_poll_io_idle(struct rtw89_dev *rtwdev)
return ret;
}
static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev)
static int rtw89_pci_lv1rst_stop_dma_ax(struct rtw89_dev *rtwdev)
{
u32 val;
int ret;
......@@ -3666,7 +3666,7 @@ static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev)
return 0;
rtw89_pci_ctrl_dma_all(rtwdev, false);
ret = rtw89_pci_poll_io_idle(rtwdev);
ret = rtw89_pci_poll_io_idle_ax(rtwdev);
if (ret) {
val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG);
rtw89_debug(rtwdev, RTW89_DBG_HCI,
......@@ -3677,7 +3677,7 @@ static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev)
if (val & B_AX_RX_STUCK)
rtw89_mac_ctrl_hci_dma_rx(rtwdev, false);
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
ret = rtw89_pci_poll_io_idle(rtwdev);
ret = rtw89_pci_poll_io_idle_ax(rtwdev);
val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG);
rtw89_debug(rtwdev, RTW89_DBG_HCI,
"[PCIe] poll_io_idle fail, after 0x%08x: 0x%08x\n",
......@@ -3687,7 +3687,7 @@ static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev)
return ret;
}
static int rtw89_pci_lv1rst_start_dma(struct rtw89_dev *rtwdev)
static int rtw89_pci_lv1rst_start_dma_ax(struct rtw89_dev *rtwdev)
{
u32 ret;
......@@ -3709,18 +3709,20 @@ static int rtw89_pci_lv1rst_start_dma(struct rtw89_dev *rtwdev)
static int rtw89_pci_ops_mac_lv1_recovery(struct rtw89_dev *rtwdev,
enum rtw89_lv1_rcvy_step step)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
const struct rtw89_pci_gen_def *gen_def = info->gen_def;
int ret;
switch (step) {
case RTW89_LV1_RCVY_STEP_1:
ret = rtw89_pci_lv1rst_stop_dma(rtwdev);
ret = gen_def->lv1rst_stop_dma(rtwdev);
if (ret)
rtw89_err(rtwdev, "lv1 rcvy pci stop dma fail\n");
break;
case RTW89_LV1_RCVY_STEP_2:
ret = rtw89_pci_lv1rst_start_dma(rtwdev);
ret = gen_def->lv1rst_start_dma(rtwdev);
if (ret)
rtw89_err(rtwdev, "lv1 rcvy pci start dma fail\n");
break;
......@@ -3839,6 +3841,9 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
.clr_idx_all = rtw89_pci_clr_idx_all_ax,
.rst_bdram = rtw89_pci_rst_bdram_ax,
.lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_ax,
.lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_ax,
};
EXPORT_SYMBOL(rtw89_pci_gen_ax);
......
......@@ -1042,6 +1042,9 @@ struct rtw89_pci_gen_def {
void (*clr_idx_all)(struct rtw89_dev *rtwdev);
int (*rst_bdram)(struct rtw89_dev *rtwdev);
int (*lv1rst_stop_dma)(struct rtw89_dev *rtwdev);
int (*lv1rst_start_dma)(struct rtw89_dev *rtwdev);
};
struct rtw89_pci_info {
......@@ -1369,6 +1372,7 @@ u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev,
u32 rtw89_pci_fill_txaddr_info_v1(struct rtw89_dev *rtwdev,
void *txaddr_info_addr, u32 total_len,
dma_addr_t dma, u8 *add_info_nr);
void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable);
void rtw89_pci_config_intr_mask(struct rtw89_dev *rtwdev);
void rtw89_pci_config_intr_mask_v1(struct rtw89_dev *rtwdev);
void rtw89_pci_enable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci);
......
......@@ -4,6 +4,7 @@
#include <linux/pci.h>
#include "mac.h"
#include "pci.h"
#include "reg.h"
......@@ -420,11 +421,65 @@ static int rtw89_pci_ops_mac_post_init_be(struct rtw89_dev *rtwdev)
return 0;
}
static int rtw89_pci_poll_io_idle_be(struct rtw89_dev *rtwdev)
{
u32 sts;
int ret;
ret = read_poll_timeout_atomic(rtw89_read32, sts,
!(sts & B_BE_HAXI_MST_BUSY),
10, 1000, false, rtwdev,
R_BE_HAXI_DMA_BUSY1);
if (ret) {
rtw89_err(rtwdev, "pci dmach busy1 0x%X\n", sts);
return ret;
}
return 0;
}
static int rtw89_pci_lv1rst_stop_dma_be(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_pci_ctrl_dma_all(rtwdev, false);
ret = rtw89_pci_poll_io_idle_be(rtwdev);
if (!ret)
return 0;
rtw89_debug(rtwdev, RTW89_DBG_HCI,
"[PCIe] poll_io_idle fail; reset hci dma trx\n");
rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
return rtw89_pci_poll_io_idle_be(rtwdev);
}
static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
rtw89_pci_clr_idx_all(rtwdev);
ret = rtw89_pci_rst_bdram_be(rtwdev);
if (ret)
return ret;
rtw89_pci_ctrl_dma_all(rtwdev, true);
return 0;
}
const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
.mac_pre_init = rtw89_pci_ops_mac_pre_init_be,
.mac_post_init = rtw89_pci_ops_mac_post_init_be,
.clr_idx_all = rtw89_pci_clr_idx_all_be,
.rst_bdram = rtw89_pci_rst_bdram_be,
.lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_be,
.lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_be,
};
EXPORT_SYMBOL(rtw89_pci_gen_be);
......@@ -361,6 +361,9 @@ static int hal_enable_dma(struct rtw89_ser *ser)
ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_2);
if (!ret)
clear_bit(RTW89_SER_HAL_STOP_DMA, ser->flags);
else
rtw89_debug(rtwdev, RTW89_DBG_SER,
"lv1 rcvy fail to start dma: %d\n", ret);
return ret;
}
......@@ -376,6 +379,9 @@ static int hal_stop_dma(struct rtw89_ser *ser)
ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_1);
if (!ret)
set_bit(RTW89_SER_HAL_STOP_DMA, ser->flags);
else
rtw89_debug(rtwdev, RTW89_DBG_SER,
"lv1 rcvy fail to stop dma: %d\n", ret);
return ret;
}
......
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