/*
 * Copyright (c) 2011-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: 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_hdd_request_manager.h"
#include "wlan_tgt_def_config.h"
#include "sch_api.h"
#include "wma_api.h"
#include <cdp_txrx_cmn.h>
#include <cdp_txrx_peer_ops.h>
#include <cdp_txrx_handle.h>
#include "wlan_ocb_public_structs.h"
#include "wlan_ocb_ucfg_api.h"
#include <cdp_txrx_cmn.h>
#include <cdp_txrx_peer_ops.h>
#include <cdp_txrx_handle.h>
#include <cdp_txrx_ocb.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

/**
 * 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(struct hdd_context *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 ocb_wmm_param 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)) {
			hdd_err("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)) {
			hdd_err("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)) {
			hdd_err("Invalid QoS parameter cwmax %d",
				qos_params[i].cwmax);
			return -EINVAL;
		}
	}

	return 0;
}

/**
 * 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 < HDD_NUM_NL80211_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 -EINVAL;
}

/**
 * hdd_ocb_validate_config() - Validates the config data
 * @config: configuration to be validated
 *
 * Return: 0 on success.
 */
static int hdd_ocb_validate_config(struct hdd_adapter *adapter,
				   struct ocb_config *config)
{
	int i;
	struct hdd_context *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)) {
			hdd_err("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(struct hdd_adapter *adapter)
{
	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
	struct ol_txrx_desc_type sta_desc = {0};
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	uint8_t peer_id;
	struct ol_txrx_ops txrx_ops;
	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);

	qdf_status = cdp_peer_register_ocb_peer(soc,
				adapter->mac_addr.bytes,
				&peer_id);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("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;

	/* Register the vdev transmit and receive functions */
	qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
	txrx_ops.rx.rx = hdd_rx_packet_cbk;
	cdp_vdev_register(soc,
		(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
		(struct cdp_pdev *)pdev, adapter->session_id),
		adapter, &txrx_ops);
	adapter->tx_fn = txrx_ops.tx.tx;

	qdf_status = cdp_peer_register(soc,
			(struct cdp_pdev *)pdev, &sta_desc);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Failed to register. Status= %d [0x%08X]",
		       qdf_status, qdf_status);
		return -EINVAL;
	}

	if (sta_ctx->conn_info.staId[0] != HDD_WLAN_INVALID_STA_ID &&
	     sta_ctx->conn_info.staId[0] != peer_id) {
		hdd_err("The ID for the OCB station has changed.");
	}

	sta_ctx->conn_info.staId[0] = peer_id;
	qdf_copy_macaddr(&sta_ctx->conn_info.peerMacAddress[0],
			 &adapter->mac_addr);

	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 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 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 ocb_config_chan) +
		num_schedule * sizeof(struct ocb_config_schdl) +
		ndl_chan_list_len +
		ndl_active_state_list_len;

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

	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:
	qdf_mem_free(ret);
	return NULL;
}

struct hdd_ocb_set_config_priv {
	int status;
};


/**
 * 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_request *hdd_request;
	struct hdd_ocb_set_config_priv *priv;
	struct ocb_set_config_response *response = response_ptr;

	hdd_request = hdd_request_get(context_ptr);
	if (!hdd_request) {
		hdd_err("Obsolete request");
		return;
	}
	priv = hdd_request_priv(hdd_request);

	if (response && response->status)
		hdd_warn("Operation failed: %d", response->status);

	if (response && (response->status == OCB_CHANNEL_CONFIG_SUCCESS))
		priv->status = 0;
	else
		priv->status = -EINVAL;

	hdd_request_complete(hdd_request);
	hdd_request_put(hdd_request);
}

/**
 * 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(struct hdd_adapter *adapter,
				  struct ocb_config *config)
{
	int rc;
	QDF_STATUS status;
	void *cookie;
	struct hdd_request *hdd_request;
	struct hdd_ocb_set_config_priv *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
	};

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

	hdd_request = hdd_request_alloc(&params);
	if (!hdd_request) {
		hdd_err("Request allocation failure");
		return -ENOMEM;
	}
	cookie = hdd_request_cookie(hdd_request);

	hdd_debug("Disabling queues");
	wlan_hdd_netif_queue_control(adapter,
				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
				     WLAN_CONTROL_PATH);

	status = ucfg_ocb_set_channel_config(adapter->hdd_vdev, config,
					     hdd_ocb_set_config_callback,
					     cookie);
	if (QDF_IS_STATUS_ERROR(status)) {
		hdd_err("Failed to set channel config.");
		rc = qdf_status_to_os_return(status);
		goto end;
	}

	/* Wait for the function to complete. */
	rc = hdd_request_wait_for_response(hdd_request);
	if (rc) {
		hdd_err("Operation timed out");
		goto end;
	}

	priv = hdd_request_priv(hdd_request);
	rc = priv->status;
	if (rc) {
		hdd_err("Operation failed: %d", rc);
		goto end;
	}

	/*
	 * 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);

	/* fall through */
end:
	hdd_request_put(hdd_request);

	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;
	struct dot11p_channel_sched *sched;
	struct hdd_context *hdd_ctx;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct ocb_config *config = NULL;
	uint8_t *mac_addr;
	int i, j;
	struct ocb_config_chan *curr_chan;

	ENTER_DEV(dev);

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	rc = wlan_hdd_validate_context(hdd_ctx);
	if (0 != rc)
		return rc;

	rc = hdd_check_private_wext_control(hdd_ctx, info);
	if (0 != rc)
		return rc;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("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) {
		hdd_err("Failed to allocate memory!");
		return -ENOMEM;
	}

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

	/* Release all the mac addresses used for OCB */
	for (i = 0; i < adapter->ocb_mac_addr_count; i++) {
		wlan_hdd_release_intf_addr(hdd_ctx,
					   adapter->ocb_mac_address[i].bytes);
	}
	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 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) {
			qdf_copy_macaddr(&curr_chan->mac_address,
				     &adapter->mac_addr);
		} else {
			mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
			if (mac_addr == NULL) {
				hdd_err("Cannot obtain mac address");
				rc = -EINVAL;
				goto fail;
			}
			qdf_mem_copy(config->channels[
				     config->channel_count].mac_address.bytes,
				     mac_addr, sizeof(tSirMacAddr));
			/* Save the mac address to release later */
			qdf_mem_copy(adapter->ocb_mac_address[
				     adapter->ocb_mac_addr_count].bytes,
				     mac_addr, QDF_MAC_ADDR_SIZE);
			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) {
		hdd_err("Error while setting OCB config");
		goto fail;
	}

	rc = 0;

fail:
	qdf_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_ocb_config_channel(
	struct ocb_config_chan *dest,
	struct wlan_hdd_ocb_config_channel *src,
	uint32_t channel_count)
{
	uint32_t i;

	qdf_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;
		qdf_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
		 *  ocb_channel_param.max_pwr and min_pwr
		 *  are in 1/2 dB increments and
		 *  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)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *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;
	uint32_t channel_count, schedule_size;
	struct ocb_config *config;
	int rc = -EINVAL;
	uint8_t *mac_addr;

	ENTER_DEV(dev);

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("Device not in OCB mode!");
		return -EINVAL;
	}

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

	/* Get the number of channels in the schedule */
	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT]) {
		hdd_err("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]) {
		hdd_err("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. */
	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY]) {
		hdd_err("NDL_CHANNEL_ARRAY is not present");
		return -EINVAL;
	}
	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);

	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY]) {
		hdd_err("NDL_ACTIVE_STATE_ARRAY is not present");
		return -EINVAL;
	}
	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) {
		hdd_err("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) {
		hdd_err("No channel present");
		goto fail;
	}
	if (nla_len(channel_array) != channel_count *
	    sizeof(struct wlan_hdd_ocb_config_channel)) {
		hdd_err("CHANNEL_ARRAY is not the correct size");
		goto fail;
	}
	wlan_hdd_ocb_config_channel_to_ocb_config_channel(
	    config->channels, nla_data(channel_array), channel_count);

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

	/* Release all the mac addresses used for OCB */
	for (i = 0; i < adapter->ocb_mac_addr_count; i++) {
		wlan_hdd_release_intf_addr(hdd_ctx,
					   adapter->ocb_mac_address[i].bytes);
	}
	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) {
			qdf_copy_macaddr(&config->channels[i].mac_address,
				&adapter->mac_addr);
		} else {
			mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
			if (mac_addr == NULL) {
				hdd_err("Cannot obtain mac address");
				goto fail;
			}
			qdf_mem_copy(config->channels[i].mac_address.bytes,
				mac_addr, QDF_MAC_ADDR_SIZE);
			/* Save the mac address to release later */
			qdf_copy_macaddr(&adapter->ocb_mac_address[
				     adapter->ocb_mac_addr_count],
				     &config->channels[i].mac_address);
			adapter->ocb_mac_addr_count++;
		}
	}

	/* Read the schedule array */
	sched_array = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY];
	if (!sched_array) {
		hdd_err("No channel present");
		goto fail;
	}
	if (nla_len(sched_array) != schedule_size * sizeof(*config->schedule)) {
		hdd_err("SCHEDULE_ARRAY is not the correct size");
		goto fail;
	}
	qdf_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;
		qdf_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;
		qdf_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)
		hdd_err("Error while setting OCB config: %d", rc);

fail:
	qdf_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)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *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 ocb_utc_param *utc;
	int rc = -EINVAL;

	ENTER_DEV(dev);

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("Device not in OCB mode!");
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->session_id)) {
		hdd_err("The device has not been started");
		return -EINVAL;
	}

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

	/* Read the UTC time */
	utc_attr = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE];
	if (!utc_attr) {
		hdd_err("UTC_TIME is not present");
		return -EINVAL;
	}
	if (nla_len(utc_attr) != SIZE_UTC_TIME) {
		hdd_err("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) {
		hdd_err("UTC_TIME is not present");
		return -EINVAL;
	}
	if (nla_len(time_error_attr) != SIZE_UTC_TIME_ERROR) {
		hdd_err("UTC_TIME is not the correct size");
		return -EINVAL;
	}

	utc = qdf_mem_malloc(sizeof(*utc));
	if (!utc) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}
	utc->vdev_id = adapter->session_id;
	qdf_mem_copy(utc->utc_time, nla_data(utc_attr), SIZE_UTC_TIME);
	qdf_mem_copy(utc->time_error, nla_data(time_error_attr),
		SIZE_UTC_TIME_ERROR);

	if (ucfg_ocb_set_utc_time(adapter->hdd_vdev, utc) !=
			QDF_STATUS_SUCCESS) {
		hdd_err("Error while setting UTC time");
		rc = -EINVAL;
	} else {
		rc = 0;
	}

	qdf_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)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX + 1];
	struct ocb_timing_advert_param *timing_advert;
	int rc = -EINVAL;

	ENTER_DEV(dev);

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("Device not in OCB mode!");
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->session_id)) {
		hdd_err("The device has not been started");
		return -EINVAL;
	}

	timing_advert = qdf_mem_malloc(sizeof(*timing_advert));
	if (!timing_advert) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}
	timing_advert->vdev_id = adapter->session_id;

	/* Parse the netlink message */
	if (wlan_cfg80211_nla_parse(tb,
			      QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX,
			      data, data_len,
			      qca_wlan_vendor_ocb_start_timing_advert_policy)) {
		hdd_err("Invalid ATTR");
		goto fail;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ]) {
		hdd_err("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]) {
		hdd_err("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->mac_addr.bytes,
			&timing_advert->template_value,
			&timing_advert->timestamp_offset,
			&timing_advert->time_value_offset);
	if (timing_advert->template_length <= 0) {
		hdd_err("Error while generating the TA frame");
		goto fail;
	}

	if (ucfg_ocb_start_timing_advert(adapter->hdd_vdev, timing_advert) !=
			QDF_STATUS_SUCCESS) {
		hdd_err("Error while starting timing advert");
		rc = -EINVAL;
	} else {
		rc = 0;
	}

fail:
	if (timing_advert->template_value)
		qdf_mem_free(timing_advert->template_value);
	qdf_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)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX + 1];
	struct ocb_timing_advert_param *timing_advert;
	int rc = -EINVAL;

	ENTER_DEV(dev);

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("Device not in OCB mode!");
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->session_id)) {
		hdd_err("The device has not been started");
		return -EINVAL;
	}

	timing_advert = qdf_mem_malloc(sizeof(*timing_advert));
	if (!timing_advert) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}
	timing_advert->vdev_id = adapter->session_id;

	/* Parse the netlink message */
	if (wlan_cfg80211_nla_parse(tb,
			       QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX,
			       data, data_len,
			       qca_wlan_vendor_ocb_stop_timing_advert_policy)) {
		hdd_err("Invalid ATTR");
		goto fail;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ]) {
		hdd_err("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 (ucfg_ocb_stop_timing_advert(adapter->hdd_vdev, timing_advert) !=
			QDF_STATUS_SUCCESS) {
		hdd_err("Error while stopping timing advert");
		rc = -EINVAL;
	} else {
		rc = 0;
	}

fail:
	qdf_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;
}

struct hdd_ocb_get_tsf_timer_priv {
	struct ocb_get_tsf_timer_response response;
	int status;
};

/**
 * 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_request *hdd_request;
	struct hdd_ocb_get_tsf_timer_priv *priv;
	struct ocb_get_tsf_timer_response *response = response_ptr;

	hdd_request = hdd_request_get(context_ptr);
	if (!hdd_request) {
		hdd_err("Obsolete request");
		return;
	}

	priv = hdd_request_priv(hdd_request);
	if (response) {
		priv->response = *response;
		priv->status = 0;
	} else {
		priv->status = -EINVAL;
	}
	hdd_request_complete(hdd_request);
	hdd_request_put(hdd_request);
}

static int
hdd_ocb_get_tsf_timer_reply(struct wiphy *wiphy,
			    struct ocb_get_tsf_timer_response *response)
{
	uint32_t nl_buf_len;
	struct sk_buff *nl_resp;
	int rc;

	/* Allocate the buffer for the response. */
	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len += 2 * (NLA_HDRLEN + sizeof(uint32_t));
	nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, nl_buf_len);
	if (!nl_resp) {
		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
		return -ENOMEM;
	}

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

	/* Send the response. */
	rc = cfg80211_vendor_cmd_reply(nl_resp);
	nl_resp = NULL;
	if (rc) {
		hdd_err("cfg80211_vendor_cmd_reply failed: %d", rc);
		goto end;
	}
end:
	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.
 */
static int
__wlan_hdd_cfg80211_ocb_get_tsf_timer(struct wiphy *wiphy,
				      struct wireless_dev *wdev,
				      const void *data,
				      int data_len)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	int rc;
	struct ocb_get_tsf_timer_param request = {0};
	QDF_STATUS status;
	void *cookie;
	struct hdd_request *hdd_request;
	struct hdd_ocb_get_tsf_timer_priv *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
	};

	ENTER_DEV(dev);

	rc = wlan_hdd_validate_context(hdd_ctx);
	if (rc)
		return rc;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("Device not in OCB mode!");
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->session_id)) {
		hdd_err("The device has not been started");
		return -EINVAL;
	}

	hdd_request = hdd_request_alloc(&params);
	if (!hdd_request) {
		hdd_err("Request allocation failure");
		return -ENOMEM;
	}
	cookie = hdd_request_cookie(hdd_request);

	request.vdev_id = adapter->session_id;
	status = ucfg_ocb_get_tsf_timer(adapter->hdd_vdev, &request,
					hdd_ocb_get_tsf_timer_callback,
					cookie);
	if (QDF_IS_STATUS_ERROR(status)) {
		hdd_err("Failed to get tsf timer.");
		rc = qdf_status_to_os_return(status);
		goto end;
	}

	rc = hdd_request_wait_for_response(hdd_request);
	if (rc) {
		hdd_err("Operation timed out");
		goto end;
	}

	priv = hdd_request_priv(hdd_request);
	rc = priv->status;
	if (rc) {
		hdd_err("Operation failed: %d", rc);
		goto end;
	}

	hdd_debug("Got TSF timer response, high=%d, low=%d",
		priv->response.timer_high,
		priv->response.timer_low);

	/* Send the response. */
	rc = hdd_ocb_get_tsf_timer_reply(wiphy, &priv->response);
	if (rc) {
		hdd_err("hdd_ocb_get_tsf_timer_reply failed: %d", rc);
		goto end;
	}

	/* fall through */
end:
	hdd_request_put(hdd_request);

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

struct hdd_dcc_stats_priv {
	struct ocb_dcc_get_stats_response *response;
	int status;
};

static void hdd_dcc_get_stats_dealloc(void *context_ptr)
{
	struct hdd_dcc_stats_priv *priv = context_ptr;

	qdf_mem_free(priv->response);
	priv->response = NULL;
}

/**
 * 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_request *hdd_request;
	struct hdd_dcc_stats_priv *priv;
	struct ocb_dcc_get_stats_response *response = response_ptr;
	struct ocb_dcc_get_stats_response *hdd_resp;

	hdd_request = hdd_request_get(context_ptr);
	if (!hdd_request) {
		hdd_err("Obsolete request");
		return;
	}

	priv = hdd_request_priv(hdd_request);
	if (!response) {
		priv->status = -EINVAL;
		goto end;
	}

	priv->response = qdf_mem_malloc(sizeof(*response) +
					response->channel_stats_array_len);
	if (!priv->response) {
		priv->status = -ENOMEM;
		goto end;
	}

	hdd_resp = priv->response;
	*hdd_resp = *response;
	hdd_resp->channel_stats_array = (void *)hdd_resp + sizeof(*hdd_resp);
	qdf_mem_copy(hdd_resp->channel_stats_array,
		     response->channel_stats_array,
		     response->channel_stats_array_len);
	priv->status = 0;

end:
	hdd_request_complete(hdd_request);
	hdd_request_put(hdd_request);
}

static int
hdd_dcc_get_stats_send_reply(struct wiphy *wiphy,
			     struct ocb_dcc_get_stats_response *response)
{
	uint32_t nl_buf_len;
	struct sk_buff *nl_resp;
	int rc;

	/* Allocate the buffer for the response. */
	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len += NLA_HDRLEN + sizeof(uint32_t);
	nl_buf_len += NLA_HDRLEN + response->channel_stats_array_len;
	nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, nl_buf_len);
	if (!nl_resp) {
		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
		return -ENOMEM;
	}

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

	/* Send the response. */
	rc = cfg80211_vendor_cmd_reply(nl_resp);
	nl_resp = NULL;
	if (rc) {
		hdd_err("cfg80211_vendor_cmd_reply failed: %d", rc);
		goto end;
	}
end:
	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.
 */
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;
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_MAX + 1];
	int rc;
	struct ocb_dcc_get_stats_param request = {0};
	QDF_STATUS status;
	void *cookie;
	struct hdd_request *hdd_request;
	struct hdd_dcc_stats_priv *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
		.dealloc = hdd_dcc_get_stats_dealloc,
	};

	ENTER_DEV(dev);

	rc = wlan_hdd_validate_context(hdd_ctx);
	if (rc)
		return rc;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("Device not in OCB mode!");
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->session_id)) {
		hdd_err("The device has not been started");
		return -EINVAL;
	}

	/* Parse the netlink message */
	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_MAX,
				    data, data_len,
				    qca_wlan_vendor_dcc_get_stats)) {
		hdd_err("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]) {
		hdd_err("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]);

	hdd_request = hdd_request_alloc(&params);
	if (!hdd_request) {
		hdd_err("Request allocation failure");
		return -ENOMEM;
	}
	cookie = hdd_request_cookie(hdd_request);

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

	status = ucfg_ocb_dcc_get_stats(adapter->hdd_vdev, &request,
					hdd_dcc_get_stats_callback,
					cookie);
	if (QDF_IS_STATUS_ERROR(status)) {
		hdd_err("Failed to get DCC stats.");
		rc = qdf_status_to_os_return(status);
		goto end;
	}

	/* Wait for the function to complete. */
	rc = hdd_request_wait_for_response(hdd_request);
	if (rc) {
		hdd_err("Operation timed out");
		goto end;
	}

	priv = hdd_request_priv(hdd_request);
	rc = priv->status;
	if (rc) {
		hdd_err("Operation failed: %d", rc);
		goto end;
	}

	/* Send the response. */
	rc = hdd_dcc_get_stats_send_reply(wiphy, priv->response);
	if (rc) {
		hdd_err("hdd_dcc_get_stats_send_reply failed: %d", rc);
		goto end;
	}

	/* fall through */
end:
	hdd_request_put(hdd_request);

	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)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_MAX + 1];

	ENTER_DEV(dev);

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("Device not in OCB mode!");
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->session_id)) {
		hdd_err("The device has not been started");
		return -EINVAL;
	}

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

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

	if (ucfg_ocb_dcc_clear_stats(adapter->hdd_vdev, adapter->session_id,
		nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP])) !=
			QDF_STATUS_SUCCESS) {
		hdd_err("Failed to clear DCC stats.");
		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;
}

struct hdd_dcc_update_ndl_priv {
	int status;
};

/**
 * 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_request *hdd_request;
	struct hdd_dcc_update_ndl_priv *priv;
	struct ocb_dcc_update_ndl_response *response = response_ptr;

	hdd_request = hdd_request_get(context_ptr);
	if (!hdd_request) {
		hdd_err("Obsolete request");
		return;
	}
	priv = hdd_request_priv(hdd_request);
	if (response && (0 == response->status)) {
		priv->status = 0;
	} else {
		priv->status = -EINVAL;
	}
	hdd_request_complete(hdd_request);
	hdd_request_put(hdd_request);
}

/**
 * __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)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX + 1];
	struct ocb_dcc_update_ndl_param 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;
	QDF_STATUS status;
	void *cookie;
	struct hdd_request *hdd_request;
	struct hdd_dcc_update_ndl_priv *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
	};

	ENTER_DEV(dev);

	rc = wlan_hdd_validate_context(hdd_ctx);
	if (rc)
		return rc;

	if (adapter->device_mode != QDF_OCB_MODE) {
		hdd_err("Device not in OCB mode!");
		return -EINVAL;
	}

	if (!wma_is_vdev_up(adapter->session_id)) {
		hdd_err("The device has not been started");
		return -EINVAL;
	}

	/* Parse the netlink message */
	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX,
				    data, data_len,
				    qca_wlan_vendor_dcc_update_ndl)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	/* 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]) {
		hdd_err("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]);

	hdd_request = hdd_request_alloc(&params);
	if (!hdd_request) {
		hdd_err("Request allocation failure");
		return -ENOMEM;
	}
	cookie = hdd_request_cookie(hdd_request);

	/* Copy the parameters to the request structure. */
	request.vdev_id = adapter->session_id;
	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;

	status = ucfg_ocb_dcc_update_ndl(adapter->hdd_vdev, &request,
					 hdd_dcc_update_ndl_callback,
					 cookie);
	if (QDF_IS_STATUS_ERROR(status)) {
		hdd_err("Failed to update NDL.");
		rc = qdf_status_to_os_return(status);
		goto end;
	}

	/* Wait for the function to complete. */
	rc = hdd_request_wait_for_response(hdd_request);
	if (rc) {
		hdd_err("Operation timed out");
		goto end;
	}

	priv = hdd_request_priv(hdd_request);
	rc = priv->status;
	if (rc) {
		hdd_err("Operation failed: %d", rc);
		goto end;
	}

	/* fall through */
end:
	hdd_request_put(hdd_request);

	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)
{
	struct hdd_context *hdd_ctx = (struct hdd_context *)context_ptr;
	struct ocb_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) {
		hdd_err("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)) {
		hdd_err("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(struct hdd_context *hdd_ctx)
{
	int rc;

	rc = ucfg_ocb_register_for_dcc_stats_event(hdd_ctx->hdd_pdev, hdd_ctx,
				      wlan_hdd_dcc_stats_event_callback);
	if (rc)
		hdd_err("Register DCC stats callback failed: %d", rc);
}
