From e46c66008eb57162a907bd96a1ae112022be3f6f Mon Sep 17 00:00:00 2001
From: Doredla Sudheer Kumar <s-doredla@ti.com>
Date: Wed, 31 Jan 2024 17:06:25 +0530
Subject: [PATCH] mcm: Fix race condition in MCM request/response handling

    Facing the race conditions between multiple MailboxP_post requests for
    EnetMcm_serverTask. Two or more client tasks were posting Mailbox with
    MCM commands for EnetMcm_serverTask and then pending on the response.
    As we had only one response queue, the response was pulled in by the
    wrong client task followed by Assertion.

    This condition is not easily reproducible, it happens only when server
    task is processing one client task and simultaneously another client
    task posted on the server Mailbox. This race condition was achieved
    by creating two tasks and adding sleep after one client request.
    EnetMcm_serverTask was processing client request of task 1 and
    immediately after sleep client task 2 posted Mailboxfor another
    request for EnetMcm_serverTask.

    Now, we will have a queue of response mailbox per client in order to
    handle MCM commands for EnetMcm_serverTask so that each client have
    its own response mailbox for its requested MCM command.

Signed-off-by: Doredla Sudheer Kumar <s-doredla@ti.com>
---
 ethfw/ethfw/src/ethfw.c                       |   1 +
 .../src/ethfw_callbacks_lwipif.c              |   1 +
 ethfw/utils/ethfw_stats/src/app_ethfw_stats.c |   2 +
 ethfw/utils/intervlan/src/eth_swintervlan.c   |   1 +
 .../enet/examples/enet_lwip_example/main.c    |   1 +
 .../examples/timesync/hal/src/timeSync_cpsw.c |   1 +
 .../timesync/hal/src/timeSync_icssg.c         |   1 +
 .../ti/drv/enet/examples/utils/enet_mcm.c     | 396 +++++++++++++-----
 .../enet/examples/utils/include/enet_mcm.h    |   3 +
 .../packages/ti/osal/src/nonos/QueueP_nonos.c |  13 +-
 10 files changed, 303 insertions(+), 117 deletions(-)

diff --git a/ethfw/ethfw/src/ethfw.c b/ethfw/ethfw/src/ethfw.c
index 3aa264ed..70a78ec4 100644
--- a/ethfw/ethfw/src/ethfw.c
+++ b/ethfw/ethfw/src/ethfw.c
@@ -1181,6 +1181,7 @@ static void EthFw_deinitMcm(void)
 {
     /* Release MCM handle - CPSW should close if we're last client */
     EnetMcm_releaseHandleInfo(&gEthFwObj.mcmCmdIf);
+    EnetMcm_releaseCmdIf(gEthFwObj.enetType, &gEthFwObj.mcmCmdIf);
 
     /* De-initialize CPSW MCM */
     EnetMcm_deInit(gEthFwObj.enetType);
diff --git a/ethfw/utils/ethfw_callbacks/src/ethfw_callbacks_lwipif.c b/ethfw/utils/ethfw_callbacks/src/ethfw_callbacks_lwipif.c
index 1ba014e4..14994306 100644
--- a/ethfw/utils/ethfw_callbacks/src/ethfw_callbacks_lwipif.c
+++ b/ethfw/utils/ethfw_callbacks/src/ethfw_callbacks_lwipif.c
@@ -378,6 +378,7 @@ void EthFwCallbacks_lwipifCpswReleaseHandle(LwipifEnetAppIf_ReleaseHandleInfo *r
 
     EnetMcm_coreDetach(&mcmCmdIf, releaseInfo->coreId, releaseInfo->coreKey);
     EnetMcm_releaseHandleInfo(&mcmCmdIf);
+    EnetMcm_releaseCmdIf(enetType, &mcmCmdIf);
 }
 
 #if defined(ETHFW_PROXY_ARP_HANDLING)
diff --git a/ethfw/utils/ethfw_stats/src/app_ethfw_stats.c b/ethfw/utils/ethfw_stats/src/app_ethfw_stats.c
index 626ac145..5e8ebe25 100644
--- a/ethfw/utils/ethfw_stats/src/app_ethfw_stats.c
+++ b/ethfw/utils/ethfw_stats/src/app_ethfw_stats.c
@@ -321,6 +321,8 @@ int32_t appEthfwStatsInit(Enet_Type enetType, uint32_t instId)
         obj->ethfwStatsShutdown = false;
     }
 
+    EnetMcm_releaseCmdIf(obj->enetType, &cmdIf);
+
     return status;
 }
 
diff --git a/ethfw/utils/intervlan/src/eth_swintervlan.c b/ethfw/utils/intervlan/src/eth_swintervlan.c
index 984f6b58..4de27ae8 100644
--- a/ethfw/utils/intervlan/src/eth_swintervlan.c
+++ b/ethfw/utils/intervlan/src/eth_swintervlan.c
@@ -279,6 +279,7 @@ static void CpswApp_InterVlanRouting(void* a0,
     EnetAppUtils_freePktInfoQ(&cqPktInfoQ);
 
     EnetMcm_releaseHandleInfo(&cmdIf);
+    EnetMcm_releaseCmdIf(gCpswInterVlanAppObj.enetType, &cmdIf);
 }
 
 void CpswApp_ingRxIsrFxn(void *appData)
diff --git a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/enet_lwip_example/main.c b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/enet_lwip_example/main.c
index 78370473..6e758518 100644
--- a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/enet_lwip_example/main.c
+++ b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/enet_lwip_example/main.c
@@ -780,6 +780,7 @@ void LwipifEnetAppCb_releaseHandle(LwipifEnetAppIf_ReleaseHandleInfo *releaseInf
 
     EnetMcm_coreDetach(pMcmCmdIf, releaseInfo->coreId, releaseInfo->coreKey);
     EnetMcm_releaseHandleInfo(pMcmCmdIf);
+    EnetMcm_releaseCmdIf(gEnetAppCfg.enetType, pMcmCmdIf);
 }
 
 static void EnetApp_deinit(void)
diff --git a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/timesync/hal/src/timeSync_cpsw.c b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/timesync/hal/src/timeSync_cpsw.c
index c7e54e88..8f681497 100644
--- a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/timesync/hal/src/timeSync_cpsw.c
+++ b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/timesync/hal/src/timeSync_cpsw.c
@@ -946,6 +946,7 @@ void TimeSync_close(TimeSync_Handle timeSyncHandle)
                            timeSyncHandle->coreKey);
         /* Release handle info */
         EnetMcm_releaseHandleInfo(&timeSyncHandle->hMcmCmdIf);
+		EnetMcm_releaseCmdIf(timeSyncHandle->enetType, &timeSyncHandle->hMcmCmdIf);
 
     }
 }
diff --git a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/timesync/hal/src/timeSync_icssg.c b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/timesync/hal/src/timeSync_icssg.c
index 2d6454c1..24fadc1e 100644
--- a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/timesync/hal/src/timeSync_icssg.c
+++ b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/timesync/hal/src/timeSync_icssg.c
@@ -779,6 +779,7 @@ void TimeSync_close(TimeSync_Handle timeSyncHandle)
                            timeSyncHandle->coreKey);
         /* Release handle info */
         EnetMcm_releaseHandleInfo(&timeSyncHandle->hMcmCmdIf);
+		EnetMcm_releaseCmdIf(timeSyncHandle->enetType, &timeSyncHandle->hMcmCmdIf);
 
     }
 }
diff --git a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/utils/enet_mcm.c b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/utils/enet_mcm.c
index a7294221..7481822a 100644
--- a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/utils/enet_mcm.c
+++ b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/utils/enet_mcm.c
@@ -68,6 +68,9 @@
 #define ENETMCM_TSK_PRIORITY                (2U)
 #define ENETMCM_PERIODICTSK_PRIORITY        (7U)
 #define ENETMCM_ASYNCIOCTLTASK_PRIORITY     (9U)
+#define ENETMCM_MAX_CLIENTS                 (8U)
+#define ENETMCM_INTERNAL_CLIENT_IDX         (ENETMCM_MAX_CLIENTS)
+
 
 #if defined(SAFERTOS)
 #define ENETMCM_TSK_STACK_SIZE              (16U * 1024U)
@@ -79,6 +82,15 @@
 #define ENETMCM_MBOX_SIZE                   (sizeof(EnetMcm_mailboxObj) * ENETMCM_MBOX_MSG_COUNT)
 #endif
 
+/*! \brief Get the index of the given element within an array */
+#define ENETMCM_UTILS_GETARRAYINDEX(member, array)   (member - &array[0])
+
+/*! \brief Macro to determine if a member is part of an array */
+#define ENETMCM_UTILS_ARRAYISMEMBER(member, array)                              \
+    (((((uintptr_t)member - (uintptr_t) & array[0]) % sizeof(array[0])) == 0)   \
+     && (member >= &array[0])                                                   \
+     && (ENETMCM_UTILS_GETARRAYINDEX(member, array) < ENET_ARRAYSIZE(array)))
+
 /* ========================================================================== */
 /*                         Structure Declarations                             */
 /* ========================================================================== */
@@ -102,6 +114,76 @@ typedef struct EnetMcm_CoreAttachTable_s
     EnetMcm_CoreAttachTableEntry entry[ENET_CFG_REMOTE_CLIENT_CORES_MAX];
 }  EnetMcm_CoreAttachTable;
 
+typedef enum EnetMcm_Command_e
+{
+    /*! GET CPSW & UDMA HANDLE */
+    MCM_GET_HANDLE,
+
+    /*! RELEASE HANDLE */
+    MCM_RELEASE_HANDLE,
+
+    /*! ATTACH core */
+    MCM_CORE_ATTACH,
+
+    /*! DETACH core */
+    MCM_CORE_DETACH,
+
+    /*! Run IOCTL. Mainly useful for asynchronous IOCTLs */
+    MCM_IOCTL,
+
+    /*! SHUTDOWN MCM */
+    MCM_SHUTDOWN,
+
+    /*! Disconnecting client */
+    MCM_CLIENT_DISCONNECT,
+
+    /*! Response to MCM_GET_HANDLE command */
+    MCM_RESPONSE_GET_HANDLE,
+
+    /*! Response to MCM_RELEASE_HANDLE command */
+    MCM_RESPONSE_RELEASE_HANDLE,
+
+    /*! Response to MCM_CORE_ATTACH command */
+    MCM_RESPONSE_CORE_ATTACH,
+
+    /*! Response to MCM_CORE_DETACH command */
+    MCM_RESPONSE_CORE_DETACH,
+
+    /*! Response to MCM_IOCL command */
+    MCM_RESPONSE_IOCTL,
+
+    /*! Response to SHUTDOWN MCM */
+    MCM_RESPONSE_SHUTDOWN,
+
+    /*! Response to Client Disconnect */
+    MCM_RESPONSE_CLIENT_DISCONNECT,
+}
+EnetMcm_Command;
+
+typedef struct EnetMcm_mailboxObj_s
+{
+    EnetMcm_Command cmd;
+    MailboxP_Handle response;
+
+    struct EnetMcm_mailboxMsgs_s
+    {
+        uint32_t coreId;
+        uint32_t coreKey;
+        uint32_t ioctlStatus;
+        uint32_t ioctlCmd;
+        Enet_IoctlPrms *ioctlPrms;
+        EnetMcm_HandleInfo handleInfo;
+        EnetPer_AttachCoreOutArgs attachInfo;
+    } msgBody;
+} EnetMcm_mailboxObj;
+
+typedef struct EnetMcm_RespMboxObj_s
+{
+    QueueP_Elem qElem;
+    bool isValidClient;
+    MailboxP_Handle hMbox;
+} EnetMcm_RespMboxObj;
+
 typedef struct EnetMcm_Obj_s
 {
     bool isInitDone;
@@ -136,7 +218,11 @@ typedef struct EnetMcm_Obj_s
 
     MailboxP_Handle hMboxCmd;
 
-    MailboxP_Handle hMboxResponse;
+    EnetMcm_RespMboxObj *hInternalClientRespMbox;
+
+    QueueP_Handle hMboxRespFreeQ;
+
+    EnetMcm_RespMboxObj respMbox[(ENETMCM_MAX_CLIENTS + 1)];
 
     ClockP_Handle hTimer;
 
@@ -171,63 +257,17 @@ typedef struct EnetMcm_Obj_s
     /*! Semaphore used to wait for async IOCTL completion. It's posted from
      *  async IOCTL callback which is called from Enet_poll() */
     SemaphoreP_Handle asyncIoctlSem;
-}EnetMcm_Obj;
-
-typedef enum EnetMcm_Command_e
-{
-    /*! GET CPSW & UDMA HANDLE */
-    MCM_GET_HANDLE,
-
-    /*! RELEASE HANDLE */
-    MCM_RELEASE_HANDLE,
-
-    /*! ATTACH core */
-    MCM_CORE_ATTACH,
-
-    /*! DETACH core */
-    MCM_CORE_DETACH,
-
-    /*! Run IOCTL. Mainly useful for asynchronous IOCTLs */
-    MCM_IOCTL,
-
-    /*! SHUTDOWN MCM */
-    MCM_SHUTDOWN,
-
-    /*! Response to MCM_GET_HANDLE command */
-    MCM_RESPONSE_GET_HANDLE,
-
-    /*! Response to MCM_RELEASE_HANDLE command */
-    MCM_RESPONSE_RELEASE_HANDLE,
 
-    /*! Response to MCM_CORE_ATTACH command */
-    MCM_RESPONSE_CORE_ATTACH,
+    uint8_t mcmMainTaskStack[ENETMCM_TSK_STACK_SIZE] __attribute__ ((aligned(ENETMCM_TSK_STACK_ALIGN)));
 
-    /*! Response to MCM_CORE_DETACH command */
-    MCM_RESPONSE_CORE_DETACH,
+    uint8_t mcmPrdTaskStack[ENETMCM_TSK_STACK_SIZE] __attribute__ ((aligned(ENETMCM_TSK_STACK_ALIGN)));
 
-    /*! Response to MCM_IOCL command */
-    MCM_RESPONSE_IOCTL,
+    uint8_t asyncIoctlTaskStack[ENETMCM_TSK_STACK_SIZE] __attribute__ ((aligned(ENETMCM_TSK_STACK_ALIGN)));
 
-    /*! Response to SHUTDOWN MCM */
-    MCM_RESPONSE_SHUTDOWN,
-}
-EnetMcm_Command;
+    uint8_t mcmRequestMbxBuf[ENETMCM_MBOX_SIZE] __attribute__ ((aligned(32)));
 
-typedef struct EnetMcm_mailboxObj_s
-{
-    EnetMcm_Command cmd;
-
-    struct EnetMcm_mailboxMsgs_s
-    {
-        uint32_t coreId;
-        uint32_t coreKey;
-        uint32_t ioctlStatus;
-        uint32_t ioctlCmd;
-        Enet_IoctlPrms *ioctlPrms;
-        EnetMcm_HandleInfo handleInfo;
-        EnetPer_AttachCoreOutArgs attachInfo;
-    } msgBody;
-}EnetMcm_mailboxObj;
+    uint8_t mcmResponseMbxBuf[(ENETMCM_MAX_CLIENTS + 1)][ENETMCM_MBOX_SIZE] __attribute__ ((aligned(32)));
+}EnetMcm_Obj;
 
 /* ========================================================================== */
 /*                          Function Declarations                             */
@@ -242,6 +282,12 @@ static void     EnetMcm_serverTask(void * hMcm,
 
 static int32_t  EnetMcm_enablePorts(EnetMcm_Handle hMcm);
 
+static void EnetMcm_shutdown(Enet_Type enetType,
+                             EnetMcm_CmdIf *hMcmCmdIf);
+
+static EnetMcm_RespMboxObj* EnetMcm_getRespMbox(EnetMcm_Handle hMcm,
+                                                MailboxP_Handle hMboxResp);
+
 /* ========================================================================== */
 /*                            Global Variables                                */
 /* ========================================================================== */
@@ -255,7 +301,7 @@ static EnetMcm_Obj gMcmObj[] =
         .hMutex                 = NULL,
         .task                   = NULL,
         .hMboxCmd               = NULL,
-        .hMboxResponse          = NULL,
+        .hInternalClientRespMbox = NULL,
         .hTimer                 = NULL,
         .task_periodicTick      = NULL,
         .timerSem               = NULL,
@@ -272,7 +318,7 @@ static EnetMcm_Obj gMcmObj[] =
         .hMutex                 = NULL,
         .task                   = NULL,
         .hMboxCmd               = NULL,
-        .hMboxResponse          = NULL,
+        .hInternalClientRespMbox = NULL,
         .hTimer                 = NULL,
         .task_periodicTick      = NULL,
         .timerSem               = NULL,
@@ -290,7 +336,7 @@ static EnetMcm_Obj gMcmObj[] =
         .hMutex                 = NULL,
         .task                   = NULL,
         .hMboxCmd               = NULL,
-        .hMboxResponse          = NULL,
+        .hInternalClientRespMbox = NULL,
         .hTimer                 = NULL,
         .task_periodicTick      = NULL,
         .timerSem               = NULL,
@@ -308,7 +354,7 @@ static EnetMcm_Obj gMcmObj[] =
         .hMutex                 = NULL,
         .task                   = NULL,
         .hMboxCmd               = NULL,
-        .hMboxResponse          = NULL,
+        .hInternalClientRespMbox = NULL,
         .hTimer                 = NULL,
         .task_periodicTick      = NULL,
         .timerSem               = NULL,
@@ -319,16 +365,6 @@ static EnetMcm_Obj gMcmObj[] =
     },
 };
 
-uint8_t mcmMainTaskStack[ENETMCM_TSK_STACK_SIZE] __attribute__ ((aligned(ENETMCM_TSK_STACK_ALIGN)));
-
-uint8_t mcmPrdTaskStack[ENETMCM_TSK_STACK_SIZE] __attribute__ ((aligned(ENETMCM_TSK_STACK_ALIGN)));
-
-uint8_t asyncIoctlTaskStack[ENETMCM_TSK_STACK_SIZE] __attribute__ ((aligned(ENETMCM_TSK_STACK_ALIGN)));
-
-uint8_t mcmRequestMbxBuf[ENETMCM_MBOX_SIZE] __attribute__ ((aligned(32)));
-
-uint8_t mcmResponseMbxBuf[ENETMCM_MBOX_SIZE] __attribute__ ((aligned(32)));
-
 /* ========================================================================== */
 /*                          Function Definitions                              */
 /* ========================================================================== */
@@ -454,34 +490,55 @@ static void EnetMcm_delCoreAttachEntry(EnetMcm_CoreAttachTable *attachTbl,
 static void EnetMcm_initMbox(EnetMcm_Handle hMcm)
 {
     TaskP_Params params;
-
+    EnetMcm_RespMboxObj *respMbox;
+    QueueP_Params qPrms;
     MailboxP_Params mboxParams;
+    uint32_t i;
+
+    QueueP_Params_init(&qPrms);
+
+    hMcm->hMboxRespFreeQ = QueueP_create(&qPrms);
+    EnetAppUtils_assert(hMcm->hMboxRespFreeQ != NULL);
 
     MailboxP_Params_init(&mboxParams);
     mboxParams.name = (uint8_t *)"MCM Request MBX";
     mboxParams.size =  sizeof(EnetMcm_mailboxObj);
     mboxParams.count = ENETMCM_MBOX_MSG_COUNT;
-    mboxParams.buf = (void *)mcmRequestMbxBuf;
-    mboxParams.bufsize = sizeof(mcmRequestMbxBuf);
+    mboxParams.buf = (void *)hMcm->mcmRequestMbxBuf;
+    mboxParams.bufsize = sizeof(hMcm->mcmRequestMbxBuf);
 
     hMcm->hMboxCmd = MailboxP_create(&mboxParams);
     EnetAppUtils_assert(hMcm->hMboxCmd != NULL);
 
-    MailboxP_Params_init(&mboxParams);
-    mboxParams.name = (uint8_t *)"MCM Response MBX";
-    mboxParams.size =  sizeof(EnetMcm_mailboxObj);
-    mboxParams.count = ENETMCM_MBOX_MSG_COUNT;
-    mboxParams.buf = (void *)mcmResponseMbxBuf;
-    mboxParams.bufsize = sizeof(mcmResponseMbxBuf);
-
-    hMcm->hMboxResponse = MailboxP_create(&mboxParams);
-    EnetAppUtils_assert(hMcm->hMboxResponse != NULL);
+    for (i = 0U; i < ENET_ARRAYSIZE(hMcm->respMbox); i++)
+    {
+        MailboxP_Params_init(&mboxParams);
+        mboxParams.name = (uint8_t *)"MCM Response MBX";
+        mboxParams.size =  sizeof(EnetMcm_mailboxObj);
+        mboxParams.count = ENETMCM_MBOX_MSG_COUNT;
+        mboxParams.buf = (void *)&hMcm->mcmResponseMbxBuf[i][0];
+        mboxParams.bufsize = sizeof(hMcm->mcmResponseMbxBuf[i]);
+
+        respMbox = &hMcm->respMbox[i];
+        respMbox->hMbox = MailboxP_create(&mboxParams);
+        respMbox->isValidClient = false;
+        EnetAppUtils_assert(respMbox->hMbox != NULL);
+        if (i != ENETMCM_INTERNAL_CLIENT_IDX)
+        {
+            QueueP_put(hMcm->hMboxRespFreeQ, &respMbox->qElem);
+        }
+        else
+        {
+            respMbox->isValidClient = true;
+            hMcm->hInternalClientRespMbox = respMbox;
+        }
+    }
 
     TaskP_Params_init(&params);
 
     params.priority  = ENETMCM_TSK_PRIORITY;
-    params.stack     = &mcmMainTaskStack[0];
-    params.stacksize = ENETMCM_TSK_STACK_SIZE;
+    params.stack     = &hMcm->mcmMainTaskStack[0];
+    params.stacksize = sizeof(hMcm->mcmMainTaskStack);
     params.arg0      = hMcm;
 
     switch (hMcm->enetType)
@@ -660,6 +717,8 @@ void  EnetMcm_getCmdIf(Enet_Type enetType,
                        EnetMcm_CmdIf *hMcmCmdIf)
 {
     EnetMcm_Handle hMcm = &gMcmObj[enetType];
+    EnetMcm_RespMboxObj *respMbox;
+    QueueP_Elem *elem;
 
     EnetAppUtils_assert(hMcmCmdIf != NULL);
     EnetAppUtils_assert(hMcm->hMutex != NULL);
@@ -667,8 +726,15 @@ void  EnetMcm_getCmdIf(Enet_Type enetType,
     MutexP_lock(hMcm->hMutex, MutexP_WAIT_FOREVER);
     EnetAppUtils_assert(hMcm->isInitDone == true);
 
+    elem = (QueueP_Elem *)QueueP_get(hMcm->hMboxRespFreeQ);
+    EnetAppUtils_assert(elem != NULL);
+    respMbox = container_of(elem, EnetMcm_RespMboxObj, qElem);
+
     hMcmCmdIf->hMboxCmd      = hMcm->hMboxCmd;
-    hMcmCmdIf->hMboxResponse = hMcm->hMboxResponse;
+    hMcmCmdIf->hMboxResponse = respMbox->hMbox;
+
+    EnetAppUtils_assert(respMbox->isValidClient == false);
+    respMbox->isValidClient = true;
 
     MutexP_unlock(hMcm->hMutex);
 
@@ -676,10 +742,54 @@ void  EnetMcm_getCmdIf(Enet_Type enetType,
     EnetAppUtils_assert(hMcmCmdIf->hMboxResponse != NULL);
 }
 
+void EnetMcm_releaseCmdIf(Enet_Type enetType,
+                          EnetMcm_CmdIf *hMcmCmdIf)
+{
+    EnetMcm_Handle hMcm = &gMcmObj[enetType];
+    EnetMcm_RespMboxObj *respMbox = NULL;
+    EnetMcm_mailboxObj msg;
+
+    EnetAppUtils_assert(hMcmCmdIf != NULL);
+    EnetAppUtils_assert(hMcm->hMutex != NULL);
+
+    memset(&msg, 0, sizeof(msg));
+    msg.cmd = MCM_CLIENT_DISCONNECT;
+    msg.response = hMcmCmdIf->hMboxResponse;
+
+    MailboxP_post(hMcmCmdIf->hMboxCmd, &msg, SemaphoreP_WAIT_FOREVER);
+    MailboxP_pend(hMcmCmdIf->hMboxResponse, &msg, SemaphoreP_WAIT_FOREVER);
+    EnetAppUtils_assert(msg.cmd == MCM_RESPONSE_CLIENT_DISCONNECT);
+    EnetAppUtils_assert(MailboxP_getNumPendingMsgs(hMcmCmdIf->hMboxResponse) == 0);
+
+    respMbox = EnetMcm_getRespMbox(hMcm, hMcmCmdIf->hMboxResponse);
+    /* The mcm server should have cleared the isValidClient on receiving the disconnect command */
+    EnetAppUtils_assert(respMbox->isValidClient == false);
+
+    QueueP_put(hMcm->hMboxRespFreeQ, &respMbox->qElem);
+}
+
+static void EnetMcm_releaseInternalRespMbox(EnetMcm_Handle hMcm)
+{
+    EnetMcm_mailboxObj msg;
+
+    memset(&msg, 0, sizeof(msg));
+    msg.cmd = MCM_CLIENT_DISCONNECT;
+    EnetAppUtils_assert(hMcm->hInternalClientRespMbox != NULL);
+    msg.response = hMcm->hInternalClientRespMbox->hMbox;
+
+    MailboxP_post(hMcm->hMboxCmd, &msg, SemaphoreP_WAIT_FOREVER);
+    MailboxP_pend(hMcm->hInternalClientRespMbox->hMbox, &msg, SemaphoreP_WAIT_FOREVER);
+    EnetAppUtils_assert(msg.cmd == MCM_RESPONSE_CLIENT_DISCONNECT);
+    EnetAppUtils_assert(MailboxP_getNumPendingMsgs(hMcm->hInternalClientRespMbox->hMbox) == 0);
+
+    EnetAppUtils_assert(hMcm->hInternalClientRespMbox->isValidClient == false);
+}
+
 void EnetMcm_deInit(Enet_Type enetType)
 {
     EnetMcm_Handle hMcm = &gMcmObj[enetType];
-    uint32_t numPendingmsgs;
+    uint32_t i;
+    EnetMcm_CmdIf mcmCmdIf;
 
     EnetAppUtils_assert(hMcm->hMutex != NULL);
 
@@ -687,39 +797,45 @@ void EnetMcm_deInit(Enet_Type enetType)
 
     if (hMcm->isInitDone == true)
     {
-        EnetMcm_mailboxObj msg;
-
-        msg.cmd = MCM_SHUTDOWN;
-
-        MailboxP_post(hMcm->hMboxCmd, &msg, MailboxP_WAIT_FOREVER);
-        MailboxP_pend(hMcm->hMboxResponse, &msg, MailboxP_WAIT_FOREVER);
-        EnetAppUtils_assert(msg.cmd == MCM_RESPONSE_SHUTDOWN);
-
-        while (TaskP_isTerminated(hMcm->task) != 1)
+        /*! Releasing response queue mailbox per client */
+        for (i = 0U; i < ENETMCM_MAX_CLIENTS; i++)
         {
-            TaskP_sleep(10);
+            if ((i != ENETMCM_INTERNAL_CLIENT_IDX) && (hMcm->respMbox[i].isValidClient == true))
+            {
+                mcmCmdIf.hMboxCmd = hMcm->hMboxCmd;
+                mcmCmdIf.hMboxResponse = hMcm->respMbox[i].hMbox;
+                EnetMcm_releaseCmdIf(enetType, &mcmCmdIf);
+            }
         }
-        TaskP_delete(&hMcm->task);
 
-        numPendingmsgs = MailboxP_getNumPendingMsgs(hMcm->hMboxCmd);
-        while (numPendingmsgs != 0U)
-        {
-            MailboxP_pend(hMcm->hMboxCmd, &msg, SemaphoreP_WAIT_FOREVER);
-            numPendingmsgs = MailboxP_getNumPendingMsgs(hMcm->hMboxCmd);
-        }
+        /* For shutting down MCM*/
+        EnetMcm_releaseInternalRespMbox(hMcm);
+        mcmCmdIf.hMboxCmd = hMcm->hMboxCmd;
+        EnetAppUtils_assert(hMcm->hInternalClientRespMbox != NULL);
+        mcmCmdIf.hMboxResponse = hMcm->hInternalClientRespMbox->hMbox;
+        EnetMcm_shutdown(enetType, &mcmCmdIf);
 
+        /* Deleting hMboxCmd Mailbox*/
+        EnetAppUtils_assert(MailboxP_getNumPendingMsgs(hMcm->hMboxCmd) == 0);
         MailboxP_delete(hMcm->hMboxCmd);
+        hMcm->hMboxCmd = NULL;
 
-        numPendingmsgs = MailboxP_getNumPendingMsgs(hMcm->hMboxResponse);
-        while (numPendingmsgs != 0U)
+        /* Deleting all hMboxResp Mailboxes */
+        for (i = 0U; i < ENET_ARRAYSIZE(hMcm->respMbox); i++)
         {
-            MailboxP_pend(hMcm->hMboxResponse, &msg, SemaphoreP_WAIT_FOREVER);
-            numPendingmsgs = MailboxP_getNumPendingMsgs(hMcm->hMboxResponse);
+            EnetAppUtils_assert(MailboxP_getNumPendingMsgs(hMcm->respMbox[i].hMbox) == 0);
+            MailboxP_delete(hMcm->respMbox[i].hMbox);
         }
+        hMcm->hInternalClientRespMbox = NULL;
 
-        MailboxP_delete(hMcm->hMboxResponse);
+        QueueP_delete(hMcm->hMboxRespFreeQ);
 
         EnetMcm_initAttachTable(&hMcm->coreAttachTable);
+        while (TaskP_isTerminated(hMcm->task) != 1)
+        {
+            TaskP_sleep(10);
+        }
+        TaskP_delete(&hMcm->task);
         hMcm->isInitDone = false;
     }
 
@@ -909,8 +1025,8 @@ static void EnetMcm_createClock(EnetMcm_Handle hMcm)
      * default priority (1) */
     TaskP_Params_init(&params);
     params.priority       = ENETMCM_PERIODICTSK_PRIORITY;
-    params.stack          = &mcmPrdTaskStack[0];
-    params.stacksize      = ENETMCM_TSK_STACK_SIZE;
+    params.stack          = &hMcm->mcmPrdTaskStack[0];
+    params.stacksize      = sizeof(hMcm->mcmPrdTaskStack);
     params.arg0           = hMcm->timerSem;
     params.arg1           = hMcm;
     params.name           = (const char *)"Enet_PeriodicTickTask";
@@ -926,7 +1042,7 @@ static int32_t EnetMcm_open(EnetMcm_Handle hMcm)
     EnetUtils_Cfg utilsPrms;
     void *perCfg = NULL;
     EnetUdma_Cfg *udmaCfg = &hMcm->dmaCfg;
-    uint32_t cfgSize;
+    uint32_t cfgSize = 0U;
     TaskP_Params params;
     SemaphoreP_Params semParams;
 
@@ -1005,8 +1121,8 @@ static int32_t EnetMcm_open(EnetMcm_Handle hMcm)
     params.arg0           = hMcm;
     params.arg1           = hMcm->asyncIoctlSem;
     params.name           = (const char *)"EnetMcm_AsyncIoctlTask";
-    params.stack          =  &asyncIoctlTaskStack[0];
-    params.stacksize      =  sizeof(asyncIoctlTaskStack);
+    params.stack          = &hMcm->asyncIoctlTaskStack[0];
+    params.stacksize      = sizeof(hMcm->asyncIoctlTaskStack);
 
     hMcm->asyncIoctlTaskShutdown = false;
 
@@ -1150,9 +1266,16 @@ static void EnetMcm_serverTask(void * McmHandle,
     {
         int32_t status = ENET_SOK;
         EnetMcm_mailboxObj msg;
+        EnetMcm_RespMboxObj *respMbox;
+        uint32_t idx;
 
         MailboxP_pend(hMcm->hMboxCmd, &msg, SemaphoreP_WAIT_FOREVER);
 
+        respMbox = EnetMcm_getRespMbox(hMcm, msg.response);
+        /* For MCM_SHUTDOWN the cmd is sent by internal MCM client at deInit time.
+         * This client should have isValidClient set to false */
+        EnetAppUtils_assert((respMbox->isValidClient == true) || (msg.cmd == MCM_SHUTDOWN));
+
         switch (msg.cmd)
         {
             case MCM_GET_HANDLE:
@@ -1205,14 +1328,22 @@ static void EnetMcm_serverTask(void * McmHandle,
             case MCM_SHUTDOWN:
                 isShutdownMcm = true;
                 msg.cmd       = MCM_RESPONSE_SHUTDOWN;
+                EnetAppUtils_assert(ENETMCM_UTILS_ARRAYISMEMBER(respMbox, hMcm->respMbox) == true);
+                idx = ENETMCM_UTILS_GETARRAYINDEX(respMbox, hMcm->respMbox);
+                EnetAppUtils_assert(idx == ENETMCM_INTERNAL_CLIENT_IDX);
+                break;
+
+            case MCM_CLIENT_DISCONNECT:
+                msg.cmd = MCM_RESPONSE_CLIENT_DISCONNECT;
+                /* Clear client valid flag on receiving disconnect message */
+                respMbox->isValidClient = false;
                 break;
 
             default:
                 /* Unahandle MCM command */
                 EnetAppUtils_assert(false);
         }
-
-        MailboxP_post(hMcm->hMboxResponse, &msg, SemaphoreP_WAIT_FOREVER);
+        MailboxP_post(msg.response, &msg, SemaphoreP_WAIT_FOREVER);
     }
 }
 
@@ -1319,6 +1450,8 @@ void EnetMcm_acquireHandleInfo(const EnetMcm_CmdIf *hMcmCmdIf,
     msg.cmd = MCM_GET_HANDLE;
     if ((hMcmCmdIf != NULL) && (handleInfo != NULL))
     {
+        msg.response = hMcmCmdIf->hMboxResponse;
+
         MailboxP_post(hMcmCmdIf->hMboxCmd, &msg, SemaphoreP_WAIT_FOREVER);
         MailboxP_pend(hMcmCmdIf->hMboxResponse, &msg, SemaphoreP_WAIT_FOREVER);
         EnetAppUtils_assert(msg.cmd == MCM_RESPONSE_GET_HANDLE);
@@ -1335,9 +1468,11 @@ void EnetMcm_releaseHandleInfo(const EnetMcm_CmdIf *hMcmCmdIf)
 {
     EnetMcm_mailboxObj msg;
 
+    EnetAppUtils_assert(hMcmCmdIf != NULL);
+
     memset(&msg, 0, sizeof(msg));
     msg.cmd = MCM_RELEASE_HANDLE;
-    EnetAppUtils_assert(hMcmCmdIf != NULL);
+    msg.response = hMcmCmdIf->hMboxResponse;
 
     MailboxP_post(hMcmCmdIf->hMboxCmd, &msg, SemaphoreP_WAIT_FOREVER);
     MailboxP_pend(hMcmCmdIf->hMboxResponse, &msg, SemaphoreP_WAIT_FOREVER);
@@ -1354,6 +1489,7 @@ void EnetMcm_coreAttach(const EnetMcm_CmdIf *hMcmCmdIf,
     if ((hMcmCmdIf != NULL) && (attachInfo != NULL))
     {
         msg.cmd            = MCM_CORE_ATTACH;
+        msg.response       = hMcmCmdIf->hMboxResponse;
         msg.msgBody.coreId = coreId;
 
         MailboxP_post(hMcmCmdIf->hMboxCmd, &msg, SemaphoreP_WAIT_FOREVER);
@@ -1376,6 +1512,7 @@ void     EnetMcm_coreDetach(const EnetMcm_CmdIf *hMcmCmdIf,
     memset(&msg, 0, sizeof(msg));
     EnetAppUtils_assert(hMcmCmdIf != NULL);
     msg.cmd             = MCM_CORE_DETACH;
+    msg.response        = hMcmCmdIf->hMboxResponse;
     msg.msgBody.coreId  = coreId;
     msg.msgBody.coreKey = coreKey;
 
@@ -1395,7 +1532,8 @@ int32_t EnetMcm_ioctl(const EnetMcm_CmdIf *hMcmCmdIf,
 
     if ((hMcmCmdIf != NULL) && (prms != NULL))
     {
-        msg.cmd = MCM_IOCTL;
+        msg.cmd               = MCM_IOCTL;
+        msg.response          = hMcmCmdIf->hMboxResponse;
         msg.msgBody.ioctlCmd  = cmd;
         msg.msgBody.ioctlPrms = prms;
 
@@ -1412,3 +1550,33 @@ int32_t EnetMcm_ioctl(const EnetMcm_CmdIf *hMcmCmdIf,
 
     return status;
 }
+
+static void EnetMcm_shutdown(Enet_Type enetType, EnetMcm_CmdIf *hMcmCmdIf)
+{
+    EnetMcm_mailboxObj msg;
+
+    msg.cmd = MCM_SHUTDOWN;
+    msg.response = hMcmCmdIf->hMboxResponse;
+
+    MailboxP_post(hMcmCmdIf->hMboxCmd, &msg, SemaphoreP_WAIT_FOREVER);
+    MailboxP_pend(hMcmCmdIf->hMboxResponse, &msg, SemaphoreP_WAIT_FOREVER);
+    EnetAppUtils_assert(msg.cmd == MCM_RESPONSE_SHUTDOWN);
+}
+
+static EnetMcm_RespMboxObj* EnetMcm_getRespMbox(EnetMcm_Handle hMcm, MailboxP_Handle hMboxResp)
+{
+    EnetMcm_RespMboxObj *respMbox = NULL;
+    uint32_t i;
+
+    for (i = 0U; i < ENET_ARRAYSIZE(hMcm->respMbox); i++)
+    {
+        if(hMboxResp == hMcm->respMbox[i].hMbox)
+        {
+            respMbox = &hMcm->respMbox[i];
+            break;
+        }
+    }
+    EnetAppUtils_assert(respMbox != NULL);
+
+    return respMbox;
+}
diff --git a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/utils/include/enet_mcm.h b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/utils/include/enet_mcm.h
index 46908631..86595632 100644
--- a/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/utils/include/enet_mcm.h
+++ b/pdk_jacinto_08_06_00_31/packages/ti/drv/enet/examples/utils/include/enet_mcm.h
@@ -115,6 +115,9 @@ int32_t  EnetMcm_init(const EnetMcm_InitConfig *pMcmInitCfg);
 void  EnetMcm_getCmdIf(Enet_Type enetType,
                        EnetMcm_CmdIf *hMcmCmdIf);
 
+void  EnetMcm_releaseCmdIf(Enet_Type enetType,
+                           EnetMcm_CmdIf *hMcmCmdIf);
+
 void     EnetMcm_acquireHandleInfo(const EnetMcm_CmdIf *hMcmCmdIf,
                                    EnetMcm_HandleInfo *handleInfo);
 
diff --git a/pdk_jacinto_08_06_00_31/packages/ti/osal/src/nonos/QueueP_nonos.c b/pdk_jacinto_08_06_00_31/packages/ti/osal/src/nonos/QueueP_nonos.c
index e325661e..b9384f12 100644
--- a/pdk_jacinto_08_06_00_31/packages/ti/osal/src/nonos/QueueP_nonos.c
+++ b/pdk_jacinto_08_06_00_31/packages/ti/osal/src/nonos/QueueP_nonos.c
@@ -202,10 +202,17 @@ void * QueueP_get(QueueP_Handle handle)
     { 
         q = &queue->queueHndl;
 
-        pElem = q->next;
+        if ((bool)true != QueueP_isEmpty(handle))
+        {
+            pElem = q->next;
 
-        q->next = pElem->next;
-        pElem->next->prev = q;
+            q->next = pElem->next;
+            pElem->next->prev = q;
+        }
+        else
+        {
+            pElem = NULL;
+        }
     }
     
     HwiP_restore(key);
-- 
2.17.1

