linux/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
Chin-Yen Lee 16e3d93c61 wifi: rtw89: pci: add PCI Express error handling
Sometimes PCIe Advanced Error Reporting(AER), like bad TLP or
Data link protocol error, happens due to unstable pci signal or
no response from PCI host.

  pcieport 0000:00:1c.0: AER: Uncorrected (Non-Fatal) error message received from 0000:01:00.0
  rtw89_8852be 0000:01:00.0: PCIe Bus Error: severity=Uncorrected (Non-Fatal), type=Transaction Layer, (Requester ID)
  rtw89_8852be 0000:01:00.0:   device [10ec:b852] error status/mask=00004000/00400000
  rtw89_8852be 0000:01:00.0:    [14] CmpltTO                (First)
  rtw89_8852be 0000:01:00.0: SER catches error: 0x4000
  pcieport 0000:00:1c.0: AER: device recovery successful
  rtw89_8852be 0000:01:00.0: FW backtrace invalid key: 0xbb6c3214
  ieee80211 phy0: Hardware restart was requested

Setup callback function to call SER function to reset driver to recover
from these states.

Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250523062711.27213-3-pkshih@realtek.com
2025-06-10 09:23:06 +08:00

127 lines
3.8 KiB
C

// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2020-2022 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "reg.h"
#include "rtw8852c.h"
static const struct rtw89_pci_bd_idx_addr rtw8852c_bd_idx_addr_low_power = {
.tx_bd_addrs = {R_AX_DRV_FW_HSK_0, R_AX_DRV_FW_HSK_1, R_AX_DRV_FW_HSK_2,
R_AX_DRV_FW_HSK_3, 0, 0,
0, 0, R_AX_DRV_FW_HSK_4,
0, 0, 0,
R_AX_DRV_FW_HSK_5},
.rx_bd_addrs = {R_AX_DRV_FW_HSK_6, R_AX_DRV_FW_HSK_7},
};
static const struct rtw89_pci_info rtw8852c_pci_info = {
.gen_def = &rtw89_pci_gen_ax,
.txbd_trunc_mode = MAC_AX_BD_TRUNC,
.rxbd_trunc_mode = MAC_AX_BD_TRUNC,
.rxbd_mode = MAC_AX_RXBD_PKT,
.tag_mode = MAC_AX_TAG_MULTI,
.tx_burst = MAC_AX_TX_BURST_V1_256B,
.rx_burst = MAC_AX_RX_BURST_V1_128B,
.wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS,
.wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS,
.multi_tag_num = MAC_AX_TAG_NUM_8,
.lbc_en = MAC_AX_PCIE_ENABLE,
.lbc_tmr = MAC_AX_LBC_TMR_2MS,
.autok_en = MAC_AX_PCIE_DISABLE,
.io_rcy_en = MAC_AX_PCIE_ENABLE,
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
.rx_ring_eq_is_full = false,
.check_rx_tag = false,
.no_rxbd_fs = false,
.init_cfg_reg = R_AX_HAXI_INIT_CFG1,
.txhci_en_bit = B_AX_TXHCI_EN_V1,
.rxhci_en_bit = B_AX_RXHCI_EN_V1,
.rxbd_mode_bit = B_AX_RXBD_MODE_V1,
.exp_ctrl_reg = R_AX_HAXI_EXP_CTRL,
.max_tag_num_mask = B_AX_MAX_TAG_NUM_V1_MASK,
.rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR_V1,
.txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2_V1,
.dma_io_stop = {R_AX_HAXI_INIT_CFG1, B_AX_STOP_AXI_MST},
.dma_stop1 = {R_AX_HAXI_DMA_STOP1, B_AX_TX_STOP1_MASK},
.dma_stop2 = {R_AX_HAXI_DMA_STOP2, B_AX_TX_STOP2_ALL},
.dma_busy1 = {R_AX_HAXI_DMA_BUSY1, DMA_BUSY1_CHECK},
.dma_busy2_reg = R_AX_HAXI_DMA_BUSY2,
.dma_busy3_reg = R_AX_HAXI_DMA_BUSY3,
.rpwm_addr = R_AX_PCIE_HRPWM_V1,
.cpwm_addr = R_AX_PCIE_CRPWM,
.mit_addr = R_AX_INT_MIT_RX_V1,
.wp_sel_addr = R_AX_WP_ADDR_H_SEL0_3,
.tx_dma_ch_mask = 0,
.bd_idx_addr_low_power = &rtw8852c_bd_idx_addr_low_power,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1,
.bd_ram_table = &rtw89_bd_ram_table_dual,
.ltr_set = rtw89_pci_ltr_set_v1,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1,
.config_intr_mask = rtw89_pci_config_intr_mask_v1,
.enable_intr = rtw89_pci_enable_intr_v1,
.disable_intr = rtw89_pci_disable_intr_v1,
.recognize_intrs = rtw89_pci_recognize_intrs_v1,
.ssid_quirks = NULL,
};
static const struct dmi_system_id rtw8852c_pci_quirks[] = {
{
.ident = "Dell Inc. Vostro 16 5640",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 16 5640"),
DMI_MATCH(DMI_PRODUCT_SKU, "0CA0"),
},
.driver_data = (void *)RTW89_QUIRK_PCI_BER,
},
{
.ident = "Dell Inc. Inspiron 16 5640",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5640"),
DMI_MATCH(DMI_PRODUCT_SKU, "0C9F"),
},
.driver_data = (void *)RTW89_QUIRK_PCI_BER,
},
{},
};
static const struct rtw89_driver_info rtw89_8852ce_info = {
.chip = &rtw8852c_chip_info,
.variant = NULL,
.quirks = rtw8852c_pci_quirks,
.bus = {
.pci = &rtw8852c_pci_info,
},
};
static const struct pci_device_id rtw89_8852ce_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xc852),
.driver_data = (kernel_ulong_t)&rtw89_8852ce_info,
},
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8852ce_id_table);
static struct pci_driver rtw89_8852ce_driver = {
.name = "rtw89_8852ce",
.id_table = rtw89_8852ce_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852ce_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852CE driver");
MODULE_LICENSE("Dual BSD/GPL");