wlan: Added the ioctl support to flush FW logs.

Currently, FW sends the logs to host when the threshold
is reached or timer gets expired.
IOCTL is added to query the FW logs whenever user wants it.

Change-Id: I322af974a23d887b277dbc324cdc202b00e8bb69
CRs-Fixed: 882148
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 245e63d..b84d4e3 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -136,6 +136,7 @@
 #define CRDA_WAIT_TIME 300
 #endif
 
+#define WAIT_TIME_FW_LOGS 2000
 /* Scan Req Timeout */
 #define WLAN_WAIT_TIME_SCAN_REQ 100
 
@@ -1263,7 +1264,6 @@
 #else
    struct completion driver_crda_req;
 #endif
-
    /* Completion variable to indicate updation of channel */
    struct completion wiphy_channel_update_event;
 
diff --git a/CORE/HDD/src/wlan_hdd_ftm.c b/CORE/HDD/src/wlan_hdd_ftm.c
index dec6418..e420de8 100644
--- a/CORE/HDD/src/wlan_hdd_ftm.c
+++ b/CORE/HDD/src/wlan_hdd_ftm.c
@@ -628,6 +628,15 @@
       goto err_probe_event;
    }
 
+   if(vos_event_init(&(gpVosContext->fwLogsComplete)) != VOS_STATUS_SUCCESS )
+   {
+      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                "%s: Unable to init fwLogsComplete",__func__);
+      VOS_ASSERT(0);
+
+      goto err_wda_complete_event;
+   }
+
    /* Initialize the free message queue */
    vStatus = vos_mq_init(&gpVosContext->freeVosMq);
    if (! VOS_IS_STATUS_SUCCESS(vStatus))
@@ -637,7 +646,7 @@
                 "%s: Failed to initialize VOS free message queue %d",
                  __func__, vStatus);
       VOS_ASSERT(0);
-      goto err_wda_complete_event;
+      goto err_fw_logs_complete_event;
    }
 
    for (iter = 0; iter < VOS_CORE_MAX_MESSAGES; iter++)
@@ -759,6 +768,9 @@
 err_msg_queue:
    vos_mq_deinit(&gpVosContext->freeVosMq);
 
+err_fw_logs_complete_event:
+   vos_event_destroy(&gpVosContext->fwLogsComplete);
+
 err_wda_complete_event:
    vos_event_destroy(&gpVosContext->wdaCompleteEvent);
 
@@ -849,6 +861,14 @@
      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
   }
 
+  vosStatus = vos_event_destroy(&gpVosContext->fwLogsComplete);
+  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
+  {
+     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+         "%s: Failed to destroy fwLogsComplete %d", __func__, vosStatus);
+     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
+  }
+
   return VOS_STATUS_SUCCESS;
 }
 
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index adcdae0..f28dc8e 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -240,6 +240,7 @@
 #define WE_STOP_OBSS_SCAN    11
 #define WE_DUMP_ROAM_TIMER_LOG     12
 #define WE_RESET_ROAM_TIMER_LOG    13
+#define WE_GET_FW_LOGS             14
 
 /* Private ioctls and their sub-ioctls */
 #define WLAN_PRIV_SET_VAR_INT_GET_NONE   (SIOCIWFIRSTPRIV + 7)
@@ -982,6 +983,7 @@
    return VOS_STATUS_SUCCESS;
 }
 
+
 VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr)
 {
    struct statsContext context;
@@ -7002,6 +7004,14 @@
             vos_reset_roam_timer_log();
             break;
         }
+        case WE_GET_FW_LOGS:
+        {
+            vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
+                     WLAN_LOG_INDICATOR_IOCTL,
+                     WLAN_LOG_REASON_CODE_UNUSED,
+                     TRUE);
+            break;
+        }
         default:
         {
             hddLog(LOGE, "%s: unknown ioctl %d", __func__, sub_cmd);
@@ -10434,12 +10444,19 @@
         0,
         0,
         "resetRoamDelay" },
+    {
+        WE_GET_FW_LOGS,
+        0,
+        0,
+        "getFwLogs" },
     /* handlers for main ioctl */
     {   WLAN_PRIV_SET_VAR_INT_GET_NONE,
         IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
         0,
         "" },
 
+
+
     /* handlers for sub-ioctl */
     {   WE_LOG_DUMP_CMD,
         IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 4b14650..cc57479 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -3745,6 +3745,11 @@
     void                   *fwlogInitCbContext;
 }tSirFWLoggingInitParam,*tpSirFWLoggingInitParam;
 
+typedef struct sSirFatalEventLogsReqParam
+{
+    tANI_U32 reason_code;
+}tSirFatalEventLogsReqParam, *tpSirFatalEventLogsReqParam;
+
 #ifdef FEATURE_WLAN_SCAN_PNO
 //
 // PNO Messages
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 2fa32dd..f769de6 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -712,6 +712,7 @@
 #define SIR_HAL_SET_RTS_CTS_HTVHT            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 268)
 #define SIR_HAL_MON_START_REQ               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 269)
 #define SIR_HAL_MON_STOP_REQ                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 270)
+#define SIR_HAL_FATAL_EVENT_LOGS_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 271)
 
 #define SIR_HAL_MSG_TYPES_END              (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 // CFG message types
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index ff648ba..d8defd9 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3707,4 +3707,7 @@
                                       tANI_U8 fcc_constraint);
 
 eHalStatus sme_DeleteAllTDLSPeers(tHalHandle hHal, uint8_t sessionId);
+eHalStatus sme_fatal_event_logs_req(tHalHandle hHal, tANI_U32 is_fatal,
+                               tANI_U32 indicator, tANI_U32 reason_code);
+
 #endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 30e7200..2a4ed84 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -12794,6 +12794,55 @@
 
 }
 
+
+/* ---------------------------------------------------------------------------
+    \fn sme_fatal_event_logs_req
+    \brief  API to to send flush log command to FW..
+
+    \param  hHal - Mac Context Handle
+    \- return VOS_STATUS_SUCCES if command is posted to
+       WDA else return eHAL_STATUS_FAILURE
+    -------------------------------------------------------------------------*/
+eHalStatus sme_fatal_event_logs_req(tHalHandle hHal, tANI_U32 is_fatal,
+                               tANI_U32 indicator, tANI_U32 reason_code)
+{
+    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+    vos_msg_t msg;
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
+    tpSirFatalEventLogsReqParam pFatalEventLogsReqParams;
+
+    if ( eHAL_STATUS_SUCCESS ==  sme_AcquireGlobalLock( &pMac->sme ))
+    {
+        pFatalEventLogsReqParams = vos_mem_malloc(sizeof(tSirFatalEventLogsReqParam));
+        if(NULL == pFatalEventLogsReqParams)
+        {
+            smsLog(pMac, LOGE,
+                 FL("vos_mem_alloc failed "));
+            return eHAL_STATUS_FAILED_ALLOC;
+        }
+        vos_mem_set(pFatalEventLogsReqParams, sizeof(pFatalEventLogsReqParams), 0);
+        pFatalEventLogsReqParams->reason_code = reason_code;
+
+        vos_mem_zero(&msg, sizeof(vos_msg_t));
+        msg.type = WDA_FATAL_EVENT_LOGS_REQ;
+        msg.reserved = 0;
+        msg.bodyptr = pFatalEventLogsReqParams;
+        msg.bodyval = 0;
+        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &msg);
+        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
+        {
+           vos_mem_free(pFatalEventLogsReqParams);
+           status = eHAL_STATUS_FAILURE;
+        }
+        sme_ReleaseGlobalLock( &pMac->sme );
+        return status;
+
+    }
+    return eHAL_STATUS_FAILURE;
+}
+
+
 /**
  * sme_handleSetFccChannel() - handle fcc constraint request
  * @hal: HAL pointer
diff --git a/CORE/SVC/inc/wlan_logging_sock_svc.h b/CORE/SVC/inc/wlan_logging_sock_svc.h
index f3c1412..2cd6745 100644
--- a/CORE/SVC/inc/wlan_logging_sock_svc.h
+++ b/CORE/SVC/inc/wlan_logging_sock_svc.h
@@ -39,6 +39,7 @@
 #include <vos_trace.h>
 #include <wlan_nlink_common.h>
 
+
 int wlan_logging_sock_init_svc(void);
 int wlan_logging_sock_deinit_svc(void);
 int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf);
@@ -46,6 +47,20 @@
 int wlan_logging_sock_deactivate_svc(void);
 int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length);
 int wlan_queue_logpkt_for_app(vos_pkt_t *pPacket, uint32 pkt_type);
+void wlan_process_done_indication(uint8 type, uint32 reason_code);
+
+void wlan_init_log_completion(void);
+int wlan_set_log_completion(uint32 is_fatal,
+                            uint32 indicator,
+                            uint32 reason_code);
+void wlan_get_log_completion(uint32 *is_fatal,
+                             uint32 *indicator,
+                             uint32 *reason_code);
+bool wlan_is_log_report_in_progress(void);
+void wlan_reset_log_report_in_progress(void);
+
+void wlan_deinit_log_completion(void);
+
 void wlan_logging_set_log_level(void);
 
 
diff --git a/CORE/SVC/src/logging/wlan_logging_sock_svc.c b/CORE/SVC/src/logging/wlan_logging_sock_svc.c
old mode 100755
new mode 100644
index 1d6ddec..0558f85
--- a/CORE/SVC/src/logging/wlan_logging_sock_svc.c
+++ b/CORE/SVC/src/logging/wlan_logging_sock_svc.c
@@ -58,6 +58,7 @@
 #define LOGGER_MGMT_DATA_PKT_POST_MASK   0x001
 #define HOST_LOG_POST_MASK   0x002
 #define LOGGER_FW_LOG_PKT_POST_MASK   0x003
+#define LOGGER_FATAL_EVENT_POST_MASK  0x004
 
 #define LOGGER_MAX_DATA_MGMT_PKT_Q_LEN   (8)
 #define LOGGER_MAX_FW_LOG_PKT_Q_LEN   (16)
@@ -85,6 +86,14 @@
 	char logbuf[MAX_LOGMSG_LENGTH];
 };
 
+struct logger_log_complete {
+	uint32_t is_fatal;
+	uint32_t indicator;
+	uint32_t reason_code;
+	bool is_report_in_progress;
+	bool is_flush_complete;
+};
+
 struct wlan_logging {
 	/* Log Fatal and ERROR to console */
 	bool log_fe_to_console;
@@ -128,6 +137,9 @@
 	unsigned long event_flag;
 	/* Indicates logger thread is activated */
 	bool is_active;
+	/* data structure for log complete event*/
+	struct logger_log_complete log_complete;
+	spinlock_t bug_report_lock;
 };
 
 static struct wlan_logging gwlan_logging;
@@ -722,9 +734,10 @@
 		ret_wait_status = wait_event_interruptible(
 		  gwlan_logging.wait_queue,
 		  (test_bit(HOST_LOG_POST_MASK, &gwlan_logging.event_flag) ||
-		  gwlan_logging.exit || test_bit(LOGGER_MGMT_DATA_PKT_POST_MASK,
-		  &gwlan_logging.event_flag) || test_bit(
-		  LOGGER_FW_LOG_PKT_POST_MASK, &gwlan_logging.event_flag)));
+		   gwlan_logging.exit ||
+		   test_bit(LOGGER_MGMT_DATA_PKT_POST_MASK,&gwlan_logging.event_flag) ||
+		   test_bit(LOGGER_FW_LOG_PKT_POST_MASK, &gwlan_logging.event_flag) ||
+		   test_bit(LOGGER_FATAL_EVENT_POST_MASK, &gwlan_logging.event_flag)));
 
 		if (ret_wait_status == -ERESTARTSYS) {
 			pr_err("%s: wait_event return -ERESTARTSYS", __func__);
@@ -753,6 +766,21 @@
 			&gwlan_logging.event_flag)) {
 			send_data_mgmt_log_pkt_to_user();
 		}
+
+		if (test_and_clear_bit(LOGGER_FATAL_EVENT_POST_MASK,
+			&gwlan_logging.event_flag)) {
+			if (gwlan_logging.log_complete.is_flush_complete == true) {
+				gwlan_logging.log_complete.is_flush_complete = false;
+				vos_send_fatal_event_done();
+			}
+			else {
+				gwlan_logging.log_complete.is_flush_complete = true;
+				set_bit(HOST_LOG_POST_MASK,&gwlan_logging.event_flag);
+				set_bit(LOGGER_FW_LOG_PKT_POST_MASK,&gwlan_logging.event_flag);
+				set_bit(LOGGER_FATAL_EVENT_POST_MASK,&gwlan_logging.event_flag);
+				wake_up_interruptible(&gwlan_logging.wait_queue);
+			}
+		}
 	}
 
 	pr_info("%s: Terminating\n", __func__);
@@ -817,6 +845,67 @@
 	return ret;
 }
 
+void wlan_init_log_completion(void)
+{
+	gwlan_logging.log_complete.indicator = WLAN_LOG_TYPE_NON_FATAL;
+	gwlan_logging.log_complete.is_fatal = WLAN_LOG_INDICATOR_UNUSED;
+	gwlan_logging.log_complete.is_report_in_progress = false;
+	gwlan_logging.log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
+
+	spin_lock_init(&gwlan_logging.bug_report_lock);
+}
+
+int wlan_set_log_completion(uint32 is_fatal,
+                            uint32 indicator,
+                            uint32 reason_code)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags);
+	gwlan_logging.log_complete.indicator = indicator;
+	gwlan_logging.log_complete.is_fatal = is_fatal;
+	gwlan_logging.log_complete.is_report_in_progress = true;
+	gwlan_logging.log_complete.reason_code = reason_code;
+	spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags);
+
+	return 0;
+}
+void wlan_get_log_completion(uint32 *is_fatal,
+                             uint32 *indicator,
+                             uint32 *reason_code)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags);
+	*indicator = gwlan_logging.log_complete.indicator;
+	*is_fatal = gwlan_logging.log_complete.is_fatal;
+	*reason_code = gwlan_logging.log_complete.reason_code;
+	gwlan_logging.log_complete.is_report_in_progress = false;
+
+	spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags);
+
+}
+bool wlan_is_log_report_in_progress(void)
+{
+	return gwlan_logging.log_complete.is_report_in_progress;
+}
+
+void wlan_reset_log_report_in_progress(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags);
+	gwlan_logging.log_complete.is_report_in_progress = false;
+	spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags);
+}
+
+
+void wlan_deinit_log_completion(void)
+{
+	return;
+}
+
+
 int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf)
 {
 	int i = 0;
@@ -856,6 +945,8 @@
 	gwlan_logging.exit = false;
 	clear_bit(HOST_LOG_POST_MASK, &gwlan_logging.event_flag);
 	clear_bit(LOGGER_MGMT_DATA_PKT_POST_MASK, &gwlan_logging.event_flag);
+	clear_bit(LOGGER_FW_LOG_PKT_POST_MASK, &gwlan_logging.event_flag);
+	clear_bit(LOGGER_FATAL_EVENT_POST_MASK, &gwlan_logging.event_flag);
 	init_completion(&gwlan_logging.shutdown_comp);
 	gwlan_logging.thread = kthread_create(wlan_logging_thread, NULL,
 					"wlan_logging_thread");
@@ -955,6 +1046,8 @@
 	gapp_pid = INVALID_PID;
 	gwlan_logging.pcur_node = NULL;
 
+	wlan_init_log_completion();
+
 	return 0;
 }
 
@@ -963,7 +1056,8 @@
 	gwlan_logging.pcur_node = NULL;
 	gapp_pid = INVALID_PID;
 
-       return 0;
+	wlan_deinit_log_completion();
+	return 0;
 }
 
 int wlan_queue_data_mgmt_pkt_for_app(vos_pkt_t *pPacket)
@@ -1121,4 +1215,15 @@
 	return status;
 }
 
+
+void wlan_process_done_indication(uint8 type, uint32 reason_code)
+{
+    if ((type == WLAN_QXDM_LOGGING) && (wlan_is_log_report_in_progress() == TRUE))
+    {
+        pr_info("%s: Setting LOGGER_FATAL_EVENT\n", __func__);
+        set_bit(LOGGER_FATAL_EVENT_POST_MASK, &gwlan_logging.event_flag);
+        wake_up_interruptible(&gwlan_logging.wait_queue);
+    }
+}
+
 #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */
diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h
index 6f6d4d7..100ac75 100644
--- a/CORE/VOSS/inc/vos_api.h
+++ b/CORE/VOSS/inc/vos_api.h
@@ -75,6 +75,80 @@
 #include <vos_timer.h>
 #include <vos_pack_align.h>
 
+
+/**
+ * enum log_event_type - Type of event initiating bug report
+ * @WLAN_LOG_TYPE_NON_FATAL: Non fatal event
+ * @WLAN_LOG_TYPE_FATAL: Fatal event
+ *
+ * Enum indicating the type of event that is initiating the bug report
+ */
+enum log_event_type {
+	WLAN_LOG_TYPE_NON_FATAL,
+	WLAN_LOG_TYPE_FATAL,
+};
+
+/**
+ * enum log_event_indicator - Module triggering bug report
+ * @WLAN_LOG_INDICATOR_UNUSED: Unused
+ * @WLAN_LOG_INDICATOR_FRAMEWORK: Framework triggers bug report
+ * @WLAN_LOG_INDICATOR_HOST_DRIVER: Host driver triggers bug report
+ * @WLAN_LOG_INDICATOR_FIRMWARE: FW initiates bug report
+ *
+ * Enum indicating the module that triggered the bug report
+ */
+enum log_event_indicator {
+	WLAN_LOG_INDICATOR_UNUSED,
+	WLAN_LOG_INDICATOR_FRAMEWORK,
+	WLAN_LOG_INDICATOR_HOST_DRIVER,
+	WLAN_LOG_INDICATOR_FIRMWARE,
+	WLAN_LOG_INDICATOR_IOCTL
+};
+
+/**
+ * enum log_event_host_reason_code - Reason code for bug report
+ * @WLAN_LOG_REASON_CODE_UNUSED: Unused
+ * @WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL: Command response status from FW
+ * is error
+ * @WLAN_LOG_REASON_ROAM_FAIL: Driver initiated roam has failed
+ * @WLAN_LOG_REASON_THREAD_STUCK: Monitor Health of host threads and report
+ * fatal event if some thread is stuck
+ * @WLAN_LOG_REASON_DATA_STALL: Unable to send/receive data due to low resource
+ * scenario for a prolonged period
+ * @WLAN_LOG_REASON_SME_COMMAND_STUCK: SME command is stuck in SME active queue
+ * @WLAN_LOG_REASON_ZERO_SCAN_RESULTS: Full scan resulted in zero scan results
+ * @WLAN_LOG_REASON_QUEUE_FULL: Defer queue becomes full for a prolonged period
+ * @WLAN_LOG_REASON_POWER_COLLAPSE_FAIL: Unable to allow apps power collapse
+ * for a prolonged period
+ * @WLAN_LOG_REASON_SSR_FAIL: Unable to gracefully complete SSR
+ * @WLAN_LOG_REASON_DISCONNECT_FAIL: Disconnect from Supplicant is not
+ * successful
+ * @WLAN_LOG_REASON_CLEAN_UP_FAIL: Clean up of  TDLS or Pre-Auth Sessions
+ * not successful
+ * @WLAN_LOG_REASON_MALLOC_FAIL: Memory allocation Fails
+ * @WLAN_LOG_REASON_VOS_MSG_UNDER_RUN: VOS Core runs out of message wrapper
+ * @WLAN_LOG_REASON_MSG_POST_FAIL: Unable to post msg
+ *
+ * This enum contains the different reason codes for bug report
+ */
+enum log_event_host_reason_code {
+	WLAN_LOG_REASON_CODE_UNUSED,
+	WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL,
+	WLAN_LOG_REASON_ROAM_FAIL,
+	WLAN_LOG_REASON_THREAD_STUCK,
+	WLAN_LOG_REASON_DATA_STALL,
+	WLAN_LOG_REASON_SME_COMMAND_STUCK,
+	WLAN_LOG_REASON_ZERO_SCAN_RESULTS,
+	WLAN_LOG_REASON_QUEUE_FULL,
+	WLAN_LOG_REASON_POWER_COLLAPSE_FAIL,
+	WLAN_LOG_REASON_SSR_FAIL,
+	WLAN_LOG_REASON_DISCONNECT_FAIL,
+	WLAN_LOG_REASON_CLEAN_UP_FAIL,
+	WLAN_LOG_REASON_MALLOC_FAIL,
+	WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
+	WLAN_LOG_REASON_MSG_POST_FAIL,
+};
+
 /*------------------------------------------------------------------------- 
   Function declarations and documenation
   ------------------------------------------------------------------------*/
@@ -178,6 +252,15 @@
 v_U8_t vos_is_reinit_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext);
 void vos_set_reinit_in_progress(VOS_MODULE_ID moduleId, v_U8_t value);
 VOS_STATUS vos_logger_pkt_serialize(vos_pkt_t *pPacket, uint32 pkt_type);
+bool vos_is_log_report_in_progress(void);
+void vos_reset_log_report_in_progress(void);
+int vos_set_log_completion(uint32 is_fatal, uint32 indicator, uint32 reason_code);
+void vos_get_log_completion(uint32 *is_fatal, uint32 *indicator, uint32 *reason_code);
+VOS_STATUS vos_fatal_event_logs_req( uint32_t is_fatal, uint32_t indicator,
+                                 uint32_t reason_code, bool waitRequired);
+VOS_STATUS vos_process_done_indication(v_U8_t type, v_U32_t reason_code);
+void vos_send_fatal_event_done(void);
+
 
 /**---------------------------------------------------------------------------
   
diff --git a/CORE/VOSS/inc/vos_trace.h b/CORE/VOSS/inc/vos_trace.h
index 5ed4944..a0c32f7 100644
--- a/CORE/VOSS/inc/vos_trace.h
+++ b/CORE/VOSS/inc/vos_trace.h
@@ -86,6 +86,17 @@
 	LOG_PKT_TYPE_FW_LOG    = 0x2
 };
 
+
+
+/* Log types. These types are defined in mailbox*/
+typedef enum
+{
+    WLAN_MGMT_FRAME_LOGS    = 0,
+    WLAN_QXDM_LOGGING       = 1,
+    WLAN_FW_MEMORY_DUMP     = 2
+}FrameLoggingType;
+
+
 /*-------------------------------------------------------------------------- 
   Preprocessor definitions and constants
   ------------------------------------------------------------------------*/
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index e5be663..21484db 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -284,6 +284,14 @@
     
       goto err_probe_event;
    }
+   if (vos_event_init( &(gpVosContext->fwLogsComplete) ) != VOS_STATUS_SUCCESS )
+   {
+      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+                  "%s: Unable to init fwLogsComplete", __func__);
+      VOS_ASSERT(0);
+
+      goto err_wda_complete_event;
+   }
 
    /* Initialize the free message queue */
    vStatus = vos_mq_init(&gpVosContext->freeVosMq);
@@ -294,7 +302,7 @@
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                 "%s: Failed to initialize VOS free message queue", __func__);
       VOS_ASSERT(0);
-      goto err_wda_complete_event;
+      goto err_fw_logs_complete_event;
    }
 
    for (iter = 0; iter < VOS_CORE_MAX_MESSAGES; iter++)
@@ -466,6 +474,9 @@
 err_msg_queue:
    vos_mq_deinit(&gpVosContext->freeVosMq);
 
+err_fw_logs_complete_event:
+    vos_event_destroy( &gpVosContext->fwLogsComplete);
+
 err_wda_complete_event:
    vos_event_destroy( &gpVosContext->wdaCompleteEvent );
 
@@ -1153,6 +1164,14 @@
 
   vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq);
 
+  vosStatus = vos_event_destroy(&gpVosContext->fwLogsComplete);
+  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
+  {
+     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+         "%s: failed to destroy fwLogsComplete", __func__);
+     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
+  }
+
   vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
@@ -1161,6 +1180,7 @@
      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
   }
 
+
   vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
@@ -1647,6 +1667,170 @@
 
 } /* vos_free_context() */
 
+
+bool vos_is_log_report_in_progress(void)
+{
+    return wlan_is_log_report_in_progress();
+}
+
+void vos_reset_log_report_in_progress(void)
+{
+    return wlan_reset_log_report_in_progress();
+}
+
+
+
+
+int vos_set_log_completion(uint32 is_fatal,
+                            uint32 indicator,
+                            uint32 reason_code)
+{
+    return wlan_set_log_completion(is_fatal,
+                                   indicator,reason_code);
+}
+
+void vos_get_log_completion(uint32 *is_fatal,
+                             uint32 *indicator,
+                             uint32 *reason_code)
+{
+    wlan_get_log_completion(is_fatal, indicator, reason_code);
+}
+
+
+
+void vos_send_fatal_event_done(void)
+{
+    /*Complete the fwLogsComplete Event*/
+    VosContextType *vos_context;
+    uint32_t is_fatal, indicator, reason_code;
+
+    vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+    if (!vos_context) {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+            "%s: vos context is Invalid", __func__);
+        return;
+    }
+    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+         "%s: vos_event_set for fwLogsComplete", __func__);
+    if (vos_event_set(&vos_context->fwLogsComplete)!= VOS_STATUS_SUCCESS)
+    {
+        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+         "%s: vos_event_set failed for fwLogsComplete", __func__);
+        return;
+    }
+    /*The below API will reset is_report_in_progress flag*/
+    vos_get_log_completion(&is_fatal, &indicator, &reason_code);
+    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+         "%s: is_fatal : %d, indicator: %d, reason_code=%d",
+         __func__, is_fatal, indicator, reason_code);
+}
+
+
+
+/**---------------------------------------------------------------------------
+
+  \brief vos_fatal_event_logs_req() - used to send flush command to FW
+
+  This API is wrapper to SME flush API.
+
+  \param is_fatal - fatal or non fatal event
+         indicator - Tyoe of indicator framework/Host/FW
+         reason_code - reason code for flush logs
+
+  \return VOS_STATUS_SUCCESS - if command is sent successfully.
+          VOS_STATUS_E_FAILURE - if command is not sent successfully.
+  --------------------------------------------------------------------------*/
+VOS_STATUS vos_fatal_event_logs_req( uint32_t is_fatal,
+                        uint32_t indicator,
+                        uint32_t reason_code,
+                        bool waitRequired)
+{
+    VOS_STATUS vosStatus;
+    eHalStatus status;
+    VosContextType *vos_context;
+
+    vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+    if (!vos_context)
+    {
+        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+            "%s: vos context is Invalid", __func__);
+        return eHAL_STATUS_FAILURE;
+    }
+
+
+    if (vos_is_log_report_in_progress() == true)
+    {
+        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+        "%s: Fatal Event Req already in progress - dropping! type:%d, indicator=%d reason_code=%d",
+        __func__, is_fatal, indicator, reason_code);
+        return VOS_STATUS_E_FAILURE;
+    }
+
+    vosStatus = vos_set_log_completion(is_fatal, indicator, reason_code);
+    if (VOS_STATUS_SUCCESS != vosStatus) {
+        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+        "%s: Failed to set log trigger params for fatalEvent", __func__);
+        return VOS_STATUS_E_FAILURE;
+    }
+    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+        "%s: Triggering fatal Event: type:%d, indicator=%d reason_code=%d",
+        __func__, is_fatal, indicator, reason_code);
+
+    vos_event_reset(&gpVosContext->fwLogsComplete);
+    status = sme_fatal_event_logs_req(vos_context->pMACContext,
+                                      is_fatal, indicator,
+                                      reason_code);
+
+    if (HAL_STATUS_SUCCESS(status) && (waitRequired == TRUE))
+    {
+
+        /* Need to update time out of complete */
+        vosStatus = vos_wait_single_event(&gpVosContext->fwLogsComplete,
+                                    WAIT_TIME_FW_LOGS);
+        if ( vosStatus != VOS_STATUS_SUCCESS )
+        {
+            if ( vosStatus == VOS_STATUS_E_TIMEOUT )
+            {
+                VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                 "%s: Timeout occurred before fwLogsComplete", __func__);
+            }
+            else
+            {
+                VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                     "%s: fwLogsComplete reporting other error", __func__);
+            }
+            /*Done indication is not received.So reset the bug report in progress*/
+            vos_reset_log_report_in_progress();
+            return VOS_STATUS_E_FAILURE;
+        }
+    }
+    if (HAL_STATUS_SUCCESS( status ))
+        return VOS_STATUS_SUCCESS;
+    else
+        return VOS_STATUS_E_FAILURE;
+}
+
+/**---------------------------------------------------------------------------
+
+  \brief vos_process_done_indication() - Process the done indication for fatal event,
+   FW memory dump
+
+  This API processes the done indication and wakeup the logger thread accordingly.
+
+  \param type - Type for which done indication is received.
+
+
+  \return VOS_STATUS_SUCCESS - the pkt has been successfully queued.
+          VOS_STATUS_E_FAILURE - the pkt queue handler has reported
+          a failure.
+  --------------------------------------------------------------------------*/
+
+VOS_STATUS vos_process_done_indication(v_U8_t type, v_U32_t reason_code)
+{
+    wlan_process_done_indication(type, reason_code);
+    return VOS_STATUS_SUCCESS;
+}
+
 /**---------------------------------------------------------------------------
 
   \brief vos_logger_pkt_serialize() - queue a logging vos pkt
@@ -2241,6 +2425,15 @@
 
   vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq);
 
+  vosStatus = vos_event_destroy(&gpVosContext->fwLogsComplete);
+  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
+  {
+     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+         "%s: failed to destroy fwLogsComplete", __func__);
+     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
+  }
+
+
   vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
diff --git a/CORE/VOSS/src/vos_sched.h b/CORE/VOSS/src/vos_sched.h
index 500f684..f9c3b65 100644
--- a/CORE/VOSS/src/vos_sched.h
+++ b/CORE/VOSS/src/vos_sched.h
@@ -336,6 +336,9 @@
 
    /* Roam delay statistic enabled in ini*/
    v_U8_t             roamDelayStatsEnabled;
+
+   /*Fw log complete Event*/
+   vos_event_t fwLogsComplete;
 } VosContextType, *pVosContextType;
 
 
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index cf9ae9d..80eeb34 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1283,6 +1283,9 @@
 #define WDA_MGMT_LOGGING_INIT_REQ               SIR_HAL_MGMT_LOGGING_INIT_REQ
 #define WDA_GET_FRAME_LOG_REQ                   SIR_HAL_GET_FRAME_LOG_REQ
 
+#define WDA_FATAL_EVENT_LOGS_REQ                   SIR_HAL_FATAL_EVENT_LOGS_REQ
+
+
 #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames
 
 #define halTxFrame(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc, pData, txFlag) \
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index 3fb3ad4..79cf4b4 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -9778,6 +9778,122 @@
    return status;
 }
 
+
+/*
+ * FUNCTION: WDA_FatalEventLogsRspCallback
+ * recieves Flush Logs response from FW
+ */
+
+void WDA_FatalEventLogsRspCallback(WDI_FatalEventLogsRspParamType* wdiRsp,
+                                        void* pUserData)
+{
+    tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+
+    VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                     "<------ %s,wdiStatus:%d  " ,
+                     __func__, wdiRsp->wdiStatus);
+    if(NULL == pWdaParams)
+    {
+       VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "%s: pWdaParams received NULL", __func__);
+       VOS_ASSERT(0);
+       return ;
+    }
+
+    if(NULL == pWdaParams->wdaMsgParam)
+    {
+       VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+       VOS_ASSERT(0);
+       vos_mem_free(pWdaParams);
+       return ;
+    }
+
+    if(IS_WDI_STATUS_FAILURE(wdiRsp->wdiStatus))
+    {
+        /*
+              * If it is failure, it means JOb is already posted by FW
+              * for logging, so for failure scenario also we will get the
+              * done indication
+              */
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "%s: Fatal Event Rsp Failure,wdiStatus : %d ",
+               __func__, wdiRsp->wdiStatus);
+    }
+
+    vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+    vos_mem_free(pWdaParams->wdaMsgParam);
+    vos_mem_free(pWdaParams);
+
+    return;
+
+}
+
+/*
+ * FUNCTION: WDA_ProcessFatalEventLogsReq
+ * Request to WDI to send the fatal Event Logs Req.
+ */
+
+VOS_STATUS WDA_ProcessFatalEventLogsReq(tWDA_CbContext *pWDA,
+                              tSirFatalEventLogsReqParam *pFatalEventLogsReqParam)
+{
+    VOS_STATUS status = VOS_STATUS_SUCCESS;
+    WDI_FatalEventLogsReqInfoType *wdiFatalEventLogsReqInfo;
+    tWDA_ReqParams *pWdaParams ;
+    WDI_Status wstatus;
+
+
+    VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                                          "------> %s " ,__func__);
+    if (NULL == pFatalEventLogsReqParam)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                           "%s: pMgmtLoggingInitParam received NULL", __func__);
+        VOS_ASSERT(0) ;
+        return VOS_STATUS_E_FAULT;
+    }
+    wdiFatalEventLogsReqInfo = (WDI_FatalEventLogsReqInfoType *)vos_mem_malloc(
+                                       sizeof(WDI_FatalEventLogsReqInfoType));
+    if(NULL == wdiFatalEventLogsReqInfo)
+    {
+       VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                            "%s: VOS MEM Alloc Failure", __func__);
+       VOS_ASSERT(0);
+       vos_mem_free(pFatalEventLogsReqParam);
+       return VOS_STATUS_E_NOMEM;
+    }
+    pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+    if(NULL == pWdaParams)
+    {
+       VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                            "%s: VOS MEM Alloc Failure", __func__);
+       VOS_ASSERT(0);
+       vos_mem_free(wdiFatalEventLogsReqInfo);
+       vos_mem_free(pFatalEventLogsReqParam);
+       return VOS_STATUS_E_NOMEM;
+    }
+    wdiFatalEventLogsReqInfo->reason_code = pFatalEventLogsReqParam->reason_code;
+    pWdaParams->pWdaContext = pWDA;
+    pWdaParams->wdaMsgParam = pFatalEventLogsReqParam;
+    pWdaParams->wdaWdiApiMsgParam = (void *)wdiFatalEventLogsReqInfo;
+
+   wstatus = WDI_FatalEventLogsReq(wdiFatalEventLogsReqInfo,
+                       (WDI_FatalEventLogsRspCb)WDA_FatalEventLogsRspCallback,
+                        pWdaParams);
+   if(IS_WDI_STATUS_FAILURE(wstatus))
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "Failure in Mgmt Logging init REQ WDI API, free all the memory" );
+      status = CONVERT_WDI2VOS_STATUS(wstatus);
+      vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ;
+      vos_mem_free(pWdaParams->wdaMsgParam);
+      vos_mem_free(pWdaParams);
+   }
+
+   return status;
+
+}
+
 /*
  * FUNCTION: WDA_ProcessFWLoggingInitReq
  *
@@ -13766,6 +13882,12 @@
                                         (tAniGetFrameLogReq *)pMsg->bodyptr);
          break;
       }
+      case WDA_FATAL_EVENT_LOGS_REQ:
+      {
+         WDA_ProcessFatalEventLogsReq(pWDA,
+                                       (tSirFatalEventLogsReqParam *)pMsg->bodyptr);
+         break;
+      }
       case WDA_SET_HOST_OFFLOAD:
       {
          WDA_ProcessHostOffloadReq(pWDA, (tSirHostOffloadReq *)pMsg->bodyptr);
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 0690f78..426013f 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -2692,6 +2692,17 @@
   wpt_uint32 reserved1;
   wpt_uint32 reserved2;
 }WDI_FWLoggingInitRspParamType;
+
+
+/*---------------------------------------------------------------------------
+  WDI_FatalEventLogsRspParamType
+---------------------------------------------------------------------------*/
+typedef struct
+{
+  /* wdi status */
+  wpt_uint32   wdiStatus;
+}WDI_FatalEventLogsRspParamType;
+
 /*---------------------------------------------------------------------------
   WDI_AddBAReqinfoType
 ---------------------------------------------------------------------------*/
@@ -4077,6 +4088,12 @@
 
 typedef struct
 {
+    wpt_uint32 reason_code;
+}WDI_FatalEventLogsReqInfoType;
+
+
+typedef struct
+{
    wpt_uint8 flags;
 }WDI_GetFrameLogReqInfoType;
 
@@ -8025,6 +8042,8 @@
                         WDI_FWLoggingInitRspParamType *wdiRsp, void *pUserData);
 typedef void  (*WDI_GetFrameLogRspCb)(
                         WDI_GetFrameLogRspParamType *wdiRsp, void *pUserData);
+typedef void  (*WDI_FatalEventLogsRspCb)(
+                         WDI_FatalEventLogsRspParamType *wdiRsp, void *pUserData);
 
 typedef void  (*WDI_MonStartRspCb)(void *pEventData,void *pUserData);
 typedef void  (*WDI_MonStopRspCb)(void *pUserData);
@@ -9456,6 +9475,39 @@
   WDI_SetUapsdAcParamsCb  wdiSetUapsdAcParamsCb,
   void*                   pUserData
 );
+
+
+/**
+ @brief WDI_FatalEventLogsReq will be called when the upper
+        MAC wants to send the fatal event req. Upon the call of
+        this API the WLAN DAL will pack and send a HAL
+        Fatal event request message to the lower RIVA sub-system.
+
+        In state BUSY this request will be queued. Request won't
+        be allowed in any other state.
+
+
+ @param pwdiFatalEventLogsReqInfo: the Fatal event logs params
+                      as specified by the Device Interface
+
+        wdiFatalEventLogsRspCb: callback for passing back the
+        response of the fatal event operation received
+        from the device
+
+        pUserData: user data will be passed back with the
+        callback
+
+ @return Result of the function call
+*/
+
+WDI_Status
+WDI_FatalEventLogsReq
+(
+   WDI_FatalEventLogsReqInfoType      *pwdiFatalEventLogsReqInfo,
+   WDI_FatalEventLogsRspCb             wdiFatalEventLogsRspCb,
+   void*                               pUserData
+);
+
 /**
  @brief WDI_GetFrameLogReq will be called when the upper
         MAC wants to initialize frame logging. Upon the call of
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index 8a8a3a6..04cc121 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -478,6 +478,7 @@
 
   WDI_MON_START_REQ                              = 107,
   WDI_MON_STOP_REQ                               = 108,
+  WDI_FATAL_EVENT_LOGGING_REQ                    = 109,
 
   WDI_MAX_REQ,
 
@@ -818,6 +819,7 @@
 
   WDI_MON_START_RSP                              = 107,
   WDI_MON_STOP_RSP                               = 108,
+  WDI_FATAL_EVENT_LOGGING_RSP                    = 109,
 
   /*-------------------------------------------------------------------------
     Indications
@@ -6145,6 +6147,21 @@
 );
 
 WDI_Status
+WDI_ProcessFatalEventLogsReq
+
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+
+WDI_Status
+WDI_ProcessFatalEventLogsRsp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+
+WDI_Status
 WDI_ProcessFWLoggingInitReq
 (
   WDI_ControlBlockType*  pWDICtx,
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 430257e..f1b3f9d 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -479,6 +479,7 @@
 
   WDI_ProcessMonStartReq,          /* WDI_MON_START_REQ */
   WDI_ProcessMonStopReq,           /* WDI_MON_STOP_REQ */
+  WDI_ProcessFatalEventLogsReq,     /*WDI_FATAL_EVENT_LOGGING_REQ*/
   /*-------------------------------------------------------------------------
     Indications
   -------------------------------------------------------------------------*/
@@ -750,6 +751,7 @@
 
     WDI_ProcessMonStartRsp,                    /* WDI_MON_START_RSP*/
     WDI_ProcessMonStopRsp,                    /* WDI_MON_STOP_RSP*/
+    WDI_ProcessFatalEventLogsRsp,              /*WDI_FATAL_EVENT_LOGGING_RSP*/
   /*---------------------------------------------------------------------
     Indications
   ---------------------------------------------------------------------*/
@@ -1177,6 +1179,7 @@
     CASE_RETURN_STRING( WDI_SET_RTS_CTS_HTVHT_IND );
     CASE_RETURN_STRING( WDI_MON_START_REQ );
     CASE_RETURN_STRING( WDI_MON_STOP_REQ );
+    CASE_RETURN_STRING( WDI_FATAL_EVENT_LOGGING_REQ );
     default:
         return "Unknown WDI MessageId";
   }
@@ -1312,6 +1315,7 @@
     CASE_RETURN_STRING( WDI_ENCRYPT_MSG_RSP);
     CASE_RETURN_STRING( WDI_FW_LOGGING_INIT_RSP);
     CASE_RETURN_STRING( WDI_GET_FRAME_LOG_RSP);
+    CASE_RETURN_STRING (WDI_FATAL_EVENT_LOGGING_RSP);
     default:
         return "Unknown WDI MessageId";
   }
@@ -4325,6 +4329,66 @@
 
    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
 }
+
+
+/**
+ @brief WDI_FatalEventLogsReq will be called when the upper
+        MAC wants to send the flush command. Upon the call of
+        this API the WLAN DAL will pack and send a HAL
+        Fatal Event Req message to the lower RIVA sub-system.
+
+        In state BUSY this request will be queued. Request won't
+        be allowed in any other state.
+
+
+ @param pwdiFlushLogsReqInfo: the Flush Logs params
+                      as specified by the Device Interface
+
+        wdiFlushLogsRspCb: callback for passing back the
+        response of the Flush Logs operation received
+        from the device
+
+        pUserData: user data will be passed back with the
+        callback
+
+ @return Result of the function call
+*/
+
+WDI_Status
+WDI_FatalEventLogsReq
+(
+   WDI_FatalEventLogsReqInfoType      *pwdiFatalEventLogsReqInfo,
+   WDI_FatalEventLogsRspCb             wdiFatalEventLogsRspCb,
+   void*                               pUserData
+)
+{
+    WDI_EventInfoType      wdiEventData;
+
+    /*------------------------------------------------------------------------
+      Sanity Check
+    ------------------------------------------------------------------------*/
+    if ( eWLAN_PAL_FALSE == gWDIInitialized )
+    {
+      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+                "WDI API call before module is initialized - Fail request");
+
+      return WDI_STATUS_E_NOT_ALLOWED;
+    }
+
+    /*------------------------------------------------------------------------
+      Fill in Event data and post to the Main FSM
+    ------------------------------------------------------------------------*/
+    wdiEventData.wdiRequest      = WDI_FATAL_EVENT_LOGGING_REQ;
+    wdiEventData.pEventData      = pwdiFatalEventLogsReqInfo;
+    wdiEventData.uEventDataSize  = sizeof(*pwdiFatalEventLogsReqInfo);
+    wdiEventData.pCBfnc          = wdiFatalEventLogsRspCb;
+    wdiEventData.pUserData       = pUserData;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+
+}
+
+
 /**
  @brief WDI_FWLoggingInitReq will be called when the upper
         MAC wants to initialize frame logging. Upon the call of
@@ -24203,6 +24267,9 @@
        return WLAN_HAL_DISABLE_MONITOR_MODE_REQ;
   case WDI_FW_LOGGING_DXE_DONE_IND:
        return WLAN_HAL_FW_LOGGING_DXE_DONE_IND;
+  case WDI_FATAL_EVENT_LOGGING_REQ:
+       return WLAN_HAL_FATAL_EVENT_LOGGING_REQ;
+
   default:
     return WLAN_HAL_MSG_MAX;
   }
@@ -24532,6 +24599,8 @@
        return WDI_MON_START_RSP;
   case WLAN_HAL_DISABLE_MONITOR_MODE_RSP:
        return WDI_MON_STOP_RSP;
+  case WLAN_HAL_FATAL_EVENT_LOGGING_RSP:
+       return WDI_FATAL_EVENT_LOGGING_RSP;
   default:
     return eDRIVER_TYPE_MAX;
   }
@@ -34551,6 +34620,139 @@
   return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
 }
 
+
+/**
+ @brief Process Fatal Event Logs Rsp function
+        (called when a response is being received over the bus from HAL)
+
+ @param  pWDICtx:         pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessFatalEventLogsRsp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+    tHalFatalEventLoggingRspParams           halRsp;
+    WDI_FatalEventLogsRspCb                 wdiFatalEventLogsRspCb;
+    WDI_FatalEventLogsRspParamType          wdiFatalEventLogsRsp;
+
+    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+                    "%s: %d Enter",__func__, __LINE__);
+
+    /*-------------------------------------------------------------------------
+      Sanity check
+    -------------------------------------------------------------------------*/
+    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
+        ( NULL == pEventData->pEventData))
+    {
+       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                   "%s: Invalid parameters", __func__);
+       WDI_ASSERT(0);
+       return WDI_STATUS_E_FAILURE;
+    }
+    wdiFatalEventLogsRspCb = (WDI_FatalEventLogsRspCb)pWDICtx->pfncRspCB;
+
+    /*-------------------------------------------------------------------------
+      Extract response and send it to UMAC
+    -------------------------------------------------------------------------*/
+    wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp));
+
+    wdiFatalEventLogsRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halRsp.status);
+
+    /*Notify UMAC*/
+    wdiFatalEventLogsRspCb( &wdiFatalEventLogsRsp,
+                                  pWDICtx->pRspCBUserData);
+
+    return WDI_STATUS_SUCCESS;
+}
+
+/**
+ @brief Process FatalEventLogs Request
+
+ @param  pWDICtx:         pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+
+WDI_Status
+WDI_ProcessFatalEventLogsReq
+
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+    WDI_FatalEventLogsReqInfoType*     wdiFatalEventLogsReq;
+    wpt_uint8*                         pSendBuffer  = NULL;
+    wpt_uint16                         usDataOffset = 0;
+    wpt_uint16                         usSendSize   = 0;
+    WDI_Status                         wdiStatus;
+    tHalFatalEventLoggingReqMsg        halFatalEventLoggingReq;
+    WDI_FatalEventLogsRspCb            wdiFatalEventLogsRspCb;
+
+
+    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+            "%s: %d Enter",__func__, __LINE__);
+
+    /*-------------------------------------------------------------------------
+      Sanity check
+      ------------------------------------------------------------------------*/
+    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
+            ( NULL == pEventData->pEventData))
+    {
+        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+    wdiFatalEventLogsReq =
+                     (WDI_FatalEventLogsReqInfoType *)pEventData->pEventData;
+
+    /*-----------------------------------------------------------------------
+      Get message buffer
+      -----------------------------------------------------------------------*/
+    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+                    WDI_FATAL_EVENT_LOGGING_REQ,
+                    sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams),
+                    &pSendBuffer, &usDataOffset, &usSendSize))||
+            (usSendSize < (usDataOffset +
+            sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams))))
+    {
+        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+                "Unable to get send buffer in Fatal Event Req");
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+    halFatalEventLoggingReq.tFatalEventLoggingReqParams.reasonCode =
+                                    wdiFatalEventLogsReq->reason_code;
+
+    wdiFatalEventLogsRspCb   = (WDI_FatalEventLogsRspCb)pEventData->pCBfnc;
+
+    wpalMemoryCopy( pSendBuffer+usDataOffset,
+                    &halFatalEventLoggingReq.tFatalEventLoggingReqParams,
+                    sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams));
+
+    /*-------------------------------------------------------------------------
+      Send Mgmt Logging Init Request to HAL
+      ------------------------------------------------------------------------*/
+    wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
+                             wdiFatalEventLogsRspCb, pEventData->pUserData,
+                             WDI_FATAL_EVENT_LOGGING_RSP);
+
+    return  wdiStatus;
+
+
+}
+
+
 /**
  @brief Process FWLoggingInit Request
 
diff --git a/riva/inc/wlan_hal_msg.h b/riva/inc/wlan_hal_msg.h
index 59992bc..f1c29bb 100644
--- a/riva/inc/wlan_hal_msg.h
+++ b/riva/inc/wlan_hal_msg.h
@@ -8529,6 +8529,35 @@
 }  tGetFrameLogRespMsg,  * tpGetFrameLogRespMsg;
 
 /*---------------------------------------------------------------------------
+ * WLAN_HAL_FATAL_EVENT_LOGGING_REQ
+ *-------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+    tANI_U32 reasonCode;
+}tHalFatalEventLoggingReqParams, *tpHalFatalEventLoggingReqParams;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    tHalMsgHeader header;
+    tHalFatalEventLoggingReqParams tFatalEventLoggingReqParams;
+}tHalFatalEventLoggingReqMsg, *tpHalFatalEventLoggingReqMsg;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_FATAL_EVENT_LOGGING_RSP
+ *-------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{   tANI_U32 status;
+}tHalFatalEventLoggingRspParams, *tpHalFatalEventLoggingRspParams;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    tHalMsgHeader header;
+    tHalFatalEventLoggingRspParams tFatalEventLoggingRspParams;
+}tHalFatalEventLoggingRspMsg, *tpHalFatalEventLoggingRspMsg;
+
+
+
+/*---------------------------------------------------------------------------
  *WLAN_HAL_FW_LOGGING_INIT_REQ
  *--------------------------------------------------------------------------*/
 typedef PACKED_PRE struct PACKED_POST