From 436b140d0252badbe665c7369e6d8d31c3719cff Mon Sep 17 00:00:00 2001 From: Basabjit Sengupta Date: Tue, 14 Jul 2015 05:48:03 -0500 Subject: SBE FIFO Infrastructure Refactoring RTC:130575 Change-Id: Iff63ac28202deb86f13ee4f26c10e022509c4444 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/19078 Tested-by: Jenkins Server Reviewed-by: Sachin Gupta Reviewed-by: Amit J. Tendolkar --- sbe/sbefw/sbeFifoMsgUtils.C | 245 ++++++++++++++++++++++++++++++++++++++++++ sbe/sbefw/sbeFifoMsgUtils.H | 148 +++++++++++++++++++++++++ sbe/sbefw/sbe_sp_intf.H | 16 +-- sbe/sbefw/sbecmdgeneric.C | 13 ++- sbe/sbefw/sbecmdiplcontrol.C | 19 +--- sbe/sbefw/sbecmdprocessor.C | 157 +++++++++++---------------- sbe/sbefw/sbecmdreceiver.C | 50 ++++++--- sbe/sbefw/sbecmdscomaccess.C | 219 ++++++++++++------------------------- sbe/sbefw/sbeerrorcodes.H | 26 +++++ sbe/sbefw/sbeexeintf.H | 11 -- sbe/sbefw/sbefifo.C | 250 ------------------------------------------- sbe/sbefw/sbefifo.H | 170 ++++++----------------------- sbe/sbefw/sbefwfiles.mk | 4 +- sbe/sbefw/sbeirq.C | 2 +- 14 files changed, 641 insertions(+), 689 deletions(-) create mode 100644 sbe/sbefw/sbeFifoMsgUtils.C create mode 100644 sbe/sbefw/sbeFifoMsgUtils.H create mode 100644 sbe/sbefw/sbeerrorcodes.H delete mode 100644 sbe/sbefw/sbefifo.C (limited to 'sbe/sbefw') diff --git a/sbe/sbefw/sbeFifoMsgUtils.C b/sbe/sbefw/sbeFifoMsgUtils.C new file mode 100644 index 00000000..d86208ad --- /dev/null +++ b/sbe/sbefw/sbeFifoMsgUtils.C @@ -0,0 +1,245 @@ +/* + * @file: ppe/sbe/sbefw/sbeFifoMsgUtils.C + * + * @brief This file contains the SBE FIFO Access Common Utility Functions + * + */ + +#include "sbefifo.H" +#include "sbetrace.H" +#include "sbe_sp_intf.H" +#include "sbeFifoMsgUtils.H" +#include "sbeerrorcodes.H" +#include "assert.h" + +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +uint32_t sbeUpFifoDeq_mult (uint32_t &io_len, + uint32_t *o_pData, + const bool i_isEotExpected, + const bool i_flush) +{ + #define SBE_FUNC " sbeUpFifoDeq_mult " + uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + uint32_t l_len = 0; + + // If Caller didn't request flush operation + // and passed a non-zero valid length, we + // would expect a valid buffer + if ((!i_flush) && (io_len > 0)) + { + assert ( NULL != o_pData) + } + + do + { + sbeFifoEntry_t l_data = {0}; + + // Read Double word from the Upstream FIFO; + // The DW data represents the first 32 bits of data word entry + // followed by the status bits. + + // Bit 0-31 : Data + // Bit 32 : Data valid flag + // Bit 33 : EOT flag + // Bit 34-63 : Status (2-31) + // Valid : EOT + // 1 : 0 -> data=message + // 0 : 1 -> data=dummy_data of EOT operation + // 0 : 0 -> data=dummy_data + // 1 : 1 -> Not used + + l_rc = sbeUpFifoDeq ( reinterpret_cast(&l_data) ); + + if (l_rc) + { + // Error while dequeueing from upstream FIFO + SBE_ERROR(SBE_FUNC"sbeUpFifoDeq failed," + "l_rc=[0x%08X]", l_rc); + // @TODO RTC via : 132295 + // RC refactoring - reserve 3 bits in SBE RC for PCBPIB + l_rc = SBE_SEC_FIFO_ACCESS_FAILURE; + break; + } + + SBE_DEBUG(SBE_FUNC"sbeUpFifoDeq, " + "l_data.fifo_data=[0x%08X],", + l_data.fifo_data); + + // If FIFO reset is requested + if(l_data.statusOrReserved.req_upfifo_reset) + { + // @TODO via RTC : 126147 + // Review reset loop flow in here. + // Received a FIFO reset request + l_rc = SBE_FIFO_RESET_RECEIVED; + break; + } + + // if EOT flag is set, clear EOT and + // set the RC accordingly + if (l_data.statusOrReserved.eot_flag) + { + l_rc = sbeUpFifoAckEot(); + if (l_rc) + { + // Error while ack'ing EOT in upstream FIFO + SBE_ERROR(SBE_FUNC"sbeUpFifoAckEot failed," + "l_rc=[0x%08X]", l_rc); + + // Collect FFDC and save off the l_rc + l_rc = SBE_SEC_FIFO_ACCESS_FAILURE; + break; + } + + // Successfully Ack'ed the EOT in upstream FIFO + if ( ((!i_isEotExpected) || (l_len != io_len)) + && (!i_flush) ) + { + if (l_len < io_len) + { + // Unexpected EOT, got insufficient data + l_rc = SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA ; + } + else + { + // Unexpected EOT, got excess data + l_rc = SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA ; + } + } + break; + } + + // if Upstream FIFO is empty, + if (l_data.statusOrReserved.fifo_empty) + { + continue; + } + + if ((!i_flush) && (l_len < io_len)) + { + o_pData[l_len] = l_data.fifo_data; + } + + ++l_len; + + } while(i_flush || i_isEotExpected || (l_len < io_len)); + + // Return the length of entries dequeued. + io_len = l_len; + return l_rc; + + #undef SBE_FUNC +} + +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +uint32_t sbeDownFifoEnq_mult (uint32_t &io_len, + const uint32_t *i_pData) +{ + #define SBE_FUNC " sbeDownFifoEnq_mult " + uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + uint32_t l_len = 0; + + do + { + sbeDownFifoStatusReg_t l_status = {0}; + + // Read the down stream FIFO status + l_rc = sbeDownFifoGetStatus (reinterpret_cast(&l_status)); + if (l_rc) + { + // Error while reading downstream FIFO status + SBE_ERROR(SBE_FUNC"sbeDownFifoGetStatus failed, " + "l_rc=[0x%08X]", l_rc); + l_rc = SBE_SEC_FIFO_ACCESS_FAILURE; + break; + } + + // Check if there was a FIFO reset request from SP + if (l_status.downfifo_status.req_upfifo_reset) + { + // @TODO via RTC : 126147 + // Review reset loop flow in here. + // Received an upstream FIFO reset request + SBE_ERROR(SBE_FUNC"Received reset request"); + l_rc = SBE_FIFO_RESET_RECEIVED; + break; + } + + // Check if downstream FIFO is full + if (l_status.downfifo_status.fifo_full) + { + // Downstream FIFO is full + SBE_INFO(SBE_FUNC"Downstream FIFO is full"); + continue; + } + + // PIB write data format: + // Bit 0 - 31 : Data + // Bit 32 - 63 : Unused + + sbeFifoEntry_t l_data = {0}; + + l_data.fifo_data = *(i_pData+l_len); + + SBE_DEBUG(SBE_FUNC"Downstream fifo data entry[0x%08X]", + l_data.fifo_data); + + // Write the data into the downstream FIFO + l_rc = sbeDownFifoEnq ( *(reinterpret_cast(&l_data)) ); + if (l_rc) + { + SBE_ERROR(SBE_FUNC"sbeDownFifoEnq failed, " + "l_rc[0x%08X]", l_rc); + // @TODO RTC via : 132295 + // RC refactoring - reserve 3 bits in SBE RC for PCBPIB + l_rc = SBE_SEC_FIFO_ACCESS_FAILURE; + break; + } + + ++l_len; + + } while(l_len +#include "sbeexeintf.H" + + +/**********************************************************************/ +// SBE Utilities +/**********************************************************************/ + +/** + * @brief sbeUpFifoDeq_mult : Dequeue multiple entries from upstream FIFO + * + * @param[in/out] io_len + * On input: Non-zero number of entries (excluding EOT) to dequeue. + * Ignored when i_flush == true. + * On output: Number of entries dequeued (excluding EOT). + * @param[out] o_pData Entries dequeued into the buffer + * @param[in] i_isEotExpected true / false + * true - Default case. + * Caller expects an EOT entry after io_len entries are + * dequeued. Accordingly, this function will attempt to dequeue + * the EOT entry after io_len entries are dequeued. + * false - Caller doesn't expect an EOT after io_len entries are + * dequeued. Accordingly, this function will not attempt to + * dequeue the EOT entry after io_len entries are dequeued. + * @param[in] i_flush true / false + * true - caller requested FIFO flush + * Usually caller marks this flag as true to handle error scenario. + * All entries written in the US fifo (until an EOT is encountered), + * would be dequeued and discarded (not processed). Note that io_len + * and i_isEotExpected inputs are ignored in this case. + * However, flag i_isEotExpected is always interpreted as true in + * case. + * false - Default good path. + * US Fifo entries will be dequeued and processed per inputs io_len + * and i_isEotExpected. + * + * @return Return Code SUCCESS or a secondary response code + * SBE_SEC_OPERATION_SUCCESSFUL + * SBE_SEC_FIFO_ACCESS_FAILURE + * SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA + * SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA + * SBE_FIFO_RESET_RECEIVED + * + */ +extern uint32_t sbeUpFifoDeq_mult (uint32_t &io_len, + uint32_t *o_pData, + const bool i_isEotExpected = true, + const bool i_flush = false); + + +/** + * @brief sbeDownFifoEnq_mult : Enqueue into downstream FIFO + * + * @param[in/out] io_len number of entries to enqueue as input, + * number of entries enqueued as output + * @param[in] i_pData buffer containting data to be enqueued + * + * @return Rc SUCCESS or a secondary response code + * SBE_SEC_OPERATION_SUCCESSFUL + * SBE_SEC_FIFO_ACCESS_FAILURE + * SBE_FIFO_RESET_RECEIVED + * + */ +extern uint32_t sbeDownFifoEnq_mult (uint32_t &io_len, + const uint32_t *i_pData) ; + + +/** + * @brief sbeBuildRespHeaderMagicCodeCmdClass + * Builds the header word containing the magic code, + * the command class and the opcode + * + * @return Returns the header word in the response header + * containing the magic code, command class and opcode + * + */ +extern inline uint32_t sbeBuildRespHeaderMagicCodeCmdClass (void) +{ + return ( (0xC0DE0000 ) | + (uint32_t)(g_sbeCmdHdr.cmdClass << 8) | + (uint32_t)(g_sbeCmdHdr.command )); +} + +/** + * @brief sbeBuildRespHeaderStatusWordGlobal + * Builds the status header word from global variables + * + * @return Returns the status word in the response header + * + */ +extern inline uint32_t sbeBuildRespHeaderStatusWordGlobal (void) +{ + return ( (((uint32_t)g_sbeCmdRespHdr.prim_status)<<16) | + (g_sbeCmdRespHdr.sec_status) ); +} + +/** + * @brief sbeBuildRespHeaderStatusWordLocal + * Builds the status header word from passed in parameters + * + * @param[in] const uint16_t i_primStatus Primary Response Status Code + * @param[in] const uint16_t i_secStatus Secondary Response Status Code + * + * @return Returns the status word in the response header + * + */ +extern inline uint32_t sbeBuildRespHeaderStatusWordLocal ( + const uint16_t i_primStatus, + const uint16_t i_secStatus) +{ + return ( (((uint32_t)i_primStatus)<<16) | (i_secStatus) ); +} + +/** + * @brief sbeBuildMinRespHdr : Builds minimum response header + * + * @desc This builds the buffer with the following status words + * - Magic Bytes, Command Class, Command opcode + * - Primary Status Code, Secondary Status Code + * - PCB / PIB Status Code [optional] + * - Distance to Status Header + * @param[in/out] uint32_t *io_pBuf Buffer to be filled in + * @param[in/out] uint32_t &io_curIndex Current Index into the buffer + * @param[in] const uint16_t i_primStatus Primary Response Status Code + * @param[in] const uint16_t i_secStatus Secondary Response Status Code + * @param[in] const uint32_t i_pcbpibStatus PCB-PIB Response Status Code + * @param[in] const uint32_t i_startIndex Starting Index into the buffer + */ + +void sbeBuildMinRespHdr ( uint32_t *io_pBuf, + uint32_t &io_curIndex, + const uint16_t i_primStatus, + const uint16_t i_secStatus, + const uint32_t i_pcbpibStatus, + const uint32_t i_startIndex = 0 ); + + +#endif // __SBEFW_SBEFIFOMSGUTILS_H diff --git a/sbe/sbefw/sbe_sp_intf.H b/sbe/sbefw/sbe_sp_intf.H index 10180b06..c992a075 100644 --- a/sbe/sbefw/sbe_sp_intf.H +++ b/sbe/sbefw/sbe_sp_intf.H @@ -12,9 +12,15 @@ extern "C" { #endif /** - * $Version: Conforms to SP-SBE Interface Spec v0.8 + * $Version: Conforms to SP-SBE Interface Spec v0.8e */ +/* + * Constants for SBE FW major and minor number + */ +static const uint16_t SBE_FW_MAJOR_VERSION = 1; +static const uint16_t SBE_FW_MINOR_VERSION = 1; + /** * @brief enums for SBE command classes * @@ -161,6 +167,8 @@ enum sbeSecondaryResponse SBE_SEC_SECURITY_VALIDATION_FAILED = 0x0B, SBE_SEC_OS_FAILURE = 0x0C, SBE_SEC_FIFO_ACCESS_FAILURE = 0x0D, + SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA = 0x0E, + SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA = 0x0F, }; /** @@ -189,12 +197,6 @@ enum sbePCBPIBErrorRC SBE_PCB_PIB_ERROR_TIMEOUT = 0x07, }; -/* - * Constants for SBE FW major and minor number - */ -static const uint16_t SBE_FW_MAJOR_VERSION = 1; -static const uint16_t SBE_FW_MINOR_VERSION = 1; - /** * @brief capabilities index values. * Get Capability response will return 18 capabilities. This diff --git a/sbe/sbefw/sbecmdgeneric.C b/sbe/sbefw/sbecmdgeneric.C index 6bcb705c..e8dd646d 100644 --- a/sbe/sbefw/sbecmdgeneric.C +++ b/sbe/sbefw/sbecmdgeneric.C @@ -10,6 +10,7 @@ #include "sbetrace.H" #include "sbe_sp_intf.H" #include "sbe_build_info.H" +#include "sbeFifoMsgUtils.H" // Forward declaration sbeCapabilityRespMsg::sbeCapabilityRespMsg() @@ -40,25 +41,23 @@ uint32_t sbeGetCapabilities (uint8_t *i_pArg) #define SBE_FUNC "sbeGetCapabilities " SBE_DEBUG(SBE_FUNC); uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; - uint8_t len = 0; + uint32_t len = 0; sbeResponseGenericHeader_t respHdr; respHdr.init(); sbeCapabilityRespMsg_t capMsg; do { - // flush the EOT as no more data is expected. - rc = sbeUpFifoDeq_mult (len, NULL, true ); + // Dequeue the EOT entry as no more data is expected. + rc = sbeUpFifoDeq_mult (len, NULL); // @TODO via RTC : 130575 // Optimize both the RC handling and // FIFO operation infrastructure. - if ( rc != SBE_FIFO_RC_EOT_ACKED ) + if ( rc != SBE_SEC_OPERATION_SUCCESSFUL ) { - SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc); + // Let command processor routine to handle the RC break; } - // override Rc as we do not want to treat SBE_FIFO_RC_EOT_ACKED as error - rc = SBE_SEC_OPERATION_SUCCESSFUL; len = sizeof(capMsg)/sizeof(uint32_t); rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &capMsg); diff --git a/sbe/sbefw/sbecmdiplcontrol.C b/sbe/sbefw/sbecmdiplcontrol.C index 5bc700c0..e810d519 100644 --- a/sbe/sbefw/sbecmdiplcontrol.C +++ b/sbe/sbefw/sbecmdiplcontrol.C @@ -9,6 +9,7 @@ #include "sbefifo.H" #include "sbetrace.H" #include "sbe_sp_intf.H" +#include "sbeFifoMsgUtils.H" #include "assert.h" #include "fapi2.H" @@ -196,8 +197,8 @@ uint32_t sbeHandleIstep (uint8_t *i_pArg) #define SBE_FUNC "sbeHandleIstep " SBE_DEBUG(SBE_FUNC); uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; - uint8_t len = 0; ReturnCode fapiRc = FAPI2_RC_SUCCESS; + uint32_t len = 0; sbeIstepReqMsg_t req; sbeResponseGenericHeader_t respHdr; respHdr.init(); @@ -209,27 +210,13 @@ uint32_t sbeHandleIstep (uint8_t *i_pArg) //loop 1 do { - // @TODO via RTC : 130575 - // Optimize both the RC handling and - // FIFO operation infrastructure. len = sizeof( req )/sizeof(uint32_t); rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&req); - if (rc) //FIFO access issue + if (rc != SBE_SEC_OPERATION_SUCCESSFUL) //FIFO access issue { SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc); break; } - len = 1; - rc = sbeUpFifoDeq_mult ( len, NULL, true ); - - // If we didn't receive EOT yet - if ( rc != SBE_FIFO_RC_EOT_ACKED ) - { - SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc); - break; - } - // override Rc as we do not want to treat SBE_FIFO_RC_EOT_ACKED as error - rc = SBE_SEC_OPERATION_SUCCESSFUL; SBE_DEBUG(SBE_FUNC"Major number:0x%08x minor number:0x%08x", req.major, req.minor ); diff --git a/sbe/sbefw/sbecmdprocessor.C b/sbe/sbefw/sbecmdprocessor.C index faaa88d8..d868174b 100644 --- a/sbe/sbefw/sbecmdprocessor.C +++ b/sbe/sbefw/sbecmdprocessor.C @@ -13,6 +13,8 @@ #include "sbetrace.H" #include "sbe_sp_intf.H" #include "assert.h" +#include "sbeFifoMsgUtils.H" +#include "sbeerrorcodes.H" ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// @@ -24,8 +26,7 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) do { uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; - uint8_t l_dist2StatusHdr = 0; - uint32_t l_sbeDownFifoRespBuf[4] = {0}; + uint16_t l_primStatus = SBE_PRI_OPERATION_SUCCESSFUL; // Wait for new command processing int l_rcPk = pk_semaphore_pend ( @@ -33,10 +34,11 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) do { - uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status; - uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ; - SBE_DEBUG (SBE_FUNC"l_primStatus=[0x%04X], l_secStatus=[0x%04X]", - l_primStatus, l_secStatus); + l_primStatus = g_sbeCmdRespHdr.prim_status; + l_rc = g_sbeCmdRespHdr.sec_status; + + SBE_DEBUG (SBE_FUNC"l_primStatus=[0x%04X], l_rc=[0x%04X]", + l_primStatus, l_rc); // PK API failure if (l_rcPk != PK_OK) @@ -47,90 +49,17 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) // if the command receiver thread already updated // the response status codes, don't override them. - if (l_primStatus != SBE_PRI_OPERATION_SUCCESSFUL) + if (l_primStatus == SBE_PRI_OPERATION_SUCCESSFUL) { l_primStatus = SBE_PRI_INTERNAL_ERROR; - l_secStatus = SBE_SEC_OS_FAILURE; + l_rc = SBE_SEC_OS_FAILURE; } } SBE_DEBUG(SBE_FUNC"unblocked"); - // if there was a PK API failure or the - // command receiver thread indicated of - // a failure due to - // Command Validation or - // FIFO Reset request - if (l_primStatus) + if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) { - uint8_t l_len2dequeue = 0; - switch (l_primStatus) - { - case SBE_FIFO_RESET_RECEIVED: - SBE_ERROR(SBE_FUNC"FIFO reset received"); - l_rc = SBE_FIFO_RC_RESET; - break; - - case SBE_PRI_INVALID_COMMAND: - // Command or SBE state validation failed - // just follow through - - case SBE_PRI_INTERNAL_ERROR: - // Flush out the upstream FIFO till EOT arrives - l_len2dequeue = 1; - l_rc = sbeUpFifoDeq_mult (l_len2dequeue, NULL, true); - if (l_rc == SBE_FIFO_RC_RESET) - { - break; - } - - // Not handling any other RC from sbeUpFifoDeq_mult - // while flushing out to keep this code simple. - - // Don't break here to force the flow through - // the next case to enqueue the response into - // the downstream FIFO - - case SBE_PRI_INVALID_DATA: - // SBE caller already wrongly sent EOT - // before sending two mandatory header entries - // - // enqueue the response payload now into - // the downstream FIFO - - // @TODO via RTC : 130575 - // Optimize RC handling infrastructure code - - // Build the response packet first - sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0], - l_dist2StatusHdr, - l_primStatus, - l_secStatus, - 0); - - // Now enqueue into the downstream FIFO - l_rc = sbeDownFifoEnq_mult (++l_dist2StatusHdr, - &l_sbeDownFifoRespBuf[0]); - if (l_rc) - { - SBE_ERROR(SBE_FUNC"sbeDownFifoEnq_mult failure," - " l_rc[0x%X]", l_rc); - } - break; - - // Signal EOT in Downstream FIFO - l_rc = sbeDownFifoSignalEot(); - if (l_rc) - { - SBE_ERROR(SBE_FUNC"sbeDownFifoSignalEot failure," - " l_rc[0x0%08X]", l_rc); - break; - } - - default: - break; - } // End switch - break; } @@ -139,7 +68,6 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) uint8_t l_cmdClass = 0; uint8_t l_cmdOpCode = 0; - uint32_t (*l_pFuncP) (uint8_t *) ; // @TODO via RTC: 128658 // Review if Mutex protection is required @@ -148,7 +76,7 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) l_cmdOpCode = g_sbeCmdHdr.command; // Get the command function - l_pFuncP = sbeFindCmdFunc (l_cmdClass, l_cmdOpCode) ; + sbeCmdFunc_t l_pFuncP = sbeFindCmdFunc (l_cmdClass, l_cmdOpCode) ; assert( l_pFuncP ) @@ -160,7 +88,7 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) SBE_DEBUG(SBE_FUNC"l_rc=[0x%08X]", l_rc); // Handle FIFO reset case - if (l_rc == SBE_FIFO_RC_RESET) + if (l_rc == SBE_FIFO_RESET_RECEIVED) { // @TODO via RTC : 126147 // Handle FIFO reset flow @@ -168,19 +96,60 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) continue; } + if ( (l_rc == SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA) || + (l_rc == SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA) ) + { + l_primStatus = SBE_PRI_INVALID_DATA; + } + + uint32_t l_len2dequeue = 0; + uint32_t l_dist2StatusHdr = 0; + uint32_t l_sbeDownFifoRespBuf[4] = {0}; + uint32_t l_secStatus = l_rc; + switch (l_rc) { - // EOT arrived prematurely in upstream FIFO - // or there were unexpected data in upstream - // FIFO - case SBE_FIFO_RC_EOT_ACKED: - case SBE_FIFO_RC_EOT_ACK_FAILED: - SBE_ERROR(SBE_FUNC"Received unexpected EOT, l_rc[0x%08X]", - l_rc); + case SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED: + case SBE_SEC_COMMAND_NOT_SUPPORTED: + // Caller sent Invalid Command + + case SBE_SEC_OS_FAILURE: + // PK API Failures + + // Flush out the upstream FIFO till EOT arrives + l_len2dequeue = 1; + l_rc = sbeUpFifoDeq_mult (l_len2dequeue, NULL, + true, true); + + if ( (l_rc == SBE_FIFO_RESET_RECEIVED) || + (l_rc == SBE_SEC_FIFO_ACCESS_FAILURE) ) + { + break; + } + + if (l_rc) + { + l_secStatus = l_rc; + } + + // Don't break here to force the flow through + // the next case to enqueue the response into + // the downstream FIFO + + case SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA: + case SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA: + // EOT arrived prematurely in upstream FIFO + // or there were unexpected data in upstream FIFO + + SBE_ERROR(SBE_FUNC"Operation failure, " + "l_primStatus[0x%08X], " + "l_secStatus[0x%08X]", + l_primStatus, l_secStatus); + sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0], l_dist2StatusHdr, - SBE_PRI_INVALID_DATA, - SBE_SEC_GENERIC_FAILURE_IN_EXECUTION, + l_primStatus, + l_secStatus, 0); l_rc = sbeDownFifoEnq_mult (++l_dist2StatusHdr, &l_sbeDownFifoRespBuf[0]); diff --git a/sbe/sbefw/sbecmdreceiver.C b/sbe/sbefw/sbecmdreceiver.C index 95061fdc..e08072f4 100644 --- a/sbe/sbefw/sbecmdreceiver.C +++ b/sbe/sbefw/sbecmdreceiver.C @@ -12,6 +12,8 @@ #include "sbeirq.H" #include "sbetrace.H" #include "sbe_sp_intf.H" +#include "sbeFifoMsgUtils.H" +#include "sbeerrorcodes.H" sbeCmdReqBuf_t g_sbeCmdHdr; sbeCmdRespHdr_t g_sbeCmdRespHdr; @@ -59,31 +61,49 @@ void sbeCommandReceiver_routine(void *i_pArg) // The responsibility of this thread is limited to dequeueing // only the first two word entries from the protocol header. - uint8_t len = sizeof( g_sbeCmdHdr)/ sizeof(uint32_t); - l_rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&g_sbeCmdHdr ); + + // This thread will attempt to unblock the command processor + // thread on the following scenarios: + // - Normal scenarios where SBE would need to respond to FSP + // via downstream FIFO. This includes SUCCESS cases as well as + // the cases for Invalid Data sequence or Command validation + // failure. + // - if there is a need to handle FIFO reset + + // Accordingly, this will update g_sbeCmdRespHdr.prim_status + // and g_sbeCmdRespHdr.sec_status for command processor thread + // to handle them later in the sequence. + + uint32_t len = sizeof( g_sbeCmdHdr)/ sizeof(uint32_t); + l_rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&g_sbeCmdHdr, false ); // If FIFO reset is requested, - if (l_rc == SBE_FIFO_RC_RESET) + if (l_rc == SBE_FIFO_RESET_RECEIVED) { SBE_ERROR(SBE_FUNC"FIFO reset received"); g_sbeCmdRespHdr.prim_status = - (uint16_t)SBE_FIFO_RESET_RECEIVED; + (uint16_t)l_rc; g_sbeCmdRespHdr.sec_status = - (uint16_t)SBE_SEC_GENERIC_FAILURE_IN_EXECUTION; + (uint16_t)l_rc; + + // Reassign l_rc to Success to Unblock command processor + // thread and let that take the necessary action. + l_rc = SBE_SEC_OPERATION_SUCCESSFUL; break; } - // If we received EOT pre-maturely or - // got an error while Ack'ing EOT - if ( (l_rc == SBE_FIFO_RC_EOT_ACKED) || - (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED) ) + // If we received EOT out-of-sequence + if ( (l_rc == SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA) || + (l_rc == SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA) ) { SBE_ERROR(SBE_FUNC"sbeUpFifoDeq_mult failure, " " l_rc=[0x%08X]", l_rc); g_sbeCmdRespHdr.prim_status = SBE_PRI_INVALID_DATA; - g_sbeCmdRespHdr.sec_status = - SBE_SEC_GENERIC_FAILURE_IN_EXECUTION; + g_sbeCmdRespHdr.sec_status = l_rc; + + // Reassign l_rc to Success to Unblock command processor + // thread and let that take the necessary action. l_rc = SBE_SEC_OPERATION_SUCCESSFUL; break; } @@ -107,6 +127,9 @@ void sbeCommandReceiver_routine(void *i_pArg) SBE_ERROR(SBE_FUNC"Command validation failed"); g_sbeCmdRespHdr.prim_status = SBE_PRI_INVALID_COMMAND; g_sbeCmdRespHdr.sec_status = l_rc; + + // Reassign l_rc to Success to Unblock command processor + // thread and let that take the necessary action. l_rc = SBE_SEC_OPERATION_SUCCESSFUL; break; } @@ -125,9 +148,8 @@ void sbeCommandReceiver_routine(void *i_pArg) if ((l_rcPk != PK_OK) || (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)) { - // It's likely a code bug or PK failure, or - // FIFO reset request arrived or any other - // FIFO access failure. + // It's likely a code bug or PK failure, + // or any other FIFO access failure. // @TODO via RTC : 129166 // Review if we need to add ASSERT here diff --git a/sbe/sbefw/sbecmdscomaccess.C b/sbe/sbefw/sbecmdscomaccess.C index 5b946ffa..76147190 100644 --- a/sbe/sbefw/sbecmdscomaccess.C +++ b/sbe/sbefw/sbecmdscomaccess.C @@ -9,6 +9,8 @@ #include "sbefifo.H" #include "sbe_sp_intf.H" #include "sbetrace.H" +#include "sbeFifoMsgUtils.H" + ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// @@ -28,106 +30,63 @@ uint32_t sbeGetScom (uint8_t *i_pArg) // the scom addresses plus the expected // EOT entry at the end - // @TODO via RTC : 130575 - // Optimize both the RC handling and - // FIFO operation infrastructure. - uint8_t l_len2dequeue = 3; - uint32_t l_scomAddr[3] = {0}; + uint32_t l_len2dequeue = 2; + uint32_t l_scomAddr[2] = {0}; l_rc = sbeUpFifoDeq_mult (l_len2dequeue, &l_scomAddr[0]); // If FIFO access failure - if (l_rc == SBE_SEC_FIFO_ACCESS_FAILURE) + if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) { // Let command processor routine to handle the RC. break; } - // If we didn't receive EOT yet - if ( (l_rc != SBE_FIFO_RC_EOT_ACKED) && - (l_rc != SBE_FIFO_RC_EOT_ACK_FAILED) ) - { - // We must have received unexpected data - // on the upstream FIFO. - - // Flush upstream FIFO until EOT; - l_len2dequeue = 1; - l_rc = sbeUpFifoDeq_mult ( l_len2dequeue, NULL, true ); - - // We will break out here to force - // command processor routine to handle the RC. - // If the RC indicates the receipt of EOT, - // It would send the appropriate response - // back into the down stream FIFO. - // For all other failures, it would force - // timeout the chipOp operation - break; - } - - // If EOT arrived prematurely - if ( ((l_rc == SBE_FIFO_RC_EOT_ACKED) || - (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED)) - && (l_len2dequeue < 2) ) - { - // We will break out here to force - // command processor routine to respond - // into the downstream FIFO with - // primary response code as SBE_PRI_INVALID_DATA - break; - } - uint32_t l_sbeDownFifoRespBuf[6] = {0}; uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE; - uint8_t l_len2enqueue = 0; - uint8_t l_index = 0; - // successfully dequeued two entries for - // scom address followed by the EOT entry - if ( ((l_rc == SBE_FIFO_RC_EOT_ACKED) || - (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED)) - && (l_len2dequeue == 2) ) - { - // @TODO via RTC : 126140 - // Support Indirect SCOM - // Data entry 1 : Scom Register Address (0..31) - // Data entry 2 : Register Address (32..63) - // For Direct SCOM, will ignore entry 1 + uint32_t l_len2enqueue = 0; + uint32_t l_index = 0; - uint64_t l_scomData = 0; - SBE_TRACE(SBE_FUNC"scomAddr1[0x%08X]", l_scomAddr[1]); - l_rc = getscom (0, l_scomAddr[1], &l_scomData); + // @TODO via RTC : 126140 + // Support Indirect SCOM + // Data entry 1 : Scom Register Address (0..31) + // Data entry 2 : Register Address (32..63) + // For Direct SCOM, will ignore entry 1 - if (l_rc) // scom failed - { - SBE_ERROR(SBE_FUNC"getscom failed, l_rc[0x%08X]", l_rc); - l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE; - l_secStatus = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION; - l_pcbpibStatus = l_rc; - } + uint64_t l_scomData = 0; + SBE_DEBUG(SBE_FUNC"scomAddr1[0x%08X]", l_scomAddr[1]); + l_rc = getscom (0, l_scomAddr[1], &l_scomData); - if (!l_rc) // successful scom - { - SBE_TRACE(SBE_FUNC"getscom succeeds, l_scomData[0x%X]", + if (l_rc) // scom failed + { + SBE_ERROR(SBE_FUNC"getscom failed, l_rc[0x%08X]", l_rc); + l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE; + l_secStatus = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION; + l_pcbpibStatus = l_rc; + } + else // successful scom + { + SBE_DEBUG(SBE_FUNC"getscom succeeds, l_scomData[0x%X]", l_scomData); - l_sbeDownFifoRespBuf[0] = (uint32_t)(l_scomData>>32); - l_sbeDownFifoRespBuf[1] = (uint32_t)(l_scomData); + l_sbeDownFifoRespBuf[0] = (uint32_t)(l_scomData>>32); + l_sbeDownFifoRespBuf[1] = (uint32_t)(l_scomData); - // Push the data into downstream FIFO - l_len2enqueue = 2; - l_rc = sbeDownFifoEnq_mult (l_len2enqueue, + // Push the data into downstream FIFO + l_len2enqueue = 2; + l_rc = sbeDownFifoEnq_mult (l_len2enqueue, &l_sbeDownFifoRespBuf[0]); - if (l_rc) - { - // will let command processor routine - // handle the failure - break; - } - l_index = 2; - } // end successful scom - } // end successful dequeue + if (l_rc) + { + // will let command processor routine + // handle the failure + break; + } + l_index = 2; + } // end successful scom // Build the response header packet - uint8_t l_curIndex = l_index ; + uint32_t l_curIndex = l_index ; sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0], l_curIndex, l_primStatus, @@ -171,94 +130,56 @@ uint32_t sbePutScom (uint8_t *i_pArg) // corresponding data (two entries) plus // the expected EOT entry at the end - // @TODO via RTC : 130575 - // Optimize both the RC handling and - // FIFO operation infrastructure. - uint8_t l_len2dequeue = 5; - uint32_t l_scomAddr_Data[5] = {0}; + uint32_t l_len2dequeue = 4; + uint32_t l_scomAddr_Data[4] = {0}; l_rc = sbeUpFifoDeq_mult (l_len2dequeue, &l_scomAddr_Data[0]); // If FIFO access failure - if (l_rc == SBE_SEC_FIFO_ACCESS_FAILURE) + if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) { // Let command processor routine to handle the RC. break; } - // If we didn't receive EOT yet - if ( (l_rc != SBE_FIFO_RC_EOT_ACKED) && - (l_rc != SBE_FIFO_RC_EOT_ACK_FAILED) ) - { - // We must have received unexpected data - // on the upstream FIFO. - - // Flush upstream FIFO until EOT; - l_len2dequeue = 1; - l_rc = sbeUpFifoDeq_mult ( l_len2dequeue, NULL, true ); - - // We will break out here to force - // command processor routine to handle the RC. - // If the RC indicates the receipt of EOT, - // It would send the appropriate response - // back into the down stream FIFO. - // For all other failures, it would force - // timeout the chipOp operation - break; - } - - // If EOT arrived prematurely - if ( ((l_rc == SBE_FIFO_RC_EOT_ACKED) || - (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED)) - && (l_len2dequeue < 4) ) - { - // We will break out here to force - // command processor routine to respond - // into the downstream FIFO with - // primary response code as SBE_PRI_INVALID_DATA - break; - } - uint64_t l_scomData = 0; uint32_t l_sbeDownFifoRespBuf[4] = {0}; uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE; - uint8_t l_len2enqueue = 0; + uint32_t l_len2enqueue = 0; // successfully dequeued two entries for // scom address followed by the EOT entry - if ( ((l_rc == SBE_FIFO_RC_EOT_ACKED) || - (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED)) - && (l_len2dequeue == 4) ) - { - // @TODO via RTC : 126140 - // Support Indirect SCOM - // Data entry 1 : Scom Register Address (0..31) - // Data entry 2 : Scom Register Address (32..63) - // Data entry 3 : Scom Register Data (0..31) - // Data entry 4 : Scom Register Data (32..63) - // For Direct SCOM, will ignore entry 1 - l_scomData = ((uint64_t)(l_scomAddr_Data[2])<<32) - | (l_scomAddr_Data[3]); - SBE_DEBUG(SBE_FUNC"scomAddr0[0x%X]" - "scomAddr1[0x%X]" - "scomData0[0x%X]" - "scomData1[0x%X]", - l_scomAddr_Data[0], l_scomAddr_Data[1], - l_scomAddr_Data[2], l_scomAddr_Data[3]); + // @TODO via RTC : 126140 + // Support Indirect SCOM + // Data entry 0 : Scom Register Address (0..31) + // Data entry 1 : Scom Register Address (32..63) + // Data entry 2 : Scom Register Data (0..31) + // Data entry 3 : Scom Register Data (32..63) + // For Direct SCOM, will ignore entry 0 + l_scomData = ((uint64_t)(l_scomAddr_Data[2])<<32) + | (l_scomAddr_Data[3]); - l_rc = putscom (0, l_scomAddr_Data[1], l_scomData); + l_rc = putscom (0, l_scomAddr_Data[1], l_scomData); - if (l_rc) // scom failed - { - SBE_ERROR(SBE_FUNC"putscom failed, l_rc[0x%08X]", l_rc); - l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE; - l_secStatus = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION; - l_pcbpibStatus = l_rc; - } - } // end successful dequeue + if (l_rc) // scom failed + { + SBE_ERROR(SBE_FUNC"putscom failed, l_rc[0x%08X]", l_rc); + SBE_ERROR(SBE_FUNC"putscom failure data, " + "scomAddr0[0x%08X], " + "scomAddr1[0x%08X], " + "scomData0[0x%08X], " + "scomData1[0x%08X]", + l_scomAddr_Data[0], + l_scomAddr_Data[1], + l_scomAddr_Data[2], + l_scomAddr_Data[3]); + l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE; + l_secStatus = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION; + l_pcbpibStatus = l_rc; + } // Build the response header packet - uint8_t l_curIndex = 0; + uint32_t l_curIndex = 0; sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0], l_curIndex, l_primStatus, diff --git a/sbe/sbefw/sbeerrorcodes.H b/sbe/sbefw/sbeerrorcodes.H new file mode 100644 index 00000000..29942806 --- /dev/null +++ b/sbe/sbefw/sbeerrorcodes.H @@ -0,0 +1,26 @@ +/* + * @file: ppe/sbe/sbefw/sbeerrorcodes.H + * + * @brief This file contains the SBE internal error status codes + * + */ + +#ifndef __SBEFW_SBEERRORCODES_H +#define __SBEFW_SBEERRORCODES_H + +#include + + +/** + * @brief enums SBE internal error codes + * +*/ +enum sbeInternalResponseCodes +{ + SBE_FIFO_RESET_RECEIVED = 0xFA00, + SBE_FIFO_RESET_HANDLING_FAILED = 0xFB00, + SBE_FUNC_NOT_SUPPORTED = 0xFC00, +}; + + +#endif // __SBEFW_SBEERRORCODES_H \ No newline at end of file diff --git a/sbe/sbefw/sbeexeintf.H b/sbe/sbefw/sbeexeintf.H index f70f8c20..024cddfb 100644 --- a/sbe/sbefw/sbeexeintf.H +++ b/sbe/sbefw/sbeexeintf.H @@ -58,17 +58,6 @@ enum sbeThreadStackSize SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE = 2048, }; -/** - * @brief enums SBE internal error codes - * -*/ -enum sbeInternalResponseCodes -{ - SBE_FIFO_RESET_RECEIVED = 0xFA, - SBE_FIFO_RESET_HANDLING_FAILED = 0xFB, - SBE_FUNC_NOT_SUPPORTED = 0xFC, -}; - /** * @brief Global semaphore : g_sbeSemCmdRecv * diff --git a/sbe/sbefw/sbefifo.C b/sbe/sbefw/sbefifo.C deleted file mode 100644 index 08a493db..00000000 --- a/sbe/sbefw/sbefifo.C +++ /dev/null @@ -1,250 +0,0 @@ -/* - * @file: ppe/sbe/sbefw/sbefifo.C - * - * @brief This file contains the SBE FIFO Commands - * - */ - -#include "sbeexeintf.H" -#include "sbefifo.H" -#include "sbetrace.H" -#include "sbe_sp_intf.H" - -////////////////////////////////////////////////////// -////////////////////////////////////////////////////// -uint32_t sbeUpFifoDeq_mult (uint8_t &io_len, - uint32_t *o_pData, - const bool i_flush) -{ - #define SBE_FUNC " sbeUpFifoDeq_mult " - uint32_t l_rc = SBE_FIFO_RC_UNKNOWN; - uint8_t l_len = 0; - - // @TODO via RTC : 130575 - // Refactor this utility to - // optimize RC handling, stack usage - // and FIFO operation infrastructure. - // - - do - { - sbe_upfifo_entry_t l_data = {0}; - uint64_t l_upfifo_data = 0; - - // Read Double word from the Upstream FIFO; - // The DW data represents the first 32 bits of data word entry - // followed by the status bits. - - // Bit 0-31 : Data - // Bit 32 : Data valid flag - // Bit 33 : EOT flag - // Bit 34-63 : Status (2-31) - // Valid : EOT - // 1 : 0 -> data=message - // 0 : 1 -> data=dummy_data of EOT operation - // 0 : 0 -> data=dummy_data - // 1 : 1 -> Not used - - l_rc = sbeUpFifoDeq ( &l_upfifo_data ); - - if (l_rc) - { - // Error while dequeueing from upstream FIFO - SBE_ERROR(SBE_FUNC"sbeUpFifoDeq failed," - "l_rc=[0x%08X]", l_rc); - l_rc = SBE_SEC_FIFO_ACCESS_FAILURE; - break; - } - - l_data.upfifo_data = (uint32_t)(l_upfifo_data>>32); - l_data.upfifo_status.upfifo_status_uint32 = (uint32_t) - (l_upfifo_data); - - SBE_DEBUG(SBE_FUNC"sbeUpFifoDeq, " - "l_data.upfifo_data=[0x%08X]," - "l_data.upfifo_status=[0x%08X]", - l_data.upfifo_data, - l_data.upfifo_status.upfifo_status_uint32); - - // If FIFO reset is requested - if(l_data.upfifo_status.upfifo_status_bitset.req_upfifo_reset) - { - // @TODO via RTC : 126147 - // Review reset loop flow in here. - // Received a FIFO reset request - l_rc = SBE_FIFO_RC_RESET; - break; - } - - // if EOT flag is set - // clear EOT - if (l_data.upfifo_status.upfifo_status_bitset.eot_flag) - { - l_rc = sbeUpFifoAckEot(); - if (l_rc) - { - // Error while ack'ing EOT in upstream FIFO - SBE_ERROR(SBE_FUNC"sbeUpFifoAckEot failed," - "l_rc=[0x%08X]", l_rc); - // Collect FFDC - l_rc = SBE_FIFO_RC_EOT_ACK_FAILED; - } - else - { - l_rc = SBE_FIFO_RC_EOT_ACKED; - } - break; - } - - // if Upstream FIFO is empty, - if (l_data.upfifo_status.upfifo_status_bitset.fifo_empty) - { - l_rc = SBE_FIFO_RC_EMPTY; - continue; - } - - if (i_flush) - { - l_len = 0; // to force the upFIFO flush until EOT arrives - continue; - } - - o_pData[l_len] = l_data.upfifo_data; - ++l_len; - l_rc = SBE_SEC_OPERATION_SUCCESSFUL; - - } while(l_len>32); - - SBE_DEBUG(SBE_FUNC"downstream fifo status[0x%08X]", - l_downFifoStatus.downfifo_status_uint32); - - // Check if there was a FIFO reset request from SP - if (l_downFifoStatus.downfifo_status_bitset.req_upfifo_reset) - { - // @TODO via RTC : 126147 - // Review reset loop flow in here. - // Received an upstream FIFO reset request - SBE_ERROR(SBE_FUNC"Received reset request"); - l_rc = SBE_FIFO_RC_RESET; - break; - } - - // Check if downstream FIFO is full - if (l_downFifoStatus.downfifo_status_bitset.fifo_full) - { - // Downstream FIFO is full - SBE_INFO(SBE_FUNC"Downstream FIFO is full"); - l_rc = SBE_FIFO_RC_FULL; // in case we ever add timeout - continue; - } - - // PIB write data format: - // Bit 0 - 31 : Data - // Bit 32 - 63 : Unused - - l_sbeDownFiFoEntry.data = (uint64_t)(*(i_pData+l_len)); - l_sbeDownFiFoEntry.data = l_sbeDownFiFoEntry.data<<32; - - SBE_DEBUG(SBE_FUNC"Downstream fifo data entry[0x%08X]", - (l_sbeDownFiFoEntry.data>>32)); - - // Write the data into the downstream FIFO - l_rc = sbeDownFifoEnq (l_sbeDownFiFoEntry.data); - if (l_rc) - { - SBE_ERROR(SBE_FUNC"sbeDownFifoEnq failed, " - "l_rc[0x%08X]", l_rc); - l_rc = SBE_SEC_FIFO_ACCESS_FAILURE; - break; - } - - l_rc = SBE_SEC_OPERATION_SUCCESSFUL; - ++l_len; - - } while(l_len