Skip to content

Commit 1b66601

Browse files
Kang Yangkvalo
authored andcommitted
wifi: ath12k: get msi_data again after request_irq is called
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, then it will lead to spurious interrupt. But when VT-d in BIOS is enabled and ath12k can get 32 MSI vectors, ath12k always get the same msi_data before and after request_irq. So in case of one MSI vector, ath12k need read msi_data again after request_irq is called, and then the correct msi_data is programmed into WCN7850 hardware components. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4 Signed-off-by: Kang Yang <[email protected]> Acked-by: Jeff Johnson <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 8cc18a7 commit 1b66601

File tree

1 file changed

+30
-0
lines changed
  • drivers/net/wireless/ath/ath12k

1 file changed

+30
-0
lines changed

drivers/net/wireless/ath/ath12k/pci.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,25 @@ static void ath12k_pci_msi_free(struct ath12k_pci *ab_pci)
708708
pci_free_irq_vectors(ab_pci->pdev);
709709
}
710710

711+
static int ath12k_pci_config_msi_data(struct ath12k_pci *ab_pci)
712+
{
713+
struct msi_desc *msi_desc;
714+
715+
msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
716+
if (!msi_desc) {
717+
ath12k_err(ab_pci->ab, "msi_desc is NULL!\n");
718+
pci_free_irq_vectors(ab_pci->pdev);
719+
return -EINVAL;
720+
}
721+
722+
ab_pci->msi_ep_base_data = msi_desc->msg.data;
723+
724+
ath12k_dbg(ab_pci->ab, ATH12K_DBG_PCI, "pci after request_irq msi_ep_base_data %d\n",
725+
ab_pci->msi_ep_base_data);
726+
727+
return 0;
728+
}
729+
711730
static int ath12k_pci_claim(struct ath12k_pci *ab_pci, struct pci_dev *pdev)
712731
{
713732
struct ath12k_base *ab = ab_pci->ab;
@@ -1286,6 +1305,17 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
12861305
goto err_ce_free;
12871306
}
12881307

1308+
/* kernel may allocate a dummy vector before request_irq and
1309+
* then allocate a real vector when request_irq is called.
1310+
* So get msi_data here again to avoid spurious interrupt
1311+
* as msi_data will configured to srngs.
1312+
*/
1313+
ret = ath12k_pci_config_msi_data(ab_pci);
1314+
if (ret) {
1315+
ath12k_err(ab, "failed to config msi_data: %d\n", ret);
1316+
goto err_free_irq;
1317+
}
1318+
12891319
ret = ath12k_core_init(ab);
12901320
if (ret) {
12911321
ath12k_err(ab, "failed to init core: %d\n", ret);

0 commit comments

Comments
 (0)