Some of the Juniper ASICs report incorrect PCIe gen type for the PCIe link to the root port. Make the root port to ignore these fields. Signed-off-by: Rajat Jain <rajatja@xxxxxxxxxx> Signed-off-by: Ming Qiao <mqiao@xxxxxxxxxxx> --- drivers/pci/quirks.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 04dd490..0a28a09 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -5658,6 +5658,45 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, 0x00A9, quirk_jnx_fpga); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, 0x00AA, quirk_jnx_fpga); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_XILINX, 0x0505, quirk_jnx_fpga); +static struct dmi_system_id jnx_asic_pci_bug_affected_platforms[] = { + { + .ident = "Juniper Networks PTX MLC Card", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Juniper Networks Inc."), + DMI_MATCH(DMI_BOARD_NAME, "0C0A") + }, + }, + {}, +}; +MODULE_DEVICE_TABLE(dmi, jnx_asic_pci_bug_affected_platforms); + +#define INTEL_DEBUG_REG 0x8F8 +#define INTEL_DEBUG_REG_IGNORE_GEN BIT(3) + +/* + * Some Juniper ASICs have an issue where they report incorrect gen type + * (Gen-1 / Gen-2) for the PCIe link to the root port. + * This workaround needs to be applied to each Intel root port which connects + * to such juniper ASIC. It causes the root port to ignore the incorrect + * fields. + */ +static void fixup_jnx_intel_root_port(struct pci_dev *dev) +{ + struct pci_dev *root; + u32 tmp32; + int ret; + + root = pcie_find_root_port(dev); + if (!root || root->vendor != PCI_VENDOR_ID_INTEL) + return; + + ret = pci_read_config_dword(root, INTEL_DEBUG_REG, &tmp32); + tmp32 |= INTEL_DEBUG_REG_IGNORE_GEN; + ret |= pci_write_config_dword(root, INTEL_DEBUG_REG, tmp32); + if (ret) + dev_err(&root->dev, "Failed on root port quirk. CONFIG_PCI_MMCONFIG not selected?\n"); +} + /* * PCI class reported by some Juniper ASICs is not correct. * Change it to NETWORK. @@ -5665,6 +5704,9 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_XILINX, 0x0505, quirk_jnx_fpga); static void quirk_jnx_asic(struct pci_dev *dev) { dev->class = PCI_CLASS_NETWORK_OTHER << 8; + + if (dmi_check_system(jnx_asic_pci_bug_affected_platforms)) + fixup_jnx_intel_root_port(dev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, 0x003C, quirk_jnx_asic); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, 0x003D, quirk_jnx_asic); -- 2.10.0