wlan: Add vendor event to get the driver hang reason

Add Vendor Event to get the driver hang reason indicating to the
user space that the driver has detected an internal failure.
This event carries the information indicating the reason that triggered
this detection.

CRs-Fixed: 2184455
Change-Id: Icb8900d96431bd249fea213a4043897e7f7b0195
diff --git a/CORE/DXE/src/wlan_qct_dxe.c b/CORE/DXE/src/wlan_qct_dxe.c
index 6d87f2a..8514bb5 100644
--- a/CORE/DXE/src/wlan_qct_dxe.c
+++ b/CORE/DXE/src/wlan_qct_dxe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -64,6 +64,7 @@
 #include "wlan_qct_dxe.h"
 #include "wlan_qct_dxe_i.h"
 #include "wlan_qct_pal_device.h"
+#include "vos_api.h"
 
 /*----------------------------------------------------------------------------
  * Local Definitions
@@ -1714,7 +1715,7 @@
       if (NULL != dxeCtxt)
          dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
 
-      wpalWlanReload();
+      wpalWlanReload(VOS_DXE_FAILURE);
 
       if (NULL != usrData)
          dxeStartSSRTimer((WLANDXE_CtrlBlkType *)usrData);
@@ -2414,7 +2415,7 @@
             HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
                      "RX successive empty interrupt, Could not find invalidated DESC reload driver");
             dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
-            wpalWlanReload();
+            wpalWlanReload(VOS_DXE_FAILURE);
             dxeStartSSRTimer(dxeCtxt);
          }
       }
@@ -2743,7 +2744,7 @@
          if (eWLAN_PAL_STATUS_SUCCESS != dxeErrHandler(channelCb, chHighStat))
          {
             dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
-            wpalWlanReload();
+            wpalWlanReload(VOS_DXE_FAILURE);
             dxeStartSSRTimer(dxeCtxt);
          }
       }
@@ -2798,7 +2799,7 @@
                          dxeErrHandler(channelCb, chLowStat))
          {
             dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
-            wpalWlanReload();
+            wpalWlanReload(VOS_DXE_FAILURE);
             dxeStartSSRTimer(dxeCtxt);
          }
       }
@@ -2850,7 +2851,7 @@
                             dxeErrHandler(channelCb, chLogRxStat))
             {
                dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
-               wpalWlanReload();
+               wpalWlanReload(VOS_DXE_FAILURE);
                dxeStartSSRTimer(dxeCtxt);
             }
 
@@ -2904,7 +2905,7 @@
                             dxeErrHandler(channelCb, chLogRxFwStat))
             {
                dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
-               wpalWlanReload();
+               wpalWlanReload(VOS_DXE_FAILURE);
                dxeStartSSRTimer(dxeCtxt);
             }
 
@@ -4102,7 +4103,7 @@
                          dxeErrHandler(channelCb, chStat))
          {
             dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
-            wpalWlanReload();
+            wpalWlanReload(VOS_DXE_FAILURE);
             dxeStartSSRTimer(dxeCtxt);
          }
          bEnableISR = 1;
@@ -4159,7 +4160,7 @@
                          dxeErrHandler(channelCb, chStat))
          {
              dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
-             wpalWlanReload();
+             wpalWlanReload(VOS_DXE_FAILURE);
              dxeStartSSRTimer(dxeCtxt);
          }
          bEnableISR = 1;
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 0d0f71b..2e3f2a8 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -220,6 +220,62 @@
     QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET = 149,
     /* Get the NUD stats, represented by the enum qca_attr_nud_stats_get */
     QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET = 150,
+    /*
+     * Event indicating to the user space that the driver has detected an
+     * internal failure. This event carries the information indicating the
+     * reason that triggered this detection. The attributes for this
+     * command are defined in enum qca_wlan_vendor_attr_hang.
+     */
+    QCA_NL80211_VENDOR_SUBCMD_HANG = 157,
+};
+
+enum qca_wlan_vendor_hang_reason {
+	/* Unspecified reason */
+	QCA_WLAN_HANG_REASON_UNSPECIFIED = 0,
+	/* No Map for the MAC entry for the received frame */
+	QCA_WLAN_HANG_RX_HASH_NO_ENTRY_FOUND = 1,
+	/* peer deletion timeout happened */
+	QCA_WLAN_HANG_PEER_DELETION_TIMEDOUT = 2,
+	/* peer unmap timeout */
+	QCA_WLAN_HANG_PEER_UNMAP_TIMEDOUT = 3,
+	/* Scan request timed out */
+	QCA_WLAN_HANG_SCAN_REQ_EXPIRED = 4,
+	/* Consecutive Scan attempt failures */
+	QCA_WLAN_HANG_SCAN_ATTEMPT_FAILURES = 5,
+	/* Unable to get the message buffer */
+	QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE = 6,
+	/* Current command processing is timedout */
+	QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT = 7,
+	/* Timeout for an ACK from FW for suspend request */
+	QCA_WLAN_HANG_SUSPEND_TIMEOUT = 8,
+	/* Timeout for an ACK from FW for resume request */
+	QCA_WLAN_HANG_RESUME_TIMEOUT = 9,
+	/* Transmission timeout for consecutive data frames */
+	QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT = 10,
+	/* Timeout for the TX completion status of data frame */
+	QCA_WLAN_HANG_TX_COMPLETE_TIMEOUT = 11,
+	/* DXE failure for tx/Rx, DXE resource unavailability */
+	QCA_WLAN_HANG_DXE_FAILURE = 12,
+	/* WMI pending commands exceed the maximum count */
+	QCA_WLAN_HANG_WMI_EXCEED_MAX_PENDING_CMDS = 13,
+	/* WDI failure for commands, WDI resource unavailability */
+	QCA_WLAN_HANG_WDI_FAILURE = 14,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_hang - Used by the vendor command
+ * QCA_NL80211_VENDOR_SUBCMD_HANG.
+ */
+enum qca_wlan_vendor_attr_hang {
+	QCA_WLAN_VENDOR_ATTR_HANG_INVALID = 0,
+	/*
+	 * Reason for the Hang - Represented by enum
+	 * qca_wlan_vendor_hang_reason.
+	 */
+	 QCA_WLAN_VENDOR_ATTR_HANG_REASON = 1,
+	 QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST,
+	 QCA_WLAN_VENDOR_ATTR_HANG_MAX =
+		QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST - 1,
 };
 
 /**
@@ -418,6 +474,7 @@
     QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
     QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX,
     QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX,
+    QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX,
 };
 
 /**
@@ -1666,6 +1723,16 @@
 #endif
 
 /**
+ * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
+ * @hdd_ctx: Pointer to hdd context
+ * @reason: cds recovery reason
+ *
+ * Return: 0 on success or failure reason
+ */
+int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
+				    unsigned int reason);
+
+/**
  * enum qca_wlan_vendor_attr_memory_dump - values for memory dump attributes
  * @QCA_WLAN_VENDOR_ATTR_MEMORY_DUMP_INVALID - Invalid
  * @QCA_WLAN_VENDOR_ATTR_REQUEST_ID - Indicate request ID
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 5297661..55df656 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -652,6 +652,101 @@
 #endif /* FEATURE_WLAN_CH_AVOID */
 
 /*
+ * define short names for the global vendor params
+ * used by QCA_NL80211_VENDOR_SUBCMD_HANG
+ */
+#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
+
+/**
+ * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
+ * hang reason
+ * @reason: cds recovery reason
+ *
+ * Return: Vendor specific reason code
+ */
+static enum qca_wlan_vendor_hang_reason
+hdd_convert_hang_reason(enum vos_hang_reason reason)
+{
+	unsigned int ret_val;
+
+	switch (reason) {
+	case VOS_GET_MSG_BUFF_FAILURE:
+		ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
+		break;
+	case VOS_ACTIVE_LIST_TIMEOUT:
+		ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
+		break;
+	case VOS_SCAN_REQ_EXPIRED:
+		ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
+		break;
+	case VOS_TRANSMISSIONS_TIMEOUT:
+		ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
+		break;
+	case VOS_DXE_FAILURE:
+		ret_val = QCA_WLAN_HANG_DXE_FAILURE;
+		break;
+	case VOS_WDI_FAILURE:
+		ret_val = QCA_WLAN_HANG_WDI_FAILURE;
+		break;
+	case VOS_REASON_UNSPECIFIED:
+	default:
+		ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
+	}
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
+ * @hdd_ctx: Pointer to hdd context
+ * @reason: cds recovery reason
+ *
+ * Return: 0 on success or failure reason
+ */
+int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
+				    enum vos_hang_reason reason)
+{
+	struct sk_buff *vendor_event;
+	enum qca_wlan_vendor_hang_reason hang_reason;
+
+	ENTER();
+
+	if (!hdd_ctx) {
+		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+			  "HDD context is null");
+		return -EINVAL;
+	}
+
+	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+						   NULL,
+#endif
+						   sizeof(unsigned int),
+						   HANG_REASON_INDEX,
+						   GFP_KERNEL);
+	if (!vendor_event) {
+		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+			  "cfg80211_vendor_event_alloc failed");
+		return -ENOMEM;
+	}
+
+	hang_reason = hdd_convert_hang_reason(reason);
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
+			(unsigned int) hang_reason)) {
+		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+			  "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
+		kfree_skb(vendor_event);
+		return -EINVAL;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+	EXIT();
+	return 0;
+}
+#undef HANG_REASON_INDEX
+
+/*
  * FUNCTION: __wlan_hdd_cfg80211_nan_request
  * This is called when wlan driver needs to send vendor specific
  * nan request event.
@@ -8763,6 +8858,10 @@
         .vendor_id = QCA_NL80211_VENDOR_ID,
         .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
     },
+    [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
+        .vendor_id = QCA_NL80211_VENDOR_ID,
+        .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
+    },
 };
 
 /*
@@ -14825,7 +14924,7 @@
                 else
                 {
                     hddLog(LOGE, FL("Triggering SSR"));
-                    vos_wlanRestart();
+                    vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
                 }
             }
         }
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index 375adab..f54e414 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -2221,6 +2221,25 @@
 };
 #endif
 
+/**
+ * hdd_send_hang_reason() - Send hang reason to the userspace
+ *
+ * Return: None
+ */
+static void hdd_send_hang_reason(hdd_context_t *hdd_ctx)
+{
+	unsigned int reason = 0;
+
+	if(!hdd_ctx) {
+		hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
+		return;
+	}
+
+	vos_get_recovery_reason(&reason);
+	vos_reset_recovery_reason();
+	wlan_hdd_send_hang_reason_event(hdd_ctx, reason);
+}
+
 /* the HDD interface to WLAN driver shutdown,
  * the primary shutdown function in SSR
  */
@@ -2407,6 +2426,7 @@
                                            __func__);
    }
    hdd_wlan_ssr_shutdown_event();
+   hdd_send_hang_reason(pHddCtx);
    hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
                                    ,__func__);
    return VOS_STATUS_SUCCESS;
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index fd5f1db..272a76f 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -483,7 +483,7 @@
         else
         {
            /* Trigger SSR */
-           vos_wlanRestart();
+           vos_wlanRestart(VOS_GET_MSG_BUFF_FAILURE);
         }
     }
 
@@ -12801,7 +12801,7 @@
        if (!(vos_isLoadUnloadInProgress() ||
            vos_is_logp_in_progress(VOS_MODULE_ID_SME, NULL)))
        {
-          vos_wlanRestart();
+          vos_wlanRestart(VOS_ACTIVE_LIST_TIMEOUT);
        }
     }
 }
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index 91f1ba6..6846f66 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -7822,7 +7822,7 @@
     * Issue SSR. vos_wlanRestart has tight checks to make sure that
     * we do not send an FIQ if previous FIQ is not processed
     */
-   vos_wlanRestart();
+   vos_wlanRestart(VOS_REASON_UNSPECIFIED);
 }
 
 /*==========================================================================
diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h
index d6c17c5..b1287b5 100644
--- a/CORE/VOSS/inc/vos_api.h
+++ b/CORE/VOSS/inc/vos_api.h
@@ -220,6 +220,26 @@
    VOS_WDI_WRITE,
 } vos_wdi_trace_event_type;
 
+/**
+ * enum vos_hang_reason - host hang/ssr reason
+ * @VOS_REASON_UNSPECIFIED: Unspecified reason
+ * @VOS_GET_MSG_BUFF_FAILURE: Unable to get the message buffer
+ * @VOS_ACTIVE_LIST_TIMEOUT: Current command processing is timedout
+ * @VOS_SCAN_REQ_EXPIRED: Scan request timed out
+ * @VOS_TRANSMISSIONS_TIMEOUT: transmission timed out
+ * @VOS_DXE_FAILURE: dxe failure
+ * @VOS_WDI_FAILURE: wdi failure
+ */
+enum vos_hang_reason {
+	VOS_REASON_UNSPECIFIED = 0,
+	VOS_GET_MSG_BUFF_FAILURE = 1,
+	VOS_ACTIVE_LIST_TIMEOUT = 2,
+	VOS_SCAN_REQ_EXPIRED = 3,
+	VOS_TRANSMISSIONS_TIMEOUT = 4,
+	VOS_DXE_FAILURE = 5,
+	VOS_WDI_FAILURE = 6,
+};
+
 /*------------------------------------------------------------------------- 
   Function declarations and documenation
   ------------------------------------------------------------------------*/
@@ -459,13 +479,13 @@
   Note that this API will not initiate any RIVA subsystem restart.
 
   @param
-       NONE
+       reason: vos_hang_reason
   @return
        VOS_STATUS_SUCCESS   - Operation completed successfully.
        VOS_STATUS_E_FAILURE - Operation failed.
 
 */
-VOS_STATUS vos_wlanRestart(void);
+VOS_STATUS vos_wlanRestart(enum vos_hang_reason reason);
 
 /**
   @brief vos_fwDumpReq()
@@ -558,4 +578,18 @@
 }
 #endif /* LINUX_VERSION_CODE */
 
+/**
+ * vos_get_recovery_reason() - get self recovery reason
+ * @reason: recovery reason
+ *
+ * Return: None
+ */
+void vos_get_recovery_reason(enum vos_hang_reason *reason);
+
+/**
+ * vos_reset_recovery_reason() - reset the reason to unspecified
+ *
+ * Return: None
+ */
+void vos_reset_recovery_reason(void);
 #endif // if !defined __VOS_NVITEM_H
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index fc10b55..6dd7f8c 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -1775,7 +1775,7 @@
     {
          VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "Do SSR for reason_code=%d", reason_code);
-         vos_wlanRestart();
+         vos_wlanRestart(VOS_GET_MSG_BUFF_FAILURE);
     }
 }
 
@@ -2864,7 +2864,7 @@
   The function wlan_hdd_restart_driver protects against re-entrant calls.
 
   @param
-       NONE
+       reason: recovery reason
   @return
        VOS_STATUS_SUCCESS   - Operation completed successfully.
        VOS_STATUS_E_FAILURE - Operation failed.
@@ -2873,11 +2873,11 @@
 
 
 */
-VOS_STATUS vos_wlanRestart(void)
+VOS_STATUS vos_wlanRestart(enum vos_hang_reason reason)
 {
    VOS_STATUS vstatus;
    hdd_context_t *pHddCtx = NULL;
-   v_CONTEXT_t pVosContext        = NULL;
+   VosContextType  *pVosContext        = NULL;
 
    /* Check whether driver load unload is in progress */
    if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL)) 
@@ -2894,7 +2894,8 @@
                "%s: Global VOS context is Null", __func__);
       return VOS_STATUS_E_FAILURE;
    }
-    
+   pVosContext->recovery_reason = reason;
+
    /* Get the HDD context */
    pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
    if(!pHddCtx) {
@@ -2908,6 +2909,45 @@
    return vstatus;
 }
 
+/**
+ * vos_get_recovery_reason() - get self recovery reason
+ * @reason: recovery reason
+ *
+ * Return: None
+ */
+void vos_get_recovery_reason(enum vos_hang_reason *reason)
+{
+	VosContextType *pVosContext = NULL;
+
+	pVosContext = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL);
+	if(!pVosContext) {
+		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+		     "%s: Global VOS context is Null", __func__);
+		return;
+	}
+
+	*reason = pVosContext->recovery_reason;
+}
+
+/**
+ * vos_reset_recovery_reason() - reset the reason to unspecified
+ *
+ * Return: None
+ */
+void vos_reset_recovery_reason(void)
+{
+	VosContextType *pVosContext = NULL;
+
+	pVosContext = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL);
+	if(!pVosContext) {
+		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+		     "%s: Global VOS context is Null", __func__);
+		return;
+	}
+
+	pVosContext->recovery_reason = VOS_REASON_UNSPECIFIED;
+}
+
 
 /**
   @brief vos_fwDumpReq()
diff --git a/CORE/VOSS/src/vos_sched.h b/CORE/VOSS/src/vos_sched.h
index 0e5d612..3a92a65 100644
--- a/CORE/VOSS/src/vos_sched.h
+++ b/CORE/VOSS/src/vos_sched.h
@@ -83,6 +83,7 @@
 #endif
 
 #include <vos_timer.h>
+#include <vos_api.h>
 
 
 #define TX_POST_EVENT               0x000
@@ -375,6 +376,7 @@
    spinlock_t wdthread_work_lock;
    bool snoc_high_freq_voting;
    spinlock_t freq_voting_lock;
+   enum vos_hang_reason recovery_reason;
 } VosContextType, *pVosContextType;
 
 
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index f27cefd..6c3c993 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -9869,7 +9869,7 @@
        {
            VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
                   FL("reload wlan driver"));
-           wpalWlanReload();
+           wpalWlanReload(VOS_WDI_FAILURE);
        }
    }
    return;
@@ -15038,7 +15038,7 @@
       {
          VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
                    "%s: Request system recovery", __func__);
-         vos_wlanRestart();
+         vos_wlanRestart(VOS_TRANSMISSIONS_TIMEOUT);
       }
       status = VOS_STATUS_E_FAILURE;
    }
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 6e5069f..4b4ebd0 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -16943,7 +16943,7 @@
     wdiStartRspCb( &wdiRspParams, pWDICtx->pRspCBUserData);
 
     WDI_DetectedDeviceError(pWDICtx, wdiRspParams.wdiStatus);
-    wpalWlanReload();
+    wpalWlanReload(VOS_WDI_FAILURE);
 
     /*Although the response is an error - it was processed by our function
     so as far as the caller is concerned this is a succesful reponse processing*/
@@ -17079,7 +17079,7 @@
                halMacStopRspMsg.stopRspParams.status);
 
     WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE);
-    wpalWlanReload();
+    wpalWlanReload(VOS_WDI_FAILURE);
 
     wpalMutexRelease(&pWDICtx->wptMutex);
     return WDI_STATUS_E_FAILURE;
@@ -23073,7 +23073,7 @@
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Invalid packet received from HAL - catastrophic failure");
     WDI_DetectedDeviceError( pWDICtx, WDI_ERR_INVALID_RSP_FMT);
-    wpalWlanReload();
+    wpalWlanReload(VOS_WDI_FAILURE);
 
     return;
   }
@@ -23600,7 +23600,7 @@
     }
 #else
     WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE);
-    wpalWlanReload();
+    wpalWlanReload(VOS_WDI_FAILURE);
 #endif
   }
   else
diff --git a/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h b/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h
index aeacf6f..7998a40 100644
--- a/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h
+++ b/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015,2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -309,11 +309,11 @@
     wpalWlanReload -  Initiate WLAN Driver reload
 
     Param:
-       None
+       reason: hang reason
     Return:
        NONE
 ---------------------------------------------------------------------------*/
-void wpalWlanReload(void);
+void wpalWlanReload(wpt_uint32 reason);
 
 /*---------------------------------------------------------------------------
     wpalWcnssResetIntr -  Trigger the reset FIQ to Riva
diff --git a/CORE/WDI/WPAL/src/wlan_qct_pal_api.c b/CORE/WDI/WPAL/src/wlan_qct_pal_api.c
index a6019cb..79c3ef3 100644
--- a/CORE/WDI/WPAL/src/wlan_qct_pal_api.c
+++ b/CORE/WDI/WPAL/src/wlan_qct_pal_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012,2014-2015,2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012,2014-2015,2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -389,13 +389,13 @@
     wpalWlanReload -  Initiate WLAN Driver reload
 
     Param:
-       None
+       reason: hang reason
     Return:
        NONE
 ---------------------------------------------------------------------------*/
-void wpalWlanReload(void)
+void wpalWlanReload(enum vos_hang_reason reason)
 {
-   vos_wlanRestart();
+   vos_wlanRestart(reason);
    return;
 }