openbmc.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] peci: Set "Wake On PECI" mode when required
@ 2020-10-21 12:25 Andrei Kartashev
  0 siblings, 0 replies; only message in thread
From: Andrei Kartashev @ 2020-10-21 12:25 UTC (permalink / raw)
  To: Joel Stanley, Mihm,James, Jae Hyun Yoo; +Cc: OpenBMC Maillist

RdPCIConfigLocal(), WrPCIConfigLocal(), and RdPCIConfig() PECI commands
can return "hardware resources are in a low power state". This case
retrying likely will also fail since wakeup is required.
Enable "Wake On PECI" mode before retry if processor in low power
state.

Tested: run RdPCIConfigLocal requests and control that there in no more
timeouts when processor is in low power state. There is no measurable
impact on request processing time between request succeeded from first
try before patch and request with wakeup.

Signed-off-by: Andrei Kartashev <a.kartashev@yadro.com>
---
 drivers/peci/peci-core.c | 88 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 85 insertions(+), 3 deletions(-)

diff --git a/drivers/peci/peci-core.c b/drivers/peci/peci-core.c
index ba561bf810f9..dbd33e0e3a1c 100644
--- a/drivers/peci/peci-core.c
+++ b/drivers/peci/peci-core.c
@@ -237,6 +237,10 @@ static int __peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg,
 		    PECI_DEV_CC_NEED_RETRY)
 			break;
 
+		/* Wakeup is needed when completion code is 0x82 */
+		if (msg->rx_buf[0] == PECI_DEV_CC_UNAVAIL_RESOURCE)
+			break;
+
 		/* Set the retry bit to indicate a retry attempt */
 		msg->tx_buf[1] |= PECI_DEV_RETRY_BIT;
 
@@ -285,6 +289,84 @@ static int peci_xfer_with_retries(struct peci_adapter *adapter,
 	return __peci_xfer(adapter, msg, true, has_aw_fcs);
 }
 
+static int peci_xfer_with_wakeup(struct peci_adapter *adapter,
+				  struct peci_xfer_msg *msg,
+				  bool has_aw_fcs)
+{
+	struct peci_xfer_msg *wmsg = NULL;
+	u8 aw_fcs;
+	int ret;
+	int ret_tmp;
+
+	ret = __peci_xfer(adapter, msg, true, has_aw_fcs);
+
+	/* Wakeup is needed when completion code is 0x82 */
+	if (msg->rx_buf[0] == PECI_DEV_CC_UNAVAIL_RESOURCE) {
+		wmsg = peci_get_xfer_msg(PECI_WRPKGCFG_WRITE_LEN_BASE + 4,
+					PECI_WRPKGCFG_READ_LEN);
+		if (!wmsg)
+			return -ENOMEM;
+
+		wmsg->addr = msg->addr;
+		wmsg->tx_buf[0] = PECI_WRPKGCFG_CMD;
+		wmsg->tx_buf[1] = 0;  /* request byte for Host ID | Retry bit */
+				      /* Host ID is 0 for PECI 3.0 */
+		/* RdPkgConfig index */
+		wmsg->tx_buf[2] = PECI_MBX_INDEX_WAKE_MODE_BIT;
+		wmsg->tx_buf[3] = 1;  /* LSB - Config parameter */
+		wmsg->tx_buf[4] = 0;  /* MSB - Config parameter */
+		wmsg->tx_buf[5] = 0;  /* Data */
+		wmsg->tx_buf[6] = 0;  /* Data */
+		wmsg->tx_buf[7] = 0;  /* Data */
+		wmsg->tx_buf[8] = 0;  /* Data */
+
+		/* Add an Assured Write Frame Check Sequence byte */
+		ret_tmp = peci_aw_fcs(wmsg, 8 + 4, &aw_fcs);
+		if (ret_tmp) {
+			ret = ret_tmp;
+			goto out;
+		}
+
+		wmsg->tx_buf[9] = 0x80 ^ aw_fcs;
+
+		ret_tmp = __peci_xfer(adapter, wmsg, true, true);
+		if (ret_tmp) {
+			ret = ret_tmp;
+			goto out;
+		}
+
+		/* Resend command */
+		ret = __peci_xfer(adapter, msg, true, has_aw_fcs);
+
+		/*
+		 * Assume that if we got CC 0x82 then “Wake on PECI” mode
+		 * bit was not set, so no need to read and remember it
+		 */
+		wmsg->tx_buf[3] = 0;    /* LSB - Config parameter */
+		/* Recalculate an Assured Write Frame Check Sequence byte */
+		ret_tmp = peci_aw_fcs(wmsg, 8 + 4, &aw_fcs);
+		if (ret_tmp) {
+			if (ret == 0)
+				ret = ret_tmp;
+			goto out;
+		}
+
+		wmsg->tx_buf[9] = 0x80 ^ aw_fcs;
+
+		ret_tmp = __peci_xfer(adapter, wmsg, true, true);
+		if (ret_tmp) {
+			if (ret == 0)
+				ret = ret_tmp;
+			goto out;
+		}
+	}
+
+out:
+	if (wmsg)
+		peci_put_xfer_msg(wmsg);
+	return ret;
+}
+
 static int peci_scan_cmd_mask(struct peci_adapter *adapter)
 {
 	struct peci_xfer_msg *msg;
@@ -658,7 +740,7 @@ static int peci_cmd_rd_pci_cfg(struct peci_adapter *adapter, void *vmsg)
 	msg->tx_buf[4] = (u8)(address >> 16); /* PCI Config Address */
 	msg->tx_buf[5] = (u8)(address >> 24); /* MSB - PCI Config Address */
 
-	ret = peci_xfer_with_retries(adapter, msg, false);
+	ret = peci_xfer_with_wakeup(adapter, msg, false);
 	if (!ret)
 		memcpy(umsg->pci_config, &msg->rx_buf[1], 4);
 
@@ -706,7 +788,7 @@ static int peci_cmd_rd_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
 	msg->tx_buf[3] = (u8)(address >> 8);  /* PCI Configuration Address */
 	msg->tx_buf[4] = (u8)(address >> 16); /* PCI Configuration Address */
 
-	ret = peci_xfer_with_retries(adapter, msg, false);
+	ret = peci_xfer_with_wakeup(adapter, msg, false);
 	if (!ret)
 		memcpy(umsg->pci_config, &msg->rx_buf[1], umsg->rx_len);
 
@@ -758,7 +840,7 @@ static int peci_cmd_wr_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
 
 	msg->tx_buf[5 + i] = 0x80 ^ aw_fcs;
 
-	ret = peci_xfer_with_retries(adapter, msg, true);
+	ret = peci_xfer_with_wakeup(adapter, msg, true);
 
 out:
 	umsg->cc = msg->rx_buf[0];
-- 
2.26.2


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-10-21 12:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-21 12:25 [PATCH] peci: Set "Wake On PECI" mode when required Andrei Kartashev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).