From: Rajat Jain <rajatjain@xxxxxxxxxxx> PCI quirks for all juniper platforms. This is located here since the same PCI devices are present on both PPC and x86 platforms, so per-arch quirks are not appropriate. Signed-off-by: Debjit Ghosh <dghosh@xxxxxxxxxxx> Signed-off-by: Georgi Vlaev <gvlaev@xxxxxxxxxxx> Signed-off-by: Guenter Roeck <groeck@xxxxxxxxxxx> Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@xxxxxxxxxxx> Signed-off-by: Rajat Jain <rajatjain@xxxxxxxxxxx> Signed-off-by: Shyamshankar Dharmarajan <shyamd@xxxxxxxxxxx> [Ported from Juniper kernel] Signed-off-by: Pantelis Antoniou <pantelis.antoniou@xxxxxxxxxxxx> --- drivers/staging/jnx/Kconfig | 6 ++ drivers/staging/jnx/Makefile | 1 + drivers/staging/jnx/jnx-chip-pci-quirks.c | 105 ++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 drivers/staging/jnx/jnx-chip-pci-quirks.c diff --git a/drivers/staging/jnx/Kconfig b/drivers/staging/jnx/Kconfig index 5d2b207..f01ef54 100644 --- a/drivers/staging/jnx/Kconfig +++ b/drivers/staging/jnx/Kconfig @@ -21,4 +21,10 @@ config JNX_SYSTEM endmenu +config JNX_CHIP_PCI_QUIRKS + bool + select PCI_MMCONFIG + ---help--- + PCI quirks for the Juniper chips (ASICs, CPLDs, FPGAs) + endif # JNX_DEVICES diff --git a/drivers/staging/jnx/Makefile b/drivers/staging/jnx/Makefile index 52b8286..b29699c 100644 --- a/drivers/staging/jnx/Makefile +++ b/drivers/staging/jnx/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_JNX_SYSTEM) += jnx-subsys.o jnx-board-core.o +obj-$(CONFIG_JNX_CHIP_PCI_QUIRKS)+= jnx-chip-pci-quirks.o diff --git a/drivers/staging/jnx/jnx-chip-pci-quirks.c b/drivers/staging/jnx/jnx-chip-pci-quirks.c new file mode 100644 index 0000000..f90b4c7 --- /dev/null +++ b/drivers/staging/jnx/jnx-chip-pci-quirks.c @@ -0,0 +1,105 @@ +/* + * Common Juniper ASICs - PCI fixup code + * + * Guenter Roeck <groeck@xxxxxxxxxxx> + * Copyright 2012-2014 Juniper Networks + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation + */ + +#include <linux/bitops.h> +#include <linux/dmi.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/jnx/pci_ids.h> + +#define INTEL_DEBUG_REG 0x8F8 +#define INTEL_DEBUG_REG_IGNORE_GEN BIT(3) + +static void jnx_init_fpga(struct pci_dev *dev) +{ + /* + * PCI class reported by Juniper FPGAs (SAM/PAM) is + * "Unassigned class [ff00]". Change it to something more appropriate. + */ + dev->class = PCI_CLASS_SYSTEM_OTHER << 8; +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_SAM, + jnx_init_fpga); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_SAM_OMEGA, + jnx_init_fpga); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_SAM_X, + jnx_init_fpga); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_PAM, + jnx_init_fpga); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_CBC, + jnx_init_fpga); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_CBC_P2, + jnx_init_fpga); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_OMG_CBC, + jnx_init_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); + +/* + * Juniper Broadway 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 a juniper ASIC. It causes the root port to ignore the incorrect fields. + */ +static void fixup_intel_root_port(struct pci_dev *dev) +{ + struct pci_dev *rootport = dev; + u32 tmp32; + int ret = 0; + + while (!pci_is_root_bus(rootport->bus)) + rootport = pci_upstream_bridge(rootport); + + if (rootport->vendor != PCI_VENDOR_ID_INTEL) + return; + + ret = pci_read_config_dword(rootport, INTEL_DEBUG_REG, &tmp32); + tmp32 |= INTEL_DEBUG_REG_IGNORE_GEN; + ret |= pci_write_config_dword(rootport, INTEL_DEBUG_REG, tmp32); + if (ret) + dev_err(&rootport->dev, + "Error applying Intel root port quirk! CONFIG_PCI_MMCONFIG not selected?\n"); +} + +/* + * The TL/TQ ASICs report their device class as PCI_CLASS_NOT_DEFINED. + * Linux does not configure memory access for this class, + * so we have to ajust it to something acceptable. + */ +static void jnx_init_asic(struct pci_dev *dev) +{ + dev->class = PCI_CLASS_NETWORK_OTHER << 8; + + if (dmi_check_system(jnx_asic_pci_bug_affected_platforms)) + fixup_intel_root_port(dev); +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TF, + jnx_init_asic); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TL, + jnx_init_asic); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TQ, + jnx_init_asic); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_OTN_FRAMER, + jnx_init_asic); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_PE, + jnx_init_asic); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_PF, + jnx_init_asic); -- 1.9.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel