33 #include <linux/pci.h>
38 #include <linux/module.h>
54 static int qib_tune_pcie_caps(
struct qib_devdata *);
55 static int qib_tune_pcie_coalesce(
struct qib_devdata *);
88 qib_devinfo(pdev,
"pci_request_regions fails: err %d\n", -ret);
101 qib_devinfo(pdev,
"Unable to set DMA mask: %d\n", ret);
104 ret = pci_set_consistent_dma_mask(pdev,
DMA_BIT_MASK(32));
106 ret = pci_set_consistent_dma_mask(pdev,
DMA_BIT_MASK(64));
109 "Unable to set DMA consistent mask: %d\n", ret);
117 "Unable to enable pcie error reporting: %d\n",
142 pci_set_drvdata(pdev, dd);
147 #if defined(__powerpc__)
202 struct msix_entry *msix_entry;
213 for (i = 0; i < *msixcnt; i++)
214 msix_entry[i] = qib_msix_entry[i].msix;
218 if (tabsize > *msixcnt)
228 "pci_enable_msix %d vectors failed: %d, falling back to INTx\n",
232 for (i = 0; i < tabsize; i++)
233 qib_msix_entry[i].msix = msix_entry[i];
247 static int qib_msi_setup(
struct qib_devdata *dd,
int pos)
253 ret = pci_enable_msi(pdev);
256 "pci_enable_msi failed: %d, interrupts may not work\n",
273 struct qib_msix_entry *
entry)
276 int pos = 0, ret = 1;
278 if (!pci_is_pcie(dd->
pcidev)) {
279 qib_dev_err(dd,
"Can't find PCI Express capability!\n");
287 if (nent && *nent && pos) {
288 qib_msix_setup(dd, pos, nent, entry);
293 ret = qib_msi_setup(dd, pos);
295 qib_dev_err(dd,
"No PCI MSI or MSIx capability!\n");
305 speed = linkstat & 0xf;
326 if (minw && linkstat < minw)
328 "PCIe width %u (x%u HCA), performance reduced\n",
331 qib_tune_pcie_caps(dd);
333 qib_tune_pcie_coalesce(dd);
363 "Can't find MSI capability, can't restore MSI settings\n");
379 pci_write_config_word(dd->
pcidev, pos +
464 qib_dev_err(dd,
"rewrite of BAR0 failed: %d\n", r);
468 qib_dev_err(dd,
"rewrite of BAR1 failed: %d\n", r);
476 "pci_enable_device failed after reset: %d\n", r);
481 static int fld2val(
int wd,
int mask)
488 lsbmask = mask ^ (mask & (mask - 1));
493 static int val2fld(
int wd,
int mask)
499 lsbmask = mask ^ (mask & (mask - 1));
504 static int qib_pcie_coalesce;
506 MODULE_PARM_DESC(pcie_coalesce,
"tune PCIe colescing on some Intel chipsets");
514 static int qib_tune_pcie_coalesce(
struct qib_devdata *dd)
521 if (!qib_pcie_coalesce)
525 parent = dd->
pcidev->bus->self;
526 if (parent->
bus->parent) {
530 if (!pci_is_pcie(parent))
532 if (parent->
vendor != 0x8086)
545 if (devid >= 0x25e2 && devid <= 0x25fa) {
551 mask = (3
U << 24) | (7
U << 10);
552 }
else if (devid >= 0x65e2 && devid <= 0x65fa) {
555 mask = (3
U << 24) | (7
U << 10);
556 }
else if (devid >= 0x4021 && devid <= 0x402e) {
560 }
else if (devid >= 0x3604 && devid <= 0x360a) {
563 mask = (3
U << 24) | (7
U << 10);
568 pci_read_config_dword(parent, 0x48, &val);
571 r = pci_write_config_dword(parent, 0x48, val);
579 static int qib_pcie_caps;
581 MODULE_PARM_DESC(pcie_caps,
"Max PCIe tuning: Payload (0..3), ReadReq (4..7)");
583 static int qib_tune_pcie_caps(
struct qib_devdata *dd)
592 parent = dd->
pcidev->bus->self;
593 if (parent->
bus->parent) {
598 if (!pci_is_pcie(parent) || !pci_is_pcie(dd->
pcidev))
617 if (rc_sup > (qib_pcie_caps & 7))
618 rc_sup = qib_pcie_caps & 7;
620 if (rc_sup > rc_cur) {
627 if (rc_sup > ep_cur) {
640 if (rc_sup > ((qib_pcie_caps >> 4) & 7))
641 rc_sup = (qib_pcie_caps >> 4) & 7;
645 if (rc_sup > rc_cur) {
651 if (rc_sup > ep_cur) {
678 qib_devinfo(pdev,
"State Frozen, requesting reset\n");
684 qib_devinfo(pdev,
"State Permanent Failure, disabling\n");
695 qib_devinfo(pdev,
"QIB PCI errors detected (state %d)\n",
703 qib_pci_mmio_enabled(
struct pci_dev *pdev)
709 if (dd && dd->
pport) {
715 "QIB mmio_enabled function called, read wordscntr %Lx, returning %d\n",
721 qib_pci_slot_reset(
struct pci_dev *pdev)
723 qib_devinfo(pdev,
"QIB slot_reset function called, ignored\n");
728 qib_pci_link_reset(
struct pci_dev *pdev)
730 qib_devinfo(pdev,
"QIB link_reset function called, ignored\n");
735 qib_pci_resume(
struct pci_dev *pdev)
749 .error_detected = qib_pci_error_detected,
750 .mmio_enabled = qib_pci_mmio_enabled,
751 .link_reset = qib_pci_link_reset,
752 .slot_reset = qib_pci_slot_reset,
753 .resume = qib_pci_resume,