mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
@ 2026-07-22  2:13 Nika Krasnova
  2026-07-28 20:05 ` Bjorn Helgaas
  0 siblings, 1 reply; 4+ messages in thread
From: Nika Krasnova @ 2026-07-22  2:13 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, linux-pci, linux-kernel, Nika Krasnova

On the Lenovo IdeaPad Pro 5 14IAH10, the Intel BE200 Wi-Fi (8086:272b,
iwlwifi) fails to power back on from D3cold after a suspend-to-idle
(s2idle) cycle.  On resume the platform reports a successful ACPI D0
transition, but the device is left unpowered: config space reads back
as 0xffffffff, the firmware reset times out, and the wiphy fails to
resume:

  iwlwifi 0000:01:00.0: power state changed by ACPI to D0
  iwlwifi 0000:01:00.0: restore config 0x2c: 0xffffffff -> 0x00f48086
  ieee80211 phy0: PM: failed to resume async: error -110

The device stays unusable until a full power cycle; an iwlwifi module
reload and a PCI remove/rescan do not recover it, confirming the device
is genuinely unpowered rather than in a bad software state.

Setting the device's d3cold_allowed to 0 keeps it in D3hot across
suspend and resumes reliably, so the platform does not correctly restore
power to the M.2 Wi-Fi slot on the s2idle resume path.  This mirrors the
untested-vendor-transition pattern already handled for the Asus B1400
NVMe (see asus_disable_nvme_d3cold): the reference OS does not appear to
exercise the D3cold->D0 path, so it is left untested.

Add a DMI-matched fixup that forbids D3cold for the BE200 on this model.
Match on the product rather than the BIOS version so the workaround
survives BIOS updates that do not address the issue.

Signed-off-by: Nika Krasnova <nika@nikableh.moe>
Assisted-by: Claude:claude-opus-4-8
---

Not sure arch/x86/pci/fixup.c is the right home versus a PCI quirk in
drivers/pci/quirks.c; would be happy to move it.

The latest BIOS from Lenovo for this model (QLCN35WW, 2025-12-23) is
installed and the failure is still present, so there is currently no
firmware-level fix.

Tested on the affected machine: with this patch applied and my local
d3cold_allowed=0 udev workaround removed, the BE200 resumes from s2idle
across repeated suspend/resume cycles with no iwlwifi errors.

 arch/x86/pci/fixup.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index b301c6c8df75..3117f313930e 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -995,6 +995,39 @@ static void asus_disable_nvme_d3cold(struct pci_dev *pdev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold);
 
+/*
+ * Disable D3cold on the Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
+ *
+ * On this platform the BE200 (8086:272b) fails to power back on from D3cold
+ * after an s2idle cycle: all config and CSR reads return 0xffffffff, the
+ * driver's firmware reset times out ("timeout waiting for FW reset ACK
+ * (inta_hw=0xffffffff)") and re-probe fails with -EIO.  A module reload and a
+ * PCI remove/rescan cannot revive the device; only a full platform power cycle
+ * does.  This looks like an untested transition by the vendor: the reference
+ * OS does not appear to exercise the D3cold->D0 path.
+ *
+ * Forbidding D3cold keeps the card in D3hot across suspend, which resumes
+ * reliably at the cost of a small amount of power while suspended.  Match on
+ * the product only (not the BIOS version) so the workaround survives BIOS
+ * updates that do not address the issue.
+ */
+static const struct dmi_system_id lenovo_be200_broken_d3cold_table[] = {
+	{
+		.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+				DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Pro 5 14IAH10"),
+		},
+	},
+	{}
+};
+
+static void lenovo_disable_be200_d3cold(struct pci_dev *pdev)
+{
+	if (dmi_check_system(lenovo_be200_broken_d3cold_table) > 0)
+		pci_d3cold_disable(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x272b, lenovo_disable_be200_d3cold);
+
 #ifdef CONFIG_SUSPEND
 /*
  * Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but
-- 
2.54.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
  2026-07-22  2:13 [PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10 Nika Krasnova
@ 2026-07-28 20:05 ` Bjorn Helgaas
  2026-07-28 20:14   ` Grumbach, Emmanuel
  0 siblings, 1 reply; 4+ messages in thread
From: Bjorn Helgaas @ 2026-07-28 20:05 UTC (permalink / raw)
  To: Nika Krasnova
  Cc: Bjorn Helgaas, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H . Peter Anvin, linux-pci, linux-kernel,
	Emmanuel Grumbach, Mark Pearson

[+cc Emmanuel, Mark]

On Wed, Jul 22, 2026 at 04:13:15AM +0200, Nika Krasnova wrote:
> On the Lenovo IdeaPad Pro 5 14IAH10, the Intel BE200 Wi-Fi (8086:272b,
> iwlwifi) fails to power back on from D3cold after a suspend-to-idle
> (s2idle) cycle.  On resume the platform reports a successful ACPI D0
> transition, but the device is left unpowered: config space reads back
> as 0xffffffff, the firmware reset times out, and the wiphy fails to
> resume:
> 
>   iwlwifi 0000:01:00.0: power state changed by ACPI to D0
>   iwlwifi 0000:01:00.0: restore config 0x2c: 0xffffffff -> 0x00f48086
>   ieee80211 phy0: PM: failed to resume async: error -110
> 
> The device stays unusable until a full power cycle; an iwlwifi module
> reload and a PCI remove/rescan do not recover it, confirming the device
> is genuinely unpowered rather than in a bad software state.

I guess this means "lspci -xs01:00.0" after resume shows all 0xff?

> Setting the device's d3cold_allowed to 0 keeps it in D3hot across
> suspend and resumes reliably, so the platform does not correctly restore
> power to the M.2 Wi-Fi slot on the s2idle resume path.  This mirrors the
> untested-vendor-transition pattern already handled for the Asus B1400
> NVMe (see asus_disable_nvme_d3cold): the reference OS does not appear to
> exercise the D3cold->D0 path, so it is left untested.
> 
> Add a DMI-matched fixup that forbids D3cold for the BE200 on this model.
> Match on the product rather than the BIOS version so the workaround
> survives BIOS updates that do not address the issue.
> 
> Signed-off-by: Nika Krasnova <nika@nikableh.moe>
> Assisted-by: Claude:claude-opus-4-8
> ---
> 
> Not sure arch/x86/pci/fixup.c is the right home versus a PCI quirk in
> drivers/pci/quirks.c; would be happy to move it.
> 
> The latest BIOS from Lenovo for this model (QLCN35WW, 2025-12-23) is
> installed and the failure is still present, so there is currently no
> firmware-level fix.
> 
> Tested on the affected machine: with this patch applied and my local
> d3cold_allowed=0 udev workaround removed, the BE200 resumes from s2idle
> across repeated suspend/resume cycles with no iwlwifi errors.
> 
>  arch/x86/pci/fixup.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
> index b301c6c8df75..3117f313930e 100644
> --- a/arch/x86/pci/fixup.c
> +++ b/arch/x86/pci/fixup.c
> @@ -995,6 +995,39 @@ static void asus_disable_nvme_d3cold(struct pci_dev *pdev)
>  }
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold);
>  
> +/*
> + * Disable D3cold on the Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
> + *
> + * On this platform the BE200 (8086:272b) fails to power back on from D3cold
> + * after an s2idle cycle: all config and CSR reads return 0xffffffff, the
> + * driver's firmware reset times out ("timeout waiting for FW reset ACK
> + * (inta_hw=0xffffffff)") and re-probe fails with -EIO.  A module reload and a
> + * PCI remove/rescan cannot revive the device; only a full platform power cycle
> + * does.  This looks like an untested transition by the vendor: the reference
> + * OS does not appear to exercise the D3cold->D0 path.
> + *
> + * Forbidding D3cold keeps the card in D3hot across suspend, which resumes
> + * reliably at the cost of a small amount of power while suspended.  Match on
> + * the product only (not the BIOS version) so the workaround survives BIOS
> + * updates that do not address the issue.
> + */
> +static const struct dmi_system_id lenovo_be200_broken_d3cold_table[] = {
> +	{
> +		.matches = {
> +				DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> +				DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Pro 5 14IAH10"),
> +		},
> +	},
> +	{}
> +};
> +
> +static void lenovo_disable_be200_d3cold(struct pci_dev *pdev)
> +{
> +	if (dmi_check_system(lenovo_be200_broken_d3cold_table) > 0)
> +		pci_d3cold_disable(pdev);
> +}
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x272b, lenovo_disable_be200_d3cold);
> +
>  #ifdef CONFIG_SUSPEND
>  /*
>   * Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but
> -- 
> 2.54.0
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
  2026-07-28 20:05 ` Bjorn Helgaas
@ 2026-07-28 20:14   ` Grumbach, Emmanuel
  2026-07-29 12:52     ` Nika Krasnova
  0 siblings, 1 reply; 4+ messages in thread
From: Grumbach, Emmanuel @ 2026-07-28 20:14 UTC (permalink / raw)
  To: helgaas, nika
  Cc: markpearson, bp, x86, hpa, mingo, linux-kernel, dave.hansen,
	tglx, linux-pci, bhelgaas

On Tue, 2026-07-28 at 15:05 -0500, Bjorn Helgaas wrote:
> [+cc Emmanuel, Mark]
> 
> On Wed, Jul 22, 2026 at 04:13:15AM +0200, Nika Krasnova wrote:
> > On the Lenovo IdeaPad Pro 5 14IAH10, the Intel BE200 Wi-Fi
> > (8086:272b,
> > iwlwifi) fails to power back on from D3cold after a suspend-to-idle
> > (s2idle) cycle.  On resume the platform reports a successful ACPI
> > D0
> > transition, but the device is left unpowered: config space reads
> > back
> > as 0xffffffff, the firmware reset times out, and the wiphy fails to
> > resume:
> > 
> >   iwlwifi 0000:01:00.0: power state changed by ACPI to D0
> >   iwlwifi 0000:01:00.0: restore config 0x2c: 0xffffffff ->
> > 0x00f48086
> >   ieee80211 phy0: PM: failed to resume async: error -110

We try to avoid resetting the firmware during suspend / resume. Out of
curiosity, can you try to reset it?

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 25f64299da1d..dfcd3ad60bd8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -806,7 +806,7 @@ void iwl_mld_mac80211_stop(struct ieee80211_hw *hw,
bool suspend)
        /* if the suspend flow fails the fw is in error. Stop it here,
and it
         * will be started upon wakeup
         */
-       if (!suspend ||
+       if (!suspend || true ||
            (IS_ENABLED(CONFIG_PM_SLEEP) &&
iwl_mld_no_wowlan_suspend(mld)))
                iwl_mld_stop_fw(mld);
 

Another thing.. Does Windows run the same suspend / resume sequence?
It also uses D3cold? I'd expect Lenovo to run thorough validation on
those flows on Windows and report possible bugs to us. I know that the
Windows driver does keep the firmware running.

> > 
> > The device stays unusable until a full power cycle; an iwlwifi
> > module
> > reload and a PCI remove/rescan do not recover it, confirming the
> > device
> > is genuinely unpowered rather than in a bad software state.
> 
> I guess this means "lspci -xs01:00.0" after resume shows all 0xff?
> 
> > Setting the device's d3cold_allowed to 0 keeps it in D3hot across
> > suspend and resumes reliably, so the platform does not correctly
> > restore
> > power to the M.2 Wi-Fi slot on the s2idle resume path.  This
> > mirrors the
> > untested-vendor-transition pattern already handled for the Asus
> > B1400
> > NVMe (see asus_disable_nvme_d3cold): the reference OS does not
> > appear to
> > exercise the D3cold->D0 path, so it is left untested.
> > 
> > Add a DMI-matched fixup that forbids D3cold for the BE200 on this
> > model.
> > Match on the product rather than the BIOS version so the workaround
> > survives BIOS updates that do not address the issue.
> > 
> > Signed-off-by: Nika Krasnova <nika@nikableh.moe>
> > Assisted-by: Claude:claude-opus-4-8
> > ---
> > 
> > Not sure arch/x86/pci/fixup.c is the right home versus a PCI quirk
> > in
> > drivers/pci/quirks.c; would be happy to move it.
> > 
> > The latest BIOS from Lenovo for this model (QLCN35WW, 2025-12-23)
> > is
> > installed and the failure is still present, so there is currently
> > no
> > firmware-level fix.
> > 
> > Tested on the affected machine: with this patch applied and my
> > local
> > d3cold_allowed=0 udev workaround removed, the BE200 resumes from
> > s2idle
> > across repeated suspend/resume cycles with no iwlwifi errors.
> > 
> >  arch/x86/pci/fixup.c | 33 +++++++++++++++++++++++++++++++++
> >  1 file changed, 33 insertions(+)
> > 
> > diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
> > index b301c6c8df75..3117f313930e 100644
> > --- a/arch/x86/pci/fixup.c
> > +++ b/arch/x86/pci/fixup.c
> > @@ -995,6 +995,39 @@ static void asus_disable_nvme_d3cold(struct
> > pci_dev *pdev)
> >  }
> >  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09,
> > asus_disable_nvme_d3cold);
> >  
> > +/*
> > + * Disable D3cold on the Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5
> > 14IAH10
> > + *
> > + * On this platform the BE200 (8086:272b) fails to power back on
> > from D3cold
> > + * after an s2idle cycle: all config and CSR reads return
> > 0xffffffff, the
> > + * driver's firmware reset times out ("timeout waiting for FW
> > reset ACK
> > + * (inta_hw=0xffffffff)") and re-probe fails with -EIO.  A module
> > reload and a
> > + * PCI remove/rescan cannot revive the device; only a full
> > platform power cycle
> > + * does.  This looks like an untested transition by the vendor:
> > the reference
> > + * OS does not appear to exercise the D3cold->D0 path.
> > + *
> > + * Forbidding D3cold keeps the card in D3hot across suspend, which
> > resumes
> > + * reliably at the cost of a small amount of power while
> > suspended.  Match on
> > + * the product only (not the BIOS version) so the workaround
> > survives BIOS
> > + * updates that do not address the issue.
> > + */
> > +static const struct dmi_system_id
> > lenovo_be200_broken_d3cold_table[] = {
> > +	{
> > +		.matches = {
> > +				DMI_MATCH(DMI_SYS_VENDOR,
> > "LENOVO"),
> > +				DMI_MATCH(DMI_PRODUCT_VERSION,
> > "IdeaPad Pro 5 14IAH10"),
> > +		},
> > +	},
> > +	{}
> > +};
> > +
> > +static void lenovo_disable_be200_d3cold(struct pci_dev *pdev)
> > +{
> > +	if (dmi_check_system(lenovo_be200_broken_d3cold_table) >
> > 0)
> > +		pci_d3cold_disable(pdev);
> > +}
> > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x272b,
> > lenovo_disable_be200_d3cold);
> > +
> >  #ifdef CONFIG_SUSPEND
> >  /*
> >   * Root Ports on some AMD SoCs advertise PME_Support for D3hot and
> > D3cold, but
> > -- 
> > 2.54.0
> > 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
  2026-07-28 20:14   ` Grumbach, Emmanuel
@ 2026-07-29 12:52     ` Nika Krasnova
  0 siblings, 0 replies; 4+ messages in thread
From: Nika Krasnova @ 2026-07-29 12:52 UTC (permalink / raw)
  To: Grumbach, Emmanuel
  Cc: helgaas @ kernel . org, nika @ nikableh . moe,
	markpearson @ lenovo . com, bp @ alien8 . de, x86 @ kernel . org,
	hpa @ zytor . com, mingo @ redhat . com,
	linux-kernel @ vger . kernel . org,
	dave . hansen @ linux . intel . com, tglx @ kernel . org,
	linux-pci @ vger . kernel . org, bhelgaas @ google . com

On Tue, 28 Jul 2026 20:14:36 +0000, "Grumbach, Emmanuel" <emmanuel.grumbach@intel.com> wrote:
> We try to avoid resetting the firmware during suspend / resume. Out of
> curiosity, can you try to reset it?

I applied your hunk on top of 7.1.3, with my quirk removed, and it makes
no difference. The patched and unpatched runs fail identically:

  iwlwifi 0000:01:00.0: timeout waiting for FW reset ACK (inta_hw=0xffffffff, reset_done 1)
  ieee80211 phy0: PM: dpm_run_callback(): wiphy_resume [cfg80211] returns -110
  ieee80211 phy0: PM: failed to resume async: error -110

On Tue, 28 Jul 2026 15:05:59 -0500, Bjorn Helgaas <helgaas@kernel.org> wrote:
> I guess this means "lspci -xs01:00.0" after resume shows all 0xff?

Yes. Before suspend:

  $ lspci -xs01:00.0
  01:00.0 Network controller: Intel Corporation Wi-Fi 7(802.11be) AX1775*/AX1790*/BE20*/BE401/BE1750* 2x2 (rev 1a)
  00: 86 80 2b 27 06 04 10 00 1a 00 80 02 10 00 80 00
  10: 04 00 20 8c 00 00 00 00 00 00 00 00 00 00 00 00
  20: 00 00 00 00 00 00 00 00 00 00 00 00 86 80 f4 00
  30: 00 00 00 00 40 00 00 00 00 00 00 00 ff 01 00 00

and after resume:

  $ lspci -xs01:00.0
  01:00.0 Network controller: Intel Corporation Wi-Fi 7(802.11be) AX1775*/AX1790*/BE20*/BE401/BE1750* 2x2 (rev 1a)
  00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
  10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
  20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
  30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

I've noticed that the root port above the card also never brings the
link back up:

  pcieport 0000:00:06.0: Data Link Layer Link Active not set in 100 msec
  [...]
  iwlwifi 0000:01:00.0: timeout waiting for FW reset ACK (inta_hw=0xffffffff, reset_done 1)
  ieee80211 phy0: PM: failed to resume async: error -110

0000:00:06.0 is the parent of 01:00.0. pci_pm_resume_noirq() only
reaches that wait with prev_state == PCI_D3cold, so the root port itself
was in D3cold, not just the endpoint. When the wait fails, everything
below the port is marked disconnected.

  $ lspci -PP -s 01:00.0
  00:06.0/01:00.0 Network controller: Intel Corporation Wi-Fi 7(802.11be) AX1775*/AX1790*/BE20*/BE401/BE1750* 2x2 (rev 1a)

(The "100 msec" there is the settle delay argument rather than the wait.
pcie_wait_for_link_delay() polls DLLLA for up to a second and also tries
pcie_failed_link_retrain(), so a larger d3cold_delay would not help.)

As far as I can tell the BE200 and its firmware are not involved. By the
time iwlwifi runs, the link is already down and every read returns ones,
which is what I would expect if the card never got its power back. That
also explains why a module reload and a PCI remove/rescan cannot revive
it: a rescan needs a working link.

D3cold on this port means switching off the ACPI power resource
\_SB.PC00.RP10.PXP_. I turned on the AML interpreter's method tracing
(trace_debug_layer=0x80, trace_debug_level=0x10, trace_state=enable) and
ran a suspend/resume where the card did not come back, to see whether
the firmware's power-on sequence runs at all. Other methods interleave
in the raw log, so this is grepped for RP10:

  Method Begin [\_SB.PC00.RP10.PXP._OFF] execution.
  Method Begin [\_SB.PC00.RP10.GPRS] execution.
  Method End [\_SB.PC00.RP10.GPRS] execution.
  Method Begin [\_SB.PC00.RP10.DL23] execution.
  Method End [\_SB.PC00.RP10.DL23] execution.
  Method Begin [\_SB.PC00.RP10.POFF] execution.
  Method Begin [\_SB.PC00.RP10.GPPR] execution.
  Method End [\_SB.PC00.RP10.GPPR] execution.
  Method End [\_SB.PC00.RP10.POFF] execution.
  Method End [\_SB.PC00.RP10.PXP._OFF] execution.
  Method Begin [\_SB.PC00.RP10.PXP._ON] execution.
  Method Begin [\_SB.PC00.RP10.GPRS] execution.
  Method End [\_SB.PC00.RP10.GPRS] execution.
  Method Begin [\_SB.PC00.RP10.PON] execution.
  Method End [\_SB.PC00.RP10.PON] execution.
  Method Begin [\_SB.PC00.RP10.L23D] execution.
  Method End [\_SB.PC00.RP10.L23D] execution.
  Method End [\_SB.PC00.RP10.PXP._ON] execution.

The resume side mirrors the suspend side: PON() and L23D() going up,
DL23() and POFF() coming down. The firmware runs the whole sequence and
reports success. The link still does not train.

Two registers in the port's own config space say more, both named by the
ASL. L23R sits at 0xE2 bit 3; L23D writes it and then polls until the
hardware clears it, and DL23 does the same with L23E on the way down.
LTSM is at 0x32B, which the firmware's own debug strings call the LTSSM
state.

Before suspend:

  $ setpci -s 00:06.0 0xe2.b
  11

  $ for i in $(seq 5); do setpci -s 00:06.0 0x32b.b; done
  40
  40
  40
  40
  40

After the failed resume:

  $ setpci -s 00:06.0 0xe2.b
  91

  $ for i in $(seq 5); do setpci -s 00:06.0 0x32b.b; done
  01
  01
  01
  01
  01

L23R (0x08) is clear both times, so the request L23D makes does
complete. For comparison, the sibling root port 0000:00:06.2, whose link
is up:

  $ for i in $(seq 3); do setpci -s 00:06.2 0x32b.b; done
  33
  40
  40

I do not know how the values in 0x32B map to LTSSM states, so the only
thing I can point at is the comparison: the failing port sits in a state
it never occupies while a link is up. If anyone has the decode for that
register, I would like to know what 0x01 is.

I can send the full acpidump output, or the decompiled DSDT and SSDTs,
off-list to anyone who wants to look at PON()/POFF() and the GPRS()
helper themselves.

> Another thing.. Does Windows run the same suspend / resume sequence?
> It also uses D3cold? I'd expect Lenovo to run thorough validation on
> those flows on Windows and report possible bugs to us.

I've dualbooted Windows 11 on this machine. The results:

  PS C:\Users\user> powercfg /a
  The following sleep states are available on this system:
      Standby (S0 Low Power Idle) Network Connected
      Hibernate
      Fast Startup

  The following sleep states are not available on this system:
      Standby (S1)
          The system firmware does not support this standby state.
          This standby state is disabled when S0 low power idle is supported.

      Standby (S2)
          The system firmware does not support this standby state.
          This standby state is disabled when S0 low power idle is supported.

      Standby (S3)
          The system firmware does not support this standby state.
          This standby state is disabled when S0 low power idle is supported.
          The current Device Guard configuration has disabled this standby
  state.

      Hybrid Sleep
          Standby (S3) is not available.
          The hypervisor does not support this standby state.

  PS C:\Users\user> powercfg /devicequery wake_armed
  USB4 Root Router (1.0)
  Intel(R) Wi-Fi 7 BE200 320MHz

Output from devmgmt.msc for our BE200:

  Current power state:
  D0

  Power capabilities:
  00000089
  PDCAP_D0_SUPPORTED
  PDCAP_D3_SUPPORTED
  PDCAP_WAKE_FROM_D3_SUPPORTED

  Power state mappings:
  S0 -> D0
  S1 -> D3
  S2 -> D3
  S3 -> D3
  S4 -> D3
  S5 -> D3

The device clearly uses D3, but that does not distinguish D3hot from
D3cold. Windows' DEVICE_POWER_STATE enumeration [1] bottoms out at
PowerDeviceD3, and a driver does not initiate the D3hot -> D3cold step
at all: it requests D3hot, and the device reaches D3cold only when the
bus driver or the system firmware removes the power source [2]. So what
Device Manager reports is the requested D-state, not whether the rail
was subsequently removed. This machine also sleeps via S0 Low Power Idle
rather than S3, so the Sx -> Dx table above does not even describe the
flow that matters here.

Entering D3cold while the system stays in S0 has to be enabled by the
power policy owner, through the INF or a SetD3ColdSupport() call [2].
Does the Windows BE200 driver enable D3cold transitions in S0 on
platforms like this one? If it does not, then Windows never takes the
card below D3hot here, and the D3cold->D0 path would never have been
exercised in validation.

Given that the failure is at the link layer above the device rather than
in the device itself, this should probably be a PCI quirk in
drivers/pci/quirks.c instead of arch/x86/pci/fixup.c.

[1] https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_device_power_state
[2] https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/enabling-transitions-to-d3cold

-- 
Nika Krasnova

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-07-29 12:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-22  2:13 [PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10 Nika Krasnova
2026-07-28 20:05 ` Bjorn Helgaas
2026-07-28 20:14   ` Grumbach, Emmanuel
2026-07-29 12:52     ` Nika Krasnova

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®