[PATCH AUTOSEL 6.6 59/62] wifi: ath11k: determine PM policy based on machine model
Sasha Levin
sashal at kernel.org
Tue Jun 3 18:02:10 PDT 2025
From: Baochen Qiang <quic_bqiang at quicinc.com>
[ Upstream commit ce8669a27016354dfa8bf3c954255cb9f3583bae ]
To handle the Lenovo unexpected wakeup issue [1], previously we revert
commit 166a490f59ac ("wifi: ath11k: support hibernation"). So currently
WLAN target is put into WoWLAN mode during suspend. This is a temporary
solution as it does not work on machines where WLAN power is cut off.
The thought here is that we do WoWLAN suspend on Lenovo machines while
do non-WoWLAN suspend (which is done in the reverted commit) on other
machines. This requires us to identify Lenovo machines from others.
For that purpose, read board vendor and product name from DMI interface,
match it against all known affected machines. If there is a match, choose
WoWLAN suspend mode, else choose non-WoWLAN mode. Save the mode in ab
for later reference.
[1] https://bugzilla.kernel.org/show_bug.cgi?id=219196
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
Tested-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
Tested-by: Takashi Iwai <tiwai at suse.de>
Signed-off-by: Baochen Qiang <quic_bqiang at quicinc.com>
Link: https://patch.msgid.link/20250328-ath11k-bring-hibernation-back-v3-1-23405ae23431@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson at oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
**YES** This commit should definitely be backported to stable kernel
trees. Here's my detailed analysis: ## Bug Fix Nature This commit
clearly fixes a specific user-visible bug affecting Lenovo laptops with
WiFi suspend/wake functionality. The commit message explicitly
references bugzilla.kernel.org issue #219196, indicating this addresses
real user complaints about unexpected wakeup behavior. This aligns
perfectly with the **YES** backport example (Similar Commit #1) which
also reverted hibernation support due to Lenovo platform suspend issues.
## Code Changes Analysis ### 1. DMI Quirk Table Addition ```c +static
const struct dmi_system_id ath11k_pm_quirk_table[] = { + { +
.driver_data = (void *)ATH11K_PM_WOW, + .matches = { +
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME,
"21J4"), + }, + }, ``` This is a standard, low-risk pattern used
throughout the kernel for hardware-specific workarounds. It only affects
machines that exactly match the DMI criteria. ### 2. PM Policy
Infrastructure ```c +enum ath11k_pm_policy { + ATH11K_PM_DEFAULT, +
ATH11K_PM_WOW, +}; ``` The commit adds a simple enum and uses existing
WoWLAN suspend mechanisms rather than introducing new power management
code. ### 3. Policy Selection Logic ```c + dmi_id =
dmi_first_match(ath11k_pm_quirk_table); + if (dmi_id) + ab->pm_policy =
(kernel_ulong_t)dmi_id->driver_data; + else + ab->pm_policy =
ATH11K_PM_DEFAULT; ``` This is straightforward DMI matching that sets a
policy flag without changing core functionality. ## Risk Assessment
**Extremely Low Risk:** - **Scope**: Only affects specific Lenovo laptop
models (21J4, 21K4, 21K6, 21K8, 21KA, 21F9) - **Fallback**: Non-matching
machines continue using existing default behavior - **Tested Path**:
WoWLAN suspend mode is already implemented and working - **No Core
Changes**: Doesn't modify suspend/resume logic, just selects which path
to use ## Comparison to Reference Commits This follows the same pattern
as **Similar Commit #1** (marked YES), which also addressed Lenovo
platform suspend issues by reverting hibernation support. Both commits:
- Target specific hardware compatibility issues - Use conservative
approaches (WoWLAN vs full hibernation) - Have minimal code footprint -
Address real user bug reports Unlike the **NO** examples which add new
features (WoWLAN support, new suspend capabilities), this commit uses
existing infrastructure to fix hardware-specific incompatibilities. ##
Stable Tree Criteria Alignment ✅ **Fixes important bugs** - Suspend/wake
functionality on laptops ✅ **Small and contained** - Only DMI table and
policy selection ✅ **Low regression risk** - Targeted to specific
hardware ✅ **User-visible impact** - Improves power management behavior
✅ **No architectural changes** - Uses existing WoWLAN mechanisms This is
an ideal stable backport candidate that fixes real user issues with
minimal risk.
drivers/net/wireless/ath/ath11k/core.c | 55 ++++++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/core.h | 7 ++++
2 files changed, 62 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index fc7c4564a715c..51cc612b0c01a 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -704,6 +704,52 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
},
};
+static const struct dmi_system_id ath11k_pm_quirk_table[] = {
+ {
+ .driver_data = (void *)ATH11K_PM_WOW,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21J4"),
+ },
+ },
+ {
+ .driver_data = (void *)ATH11K_PM_WOW,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21K4"),
+ },
+ },
+ {
+ .driver_data = (void *)ATH11K_PM_WOW,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21K6"),
+ },
+ },
+ {
+ .driver_data = (void *)ATH11K_PM_WOW,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21K8"),
+ },
+ },
+ {
+ .driver_data = (void *)ATH11K_PM_WOW,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21KA"),
+ },
+ },
+ {
+ .driver_data = (void *)ATH11K_PM_WOW,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21F9"),
+ },
+ },
+ {}
+};
+
static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab)
{
WARN_ON(!ab->hw_params.single_pdev_only);
@@ -2011,8 +2057,17 @@ EXPORT_SYMBOL(ath11k_core_pre_init);
int ath11k_core_init(struct ath11k_base *ab)
{
+ const struct dmi_system_id *dmi_id;
int ret;
+ dmi_id = dmi_first_match(ath11k_pm_quirk_table);
+ if (dmi_id)
+ ab->pm_policy = (kernel_ulong_t)dmi_id->driver_data;
+ else
+ ab->pm_policy = ATH11K_PM_DEFAULT;
+
+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "pm policy %u\n", ab->pm_policy);
+
ret = ath11k_core_soc_create(ab);
if (ret) {
ath11k_err(ab, "failed to create soc core: %d\n", ret);
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index b044477624837..a85ba934932d6 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -840,6 +840,11 @@ struct ath11k_msi_config {
u16 hw_rev;
};
+enum ath11k_pm_policy {
+ ATH11K_PM_DEFAULT,
+ ATH11K_PM_WOW,
+};
+
/* Master structure to hold the hw data which may be used in core module */
struct ath11k_base {
enum ath11k_hw_rev hw_rev;
@@ -992,6 +997,8 @@ struct ath11k_base {
} testmode;
#endif
+ enum ath11k_pm_policy pm_policy;
+
/* must be last */
u8 drv_priv[] __aligned(sizeof(void *));
};
--
2.39.5
More information about the ath11k
mailing list