mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 11:03:43 +02:00
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: Zong-Zhe Yang <kevin_yang@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20231110012319.12727-3-pkshih@realtek.com
This commit is contained in:
parent
d5d717a776
commit
d720cca762
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user