/*
 * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/*============================================================================
   FILE:         host_diag_log.c

   OVERVIEW:     This source file contains definitions for WLAN UTIL diag APIs

   DEPENDENCIES:
   ============================================================================*/

#include "cdf_types.h"
#include "i_host_diag_core_log.h"
#include "host_diag_core_event.h"
#include "wlan_nlink_common.h"
#include "cds_sched.h"
#include "wlan_ptt_sock_svc.h"
#include "wlan_nlink_srv.h"
#include "cds_api.h"

#define PTT_MSG_DIAG_CMDS_TYPE   (0x5050)

#define DIAG_TYPE_LOGS   (1)
#define DIAG_TYPE_EVENTS (2)

#define DIAG_SWAP16(A) ((((uint16_t)(A) & 0xff00) >> 8) | (((uint16_t)(A) & 0x00ff) << 8))

typedef struct event_report_s {
	uint32_t diag_type;
	uint16_t event_id;
	uint16_t length;
} event_report_t;

/**---------------------------------------------------------------------------

   \brief host_diag_log_set_code() -

   This function sets the logging code in the given log record.

   \param  - ptr - Pointer to the log header type.
              - code - log code.
   \return - None

   --------------------------------------------------------------------------*/

void host_diag_log_set_code(void *ptr, uint16_t code)
{
	if (ptr) {
		/* All log packets are required to start with 'log_header_type' */
		((log_hdr_type *) ptr)->code = code;
	}
}

/**---------------------------------------------------------------------------

   \brief host_diag_log_set_length() -

   This function sets the length field in the given log record.

   \param  - ptr - Pointer to the log header type.
              - length - log length.

   \return - None

   --------------------------------------------------------------------------*/

void host_diag_log_set_length(void *ptr, uint16_t length)
{
	if (ptr) {
		/* All log packets are required to start with 'log_header_type' */
		((log_hdr_type *) ptr)->len = (uint16_t) length;
	}
}

/**---------------------------------------------------------------------------

   \brief host_diag_log_submit() -

   This function sends the log data to the ptt socket app only if it is registered with the driver.

   \param  - ptr - Pointer to the log header type.

   \return - None

   --------------------------------------------------------------------------*/

void host_diag_log_submit(void *plog_hdr_ptr)
{
	log_hdr_type *pHdr = (log_hdr_type *) plog_hdr_ptr;
	tAniHdr *wmsg = NULL;
	uint8_t *pBuf;
	uint16_t data_len;
	uint16_t total_len;

	if (cds_is_load_unload_in_progress()) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
			  "%s: Unloading/Loading in Progress. Ignore!!!",
			  __func__);
		return;
	}

	if (nl_srv_is_initialized() != 0)
		return;

	if (cds_is_multicast_logging()) {
		data_len = pHdr->len;

		total_len = sizeof(tAniHdr) + sizeof(uint32_t) + data_len;

		pBuf = (uint8_t *) cdf_mem_malloc(total_len);

		if (!pBuf) {
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
				  "cdf_mem_malloc failed");
			return;
		}

		cdf_mem_zero((void *)pBuf, total_len);

		wmsg = (tAniHdr *) pBuf;
		wmsg->type = PTT_MSG_DIAG_CMDS_TYPE;
		wmsg->length = total_len;
		wmsg->length = DIAG_SWAP16(wmsg->length);
		pBuf += sizeof(tAniHdr);

		/*  Diag Type events or log */
		*(uint32_t *) pBuf = DIAG_TYPE_LOGS;
		pBuf += sizeof(uint32_t);

		memcpy(pBuf, pHdr, data_len);
		ptt_sock_send_msg_to_app (wmsg, 0, ANI_NL_MSG_PUMAC,
			INVALID_PID);
		cdf_mem_free((void *)wmsg);
	}
	return;
}

/**
 * host_diag_log_wlock() - This function is used to send wake lock diag events
 * @reason: Reason why the wakelock was taken or released
 * @wake_lock_name: Function in which the wakelock was taken or released
 * @timeout: Timeout value in case of timed wakelocks
 * @status: Status field indicating whether the wake lock was taken/released
 *
 * This function is used to send wake lock diag events to user space
 *
 * Return: None
 *
 */
void host_diag_log_wlock(uint32_t reason, const char *wake_lock_name,
		uint32_t timeout, uint32_t status)
{
	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
			struct host_event_wlan_wake_lock);

	if ((nl_srv_is_initialized() != 0) ||
	    (cds_is_wakelock_enabled() == false))
		return;

	wlan_diag_event.status = status;
	wlan_diag_event.reason = reason;
	wlan_diag_event.timeout = timeout;
	wlan_diag_event.name_len = strlen(wake_lock_name);
	strlcpy(&wlan_diag_event.name[0],
			wake_lock_name,
			wlan_diag_event.name_len+1);

	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_WAKE_LOCK);
}

/**---------------------------------------------------------------------------

   \brief host_diag_event_report_payload() -

   This function sends the event data to the ptt socket app only if it is
   registered with the driver.

   \param  - ptr - Pointer to the log header type.

   \return - None

   --------------------------------------------------------------------------*/

void host_diag_event_report_payload(uint16_t event_Id, uint16_t length,
				    void *pPayload)
{
	tAniHdr *wmsg = NULL;
	uint8_t *pBuf;
	event_report_t *pEvent_report;
	uint16_t total_len;

	if (cds_is_load_unload_in_progress()) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
			  "%s: Unloading/Loading in Progress. Ignore!!!",
			  __func__);
		return;
	}

	if (nl_srv_is_initialized() != 0)
		return;

	if (cds_is_multicast_logging()) {
		total_len = sizeof(tAniHdr) + sizeof(event_report_t) + length;

		pBuf = (uint8_t *) cdf_mem_malloc(total_len);

		if (!pBuf) {
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
				  "cdf_mem_malloc failed");
			return;
		}
		wmsg = (tAniHdr *) pBuf;
		wmsg->type = PTT_MSG_DIAG_CMDS_TYPE;
		wmsg->length = total_len;
		wmsg->length = DIAG_SWAP16(wmsg->length);
		pBuf += sizeof(tAniHdr);

		pEvent_report = (event_report_t *) pBuf;
		pEvent_report->diag_type = DIAG_TYPE_EVENTS;
		pEvent_report->event_id = event_Id;
		pEvent_report->length = length;

		pBuf += sizeof(event_report_t);

		memcpy(pBuf, pPayload, length);

		if (ptt_sock_send_msg_to_app
			    (wmsg, 0, ANI_NL_MSG_PUMAC, INVALID_PID) < 0) {
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
				  "Ptt Socket error sending message to the app!!");
			cdf_mem_free((void *)wmsg);
			return;
		}

		cdf_mem_free((void *)wmsg);
	}

	return;

}
