<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>