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;
|
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)
|
static int cnss_pci_config_msi_data(struct cnss_pci_data *pci_priv)
|
||||||
{
|
{
|
||||||
struct msi_desc *msi_desc;
|
struct msi_desc *msi_desc;
|
||||||
|
struct cnss_msi_config *msi_config;
|
||||||
struct pci_dev *pci_dev = pci_priv->pci_dev;
|
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);
|
msi_desc = irq_get_msi_desc(pci_dev->irq);
|
||||||
if (!msi_desc) {
|
if (!msi_desc) {
|
||||||
cnss_pr_err("msi_desc is NULL!\n");
|
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,
|
num_vectors = pci_alloc_irq_vectors(pci_dev,
|
||||||
msi_config->total_vectors,
|
msi_config->total_vectors,
|
||||||
msi_config->total_vectors,
|
msi_config->total_vectors,
|
||||||
PCI_IRQ_MSI);
|
PCI_IRQ_MSI | PCI_IRQ_MSIX);
|
||||||
if ((num_vectors != msi_config->total_vectors) &&
|
if ((num_vectors != msi_config->total_vectors) &&
|
||||||
!cnss_pci_fallback_one_msi(pci_priv, &num_vectors)) {
|
!cnss_pci_fallback_one_msi(pci_priv, &num_vectors)) {
|
||||||
cnss_pr_err("Failed to get enough MSI vectors (%d), available vectors = %d",
|
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;
|
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)) {
|
if (cnss_pci_config_msi_data(pci_priv)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto free_msi_vector;
|
goto free_msi_vector;
|
||||||
@@ -5178,8 +5220,25 @@ void cnss_get_msi_address(struct device *dev, u32 *msi_addr_low,
|
|||||||
u32 *msi_addr_high)
|
u32 *msi_addr_high)
|
||||||
{
|
{
|
||||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||||
|
struct cnss_pci_data *pci_priv;
|
||||||
u16 control;
|
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,
|
pci_read_config_word(pci_dev, pci_dev->msi_cap + PCI_MSI_FLAGS,
|
||||||
&control);
|
&control);
|
||||||
pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO,
|
pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO,
|
||||||
|
@@ -160,6 +160,7 @@ struct cnss_pci_data {
|
|||||||
void __iomem *bar;
|
void __iomem *bar;
|
||||||
struct cnss_msi_config *msi_config;
|
struct cnss_msi_config *msi_config;
|
||||||
u32 msi_ep_base_data;
|
u32 msi_ep_base_data;
|
||||||
|
u32 msix_addr;
|
||||||
struct mhi_controller *mhi_ctrl;
|
struct mhi_controller *mhi_ctrl;
|
||||||
unsigned long mhi_state;
|
unsigned long mhi_state;
|
||||||
u32 remap_window;
|
u32 remap_window;
|
||||||
|
Reference in New Issue
Block a user