# HG changeset patch # User Yu Zhao # Date 1237445637 14400 # Node ID cdfa79a9463c46ac99b4ce543c86951cfbc40c43 # Parent 2bd960a6fe028119867357f0d99f3388d7a14047 PCI: add a SR-IOV quirk for Intel 82576 NIC If BIOS doesn't allocate resources for VF BARs, zero Flash BAR and program VF BARs to use the old Flash Memory Space. Please refer to Intel 82576 Gigabit Ethernet Controller Datasheet section 7.9.2.14.2 for details. http://download.intel.com/design/network/datashts/82576_Datasheet.pdf Signed-off-by: Yu Zhao diff -r 2bd960a6fe02 -r cdfa79a9463c drivers/pci/quirks.c --- a/drivers/pci/quirks.c Thu Mar 19 02:01:08 2009 -0400 +++ b/drivers/pci/quirks.c Thu Mar 19 02:53:57 2009 -0400 @@ -1747,3 +1747,60 @@ #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_fixup_device); #endif + +#ifdef CONFIG_PCI_IOV +/* + * If BIOS doesn't allocate resources for SR-IOV BARs, zero Flash BAR + * and program SR-IOV BARs to use the old Flash Memory Space. + * PCI subsystem may try to allocate Memory Space for Flash BAR later, + * that's why we don't clear Flash BAR flags. + */ +static void __devinit intel_82576_quirk(struct pci_dev *dev) +{ + int i, flags; + u32 bar, start, size; + + if (PAGE_SIZE > 0x10000) + return; + + if (pci_read_config_dword(dev, 0x184, &bar)) + return; + + if (bar & PCI_BASE_ADDRESS_MEM_MASK) + return; + + i = 1; + flags = pci_resource_flags(dev, i); + if ((flags & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_MEMORY && + (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_32) + goto found; + + i = 2; + flags = pci_resource_flags(dev, i); + if ((flags & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_MEMORY && + (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64) + goto found; + + return; +found: + start = pci_resource_start(dev, i); + size = pci_resource_len(dev, i); + if (!start || size != 0x400000 || start & (size - 1)) + return; + + pci_write_config_dword(dev, 0x10 + i * 4, 0); + pci_resource_start(dev, i) = 0; + pci_resource_end(dev, i) = size - 1; + pci_write_config_dword(dev, 0x184, start); + pci_write_config_dword(dev, 0x190, start + size / 2); + + dev_info(&dev->dev, "use Flash Memory Space for SR-IOV BARs\n"); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, intel_82576_quirk); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, intel_82576_quirk); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, intel_82576_quirk); +#endif /* CONFIG_PCI_IOV */