cnss2: Add support for MSIX interrupts
Read MSI-X address from device tree file and initialize MSI-X address and data to support MSI-X interrupts. Change-Id: I7cc43ca4d3e4c937f09facf12dd02437ddc2e039 CRs-Fixed: 3488821
This commit is contained in:

committed by
Madan Koyyalamudi

parent
4ae0fef4d3
commit
693e91a938
61
cnss2/pci.c
61
cnss2/pci.c
@@ -2121,11 +2121,48 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_pci_config_msi_addr(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct pci_dev *pci_dev = pci_priv->pci_dev;
|
||||
struct cnss_plat_data *plat_priv;
|
||||
|
||||
if (!pci_dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (!pci_dev->msix_enabled)
|
||||
return ret;
|
||||
|
||||
plat_priv = pci_priv->plat_priv;
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(plat_priv->plat_dev->dev.of_node,
|
||||
"msix-match-addr",
|
||||
&pci_priv->msix_addr);
|
||||
cnss_pr_dbg("MSI-X Match address is 0x%X\n",
|
||||
pci_priv->msix_addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_pci_config_msi_data(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
struct msi_desc *msi_desc;
|
||||
struct cnss_msi_config *msi_config;
|
||||
struct pci_dev *pci_dev = pci_priv->pci_dev;
|
||||
|
||||
msi_config = pci_priv->msi_config;
|
||||
|
||||
if (pci_dev->msix_enabled) {
|
||||
pci_priv->msi_ep_base_data = msi_config->users[0].base_vector;
|
||||
cnss_pr_dbg("MSI-X base data is %d\n",
|
||||
pci_priv->msi_ep_base_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
msi_desc = irq_get_msi_desc(pci_dev->irq);
|
||||
if (!msi_desc) {
|
||||
cnss_pr_err("msi_desc is NULL!\n");
|
||||
@@ -5077,7 +5114,7 @@ static int cnss_pci_enable_msi(struct cnss_pci_data *pci_priv)
|
||||
num_vectors = pci_alloc_irq_vectors(pci_dev,
|
||||
msi_config->total_vectors,
|
||||
msi_config->total_vectors,
|
||||
PCI_IRQ_MSI);
|
||||
PCI_IRQ_MSI | PCI_IRQ_MSIX);
|
||||
if ((num_vectors != msi_config->total_vectors) &&
|
||||
!cnss_pci_fallback_one_msi(pci_priv, &num_vectors)) {
|
||||
cnss_pr_err("Failed to get enough MSI vectors (%d), available vectors = %d",
|
||||
@@ -5087,6 +5124,11 @@ static int cnss_pci_enable_msi(struct cnss_pci_data *pci_priv)
|
||||
goto reset_msi_config;
|
||||
}
|
||||
|
||||
if (cnss_pci_config_msi_addr(pci_priv)) {
|
||||
ret = -EINVAL;
|
||||
goto free_msi_vector;
|
||||
}
|
||||
|
||||
if (cnss_pci_config_msi_data(pci_priv)) {
|
||||
ret = -EINVAL;
|
||||
goto free_msi_vector;
|
||||
@@ -5178,8 +5220,25 @@ void cnss_get_msi_address(struct device *dev, u32 *msi_addr_low,
|
||||
u32 *msi_addr_high)
|
||||
{
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
struct cnss_pci_data *pci_priv;
|
||||
u16 control;
|
||||
|
||||
if (!pci_dev)
|
||||
return;
|
||||
|
||||
pci_priv = cnss_get_pci_priv(pci_dev);
|
||||
if (!pci_priv)
|
||||
return;
|
||||
|
||||
if (pci_dev->msix_enabled) {
|
||||
*msi_addr_low = pci_priv->msix_addr;
|
||||
*msi_addr_high = 0;
|
||||
if (!print_optimize.msi_addr_chk++)
|
||||
cnss_pr_dbg("Get MSI low addr = 0x%x, high addr = 0x%x\n",
|
||||
*msi_addr_low, *msi_addr_high);
|
||||
return;
|
||||
}
|
||||
|
||||
pci_read_config_word(pci_dev, pci_dev->msi_cap + PCI_MSI_FLAGS,
|
||||
&control);
|
||||
pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO,
|
||||
|
Reference in New Issue
Block a user