ath11k: get msi_data again after request_irq is called
PATCH 1/7 ath11k: get msi_data again after request_irq is called
From: Carl Huang <[email protected]>
The reservation mode of interrupts in kernel assigns a dummy vector when the interrupt is allocated and assigns a real vector when the request_irq is called. The reservation mode helps to ease vector pressure when devices with a large amount of queues/interrupts are initialized, but only a minimal subset of those queues/interrupts is actually used.
So on reservation mode, the msi_data may change after request_irq is called, so ath11k reads msi_data again after request_irq is called, and then the correct msi_data is programmed into QCA6390 hardware components. Without this change, spurious interrupt occurs in case of one MSI vector. When VT-d in BIOS is enabled and ath11k can get 32 MSI vectors, ath11k always get the same msi_data before and after request_irq, that's why this change is only required when one MSI vector is to be supported.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
--- drivers/net/wireless/ath/ath11k/pci.c | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
drivers/net/wireless/ath/ath11k/pci.c +30 -0
@@ -929,6 +929,25 @@ static void ath11k_pci_free_msi(struct ath11k_pci *ab_pci)pci_free_irq_vectors (ab_pci->pdev); } +static int ath11k_pci_config_msi_data (struct ath11k_pci *ab_pci) +{ +struct msi_desc *msi_desc; + + msi_desc =irq_get_msi_desc (ab_pci->pdev->irq); +if (!msi_desc) { +ath11k_err (ab_pci->ab,"msi_desc is NULL!\n" ); +pci_free_irq_vectors (ab_pci->pdev); +return -EINVAL ; + } + + ab_pci->msi_ep_base_data = msi_desc->msg.data; + +ath11k_dbg (ab_pci->ab,ATH11K_DBG_PCI ,"pci after request_irq msi_ep_base_data %d\n" , + ab_pci->msi_ep_base_data); + +return 0 ; +} +static int ath11k_pci_claim (struct ath11k_pci *ab_pci,struct pci_dev *pdev) {struct ath11k_base *ab = ab_pci->ab;
@@ -1328,6 +1347,17 @@ static int ath11k_pci_probe(struct pci_dev *pdev, goto err_ce_free; } +/* kernel may allocate a dummy vector before request_irq and +* then allocate a real vector when request_irq is called. +* So get msi_data here again to avoid spurious interrupt +* as msi_data will configured to srngs. +*/ + ret =ath11k_pci_config_msi_data (ab_pci); +if (ret) { +ath11k_err (ab,"failed to config msi_data: %d\n" , ret); + goto err_free_irq; + } + ret =ath11k_core_init (ab);if (ret) {ath11k_err (ab,"failed to init core: %d\n" , ret);
Signature · 1 line
2.25.1
Quoted 16 lines · Baochen Qiang
The reservation mode of interrupts in kernel assigns a dummy vector when the interrupt is allocated and assigns a real vector when the
request_irqis called. The reservation mode helps to ease vector pressure when devices with a large amount of queues/interrupts are initialized, but only a minimal subset of those queues/interrupts is actually used.So on reservation mode, the
msi_datamay change afterrequest_irqis called, so ath11k readsmsi_dataagain afterrequest_irqis called, and then the correctmsi_datais programmed into QCA6390 hardware components. Without this change, spurious interrupt occurs in case of one MSI vector. When VT-d in BIOS is enabled and ath11k can get 32 MSI vectors, ath11k always get the samemsi_databefore and afterrequest_irq, that's why this change is only required when one MSI vector is to be supported.
Quoted 4 lines
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Signed-off-by Carl Huang <[email protected]>Signed-off-by Kalle Valo <[email protected]>
7 patches applied to ath-next branch of ath.git, thanks.
87b4072d7ef8 ath11k: get msi_data again after request_irq is called 01279bcd01d9 ath11k: add CE and ext IRQ flag to indicate irq_handler 4ab4693f327a ath11k: use ATH11K_PCI_IRQ_DP_OFFSET for DP IRQ c41a6700b276 ath11k: refactor multiple MSI vector implementation ac6e73483f7b ath11k: add support one MSI vector915a081ff307 ath11k: do not restore ASPM in case of single MSI vector e94b07493da3 ath11k: Set IRQ affinity to CPU0 in case of one MSI vector
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches