wifi: ath12k: handle ath12k_core_reset() with hardware grouping

Currently, in ath12k_core_reset(), the device is powered up immediately
after a power down. However, with hardware grouping, when one device
asserts, all partner devices also asserts. If there is a delay in
processing these asserts, by the time this device powers up, other devices
might still be asserting, leading to an overall recovery failure.

To prevent this issue, ensure all asserts for a group are processed before
initiating the power-up sequence.

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-8-95e7bf048595@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
Aditya Kumar Singh 2025-04-08 11:36:36 +05:30 committed by Jeff Johnson
parent 3e1312f01b
commit 929069c1bd

View File

@ -1582,7 +1582,8 @@ static void ath12k_core_restart(struct work_struct *work)
static void ath12k_core_reset(struct work_struct *work)
{
struct ath12k_base *ab = container_of(work, struct ath12k_base, reset_work);
int reset_count, fail_cont_count;
struct ath12k_hw_group *ag = ab->ag;
int reset_count, fail_cont_count, i;
long time_left;
if (!(test_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags))) {
@ -1641,9 +1642,31 @@ static void ath12k_core_reset(struct work_struct *work)
ath12k_hif_ce_irq_disable(ab);
ath12k_hif_power_down(ab, false);
ath12k_hif_power_up(ab);
ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset started\n");
/* prepare for power up */
ab->qmi.num_radios = U8_MAX;
mutex_lock(&ag->mutex);
ath12k_core_to_group_ref_put(ab);
if (ag->num_started > 0) {
ath12k_dbg(ab, ATH12K_DBG_BOOT,
"waiting for %d partner device(s) to reset\n",
ag->num_started);
mutex_unlock(&ag->mutex);
return;
}
for (i = 0; i < ag->num_devices; i++) {
ab = ag->ab[i];
if (!ab)
continue;
ath12k_hif_power_up(ab);
ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset started\n");
}
mutex_unlock(&ag->mutex);
}
int ath12k_core_pre_init(struct ath12k_base *ab)