wlan: Address memory corruption due to double free

If MC thread fails to post any WDI message over bus then failure
status is sent to the caller through registered request callback
and WDI_STATUS_PENDING is returned to the actual request funcion
to avoid repeated functionality done in the request callback for
failure case. But the commit "Reload driver if EXIT IMPS REQ fails
due to invalid SMD port" will modify the wdiStatus which results
in double free, i.e both WDA request and WDA request status callback
functions endup in freeing the same memory.

To mitigate this issue, return WDI_STATUS_PENDING to the request
function if we already returned WDI_STATUS_DEV_INTERNAL_FAILURE
or WDI_STATUS_E_FAILURE status through registered request callback.
And also handle the logic to reload the wlan driver if WDI_EXIT_IMPS
REQ fails due to closed SMD port in request callback function.

Change-Id: I932e6684c4272332c2b14cc4896b7c00c86fa4cd
CRs-Fixed: 767711
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 2b0a32e..f2401ae 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -3776,6 +3776,7 @@
 WDI_Status
 WDI_ExitImpsReq
 (
+   WDI_ExitImpsReqParamsType *pwdiExitImpsReqParams,
    WDI_ExitImpsRspCb  wdiExitImpsRspCb,
    void*                   pUserData
 )
@@ -3798,8 +3799,8 @@
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_EXIT_IMPS_REQ;
-  wdiEventData.pEventData      = NULL;
-  wdiEventData.uEventDataSize  = 0;
+  wdiEventData.pEventData      = pwdiExitImpsReqParams;
+  wdiEventData.uEventDataSize  = sizeof(*pwdiExitImpsReqParams);
   wdiEventData.pCBfnc          = wdiExitImpsRspCb;
   wdiEventData.pUserData       = pUserData;
 
@@ -13885,13 +13886,16 @@
    wpt_uint8*               pSendBuffer         = NULL;
    wpt_uint16               usDataOffset        = 0;
    wpt_uint16               usSendSize          = 0;
+   WDI_ExitImpsReqParamsType *pwdiExitImpsReqParams = NULL;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
    /*-------------------------------------------------------------------------
      Sanity check
    -------------------------------------------------------------------------*/
    if (( NULL == pEventData ) ||
-       ( NULL == (wdiExitImpsRspCb   = (WDI_ExitImpsRspCb)pEventData->pCBfnc)))
+       ( NULL == (wdiExitImpsRspCb   = (WDI_ExitImpsRspCb)pEventData->pCBfnc)) ||
+        (NULL == (pwdiExitImpsReqParams =
+                 (WDI_ExitImpsReqParamsType*)pEventData->pEventData)))
    {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                   "%s: Invalid parameters", __func__);
@@ -13914,7 +13918,8 @@
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
    }
-
+   pWDICtx->wdiReqStatusCB = pwdiExitImpsReqParams->wdiReqStatusCB;
+   pWDICtx->pReqStatusUserData = pwdiExitImpsReqParams->pUserData;
    /*-------------------------------------------------------------------------
      Send Get STA Request to HAL
    -------------------------------------------------------------------------*/
@@ -22171,7 +22176,8 @@
                 WDI_getRespMsgString(pWDICtx->wdiExpectedResponse),
                 pWDICtx->wdiExpectedResponse);
 
-     wdiStatus = WDI_STATUS_E_FAILURE;
+     wdiStatus = (ret == eWLAN_PAL_STATUS_E_FAILURE) ?
+                  WDI_STATUS_DEV_INTERNAL_FAILURE : WDI_STATUS_E_FAILURE;
    }
    else
    {
@@ -22204,8 +22210,10 @@
      (wdiStatus) to WDI_STATUS_PENDING. This makes sure that WDA doesnt
      end up repeating the functonality in the req callback  for the
      WDI_STATUS_E_FAILURE case*/
-     if (wdiStatus == WDI_STATUS_E_FAILURE)
+     if (wdiStatus != WDI_STATUS_SUCCESS)
+     {
        wdiStatus = WDI_STATUS_PENDING;
+     }
    }
 
   if ( wdiStatus == WDI_STATUS_SUCCESS )
@@ -22221,10 +22229,6 @@
   {
      /*Inform upper stack layers that a transport fatal error occurred*/
      WDI_DetectedDeviceError(pWDICtx, WDI_ERR_TRANSPORT_FAILURE);
-     if (eWLAN_PAL_STATUS_E_FAILURE == ret)
-     {
-         wdiStatus = WDI_STATUS_DEV_INTERNAL_FAILURE;
-     }
   }
 
   return wdiStatus;