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

/**
 * DOC: wlan_hdd_ocb.c
 *
 * WLAN Host Device Driver 802.11p OCB implementation
 */

#include "cds_sched.h"
#include "wlan_hdd_assoc.h"
#include "wlan_hdd_main.h"
#include "wlan_hdd_ocb.h"
#include "wlan_hdd_trace.h"
#include "wlan_tgt_def_config.h"
#include "sch_api.h"
#include "wma_api.h"

/* Structure definitions for WLAN_SET_DOT11P_CHANNEL_SCHED */
#define AIFSN_MIN		(2)
#define AIFSN_MAX		(15)
#define CW_MIN			(1)
#define CW_MAX			(10)

/* Maximum time(ms) to wait for OCB operations */
#define WLAN_WAIT_TIME_OCB_CMD 1500
#define HDD_OCB_MAGIC 0x489a154f

/**
 * struct hdd_ocb_ctxt - Context for OCB operations
 * adapter: the ocb adapter
 * completion_evt: the completion event
 * status: status of the request
 */
struct hdd_ocb_ctxt {
	uint32_t magic;
	hdd_adapter_t *adapter;
	struct completion completion_evt;
	int status;
};

/**
 * hdd_set_dot11p_config() - Set 802.11p config flag
 * @hdd_ctx: HDD Context pointer
 *
 * TODO-OCB: This has been temporarily added to ensure this paramter
 * is set in CSR when we init the channel list. This should be removed
 * once the 5.9 GHz channels are added to the regulatory domain.
 */
void hdd_set_dot11p_config(hdd_context_t *hdd_ctx)
{
	sme_set_dot11p_config(hdd_ctx->hHal,
			      hdd_ctx->config->dot11p_mode !=
				WLAN_HDD_11P_DISABLED);
}

/**
 * dot11p_validate_qos_params() - Check if QoS parameters are valid
 * @qos_params:   Array of QoS parameters
 *
 * Return: 0 on success. error code on failure.
 */
static int dot11p_validate_qos_params(struct sir_qos_params qos_params[])
{
	int i;

	for (i = 0; i < MAX_NUM_AC; i++) {
		if ((!qos_params[i].aifsn) && (!qos_params[i].cwmin)
				&& (!qos_params[i].cwmax))
			continue;

		/* Validate AIFSN */
		if ((qos_params[i].aifsn < AIFSN_MIN)
				|| (qos_params[i].aifsn > AIFSN_MAX)) {
			hddLog(LOGE, FL("Invalid QoS parameter aifsn %d"),
				qos_params[i].aifsn);
			return -EINVAL;
		}

		/* Validate CWMin */
		if ((qos_params[i].cwmin < CW_MIN)
				|| (qos_params[i].cwmin > CW_MAX)) {
			hddLog(LOGE, FL("Invalid QoS parameter cwmin %d"),
				qos_params[i].cwmin);
			return -EINVAL;
		}

		/* Validate CWMax */
		if ((qos_params[i].cwmax < CW_MIN)
				|| (qos_params[i].cwmax > CW_MAX)) {
			hddLog(LOGE, FL("Invalid QoS parameter cwmax %d"),
				qos_params[i].cwmax);
			return -EINVAL;
		}
	}

	return 0;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) || \
				 defined(FEATURE_STATICALLY_ADD_11P_CHANNELS)
/*
 * If FEATURE_STATICALLY_ADD_11P_CHANNELS
 * is defined, IEEE80211_CHAN_NO_10MHZ,
 * and IEEE80211_CHAN_NO_20MHZ won't
 * be defined.
 */
#define IEEE80211_CHAN_NO_20MHZ	(1<<11)
#define IEEE80211_CHAN_NO_10MHZ	(1<<12)
#endif

#ifdef FEATURE_STATICALLY_ADD_11P_CHANNELS

#define DOT11P_TX_PWR_MAX	30
#define DOT11P_TX_ANTENNA_MAX	6
#define NUM_DOT11P_CHANNELS	10
/**
 * struct chan_info - information for the channel
 * @center_freq: center frequency
 * @max_bandwidth: maximum bandwidth of the channel in MHz
 */
struct chan_info {
	uint32_t center_freq;
	uint32_t max_bandwidth;
};

struct chan_info valid_dot11p_channels[NUM_DOT11P_CHANNELS] = {
	{5860, 10},
	{5870, 10},
	{5880, 10},
	{5890, 10},
	{5900, 10},
	{5910, 10},
	{5920, 10},
	{5875, 20},
	{5905, 20},
	{5852, 5}
};

/**
 * dot11p_validate_channel_static_channels() - validate a DSRC channel
 * @center_freq: the channel's center frequency
 * @bandwidth: the channel's bandwidth
 * @tx_power: transmit power
 * @reg_power: (output) the max tx power from the regulatory domain
 * @antenna_max: (output) the max antenna gain from the regulatory domain
 *
 * This function of the function checks the channel parameters against a
 * hardcoded list of valid channels based on the FCC rules.
 *
 * Return: 0 if the channel is valid, error code otherwise.
 */
static int dot11p_validate_channel_static_channels(struct wiphy *wiphy,
	uint32_t channel_freq, uint32_t bandwidth, uint32_t tx_power,
	uint8_t *reg_power, uint8_t *antenna_max)
{
	int i;

	for (i = 0; i < NUM_DOT11P_CHANNELS; i++) {
		if (channel_freq == valid_dot11p_channels[i].center_freq) {
			if (reg_power)
				*reg_power = DOT11P_TX_PWR_MAX;
			if (antenna_max)
				*antenna_max = DOT11P_TX_ANTENNA_MAX;

			if (bandwidth == 0)
				bandwidth =
					valid_dot11p_channels[i].max_bandwidth;
			else if (bandwidth >
				 valid_dot11p_channels[i].max_bandwidth)
				return -EINVAL;

			if (bandwidth != 5 && bandwidth != 10 &&
			    bandwidth != 20)
				return -EINVAL;
			if (tx_power > DOT11P_TX_PWR_MAX)
				return -EINVAL;

			return 0;
		}
	}

	return -EINVAL;
}
#else
/**
 * dot11p_validate_channel_static_channels() - validate a DSRC channel
 * @center_freq: the channel's center frequency
 * @bandwidth: the channel's bandwidth
 * @tx_power: transmit power
 * @reg_power: (output) the max tx power from the regulatory domain
 * @antenna_max: (output) the max antenna gain from the regulatory domain
 *
 * This function of the function checks the channel parameters against a
 * hardcoded list of valid channels based on the FCC rules.
 *
 * Return: 0 if the channel is valid, error code otherwise.
 */
static int dot11p_validate_channel_static_channels(struct wiphy *wiphy,
	uint32_t channel_freq, uint32_t bandwidth, uint32_t tx_power,
	uint8_t *reg_power, uint8_t *antenna_max)
{
	return -EINVAL;
}
#endif /* FEATURE_STATICALLY_ADD_11P_CHANNELS */

/**
 * dot11p_validate_channel() - validates a DSRC channel
 * @center_freq: the channel's center frequency
 * @bandwidth: the channel's bandwidth
 * @tx_power: transmit power
 * @reg_power: (output) the max tx power from the regulatory domain
 * @antenna_max: (output) the max antenna gain from the regulatory domain
 *
 * Return: 0 if the channel is valid, error code otherwise.
 */
static int dot11p_validate_channel(struct wiphy *wiphy,
				   uint32_t channel_freq, uint32_t bandwidth,
				   uint32_t tx_power, uint8_t *reg_power,
				   uint8_t *antenna_max)
{
	int band_idx, channel_idx;
	struct ieee80211_supported_band *current_band;
	struct ieee80211_channel *current_channel;

	for (band_idx = 0; band_idx < IEEE80211_NUM_BANDS; band_idx++) {
		current_band = wiphy->bands[band_idx];
		if (!current_band)
			continue;

		for (channel_idx = 0; channel_idx < current_band->n_channels;
		      channel_idx++) {
			current_channel = &current_band->channels[channel_idx];

			if (channel_freq == current_channel->center_freq) {
				if (current_channel->flags &
				    IEEE80211_CHAN_DISABLED)
					return -EINVAL;

				if (reg_power)
					*reg_power =
						current_channel->max_reg_power;
				if (antenna_max)
					*antenna_max =
						current_channel->
						max_antenna_gain;

				switch (bandwidth) {
				case 0:
					if (current_channel->flags &
					    IEEE80211_CHAN_NO_10MHZ)
						bandwidth = 5;
					else if (current_channel->flags &
						 IEEE80211_CHAN_NO_20MHZ)
						bandwidth = 10;
					else
						bandwidth = 20;
					break;
				case 5:
					break;
				case 10:
					if (current_channel->flags &
					    IEEE80211_CHAN_NO_10MHZ)
						return -EINVAL;
					break;
				case 20:
					if (current_channel->flags &
					    IEEE80211_CHAN_NO_20MHZ)
						return -EINVAL;
					break;
				default:
					return -EINVAL;
				}

				if (tx_power > current_channel->max_power)
					return -EINVAL;

				return 0;
			}
		}
	}

	return dot11p_validate_channel_static_channels(wiphy, channel_freq,
		bandwidth, tx_power, reg_power, antenna_max);
}

/**
 * hdd_ocb_validate_config() - Validates the config data
 * @config: configuration to be validated
 *
 * Return: 0 on success.
 */
static int hdd_ocb_validate_config(hdd_adapter_t *adapter,
				   struct sir_ocb_config *config)
{
	int i;
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	for (i = 0; i < config->channel_count; i++) {
		if (dot11p_validate_channel(hdd_ctx->wiphy,
					    config->channels[i].chan_freq,
					    config->channels[i].bandwidth,
					    config->channels[i].max_pwr,
					    &config->channels[i].reg_pwr,
					    &config->channels[i].antenna_max)) {
			hddLog(LOGE, FL("Invalid channel frequency %d"),
				config->channels[i].chan_freq);
			return -EINVAL;
		}
		if (dot11p_validate_qos_params(config->channels[i].qos_params))
			return -EINVAL;
	}

	return 0;
}

/**
 * hdd_ocb_register_sta() - Register station with Transport Layer
 * @adapter: Pointer to HDD Adapter
 *
 * This function should be invoked in the OCB Set Schedule callback
 * to enable the data path in the TL by calling RegisterSTAClient
 *
 * Return: 0 on success. -1 on failure.
 */
static int hdd_ocb_register_sta(hdd_adapter_t *adapter)
{
	CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
	struct ol_txrx_desc_type sta_desc = {0};
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	uint8_t peer_id;

	cdf_status = ol_txrx_register_ocb_peer(hdd_ctx->pcds_context,
					       adapter->macAddressCurrent.bytes,
					       &peer_id);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		hddLog(LOGE, FL("Error registering OCB Self Peer!"));
		return -EINVAL;
	}

	hdd_ctx->sta_to_adapter[peer_id] = adapter;

	sta_desc.sta_id = peer_id;
	sta_desc.is_qos_enabled = 1;

	cdf_status = ol_txrx_register_peer(hdd_rx_packet_cbk,
						&sta_desc);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		hddLog(LOGE, FL("Failed to register. Status= %d [0x%08X]"),
		       cdf_status, cdf_status);
		return -EINVAL;
	}

	if (pHddStaCtx->conn_info.staId[0] != 0 &&
	     pHddStaCtx->conn_info.staId[0] != peer_id) {
		hddLog(LOGE, FL("The ID for the OCB station has changed."));
	}

	pHddStaCtx->conn_info.staId[0] = peer_id;
	cdf_copy_macaddr(&pHddStaCtx->conn_info.peerMacAddress[0],
			 &adapter->macAddressCurrent);

	return 0;
}

/**
 * hdd_ocb_config_new() - Creates a new OCB configuration
 * @num_channels: the number of channels
 * @num_schedule: the schedule size
 * @ndl_chan_list_len: length in bytes of the NDL chan blob
 * @ndl_active_state_list_len: length in bytes of the active state blob
 *
 * Return: A pointer to the OCB configuration struct, NULL on failure.
 */
static struct sir_ocb_config *hdd_ocb_config_new(int num_channels,
						 int num_schedule,
						 int ndl_chan_list_len,
						 int ndl_active_state_list_len)
{
	struct sir_ocb_config *ret = 0;
	uint32_t len;
	void *cursor;

	if (num_channels > CFG_TGT_NUM_OCB_CHANNELS ||
			num_schedule > CFG_TGT_NUM_OCB_SCHEDULES)
		return NULL;

	len = sizeof(*ret) +
		num_channels * sizeof(struct sir_ocb_config_channel) +
		num_schedule * sizeof(struct sir_ocb_config_sched) +
		ndl_chan_list_len +
		ndl_active_state_list_len;

	cursor = cdf_mem_malloc(len);
	if (!cursor)
		goto fail;

	cdf_mem_zero(cursor, len);
	ret = cursor;
	cursor += sizeof(*ret);

	ret->channel_count = num_channels;
	ret->channels = cursor;
	cursor += num_channels * sizeof(*ret->channels);

	ret->schedule_size = num_schedule;
	ret->schedule = cursor;
	cursor += num_schedule * sizeof(*ret->schedule);

	ret->dcc_ndl_chan_list = cursor;
	cursor += ndl_chan_list_len;

	ret->dcc_ndl_active_state_list = cursor;
	cursor += ndl_active_state_list_len;

	return ret;

fail:
	cdf_mem_free(ret);
	return NULL;
}

/**
 * hdd_ocb_set_config_callback() - OCB set config callback function
 * @context_ptr: OCB call context
 * @response_ptr: Pointer to response structure
 *
 * This function is registered as a callback with the lower layers
 * and is used to respond with the status of a OCB set config command.
 */
static void hdd_ocb_set_config_callback(void *context_ptr, void *response_ptr)
{
	struct hdd_ocb_ctxt *context = context_ptr;
	struct sir_ocb_set_config_response *resp = response_ptr;

	if (!context)
		return;

	if (resp && resp->status)
		hddLog(LOGE, FL("Operation failed: %d"), resp->status);

	spin_lock(&hdd_context_lock);
	if (context->magic == HDD_OCB_MAGIC) {
		hdd_adapter_t *adapter = context->adapter;
		if (!resp) {
			context->status = -EINVAL;
			complete(&context->completion_evt);
			spin_unlock(&hdd_context_lock);
			return;
		}

		context->adapter->ocb_set_config_resp = *resp;
		spin_unlock(&hdd_context_lock);
		if (!resp->status) {
			/*
			 * OCB set config command successful.
			 * Open the TX data path
			 */
			if (!hdd_ocb_register_sta(adapter)) {
				netif_carrier_on(adapter->dev);
				netif_tx_start_all_queues(
				    adapter->dev);
			}
		}

		spin_lock(&hdd_context_lock);
		if (context->magic == HDD_OCB_MAGIC)
			complete(&context->completion_evt);
		spin_unlock(&hdd_context_lock);
	} else {
		spin_unlock(&hdd_context_lock);
	}
}

/**
 * hdd_ocb_set_config_req() - Send an OCB set config request
 * @adapter: a pointer to the adapter
 * @config: a pointer to the OCB configuration
 *
 * Return: 0 on success.
 */
static int hdd_ocb_set_config_req(hdd_adapter_t *adapter,
				  struct sir_ocb_config *config)
{
	int rc;
	CDF_STATUS cdf_status;
	struct hdd_ocb_ctxt context = {0};

	if (hdd_ocb_validate_config(adapter, config)) {
		hddLog(LOGE, FL("The configuration is invalid"));
		return -EINVAL;
	}

	init_completion(&context.completion_evt);
	context.adapter = adapter;
	context.magic = HDD_OCB_MAGIC;

	hddLog(LOG1, FL("Disabling queues"));
	netif_tx_disable(adapter->dev);
	netif_carrier_off(adapter->dev);

	/* Call the SME API to set the config */
	cdf_status = sme_ocb_set_config(
		((hdd_context_t *)adapter->pHddCtx)->hHal, &context,
		hdd_ocb_set_config_callback, config);
	if (cdf_status != CDF_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error calling SME function."));
		/* Convert from ecdf_status to errno */
		return -EINVAL;
	}

	/* Wait for the function to complete. */
	rc = wait_for_completion_timeout(&context.completion_evt,
		msecs_to_jiffies(WLAN_WAIT_TIME_OCB_CMD));
	if (rc == 0) {
		rc = -ETIMEDOUT;
		goto end;
	}
	rc = 0;

	if (context.status) {
		rc = context.status;
		goto end;
	}

	if (adapter->ocb_set_config_resp.status) {
		rc = -EINVAL;
		goto end;
	}

	/* fall through */
end:
	spin_lock(&hdd_context_lock);
	context.magic = 0;
	spin_unlock(&hdd_context_lock);
	if (rc)
		hddLog(LOGE, FL("Operation failed: %d"), rc);
	return rc;
}

/**
 * __iw_set_dot11p_channel_sched() - Handler for WLAN_SET_DOT11P_CHANNEL_SCHED
 *				     ioctl
 * @dev: Pointer to net_device structure
 * @iw_request_info: IW Request Info
 * @wrqu: IW Request Userspace Data Pointer
 * @extra: IW Request Kernel Data Pointer
 *
 * Return: 0 on success
 */
static int __iw_set_dot11p_channel_sched(struct net_device *dev,
					 struct iw_request_info *info,
					 union iwreq_data *wrqu, char *extra)
{
	int rc = 0;
	struct dot11p_channel_sched *sched;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct sir_ocb_config *config = NULL;
	uint8_t *mac_addr;
	int i, j;
	struct sir_ocb_config_channel *curr_chan;

	if (wlan_hdd_validate_context(WLAN_HDD_GET_CTX(adapter))) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return -EINVAL;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		return -EINVAL;
	}

	sched = (struct dot11p_channel_sched *)extra;

	/* Scheduled slots same as num channels for compatibility */
	config = hdd_ocb_config_new(sched->num_channels, sched->num_channels,
				    0, 0);
	if (config == NULL) {
		hddLog(LOGE, FL("Failed to allocate memory!"));
		return -ENOMEM;
	}

	/* Identify the vdev interface */
	config->session_id = adapter->sessionId;

	/* Release all the mac addresses used for OCB */
	for (i = 0; i < adapter->ocb_mac_addr_count; i++) {
		wlan_hdd_release_intf_addr(adapter->pHddCtx,
					   adapter->ocb_mac_address[i]);
	}
	adapter->ocb_mac_addr_count = 0;

	config->channel_count = 0;
	for (i = 0; i < sched->num_channels; i++) {
		if (0 == sched->channels[i].channel_freq)
			continue;

		curr_chan = &(config->channels[config->channel_count]);

		curr_chan->chan_freq = sched->channels[i].channel_freq;
		/*
		 * tx_power is divided by 2 because ocb_channel.tx_power is
		 * in half dB increments and sir_ocb_config_channel.max_pwr
		 * is in 1 dB increments.
		 */
		curr_chan->max_pwr = sched->channels[i].tx_power / 2;
		curr_chan->bandwidth = sched->channels[i].channel_bandwidth;
		/* assume 10 as default if not provided */
		if (curr_chan->bandwidth == 0)
			curr_chan->bandwidth = 10;

		/*
		 * Setup locally administered mac addresses for each channel.
		 * First channel uses the adapter's address.
		 */
		if (i == 0) {
			cdf_mem_copy(curr_chan->mac_address,
				     adapter->macAddressCurrent.bytes,
				     sizeof(tSirMacAddr));
		} else {
			mac_addr = wlan_hdd_get_intf_addr(adapter->pHddCtx);
			if (mac_addr == NULL) {
				hddLog(LOGE, FL("Cannot obtain mac address"));
				rc = -EINVAL;
				goto fail;
			}
			cdf_mem_copy(config->channels[
				     config->channel_count].mac_address,
				     mac_addr, sizeof(tSirMacAddr));
			/* Save the mac address to release later */
			cdf_mem_copy(adapter->ocb_mac_address[
				     adapter->ocb_mac_addr_count],
				     mac_addr,
				     sizeof(adapter->ocb_mac_address[
				     adapter->ocb_mac_addr_count]));
			adapter->ocb_mac_addr_count++;
		}

		for (j = 0; j < MAX_NUM_AC; j++) {
			curr_chan->qos_params[j].aifsn =
				sched->channels[i].qos_params[j].aifsn;
			curr_chan->qos_params[j].cwmin =
				sched->channels[i].qos_params[j].cwmin;
			curr_chan->qos_params[j].cwmax =
				sched->channels[i].qos_params[j].cwmax;
		}

		config->channel_count++;
	}

	/*
	 * Scheduled slots same as num channels for compatibility with
	 * legacy use.
	 */
	for (i = 0; i < sched->num_channels; i++) {
		config->schedule[i].chan_freq = sched->channels[i].channel_freq;
		config->schedule[i].guard_interval =
			sched->channels[i].start_guard_interval;
		config->schedule[i].total_duration =
			sched->channels[i].duration;
	}

	rc = hdd_ocb_set_config_req(adapter, config);
	if (rc) {
		hddLog(LOGE, FL("Error while setting OCB config"));
		goto fail;
	}

	rc = 0;

fail:
	cdf_mem_free(config);
	return rc;
}

/**
 * iw_set_dot11p_channel_sched() - IOCTL interface for setting channel schedule
 * @dev: Pointer to net_device structure
 * @iw_request_info: IW Request Info
 * @wrqu: IW Request Userspace Data Pointer
 * @extra: IW Request Kernel Data Pointer
 *
 * Return: 0 on success.
 */
int iw_set_dot11p_channel_sched(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __iw_set_dot11p_channel_sched(dev, info, wrqu, extra);
	cds_ssr_unprotect(__func__);

	return ret;
}

static const struct nla_policy qca_wlan_vendor_ocb_set_config_policy[
		QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY] = {
		.type = NLA_BINARY
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY] = {
		.type = NLA_BINARY
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY] = {
		.type = NLA_BINARY
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY] = {
		.type = NLA_BINARY
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS] = {
		.type = NLA_U32
	},
};

static const struct nla_policy qca_wlan_vendor_ocb_set_utc_time_policy[
		QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE] = {
		.type = NLA_BINARY, .len = SIZE_UTC_TIME
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR] = {
		.type = NLA_BINARY, .len = SIZE_UTC_TIME_ERROR
	},
};

static const struct nla_policy qca_wlan_vendor_ocb_start_timing_advert_policy[
		QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE] = {
		.type = NLA_U32
	},
};

static const struct nla_policy  qca_wlan_vendor_ocb_stop_timing_advert_policy[
		QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ] = {
		.type = NLA_U32
	},
};

static const struct nla_policy qca_wlan_vendor_ocb_get_tsf_timer_resp[] = {
	[QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW] = {
		.type = NLA_U32
	},
};

static const struct nla_policy qca_wlan_vendor_dcc_get_stats[] = {
	[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_CHANNEL_COUNT] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY] = {
		.type = NLA_BINARY
	},
};

static const struct nla_policy qca_wlan_vendor_dcc_get_stats_resp[] = {
	[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY] = {
		.type = NLA_BINARY
	},
};

static const struct nla_policy qca_wlan_vendor_dcc_clear_stats[] = {
	[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP] = {
		.type = NLA_U32
	},
};

static const struct nla_policy qca_wlan_vendor_dcc_update_ndl[
		QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_COUNT] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY] = {
		.type = NLA_BINARY
	},
	[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY] = {
		.type = NLA_BINARY
	},
};

/**
 * struct wlan_hdd_ocb_config_channel
 * @chan_freq: frequency of the channel
 * @bandwidth: bandwidth of the channel, either 10 or 20 MHz
 * @mac_address: MAC address assigned to this channel
 * @qos_params: QoS parameters
 * @max_pwr: maximum transmit power of the channel (1/2 dBm)
 * @min_pwr: minimum transmit power of the channel (1/2 dBm)
 */
struct wlan_hdd_ocb_config_channel {
	uint32_t chan_freq;
	uint32_t bandwidth;
	uint16_t flags;
	uint8_t reserved[4];
	struct sir_qos_params qos_params[MAX_NUM_AC];
	uint32_t max_pwr;
	uint32_t min_pwr;
};

static void wlan_hdd_ocb_config_channel_to_sir_ocb_config_channel(
	struct sir_ocb_config_channel *dest,
	struct wlan_hdd_ocb_config_channel *src,
	uint32_t channel_count)
{
	uint32_t i;

	cdf_mem_zero(dest, channel_count * sizeof(*dest));

	for (i = 0; i < channel_count; i++) {
		dest[i].chan_freq = src[i].chan_freq;
		dest[i].bandwidth = src[i].bandwidth;
		cdf_mem_copy(dest[i].qos_params, src[i].qos_params,
			     sizeof(dest[i].qos_params));
		/*
		 *  max_pwr and min_pwr are divided by 2 because
		 *  wlan_hdd_ocb_config_channel.max_pwr and min_pwr
		 *  are in 1/2 dB increments and
		 *  sir_ocb_config_channel.max_pwr and min_pwr are in
		 *  1 dB increments.
		 */
		dest[i].max_pwr = src[i].max_pwr / 2;
		dest[i].min_pwr = (src[i].min_pwr + 1) / 2;
		dest[i].flags = src[i].flags;
	}
}

/**
 * __wlan_hdd_cfg80211_ocb_set_config() - Interface for set config command
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
					      struct wireless_dev *wdev,
					      const void *data,
					      int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX + 1];
	struct nlattr *channel_array;
	struct nlattr *sched_array;
	struct nlattr *ndl_chan_list;
	uint32_t ndl_chan_list_len;
	struct nlattr *ndl_active_state_list;
	uint32_t ndl_active_state_list_len;
	uint32_t flags = 0;
	int i;
	int channel_count, schedule_size;
	struct sir_ocb_config *config;
	int rc = -EINVAL;
	uint8_t *mac_addr;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return -EINVAL;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		return -EINVAL;
	}

	/* Parse the netlink message */
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX,
			data,
			data_len, qca_wlan_vendor_ocb_set_config_policy)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		return -EINVAL;
	}

	/* Get the number of channels in the schedule */
	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT]) {
		hddLog(LOGE, FL("CHANNEL_COUNT is not present"));
		return -EINVAL;
	}
	channel_count = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT]);

	/* Get the size of the channel schedule */
	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE]) {
		hddLog(LOGE, FL("SCHEDULE_SIZE is not present"));
		return -EINVAL;
	}
	schedule_size = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE]);

	/* Get the ndl chan array and the ndl active state array. */
	ndl_chan_list =
		tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY];
	ndl_chan_list_len = (ndl_chan_list ? nla_len(ndl_chan_list) : 0);

	ndl_active_state_list =
		tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY];
	ndl_active_state_list_len = (ndl_active_state_list ?
				    nla_len(ndl_active_state_list) : 0);

	/* Get the flags */
	if (tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS])
		flags = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS]);

	config = hdd_ocb_config_new(channel_count, schedule_size,
				    ndl_chan_list_len,
				    ndl_active_state_list_len);
	if (config == NULL) {
		hddLog(LOGE, FL("Failed to allocate memory!"));
		return -ENOMEM;
	}

	config->channel_count = channel_count;
	config->schedule_size = schedule_size;
	config->flags = flags;

	/* Read the channel array */
	channel_array = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY];
	if (!channel_array) {
		hddLog(LOGE, FL("No channel present"));
		goto fail;
	}
	if (nla_len(channel_array) != channel_count *
	    sizeof(struct wlan_hdd_ocb_config_channel)) {
		hddLog(LOGE, FL("CHANNEL_ARRAY is not the correct size"));
		goto fail;
	}
	wlan_hdd_ocb_config_channel_to_sir_ocb_config_channel(
	    config->channels, nla_data(channel_array), channel_count);

	/* Identify the vdev interface */
	config->session_id = adapter->sessionId;

	/* Release all the mac addresses used for OCB */
	for (i = 0; i < adapter->ocb_mac_addr_count; i++) {
		wlan_hdd_release_intf_addr(adapter->pHddCtx,
					   adapter->ocb_mac_address[i]);
	}
	adapter->ocb_mac_addr_count = 0;

	/*
	 * Setup locally administered mac addresses for each channel.
	 * First channel uses the adapter's address.
	 */
	for (i = 0; i < config->channel_count; i++) {
		if (i == 0) {
			cdf_mem_copy(config->channels[i].mac_address,
				adapter->macAddressCurrent.bytes,
				sizeof(tSirMacAddr));
		} else {
			mac_addr = wlan_hdd_get_intf_addr(adapter->pHddCtx);
			if (mac_addr == NULL) {
				hddLog(LOGE, FL("Cannot obtain mac address"));
				goto fail;
			}
			cdf_mem_copy(config->channels[i].mac_address,
				mac_addr, sizeof(tSirMacAddr));
			/* Save the mac address to release later */
			cdf_mem_copy(adapter->ocb_mac_address[
				     adapter->ocb_mac_addr_count],
				     config->channels[i].mac_address,
				     sizeof(adapter->ocb_mac_address[
				     adapter->ocb_mac_addr_count]));
			adapter->ocb_mac_addr_count++;
		}
	}

	/* Read the schedule array */
	sched_array = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY];
	if (!sched_array) {
		hddLog(LOGE, FL("No channel present"));
		goto fail;
	}
	if (nla_len(sched_array) != schedule_size * sizeof(*config->schedule)) {
		hddLog(LOGE, FL("SCHEDULE_ARRAY is not the correct size"));
		goto fail;
	}
	cdf_mem_copy(config->schedule, nla_data(sched_array),
		nla_len(sched_array));

	/* Copy the NDL chan array */
	if (ndl_chan_list_len) {
		config->dcc_ndl_chan_list_len = ndl_chan_list_len;
		cdf_mem_copy(config->dcc_ndl_chan_list, nla_data(ndl_chan_list),
			nla_len(ndl_chan_list));
	}

	/* Copy the NDL active state array */
	if (ndl_active_state_list_len) {
		config->dcc_ndl_active_state_list_len =
			ndl_active_state_list_len;
		cdf_mem_copy(config->dcc_ndl_active_state_list,
			nla_data(ndl_active_state_list),
			nla_len(ndl_active_state_list));
	}

	rc = hdd_ocb_set_config_req(adapter, config);
	if (rc)
		hddLog(LOGE, FL("Error while setting OCB config: %d"), rc);

fail:
	cdf_mem_free(config);
	return rc;
}

/**
 * wlan_hdd_cfg80211_ocb_set_config() - Interface for set config command
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
int wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
				     struct wireless_dev *wdev,
				     const void *data,
				     int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_set_config(wiphy, wdev, data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __wlan_hdd_cfg80211_ocb_set_utc_time() - Interface for set UTC time command
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
static int __wlan_hdd_cfg80211_ocb_set_utc_time(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data,
						int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX + 1];
	struct nlattr *utc_attr;
	struct nlattr *time_error_attr;
	struct sir_ocb_utc *utc;
	int rc = -EINVAL;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return -EINVAL;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->sessionId)) {
		hddLog(LOGE, FL("The device has not been started"));
		return -EINVAL;
	}

	/* Parse the netlink message */
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX,
		      data,
		      data_len, qca_wlan_vendor_ocb_set_utc_time_policy)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		return -EINVAL;
	}

	/* Read the UTC time */
	utc_attr = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE];
	if (!utc_attr) {
		hddLog(LOGE, FL("UTC_TIME is not present"));
		return -EINVAL;
	}
	if (nla_len(utc_attr) != SIZE_UTC_TIME) {
		hddLog(LOGE, FL("UTC_TIME is not the correct size"));
		return -EINVAL;
	}

	/* Read the time error */
	time_error_attr = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR];
	if (!time_error_attr) {
		hddLog(LOGE, FL("UTC_TIME is not present"));
		return -EINVAL;
	}
	if (nla_len(time_error_attr) != SIZE_UTC_TIME_ERROR) {
		hddLog(LOGE, FL("UTC_TIME is not the correct size"));
		return -EINVAL;
	}

	utc = cdf_mem_malloc(sizeof(*utc));
	if (!utc) {
		hddLog(LOGE, FL("cdf_mem_malloc failed"));
		return -ENOMEM;
	}
	utc->vdev_id = adapter->sessionId;
	cdf_mem_copy(utc->utc_time, nla_data(utc_attr), SIZE_UTC_TIME);
	cdf_mem_copy(utc->time_error, nla_data(time_error_attr),
		SIZE_UTC_TIME_ERROR);

	if (sme_ocb_set_utc_time(hdd_ctx->hHal, utc) != CDF_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error while setting UTC time"));
		rc = -EINVAL;
	} else {
		rc = 0;
	}

	cdf_mem_free(utc);
	return rc;
}

/**
 * wlan_hdd_cfg80211_ocb_set_utc_time() - Interface for the set UTC time command
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
int wlan_hdd_cfg80211_ocb_set_utc_time(struct wiphy *wiphy,
				       struct wireless_dev *wdev,
				       const void *data,
				       int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_set_utc_time(wiphy, wdev, data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __wlan_hdd_cfg80211_ocb_start_timing_advert() - Interface for start TA cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
static int
__wlan_hdd_cfg80211_ocb_start_timing_advert(struct wiphy *wiphy,
					    struct wireless_dev *wdev,
					    const void *data,
					    int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(WLAN_HDD_GET_HAL_CTX(adapter));
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX + 1];
	struct sir_ocb_timing_advert *timing_advert;
	int rc = -EINVAL;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return -EINVAL;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->sessionId)) {
		hddLog(LOGE, FL("The device has not been started"));
		return -EINVAL;
	}

	timing_advert = cdf_mem_malloc(sizeof(*timing_advert));
	if (!timing_advert) {
		hddLog(LOGE, FL("cdf_mem_malloc failed"));
		return -ENOMEM;
	}
	cdf_mem_zero(timing_advert, sizeof(*timing_advert));
	timing_advert->vdev_id = adapter->sessionId;

	/* Parse the netlink message */
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX,
		      data,
		      data_len,
		      qca_wlan_vendor_ocb_start_timing_advert_policy)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		goto fail;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ]) {
		hddLog(LOGE, FL("CHANNEL_FREQ is not present"));
		goto fail;
	}
	timing_advert->chan_freq = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ]);

	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE]) {
		hddLog(LOGE, FL("REPEAT_RATE is not present"));
		goto fail;
	}
	timing_advert->repeat_rate = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE]);

	timing_advert->template_length =
		sch_gen_timing_advert_frame(mac_ctx,
			*(tSirMacAddr *)&adapter->macAddressCurrent.bytes,
			&timing_advert->template_value,
			&timing_advert->timestamp_offset,
			&timing_advert->time_value_offset);
	if (timing_advert->template_length <= 0) {
		hddLog(LOGE, FL("Error while generating the TA frame"));
		goto fail;
	}

	if (sme_ocb_start_timing_advert(hdd_ctx->hHal, timing_advert) !=
			CDF_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error while starting timing advert"));
		rc = -EINVAL;
	} else {
		rc = 0;
	}

fail:
	if (timing_advert->template_value)
		cdf_mem_free(timing_advert->template_value);
	cdf_mem_free(timing_advert);
	return rc;
}

/**
 * wlan_hdd_cfg80211_ocb_start_timing_advert() - Interface for the start TA cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
int wlan_hdd_cfg80211_ocb_start_timing_advert(struct wiphy *wiphy,
					      struct wireless_dev *wdev,
					      const void *data,
					      int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_start_timing_advert(wiphy, wdev,
							  data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __wlan_hdd_cfg80211_ocb_stop_timing_advert() - Interface for the stop TA cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
static int
__wlan_hdd_cfg80211_ocb_stop_timing_advert(struct wiphy *wiphy,
					   struct wireless_dev *wdev,
					   const void *data,
					   int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX + 1];
	struct sir_ocb_timing_advert *timing_advert;
	int rc = -EINVAL;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return -EINVAL;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->sessionId)) {
		hddLog(LOGE, FL("The device has not been started"));
		return -EINVAL;
	}

	timing_advert = cdf_mem_malloc(sizeof(*timing_advert));
	if (!timing_advert) {
		hddLog(LOGE, FL("cdf_mem_malloc failed"));
		return -ENOMEM;
	}
	cdf_mem_zero(timing_advert, sizeof(sizeof(*timing_advert)));
	timing_advert->vdev_id = adapter->sessionId;

	/* Parse the netlink message */
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX,
		      data,
		      data_len,
		      qca_wlan_vendor_ocb_stop_timing_advert_policy)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		goto fail;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ]) {
		hddLog(LOGE, FL("CHANNEL_FREQ is not present"));
		goto fail;
	}
	timing_advert->chan_freq = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ]);

	if (sme_ocb_stop_timing_advert(hdd_ctx->hHal, timing_advert) !=
			CDF_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error while stopping timing advert"));
		rc = -EINVAL;
	} else {
		rc = 0;
	}

fail:
	cdf_mem_free(timing_advert);
	return rc;
}

/**
 * wlan_hdd_cfg80211_ocb_stop_timing_advert() - Interface for the stop TA cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
int wlan_hdd_cfg80211_ocb_stop_timing_advert(struct wiphy *wiphy,
					     struct wireless_dev *wdev,
					     const void *data,
					     int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_stop_timing_advert(wiphy, wdev,
							 data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_ocb_get_tsf_timer_callback() - Callback to get TSF command
 * @context_ptr: request context
 * @response_ptr: response data
 */
static void hdd_ocb_get_tsf_timer_callback(void *context_ptr,
					   void *response_ptr)
{
	struct hdd_ocb_ctxt *context = context_ptr;
	struct sir_ocb_get_tsf_timer_response *response = response_ptr;

	if (!context)
		return;

	spin_lock(&hdd_context_lock);
	if (context->magic == HDD_OCB_MAGIC) {
		if (response) {
			context->adapter->ocb_get_tsf_timer_resp = *response;
			context->status = 0;
		} else {
			context->status = -EINVAL;
		}
		complete(&context->completion_evt);
	}
	spin_unlock(&hdd_context_lock);
}

/**
 * __wlan_hdd_cfg80211_ocb_get_tsf_timer() - Interface for get TSF timer cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
static int
__wlan_hdd_cfg80211_ocb_get_tsf_timer(struct wiphy *wiphy,
				      struct wireless_dev *wdev,
				      const void *data,
				      int data_len)
{
	struct sk_buff *nl_resp = 0;
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	int rc = -EINVAL;
	struct sir_ocb_get_tsf_timer request = {0};
	struct hdd_ocb_ctxt context = {0};

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return -EINVAL;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->sessionId)) {
		hddLog(LOGE, FL("The device has not been started"));
		return -EINVAL;
	}

	/* Initialize the callback context */
	init_completion(&context.completion_evt);
	context.adapter = adapter;
	context.magic = HDD_OCB_MAGIC;

	request.vdev_id = adapter->sessionId;
	/* Call the SME function */
	rc = sme_ocb_get_tsf_timer(hdd_ctx->hHal, &context,
				   hdd_ocb_get_tsf_timer_callback,
				   &request);
	if (rc) {
		hddLog(LOGE, FL("Error calling SME function"));
		/* Need to convert from ecdf_status to errno. */
		return -EINVAL;
	}

	rc = wait_for_completion_timeout(&context.completion_evt,
		msecs_to_jiffies(WLAN_WAIT_TIME_OCB_CMD));
	if (rc == 0) {
		hddLog(LOGE, FL("Operation timed out"));
		rc = -ETIMEDOUT;
		goto end;
	}
	rc = 0;

	if (context.status) {
		hddLog(LOGE, FL("Operation failed: %d"), context.status);
		rc = context.status;
		goto end;
	}

	/* Allocate the buffer for the response. */
	nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
		2 * sizeof(uint32_t) + NLMSG_HDRLEN);

	if (!nl_resp) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
		rc = -ENOMEM;
		goto end;
	}

	hddLog(LOGE, FL("Got TSF timer response, high=%d, low=%d"),
	       adapter->ocb_get_tsf_timer_resp.timer_high,
	       adapter->ocb_get_tsf_timer_resp.timer_low);

	/* Populate the response. */
	rc = nla_put_u32(nl_resp,
			QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH,
			adapter->ocb_get_tsf_timer_resp.timer_high);
	if (rc)
		goto end;
	rc = nla_put_u32(nl_resp,
			    QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW,
			    adapter->ocb_get_tsf_timer_resp.timer_low);
	if (rc)
		goto end;

	/* Send the response. */
	rc = cfg80211_vendor_cmd_reply(nl_resp);
	nl_resp = NULL;
	if (rc) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_reply failed: %d"), rc);
		goto end;
	}

end:
	spin_lock(&hdd_context_lock);
	context.magic = 0;
	spin_unlock(&hdd_context_lock);
	if (nl_resp)
		kfree_skb(nl_resp);
	return rc;
}

/**
 * wlan_hdd_cfg80211_ocb_get_tsf_timer() - Interface for get TSF timer cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
int wlan_hdd_cfg80211_ocb_get_tsf_timer(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data,
					int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_get_tsf_timer(wiphy, wdev,
						    data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_dcc_get_stats_callback() - Callback to get stats command
 * @context_ptr: request context
 * @response_ptr: response data
 */
static void hdd_dcc_get_stats_callback(void *context_ptr, void *response_ptr)
{
	struct hdd_ocb_ctxt *context = context_ptr;
	struct sir_dcc_get_stats_response *response = response_ptr;
	struct sir_dcc_get_stats_response *hdd_resp;

	if (!context)
		return;

	spin_lock(&hdd_context_lock);
	if (context->magic == HDD_OCB_MAGIC) {
		if (response) {
			/*
			 * If the response is hanging around from the previous
			 * request, delete it
			 */
			if (context->adapter->dcc_get_stats_resp) {
				cdf_mem_free(
				    context->adapter->dcc_get_stats_resp);
			}
			context->adapter->dcc_get_stats_resp =
				cdf_mem_malloc(sizeof(
				    *context->adapter->dcc_get_stats_resp) +
				    response->channel_stats_array_len);
			if (context->adapter->dcc_get_stats_resp) {
				hdd_resp = context->adapter->dcc_get_stats_resp;
				*hdd_resp = *response;
				hdd_resp->channel_stats_array =
					(void *)hdd_resp + sizeof(*hdd_resp);
				cdf_mem_copy(hdd_resp->channel_stats_array,
					     response->channel_stats_array,
					     response->channel_stats_array_len);
				context->status = 0;
			} else {
				context->status = -ENOMEM;
			}
		} else {
			context->status = -EINVAL;
		}
		complete(&context->completion_evt);
	}
	spin_unlock(&hdd_context_lock);
}

/**
 * __wlan_hdd_cfg80211_dcc_get_stats() - Interface for get dcc stats
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
static int __wlan_hdd_cfg80211_dcc_get_stats(struct wiphy *wiphy,
					     struct wireless_dev *wdev,
					     const void *data,
					     int data_len)
{
	uint32_t channel_count = 0;
	uint32_t request_array_len = 0;
	void *request_array = 0;
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_MAX + 1];
	struct sk_buff *nl_resp = 0;
	int rc = -EINVAL;
	struct sir_dcc_get_stats request = {0};
	struct hdd_ocb_ctxt context = {0};

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return -EINVAL;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->sessionId)) {
		hddLog(LOGE, FL("The device has not been started"));
		return -EINVAL;
	}

	/* Parse the netlink message */
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_MAX,
		      data,
		      data_len,
		      qca_wlan_vendor_dcc_get_stats)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		return -EINVAL;
	}

	/* Validate all the parameters are present */
	if (!tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_CHANNEL_COUNT] ||
	    !tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]) {
		hddLog(LOGE, FL("Parameters are not present."));
		return -EINVAL;
	}

	channel_count = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_CHANNEL_COUNT]);
	request_array_len = nla_len(
		tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]);
	request_array = nla_data(
		tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]);

	/* Initialize the callback context */
	init_completion(&context.completion_evt);
	context.adapter = adapter;
	context.magic = HDD_OCB_MAGIC;

	request.vdev_id = adapter->sessionId;
	request.channel_count = channel_count;
	request.request_array_len = request_array_len;
	request.request_array = request_array;

	/* Call the SME function. */
	rc = sme_dcc_get_stats(hdd_ctx->hHal, &context,
			       hdd_dcc_get_stats_callback,
			       &request);
	if (rc) {
		hddLog(LOGE, FL("Error calling SME function"));
		/* Need to convert from cdf_status to errno. */
		return -EINVAL;
	}

	/* Wait for the function to complete. */
	rc = wait_for_completion_timeout(&context.completion_evt,
				msecs_to_jiffies(WLAN_WAIT_TIME_OCB_CMD));
	if (rc == 0) {
		hddLog(LOGE, FL("Operation failed: %d"), rc);
		rc = -ETIMEDOUT;
		goto end;
	}

	if (context.status) {
		hddLog(LOGE, FL("There was error: %d"), context.status);
		rc = context.status;
		goto end;
	}

	if (!adapter->dcc_get_stats_resp) {
		hddLog(LOGE, FL("The response was NULL"));
		rc = -EINVAL;
		goto end;
	}

	/* Allocate the buffer for the response. */
	nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(uint32_t) +
		adapter->dcc_get_stats_resp->channel_stats_array_len +
		NLMSG_HDRLEN);
	if (!nl_resp) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
		rc = -ENOMEM;
		goto end;
	}

	/* Populate the response. */
	rc = nla_put_u32(nl_resp,
			 QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT,
			 adapter->dcc_get_stats_resp->num_channels);
	if (rc)
		goto end;
	rc = nla_put(nl_resp,
		     QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY,
		     adapter->dcc_get_stats_resp->channel_stats_array_len,
		     adapter->dcc_get_stats_resp->channel_stats_array);
	if (rc)
		goto end;

	/* Send the response. */
	rc = cfg80211_vendor_cmd_reply(nl_resp);
	nl_resp = NULL;
	if (rc) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_reply failed: %d"), rc);
		goto end;
	}

	/* fall through */
end:
	spin_lock(&hdd_context_lock);
	context.magic = 0;
	cdf_mem_free(adapter->dcc_get_stats_resp);
	adapter->dcc_get_stats_resp = NULL;
	spin_unlock(&hdd_context_lock);
	if (nl_resp)
		kfree_skb(nl_resp);
	return rc;
}

/**
 * wlan_hdd_cfg80211_dcc_get_stats() - Interface for get dcc stats
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
int wlan_hdd_cfg80211_dcc_get_stats(struct wiphy *wiphy,
				    struct wireless_dev *wdev,
				    const void *data,
				    int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_dcc_get_stats(wiphy, wdev,
						data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __wlan_hdd_cfg80211_dcc_clear_stats() - Interface for clear dcc stats cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
static int __wlan_hdd_cfg80211_dcc_clear_stats(struct wiphy *wiphy,
					       struct wireless_dev *wdev,
					       const void *data,
					       int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_MAX + 1];

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return -EINVAL;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->sessionId)) {
		hddLog(LOGE, FL("The device has not been started"));
		return -EINVAL;
	}

	/* Parse the netlink message */
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_MAX,
		      data,
		      data_len,
		      qca_wlan_vendor_dcc_clear_stats)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		return -EINVAL;
	}

	/* Verify that the parameter is present */
	if (!tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP]) {
		hddLog(LOGE, FL("Parameters are not present."));
		return -EINVAL;
	}

	/* Call the SME function */
	if (sme_dcc_clear_stats(hdd_ctx->hHal, adapter->sessionId,
		nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP])) !=
			CDF_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error calling SME function."));
		return -EINVAL;
	}

	return 0;
}

/**
 * wlan_hdd_cfg80211_dcc_clear_stats() - Interface for clear dcc stats cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
int wlan_hdd_cfg80211_dcc_clear_stats(struct wiphy *wiphy,
				      struct wireless_dev *wdev,
				      const void *data,
				      int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_dcc_clear_stats(wiphy, wdev,
						  data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_dcc_update_ndl_callback() - Callback to update NDL command
 * @context_ptr: request context
 * @response_ptr: response data
 */
static void hdd_dcc_update_ndl_callback(void *context_ptr, void *response_ptr)
{
	struct hdd_ocb_ctxt *context = context_ptr;
	struct sir_dcc_update_ndl_response *response = response_ptr;

	if (!context)
		return;

	spin_lock(&hdd_context_lock);
	if (context->magic == HDD_OCB_MAGIC) {
		if (response) {
			context->adapter->dcc_update_ndl_resp = *response;
			context->status = 0;
		} else {
			context->status = -EINVAL;
		}
		complete(&context->completion_evt);
	}
	spin_unlock(&hdd_context_lock);
}

/**
 * __wlan_hdd_cfg80211_dcc_update_ndl() - Interface for update dcc cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
static int __wlan_hdd_cfg80211_dcc_update_ndl(struct wiphy *wiphy,
					      struct wireless_dev *wdev,
					      const void *data,
					      int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX + 1];
	struct sir_dcc_update_ndl request;
	uint32_t channel_count;
	uint32_t ndl_channel_array_len;
	void *ndl_channel_array;
	uint32_t ndl_active_state_array_len;
	void *ndl_active_state_array;
	int rc = -EINVAL;
	struct hdd_ocb_ctxt context = {0};

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(LOGE, FL("HDD context is not valid"));
		goto end;
	}

	if (adapter->device_mode != WLAN_HDD_OCB) {
		hddLog(LOGE, FL("Device not in OCB mode!"));
		goto end;
	}

	if (!wma_is_vdev_up(adapter->sessionId)) {
		hddLog(LOGE, FL("The device has not been started"));
		return -EINVAL;
	}

	/* Parse the netlink message */
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX,
		      data,
		      data_len,
		      qca_wlan_vendor_dcc_update_ndl)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		goto end;
	}

	/* Verify that the parameter is present */
	if (!tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_COUNT] ||
	    !tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY] ||
	    !tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY]) {
		hddLog(LOGE, FL("Parameters are not present."));
		return -EINVAL;
	}

	channel_count = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_COUNT]);
	ndl_channel_array_len = nla_len(
		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY]);
	ndl_channel_array = nla_data(
		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY]);
	ndl_active_state_array_len = nla_len(
		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY]);
	ndl_active_state_array = nla_data(
		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY]);

	/* Initialize the callback context */
	init_completion(&context.completion_evt);
	context.adapter = adapter;
	context.magic = HDD_OCB_MAGIC;

	/* Copy the parameters to the request structure. */
	request.vdev_id = adapter->sessionId;
	request.channel_count = channel_count;
	request.dcc_ndl_chan_list_len = ndl_channel_array_len;
	request.dcc_ndl_chan_list = ndl_channel_array;
	request.dcc_ndl_active_state_list_len = ndl_active_state_array_len;
	request.dcc_ndl_active_state_list = ndl_active_state_array;

	/* Call the SME function */
	rc = sme_dcc_update_ndl(hdd_ctx->hHal, &context,
				hdd_dcc_update_ndl_callback,
				&request);
	if (rc) {
		hddLog(LOGE, FL("Error calling SME function."));
		/* Convert from cdf_status to errno */
		return -EINVAL;
	}

	/* Wait for the function to complete. */
	rc = wait_for_completion_timeout(&context.completion_evt,
		msecs_to_jiffies(WLAN_WAIT_TIME_OCB_CMD));
	if (rc == 0) {
		hddLog(LOGE, FL("Operation timed out"));
		rc = -ETIMEDOUT;
		goto end;
	}
	rc = 0;

	if (context.status) {
		hddLog(LOGE, FL("Operation failed: %d"), context.status);
		rc = context.status;
		goto end;
	}

	if (adapter->dcc_update_ndl_resp.status) {
		hddLog(LOGE, FL("Operation returned: %d"),
		       adapter->dcc_update_ndl_resp.status);
		rc = -EINVAL;
		goto end;
	}

	/* fall through */
end:
	spin_lock(&hdd_context_lock);
	context.magic = 0;
	spin_unlock(&hdd_context_lock);
	return rc;
}

/**
 * wlan_hdd_cfg80211_dcc_update_ndl() - Interface for update dcc cmd
 * @wiphy: pointer to the wiphy
 * @wdev: pointer to the wdev
 * @data: The netlink data
 * @data_len: The length of the netlink data in bytes
 *
 * Return: 0 on success.
 */
int wlan_hdd_cfg80211_dcc_update_ndl(struct wiphy *wiphy,
				     struct wireless_dev *wdev,
				     const void *data,
				     int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_dcc_update_ndl(wiphy, wdev,
						 data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * wlan_hdd_dcc_stats_event_callback() - Callback to get stats event
 * @context_ptr: request context
 * @response_ptr: response data
 */
static void wlan_hdd_dcc_stats_event_callback(void *context_ptr,
					      void *response_ptr)
{
	hdd_context_t *hdd_ctx = (hdd_context_t *)context_ptr;
	struct sir_dcc_get_stats_response *resp = response_ptr;
	struct sk_buff *vendor_event;

	ENTER();

	vendor_event =
		cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
			NULL, sizeof(uint32_t) + resp->channel_stats_array_len +
			NLMSG_HDRLEN,
			QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX,
			GFP_KERNEL);

	if (!vendor_event) {
		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
		return;
	}

	if (nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT,
			resp->num_channels) ||
		nla_put(vendor_event,
			QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY,
			resp->channel_stats_array_len,
			resp->channel_stats_array)) {
		hddLog(LOGE, FL("nla put failed"));
		kfree_skb(vendor_event);
		return;
	}

	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
}

/**
 * wlan_hdd_dcc_register_for_dcc_stats_event() - Register for dcc stats events
 * @hdd_ctx: hdd context
 */
void wlan_hdd_dcc_register_for_dcc_stats_event(hdd_context_t *hdd_ctx)
{
	int rc;

	rc = sme_register_for_dcc_stats_event(hdd_ctx->hHal, hdd_ctx,
		wlan_hdd_dcc_stats_event_callback);
	if (rc)
		hddLog(LOGE, FL("Register callback failed: %d"), rc);
}
