diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 1179231a672d..9c0b746540b0 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -432,6 +432,11 @@ enum rtw_wow_flags { RTW_WOW_FLAG_MAX, }; +enum rtw_quirk_dis_caps { + QUIRK_DIS_CAP_PCI_ASPM, + QUIRK_DIS_CAP_LPS_DEEP, +}; + /* the power index is represented by differences, which cck-1s & ht40-1s are * the base values, so for 1s's differences, there are only ht20 & ofdm */ diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index ec0a45bfb670..bba370ad510c 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -2,6 +2,7 @@ /* Copyright(c) 2018-2019 Realtek Corporation */ +#include #include #include #include "main.h" @@ -1744,6 +1745,34 @@ const struct pci_error_handlers rtw_pci_err_handler = { }; EXPORT_SYMBOL(rtw_pci_err_handler); +static int rtw_pci_disable_caps(const struct dmi_system_id *dmi) +{ + uintptr_t dis_caps = (uintptr_t)dmi->driver_data; + + if (dis_caps & BIT(QUIRK_DIS_CAP_PCI_ASPM)) + rtw_pci_disable_aspm = true; + + if (dis_caps & BIT(QUIRK_DIS_CAP_LPS_DEEP)) + rtw_disable_lps_deep_mode = true; + + return 1; +} + +static const struct dmi_system_id rtw_pci_quirks[] = { + { + .callback = rtw_pci_disable_caps, + .ident = "HP Notebook - P3S95EA#ACB", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Notebook"), + DMI_MATCH(DMI_PRODUCT_SKU, "P3S95EA#ACB"), + }, + .driver_data = (void *)(BIT(QUIRK_DIS_CAP_PCI_ASPM) | + BIT(QUIRK_DIS_CAP_LPS_DEEP)), + }, + {} +}; + int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -1771,6 +1800,8 @@ int rtw_pci_probe(struct pci_dev *pdev, rtwpci = (struct rtw_pci *)rtwdev->priv; atomic_set(&rtwpci->link_usage, 1); + dmi_check_system(rtw_pci_quirks); + ret = rtw_core_init(rtwdev); if (ret) goto err_release_hw;