lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241118054447.2470345-1-hongxing.zhu@nxp.com>
Date: Mon, 18 Nov 2024 13:44:47 +0800
From: Richard Zhu <hongxing.zhu@....com>
To: jingoohan1@...il.com,
	bhelgaas@...gle.com,
	lpieralisi@...nel.org,
	kw@...ux.com,
	manivannan.sadhasivam@...aro.org,
	robh@...nel.org,
	frank.li@....com
Cc: imx@...ts.linux.dev,
	kernel@...gutronix.de,
	linux-pci@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Richard Zhu <hongxing.zhu@....com>
Subject: [PATCH v3] PCI: dwc: Clean up some unnecessary codes in dw_pcie_suspend_noirq()

Before sending PME_TURN_OFF, don't test the LTSSM state. Since it's safe
to send PME_TURN_OFF message regardless of whether the link is up or
down. So, there would be no need to test the LTSSM state before sending
PME_TURN_OFF message.

Only print the message when ltssm_stat is not in DETECT and POLL.
In the other words, there isn't an error message when no endpoint is
connected at all.

Also, when the endpoint is connected and PME_TURN_OFF is sent, do not return
error if the link doesn't enter L2. Just print a warning and continue with the
suspend as the link will be recovered in dw_pcie_resume_noirq().

Signed-off-by: Richard Zhu <hongxing.zhu@....com>
---
v3 changes:
- Refine the commit message refer to Manivannan's comments.
- Regarding Frank's comments, avoid 10ms wait when no link up.
v2 changes:
- Don't remove L2 poll check.
- Add one 1us delay after L2 entry.
- No error return when L2 entry is timeout
- Don't print message when no link up.
---
 .../pci/controller/dwc/pcie-designware-host.c | 40 ++++++++++---------
 drivers/pci/controller/dwc/pcie-designware.h  |  1 +
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 24e89b66b772..68fbc16199e8 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -927,24 +927,28 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
 	if (dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKCTL) & PCI_EXP_LNKCTL_ASPM_L1)
 		return 0;
 
-	/* Only send out PME_TURN_OFF when PCIE link is up */
-	if (dw_pcie_get_ltssm(pci) > DW_PCIE_LTSSM_DETECT_ACT) {
-		if (pci->pp.ops->pme_turn_off)
-			pci->pp.ops->pme_turn_off(&pci->pp);
-		else
-			ret = dw_pcie_pme_turn_off(pci);
-
-		if (ret)
-			return ret;
+	if (pci->pp.ops->pme_turn_off)
+		pci->pp.ops->pme_turn_off(&pci->pp);
+	else
+		ret = dw_pcie_pme_turn_off(pci);
+	if (ret)
+		return ret;
 
-		ret = read_poll_timeout(dw_pcie_get_ltssm, val, val == DW_PCIE_LTSSM_L2_IDLE,
-					PCIE_PME_TO_L2_TIMEOUT_US/10,
-					PCIE_PME_TO_L2_TIMEOUT_US, false, pci);
-		if (ret) {
-			dev_err(pci->dev, "Timeout waiting for L2 entry! LTSSM: 0x%x\n", val);
-			return ret;
-		}
-	}
+	ret = read_poll_timeout(dw_pcie_get_ltssm, val,
+				val == DW_PCIE_LTSSM_L2_IDLE ||
+				val <= DW_PCIE_LTSSM_DETECT_WAIT,
+				PCIE_PME_TO_L2_TIMEOUT_US/10,
+				PCIE_PME_TO_L2_TIMEOUT_US, false, pci);
+	if (ret && (val > DW_PCIE_LTSSM_DETECT_WAIT))
+		/* Only dump message when ltssm_stat isn't in DETECT and POLL */
+		dev_warn(pci->dev, "Timeout waiting for L2 entry! LTSSM: 0x%x\n", val);
+	else
+		/*
+		 * Refer to r6.0, sec 5.3.3.2.1, software should wait at least
+		 * 100ns after L2/L3 Ready before turning off refclock and
+		 * main power. It's harmless too when no endpoint connected.
+		 */
+		udelay(1);
 
 	dw_pcie_stop_link(pci);
 	if (pci->pp.ops->deinit)
@@ -952,7 +956,7 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
 
 	pci->suspended = true;
 
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(dw_pcie_suspend_noirq);
 
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 347ab74ac35a..bf036e66717e 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -330,6 +330,7 @@ enum dw_pcie_ltssm {
 	/* Need to align with PCIE_PORT_DEBUG0 bits 0:5 */
 	DW_PCIE_LTSSM_DETECT_QUIET = 0x0,
 	DW_PCIE_LTSSM_DETECT_ACT = 0x1,
+	DW_PCIE_LTSSM_DETECT_WAIT = 0x6,
 	DW_PCIE_LTSSM_L0 = 0x11,
 	DW_PCIE_LTSSM_L2_IDLE = 0x15,
 
-- 
2.37.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ