/*
 * Copyright (c) 2012-2016 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.
 */

#ifdef FEATURE_OEM_DATA_SUPPORT

/**
 *  DOC: wlan_hdd_oemdata.c
 *
 *  Support for generic OEM Data Request handling
 *
 */

#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/wireless.h>
#include <wlan_hdd_includes.h>
#include <net/arp.h>
#include "qwlan_version.h"
#include "cds_utils.h"
#include "wma.h"
#include "sme_api.h"

static struct hdd_context_s *p_hdd_ctx;

/**
 * populate_oem_data_cap() - populate oem capabilities
 * @adapter: device adapter
 * @data_cap: pointer to populate the capabilities
 *
 * Return: error code
 */
static int populate_oem_data_cap(hdd_adapter_t *adapter,
				 t_iw_oem_data_cap *data_cap)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	struct hdd_config *config;
	uint32_t num_chan;
	uint8_t *chan_list;
	hdd_context_t *hdd_ctx = adapter->pHddCtx;

	config = hdd_ctx->config;
	if (!config) {
		hdd_err("HDD configuration is null");
		return -EINVAL;
	}
	chan_list = cdf_mem_malloc(sizeof(uint8_t) * OEM_CAP_MAX_NUM_CHANNELS);
	if (NULL == chan_list) {
		hdd_err("Memory allocation failed");
		return -ENOMEM;
	}

	strlcpy(data_cap->oem_target_signature, OEM_TARGET_SIGNATURE,
		OEM_TARGET_SIGNATURE_LEN);
	data_cap->oem_target_type = hdd_ctx->target_type;
	data_cap->oem_fw_version = hdd_ctx->target_fw_version;
	data_cap->driver_version.major = QWLAN_VERSION_MAJOR;
	data_cap->driver_version.minor = QWLAN_VERSION_MINOR;
	data_cap->driver_version.patch = QWLAN_VERSION_PATCH;
	data_cap->driver_version.build = QWLAN_VERSION_BUILD;
	data_cap->allowed_dwell_time_min = config->nNeighborScanMinChanTime;
	data_cap->allowed_dwell_time_max = config->nNeighborScanMaxChanTime;
	data_cap->curr_dwell_time_min =
		sme_get_neighbor_scan_min_chan_time(hdd_ctx->hHal,
						    adapter->sessionId);
	data_cap->curr_dwell_time_max =
		sme_get_neighbor_scan_max_chan_time(hdd_ctx->hHal,
						    adapter->sessionId);
	data_cap->supported_bands = config->nBandCapability;

	/* request for max num of channels */
	num_chan = WNI_CFG_VALID_CHANNEL_LIST_LEN;
	status = sme_get_cfg_valid_channels(hdd_ctx->hHal,
					    &chan_list[0], &num_chan);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("failed to get valid channel list, status: %d", status);
		cdf_mem_free(chan_list);
		return -EINVAL;
	}

	/* make sure num channels is not more than chan list array */
	if (num_chan > OEM_CAP_MAX_NUM_CHANNELS) {
		hdd_err("Num of channels-%d > length-%d of chan_list",
			num_chan, OEM_CAP_MAX_NUM_CHANNELS);
		cdf_mem_free(chan_list);
		return -ENOMEM;
	}

	data_cap->num_channels = num_chan;
	cdf_mem_copy(data_cap->channel_list, chan_list,
		     sizeof(uint8_t) * num_chan);

	cdf_mem_free(chan_list);
	return 0;
}

/**
 * iw_get_oem_data_cap() - Get OEM Data Capabilities
 * @dev: net device upon which the request was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl data payload
 *
 * This function gets the capability information for OEM Data Request
 * and Response.
 *
 * Return: 0 for success, negative errno value on failure
 */
int iw_get_oem_data_cap(struct net_device *dev,
			struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	int status;
	t_iw_oem_data_cap oemDataCap = { {0} };
	t_iw_oem_data_cap *pHddOemDataCap;
	hdd_adapter_t *pAdapter = (netdev_priv(dev));
	hdd_context_t *pHddContext;
	int ret;

	ENTER();

	pHddContext = WLAN_HDD_GET_CTX(pAdapter);
	ret = wlan_hdd_validate_context(pHddContext);
	if (0 != ret)
		return ret;

	status = populate_oem_data_cap(pAdapter, &oemDataCap);
	if (!status)
		return status;

	pHddOemDataCap = (t_iw_oem_data_cap *) (extra);
	*pHddOemDataCap = oemDataCap;

	EXIT();
	return 0;
}

/**
 * send_oem_reg_rsp_nlink_msg() - send oem registration response
 *
 * This function sends oem message to registered application process
 *
 * Return:  none
 */
static void send_oem_reg_rsp_nlink_msg(void)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	tAniMsgHdr *aniHdr;
	uint8_t *buf;
	uint8_t *numInterfaces;
	uint8_t *deviceMode;
	uint8_t *vdevId;
	hdd_adapter_list_node_t *pAdapterNode = NULL;
	hdd_adapter_list_node_t *pNext = NULL;
	hdd_adapter_t *pAdapter = NULL;
	QDF_STATUS status = 0;

	/* OEM message is always to a specific process and cannot be a broadcast */
	if (p_hdd_ctx->oem_pid == 0) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: invalid dest pid", __func__);
		return;
	}

	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
	if (skb == NULL) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: alloc_skb failed", __func__);
		return;
	}

	nlh = (struct nlmsghdr *)skb->data;
	nlh->nlmsg_pid = 0;     /* from kernel */
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_seq = 0;
	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
	aniHdr = NLMSG_DATA(nlh);
	aniHdr->type = ANI_MSG_APP_REG_RSP;

	/* Fill message body:
	 *   First byte will be number of interfaces, followed by
	 *   two bytes for each interfaces
	 *     - one byte for device mode
	 *     - one byte for vdev id
	 */
	buf = (char *)((char *)aniHdr + sizeof(tAniMsgHdr));
	numInterfaces = buf++;
	*numInterfaces = 0;

	/* Iterate through each of the adapters and fill device mode and vdev id */
	status = hdd_get_front_adapter(p_hdd_ctx, &pAdapterNode);
	while ((QDF_STATUS_SUCCESS == status) && pAdapterNode) {
		pAdapter = pAdapterNode->pAdapter;
		if (pAdapter) {
			deviceMode = buf++;
			vdevId = buf++;
			*deviceMode = pAdapter->device_mode;
			*vdevId = pAdapter->sessionId;
			(*numInterfaces)++;
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
				  "%s: numInterfaces: %d, deviceMode: %d, vdevId: %d",
				  __func__, *numInterfaces, *deviceMode,
				  *vdevId);
		}
		status = hdd_get_next_adapter(p_hdd_ctx, pAdapterNode, &pNext);
		pAdapterNode = pNext;
	}

	aniHdr->length =
		sizeof(uint8_t) + (*numInterfaces) * 2 * sizeof(uint8_t);
	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));

	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));

	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
		  "%s: sending App Reg Response length (%d) to process pid (%d)",
		  __func__, aniHdr->length, p_hdd_ctx->oem_pid);

	(void)nl_srv_ucast(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);

	return;
}

/**
 * send_oem_err_rsp_nlink_msg() - send oem error response
 * @app_pid: PID of oem application process
 * @error_code: response error code
 *
 * This function sends error response to oem app
 *
 * Return: none
 */
static void send_oem_err_rsp_nlink_msg(int32_t app_pid, uint8_t error_code)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	tAniMsgHdr *aniHdr;
	uint8_t *buf;

	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
	if (skb == NULL) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: alloc_skb failed", __func__);
		return;
	}

	nlh = (struct nlmsghdr *)skb->data;
	nlh->nlmsg_pid = 0;     /* from kernel */
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_seq = 0;
	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
	aniHdr = NLMSG_DATA(nlh);
	aniHdr->type = ANI_MSG_OEM_ERROR;
	aniHdr->length = sizeof(uint8_t);
	nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + aniHdr->length);

	/* message body will contain one byte of error code */
	buf = (char *)((char *)aniHdr + sizeof(tAniMsgHdr));
	*buf = error_code;

	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + aniHdr->length));

	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
		  "%s: sending oem error response to process pid (%d)",
		  __func__, app_pid);

	(void)nl_srv_ucast(skb, app_pid, MSG_DONTWAIT);

	return;
}

/**
 * hdd_send_oem_data_rsp_msg() - send oem data response
 * @length: length of the OEM Data Response message
 * @oemDataRsp: the actual OEM Data Response message
 *
 * This function sends an OEM Data Response message to a registered
 * application process over the netlink socket.
 *
 * Return: 0 for success, non zero for failure
 */
void hdd_send_oem_data_rsp_msg(int length, uint8_t *oemDataRsp)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	tAniMsgHdr *aniHdr;
	uint8_t *oemData;

	/* OEM message is always to a specific process and cannot be a broadcast */
	if (p_hdd_ctx->oem_pid == 0) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: invalid dest pid", __func__);
		return;
	}

	if (length > OEM_DATA_RSP_SIZE) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: invalid length of Oem Data response", __func__);
		return;
	}

	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + OEM_DATA_RSP_SIZE),
			GFP_KERNEL);
	if (skb == NULL) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: alloc_skb failed", __func__);
		return;
	}

	nlh = (struct nlmsghdr *)skb->data;
	nlh->nlmsg_pid = 0;     /* from kernel */
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_seq = 0;
	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
	aniHdr = NLMSG_DATA(nlh);
	aniHdr->type = ANI_MSG_OEM_DATA_RSP;

	aniHdr->length = length;
	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));
	oemData = (uint8_t *) ((char *)aniHdr + sizeof(tAniMsgHdr));
	cdf_mem_copy(oemData, oemDataRsp, length);

	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));

	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
		  "%s: sending Oem Data Response of len (%d) to process pid (%d)",
		  __func__, length, p_hdd_ctx->oem_pid);

	(void)nl_srv_ucast(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);

	return;
}

/**
 * oem_process_data_req_msg() - process oem data request
 * @oemDataLen: Length to OEM Data buffer
 * @oemData: Pointer to OEM Data buffer
 *
 * This function sends oem message to SME
 *
 * Return: QDF_STATUS enumeration
 */
static QDF_STATUS oem_process_data_req_msg(int oemDataLen, char *oemData)
{
	hdd_adapter_t *pAdapter = NULL;
	tOemDataReqConfig oemDataReqConfig;
	uint32_t oemDataReqID = 0;
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	/* for now, STA interface only */
	pAdapter = hdd_get_adapter(p_hdd_ctx, WLAN_HDD_INFRA_STATION);
	if (!pAdapter) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: No adapter for STA mode", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	if (!oemData) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: oemData is null", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	cdf_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig));

	oemDataReqConfig.data = cdf_mem_malloc(oemDataLen);
	if (!oemDataReqConfig.data) {
		hddLog(LOGE, FL("malloc failed for data req buffer"));
		return QDF_STATUS_E_NOMEM;
	}

	oemDataReqConfig.data_len = oemDataLen;
	cdf_mem_copy(oemDataReqConfig.data, oemData, oemDataLen);

	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
		  "%s: calling sme_oem_data_req", __func__);

	status = sme_oem_data_req(p_hdd_ctx->hHal,
				  pAdapter->sessionId,
				  &oemDataReqConfig,
				  &oemDataReqID);

	cdf_mem_free(oemDataReqConfig.data);
	oemDataReqConfig.data = NULL;

	return status;
}

/**
 * oem_process_channel_info_req_msg() - process oem channel_info request
 * @numOfChannels: number of channels
 * @chanList: list of channel information
 *
 * This function responds with channel info to oem process
 *
 * Return: 0 for success, non zero for failure
 */
static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	tAniMsgHdr *aniHdr;
	tHddChannelInfo *pHddChanInfo;
	tHddChannelInfo hddChanInfo;
	uint8_t chanId;
	uint32_t reg_info_1;
	uint32_t reg_info_2;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	int i;
	uint8_t *buf;

	/* OEM message is always to a specific process and cannot be a broadcast */
	if (p_hdd_ctx->oem_pid == 0) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: invalid dest pid", __func__);
		return -EPERM;
	}

	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + sizeof(uint8_t) +
				    numOfChannels * sizeof(tHddChannelInfo)),
			GFP_KERNEL);
	if (skb == NULL) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: alloc_skb failed", __func__);
		return -ENOMEM;
	}

	nlh = (struct nlmsghdr *)skb->data;
	nlh->nlmsg_pid = 0;     /* from kernel */
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_seq = 0;
	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
	aniHdr = NLMSG_DATA(nlh);
	aniHdr->type = ANI_MSG_CHANNEL_INFO_RSP;

	aniHdr->length =
		sizeof(uint8_t) + numOfChannels * sizeof(tHddChannelInfo);
	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));

	/* First byte of message body will have num of channels */
	buf = (char *)((char *)aniHdr + sizeof(tAniMsgHdr));
	*buf++ = numOfChannels;

	/* Next follows channel info struct for each channel id.
	 * If chan id is wrong or SME returns failure for a channel
	 * then fill in 0 in channel info for that particular channel
	 */
	for (i = 0; i < numOfChannels; i++) {
		pHddChanInfo = (tHddChannelInfo *) ((char *)buf +
						    i *
						    sizeof(tHddChannelInfo));

		chanId = chanList[i];
		status = sme_get_reg_info(p_hdd_ctx->hHal, chanId,
					  &reg_info_1, &reg_info_2);
		if (QDF_STATUS_SUCCESS == status) {
			/* copy into hdd chan info struct */
			hddChanInfo.chan_id = chanId;
			hddChanInfo.reserved0 = 0;
			hddChanInfo.mhz = cds_chan_to_freq(chanId);
			hddChanInfo.band_center_freq1 = hddChanInfo.mhz;
			hddChanInfo.band_center_freq2 = 0;

			hddChanInfo.info = 0;
			if (CHANNEL_STATE_DFS ==
			    cds_get_channel_state(chanId))
				WMI_SET_CHANNEL_FLAG(&hddChanInfo,
						     WMI_CHAN_FLAG_DFS);
			hddChanInfo.reg_info_1 = reg_info_1;
			hddChanInfo.reg_info_2 = reg_info_2;
		} else {
			/* channel info is not returned, fill in zeros in channel
			 * info struct
			 */
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
				  "%s: sme_get_reg_info failed for chan (%d), return info 0",
				  __func__, chanId);
			hddChanInfo.chan_id = chanId;
			hddChanInfo.reserved0 = 0;
			hddChanInfo.mhz = 0;
			hddChanInfo.band_center_freq1 = 0;
			hddChanInfo.band_center_freq2 = 0;
			hddChanInfo.info = 0;
			hddChanInfo.reg_info_1 = 0;
			hddChanInfo.reg_info_2 = 0;
		}
		cdf_mem_copy(pHddChanInfo, &hddChanInfo,
			     sizeof(tHddChannelInfo));
	}

	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));

	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
		  "%s: sending channel info resp for num channels (%d) to pid (%d)",
		  __func__, numOfChannels, p_hdd_ctx->oem_pid);

	(void)nl_srv_ucast(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);

	return 0;
}

/**
 * oem_process_set_cap_req_msg() - process oem set capability request
 * @oem_cap_len: Length of OEM capability
 * @oem_cap: Pointer to OEM capability buffer
 * @app_pid: process ID, to which rsp message is to be sent
 *
 * This function sends oem message to SME
 *
 * Return: error code
 */
static int oem_process_set_cap_req_msg(int oem_cap_len,
				       char *oem_cap, int32_t app_pid)
{
	QDF_STATUS status;
	int error_code;
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	tAniMsgHdr *ani_hdr;
	uint8_t *buf;

	if (!oem_cap) {
		hdd_err("oem_cap is null");
		return -EINVAL;
	}

	status = sme_oem_update_capability(p_hdd_ctx->hHal,
					(struct sme_oem_capability *)oem_cap);
	if (!QDF_IS_STATUS_SUCCESS(status))
		hdd_err("error updating rm capability, status: %d", status);
	error_code = cdf_status_to_os_return(status);

	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
	if (skb == NULL) {
		hdd_err("alloc_skb failed");
		return -ENOMEM;
	}

	nlh = (struct nlmsghdr *)skb->data;
	nlh->nlmsg_pid = 0;     /* from kernel */
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_seq = 0;
	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
	ani_hdr = NLMSG_DATA(nlh);
	ani_hdr->type = ANI_MSG_SET_OEM_CAP_RSP;
	/* 64 bit alignment */
	ani_hdr->length = sizeof(error_code);
	nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + ani_hdr->length);

	/* message body will contain only status code */
	buf = (char *)((char *)ani_hdr + sizeof(tAniMsgHdr));
	cdf_mem_copy(buf, &error_code, ani_hdr->length);

	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + ani_hdr->length));

	hdd_info("sending oem response to process pid %d", app_pid);

	(void)nl_srv_ucast(skb, app_pid, MSG_DONTWAIT);

	return error_code;
}

/**
 * oem_process_get_cap_req_msg() - process oem get capability request
 *
 * This function process the get capability request from OEM and responds
 * with the capability.
 *
 * Return: error code
 */
static int oem_process_get_cap_req_msg(void)
{
	int error_code;
	struct oem_get_capability_rsp *cap_rsp;
	t_iw_oem_data_cap data_cap = { {0} };
	struct sme_oem_capability oem_cap;
	hdd_adapter_t *adapter;
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	tAniMsgHdr *ani_hdr;
	uint8_t *buf;

	/* for now, STA interface only */
	adapter = hdd_get_adapter(p_hdd_ctx, WLAN_HDD_INFRA_STATION);
	if (!adapter) {
		hdd_err("No adapter for STA mode");
		return -EINVAL;
	}

	error_code = populate_oem_data_cap(adapter, &data_cap);
	if (0 != error_code)
		return error_code;

	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + sizeof(*cap_rsp)),
			GFP_KERNEL);
	if (skb == NULL) {
		hdd_err("alloc_skb failed");
		return -ENOMEM;
	}

	nlh = (struct nlmsghdr *)skb->data;
	nlh->nlmsg_pid = 0;     /* from kernel */
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_seq = 0;
	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
	ani_hdr = NLMSG_DATA(nlh);
	ani_hdr->type = ANI_MSG_GET_OEM_CAP_RSP;

	ani_hdr->length = sizeof(*cap_rsp);
	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + ani_hdr->length));

	buf = (char *)((char *)ani_hdr + sizeof(tAniMsgHdr));
	cdf_mem_copy(buf, &data_cap, sizeof(data_cap));

	buf = (char *) buf +  sizeof(data_cap);
	cdf_mem_zero(&oem_cap, sizeof(oem_cap));
	sme_oem_get_capability(p_hdd_ctx->hHal, &oem_cap);
	cdf_mem_copy(buf, &oem_cap, sizeof(oem_cap));

	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + ani_hdr->length)));
	hdd_info("send rsp to oem-pid:%d for get_capability",
		p_hdd_ctx->oem_pid);

	(void)nl_srv_ucast(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);
	return 0;
}

/**
 * hdd_send_peer_status_ind_to_oem_app() -
 *	Function to send peer status to a registered application
 * @peerMac: MAC address of peer
 * @peerStatus: ePeerConnected or ePeerDisconnected
 * @peerTimingMeasCap: 0: RTT/RTT2, 1: RTT3. Default is 0
 * @sessionId: SME session id, i.e. vdev_id
 * @chan_info: operating channel information
 *
 * Return: none
 */
void hdd_send_peer_status_ind_to_oem_app(struct cdf_mac_addr *peerMac,
					 uint8_t peerStatus,
					 uint8_t peerTimingMeasCap,
					 uint8_t sessionId,
					 tSirSmeChanInfo *chan_info)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	tAniMsgHdr *aniHdr;
	tPeerStatusInfo *pPeerInfo;

	if (!p_hdd_ctx || !p_hdd_ctx->hHal) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: Either HDD Ctx is null or Hal Ctx is null",
			  __func__);
		return;
	}

	/* check if oem app has registered and pid is valid */
	if ((!p_hdd_ctx->oem_app_registered) || (p_hdd_ctx->oem_pid == 0)) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
			  "%s: OEM app is not registered(%d) or pid is invalid(%d)",
			  __func__, p_hdd_ctx->oem_app_registered,
			  p_hdd_ctx->oem_pid);
		return;
	}

	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) +
				    sizeof(tPeerStatusInfo)),
			GFP_KERNEL);
	if (skb == NULL) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: alloc_skb failed", __func__);
		return;
	}

	nlh = (struct nlmsghdr *)skb->data;
	nlh->nlmsg_pid = 0;     /* from kernel */
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_seq = 0;
	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
	aniHdr = NLMSG_DATA(nlh);
	aniHdr->type = ANI_MSG_PEER_STATUS_IND;

	aniHdr->length = sizeof(tPeerStatusInfo);
	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));

	pPeerInfo = (tPeerStatusInfo *) ((char *)aniHdr + sizeof(tAniMsgHdr));

	cdf_mem_copy(pPeerInfo->peer_mac_addr, peerMac->bytes,
		     sizeof(peerMac->bytes));
	pPeerInfo->peer_status = peerStatus;
	pPeerInfo->vdev_id = sessionId;
	pPeerInfo->peer_capability = peerTimingMeasCap;
	pPeerInfo->reserved0 = 0;

	if (chan_info) {
		pPeerInfo->peer_chan_info.chan_id = chan_info->chan_id;
		pPeerInfo->peer_chan_info.reserved0 = 0;
		pPeerInfo->peer_chan_info.mhz = chan_info->mhz;
		pPeerInfo->peer_chan_info.band_center_freq1 =
			chan_info->band_center_freq1;
		pPeerInfo->peer_chan_info.band_center_freq2 =
			chan_info->band_center_freq2;
		pPeerInfo->peer_chan_info.info = chan_info->info;
		pPeerInfo->peer_chan_info.reg_info_1 = chan_info->reg_info_1;
		pPeerInfo->peer_chan_info.reg_info_2 = chan_info->reg_info_2;
	} else {
		pPeerInfo->peer_chan_info.chan_id = 0;
		pPeerInfo->peer_chan_info.reserved0 = 0;
		pPeerInfo->peer_chan_info.mhz = 0;
		pPeerInfo->peer_chan_info.band_center_freq1 = 0;
		pPeerInfo->peer_chan_info.band_center_freq2 = 0;
		pPeerInfo->peer_chan_info.info = 0;
		pPeerInfo->peer_chan_info.reg_info_1 = 0;
		pPeerInfo->peer_chan_info.reg_info_2 = 0;
	}
	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));

	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
		  "%s: sending peer " MAC_ADDRESS_STR
		  " status(%d), peerTimingMeasCap(%d), vdevId(%d), chanId(%d)"
		  " to oem app pid(%d), center freq 1 (%d), center freq 2 (%d),"
		  " info (0x%x), frequency (%d),reg info 1 (0x%x),"
		  " reg info 2 (0x%x)", __func__,
		  MAC_ADDR_ARRAY(peerMac->bytes),
		  peerStatus, peerTimingMeasCap,
		  sessionId, pPeerInfo->peer_chan_info.chan_id,
		  p_hdd_ctx->oem_pid,
		  pPeerInfo->peer_chan_info.band_center_freq1,
		  pPeerInfo->peer_chan_info.band_center_freq2,
		  pPeerInfo->peer_chan_info.info,
		  pPeerInfo->peer_chan_info.mhz,
		  pPeerInfo->peer_chan_info.reg_info_1,
		  pPeerInfo->peer_chan_info.reg_info_2);

	(void)nl_srv_ucast(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);

	return;
}

/*
 * Callback function invoked by Netlink service for all netlink
 * messages (from user space) addressed to WLAN_NL_MSG_OEM
 */

/**
 * oem_msg_callback() - callback invoked by netlink service
 * @skb:    skb with netlink message
 *
 * This function gets invoked by netlink service when a message
 * is received from user space addressed to WLAN_NL_MSG_OEM
 *
 * Return: zero on success
 *         On error, error number will be returned.
 */
static int oem_msg_callback(struct sk_buff *skb)
{
	struct nlmsghdr *nlh;
	tAniMsgHdr *msg_hdr;
	int ret;
	char *sign_str = NULL;
	nlh = (struct nlmsghdr *)skb->data;

	if (!nlh) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: Netlink header null", __func__);
		return -EPERM;
	}

	ret = wlan_hdd_validate_context(p_hdd_ctx);
	if (0 != ret) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  FL("HDD context is not valid"));
		return ret;
	}

	msg_hdr = NLMSG_DATA(nlh);

	if (!msg_hdr) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: Message header null", __func__);
		send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
					   OEM_ERR_NULL_MESSAGE_HEADER);
		return -EPERM;
	}

	if (nlh->nlmsg_len <
	    NLMSG_LENGTH(sizeof(tAniMsgHdr) + msg_hdr->length)) {
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: Invalid nl msg len, nlh->nlmsg_len (%d), msg_hdr->len (%d)",
			  __func__, nlh->nlmsg_len, msg_hdr->length);
		send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
					   OEM_ERR_INVALID_MESSAGE_LENGTH);
		return -EPERM;
	}

	switch (msg_hdr->type) {
	case ANI_MSG_APP_REG_REQ:
		/* Registration request is only allowed for Qualcomm Application */
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
			  "%s: Received App Req Req from App process pid(%d), len(%d)",
			  __func__, nlh->nlmsg_pid, msg_hdr->length);

		sign_str = (char *)((char *)msg_hdr + sizeof(tAniMsgHdr));
		if ((OEM_APP_SIGNATURE_LEN == msg_hdr->length) &&
		    (0 == strncmp(sign_str, OEM_APP_SIGNATURE_STR,
				  OEM_APP_SIGNATURE_LEN))) {
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
				  "%s: Valid App Req Req from oem app process pid(%d)",
				  __func__, nlh->nlmsg_pid);

			p_hdd_ctx->oem_app_registered = true;
			p_hdd_ctx->oem_pid = nlh->nlmsg_pid;
			send_oem_reg_rsp_nlink_msg();
		} else {
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
				  "%s: Invalid signature in App Reg Request from pid(%d)",
				  __func__, nlh->nlmsg_pid);
			send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
						   OEM_ERR_INVALID_SIGNATURE);
			return -EPERM;
		}
		break;

	case ANI_MSG_OEM_DATA_REQ:
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
			  "%s: Received Oem Data Request length(%d) from pid: %d",
			  __func__, msg_hdr->length, nlh->nlmsg_pid);

		if ((!p_hdd_ctx->oem_app_registered) ||
		    (nlh->nlmsg_pid != p_hdd_ctx->oem_pid)) {
			/* either oem app is not registered yet or pid is different */
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
				  "%s: OEM DataReq: app not registered(%d) or incorrect pid(%d)",
				  __func__, p_hdd_ctx->oem_app_registered,
				  nlh->nlmsg_pid);
			send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
						   OEM_ERR_APP_NOT_REGISTERED);
			return -EPERM;
		}

		if ((!msg_hdr->length) || (OEM_DATA_REQ_SIZE < msg_hdr->length)) {
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
				  "%s: Invalid length (%d) in Oem Data Request",
				  __func__, msg_hdr->length);
			send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
						   OEM_ERR_INVALID_MESSAGE_LENGTH);
			return -EPERM;
		}
		oem_process_data_req_msg(msg_hdr->length,
					 (char *)((char *)msg_hdr +
						  sizeof(tAniMsgHdr)));
		break;

	case ANI_MSG_CHANNEL_INFO_REQ:
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
			  "%s: Received channel info request, num channel(%d) from pid: %d",
			  __func__, msg_hdr->length, nlh->nlmsg_pid);

		if ((!p_hdd_ctx->oem_app_registered) ||
		    (nlh->nlmsg_pid != p_hdd_ctx->oem_pid)) {
			/* either oem app is not registered yet or pid is different */
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
				  "%s: Chan InfoReq: app not registered(%d) or incorrect pid(%d)",
				  __func__, p_hdd_ctx->oem_app_registered,
				  nlh->nlmsg_pid);
			send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
						   OEM_ERR_APP_NOT_REGISTERED);
			return -EPERM;
		}

		/* message length contains list of channel ids */
		if ((!msg_hdr->length) ||
		    (WNI_CFG_VALID_CHANNEL_LIST_LEN < msg_hdr->length)) {
			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
				  "%s: Invalid length (%d) in channel info request",
				  __func__, msg_hdr->length);
			send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
						   OEM_ERR_INVALID_MESSAGE_LENGTH);
			return -EPERM;
		}
		oem_process_channel_info_req_msg(msg_hdr->length,
						 (char *)((char *)msg_hdr +
							  sizeof(tAniMsgHdr)));
		break;

	case ANI_MSG_SET_OEM_CAP_REQ:
		hdd_info("Received set oem capability req of length:%d from pid: %d",
			 msg_hdr->length, nlh->nlmsg_pid);

		if ((!p_hdd_ctx->oem_app_registered) ||
		    (nlh->nlmsg_pid != p_hdd_ctx->oem_pid)) {
			/* oem app is not registered yet or pid is different */
			hdd_err("set_oem_capability : app not registered(%d) or incorrect pid(%d)",
				p_hdd_ctx->oem_app_registered,
				nlh->nlmsg_pid);
			send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
						   OEM_ERR_APP_NOT_REGISTERED);
			return -EPERM;
		}

		if ((!msg_hdr->length) ||
			(sizeof(struct sme_oem_capability) < msg_hdr->length)) {
			hdd_err("Invalid length (%d) in set_oem_capability",
				msg_hdr->length);
			send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
						OEM_ERR_INVALID_MESSAGE_LENGTH);
			return -EPERM;
		}

		oem_process_set_cap_req_msg(msg_hdr->length,
					(char *)((char *)msg_hdr +
						sizeof(tAniMsgHdr)),
					nlh->nlmsg_pid);
		break;

	case ANI_MSG_GET_OEM_CAP_REQ:
		hdd_info("Rcvd get oem capability req of length:%d from pid: %d",
			 msg_hdr->length, nlh->nlmsg_pid);

		if ((!p_hdd_ctx->oem_app_registered) ||
		    (nlh->nlmsg_pid != p_hdd_ctx->oem_pid)) {
			/* oem app is not registered yet or pid is different */
			hdd_err("get_oem_capability : app not registered(%d) or incorrect pid(%d)",
				p_hdd_ctx->oem_app_registered,
				nlh->nlmsg_pid);
			send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
						   OEM_ERR_APP_NOT_REGISTERED);
			return -EPERM;
		}

		oem_process_get_cap_req_msg();
		break;

	default:
		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
			  "%s: Received Invalid message type (%d), length (%d)",
			  __func__, msg_hdr->type, msg_hdr->length);
		send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
					   OEM_ERR_INVALID_MESSAGE_TYPE);
		return -EPERM;
	}
	return 0;
}

static int __oem_msg_callback(struct sk_buff *skb)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = oem_msg_callback(skb);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * oem_activate_service() - Activate oem message handler
 * @hdd_ctx:   pointer to global HDD context
 *
 * This function registers a handler to receive netlink message from
 * an OEM application process.
 *
 * Return: zero on success
 *         On error, error number will be returned.
 */
int oem_activate_service(struct hdd_context_s *hdd_ctx)
{
	p_hdd_ctx = hdd_ctx;

	/* Register the msg handler for msgs addressed to WLAN_NL_MSG_OEM */
	return nl_srv_register(WLAN_NL_MSG_OEM, __oem_msg_callback);
}

#endif
