int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent, struct qib_msix_entry *entry) { u16 linkstat, speed; int pos = 0, pose, ret = 1; pose = pci_pcie_cap(dd->pcidev); if (!pose) { qib_dev_err(dd, "Can't find PCI Express capability!\n"); /* */ dd->lbus_width = 1; dd->lbus_speed = 2500; /* */ goto bail; } pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSIX); if (nent && *nent && pos) { qib_msix_setup(dd, pos, nent, entry); ret = 0; /* */ } else { pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI); if (pos) ret = qib_msi_setup(dd, pos); else qib_dev_err(dd, "No PCI MSI or MSIx capability!\n"); } if (!pos) qib_enable_intx(dd->pcidev); pci_read_config_word(dd->pcidev, pose + PCI_EXP_LNKSTA, &linkstat); /* */ speed = linkstat & 0xf; linkstat >>= 4; linkstat &= 0x1f; dd->lbus_width = linkstat; switch (speed) { case 1: dd->lbus_speed = 2500; /* */ break; case 2: dd->lbus_speed = 5000; /* */ break; default: /* */ dd->lbus_speed = 2500; break; } /* */ if (minw && linkstat < minw) qib_dev_err(dd, "PCIe width %u (x%u HCA), performance reduced\n", linkstat, minw); qib_tune_pcie_caps(dd); qib_tune_pcie_coalesce(dd); bail: /* */ snprintf(dd->lbus_info, sizeof(dd->lbus_info), "PCIe,%uMHz,x%u\n", dd->lbus_speed, dd->lbus_width); return ret; }
int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent) { u16 linkstat, speed; int nvec; int maxvec; int ret = 0; if (!pci_is_pcie(dd->pcidev)) { qib_dev_err(dd, "Can't find PCI Express capability!\n"); /* set up something... */ dd->lbus_width = 1; dd->lbus_speed = 2500; /* Gen1, 2.5GHz */ ret = -1; goto bail; } maxvec = (nent && *nent) ? *nent : 1; nvec = qib_allocate_irqs(dd, maxvec); if (nvec < 0) { ret = nvec; goto bail; } /* * If nent exists, make sure to record how many vectors were allocated */ if (nent) { *nent = nvec; /* * If we requested (nent) MSIX, but msix_enabled is not set, * pci_alloc_irq_vectors() enabled INTx. */ if (!dd->pcidev->msix_enabled) qib_dev_err(dd, "no msix vectors allocated, using INTx\n"); } pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat); /* * speed is bits 0-3, linkwidth is bits 4-8 * no defines for them in headers */ speed = linkstat & 0xf; linkstat >>= 4; linkstat &= 0x1f; dd->lbus_width = linkstat; switch (speed) { case 1: dd->lbus_speed = 2500; /* Gen1, 2.5GHz */ break; case 2: dd->lbus_speed = 5000; /* Gen1, 5GHz */ break; default: /* not defined, assume gen1 */ dd->lbus_speed = 2500; break; } /* * Check against expected pcie width and complain if "wrong" * on first initialization, not afterwards (i.e., reset). */ if (minw && linkstat < minw) qib_dev_err(dd, "PCIe width %u (x%u HCA), performance reduced\n", linkstat, minw); qib_tune_pcie_caps(dd); qib_tune_pcie_coalesce(dd); bail: /* fill in string, even on errors */ snprintf(dd->lbus_info, sizeof(dd->lbus_info), "PCIe,%uMHz,x%u\n", dd->lbus_speed, dd->lbus_width); return ret; }
int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent, struct qib_msix_entry *entry) { u16 linkstat, speed; int pos = 0, ret = 1; if (!pci_is_pcie(dd->pcidev)) { qib_dev_err(dd, "Can't find PCI Express capability!\n"); /* set up something... */ dd->lbus_width = 1; dd->lbus_speed = 2500; /* Gen1, 2.5GHz */ goto bail; } pos = dd->pcidev->msix_cap; if (nent && *nent && pos) { qib_msix_setup(dd, pos, nent, entry); ret = 0; /* did it, either MSIx or INTx */ } else { pos = dd->pcidev->msi_cap; if (pos) ret = qib_msi_setup(dd, pos); else qib_dev_err(dd, "No PCI MSI or MSIx capability!\n"); } if (!pos) qib_enable_intx(dd->pcidev); pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat); /* * speed is bits 0-3, linkwidth is bits 4-8 * no defines for them in headers */ speed = linkstat & 0xf; linkstat >>= 4; linkstat &= 0x1f; dd->lbus_width = linkstat; switch (speed) { case 1: dd->lbus_speed = 2500; /* Gen1, 2.5GHz */ break; case 2: dd->lbus_speed = 5000; /* Gen1, 5GHz */ break; default: /* not defined, assume gen1 */ dd->lbus_speed = 2500; break; } /* * Check against expected pcie width and complain if "wrong" * on first initialization, not afterwards (i.e., reset). */ if (minw && linkstat < minw) qib_dev_err(dd, "PCIe width %u (x%u HCA), performance reduced\n", linkstat, minw); qib_tune_pcie_caps(dd); qib_tune_pcie_coalesce(dd); bail: /* fill in string, even on errors */ snprintf(dd->lbus_info, sizeof(dd->lbus_info), "PCIe,%uMHz,x%u\n", dd->lbus_speed, dd->lbus_width); return ret; }