diff options
author | Yu Zhao <yu.zhao@intel.com> | 2009-04-03 03:18:11 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-04-06 14:21:40 -0400 |
commit | 7eb93b175d4de9438a4b0af3a94a112cb5266944 (patch) | |
tree | d92404ff26d269f8b1f4db2b3cd7a3f0f9f830ff | |
parent | 0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (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.c | 48 |
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 | */ | ||
2421 | static 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 | } | ||
2456 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, quirk_i82576_sriov); | ||
2457 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov); | ||
2458 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov); | ||
2459 | |||
2460 | #endif /* CONFIG_PCI_IOV */ | ||
2461 | |||
2414 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2462 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2415 | struct pci_fixup *end) | 2463 | struct pci_fixup *end) |
2416 | { | 2464 | { |