/* Copyright(c) 2018-2019 Realtek Corporation
*/
+#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "main.h"
* throughput. This is probably because the ASPM behavior slightly
* varies from different SOC.
*/
- if (!(rtwpci->link_ctrl & PCI_EXP_LNKCTL_ASPM_L1))
- return;
-
- if ((enter && atomic_dec_if_positive(&rtwpci->link_usage) == 0) ||
- (!enter && atomic_inc_return(&rtwpci->link_usage) == 1))
+ if (rtwpci->link_ctrl & PCI_EXP_LNKCTL_ASPM_L1)
rtw_pci_aspm_set(rtwdev, enter);
}
priv);
int work_done = 0;
- if (rtwpci->rx_no_aspm)
- rtw_pci_link_ps(rtwdev, false);
-
while (work_done < budget) {
u32 work_done_once;
if (rtw_pci_get_hw_rx_ring_nr(rtwdev, rtwpci))
napi_schedule(napi);
}
- if (rtwpci->rx_no_aspm)
- rtw_pci_link_ps(rtwdev, true);
return work_done;
}
netif_napi_del(&rtwpci->napi);
}
+enum rtw88_quirk_dis_pci_caps {
+ QUIRK_DIS_PCI_CAP_MSI,
+ QUIRK_DIS_PCI_CAP_ASPM,
+};
+
+static int disable_pci_caps(const struct dmi_system_id *dmi)
+{
+ uintptr_t dis_caps = (uintptr_t)dmi->driver_data;
+
+ if (dis_caps & BIT(QUIRK_DIS_PCI_CAP_MSI))
+ rtw_disable_msi = true;
+ if (dis_caps & BIT(QUIRK_DIS_PCI_CAP_ASPM))
+ rtw_pci_disable_aspm = true;
+
+ return 1;
+}
+
+static const struct dmi_system_id rtw88_pci_quirks[] = {
+ {
+ .callback = disable_pci_caps,
+ .ident = "Protempo Ltd L116HTN6SPW",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Protempo Ltd"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "L116HTN6SPW"),
+ },
+ .driver_data = (void *)BIT(QUIRK_DIS_PCI_CAP_ASPM),
+ },
+ {
+ .callback = disable_pci_caps,
+ .ident = "HP HP Pavilion Laptop 14-ce0xxx",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Laptop 14-ce0xxx"),
+ },
+ .driver_data = (void *)BIT(QUIRK_DIS_PCI_CAP_ASPM),
+ },
+ {}
+};
+
int rtw_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
- struct pci_dev *bridge = pci_upstream_bridge(pdev);
struct ieee80211_hw *hw;
struct rtw_dev *rtwdev;
- struct rtw_pci *rtwpci;
int drv_data_size;
int ret;
rtwdev->hci.ops = &rtw_pci_ops;
rtwdev->hci.type = RTW_HCI_TYPE_PCIE;
- rtwpci = (struct rtw_pci *)rtwdev->priv;
- atomic_set(&rtwpci->link_usage, 1);
-
ret = rtw_core_init(rtwdev);
if (ret)
goto err_release_hw;
goto err_destroy_pci;
}
- /* Disable PCIe ASPM L1 while doing NAPI poll for 8821CE */
- if (pdev->device == 0xc821 && bridge->vendor == PCI_VENDOR_ID_INTEL)
- rtwpci->rx_no_aspm = true;
-
+ dmi_check_system(rtw88_pci_quirks);
rtw_pci_phy_cfg(rtwdev);
ret = rtw_register_hw(rtwdev, hw);