Skip to content

Commit a3012f2

Browse files
Kang Yangkvalo
authored andcommitted
wifi: ath12k: set IRQ affinity to CPU0 in case of one MSI vector
With VT-d disabled on Intel platform, ath12k gets only one MSI vector. In that case, ath12k does not free IRQ when doing suspend, hence the kernel has to migrate it to CPU0 (if it was affine to other CPUs) and allocates a new MSI vector. However, ath12k has no chance to reconfig it to HW srngs during this phase, thus ath12k fails to resume. This issue can be fixed by setting IRQ affinity to CPU0 before request_irq is called. With such affinity, migration will not happen and thus the vector keeps unchanged during suspend/resume. 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 08d52ba commit a3012f2

File tree

1 file changed

+23
-1
lines changed
  • drivers/net/wireless/ath/ath12k

1 file changed

+23
-1
lines changed

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,15 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
617617
return 0;
618618
}
619619

620+
static int ath12k_pci_set_irq_affinity_hint(struct ath12k_pci *ab_pci,
621+
const struct cpumask *m)
622+
{
623+
if (test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
624+
return 0;
625+
626+
return irq_set_affinity_hint(ab_pci->pdev->irq, m);
627+
}
628+
620629
static int ath12k_pci_config_irq(struct ath12k_base *ab)
621630
{
622631
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
@@ -1359,10 +1368,16 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
13591368
if (ret)
13601369
goto err_pci_msi_free;
13611370

1371+
ret = ath12k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
1372+
if (ret) {
1373+
ath12k_err(ab, "failed to set irq affinity %d\n", ret);
1374+
goto err_pci_msi_free;
1375+
}
1376+
13621377
ret = ath12k_mhi_register(ab_pci);
13631378
if (ret) {
13641379
ath12k_err(ab, "failed to register mhi: %d\n", ret);
1365-
goto err_pci_msi_free;
1380+
goto err_irq_affinity_cleanup;
13661381
}
13671382

13681383
ret = ath12k_hal_srng_init(ab);
@@ -1416,6 +1431,9 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
14161431
err_pci_msi_free:
14171432
ath12k_pci_msi_free(ab_pci);
14181433

1434+
err_irq_affinity_cleanup:
1435+
ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
1436+
14191437
err_pci_free_region:
14201438
ath12k_pci_free_region(ab_pci);
14211439

@@ -1430,6 +1448,8 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
14301448
struct ath12k_base *ab = pci_get_drvdata(pdev);
14311449
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
14321450

1451+
ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
1452+
14331453
if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
14341454
ath12k_pci_power_down(ab);
14351455
ath12k_qmi_deinit_service(ab);
@@ -1456,7 +1476,9 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
14561476
static void ath12k_pci_shutdown(struct pci_dev *pdev)
14571477
{
14581478
struct ath12k_base *ab = pci_get_drvdata(pdev);
1479+
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
14591480

1481+
ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
14601482
ath12k_pci_power_down(ab);
14611483
}
14621484

0 commit comments

Comments
 (0)