/*
 * Copyright (c) 2015-2018 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: wma_hdd_ocb.c
 *
 * WLAN Host Device Driver 802.11p OCB implementation
 */

#include "vos_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 "schApi.h"
#include "wma.h"
#include "vos_types.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->cfg_ini->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;
}

#ifdef FEATURE_STATICALLY_ADD_11P_CHANNELS

#define DOT11P_TX_PWR_MAX	30
#define DOT11P_TX_ANTENNA_MAX	6
#define NUM_DOT11P_CHANNELS	ARRAY_SIZE(valid_dot11p_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)

/**
 * 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[] = {
	{5860, 10},
	{5870, 10},
	{5880, 10},
	{5890, 10},
	{5900, 10},
	{5910, 10},
	{5920, 10},
	{5875, 20},
	{5905, 20},
	{5852, 5},
	{5857, 5},
	{5862, 5},
	{5867, 5},
	{5872, 5},
	{5877, 5},
	{5882, 5},
	{5887, 5},
	{5892, 5},
	{5897, 5},
	{5902, 5},
	{5907, 5},
	{5912, 5},
	{5917, 5},
	{5922, 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)
{
	VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
	WLAN_STADescType 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);
	u_int8_t peer_id;
	v_MACADDR_t wildcardBSSID = {
		{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
	};

	vos_status = WLANTL_RegisterOCBPeer(hdd_ctx->pvosContext,
					    adapter->macAddressCurrent.bytes,
					    &peer_id);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		hddLog(LOGE, FL("Error registering OCB Self Peer!"));
		return -EINVAL;
	}

	hdd_ctx->sta_to_adapter[peer_id] = adapter;

	sta_desc.ucSTAId = peer_id;
	/* Fill in MAC addresses */
	vos_copy_macaddr(&sta_desc.vSelfMACAddress,
			 &adapter->macAddressCurrent);
	vos_copy_macaddr(&sta_desc.vSTAMACAddress, &adapter->macAddressCurrent);
	vos_copy_macaddr(&sta_desc.vBSSIDforIBSS, &wildcardBSSID);

	sta_desc.wSTAType = WLAN_STA_OCB;
	sta_desc.ucQosEnabled = 1;
	sta_desc.ucInitState = WLANTL_STA_AUTHENTICATED;

	vos_status = WLANTL_RegisterSTAClient(hdd_ctx->pvosContext,
					      hdd_rx_packet_cbk,
					      &sta_desc,
					      0);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		hddLog(LOGE, FL("Failed to register STA client. ret=[0x%08X]"),
		       vos_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;
	vos_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(uint32_t num_channels,
					  uint32_t num_schedule,
					  uint32_t ndl_chan_list_len,
					  uint32_t 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 = vos_mem_malloc(len);
	if (!cursor)
		goto fail;

	vos_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:
	vos_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)) {
				wlan_hdd_netif_queue_control(adapter,
					WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
					WLAN_CONTROL_PATH);
			}
		}

		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 i, rc;
	eHalStatus halStatus;
	bool enable_chan_stats;
	struct hdd_ocb_ctxt context = {0};
	struct dsrc_radio_chan_stats_ctxt *ctx;

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

	/*
	 * Save OCB configured channel information for
	 * DSRC Radio channel statistics event processsor.
	 */
	ctx = &adapter->dsrc_chan_stats;
	ctx->config_chans_num = config->channel_count;
	for (i = 0; i < config->channel_count; i++)
		ctx->config_chans_freq[i] = config->channels[i].chan_freq;
	if (ctx->cur_req) {
		vos_mem_free(ctx->cur_req);
		ctx->cur_req = NULL;
	}
	/* Disable Channel Statistics */
	enable_chan_stats = ctx->enable_chan_stats;
	if (enable_chan_stats)
		wlan_hdd_dsrc_config_radio_chan_stats(adapter, false);

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

	hddLog(LOG1, FL("Disabling queues"));
	wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
				     WLAN_CONTROL_PATH);
	/* Call the SME API to set the config */
	halStatus = sme_ocb_set_config(
		((hdd_context_t *)adapter->pHddCtx)->hHal, &context,
		hdd_ocb_set_config_callback, config);
	if (halStatus != eHAL_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error calling SME function."));
		/* Convert from eHalStatus 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);

		/* Flush already saved configured channel frequence */
		ctx->config_chans_num = 0;
		vos_mem_zero(ctx->config_chans_freq, 2 * sizeof(uint32_t));
	} else {
		if (enable_chan_stats)
			wlan_hdd_dsrc_config_radio_chan_stats(adapter, true);

		/*
		 * Net device mtu size is 1500 by default, But for OCB RAW mode,
		 * driver need later convert 802.3 data header to IEEE802.11
		 * data header and EPD header, which will increase total frame
		 * length. In such case, long packet length will exceed the
		 * target credit size. It resulted in that the packet is cut
		 * down, data would be missed and the traffic would be broken.
		 * So decrease the netdev mtu size to work around this issue
		 * in IEEE80211p RAW mode.
		 */
		if (config->flags & OCB_CONFIG_FLAG_80211_FRAME_MODE)
			adapter->dev->mtu = ETH_DATA_LEN - 8;
		else
			adapter->dev->mtu = ETH_DATA_LEN;
	}
	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;

	if (wlan_hdd_validate_context(WLAN_HDD_GET_CTX(adapter)))
		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;
		}

		config->channels[config->channel_count].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.
		 */
		config->channels[config->channel_count].max_pwr =
			sched->channels[i].tx_power / 2;
		config->channels[config->channel_count].bandwidth =
			sched->channels[i].channel_bandwidth;
		/* assume 10 as default if not provided */
		if (config->channels[config->channel_count].bandwidth == 0) {
			config->channels[config->channel_count].bandwidth = 10;
		}

		/*
		 * Setup locally administered mac addresses for each channel.
		 * First channel uses the adapter's address.
		 */
		if (i == 0) {
			vos_mem_copy(config->channels[config->channel_count].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;
			}
			vos_mem_copy(config->channels[
				     config->channel_count].mac_address,
				     mac_addr, sizeof(tSirMacAddr));
			/* Save the mac address to release later */
			vos_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++) {
			config->channels[config->channel_count].qos_params[j].aifsn =
				sched->channels[i].qos_params[j].aifsn;
			config->channels[config->channel_count].qos_params[j].cwmin =
				sched->channels[i].qos_params[j].cwmin;
			config->channels[config->channel_count].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:
	vos_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;

	vos_ssr_protect(__func__);
	ret = __iw_set_dot11p_channel_sched(dev, info, wrqu, extra);
	vos_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
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM] = {
		.type = NLA_BINARY
	},
	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_TA_MAX_DURATION] = {
		.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];
	sir_qos_params_t qos_params[MAX_NUM_AC];
	uint32_t max_pwr;
	uint32_t min_pwr;
	uint32_t datarate;
	uint8_t mac_address[6];
};

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;

	vos_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;
		vos_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;
		vos_mem_copy(dest[i].mac_address, src[i].mac_address, 6);
	}
}

/**
 * __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;
	uint32_t ta_max_duration = 0;
	void *def_tx_param = NULL;
	uint32_t def_tx_param_size = 0;
	int i;
	uint32_t channel_count, schedule_size;
	struct sir_ocb_config *config;
	int rc = -EINVAL;
	uint8_t *mac_addr;

	ENTER();

	if (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		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. This parameter is optional. */
	if (tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS])
		flags = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS]);

	/* Get the default TX parameters. This parameter is optional. */
	if (tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM]) {
		def_tx_param_size = nla_len(tb[
			QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM]);
		def_tx_param = nla_data(tb[
			QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM]);
	}

	/* Get the ta max duration. This parameter is optional. */
	if (tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_TA_MAX_DURATION])
		ta_max_duration = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_TA_MAX_DURATION]);

	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;
	/*
	 * Set max duration after the last TA received that the local time set
	 * by TA is synchronous to other communicating OCB STAs. If it expires,
	 * the OCB STA itself without UTC time source like GPS thinks that the
	 * local time of itself is not sync to other STAs and stop scheduling
	 * DSRC channel switch.
	 */
	config->ta_max_duration = ta_max_duration;
	config->def_tx_param = def_tx_param;
	config->def_tx_param_size = def_tx_param_size;

	/* 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 managed mac addresses for each channel.
	 * If no configured mac address set from userspace,
	 * first channel uses the adapter's default address.
	 */
	for (i = 0; i < config->channel_count; i++) {
		/*
		 * If dsrc_config not set the mac address, then default mac
		 * address from dsrc_config app is all zero and invalid.
		 */
		if (!vos_is_macaddr_zero(
		    (v_MACADDR_t *)config->channels[i].mac_address))
			continue;

		if (i == 0) {
			vos_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;
			}
			vos_mem_copy(config->channels[i].mac_address,
				mac_addr, sizeof(tSirMacAddr));
			/* Save the mac address to release later */
			vos_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;
	}
	vos_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;
		vos_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;
		vos_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:
	vos_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;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_set_config(wiphy, wdev, data, data_len);
	vos_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 (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		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 = vos_mem_malloc(sizeof(*utc));
	if (!utc) {
		hddLog(LOGE, FL("vos_mem_malloc failed"));
		return -ENOMEM;
	}
	utc->vdev_id = adapter->sessionId;
	vos_mem_copy(utc->utc_time, nla_data(utc_attr), SIZE_UTC_TIME);
	vos_mem_copy(utc->time_error, nla_data(time_error_attr),
		SIZE_UTC_TIME_ERROR);

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

	vos_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;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_set_utc_time(wiphy, wdev, data, data_len);
	vos_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);
	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 (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		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 = vos_mem_malloc(sizeof(*timing_advert));
	if (!timing_advert) {
		hddLog(LOGE, FL("vos_mem_malloc failed"));
		return -ENOMEM;
	}
	vos_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 =
		sme_ocb_gen_timing_advert_frame(hdd_ctx->hHal,
			*(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(timing_advert) != eHAL_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error while starting timing advert"));
		rc = -EINVAL;
	} else {
		rc = 0;
	}

fail:
	if (timing_advert->template_value)
		vos_mem_free(timing_advert->template_value);
	vos_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;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_start_timing_advert(wiphy, wdev,
							  data, data_len);
	vos_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 (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		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 = vos_mem_malloc(sizeof(*timing_advert));
	if (!timing_advert) {
		hddLog(LOGE, FL("vos_mem_malloc failed"));
		return -ENOMEM;
	}
	vos_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(timing_advert) != eHAL_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error while stopping timing advert"));
		rc = -EINVAL;
	} else {
		rc = 0;
	}

fail:
	vos_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;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_stop_timing_advert(wiphy, wdev,
							 data, data_len);
	vos_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 (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		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 eHalStatus 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;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_ocb_get_tsf_timer(wiphy, wdev,
						    data, data_len);
	vos_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) {
				vos_mem_free(
				    context->adapter->dcc_get_stats_resp);
			}
			context->adapter->dcc_get_stats_resp =
				vos_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);
				vos_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 (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		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 eHalStatus 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;
	vos_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;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_dcc_get_stats(wiphy, wdev,
						data, data_len);
	vos_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 (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		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(adapter->sessionId,
		nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP])) !=
			eHAL_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;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_dcc_clear_stats(wiphy, wdev,
						  data, data_len);
	vos_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 (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		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 eHalStatus 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;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_dcc_update_ndl(wiphy, wdev,
						 data, data_len);
	vos_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);
}

static void wlan_hdd_dsrc_update_radio_chan_stats(
		struct dsrc_radio_chan_stats_ctxt *ctx,
		struct radio_chan_stats_rsp *resp)
{
	int i, j;
	struct radio_chan_stats_info *src, *dest;

	if (!ctx || !resp)
		return;

	if (resp->num_chans > ctx->config_chans_num)
		return;

	src = resp->chan_stats;
	dest = ctx->chan_stats;
	/* Check if current event is for previous channel configuration. */
	for (i = 0; i < resp->num_chans; i++, src++) {
		if (!src) {
			hddLog(LOGE, FL("Channel stats data is null"));
			return;
		}

		for (j = 0; j < ctx->config_chans_num; j++) {
			if (src->chan_freq == ctx->config_chans_freq[j])
				break;
		}
		if (j == ctx->config_chans_num) {
			/*
			 * This DSRC Channel Radio channel statistics event
			 * is for previous old channel configuration.
			 * Now just Ignore this type event and clear saved
			 * entry in driver. If possible, driver can post
			 * the recorders to application.
			 */
			spin_lock(&ctx->chan_stats_lock);
			ctx->chan_stats_num = 0;
			vos_mem_zero(dest, 2 * sizeof(*dest));
			spin_unlock(&ctx->chan_stats_lock);
			hddLog(LOGE, FL("Old Chan Stats Data"));
			return;
		}
	}

	/* Save the first channels statistics event in adapter. */
	src = resp->chan_stats;
	if (!ctx->chan_stats_num) {
		spin_lock(&ctx->chan_stats_lock);
		vos_mem_copy(dest, src, resp->num_chans * sizeof(*src));
		ctx->chan_stats_num = resp->num_chans;
		spin_unlock(&ctx->chan_stats_lock);
		return;
	}

	/* Merge new received channel statistics data to previous entry. */
	spin_lock(&ctx->chan_stats_lock);
	for (i = 0; i < resp->num_chans; i++, src++) {
		struct radio_chan_stats_info *dest_entry = NULL;
		struct radio_chan_stats_info *empty_entry = NULL;

		/* Now only two channel stats supported. */
		dest = ctx->chan_stats;
		for (j = 0; j < DSRC_MAX_CHAN_STATS_CNT; j++, dest++) {
			/* Get empty entry */
			if (dest->chan_freq == 0) {
				empty_entry = dest;
				continue;
			}
			if (src->chan_freq == dest->chan_freq) {
				dest_entry = dest;
				break;
			}
		}

		if (dest_entry) {
			dest = dest_entry;
		} else if (empty_entry) {
			/* Copy new recorders to new entry*/
			ctx->chan_stats_num++;
			vos_mem_copy(empty_entry, src, sizeof(*src));
			continue;
		} else {
			spin_unlock(&ctx->chan_stats_lock);
			hddLog(LOGE, FL("No entry found."));
			return;
		}

		/* Ignore Invalid statistics data. */
		if (src->measurement_period == 0) {
			hddLog(LOGE, FL("Invalid stats data."));
			continue;
		}

		/* Merge Channel Statistics. */
		dest->measurement_period += src->measurement_period;
		dest->on_chan_us += src->on_chan_us;
		dest->on_chan_ratio = (uint32_t)vos_do_div64(
				dest->on_chan_us * 100,
				dest->measurement_period);
		dest->tx_duration_us += src->tx_duration_us;
		dest->rx_duration_us += src->rx_duration_us;
		if (dest->on_chan_us == 0) {
			dest->chan_busy_ratio = 0;
		} else {
			dest->chan_busy_ratio = (uint32_t)vos_do_div64(
				(dest->tx_duration_us +
				 dest->rx_duration_us) * 100,
				dest->on_chan_us);
		}
		dest->tx_mpdus += src->tx_mpdus;
		dest->tx_msdus += src->tx_msdus;
		dest->rx_succ_pkts += src->rx_succ_pkts;
		dest->rx_fail_pkts += src->rx_fail_pkts;
	}
	spin_unlock(&ctx->chan_stats_lock);

	return;
}

/**
 * wlan_hdd_dsrc_radio_chan_stats_event_callback() - Callback function for
 * WLAN DSRC Radio channel statistics event.
 * @context_ptr: pointer to radio channel statistics context.
 * @resp_ptr: pointer to radio channel statistics event buffer.
 */
static void wlan_hdd_dsrc_radio_chan_stats_event_callback(void *context_ptr,
							  void *resp_ptr)
{
	int i;
	struct radio_chan_stats_req *req;
	struct radio_chan_stats_rsp *resp;
	struct radio_chan_stats_info *chan_stats;
	struct dsrc_radio_chan_stats_ctxt *ctx;

	if (!context_ptr || !resp_ptr)
		return;

	ctx = (struct dsrc_radio_chan_stats_ctxt *)context_ptr;
	resp = (struct radio_chan_stats_rsp *)resp_ptr;
	chan_stats = resp->chan_stats;

	if (!chan_stats) {
		hddLog(LOGE, FL("No channel stats data"));
		return;
	}

	wlan_hdd_dsrc_update_radio_chan_stats(ctx, resp);

	/*
	 * DSRC Radio channel statistics RADIO_CHAN_STATS event is reported
	 * to HDD as following cases.
	 * 1. FW randomly report event caused by overflow,
	 *	configuration change....
	 * 2. Firmware response to the request from Host APP.
	 * Need check whether current event is response for request.
	 */
	spin_lock(&hdd_context_lock);
	if ((ctx->magic != HDD_OCB_MAGIC) || (!ctx->cur_req)) {
		spin_unlock(&hdd_context_lock);
		return;
	}
	req = ctx->cur_req;
	switch (req->req_type) {
	case WLAN_DSRC_REQUEST_ONE_RADIO_CHAN_STATS:
		if ((resp->num_chans == 1) &&
		    (req->chan_freq == chan_stats->chan_freq)) {
			complete(&ctx->completion_evt);
			spin_unlock(&hdd_context_lock);
			return;
		}
		break;
	case WLAN_DSRC_REQUEST_ALL_RADIO_CHAN_STATS:
		if (resp->num_chans != ctx->config_chans_num) {
			spin_unlock(&hdd_context_lock);
			return;
		}
		/* Check response channel is configured. */
		for (i = 0; i < resp->num_chans; i++) {
			if (chan_stats[i].chan_freq !=
			    ctx->config_chans_freq[i]) {
				spin_unlock(&hdd_context_lock);
				return;
			}
		}
		complete(&ctx->completion_evt);
		break;
	}
	spin_unlock(&hdd_context_lock);

	return;
}

int wlan_hdd_dsrc_config_radio_chan_stats(hdd_adapter_t *adapter,
					  bool enable_chan_stats)
{
	int ret = 0;
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	struct dsrc_radio_chan_stats_ctxt *ctx;
	struct radio_chan_stats_info *chan_stats;

	if (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	ctx = &adapter->dsrc_chan_stats;
	if (ctx->enable_chan_stats == enable_chan_stats) {
		hddLog(LOGE, FL("DSRC channel stats already %s\n"),
			enable_chan_stats == true ? "enable" : "disable");
		return ret;
	}

	ctx->chan_stats_num = 0;
	chan_stats = ctx->chan_stats;
	vos_mem_zero(chan_stats, DSRC_MAX_CHAN_STATS_CNT * sizeof(*chan_stats));

	if (enable_chan_stats) {
		spin_lock_init(&ctx->chan_stats_lock);
		ret = sme_register_radio_chan_stats_cb(
			((hdd_context_t *)adapter->pHddCtx)->hHal, (void *)ctx,
			wlan_hdd_dsrc_radio_chan_stats_event_callback);
	} else {
		ret = sme_unregister_radio_chan_stats_cb(
			((hdd_context_t *)adapter->pHddCtx)->hHal);
	}

	ret = process_wma_set_command((int)adapter->sessionId,
			(int)WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE,
			enable_chan_stats, PDEV_CMD);

	if (!ret)
		ctx->enable_chan_stats = enable_chan_stats;

	return ret;
}

int wlan_hdd_dsrc_request_radio_chan_stats(hdd_adapter_t *adapter,
					   struct radio_chan_stats_req *req)
{
	int ret = 0;
	eHalStatus halStatus;
	struct dsrc_radio_chan_stats_ctxt *ctx;

	halStatus = sme_request_radio_chan_stats(
			((hdd_context_t *)adapter->pHddCtx)->hHal, req);
	if (halStatus != eHAL_STATUS_SUCCESS) {
		hddLog(LOGE, FL("Error call dsrc chan stats req func."));
		return -EINVAL;
	}

	ctx = &adapter->dsrc_chan_stats;
	init_completion(&ctx->completion_evt);
	spin_lock(&hdd_context_lock);
	ctx->magic = HDD_OCB_MAGIC;
	spin_unlock(&hdd_context_lock);
	if (!wait_for_completion_timeout(&ctx->completion_evt,
		msecs_to_jiffies(WLAN_WAIT_TIME_OCB_CMD))) {
		hddLog(LOGE, FL("Wait for request completion timedout."));
		ret = -ETIMEDOUT;
	}

	spin_lock(&hdd_context_lock);
	ctx->magic = 0;
	spin_unlock(&hdd_context_lock);
	return ret;
}

void wlan_hdd_dsrc_deinit_chan_stats(hdd_adapter_t *adapter)
{
	struct dsrc_radio_chan_stats_ctxt *ctx;

	if (!adapter)
		return;

	ctx = &adapter->dsrc_chan_stats;
	if (ctx->cur_req) {
		vos_mem_free(ctx->cur_req);
		ctx->cur_req = NULL;
	}

	return;
}
