[][openwrt][mt7988][crypto][EIP197 DDK Porting]

[Description]
Add eip197 DDK(Driver Development Kit) and firmware
to eip197 package(crypto-eip)

eip197 DDK v5.6.1
eip197b-iew firmware v3.5

[Release-log]
N/A

Change-Id: I662327ecfbdac69742bf0b50362d7c28fc06372b
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7895272
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip74.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip74.c
new file mode 100644
index 0000000..f31fa52
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip74.c
@@ -0,0 +1,630 @@
+/* api_global_eip74.c
+ *
+ * Deterministic Random Bit Generator (EIP-74) Global Control Initialization
+ * Adapter. The EIP-74 is used to generate pseudo-random IVs for outbound
+ * operations in CBC mode.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "api_global_eip74.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Configuration.
+#include "c_adapter_eip74.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint8_t
+
+// memcpy
+#include "clib.h"
+
+// EIP-73 Driver Library.
+#include "eip74.h"
+
+#include "device_types.h"       // Device_Handle_t
+#include "device_mgmt.h"        // Device_find
+
+// Logging API
+#include "log.h"                // Log_*, LOG_*
+
+// Adapter interrupts API
+#include "adapter_interrupts.h" // Adapter_Interrupt_*
+
+// Runtime Power Management Device Macros API
+#include "rpm_device_macros.h"  // RPM_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/* Put all adapter local variables in one structure */
+static struct {
+    EIP74_IOArea_t IOArea;
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    GlobalControl74_NotifyFunction_t Notify_CBFunc;
+#endif
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+    GlobalControl74_Configuration_t CachedConfig;
+    bool fInitialized;
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    bool fInterruptEnabled;
+#endif
+#endif
+} EIP74State;
+
+
+static const  GlobalControl74_Capabilities_t Global_CapabilitiesString =
+{
+  "EIP-74 v_._p_"// szTextDescription
+};
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_Init
+ */
+static GlobalControl74_Error_t
+GlobalControl74Lib_Init(
+        const GlobalControl74_Configuration_t * const Configuration_p,
+        const uint8_t * const Entropy_p);
+
+
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_Resune
+ */
+static int
+GlobalControl74Lib_Resune(
+        void *p)
+{
+    uint8_t Entropy[48];
+    IDENTIFIER_NOT_USED(p);
+    if (EIP74State.fInitialized)
+    {
+        /* Note we should add fresh random data here */
+        ZEROINIT(Entropy);
+        if (GlobalControl74Lib_Init(&EIP74State.CachedConfig, Entropy) !=
+            GLOBAL_CONTROL_EIP74_NO_ERROR)
+        {
+            return -1;
+        }
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+        if (EIP74State.fInitialized && EIP74State.fInterruptEnabled)
+        {
+            Adapter_Interrupt_Disable(ADAPTER_EIP74_ERR_IRQ, 0);
+            Adapter_Interrupt_Disable(ADAPTER_EIP74_RES_IRQ, 0);
+        }
+#endif
+    }
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_Suspend
+ */
+static int
+GlobalControl74Lib_Suspend(
+        void *p)
+{
+    IDENTIFIER_NOT_USED(p);
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    if (EIP74State.fInitialized && EIP74State.fInterruptEnabled)
+    {
+        Adapter_Interrupt_Disable(ADAPTER_EIP74_ERR_IRQ, 0);
+        Adapter_Interrupt_Disable(ADAPTER_EIP74_RES_IRQ, 0);
+    }
+#endif
+    return 0;
+}
+
+#endif
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_CopyKeyMat
+ *
+ * Copy a key represented as a byte array into a word array..
+ *
+ * Destination_p (input)
+ *   Destination (word-aligned) of the word array
+ *
+ * Source_p (input)
+ *   Source (byte aligned) of the data.
+ *
+ * KeyByteCount (input)
+ *   Size of the key in bytes.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no key
+ * will be written.
+ */
+static void
+GlobalControl74Lib_CopyKeyMat(
+        uint32_t * const Destination_p,
+        const uint8_t * const Source_p,
+        const unsigned int KeyByteCount)
+{
+    uint32_t *dst = Destination_p;
+    const uint8_t *src = Source_p;
+    unsigned int i,j;
+    uint32_t w;
+    if (Destination_p == NULL)
+        return;
+    for(i=0; i < KeyByteCount / sizeof(uint32_t); i++)
+    {
+        w=0;
+        for(j=0; j<sizeof(uint32_t); j++)
+            w=(w<<8)|(*src++);
+        *dst++ = w;
+    }
+}
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+/*----------------------------------------------------------------------------
+ * GlobalControl74_InterruptHandlerNotify
+ */
+static void
+GlobalControl74_InterruptHandlerNotify(
+        const int nIRQ,
+        const unsigned int flags)
+{
+    GlobalControl74_NotifyFunction_t CB_Func = EIP74State.Notify_CBFunc;
+
+    IDENTIFIER_NOT_USED(nIRQ);
+    IDENTIFIER_NOT_USED(flags);
+
+    LOG_INFO("GlobalControl74_InterruptHandlerNotify\n");
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+    EIP74State.fInterruptEnabled = true;
+#endif
+
+    EIP74State.Notify_CBFunc = NULL;
+    if (CB_Func != NULL)
+    {
+        LOG_INFO("\t Invoking callback\n");
+        CB_Func();
+    }
+}
+#endif
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_Init
+ *
+ * This function performs the initialization of the EIP-74 Deterministic
+ * Random Bit Generator.
+ *
+ * Note: the Device was already found and the IOArea is already initialized.
+ *
+ * Configuration_p (input)
+ *     Configuration parameters of the DRBG.
+ *
+ * Entropy_p (input)
+ *     Pointer to a string of exactly 48 bytes that serves as the entropy.
+ *     to initialize the DRBG.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_EIP74_NO_ERROR : initialization performed successfully
+ *     GLOBAL_CONTROL_EIP74_ERROR_INTERNAL : initialization failed
+ */
+static GlobalControl74_Error_t
+GlobalControl74Lib_Init(
+        const GlobalControl74_Configuration_t * const Configuration_p,
+        const uint8_t * const Entropy_p)
+{
+    EIP74_Error_t Rc;
+    EIP74_Configuration_t Conf;
+    unsigned LoopCounter = ADAPTER_EIP74_RESET_MAX_RETRIES;
+    uint32_t Entropy[12];
+
+    Rc = EIP74_Reset(&EIP74State.IOArea);
+    do
+    {
+        if (Rc == EIP74_BUSY_RETRY_LATER)
+        {
+            LoopCounter--;
+            if (LoopCounter == 0)
+            {
+                LOG_CRIT("%s EIP74 reset timed out\n",__func__);
+                return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+            }
+            Rc = EIP74_Reset_IsDone(&EIP74State.IOArea);
+        }
+        else if (Rc != EIP74_NO_ERROR)
+        {
+            LOG_CRIT("%s EIP74 reset error\n",__func__);
+            return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+        }
+    } while (Rc != EIP74_NO_ERROR);
+
+    if (Configuration_p->GenerateBlockSize == 0)
+    {
+        Conf.GenerateBlockSize =  ADAPTER_EIP74_GEN_BLK_SIZE;
+    }
+    else
+    {
+        Conf.GenerateBlockSize = Configuration_p->GenerateBlockSize;
+    }
+
+    if (Configuration_p->ReseedThr == 0)
+    {
+        Conf.ReseedThr =  ADAPTER_EIP74_RESEED_THR;
+    }
+    else
+    {
+        Conf.ReseedThr = Configuration_p->ReseedThr;
+    }
+
+    if (Configuration_p->ReseedThrEarly == 0)
+    {
+        Conf.ReseedThrEarly =  ADAPTER_EIP74_RESEED_THR_EARLY;
+    }
+    else
+    {
+        Conf.ReseedThrEarly = Configuration_p->ReseedThrEarly;
+    }
+
+    Rc = EIP74_Configure(&EIP74State.IOArea, &Conf);
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be configured\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    GlobalControl74Lib_CopyKeyMat(Entropy, Entropy_p, 48);
+
+    Rc = EIP74_Instantiate(&EIP74State.IOArea, Entropy, Configuration_p->fStuckOut);
+
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be instantiated\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Capabilities_Get
+ */
+void
+GlobalControl74_Capabilities_Get(
+        GlobalControl74_Capabilities_t * const Capabilities_p)
+{
+    Device_Handle_t Device;
+    uint8_t Versions[3];
+    LOG_INFO("\n\t\t\t GlobalControl74_Capabilities_Get\n");
+
+    memcpy(Capabilities_p, &Global_CapabilitiesString,
+           sizeof(Global_CapabilitiesString));
+
+    Device = Device_Find(ADAPTER_EIP74_DEVICE_NAME);
+    if (Device == NULL)
+    {
+        LOG_CRIT("%s EIP74 Device not found\n",__func__);
+        return;
+    }
+
+    {
+        EIP74_Capabilities_t Capabilities;
+        EIP74_Error_t Rc;
+
+        if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                RPM_FLAG_SYNC) != RPM_SUCCESS)
+            return;
+
+        Rc = EIP74_HWRevision_Get(Device, &Capabilities);
+
+        (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                       RPM_FLAG_ASYNC);
+
+        if (Rc != EIP74_NO_ERROR)
+        {
+            LOG_CRIT("%s EIP74_Capaboilities_Get() failed\n",__func__);
+            return;
+        }
+
+        Log_FormattedMessage(
+            "EIP74 options: Nof Clients=%u Nof AESCores=%u\n"
+            "\t\tAESSpeed=%u FIFODepth=%u\n",
+            Capabilities.HW_Options.ClientCount,
+            Capabilities.HW_Options.AESCoreCount,
+            Capabilities.HW_Options.AESSpeed,
+            Capabilities.HW_Options.FIFODepth);
+
+
+        Versions[0] = Capabilities.HW_Revision.MajHWRevision;
+        Versions[1] = Capabilities.HW_Revision.MinHWRevision;
+        Versions[2] = Capabilities.HW_Revision.HWPatchLevel;
+    }
+
+    {
+        char * p = Capabilities_p->szTextDescription;
+        int VerIndex = 0;
+        int i = 0;
+
+        while(p[i])
+        {
+            if (p[i] == '_' && VerIndex < 3)
+            {
+                if (Versions[VerIndex] > 9)
+                    p[i] = '?';
+                else
+                    p[i] = '0' + Versions[VerIndex];
+
+                VerIndex++;
+            }
+
+            i++;
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Init
+ */
+GlobalControl74_Error_t
+GlobalControl74_Init(
+        const GlobalControl74_Configuration_t * const Configuration_p,
+        const uint8_t * const Entropy_p)
+{
+    EIP74_Error_t Rc;
+    Device_Handle_t Device;
+
+    LOG_INFO("\n\t\t\t GlobalControl74_Init\n");
+
+    Device = Device_Find(ADAPTER_EIP74_DEVICE_NAME);
+    if (Device == NULL)
+    {
+        LOG_CRIT("%s EIP74 Device not found\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_NOT_IMPLEMENTED;
+    }
+
+
+    Rc = EIP74_Init(&EIP74State.IOArea, Device);
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be initialized\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_NOT_IMPLEMENTED;
+    }
+
+    if (RPM_DEVICE_INIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                    GlobalControl74Lib_Suspend,
+                                    GlobalControl74Lib_Resume) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+
+    if (GlobalControl74Lib_Init(Configuration_p,Entropy_p) !=
+        GLOBAL_CONTROL_EIP74_NO_ERROR)
+    {
+        (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+    EIP74State.fInitialized = true;
+    EIP74State.CachedConfig = *Configuration_p;
+#endif
+    (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    Adapter_Interrupt_SetHandler(ADAPTER_EIP74_ERR_IRQ,
+                                 GlobalControl74_InterruptHandlerNotify);
+    Adapter_Interrupt_SetHandler(ADAPTER_EIP74_RES_IRQ,
+                                 GlobalControl74_InterruptHandlerNotify);
+#endif
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_UnInit
+ */
+GlobalControl74_Error_t
+GlobalControl74_UnInit(void)
+{
+    EIP74_Error_t Rc;
+    unsigned LoopCounter = ADAPTER_EIP74_RESET_MAX_RETRIES;
+
+    LOG_INFO("\n\t\t\t GlobalControl74_UnInit\n");
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    Adapter_Interrupt_SetHandler(ADAPTER_EIP74_ERR_IRQ, NULL);
+    Adapter_Interrupt_SetHandler(ADAPTER_EIP74_RES_IRQ, NULL);
+    Adapter_Interrupt_Disable(ADAPTER_EIP74_ERR_IRQ, 0);
+    Adapter_Interrupt_Disable(ADAPTER_EIP74_RES_IRQ, 0);
+#endif
+    (void)RPM_DEVICE_UNINIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID, false);
+
+    Rc = EIP74_Reset(&EIP74State.IOArea);
+    do
+    {
+        if (Rc == EIP74_BUSY_RETRY_LATER)
+        {
+            LoopCounter--;
+            if (LoopCounter == 0)
+            {
+                LOG_CRIT("%s EIP74 reset timed out\n",__func__);
+                (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+                return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+            }
+            Rc = EIP74_Reset_IsDone(&EIP74State.IOArea);
+        }
+        else if (Rc != EIP74_NO_ERROR)
+        {
+            LOG_CRIT("%s EIP74 reset error\n",__func__);
+            (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+
+            return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+        }
+    } while (Rc != EIP74_NO_ERROR);
+    (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+    EIP74State.fInitialized = false;
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    EIP74State.fInterruptEnabled = false;
+#endif
+#endif
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Reseed
+ */
+GlobalControl74_Error_t
+GlobalControl74_Reseed(
+        const uint8_t * const Entropy_p)
+{
+    EIP74_Error_t Rc;
+    uint32_t Entropy[12];
+    LOG_INFO("\n\t\t\t GlobalControl74_Reseed\n");
+
+
+    GlobalControl74Lib_CopyKeyMat(Entropy, Entropy_p, 48);
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+
+    Rc = EIP74_Reseed(&EIP74State.IOArea, Entropy);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be reseeded\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Status_Get
+ */
+GlobalControl74_Error_t
+GlobalControl74_Status_Get(
+        GlobalControl74_Status_t * const Status_p)
+{
+    EIP74_Error_t Rc;
+    EIP74_Status_t Status;
+    LOG_INFO("\n\t\t\t GlobalControl74_Status_Get\n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+
+    Rc = EIP74_Status_Get(&EIP74State.IOArea, &Status);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 status could not be read\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    Status_p->GenerateBlockCount = Status.GenerateBlockCount;
+    Status_p->fStuckOut = Status.fStuckOut;
+    Status_p->fNotInitialized = Status.fNotInitialized;
+    Status_p->fReseedError = Status.fReseedError;
+    Status_p->fReseedWarning = Status.fReseedWarning;
+    Status_p->fInstantiated = Status.fInstantiated;
+    Status_p->AvailableCount = Status.AvailableCount;
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Clear
+ */
+GlobalControl74_Error_t
+GlobalControl74_Clear(void)
+{
+    EIP74_Error_t Rc;
+    LOG_INFO("\n\t\t\t GlobalControl74_Clear\n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+
+    Rc = EIP74_Clear(&EIP74State.IOArea);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be cleared\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Notify_Request
+ */
+GlobalControl74_Error_t
+GlobalControl74_Notify_Request(
+        GlobalControl74_NotifyFunction_t CBFunc_p)
+{
+    LOG_INFO("\n\t\t\t GlobalControl74_Notify_Request\n");
+    IDENTIFIER_NOT_USED(CBFunc_p);
+
+    EIP74State.Notify_CBFunc = CBFunc_p;
+    if (CBFunc_p != NULL)
+    {
+        Adapter_Interrupt_Enable(ADAPTER_EIP74_ERR_IRQ, 0);
+        Adapter_Interrupt_Enable(ADAPTER_EIP74_RES_IRQ, 0);
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+        EIP74State.fInterruptEnabled = true;
+#endif
+    }
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+#endif
+
+
+/* end of file adapter_global_eip74.c */