/**
 * wlan_logging_thread() - The WLAN Logger thread
 * @Arg - pointer to the HDD context
 *
 * This thread logs log message to App registered for the logs.
 */
static int wlan_logging_thread(void *Arg)
{
	int ret_wait_status = 0;
	int ret = 0;

	set_user_nice(current, -2);

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
	daemonize("wlan_logging_thread");
#endif

	while (!gwlan_logging.exit) {
		ret_wait_status = wait_event_interruptible(
		    gwlan_logging.wait_queue,
		    (gwlan_logging.wakeEvent || gwlan_logging.exit));

		gwlan_logging.wakeEvent = FALSE;

		if (ret_wait_status == -ERESTARTSYS) {
			pr_err("%s: wait_event_interruptible returned -ERESTARTSYS",
				__func__);
			break;
		}

		if (gwlan_logging.exit) {
		    pr_err("%s: Exiting the thread\n", __func__);
		    break;
		}

		if (INVALID_PID == gapp_pid) {
		    pr_err("%s: Invalid PID\n", __func__);
		    continue;
		}

		ret = send_filled_buffers_to_user();
		if (-ENOMEM == ret) {
		    msleep(200);
		}
	}

	pr_info("%s: Terminating\n", __func__);

	complete_and_exit(&gwlan_logging.shutdown_comp, 0);

	return 0;
}
/**
 * wlan_logging_thread() - The WLAN Logger thread
 * @Arg - pointer to the HDD context
 *
 * This thread logs log message to App registered for the logs.
 */
static int wlan_logging_thread(void *Arg)
{
	int ret_wait_status = 0;
	int ret = 0;

	set_user_nice(current, -2);

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
	daemonize("wlan_logging_thread");
#endif
	while (!gwlan_logging.exit) {
		ret_wait_status = wait_event_interruptible(
		  gwlan_logging.wait_queue,
		  (test_bit(HOST_LOG_POST, &gwlan_logging.event_flag) ||
		   gwlan_logging.exit ||
		   test_bit(LOGGER_MGMT_DATA_PKT_POST,
						&gwlan_logging.event_flag) ||
		   test_bit(LOGGER_FW_LOG_PKT_POST,
						&gwlan_logging.event_flag) ||
		   test_bit(LOGGER_FATAL_EVENT_POST,
						&gwlan_logging.event_flag)));

		if (ret_wait_status == -ERESTARTSYS) {
			pr_err("%s: wait_event return -ERESTARTSYS", __func__);
			break;
		}

		if (gwlan_logging.exit) {
		    break;
		}

		if (test_and_clear_bit(HOST_LOG_POST,
			&gwlan_logging.event_flag)) {
			ret = send_filled_buffers_to_user();
			if (-ENOMEM == ret) {
				msleep(200);
			}
		}

		if (test_and_clear_bit(LOGGER_FW_LOG_PKT_POST,
			&gwlan_logging.event_flag)) {
			send_fw_log_pkt_to_user();
		}

		if (test_and_clear_bit(LOGGER_MGMT_DATA_PKT_POST,
			&gwlan_logging.event_flag)) {
			send_data_mgmt_log_pkt_to_user();
		}

		if (test_and_clear_bit(LOGGER_FATAL_EVENT_POST,
			&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, &gwlan_logging.event_flag);
				set_bit(LOGGER_FW_LOG_PKT_POST,&gwlan_logging.event_flag);
				set_bit(LOGGER_FATAL_EVENT_POST, &gwlan_logging.event_flag);
				wake_up_interruptible(&gwlan_logging.wait_queue);
			}
		}
	}

	complete_and_exit(&gwlan_logging.shutdown_comp, 0);

	return 0;
}
/**
 * wlan_logging_thread() - The WLAN Logger thread
 * @Arg - pointer to the HDD context
 *
 * This thread logs log message to App registered for the logs.
 */
static int wlan_logging_thread(void *Arg)
{
	int ret_wait_status = 0;
	int ret = 0;

	set_user_nice(current, -2);

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
	daemonize("wlan_logging_thread");
#endif

	while (!gwlan_logging.exit) {
		ret_wait_status = wait_event_interruptible(
		    gwlan_logging.wait_queue,
		    (!list_empty(&gwlan_logging.filled_list)
		  || test_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag)
		  || test_bit(HOST_LOG_PER_PKT_STATS,
		     &gwlan_logging.eventFlag)
		  || test_bit(HOST_LOG_FW_FLUSH_COMPLETE,
		     &gwlan_logging.eventFlag)
		  || gwlan_logging.exit));

		if (ret_wait_status == -ERESTARTSYS) {
			pr_err("%s: wait_event_interruptible returned -ERESTARTSYS",
				__func__);
			break;
		}

		if (gwlan_logging.exit) {
			pr_err("%s: Exiting the thread\n", __func__);
			break;
		}

		if (test_and_clear_bit(HOST_LOG_DRIVER_MSG,
				       &gwlan_logging.eventFlag)) {
			ret = send_filled_buffers_to_user();
			if (-ENOMEM == ret) {
				msleep(200);
			}
		}

		if (test_and_clear_bit(HOST_LOG_PER_PKT_STATS,
				       &gwlan_logging.eventFlag)) {
			ret = pktlog_send_per_pkt_stats_to_user();
			if (-ENOMEM == ret) {
				msleep(200);
			}
		}

		if (test_and_clear_bit(HOST_LOG_FW_FLUSH_COMPLETE,
					&gwlan_logging.eventFlag)) {
			/* Flush bit could have been set while we were mid
			 * way in the logging thread. So, need to check other
			 * buffers like log messages, per packet stats again
			 * to flush any residual data in them
			 */
			if (gwlan_logging.is_flush_complete == true) {
				gwlan_logging.is_flush_complete = false;
				send_flush_completion_to_user();
			} else {
				gwlan_logging.is_flush_complete = true;
				set_bit(HOST_LOG_DRIVER_MSG,
						&gwlan_logging.eventFlag);
				set_bit(HOST_LOG_PER_PKT_STATS,
						&gwlan_logging.eventFlag);
				set_bit(HOST_LOG_FW_FLUSH_COMPLETE,
						&gwlan_logging.eventFlag);
				wake_up_interruptible(
					&gwlan_logging.wait_queue);
			}
		}
	}

	pr_info("%s: Terminating\n", __func__);

	complete_and_exit(&gwlan_logging.shutdown_comp, 0);

	return 0;
}