<p>Subrata Banik has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/22443">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/common: Add HECI message retry count<br><br>Send/Receive HECI message with 5 retry count in order<br>to avoid HECI message failure.<br><br>Change-Id: I76662f8080fe312caa77c83d1660faeee0bdbe7e<br>Signed-off-by: Subrata Banik <subrata.banik@intel.com><br>---<br>M src/soc/intel/common/block/cse/cse.c<br>1 file changed, 73 insertions(+), 52 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/43/22443/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c<br>index 53c4a81..2c2cf47 100644<br>--- a/src/soc/intel/common/block/cse/cse.c<br>+++ b/src/soc/intel/common/block/cse/cse.c<br>@@ -27,6 +27,8 @@<br> #include <string.h><br> #include <timer.h><br> <br>+#define MAX_HECI_MESSAGE_RETRY_COUNT 5<br>+<br> /* Wait up to 15 sec for HECI to get ready */<br> #define HECI_DELAY_READY (15 * 1000)<br> /* Wait up to 100 usec between circullar buffer polls */<br>@@ -309,45 +311,54 @@<br> int<br> heci_send(const void *msg, size_t len, uint8_t host_addr, uint8_t client_addr)<br> {<br>+ uint8_t retry;<br> uint32_t csr, hdr;<br> size_t sent = 0, remaining, cb_size, max_length;<br>- uint8_t *p = (uint8_t *) msg;<br>+ uint8_t *p;<br> <br> if (!msg || !len)<br> return 0;<br> <br> clear_int();<br> <br>- if (!wait_heci_ready()) {<br>- printk(BIOS_ERR, "HECI: not ready\n");<br>- return 0;<br>- }<br>+ for (retry = 0; retry < MAX_HECI_MESSAGE_RETRY_COUNT; retry++) {<br>+ p = (uint8_t *) msg;<br> <br>- csr = read_cse_csr();<br>- cb_size = ((csr & CSR_CBD) >> CSR_CBD_START) * SLOT_SIZE;<br>- /*<br>- * Reserve one slot for the header. Limit max message length by 9<br>- * bits that are available in the header.<br>- */<br>- max_length = MIN(cb_size, (1 << MEI_HDR_LENGTH_SIZE) - 1) - SLOT_SIZE;<br>- remaining = len;<br>+ if (!wait_heci_ready()) {<br>+ printk(BIOS_ERR, "HECI: not ready\n");<br>+ break;<br>+ }<br> <br>- /*<br>- * Fragment the message into smaller messages not exceeding useful<br>- * circullar buffer length. Mark last message complete.<br>- */<br>- do {<br>- hdr = MIN(max_length, remaining) << MEI_HDR_LENGTH_START;<br>- hdr |= client_addr << MEI_HDR_CSE_ADDR_START;<br>- hdr |= host_addr << MEI_HDR_HOST_ADDR_START;<br>- hdr |= (MIN(max_length, remaining) == remaining) ?<br>+ csr = read_cse_csr();<br>+ cb_size = ((csr & CSR_CBD) >> CSR_CBD_START) * SLOT_SIZE;<br>+ /*<br>+ * Reserve one slot for the header. Limit max message<br>+ * length by 9 bits that are available in the header.<br>+ */<br>+ max_length = MIN(cb_size, (1 << MEI_HDR_LENGTH_SIZE) - 1)<br>+ - SLOT_SIZE;<br>+ remaining = len;<br>+<br>+ /*<br>+ * Fragment the message into smaller messages not exceeding<br>+ * useful circullar buffer length. Mark last message complete.<br>+ */<br>+ do {<br>+ hdr = MIN(max_length, remaining)<br>+ << MEI_HDR_LENGTH_START;<br>+ hdr |= client_addr << MEI_HDR_CSE_ADDR_START;<br>+ hdr |= host_addr << MEI_HDR_HOST_ADDR_START;<br>+ hdr |= (MIN(max_length, remaining) == remaining) ?<br> MEI_HDR_IS_COMPLETE : 0;<br>- sent = send_one_message(hdr, p);<br>- p += sent;<br>- remaining -= sent;<br>- } while (remaining > 0 && sent != 0);<br>+ sent = send_one_message(hdr, p);<br>+ p += sent;<br>+ remaining -= sent;<br>+ } while (remaining > 0 && sent != 0);<br> <br>- return remaining == 0;<br>+ if (!remaining)<br>+ return 1;<br>+ }<br>+ return 0;<br> }<br> <br> static size_t<br>@@ -395,9 +406,10 @@<br> <br> int heci_receive(void *buff, size_t *maxlen)<br> {<br>+ uint8_t retry;<br> size_t left, received;<br> uint32_t hdr = 0;<br>- uint8_t *p = buff;<br>+ uint8_t *p;<br> <br> if (!buff || !maxlen || !*maxlen)<br> return 0;<br>@@ -406,31 +418,40 @@<br> <br> clear_int();<br> <br>- if (!wait_heci_ready()) {<br>- printk(BIOS_ERR, "HECI: not ready\n");<br>- return 0;<br>+ for (retry = 0; retry < MAX_HECI_MESSAGE_RETRY_COUNT; retry++) {<br>+ p = buff;<br>+<br>+ if (!wait_heci_ready()) {<br>+ printk(BIOS_ERR, "HECI: not ready\n");<br>+ break;<br>+ }<br>+<br>+ /*<br>+ * Receive multiple packets until we meet one marked<br>+ * complete or we run out of space in caller-provided buffer.<br>+ */<br>+ do {<br>+ received = recv_one_message(&hdr, p, left);<br>+ left -= received;<br>+ p += received;<br>+ /* If we read out everything ping to send more */<br>+ if (!(hdr & MEI_HDR_IS_COMPLETE) && !cse_filled_slots())<br>+ host_gen_interrupt();<br>+ } while (received && !(hdr & MEI_HDR_IS_COMPLETE) && left > 0);<br>+<br>+ *maxlen = p - (uint8_t *) buff;<br>+<br>+ /*<br>+ * If ME is not ready, something went wrong and<br>+ * we received junk<br>+ */<br>+ if (!cse_ready())<br>+ break;<br>+<br>+ if (!!((hdr & MEI_HDR_IS_COMPLETE) && received))<br>+ return 1;<br> }<br>-<br>- /*<br>- * Receive multiple packets until we meet one marked complete or we run<br>- * out of space in caller-provided buffer.<br>- */<br>- do {<br>- received = recv_one_message(&hdr, p, left);<br>- left -= received;<br>- p += received;<br>- /* If we read out everything ping to send more */<br>- if (!(hdr & MEI_HDR_IS_COMPLETE) && !cse_filled_slots())<br>- host_gen_interrupt();<br>- } while (received && !(hdr & MEI_HDR_IS_COMPLETE) && left > 0);<br>-<br>- *maxlen = p - (uint8_t *) buff;<br>-<br>- /* If ME is not ready, something went wrong and we received junk */<br>- if (!cse_ready())<br>- return 0;<br>-<br>- return !!((hdr & MEI_HDR_IS_COMPLETE) && received);<br>+ return 0;<br> }<br> <br> /*<br></pre><p>To view, visit <a href="https://review.coreboot.org/22443">change 22443</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/22443"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I76662f8080fe312caa77c83d1660faeee0bdbe7e </div>
<div style="display:none"> Gerrit-Change-Number: 22443 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Subrata Banik <subrata.banik@intel.com> </div>