drivers/pcie: Add a function to know MSI/MSI-x support of an endpoint

And since it does yet another round of pcie_get_cap() on PCIE_MSI_CAP_ID
and PCIE_MSIX_CAP_ID, let's factorize that into a utility function and
change the relevant places to use that function instead.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2021-03-15 15:00:52 +01:00 committed by Anas Nashif
commit fbb2f1511c
2 changed files with 46 additions and 40 deletions

View file

@ -10,6 +10,32 @@
/* functions documented in include/drivers/pcie/msi.h */ /* functions documented in include/drivers/pcie/msi.h */
static uint32_t pcie_msi_base(pcie_bdf_t bdf, bool *msi)
{
uint32_t base;
if (msi != NULL) {
*msi = true;
}
base = pcie_get_cap(bdf, PCI_CAP_ID_MSI);
if (IS_ENABLED(CONFIG_PCIE_MSI_X)) {
uint32_t base_msix;
base_msix = pcie_get_cap(bdf, PCI_CAP_ID_MSIX);
if (base_msix != 0U) {
base = base_msix;
if (msi != NULL) {
*msi = false;
}
}
}
return base;
}
#ifdef CONFIG_PCIE_MSI_MULTI_VECTOR #ifdef CONFIG_PCIE_MSI_MULTI_VECTOR
#include <sys/mem_manage.h> #include <sys/mem_manage.h>
@ -115,21 +141,11 @@ uint8_t pcie_msi_vectors_allocate(pcie_bdf_t bdf,
msi_vector_t *vectors, msi_vector_t *vectors,
uint8_t n_vector) uint8_t n_vector)
{ {
bool msi = true;
uint32_t base;
uint32_t req_vectors; uint32_t req_vectors;
uint32_t base;
bool msi;
base = pcie_get_cap(bdf, PCI_CAP_ID_MSI); base = pcie_msi_base(bdf, &msi);
if (IS_ENABLED(CONFIG_PCIE_MSI_X)) {
uint32_t base_msix;
base_msix = pcie_get_cap(bdf, PCI_CAP_ID_MSIX);
if (base_msix != 0U) {
msi = false;
base = base_msix;
}
}
if (IS_ENABLED(CONFIG_PCIE_MSI_X)) { if (IS_ENABLED(CONFIG_PCIE_MSI_X)) {
set_msix(vectors, n_vector, !msi); set_msix(vectors, n_vector, !msi);
@ -162,17 +178,7 @@ bool pcie_msi_vector_connect(pcie_bdf_t bdf,
{ {
uint32_t base; uint32_t base;
base = pcie_get_cap(bdf, PCI_CAP_ID_MSI); base = pcie_msi_base(bdf, NULL);
if (IS_ENABLED(CONFIG_PCIE_MSI_X)) {
uint32_t base_msix;
base_msix = pcie_get_cap(bdf, PCI_CAP_ID_MSIX);
if (base_msix != 0U) {
base = base_msix;
}
}
if (base == 0U) { if (base == 0U) {
return false; return false;
} }
@ -263,29 +269,16 @@ bool pcie_msi_enable(pcie_bdf_t bdf,
uint8_t n_vector, uint8_t n_vector,
unsigned int irq) unsigned int irq)
{ {
bool msi = true;
uint32_t base; uint32_t base;
bool msi;
base = pcie_get_cap(bdf, PCI_CAP_ID_MSI); base = pcie_msi_base(bdf, &msi);
if (IS_ENABLED(CONFIG_PCIE_MSI_X)) {
uint32_t base_msix;
base_msix = pcie_get_cap(bdf, PCI_CAP_ID_MSIX);
if ((base_msix != 0U) && (base != 0U)) {
disable_msi(bdf, base);
}
if ((base_msix != 0U)) {
msi = false;
base = base_msix;
}
}
if (base == 0U) { if (base == 0U) {
return false; return false;
} }
if (!msi && IS_ENABLED(CONFIG_PCIE_MSI_X)) { if (!msi && IS_ENABLED(CONFIG_PCIE_MSI_X)) {
disable_msi(bdf, base);
enable_msix(bdf, vectors, n_vector, base, irq); enable_msix(bdf, vectors, n_vector, base, irq);
} else { } else {
enable_msi(bdf, vectors, n_vector, base, irq); enable_msi(bdf, vectors, n_vector, base, irq);
@ -295,3 +288,8 @@ bool pcie_msi_enable(pcie_bdf_t bdf,
return true; return true;
} }
bool pcie_is_msi(pcie_bdf_t bdf)
{
return (pcie_msi_base(bdf, NULL) != 0);
}

View file

@ -109,6 +109,14 @@ extern bool pcie_msi_enable(pcie_bdf_t bdf,
uint8_t n_vector, uint8_t n_vector,
unsigned int irq); unsigned int irq);
/**
* @brief Check if the given PCI endpoint supports MSI/MSI-X
*
* @param bdf the target PCI endpoint
* @return true if the endpoint support MSI/MSI-X
*/
extern bool pcie_is_msi(pcie_bdf_t bdf);
/* /*
* The first word of the MSI capability is shared with the * The first word of the MSI capability is shared with the
* capability ID and list link. The high 16 bits are the MCR. * capability ID and list link. The high 16 bits are the MCR.