aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Zhao <yu.zhao@intel.com>2009-04-03 03:18:11 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-04-06 14:21:40 -0400
commit7eb93b175d4de9438a4b0af3a94a112cb5266944 (patch)
treed92404ff26d269f8b1f4db2b3cd7a3f0f9f830ff
parent0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff)
PCI: SR-IOV quirk for Intel 82576 NIC
If BIOS doesn't allocate resources for the SR-IOV BARs, zero the Flash BAR and program the SR-IOV 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 <yu.zhao@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/pci/quirks.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 9b2f0d96900d..51011a24589d 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2411,6 +2411,54 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375,
2411 2411
2412#endif /* CONFIG_PCI_MSI */ 2412#endif /* CONFIG_PCI_MSI */
2413 2413
2414#ifdef CONFIG_PCI_IOV
2415
2416/*
2417 * For Intel 82576 SR-IOV NIC, if BIOS doesn't allocate resources for the
2418 * SR-IOV BARs, zero the Flash BAR and program the SR-IOV BARs to use the
2419 * old Flash Memory Space.
2420 */
2421static void __devinit quirk_i82576_sriov(struct pci_dev *dev)
2422{
2423 int pos, flags;
2424 u32 bar, start, size;
2425
2426 if (PAGE_SIZE > 0x10000)
2427 return;
2428
2429 flags = pci_resource_flags(dev, 0);
2430 if ((flags & PCI_BASE_ADDRESS_SPACE) !=
2431 PCI_BASE_ADDRESS_SPACE_MEMORY ||
2432 (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) !=
2433 PCI_BASE_ADDRESS_MEM_TYPE_32)
2434 return;
2435
2436 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
2437 if (!pos)
2438 return;
2439
2440 pci_read_config_dword(dev, pos + PCI_SRIOV_BAR, &bar);
2441 if (bar & PCI_BASE_ADDRESS_MEM_MASK)
2442 return;
2443
2444 start = pci_resource_start(dev, 1);
2445 size = pci_resource_len(dev, 1);
2446 if (!start || size != 0x400000 || start & (size - 1))
2447 return;
2448
2449 pci_resource_flags(dev, 1) = 0;
2450 pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0);
2451 pci_write_config_dword(dev, pos + PCI_SRIOV_BAR, start);
2452 pci_write_config_dword(dev, pos + PCI_SRIOV_BAR + 12, start + size / 2);
2453
2454 dev_info(&dev->dev, "use Flash Memory Space for SR-IOV BARs\n");
2455}
2456DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, quirk_i82576_sriov);
2457DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov);
2458DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov);
2459
2460#endif /* CONFIG_PCI_IOV */
2461
2414static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, 2462static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
2415 struct pci_fixup *end) 2463 struct pci_fixup *end)
2416{ 2464{