Now that the MHI&QRTR patches [1] are merged, we can add
suspend/resume support for ath12k.
The whole design is quite similar to that in ath11k: firmware
is powered down when going to suspend and powered up when
resume, this makes hibernation work as well in addition to
suspend.
To summary, this series first does some preparations in the
first 8 patches. Then in patch [9/10] suspend/resume callbacks
are implemented. And at last in [10/10] we enable suspend/resume
functionality for WCN7850 because it's the only chip supporting
it for now.
[1] https://lore.kernel.org/linux-wireless/[email protected]/
Baochen Qiang (10):
wifi: ath12k: rearrange IRQ enable/disable in reset path
wifi: ath12k: remove MHI LOOPBACK channels
wifi: ath12k: do not dump SRNG statistics during resume
wifi: ath12k: fix warning on DMA ring capabilities event
wifi: ath12k: decrease MHI channel buffer length to 8KB
wifi: ath12k: flush all packets before suspend
wifi: ath12k: no need to handle pktlog during suspend/resume
wifi: ath12k: avoid stopping mac80211 queues in ath12k_core_restart()
wifi: ath12k: support suspend/resume
wifi: ath12k: change supports_suspend to true for WCN7850
drivers/net/wireless/ath/ath12k/core.c | 108 ++++++++++++++----------
drivers/net/wireless/ath/ath12k/core.h | 4 +
drivers/net/wireless/ath/ath12k/dp_rx.c | 48 -----------
drivers/net/wireless/ath/ath12k/dp_rx.h | 2 -
drivers/net/wireless/ath/ath12k/hif.h | 14 ++-
drivers/net/wireless/ath/ath12k/hw.c | 2 +-
drivers/net/wireless/ath/ath12k/mac.c | 28 ++++--
drivers/net/wireless/ath/ath12k/mac.h | 1 +
drivers/net/wireless/ath/ath12k/mhi.c | 91 +++++++-------------
drivers/net/wireless/ath/ath12k/mhi.h | 5 +-
drivers/net/wireless/ath/ath12k/pci.c | 41 +++++++--
drivers/net/wireless/ath/ath12k/pci.h | 2 +-
drivers/net/wireless/ath/ath12k/qmi.c | 3 +-
drivers/net/wireless/ath/ath12k/wmi.c | 1 +
14 files changed, 175 insertions(+), 175 deletions(-)
base-commit: 363e7193eaf258fe7f04e8db560bd8a282a12cd9
--
2.25.1
Both the firmware reset feature and the power management
suspend/resume feature share common power-down and power-up
functionality. One aspect of the power-up functionality is
the handling of the ATH12K_QMI_EVENT_FW_INIT_DONE event.
When this event is received, a call is made to
ath12k_hal_dump_srng_stats(), with the purpose to collect
information that may be useful in debugging the cause of a
firmware reset.
Unfortunately, since this functionality is shared between
both the firmware reset path and the power management
resume path, the kernel log is flooded with messages during
resume. Since these messages are not useful during resume,
and in fact can be confusing and can increase the time it
takes to resume, update the logic to only call
ath12k_hal_dump_srng_stats() during firmware reset.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath12k/qmi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index db8ba5fec2ae..59113ff90727 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -3263,7 +3263,8 @@ static void ath12k_qmi_driver_event_work(struct work_struct *work)
case ATH12K_QMI_EVENT_FW_READY:
clear_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) {
- ath12k_hal_dump_srng_stats(ab);
+ if (ab->is_reset)
+ ath12k_hal_dump_srng_stats(ab);
queue_work(ab->workqueue, &ab->restart_work);
break;
}
--
2.25.1
Now that all infrastructure is in place and ath12k is fixed to handle all the
corner cases, power down the ath12k firmware during suspend and power it back
up during resume.
For suspend, two conditions needs to be satisfied:
1. since MHI channel unprepare would be done in late suspend stage,
ath12k needs to get all QMI-dependent things done before that stage.
2. and because unprepare MHI channels requires a working MHI stack,
ath12k is not allowed to call mhi_power_down() until that finishes.
So the original suspend callback is separated into two parts: the first part
handles all QMI-dependent things in suspend callback; while the second part
powers down MHI in suspend_late callback. This is valid because kernel calls
ath12k's suspend callback before calling all suspend_late callbacks, making
the first condition satisfied. And because MHI devices are children of ath12k
device (ab->dev), kernel guarantees that ath12k's suspend_late callback is
called after QRTR's suspend_late callback, this satisfies the second condition.
Above analysis also applies to resume process. so the original resume
callback is separated into two parts: the first part powers up MHI stack
in resume_early callback, this guarantees MHI stack is working when
QRTR tries to prepare MHI channels (kernel calls QRTR's resume_early callback
after ath12k's resume_early callback, due to the child-father relationship);
the second part waits for the completion of restart, which would succeed
since MHI channels are ready for use by QMI.
Another notable change is in power down path, we tell mhi_power_down() to not
to destroy MHI devices, making it possible for QRTR to help unprepare/prepare
MHI channels, and finally get us rid of the potential probe-defer issue when
resume.
Also change related code due to interface changes.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath12k/core.c | 67 ++++++++++++++++++++------
drivers/net/wireless/ath/ath12k/core.h | 4 ++
drivers/net/wireless/ath/ath12k/hif.h | 14 ++++--
drivers/net/wireless/ath/ath12k/mhi.c | 33 +++++++++++--
drivers/net/wireless/ath/ath12k/mhi.h | 5 +-
drivers/net/wireless/ath/ath12k/pci.c | 41 +++++++++++++---
drivers/net/wireless/ath/ath12k/pci.h | 2 +-
7 files changed, 134 insertions(+), 32 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 380a3c8f7201..aefe667c3dcb 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -64,36 +64,70 @@ int ath12k_core_suspend(struct ath12k_base *ab)
}
rcu_read_unlock();
+ /* PM framework skips suspend_late/resume_early callbacks
+ * if other devices report errors in their suspend callbacks.
+ * However ath12k_core_resume() would still be called because
+ * here we return success thus kernel put us on dpm_suspended_list.
+ * Since we won't go through a power down/up cycle, there is
+ * no chance to call complete(&ab->restart_completed) in
+ * ath12k_core_restart(), making ath12k_core_resume() timeout.
+ * So call it here to avoid this issue. This also works in case
+ * no error happens thus suspend_late/resume_early get called,
+ * because it will be reinitialized in ath12k_core_resume_early().
+ */
+ complete(&ab->restart_completed);
+
+ return 0;
+}
+EXPORT_SYMBOL(ath12k_core_suspend);
+
+int ath12k_core_suspend_late(struct ath12k_base *ab)
+{
+ if (!ab->hw_params->supports_suspend)
+ return -EOPNOTSUPP;
+
ath12k_hif_irq_disable(ab);
ath12k_hif_ce_irq_disable(ab);
- ret = ath12k_hif_suspend(ab);
- if (ret) {
- ath12k_warn(ab, "failed to suspend hif: %d\n", ret);
- return ret;
- }
+ ath12k_hif_power_down(ab, true);
return 0;
}
+EXPORT_SYMBOL(ath12k_core_suspend_late);
-int ath12k_core_resume(struct ath12k_base *ab)
+int ath12k_core_resume_early(struct ath12k_base *ab)
{
int ret;
if (!ab->hw_params->supports_suspend)
return -EOPNOTSUPP;
- ret = ath12k_hif_resume(ab);
- if (ret) {
- ath12k_warn(ab, "failed to resume hif during resume: %d\n", ret);
- return ret;
- }
+ reinit_completion(&ab->restart_completed);
+ ret = ath12k_hif_power_up(ab);
+ if (ret)
+ ath12k_warn(ab, "failed to power up hif during resume: %d\n", ret);
- ath12k_hif_ce_irq_enable(ab);
- ath12k_hif_irq_enable(ab);
+ return ret;
+}
+EXPORT_SYMBOL(ath12k_core_resume_early);
+
+int ath12k_core_resume(struct ath12k_base *ab)
+{
+ long time_left;
+
+ if (!ab->hw_params->supports_suspend)
+ return -EOPNOTSUPP;
+
+ time_left = wait_for_completion_timeout(&ab->restart_completed,
+ ATH12K_RESET_TIMEOUT_HZ);
+ if (time_left == 0) {
+ ath12k_warn(ab, "timeout while waiting for restart complete");
+ return -ETIMEDOUT;
+ }
return 0;
}
+EXPORT_SYMBOL(ath12k_core_resume);
static int __ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
size_t name_len, bool with_variant,
@@ -1053,6 +1087,8 @@ static void ath12k_core_restart(struct work_struct *work)
if (ab->is_reset)
complete_all(&ab->reconfigure_complete);
+
+ complete(&ab->restart_completed);
}
static void ath12k_core_reset(struct work_struct *work)
@@ -1121,7 +1157,7 @@ static void ath12k_core_reset(struct work_struct *work)
ath12k_hif_irq_disable(ab);
ath12k_hif_ce_irq_disable(ab);
- ath12k_hif_power_down(ab);
+ ath12k_hif_power_down(ab, false);
ath12k_qmi_free_resource(ab);
ath12k_hif_power_up(ab);
@@ -1165,7 +1201,7 @@ void ath12k_core_deinit(struct ath12k_base *ab)
mutex_unlock(&ab->core_lock);
- ath12k_hif_power_down(ab);
+ ath12k_hif_power_down(ab, false);
ath12k_mac_destroy(ab);
ath12k_core_soc_destroy(ab);
ath12k_fw_unmap(ab);
@@ -1213,6 +1249,7 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
timer_setup(&ab->rx_replenish_retry, ath12k_ce_rx_replenish_retry, 0);
init_completion(&ab->htc_suspend);
+ init_completion(&ab->restart_completed);
ab->dev = dev;
ab->hif.bus = bus;
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 397d8c973265..c4a3912567d9 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -901,6 +901,8 @@ struct ath12k_base {
*/
u8 mlo_capable_flags;
+ struct completion restart_completed;
+
/* must be last */
u8 drv_priv[] __aligned(sizeof(void *));
};
@@ -927,8 +929,10 @@ int ath12k_core_fetch_regdb(struct ath12k_base *ab, struct ath12k_board_data *bd
int ath12k_core_check_dt(struct ath12k_base *ath12k);
int ath12k_core_check_smbios(struct ath12k_base *ab);
void ath12k_core_halt(struct ath12k *ar);
+int ath12k_core_resume_early(struct ath12k_base *ab);
int ath12k_core_resume(struct ath12k_base *ab);
int ath12k_core_suspend(struct ath12k_base *ab);
+int ath12k_core_suspend_late(struct ath12k_base *ab);
const struct firmware *ath12k_core_firmware_request(struct ath12k_base *ab,
const char *filename);
diff --git a/drivers/net/wireless/ath/ath12k/hif.h b/drivers/net/wireless/ath/ath12k/hif.h
index c653ca1f59b2..7f0926fe751d 100644
--- a/drivers/net/wireless/ath/ath12k/hif.h
+++ b/drivers/net/wireless/ath/ath12k/hif.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_HIF_H
@@ -17,7 +17,7 @@ struct ath12k_hif_ops {
int (*start)(struct ath12k_base *ab);
void (*stop)(struct ath12k_base *ab);
int (*power_up)(struct ath12k_base *ab);
- void (*power_down)(struct ath12k_base *ab);
+ void (*power_down)(struct ath12k_base *ab, bool is_suspend);
int (*suspend)(struct ath12k_base *ab);
int (*resume)(struct ath12k_base *ab);
int (*map_service_to_pipe)(struct ath12k_base *ab, u16 service_id,
@@ -133,12 +133,18 @@ static inline void ath12k_hif_write32(struct ath12k_base *ab, u32 address,
static inline int ath12k_hif_power_up(struct ath12k_base *ab)
{
+ if (!ab->hif.ops->power_up)
+ return -EOPNOTSUPP;
+
return ab->hif.ops->power_up(ab);
}
-static inline void ath12k_hif_power_down(struct ath12k_base *ab)
+static inline void ath12k_hif_power_down(struct ath12k_base *ab, bool is_suspend)
{
- ab->hif.ops->power_down(ab);
+ if (!ab->hif.ops->power_down)
+ return;
+
+ ab->hif.ops->power_down(ab, is_suspend);
}
#endif /* ATH12K_HIF_H */
diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c
index d6083a187021..72d3e804f453 100644
--- a/drivers/net/wireless/ath/ath12k/mhi.c
+++ b/drivers/net/wireless/ath/ath12k/mhi.c
@@ -414,6 +414,8 @@ static char *ath12k_mhi_state_to_str(enum ath12k_mhi_state mhi_state)
return "POWER_ON";
case ATH12K_MHI_POWER_OFF:
return "POWER_OFF";
+ case ATH12K_MHI_POWER_OFF_KEEP_DEV:
+ return "POWER_OFF_KEEP_DEV";
case ATH12K_MHI_FORCE_POWER_OFF:
return "FORCE_POWER_OFF";
case ATH12K_MHI_SUSPEND:
@@ -445,6 +447,7 @@ static void ath12k_mhi_set_state_bit(struct ath12k_pci *ab_pci,
set_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state);
break;
case ATH12K_MHI_POWER_OFF:
+ case ATH12K_MHI_POWER_OFF_KEEP_DEV:
case ATH12K_MHI_FORCE_POWER_OFF:
clear_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state);
clear_bit(ATH12K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state);
@@ -488,6 +491,7 @@ static int ath12k_mhi_check_state_bit(struct ath12k_pci *ab_pci,
return 0;
break;
case ATH12K_MHI_POWER_OFF:
+ case ATH12K_MHI_POWER_OFF_KEEP_DEV:
case ATH12K_MHI_SUSPEND:
if (test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state) &&
!test_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state))
@@ -538,12 +542,27 @@ static int ath12k_mhi_set_state(struct ath12k_pci *ab_pci,
ret = 0;
break;
case ATH12K_MHI_POWER_ON:
- ret = mhi_async_power_up(ab_pci->mhi_ctrl);
+ /* In case of resume, QRTR's resume_early() is called
+ * right after ath12k' resume_early(). Since QRTR requires
+ * MHI mission mode state when preparing IPCR channels
+ * (see ee_mask of that channel), we need to use the 'sync'
+ * version here to make sure MHI is in that state when we
+ * return. Or QRTR might resume before that state comes,
+ * and as a result it fails.
+ *
+ * The 'sync' version works for non-resume (normal power on)
+ * case as well.
+ */
+ ret = mhi_sync_power_up(ab_pci->mhi_ctrl);
break;
case ATH12K_MHI_POWER_OFF:
mhi_power_down(ab_pci->mhi_ctrl, true);
ret = 0;
break;
+ case ATH12K_MHI_POWER_OFF_KEEP_DEV:
+ mhi_power_down_keep_dev(ab_pci->mhi_ctrl, true);
+ ret = 0;
+ break;
case ATH12K_MHI_FORCE_POWER_OFF:
mhi_power_down(ab_pci->mhi_ctrl, false);
ret = 0;
@@ -597,9 +616,17 @@ int ath12k_mhi_start(struct ath12k_pci *ab_pci)
return ret;
}
-void ath12k_mhi_stop(struct ath12k_pci *ab_pci)
+void ath12k_mhi_stop(struct ath12k_pci *ab_pci, bool is_suspend)
{
- ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_OFF);
+ /* During suspend we need to use mhi_power_down_keep_dev()
+ * workaround, otherwise ath12k_core_resume() will timeout
+ * during resume.
+ */
+ if (is_suspend)
+ ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_OFF_KEEP_DEV);
+ else
+ ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_OFF);
+
ath12k_mhi_set_state(ab_pci, ATH12K_MHI_DEINIT);
}
diff --git a/drivers/net/wireless/ath/ath12k/mhi.h b/drivers/net/wireless/ath/ath12k/mhi.h
index ebc23640ce7a..9362ad1958c3 100644
--- a/drivers/net/wireless/ath/ath12k/mhi.h
+++ b/drivers/net/wireless/ath/ath12k/mhi.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ATH12K_MHI_H
#define _ATH12K_MHI_H
@@ -22,6 +22,7 @@ enum ath12k_mhi_state {
ATH12K_MHI_DEINIT,
ATH12K_MHI_POWER_ON,
ATH12K_MHI_POWER_OFF,
+ ATH12K_MHI_POWER_OFF_KEEP_DEV,
ATH12K_MHI_FORCE_POWER_OFF,
ATH12K_MHI_SUSPEND,
ATH12K_MHI_RESUME,
@@ -34,7 +35,7 @@ extern const struct mhi_controller_config ath12k_mhi_config_qcn9274;
extern const struct mhi_controller_config ath12k_mhi_config_wcn7850;
int ath12k_mhi_start(struct ath12k_pci *ar_pci);
-void ath12k_mhi_stop(struct ath12k_pci *ar_pci);
+void ath12k_mhi_stop(struct ath12k_pci *ar_pci, bool is_suspend);
int ath12k_mhi_register(struct ath12k_pci *ar_pci);
void ath12k_mhi_unregister(struct ath12k_pci *ar_pci);
void ath12k_mhi_set_mhictrl_reset(struct ath12k_base *ab);
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index 14954bc05144..752b30809a43 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -1271,7 +1271,7 @@ int ath12k_pci_power_up(struct ath12k_base *ab)
return 0;
}
-void ath12k_pci_power_down(struct ath12k_base *ab)
+void ath12k_pci_power_down(struct ath12k_base *ab, bool is_suspend)
{
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
@@ -1280,7 +1280,7 @@ void ath12k_pci_power_down(struct ath12k_base *ab)
ath12k_pci_force_wake(ab_pci->ab);
ath12k_pci_msi_disable(ab_pci);
- ath12k_mhi_stop(ab_pci);
+ ath12k_mhi_stop(ab_pci, is_suspend);
clear_bit(ATH12K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
ath12k_pci_sw_reset(ab_pci->ab, false);
}
@@ -1503,7 +1503,7 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
- ath12k_pci_power_down(ab);
+ ath12k_pci_power_down(ab, false);
ath12k_qmi_deinit_service(ab);
goto qmi_fail;
}
@@ -1531,7 +1531,7 @@ static void ath12k_pci_shutdown(struct pci_dev *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, false);
}
static __maybe_unused int ath12k_pci_pm_suspend(struct device *dev)
@@ -1558,9 +1558,36 @@ static __maybe_unused int ath12k_pci_pm_resume(struct device *dev)
return ret;
}
-static SIMPLE_DEV_PM_OPS(ath12k_pci_pm_ops,
- ath12k_pci_pm_suspend,
- ath12k_pci_pm_resume);
+static __maybe_unused int ath12k_pci_pm_suspend_late(struct device *dev)
+{
+ struct ath12k_base *ab = dev_get_drvdata(dev);
+ int ret;
+
+ ret = ath12k_core_suspend_late(ab);
+ if (ret)
+ ath12k_warn(ab, "failed to late suspend core: %d\n", ret);
+
+ return ret;
+}
+
+static __maybe_unused int ath12k_pci_pm_resume_early(struct device *dev)
+{
+ struct ath12k_base *ab = dev_get_drvdata(dev);
+ int ret;
+
+ ret = ath12k_core_resume_early(ab);
+ if (ret)
+ ath12k_warn(ab, "failed to early resume core: %d\n", ret);
+
+ return ret;
+}
+
+static const struct dev_pm_ops __maybe_unused ath12k_pci_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ath12k_pci_pm_suspend,
+ ath12k_pci_pm_resume)
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(ath12k_pci_pm_suspend_late,
+ ath12k_pci_pm_resume_early)
+};
static struct pci_driver ath12k_pci_driver = {
.name = "ath12k_pci",
diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h
index ca93693ba4e9..6186a78038cf 100644
--- a/drivers/net/wireless/ath/ath12k/pci.h
+++ b/drivers/net/wireless/ath/ath12k/pci.h
@@ -143,5 +143,5 @@ int ath12k_pci_hif_resume(struct ath12k_base *ab);
void ath12k_pci_stop(struct ath12k_base *ab);
int ath12k_pci_start(struct ath12k_base *ab);
int ath12k_pci_power_up(struct ath12k_base *ab);
-void ath12k_pci_power_down(struct ath12k_base *ab);
+void ath12k_pci_power_down(struct ath12k_base *ab, bool is_suspend);
#endif /* ATH12K_PCI_H */
--
2.25.1
Currently buf_len field of ath12k_mhi_config_wcn7850 is assigned
with 0, making MHI use a default size, 64KB, to allocate channel
buffers. This is likely to fail in some scenarios where system
memory is highly fragmented and memory compaction or reclaim is
not allowed.
For now we haven't get any failure report on this in ath12k, but
there indeed is one such case in ath11k [1].
Actually those buffers are used only by QMI target -> host communication.
And for WCN7850, the largest packet size for that is less than 6KB. So
change buf_len field to 8KB, which results in order 1 allocation if page
size is 4KB. In this way, we can at least save some memory, and as well
as decrease the possibility of allocation failure in those scenarios.
[1] https://lore.kernel.org/ath11k/[email protected]/
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath12k/mhi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c
index 403691355abf..d6083a187021 100644
--- a/drivers/net/wireless/ath/ath12k/mhi.c
+++ b/drivers/net/wireless/ath/ath12k/mhi.c
@@ -140,7 +140,7 @@ const struct mhi_controller_config ath12k_mhi_config_wcn7850 = {
.max_channels = 128,
.timeout_ms = 2000,
.use_bounce_buf = false,
- .buf_len = 0,
+ .buf_len = 8192,
.num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850),
.ch_cfg = ath12k_mhi_channels_wcn7850,
.num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850),
--
2.25.1
In order to send out all packets before going to suspend, current code
adds a 500ms delay as a workaround. It is a rough estimate and may not
work.
Fix this by checking packet counters, if counters become zero, then all
packets are sent out or dropped.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath12k/core.c | 20 +++++++++++++-----
drivers/net/wireless/ath/ath12k/mac.c | 28 ++++++++++++++++++++------
drivers/net/wireless/ath/ath12k/mac.h | 1 +
3 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 28663cf4db30..dfec390b66c6 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -44,15 +44,25 @@ static int ath12k_core_rfkill_config(struct ath12k_base *ab)
int ath12k_core_suspend(struct ath12k_base *ab)
{
- int ret;
+ struct ath12k *ar;
+ int ret, i;
if (!ab->hw_params->supports_suspend)
return -EOPNOTSUPP;
- /* TODO: there can frames in queues so for now add delay as a hack.
- * Need to implement to handle and remove this delay.
- */
- msleep(500);
+ rcu_read_lock();
+ for (i = 0; i < ab->num_radios; i++) {
+ ar = ath12k_mac_get_ar_by_pdev_id(ab, i);
+ if (!ar)
+ continue;
+ ret = ath12k_mac_wait_tx_complete(ar);
+ if (ret) {
+ ath12k_warn(ab, "failed to wait tx complete: %d\n", ret);
+ rcu_read_unlock();
+ return ret;
+ }
+ }
+ rcu_read_unlock();
ret = ath12k_dp_rx_pktlog_stop(ab, true);
if (ret) {
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index f15dcd75157d..69c5fd9d2612 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -7356,22 +7356,38 @@ static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
return -EOPNOTSUPP;
}
-static void ath12k_mac_flush(struct ath12k *ar)
+static int ath12k_mac_flush(struct ath12k *ar)
{
long time_left;
+ int ret = 0;
time_left = wait_event_timeout(ar->dp.tx_empty_waitq,
(atomic_read(&ar->dp.num_tx_pending) == 0),
ATH12K_FLUSH_TIMEOUT);
- if (time_left == 0)
- ath12k_warn(ar->ab, "failed to flush transmit queue %ld\n", time_left);
+ if (time_left == 0) {
+ ath12k_warn(ar->ab,
+ "failed to flush transmit queue, data pkts pending %d\n",
+ atomic_read(&ar->dp.num_tx_pending));
+ ret = -ETIMEDOUT;
+ }
time_left = wait_event_timeout(ar->txmgmt_empty_waitq,
(atomic_read(&ar->num_pending_mgmt_tx) == 0),
ATH12K_FLUSH_TIMEOUT);
- if (time_left == 0)
- ath12k_warn(ar->ab, "failed to flush mgmt transmit queue %ld\n",
- time_left);
+ if (time_left == 0) {
+ ath12k_warn(ar->ab,
+ "failed to flush mgmt transmit queue, mgmt pkts pending %d\n",
+ atomic_read(&ar->num_pending_mgmt_tx));
+ ret = -ETIMEDOUT;
+ }
+
+ return ret;
+}
+
+int ath12k_mac_wait_tx_complete(struct ath12k *ar)
+{
+ ath12k_mac_drain_tx(ar);
+ return ath12k_mac_flush(ar);
}
static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h
index 3f5e1be0dff9..f826822d30c8 100644
--- a/drivers/net/wireless/ath/ath12k/mac.h
+++ b/drivers/net/wireless/ath/ath12k/mac.h
@@ -78,4 +78,5 @@ enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw b
enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher);
int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable);
int ath12k_mac_rfkill_config(struct ath12k *ar);
+int ath12k_mac_wait_tx_complete(struct ath12k *ar);
#endif
--
2.25.1
Now that all things are ready, enable supports_suspend to
make suspend/resume work for WCN7850. Don't touch other
chips because they don't support suspend.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath12k/hw.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c
index 0b17dfd47856..613c2a9c0056 100644
--- a/drivers/net/wireless/ath/ath12k/hw.c
+++ b/drivers/net/wireless/ath/ath12k/hw.c
@@ -964,7 +964,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.idle_ps = true,
.download_calib = false,
- .supports_suspend = false,
+ .supports_suspend = true,
.tcl_ring_retry = false,
.reoq_lut_support = false,
.supports_shadow_regs = true,
--
2.25.1
Currently pktlog is stopped in suspend callback and started in
resume callback, and in either scenarios it's basically to
delete/modify ab->mon_reap_timer and to purge related rings.
For WCN7850 it's pointless because pktlog is not enabled: both
ab->mon_reap_timer and those rings are not initialized.
So remove pktlog handling in suspend/resume callbacks. And
further, remove these two functions and related callee because
no one is calling them.
Other chips are not affected because now only WCN7850 supports
suspend/resume.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath12k/core.c | 21 -----------
drivers/net/wireless/ath/ath12k/dp_rx.c | 48 -------------------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 2 --
3 files changed, 71 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index dfec390b66c6..aeb7f9e43cc4 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -64,20 +64,6 @@ int ath12k_core_suspend(struct ath12k_base *ab)
}
rcu_read_unlock();
- ret = ath12k_dp_rx_pktlog_stop(ab, true);
- if (ret) {
- ath12k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
- ret);
- return ret;
- }
-
- ret = ath12k_dp_rx_pktlog_stop(ab, false);
- if (ret) {
- ath12k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
- ret);
- return ret;
- }
-
ath12k_hif_irq_disable(ab);
ath12k_hif_ce_irq_disable(ab);
@@ -106,13 +92,6 @@ int ath12k_core_resume(struct ath12k_base *ab)
ath12k_hif_ce_irq_enable(ab);
ath12k_hif_irq_enable(ab);
- ret = ath12k_dp_rx_pktlog_start(ab);
- if (ret) {
- ath12k_warn(ab, "failed to start rx pktlog during resume: %d\n",
- ret);
- return ret;
- }
-
return 0;
}
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index a593beecdd12..dd6d9b2a5bcf 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -239,28 +239,6 @@ static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab,
return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc);
}
-static int ath12k_dp_purge_mon_ring(struct ath12k_base *ab)
-{
- int i, reaped = 0;
- unsigned long timeout = jiffies + msecs_to_jiffies(DP_MON_PURGE_TIMEOUT_MS);
-
- do {
- for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++)
- reaped += ath12k_dp_mon_process_ring(ab, i, NULL,
- DP_MON_SERVICE_BUDGET,
- ATH12K_DP_RX_MONITOR_MODE);
-
- /* nothing more to reap */
- if (reaped < DP_MON_SERVICE_BUDGET)
- return 0;
-
- } while (time_before(jiffies, timeout));
-
- ath12k_warn(ab, "dp mon ring purge timeout");
-
- return -ETIMEDOUT;
-}
-
static size_t ath12k_dp_list_cut_nodes(struct list_head *list,
struct list_head *head,
size_t count)
@@ -4264,29 +4242,3 @@ int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar)
return 0;
}
-
-int ath12k_dp_rx_pktlog_start(struct ath12k_base *ab)
-{
- /* start reap timer */
- mod_timer(&ab->mon_reap_timer,
- jiffies + msecs_to_jiffies(ATH12K_MON_TIMER_INTERVAL));
-
- return 0;
-}
-
-int ath12k_dp_rx_pktlog_stop(struct ath12k_base *ab, bool stop_timer)
-{
- int ret;
-
- if (stop_timer)
- del_timer_sync(&ab->mon_reap_timer);
-
- /* reap all the monitor related rings */
- ret = ath12k_dp_purge_mon_ring(ab);
- if (ret) {
- ath12k_warn(ab, "failed to purge dp mon ring: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index 25940061ead5..6b8e22a5b43c 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -123,8 +123,6 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar);
int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id);
-int ath12k_dp_rx_pktlog_start(struct ath12k_base *ab);
-int ath12k_dp_rx_pktlog_stop(struct ath12k_base *ab, bool stop_timer);
u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab,
struct hal_rx_desc *desc);
struct ath12k_peer *
--
2.25.1
We are seeing below warning in both reset and suspend/resume scenarios:
[ 4153.776040] ath12k_pci 0000:04:00.0: Already processed, so ignoring dma ring caps
This is because ab->num_db_cap is not cleared in
ath12k_wmi_free_dbring_caps(), so clear it to avoid such
warnings.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath12k/wmi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index a5575ce9eed4..0fb1fdb935e1 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -4041,6 +4041,7 @@ static void ath12k_wmi_free_dbring_caps(struct ath12k_base *ab)
{
kfree(ab->db_caps);
ab->db_caps = NULL;
+ ab->num_db_cap = 0;
}
static int ath12k_wmi_dma_ring_caps(struct ath12k_base *ab,
--
2.25.1
Currently when resume ath12k_core_restart() calls
ath12k_core_pre_reconfigure_recovery() where mac80211 queues are
stopped by calling ieee80211_stop_queues(). Then in
ath12k_mac_op_reconfig_complete() those queues are not started
because ieee80211_wake_queues() is skipped due to the check on
reconfig_type. The result is that mac80211
could not deliver any frame to ath12k to send out, finally making
connection fail.
[84473.104249] PM: suspend exit
[84479.372397] wlan0: no VHT 160 MHz capability on 5 GHz, limiting to 80 MHz
[84479.372401] wlan0: determined local STA to be EHT, BW limited to 80 MHz
[84479.372416] wlan0: determined AP 00:03:7f:12:b7:b7 to be HE
[84479.372420] wlan0: connecting with HE mode, max bandwidth 80 MHz
[84479.580348] wlan0: authenticate with 00:03:7f:12:b7:b7 (local address=00:03:7f:37:11:53)
[84479.580351] wlan0: send auth to 00:03:7f:12:b7:b7 (try 1/3)
[84480.698993] wlan0: send auth to 00:03:7f:12:b7:b7 (try 2/3)
[84481.816505] wlan0: send auth to 00:03:7f:12:b7:b7 (try 3/3)
[84482.810966] wlan0: authentication with 00:03:7f:12:b7:b7 timed out
Actually we don't need to stop/start queues during suspend/resume,
so remove ath12k_core_pre_reconfigure_recovery() from ath12k_core_restart().
This won't cause any regression because currently the only chance
ath12k_core_restart() gets called is in reset case, where ab->is_reset
is set so that function will never be executed.
Also remove ath12k_core_post_reconfigure_recovery() because it is
not needed in suspend/resume case. This is also valid due to above
analysis.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath12k/core.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index aeb7f9e43cc4..380a3c8f7201 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -1045,9 +1045,6 @@ static void ath12k_core_restart(struct work_struct *work)
struct ath12k_base *ab = container_of(work, struct ath12k_base, restart_work);
int ret;
- if (!ab->is_reset)
- ath12k_core_pre_reconfigure_recovery(ab);
-
ret = ath12k_core_reconfigure_on_crash(ab);
if (ret) {
ath12k_err(ab, "failed to reconfigure driver on crash recovery\n");
@@ -1056,9 +1053,6 @@ static void ath12k_core_restart(struct work_struct *work)
if (ab->is_reset)
complete_all(&ab->reconfigure_complete);
-
- if (!ab->is_reset)
- ath12k_core_post_reconfigure_recovery(ab);
}
static void ath12k_core_reset(struct work_struct *work)
--
2.25.1
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> Now that the MHI&QRTR patches [1] are merged, we can add
> suspend/resume support for ath12k.
>
> The whole design is quite similar to that in ath11k: firmware
> is powered down when going to suspend and powered up when
> resume, this makes hibernation work as well in addition to
> suspend.
>
> To summary, this series first does some preparations in the
> first 8 patches. Then in patch [9/10] suspend/resume callbacks
> are implemented. And at last in [10/10] we enable suspend/resume
> functionality for WCN7850 because it's the only chip supporting
> it for now.
>
> [1] https://lore.kernel.org/linux-wireless/[email protected]/
>
> Baochen Qiang (10):
> wifi: ath12k: rearrange IRQ enable/disable in reset path
> wifi: ath12k: remove MHI LOOPBACK channels
> wifi: ath12k: do not dump SRNG statistics during resume
> wifi: ath12k: fix warning on DMA ring capabilities event
> wifi: ath12k: decrease MHI channel buffer length to 8KB
> wifi: ath12k: flush all packets before suspend
> wifi: ath12k: no need to handle pktlog during suspend/resume
> wifi: ath12k: avoid stopping mac80211 queues in ath12k_core_restart()
> wifi: ath12k: support suspend/resume
> wifi: ath12k: change supports_suspend to true for WCN7850
>
> drivers/net/wireless/ath/ath12k/core.c | 108 ++++++++++++++----------
> drivers/net/wireless/ath/ath12k/core.h | 4 +
> drivers/net/wireless/ath/ath12k/dp_rx.c | 48 -----------
> drivers/net/wireless/ath/ath12k/dp_rx.h | 2 -
My Qualcomm Innovation Center copyright checker reports:
drivers/net/wireless/ath/ath12k/dp_rx.h copyright missing 2024
> drivers/net/wireless/ath/ath12k/hif.h | 14 ++-
> drivers/net/wireless/ath/ath12k/hw.c | 2 +-
> drivers/net/wireless/ath/ath12k/mac.c | 28 ++++--
> drivers/net/wireless/ath/ath12k/mac.h | 1 +
> drivers/net/wireless/ath/ath12k/mhi.c | 91 +++++++-------------
> drivers/net/wireless/ath/ath12k/mhi.h | 5 +-
> drivers/net/wireless/ath/ath12k/pci.c | 41 +++++++--
> drivers/net/wireless/ath/ath12k/pci.h | 2 +-
> drivers/net/wireless/ath/ath12k/qmi.c | 3 +-
> drivers/net/wireless/ath/ath12k/wmi.c | 1 +
> 14 files changed, 175 insertions(+), 175 deletions(-)
>
>
> base-commit: 363e7193eaf258fe7f04e8db560bd8a282a12cd9
patch 6 of this series conflicts with:
wifi: ath12k: add support to handle beacon miss for WCN7850
So I was not able to take this series into my local verification tree
patch 7 of this series conflicts with:
wifi: ath12k: fix mac id extraction when MSDU spillover in rx error path
So this conflicts with a patch already in the pending branch
So FYI at some point you'll need to rebase.
On 4/13/2024 2:05 AM, Jeff Johnson wrote:
> On 4/11/2024 11:06 PM, Baochen Qiang wrote:
>> Now that the MHI&QRTR patches [1] are merged, we can add
>> suspend/resume support for ath12k.
>>
>> The whole design is quite similar to that in ath11k: firmware
>> is powered down when going to suspend and powered up when
>> resume, this makes hibernation work as well in addition to
>> suspend.
>>
>> To summary, this series first does some preparations in the
>> first 8 patches. Then in patch [9/10] suspend/resume callbacks
>> are implemented. And at last in [10/10] we enable suspend/resume
>> functionality for WCN7850 because it's the only chip supporting
>> it for now.
>>
>> [1] https://lore.kernel.org/linux-wireless/[email protected]/
>>
>> Baochen Qiang (10):
>> wifi: ath12k: rearrange IRQ enable/disable in reset path
>> wifi: ath12k: remove MHI LOOPBACK channels
>> wifi: ath12k: do not dump SRNG statistics during resume
>> wifi: ath12k: fix warning on DMA ring capabilities event
>> wifi: ath12k: decrease MHI channel buffer length to 8KB
>> wifi: ath12k: flush all packets before suspend
>> wifi: ath12k: no need to handle pktlog during suspend/resume
>> wifi: ath12k: avoid stopping mac80211 queues in ath12k_core_restart()
>> wifi: ath12k: support suspend/resume
>> wifi: ath12k: change supports_suspend to true for WCN7850
>>
>> drivers/net/wireless/ath/ath12k/core.c | 108 ++++++++++++++----------
>> drivers/net/wireless/ath/ath12k/core.h | 4 +
>> drivers/net/wireless/ath/ath12k/dp_rx.c | 48 -----------
>> drivers/net/wireless/ath/ath12k/dp_rx.h | 2 -
> My Qualcomm Innovation Center copyright checker reports:
> drivers/net/wireless/ath/ath12k/dp_rx.h copyright missing 2024
Got it.
>
>> drivers/net/wireless/ath/ath12k/hif.h | 14 ++-
>> drivers/net/wireless/ath/ath12k/hw.c | 2 +-
>> drivers/net/wireless/ath/ath12k/mac.c | 28 ++++--
>> drivers/net/wireless/ath/ath12k/mac.h | 1 +
>> drivers/net/wireless/ath/ath12k/mhi.c | 91 +++++++-------------
>> drivers/net/wireless/ath/ath12k/mhi.h | 5 +-
>> drivers/net/wireless/ath/ath12k/pci.c | 41 +++++++--
>> drivers/net/wireless/ath/ath12k/pci.h | 2 +-
>> drivers/net/wireless/ath/ath12k/qmi.c | 3 +-
>> drivers/net/wireless/ath/ath12k/wmi.c | 1 +
>> 14 files changed, 175 insertions(+), 175 deletions(-)
>>
>>
>> base-commit: 363e7193eaf258fe7f04e8db560bd8a282a12cd9
> patch 6 of this series conflicts with:
> wifi: ath12k: add support to handle beacon miss for WCN7850
>
> So I was not able to take this series into my local verification tree
>
> patch 7 of this series conflicts with:
> wifi: ath12k: fix mac id extraction when MSDU spillover in rx error path
>
> So this conflicts with a patch already in the pending branch
>
> So FYI at some point you'll need to rebase.
So I should rebase after these two patches got merged in master branch?
Baochen Qiang <[email protected]> writes:
>> patch 6 of this series conflicts with:
>> wifi: ath12k: add support to handle beacon miss for WCN7850
>>
>> So I was not able to take this series into my local verification tree
>>
>> patch 7 of this series conflicts with:
>> wifi: ath12k: fix mac id extraction when MSDU spillover in rx error path
>>
>> So this conflicts with a patch already in the pending branch
>>
>> So FYI at some point you'll need to rebase.
>
> So I should rebase after these two patches got merged in master branch?
No need to rebase at this time. In the pending branch I was able to fix
the conflict in patch 7. Please check:
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=b92086862c7be6e6810eca204052cada50fc0f5f
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
On 4/16/2024 4:28 PM, Kalle Valo wrote:
> Baochen Qiang <[email protected]> writes:
>
>>> patch 6 of this series conflicts with:
>>> wifi: ath12k: add support to handle beacon miss for WCN7850
>>>
>>> So I was not able to take this series into my local verification tree
>>>
>>> patch 7 of this series conflicts with:
>>> wifi: ath12k: fix mac id extraction when MSDU spillover in rx error path
>>>
>>> So this conflicts with a patch already in the pending branch
>>>
>>> So FYI at some point you'll need to rebase.
>> So I should rebase after these two patches got merged in master branch?
> No need to rebase at this time. In the pending branch I was able to fix
> the conflict in patch 7. Please check:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=b92086862c7be6e6810eca204052cada50fc0f5f
Thanks and LGTM.
Jeff Johnson <[email protected]> writes:
> On 4/11/2024 11:06 PM, Baochen Qiang wrote:
>
>> Now that the MHI&QRTR patches [1] are merged, we can add
>> suspend/resume support for ath12k.
>>
>> The whole design is quite similar to that in ath11k: firmware
>> is powered down when going to suspend and powered up when
>> resume, this makes hibernation work as well in addition to
>> suspend.
>>
>> To summary, this series first does some preparations in the
>> first 8 patches. Then in patch [9/10] suspend/resume callbacks
>> are implemented. And at last in [10/10] we enable suspend/resume
>> functionality for WCN7850 because it's the only chip supporting
>> it for now.
>>
>> [1] https://lore.kernel.org/linux-wireless/[email protected]/
>>
>> Baochen Qiang (10):
>> wifi: ath12k: rearrange IRQ enable/disable in reset path
>> wifi: ath12k: remove MHI LOOPBACK channels
>> wifi: ath12k: do not dump SRNG statistics during resume
>> wifi: ath12k: fix warning on DMA ring capabilities event
>> wifi: ath12k: decrease MHI channel buffer length to 8KB
>> wifi: ath12k: flush all packets before suspend
>> wifi: ath12k: no need to handle pktlog during suspend/resume
>> wifi: ath12k: avoid stopping mac80211 queues in ath12k_core_restart()
>> wifi: ath12k: support suspend/resume
>> wifi: ath12k: change supports_suspend to true for WCN7850
>>
>> drivers/net/wireless/ath/ath12k/core.c | 108 ++++++++++++++----------
>> drivers/net/wireless/ath/ath12k/core.h | 4 +
>> drivers/net/wireless/ath/ath12k/dp_rx.c | 48 -----------
>> drivers/net/wireless/ath/ath12k/dp_rx.h | 2 -
>
> My Qualcomm Innovation Center copyright checker reports:
> drivers/net/wireless/ath/ath12k/dp_rx.h copyright missing 2024
I fixed this in the pending branch:
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=6b928df55a671d2c9a15edc746f6b42ef544928e
Jeff, what do you think of the patchset? Is it ready to take?
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
On 4/17/2024 7:22 AM, Kalle Valo wrote:
> Jeff Johnson <[email protected]> writes:
>> My Qualcomm Innovation Center copyright checker reports:
>> drivers/net/wireless/ath/ath12k/dp_rx.h copyright missing 2024
>
> I fixed this in the pending branch:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=6b928df55a671d2c9a15edc746f6b42ef544928e
>
> Jeff, what do you think of the patchset? Is it ready to take?
My laptop didn't boot with this patchset in place, let me debug.
On 4/17/2024 4:32 PM, Jeff Johnson wrote:
> On 4/17/2024 7:22 AM, Kalle Valo wrote:
>> Jeff Johnson <[email protected]> writes:
>>> My Qualcomm Innovation Center copyright checker reports:
>>> drivers/net/wireless/ath/ath12k/dp_rx.h copyright missing 2024
>>
>> I fixed this in the pending branch:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=6b928df55a671d2c9a15edc746f6b42ef544928e
>>
>> Jeff, what do you think of the patchset? Is it ready to take?
>
> My laptop didn't boot with this patchset in place, let me debug.
I was originally trying to test with the entire 'pending' branch, but my
laptop crashes during initial boot.
So I just tested with master+the hibernation patchset, and upon resume I'm
getting a bunch of the following:
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: mhi mhi0: Requested to power ON
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: mhi mhi0: Power on setup success
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: mhi mhi0: Wait for device to enter SBL or Mission mode
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: mhi notify status reason MHI_CB_EE_MISSION_MODE
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi wifi fw qmi service connected
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: no valid response from PHY capability, choose default num_phy 2
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi firmware request memory request
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi mem seg type 1 size 7077888
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi mem seg type 4 size 8454144
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi dma allocation failed (7077888 B type 1), will try later with small size
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: BUG: Bad page state in process kworker/u16:54 pfn:36e80
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x36e80
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: flags: 0xfffffe0000000(node=0|zone=1|lastcpupid=0x3fffff)
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page_type: 0xffffffff()
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: raw: 000fffffe0000000 0000000000000000 dead000000000122 0000000000000000
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page dumped because: nonzero _refcount
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Modules linked in: ccm michael_mic bnep amdgpu snd_hda_codec_hdmi amdxcp drm_exec gpu_sched binfmt_misc qrtr_mhi nls_iso8859_1 i915 qrtr ath12k qmi_helpers mac80211 snd_ctl_led ledtrig_audio radeon snd_hda_codec_realtek snd_hda_codec_generic snd_hda_scodec_component intel_rapl_msr intel_rapl_common snd_hda_intel snd_intel_dspcfg x86_pkg_temp_thermal snd_intel_sdw_acpi intel_powerclamp snd_hda_codec mei_hdcp uvcvideo snd_hda_core cfg80211 snd_hwdep snd_pcm drm_suballoc_helper coretemp drm_ttm_helper drm_buddy videobuf2_vmalloc btusb crct10dif_pclmul uvc ttm ghash_clmulni_intel btrtl sha512_ssse3 videobuf2_memops btintel sha256_ssse3 snd_seq_midi btbcm sha1_ssse3 snd_seq_midi_event drm_display_helper aesni_intel videobuf2_v4l2 snd_rawmidi videodev btmtk cec snd_seq bluetooth crypto_simd cryptd rc_core videobuf2_common snd_seq_device rapl drm_kms_helper libarc4 mc snd_timer intel_cstate mhi snd i2c_algo_bit ecdh_generic mei_me ecc joydev input_leds soundcore mei serio_raw at24 wmi_bmof mac_hid wireless_hotkey
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: tpm_infineon sch_fq_codel msr parport_pc ppdev lp drm parport efi_pstore ip_tables x_tables autofs4 cdc_ether usbnet mii rtsx_pci_sdmmc crc32_pclmul video e1000e i2c_i801 psmouse rtsx_pci ahci i2c_smbus libahci xhci_pci lpc_ich xhci_pci_renesas wmi
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: CPU: 2 PID: 55152 Comm: kworker/u16:54 Not tainted 6.9.0-rc3-wt-ath+ #28
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Hardware name: Hewlett-Packard HP ZBook 14 G2/2216, BIOS M71 Ver. 01.31 02/24/2020
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Workqueue: qmi_msg_handler qmi_data_ready_work [qmi_helpers]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Call Trace:
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: <TASK>
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dump_stack_lvl+0x70/0x90
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dump_stack+0x14/0x20
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: bad_page+0x71/0x100
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: free_page_is_bad_report+0x86/0x90
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: __free_pages_ok+0x3b3/0x410
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: __free_pages+0xe7/0x110
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dma_direct_free+0xb9/0x180
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dma_free_attrs+0x3f/0x60
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_qmi_free_target_mem_chunk+0x75/0x140 [ath12k]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_qmi_msg_mem_request_cb+0x1fb/0x370 [ath12k]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_invoke_handler+0xa3/0xd0 [qmi_helpers]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_handle_message+0x6f/0x190 [qmi_helpers]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_data_ready_work+0x288/0x460 [qmi_helpers]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? raw_spin_rq_unlock+0x14/0x40
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: process_one_work+0x1a0/0x3f0
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: worker_thread+0x351/0x500
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_worker_thread+0x10/0x10
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: kthread+0xf8/0x130
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_kthread+0x10/0x10
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ret_from_fork+0x40/0x60
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_kthread+0x10/0x10
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ret_from_fork_asm+0x1a/0x30
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: </TASK>
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Disabling lock debugging due to kernel taint
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: BUG: Bad page state in process kworker/u16:54 pfn:36f00
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x36f00
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: flags: 0xfffffe0000000(node=0|zone=1|lastcpupid=0x3fffff)
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page_type: 0xffffffff()
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: raw: 000fffffe0000000 0000000000000000 dead000000000122 0000000000000000
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page dumped because: nonzero _refcount
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Modules linked in: ccm michael_mic bnep amdgpu snd_hda_codec_hdmi amdxcp drm_exec gpu_sched binfmt_misc qrtr_mhi nls_iso8859_1 i915 qrtr ath12k qmi_helpers mac80211 snd_ctl_led ledtrig_audio radeon snd_hda_codec_realtek snd_hda_codec_generic snd_hda_scodec_component intel_rapl_msr intel_rapl_common snd_hda_intel snd_intel_dspcfg x86_pkg_temp_thermal snd_intel_sdw_acpi intel_powerclamp snd_hda_codec mei_hdcp uvcvideo snd_hda_core cfg80211 snd_hwdep snd_pcm drm_suballoc_helper coretemp drm_ttm_helper drm_buddy videobuf2_vmalloc btusb crct10dif_pclmul uvc ttm ghash_clmulni_intel btrtl sha512_ssse3 videobuf2_memops btintel sha256_ssse3 snd_seq_midi btbcm sha1_ssse3 snd_seq_midi_event drm_display_helper aesni_intel videobuf2_v4l2 snd_rawmidi videodev btmtk cec snd_seq bluetooth crypto_simd cryptd rc_core videobuf2_common snd_seq_device rapl drm_kms_helper libarc4 mc snd_timer intel_cstate mhi snd i2c_algo_bit ecdh_generic mei_me ecc joydev input_leds soundcore mei serio_raw at24 wmi_bmof mac_hid wireless_hotkey
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: tpm_infineon sch_fq_codel msr parport_pc ppdev lp drm parport efi_pstore ip_tables x_tables autofs4 cdc_ether usbnet mii rtsx_pci_sdmmc crc32_pclmul video e1000e i2c_i801 psmouse rtsx_pci ahci i2c_smbus libahci xhci_pci lpc_ich xhci_pci_renesas wmi
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: CPU: 2 PID: 55152 Comm: kworker/u16:54 Tainted: G B 6.9.0-rc3-wt-ath+ #28
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Hardware name: Hewlett-Packard HP ZBook 14 G2/2216, BIOS M71 Ver. 01.31 02/24/2020
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Workqueue: qmi_msg_handler qmi_data_ready_work [qmi_helpers]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Call Trace:
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: <TASK>
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dump_stack_lvl+0x70/0x90
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dump_stack+0x14/0x20
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: bad_page+0x71/0x100
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: free_page_is_bad_report+0x86/0x90
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: __free_pages_ok+0x3b3/0x410
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: __free_pages+0xe7/0x110
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dma_direct_free+0xb9/0x180
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dma_free_attrs+0x3f/0x60
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_qmi_free_target_mem_chunk+0x75/0x140 [ath12k]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_qmi_msg_mem_request_cb+0x1fb/0x370 [ath12k]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_invoke_handler+0xa3/0xd0 [qmi_helpers]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_handle_message+0x6f/0x190 [qmi_helpers]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_data_ready_work+0x288/0x460 [qmi_helpers]
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? raw_spin_rq_unlock+0x14/0x40
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: process_one_work+0x1a0/0x3f0
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: worker_thread+0x351/0x500
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_worker_thread+0x10/0x10
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: kthread+0xf8/0x130
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_kthread+0x10/0x10
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ret_from_fork+0x40/0x60
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_kthread+0x10/0x10
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ret_from_fork_asm+0x1a/0x30
Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: </TASK>
On 4/18/2024 2:06 PM, Jeff Johnson wrote:
> On 4/17/2024 4:32 PM, Jeff Johnson wrote:
>> On 4/17/2024 7:22 AM, Kalle Valo wrote:
>>> Jeff Johnson <[email protected]> writes:
>>>> My Qualcomm Innovation Center copyright checker reports:
>>>> drivers/net/wireless/ath/ath12k/dp_rx.h copyright missing 2024
>>> I fixed this in the pending branch:
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=6b928df55a671d2c9a15edc746f6b42ef544928e
>>>
>>> Jeff, what do you think of the patchset? Is it ready to take?
>> My laptop didn't boot with this patchset in place, let me debug.
> I was originally trying to test with the entire 'pending' branch, but my
> laptop crashes during initial boot.
>
> So I just tested with master+the hibernation patchset, and upon resume I'm
> getting a bunch of the following:
>
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: mhi mhi0: Requested to power ON
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: mhi mhi0: Power on setup success
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: mhi mhi0: Wait for device to enter SBL or Mission mode
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: mhi notify status reason MHI_CB_EE_MISSION_MODE
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi wifi fw qmi service connected
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: no valid response from PHY capability, choose default num_phy 2
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi firmware request memory request
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi mem seg type 1 size 7077888
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi mem seg type 4 size 8454144
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_pci 0000:03:00.0: qmi dma allocation failed (7077888 B type 1), will try later with small size
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: BUG: Bad page state in process kworker/u16:54 pfn:36e80
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x36e80
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: flags: 0xfffffe0000000(node=0|zone=1|lastcpupid=0x3fffff)
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page_type: 0xffffffff()
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: raw: 000fffffe0000000 0000000000000000 dead000000000122 0000000000000000
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page dumped because: nonzero _refcount
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Modules linked in: ccm michael_mic bnep amdgpu snd_hda_codec_hdmi amdxcp drm_exec gpu_sched binfmt_misc qrtr_mhi nls_iso8859_1 i915 qrtr ath12k qmi_helpers mac80211 snd_ctl_led ledtrig_audio radeon snd_hda_codec_realtek snd_hda_codec_generic snd_hda_scodec_component intel_rapl_msr intel_rapl_common snd_hda_intel snd_intel_dspcfg x86_pkg_temp_thermal snd_intel_sdw_acpi intel_powerclamp snd_hda_codec mei_hdcp uvcvideo snd_hda_core cfg80211 snd_hwdep snd_pcm drm_suballoc_helper coretemp drm_ttm_helper drm_buddy videobuf2_vmalloc btusb crct10dif_pclmul uvc ttm ghash_clmulni_intel btrtl sha512_ssse3 videobuf2_memops btintel sha256_ssse3 snd_seq_midi btbcm sha1_ssse3 snd_seq_midi_event drm_display_helper aesni_intel videobuf2_v4l2 snd_rawmidi videodev btmtk cec snd_seq bluetooth crypto_simd cryptd rc_core videobuf2_common snd_seq_device rapl drm_kms_helper libarc4 mc snd_timer intel_cstate mhi snd i2c_algo_bit ecdh_generic mei_me ecc joydev input_leds soundcore mei serio_raw at24 wmi_bmof mac_hid wireless_hotkey
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: tpm_infineon sch_fq_codel msr parport_pc ppdev lp drm parport efi_pstore ip_tables x_tables autofs4 cdc_ether usbnet mii rtsx_pci_sdmmc crc32_pclmul video e1000e i2c_i801 psmouse rtsx_pci ahci i2c_smbus libahci xhci_pci lpc_ich xhci_pci_renesas wmi
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: CPU: 2 PID: 55152 Comm: kworker/u16:54 Not tainted 6.9.0-rc3-wt-ath+ #28
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Hardware name: Hewlett-Packard HP ZBook 14 G2/2216, BIOS M71 Ver. 01.31 02/24/2020
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Workqueue: qmi_msg_handler qmi_data_ready_work [qmi_helpers]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Call Trace:
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: <TASK>
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dump_stack_lvl+0x70/0x90
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dump_stack+0x14/0x20
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: bad_page+0x71/0x100
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: free_page_is_bad_report+0x86/0x90
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: __free_pages_ok+0x3b3/0x410
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: __free_pages+0xe7/0x110
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dma_direct_free+0xb9/0x180
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dma_free_attrs+0x3f/0x60
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_qmi_free_target_mem_chunk+0x75/0x140 [ath12k]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_qmi_msg_mem_request_cb+0x1fb/0x370 [ath12k]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_invoke_handler+0xa3/0xd0 [qmi_helpers]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_handle_message+0x6f/0x190 [qmi_helpers]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_data_ready_work+0x288/0x460 [qmi_helpers]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? raw_spin_rq_unlock+0x14/0x40
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: process_one_work+0x1a0/0x3f0
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: worker_thread+0x351/0x500
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_worker_thread+0x10/0x10
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: kthread+0xf8/0x130
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_kthread+0x10/0x10
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ret_from_fork+0x40/0x60
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_kthread+0x10/0x10
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ret_from_fork_asm+0x1a/0x30
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: </TASK>
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Disabling lock debugging due to kernel taint
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: BUG: Bad page state in process kworker/u16:54 pfn:36f00
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x36f00
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: flags: 0xfffffe0000000(node=0|zone=1|lastcpupid=0x3fffff)
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page_type: 0xffffffff()
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: raw: 000fffffe0000000 0000000000000000 dead000000000122 0000000000000000
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: page dumped because: nonzero _refcount
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Modules linked in: ccm michael_mic bnep amdgpu snd_hda_codec_hdmi amdxcp drm_exec gpu_sched binfmt_misc qrtr_mhi nls_iso8859_1 i915 qrtr ath12k qmi_helpers mac80211 snd_ctl_led ledtrig_audio radeon snd_hda_codec_realtek snd_hda_codec_generic snd_hda_scodec_component intel_rapl_msr intel_rapl_common snd_hda_intel snd_intel_dspcfg x86_pkg_temp_thermal snd_intel_sdw_acpi intel_powerclamp snd_hda_codec mei_hdcp uvcvideo snd_hda_core cfg80211 snd_hwdep snd_pcm drm_suballoc_helper coretemp drm_ttm_helper drm_buddy videobuf2_vmalloc btusb crct10dif_pclmul uvc ttm ghash_clmulni_intel btrtl sha512_ssse3 videobuf2_memops btintel sha256_ssse3 snd_seq_midi btbcm sha1_ssse3 snd_seq_midi_event drm_display_helper aesni_intel videobuf2_v4l2 snd_rawmidi videodev btmtk cec snd_seq bluetooth crypto_simd cryptd rc_core videobuf2_common snd_seq_device rapl drm_kms_helper libarc4 mc snd_timer intel_cstate mhi snd i2c_algo_bit ecdh_generic mei_me ecc joydev input_leds soundcore mei serio_raw at24 wmi_bmof mac_hid wireless_hotkey
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: tpm_infineon sch_fq_codel msr parport_pc ppdev lp drm parport efi_pstore ip_tables x_tables autofs4 cdc_ether usbnet mii rtsx_pci_sdmmc crc32_pclmul video e1000e i2c_i801 psmouse rtsx_pci ahci i2c_smbus libahci xhci_pci lpc_ich xhci_pci_renesas wmi
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: CPU: 2 PID: 55152 Comm: kworker/u16:54 Tainted: G B 6.9.0-rc3-wt-ath+ #28
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Hardware name: Hewlett-Packard HP ZBook 14 G2/2216, BIOS M71 Ver. 01.31 02/24/2020
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Workqueue: qmi_msg_handler qmi_data_ready_work [qmi_helpers]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: Call Trace:
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: <TASK>
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dump_stack_lvl+0x70/0x90
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dump_stack+0x14/0x20
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: bad_page+0x71/0x100
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: free_page_is_bad_report+0x86/0x90
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: __free_pages_ok+0x3b3/0x410
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: __free_pages+0xe7/0x110
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dma_direct_free+0xb9/0x180
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: dma_free_attrs+0x3f/0x60
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_qmi_free_target_mem_chunk+0x75/0x140 [ath12k]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ath12k_qmi_msg_mem_request_cb+0x1fb/0x370 [ath12k]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_invoke_handler+0xa3/0xd0 [qmi_helpers]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_handle_message+0x6f/0x190 [qmi_helpers]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: qmi_data_ready_work+0x288/0x460 [qmi_helpers]
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? raw_spin_rq_unlock+0x14/0x40
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: process_one_work+0x1a0/0x3f0
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: worker_thread+0x351/0x500
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_worker_thread+0x10/0x10
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: kthread+0xf8/0x130
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_kthread+0x10/0x10
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ret_from_fork+0x40/0x60
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ? __pfx_kthread+0x10/0x10
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: ret_from_fork_asm+0x1a/0x30
> Apr 17 21:38:04 qca-HP-ZBook-14-G2 kernel: </TASK>
Thanks for testing. I am able to reproduce this issue (although not exactly same crash signature) after disabling DMA remap. Just submit below patch to fix this issue, please help review.
wifi: ath12k: fix kernel crash during resume
>
>
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> In order to send out all packets before going to suspend, current code
> adds a 500ms delay as a workaround. It is a rough estimate and may not
> work.
>
> Fix this by checking packet counters, if counters become zero, then all
> packets are sent out or dropped.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Baochen Qiang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> Currently pktlog is stopped in suspend callback and started in
> resume callback, and in either scenarios it's basically to
> delete/modify ab->mon_reap_timer and to purge related rings.
> For WCN7850 it's pointless because pktlog is not enabled: both
> ab->mon_reap_timer and those rings are not initialized.
>
> So remove pktlog handling in suspend/resume callbacks. And
> further, remove these two functions and related callee because
> no one is calling them.
>
> Other chips are not affected because now only WCN7850 supports
> suspend/resume.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Baochen Qiang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> Currently when resume ath12k_core_restart() calls
> ath12k_core_pre_reconfigure_recovery() where mac80211 queues are
> stopped by calling ieee80211_stop_queues(). Then in
> ath12k_mac_op_reconfig_complete() those queues are not started
> because ieee80211_wake_queues() is skipped due to the check on
> reconfig_type. The result is that mac80211
> could not deliver any frame to ath12k to send out, finally making
> connection fail.
>
> [84473.104249] PM: suspend exit
> [84479.372397] wlan0: no VHT 160 MHz capability on 5 GHz, limiting to 80 MHz
> [84479.372401] wlan0: determined local STA to be EHT, BW limited to 80 MHz
> [84479.372416] wlan0: determined AP 00:03:7f:12:b7:b7 to be HE
> [84479.372420] wlan0: connecting with HE mode, max bandwidth 80 MHz
> [84479.580348] wlan0: authenticate with 00:03:7f:12:b7:b7 (local address=00:03:7f:37:11:53)
> [84479.580351] wlan0: send auth to 00:03:7f:12:b7:b7 (try 1/3)
> [84480.698993] wlan0: send auth to 00:03:7f:12:b7:b7 (try 2/3)
> [84481.816505] wlan0: send auth to 00:03:7f:12:b7:b7 (try 3/3)
> [84482.810966] wlan0: authentication with 00:03:7f:12:b7:b7 timed out
>
> Actually we don't need to stop/start queues during suspend/resume,
> so remove ath12k_core_pre_reconfigure_recovery() from ath12k_core_restart().
> This won't cause any regression because currently the only chance
> ath12k_core_restart() gets called is in reset case, where ab->is_reset
> is set so that function will never be executed.
>
> Also remove ath12k_core_post_reconfigure_recovery() because it is
> not needed in suspend/resume case. This is also valid due to above
> analysis.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Baochen Qiang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> Now that all infrastructure is in place and ath12k is fixed to handle all the
> corner cases, power down the ath12k firmware during suspend and power it back
> up during resume.
>
> For suspend, two conditions needs to be satisfied:
>
> 1. since MHI channel unprepare would be done in late suspend stage,
> ath12k needs to get all QMI-dependent things done before that stage.
> 2. and because unprepare MHI channels requires a working MHI stack,
> ath12k is not allowed to call mhi_power_down() until that finishes.
>
> So the original suspend callback is separated into two parts: the first part
> handles all QMI-dependent things in suspend callback; while the second part
> powers down MHI in suspend_late callback. This is valid because kernel calls
> ath12k's suspend callback before calling all suspend_late callbacks, making
> the first condition satisfied. And because MHI devices are children of ath12k
> device (ab->dev), kernel guarantees that ath12k's suspend_late callback is
> called after QRTR's suspend_late callback, this satisfies the second condition.
>
> Above analysis also applies to resume process. so the original resume
> callback is separated into two parts: the first part powers up MHI stack
> in resume_early callback, this guarantees MHI stack is working when
> QRTR tries to prepare MHI channels (kernel calls QRTR's resume_early callback
> after ath12k's resume_early callback, due to the child-father relationship);
> the second part waits for the completion of restart, which would succeed
> since MHI channels are ready for use by QMI.
>
> Another notable change is in power down path, we tell mhi_power_down() to not
> to destroy MHI devices, making it possible for QRTR to help unprepare/prepare
> MHI channels, and finally get us rid of the potential probe-defer issue when
> resume.
>
> Also change related code due to interface changes.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Baochen Qiang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> Now that all things are ready, enable supports_suspend to
> make suspend/resume work for WCN7850. Don't touch other
> chips because they don't support suspend.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Baochen Qiang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> We are seeing below warning in both reset and suspend/resume scenarios:
>
> [ 4153.776040] ath12k_pci 0000:04:00.0: Already processed, so ignoring dma ring caps
>
> This is because ab->num_db_cap is not cleared in
> ath12k_wmi_free_dbring_caps(), so clear it to avoid such
> warnings.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Baochen Qiang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> Both the firmware reset feature and the power management
> suspend/resume feature share common power-down and power-up
> functionality. One aspect of the power-up functionality is
> the handling of the ATH12K_QMI_EVENT_FW_INIT_DONE event.
> When this event is received, a call is made to
> ath12k_hal_dump_srng_stats(), with the purpose to collect
> information that may be useful in debugging the cause of a
> firmware reset.
>
> Unfortunately, since this functionality is shared between
> both the firmware reset path and the power management
> resume path, the kernel log is flooded with messages during
> resume. Since these messages are not useful during resume,
> and in fact can be confusing and can increase the time it
> takes to resume, update the logic to only call
> ath12k_hal_dump_srng_stats() during firmware reset.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Baochen Qiang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>
On 4/11/2024 11:06 PM, Baochen Qiang wrote:
> Currently buf_len field of ath12k_mhi_config_wcn7850 is assigned
> with 0, making MHI use a default size, 64KB, to allocate channel
> buffers. This is likely to fail in some scenarios where system
> memory is highly fragmented and memory compaction or reclaim is
> not allowed.
>
> For now we haven't get any failure report on this in ath12k, but
> there indeed is one such case in ath11k [1].
>
> Actually those buffers are used only by QMI target -> host communication.
> And for WCN7850, the largest packet size for that is less than 6KB. So
> change buf_len field to 8KB, which results in order 1 allocation if page
> size is 4KB. In this way, we can at least save some memory, and as well
> as decrease the possibility of allocation failure in those scenarios.
>
> [1] https://lore.kernel.org/ath11k/[email protected]/
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Baochen Qiang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>