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:
Naman Padhiar
2023-03-28 12:15:29 +05:30
committed by Madan Koyyalamudi
parent 4ae0fef4d3
commit 693e91a938
2 changed files with 61 additions and 1 deletions

View File

@@ -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,