@@ -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;
}