Commit a3012f20 authored by Kang Yang's avatar Kang Yang Committed by Kalle Valo

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: default avatarKang Yang <quic_kangyang@quicinc.com>
Acked-by: default avatarJeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20231121021304.12966-8-quic_kangyang@quicinc.com
parent 08d52ba2
...@@ -617,6 +617,15 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab) ...@@ -617,6 +617,15 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
return 0; return 0;
} }
static int ath12k_pci_set_irq_affinity_hint(struct ath12k_pci *ab_pci,
const struct cpumask *m)
{
if (test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
return 0;
return irq_set_affinity_hint(ab_pci->pdev->irq, m);
}
static int ath12k_pci_config_irq(struct ath12k_base *ab) static int ath12k_pci_config_irq(struct ath12k_base *ab)
{ {
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
...@@ -1359,10 +1368,16 @@ static int ath12k_pci_probe(struct pci_dev *pdev, ...@@ -1359,10 +1368,16 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
if (ret) if (ret)
goto err_pci_msi_free; goto err_pci_msi_free;
ret = ath12k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
if (ret) {
ath12k_err(ab, "failed to set irq affinity %d\n", ret);
goto err_pci_msi_free;
}
ret = ath12k_mhi_register(ab_pci); ret = ath12k_mhi_register(ab_pci);
if (ret) { if (ret) {
ath12k_err(ab, "failed to register mhi: %d\n", ret); ath12k_err(ab, "failed to register mhi: %d\n", ret);
goto err_pci_msi_free; goto err_irq_affinity_cleanup;
} }
ret = ath12k_hal_srng_init(ab); ret = ath12k_hal_srng_init(ab);
...@@ -1416,6 +1431,9 @@ static int ath12k_pci_probe(struct pci_dev *pdev, ...@@ -1416,6 +1431,9 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
err_pci_msi_free: err_pci_msi_free:
ath12k_pci_msi_free(ab_pci); ath12k_pci_msi_free(ab_pci);
err_irq_affinity_cleanup:
ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
err_pci_free_region: err_pci_free_region:
ath12k_pci_free_region(ab_pci); ath12k_pci_free_region(ab_pci);
...@@ -1430,6 +1448,8 @@ static void ath12k_pci_remove(struct pci_dev *pdev) ...@@ -1430,6 +1448,8 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
struct ath12k_base *ab = pci_get_drvdata(pdev); struct ath12k_base *ab = pci_get_drvdata(pdev);
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) { if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
ath12k_pci_power_down(ab); ath12k_pci_power_down(ab);
ath12k_qmi_deinit_service(ab); ath12k_qmi_deinit_service(ab);
...@@ -1456,7 +1476,9 @@ static void ath12k_pci_remove(struct pci_dev *pdev) ...@@ -1456,7 +1476,9 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
static void ath12k_pci_shutdown(struct pci_dev *pdev) static void ath12k_pci_shutdown(struct pci_dev *pdev)
{ {
struct ath12k_base *ab = pci_get_drvdata(pdev); struct ath12k_base *ab = pci_get_drvdata(pdev);
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
ath12k_pci_power_down(ab); ath12k_pci_power_down(ab);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment