]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: fix firmware assert during reboot with hardware grouping
authorAditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
Tue, 8 Apr 2025 06:06:33 +0000 (11:36 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Sat, 12 Apr 2025 04:19:30 +0000 (21:19 -0700)
At present, during PCI shutdown, the power down is only executed for a
single device. However, when operating in a group, all devices need to be
powered down simultaneously. Failure to do so will result in a firmware
assertion.

Hence, introduce a new ath12k_pci_hw_group_power_down() and call it during
power down. This will ensure that all partner devices are properly powered
down.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250408-fix_reboot_issues_with_hw_grouping-v4-5-95e7bf048595@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/pci.c

index 35576f3734d036545e82e546e762b544732cd675..a8a17d6aa75eb7f4b0a71ef1849746bfd291a398 100644 (file)
@@ -1757,13 +1757,34 @@ qmi_fail:
        ath12k_core_free(ab);
 }
 
+static void ath12k_pci_hw_group_power_down(struct ath12k_hw_group *ag)
+{
+       struct ath12k_base *ab;
+       int i;
+
+       if (!ag)
+               return;
+
+       mutex_lock(&ag->mutex);
+
+       for (i = 0; i < ag->num_devices; i++) {
+               ab = ag->ab[i];
+               if (!ab)
+                       continue;
+
+               ath12k_pci_power_down(ab, false);
+       }
+
+       mutex_unlock(&ag->mutex);
+}
+
 static void ath12k_pci_shutdown(struct pci_dev *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, false);
+       ath12k_pci_hw_group_power_down(ab->ag);
 }
 
 static __maybe_unused int ath12k_pci_pm_suspend(struct device *dev)