Bladeren bron

qcacmn: Featurize WMI APIs and TLVs that are specific to MCL

In the existing converged component, WMI TLV APIs are implemented in
a generic manner without proper featurization. All the APIs exposed
outside of WMI are implemented in wmi_unified_api.c and all the APIs
forming the CMD or extracting the EVT is implemented in wmi_unified_tlv.c.
Since WIN and MCL have a unified WMI layer in the converged component and
there are features within WIN and MCL that are not common, there exists a
good number of WMI APIs which are specific to WIN but compiled by MCL and
vice-versa. Due to this inadvertent problem, there is a chunk of code and
memory used up by WIN and MCL for features that are not used in their
products.
Featurize WMI APIs and TLVs that are specific to MCL -
- DSRC
- NAN
- P2P
- PMO
- roaming
- concurrency
- STA
- Generic MCL specific WMI (STA)

Change-Id: I03a68b0db30a3aa585b269ab0a1745b37bc7e0b7
CRs-Fixed: 2316935
Qiwei Cai 6 jaren geleden
bovenliggende
commit
3d26b2ee7d

File diff suppressed because it is too large
+ 194 - 1593
wmi_unified_api.c


+ 65 - 0
wmi_unified_concurrency_api.c

@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+/**
+ * DOC: Implement API's specific to concurrency component.
+ */
+
+#include <wmi_unified_priv.h>
+#include <wmi_unified_concurrency_api.h>
+
+QDF_STATUS wmi_unified_set_enable_disable_mcc_adaptive_scheduler_cmd(
+		void *wmi_hdl, uint32_t mcc_adaptive_scheduler,
+		uint32_t pdev_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_enable_disable_mcc_adaptive_scheduler_cmd)
+		return wmi_handle->ops->send_set_enable_disable_mcc_adaptive_scheduler_cmd(wmi_handle,
+					mcc_adaptive_scheduler, pdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_mcc_channel_time_latency_cmd(void *wmi_hdl,
+	uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_mcc_channel_time_latency_cmd)
+		return wmi_handle->ops->send_set_mcc_channel_time_latency_cmd(wmi_handle,
+					mcc_channel_freq,
+					mcc_channel_time_latency);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_mcc_channel_time_quota_cmd(void *wmi_hdl,
+			 uint32_t adapter_1_chan_freq,
+			 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_mcc_channel_time_quota_cmd)
+		return wmi_handle->ops->send_set_mcc_channel_time_quota_cmd(wmi_handle,
+						adapter_1_chan_freq,
+						adapter_1_quota,
+						adapter_2_chan_freq);
+
+	return QDF_STATUS_E_FAILURE;
+}
+

+ 242 - 0
wmi_unified_concurrency_tlv.c

@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <osdep.h>
+#include <wmi.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_concurrency_api.h>
+
+/**
+ * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable
+ *							     mcc scheduler
+ * @wmi_handle: wmi handle
+ * @mcc_adaptive_scheduler: enable/disable
+ *
+ * This function enable/disable mcc adaptive scheduler in fw.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv(
+		wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler,
+		uint32_t pdev_id)
+{
+	QDF_STATUS ret;
+	wmi_buf_t buf = 0;
+	wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL;
+	uint16_t len =
+		sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *)
+		wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param));
+	cmd->enable = mcc_adaptive_scheduler;
+	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
+
+	wmi_mtrace(WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGP("%s: Failed to send enable/disable MCC"
+			 " adaptive scheduler command", __func__);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency
+ * @wmi: wmi handle
+ * @mcc_channel: mcc channel
+ * @mcc_channel_time_latency: MCC channel time latency.
+ *
+ * Currently used to set time latency for an MCC vdev/adapter using operating
+ * channel of it and channel number. The info is provided run time using
+ * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(
+					wmi_unified_t wmi_handle,
+					uint32_t mcc_channel_freq,
+					uint32_t mcc_channel_time_latency)
+{
+	QDF_STATUS ret;
+	wmi_buf_t buf = 0;
+	wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL;
+	uint16_t len = 0;
+	uint8_t *buf_ptr = NULL;
+	wmi_resmgr_chan_latency chan_latency;
+	/* Note: we only support MCC time latency for a single channel */
+	uint32_t num_channels = 1;
+	uint32_t chan1_freq = mcc_channel_freq;
+	uint32_t latency_chan1 = mcc_channel_time_latency;
+
+	/* If 0ms latency is provided, then FW will set to a default.
+	 * Otherwise, latency must be at least 30ms.
+	 */
+	if ((latency_chan1 > 0) &&
+	    (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) {
+		WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms "
+			 "Minimum is 30ms (or 0 to use default value by "
+			 "firmware)", __func__, latency_chan1);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/*   Set WMI CMD for channel time latency here */
+	len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) +
+	      WMI_TLV_HDR_SIZE +  /*Place holder for chan_time_latency array */
+	      num_channels * sizeof(wmi_resmgr_chan_latency);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *)
+		wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmdTL->tlv_header,
+		WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_resmgr_set_chan_latency_cmd_fixed_param));
+	cmdTL->num_chans = num_channels;
+	/* Update channel time latency information for home channel(s) */
+	buf_ptr += sizeof(*cmdTL);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       num_channels * sizeof(wmi_resmgr_chan_latency));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	chan_latency.chan_mhz = chan1_freq;
+	chan_latency.latency = latency_chan1;
+	qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency));
+	wmi_mtrace(WMI_RESMGR_SET_CHAN_LATENCY_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_RESMGR_SET_CHAN_LATENCY_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("%s: Failed to send MCC Channel Time Latency command",
+			 __func__);
+		wmi_buf_free(buf);
+		QDF_ASSERT(0);
+	}
+
+	return ret;
+}
+
+/**
+ * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota
+ * @wmi: wmi handle
+ * @adapter_1_chan_number: adapter 1 channel number
+ * @adapter_1_quota: adapter 1 quota
+ * @adapter_2_chan_number: adapter 2 channel number
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(
+					wmi_unified_t wmi_handle,
+					uint32_t adapter_1_chan_freq,
+					uint32_t adapter_1_quota,
+					uint32_t adapter_2_chan_freq)
+{
+	QDF_STATUS ret;
+	wmi_buf_t buf = 0;
+	uint16_t len = 0;
+	uint8_t *buf_ptr = NULL;
+	wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL;
+	wmi_resmgr_chan_time_quota chan_quota;
+	uint32_t quota_chan1 = adapter_1_quota;
+	/* Knowing quota of 1st chan., derive quota for 2nd chan. */
+	uint32_t quota_chan2 = 100 - quota_chan1;
+	/* Note: setting time quota for MCC requires info for 2 channels */
+	uint32_t num_channels = 2;
+	uint32_t chan1_freq = adapter_1_chan_freq;
+	uint32_t chan2_freq = adapter_2_chan_freq;
+
+	WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, "
+		 "freq2:%dMHz, Quota2:%dms", __func__,
+		 chan1_freq, quota_chan1, chan2_freq,
+		 quota_chan2);
+
+	/*
+	 * Perform sanity check on time quota values provided.
+	 */
+	if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA ||
+	    quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) {
+		WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum "
+			 "is 20ms & maximum is 80ms", __func__, quota_chan1);
+		return QDF_STATUS_E_INVAL;
+	}
+	/* Set WMI CMD for channel time quota here */
+	len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) +
+	      WMI_TLV_HDR_SIZE +       /* Place holder for chan_time_quota array */
+	      num_channels * sizeof(wmi_resmgr_chan_time_quota);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *)
+		wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmdTQ->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_resmgr_set_chan_time_quota_cmd_fixed_param));
+	cmdTQ->num_chans = num_channels;
+
+	/* Update channel time quota information for home channel(s) */
+	buf_ptr += sizeof(*cmdTQ);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       num_channels * sizeof(wmi_resmgr_chan_time_quota));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	chan_quota.chan_mhz = chan1_freq;
+	chan_quota.channel_time_quota = quota_chan1;
+	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
+	/* Construct channel and quota record for the 2nd MCC mode. */
+	buf_ptr += sizeof(chan_quota);
+	chan_quota.chan_mhz = chan2_freq;
+	chan_quota.channel_time_quota = quota_chan2;
+	qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
+
+	wmi_mtrace(WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to send MCC Channel Time Quota command");
+		wmi_buf_free(buf);
+		QDF_ASSERT(0);
+	}
+
+	return ret;
+}
+
+void wmi_concurrency_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_enable_disable_mcc_adaptive_scheduler_cmd =
+		send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv;
+	ops->send_set_mcc_channel_time_latency_cmd =
+		send_set_mcc_channel_time_latency_cmd_tlv;
+	ops->send_set_mcc_channel_time_quota_cmd =
+		send_set_mcc_channel_time_quota_cmd_tlv;
+}

+ 131 - 0
wmi_unified_nan_api.c

@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+/**
+ * DOC: Implement API's specific to NAN component.
+ */
+
+#include <wmi_unified_priv.h>
+#include <wmi_unified_nan_api.h>
+
+QDF_STATUS wmi_unified_ndp_initiator_req_cmd_send(void *wmi_hdl,
+					struct nan_datapath_initiator_req *req)
+{
+	wmi_unified_t wmi_handle = wmi_hdl;
+
+	if (wmi_handle->ops->send_ndp_initiator_req_cmd)
+		return wmi_handle->ops->send_ndp_initiator_req_cmd(wmi_handle,
+								   req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_ndp_responder_req_cmd_send(void *wmi_hdl,
+				struct nan_datapath_responder_req *req)
+{
+	wmi_unified_t wmi_handle = wmi_hdl;
+
+	if (wmi_handle->ops->send_ndp_responder_req_cmd)
+		return wmi_handle->ops->send_ndp_responder_req_cmd(wmi_handle,
+								   req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_ndp_end_req_cmd_send(void *wmi_hdl,
+					    struct nan_datapath_end_req *req)
+{
+	wmi_unified_t wmi_handle = wmi_hdl;
+
+	if (wmi_handle->ops->send_ndp_end_req_cmd)
+		return wmi_handle->ops->send_ndp_end_req_cmd(wmi_handle,
+							     req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_ndp_initiator_rsp(wmi_unified_t wmi_handle,
+			uint8_t *data, struct nan_datapath_initiator_rsp *rsp)
+{
+	if (wmi_handle->ops->extract_ndp_initiator_rsp)
+		return wmi_handle->ops->extract_ndp_initiator_rsp(wmi_handle,
+								  data, rsp);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_ndp_ind(wmi_unified_t wmi_handle, uint8_t *data,
+			       struct nan_datapath_indication_event *ind)
+{
+	if (wmi_handle->ops->extract_ndp_ind)
+		return wmi_handle->ops->extract_ndp_ind(wmi_handle,
+							data, ind);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_ndp_confirm(wmi_unified_t wmi_handle, uint8_t *data,
+				   struct nan_datapath_confirm_event *ev)
+{
+	if (wmi_handle->ops->extract_ndp_confirm)
+		return wmi_handle->ops->extract_ndp_confirm(wmi_handle,
+							    data, ev);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_ndp_responder_rsp(wmi_unified_t wmi_handle,
+					 uint8_t *data,
+					 struct nan_datapath_responder_rsp *rsp)
+{
+	if (wmi_handle->ops->extract_ndp_responder_rsp)
+		return wmi_handle->ops->extract_ndp_responder_rsp(wmi_handle,
+								  data, rsp);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_ndp_end_rsp(wmi_unified_t wmi_handle, uint8_t *data,
+				   struct nan_datapath_end_rsp_event *rsp)
+{
+	if (wmi_handle->ops->extract_ndp_end_rsp)
+		return wmi_handle->ops->extract_ndp_end_rsp(wmi_handle,
+							    data, rsp);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_ndp_end_ind(wmi_unified_t wmi_handle, uint8_t *data,
+				struct nan_datapath_end_indication_event **ind)
+{
+	if (wmi_handle->ops->extract_ndp_end_ind)
+		return wmi_handle->ops->extract_ndp_end_ind(wmi_handle,
+							    data, ind);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_ndp_sch_update(wmi_unified_t wmi_handle, uint8_t *data,
+				    struct nan_datapath_sch_update_event *ind)
+{
+	if (wmi_handle->ops->extract_ndp_sch_update)
+		return wmi_handle->ops->extract_ndp_sch_update(wmi_handle,
+							       data, ind);
+
+	return QDF_STATUS_E_FAILURE;
+}
+

+ 859 - 0
wmi_unified_nan_tlv.c

@@ -0,0 +1,859 @@
+
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <osdep.h>
+#include <wmi.h>
+#include <wmi_unified_priv.h>
+#include <nan_public_structs.h>
+#include <wmi_unified_nan_api.h>
+
+static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle,
+				struct nan_datapath_initiator_req *ndp_req)
+{
+	uint16_t len;
+	wmi_buf_t buf;
+	uint8_t *tlv_ptr;
+	QDF_STATUS status;
+	wmi_channel *ch_tlv;
+	wmi_ndp_initiator_req_fixed_param *cmd;
+	uint32_t passphrase_len, service_name_len;
+	uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len;
+	wmi_ndp_transport_ip_param *tcp_ip_param;
+
+	/*
+	 * WMI command expects 4 byte alligned len:
+	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
+	 */
+	ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4);
+	ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4);
+	pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4);
+	passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4);
+	service_name_len =
+		   qdf_roundup(ndp_req->service_name.service_name_len, 4);
+	/* allocated memory for fixed params as well as variable size data */
+	len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE)
+		+ ndp_cfg_len + ndp_app_info_len + pmk_len
+		+ passphrase_len + service_name_len;
+
+	if (ndp_req->is_ipv6_addr_present)
+		len += sizeof(*tcp_ip_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				wmi_ndp_initiator_req_fixed_param));
+	cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev);
+	cmd->transaction_id = ndp_req->transaction_id;
+	cmd->service_instance_id = ndp_req->service_instance_id;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes,
+				   &cmd->peer_discovery_mac_addr);
+
+	cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len;
+	cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len;
+	cmd->ndp_channel_cfg = ndp_req->channel_cfg;
+	cmd->nan_pmk_len = ndp_req->pmk.pmk_len;
+	cmd->nan_csid = ndp_req->ncs_sk_type;
+	cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len;
+	cmd->nan_servicename_len = ndp_req->service_name.service_name_len;
+
+	ch_tlv = (wmi_channel *)&cmd[1];
+	WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
+	ch_tlv->mhz = ndp_req->channel;
+	tlv_ptr = (uint8_t *)&ch_tlv[1];
+
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
+		     ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
+
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
+		     ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len);
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
+
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk,
+		     cmd->nan_pmk_len);
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
+
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase,
+		     cmd->nan_passphrase_len);
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
+
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
+		     ndp_req->service_name.service_name,
+		     cmd->nan_servicename_len);
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
+
+	if (ndp_req->is_ipv6_addr_present) {
+		tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr;
+		WMITLV_SET_HDR(tcp_ip_param,
+			       WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param,
+			       WMITLV_GET_STRUCT_TLVLEN(
+						wmi_ndp_transport_ip_param));
+		tcp_ip_param->ipv6_addr_present = true;
+		qdf_mem_copy(tcp_ip_param->ipv6_intf_addr,
+			     ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN);
+	}
+	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
+		 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr);
+
+	WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d",
+		 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id,
+		 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid);
+	WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x",
+		 cmd->peer_discovery_mac_addr.mac_addr31to0,
+		 cmd->peer_discovery_mac_addr.mac_addr47to32);
+
+	WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   ndp_req->ndp_config.ndp_cfg,
+			   ndp_req->ndp_config.ndp_cfg_len);
+
+	WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   ndp_req->ndp_info.ndp_app_info,
+			   ndp_req->ndp_info.ndp_app_info_len);
+
+	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   ndp_req->pmk.pmk, cmd->nan_pmk_len);
+
+	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   ndp_req->passphrase.passphrase,
+			   cmd->nan_passphrase_len);
+
+	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   ndp_req->service_name.service_name,
+			   cmd->nan_servicename_len);
+
+	WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)",
+		 WMI_NDP_INITIATOR_REQ_CMDID);
+
+	wmi_mtrace(WMI_NDP_INITIATOR_REQ_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_NDP_INITIATOR_REQ_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle,
+					struct nan_datapath_responder_req *req)
+{
+	uint16_t len;
+	wmi_buf_t buf;
+	uint8_t *tlv_ptr;
+	QDF_STATUS status;
+	wmi_ndp_responder_req_fixed_param *cmd;
+	wmi_ndp_transport_ip_param *tcp_ip_param;
+	uint32_t passphrase_len, service_name_len;
+	uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len;
+
+	vdev_id = wlan_vdev_get_id(req->vdev);
+	WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d",
+		 vdev_id, req->transaction_id,
+		 req->ndp_rsp,
+		 req->ndp_instance_id,
+		 req->ndp_info.ndp_app_info_len);
+
+	/*
+	 * WMI command expects 4 byte alligned len:
+	 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes
+	 */
+	ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4);
+	ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4);
+	pmk_len = qdf_roundup(req->pmk.pmk_len, 4);
+	passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4);
+	service_name_len =
+		qdf_roundup(req->service_name.service_name_len, 4);
+
+	/* allocated memory for fixed params as well as variable size data */
+	len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len
+		+ pmk_len + passphrase_len + service_name_len;
+
+	if (req->is_ipv6_addr_present || req->is_port_present ||
+	    req->is_protocol_present)
+		len += sizeof(*tcp_ip_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				wmi_ndp_responder_req_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->transaction_id = req->transaction_id;
+	cmd->ndp_instance_id = req->ndp_instance_id;
+	cmd->rsp_code = req->ndp_rsp;
+	cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len;
+	cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len;
+	cmd->nan_pmk_len = req->pmk.pmk_len;
+	cmd->nan_csid = req->ncs_sk_type;
+	cmd->nan_passphrase_len = req->passphrase.passphrase_len;
+	cmd->nan_servicename_len = req->service_name.service_name_len;
+
+	tlv_ptr = (uint8_t *)&cmd[1];
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
+		     req->ndp_config.ndp_cfg, cmd->ndp_cfg_len);
+
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len;
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
+		     req->ndp_info.ndp_app_info,
+		     req->ndp_info.ndp_app_info_len);
+
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len;
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk,
+		     cmd->nan_pmk_len);
+
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len;
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
+		     req->passphrase.passphrase,
+		     cmd->nan_passphrase_len);
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len;
+
+	WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len);
+	qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE],
+		     req->service_name.service_name,
+		     cmd->nan_servicename_len);
+
+	tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len;
+
+	if (req->is_ipv6_addr_present || req->is_port_present ||
+	    req->is_protocol_present) {
+		tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr;
+		WMITLV_SET_HDR(tcp_ip_param,
+			       WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param,
+			       WMITLV_GET_STRUCT_TLVLEN(
+						wmi_ndp_transport_ip_param));
+		tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present;
+		qdf_mem_copy(tcp_ip_param->ipv6_intf_addr,
+			     req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN);
+
+		tcp_ip_param->trans_port_present = req->is_port_present;
+		tcp_ip_param->transport_port = req->port;
+
+		tcp_ip_param->trans_proto_present = req->is_protocol_present;
+		tcp_ip_param->transport_protocol = req->protocol;
+	}
+	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
+		 req->is_ipv6_addr_present, req->ipv6_addr);
+	WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port);
+	WMI_LOGD(FL("protocol: %d present: %d"),
+		 req->is_protocol_present, req->protocol);
+
+	WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d",
+		 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid);
+
+	WMI_LOGD("ndp_config len: %d",
+		 req->ndp_config.ndp_cfg_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   req->ndp_config.ndp_cfg,
+			   req->ndp_config.ndp_cfg_len);
+
+	WMI_LOGD("ndp_app_info len: %d",
+		 req->ndp_info.ndp_app_info_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   req->ndp_info.ndp_app_info,
+			   req->ndp_info.ndp_app_info_len);
+
+	WMI_LOGD("pmk len: %d", cmd->nan_pmk_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   req->pmk.pmk, cmd->nan_pmk_len);
+
+	WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   req->passphrase.passphrase,
+			   cmd->nan_passphrase_len);
+
+	WMI_LOGD("service name len: %d", cmd->nan_servicename_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   req->service_name.service_name,
+			   cmd->nan_servicename_len);
+
+	WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)",
+		 WMI_NDP_RESPONDER_REQ_CMDID);
+	wmi_mtrace(WMI_NDP_RESPONDER_REQ_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_NDP_RESPONDER_REQ_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status);
+		wmi_buf_free(buf);
+	}
+	return status;
+}
+
+static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle,
+				      struct nan_datapath_end_req *req)
+{
+	uint16_t len;
+	wmi_buf_t buf;
+	QDF_STATUS status;
+	uint32_t ndp_end_req_len, i;
+	wmi_ndp_end_req *ndp_end_req_lst;
+	wmi_ndp_end_req_fixed_param *cmd;
+
+	/* len of tlv following fixed param  */
+	ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances;
+	/* above comes out to 4 byte alligned already, no need of padding */
+	len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param));
+
+	cmd->transaction_id = req->transaction_id;
+
+	/* set tlv pointer to end of fixed param */
+	WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC,
+			ndp_end_req_len);
+
+	ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] +
+						WMI_TLV_HDR_SIZE);
+	for (i = 0; i < req->num_ndp_instances; i++) {
+		WMITLV_SET_HDR(&ndp_end_req_lst[i],
+			       WMITLV_TAG_ARRAY_FIXED_STRUC,
+			       (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE));
+
+		ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i];
+	}
+
+	WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW");
+	wmi_mtrace(WMI_NDP_END_REQ_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_NDP_END_REQ_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle,
+			uint8_t *data, struct nan_datapath_initiator_rsp *rsp)
+{
+	WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event;
+	wmi_ndp_initiator_rsp_event_fixed_param  *fixed_params;
+
+	event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data;
+	fixed_params = event->fixed_param;
+
+	rsp->vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
+						     fixed_params->vdev_id,
+						     WLAN_NAN_ID);
+	if (!rsp->vdev) {
+		WMI_LOGE("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rsp->transaction_id = fixed_params->transaction_id;
+	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
+	rsp->status = fixed_params->rsp_status;
+	rsp->reason = fixed_params->reason_code;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle,
+		uint8_t *data, struct nan_datapath_indication_event *rsp)
+{
+	WMI_NDP_INDICATION_EVENTID_param_tlvs *event;
+	wmi_ndp_indication_event_fixed_param *fixed_params;
+	size_t total_array_len;
+
+	event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data;
+	fixed_params =
+		(wmi_ndp_indication_event_fixed_param *)event->fixed_param;
+
+	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
+		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
+			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
+		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
+			 fixed_params->ndp_app_info_len,
+			 event->num_ndp_app_info);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (fixed_params->ndp_cfg_len >
+		(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
+		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
+			 __func__, fixed_params->ndp_cfg_len);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	total_array_len = fixed_params->ndp_cfg_len +
+					sizeof(*fixed_params);
+
+	if (fixed_params->ndp_app_info_len >
+		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
+		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
+			 __func__, fixed_params->ndp_app_info_len);
+		return QDF_STATUS_E_INVAL;
+	}
+	total_array_len += fixed_params->ndp_app_info_len;
+
+	if (fixed_params->nan_scid_len >
+		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
+		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
+			 __func__, fixed_params->nan_scid_len);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rsp->vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
+						     fixed_params->vdev_id,
+						     WLAN_NAN_ID);
+	if (!rsp->vdev) {
+		WMI_LOGE("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	rsp->service_instance_id = fixed_params->service_instance_id;
+	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
+	rsp->role = fixed_params->self_ndp_role;
+	rsp->policy = fixed_params->accept_policy;
+
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
+				rsp->peer_mac_addr.bytes);
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr,
+				rsp->peer_discovery_mac_addr.bytes);
+
+	WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n"
+		"service_instance %d, ndp_instance %d, role %d, policy %d,\n"
+		"csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM",
+		 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id,
+		 fixed_params->service_instance_id,
+		 fixed_params->ndp_instance_id, fixed_params->self_ndp_role,
+		 fixed_params->accept_policy,
+		 fixed_params->nan_csid, fixed_params->nan_scid_len,
+		 rsp->peer_mac_addr.bytes,
+		 rsp->peer_discovery_mac_addr.bytes);
+
+	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   &event->ndp_cfg, fixed_params->ndp_cfg_len);
+
+	WMI_LOGD("ndp_app_info - %d bytes",
+		 fixed_params->ndp_app_info_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			&event->ndp_app_info, fixed_params->ndp_app_info_len);
+
+	rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len;
+	rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
+	rsp->ncs_sk_type = fixed_params->nan_csid;
+	rsp->scid.scid_len = fixed_params->nan_scid_len;
+
+	if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN)
+		rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN;
+	qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg,
+		     rsp->ndp_config.ndp_cfg_len);
+
+	if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN)
+		rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN;
+	qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
+		     rsp->ndp_info.ndp_app_info_len);
+
+	if (rsp->scid.scid_len > NDP_SCID_BUF_LEN)
+		rsp->scid.scid_len = NDP_SCID_BUF_LEN;
+	qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len);
+
+	if (event->ndp_transport_ip_param &&
+	    event->num_ndp_transport_ip_param) {
+		if (event->ndp_transport_ip_param->ipv6_addr_present) {
+			rsp->is_ipv6_addr_present = true;
+			qdf_mem_copy(rsp->ipv6_addr,
+				event->ndp_transport_ip_param->ipv6_intf_addr,
+				WMI_NDP_IPV6_INTF_ADDR_LEN);
+		}
+	}
+	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
+		    rsp->is_ipv6_addr_present, rsp->ipv6_addr);
+
+	WMI_LOGD("scid hex dump:");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   rsp->scid.scid, rsp->scid.scid_len);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle,
+			uint8_t *data, struct nan_datapath_confirm_event *rsp)
+{
+	uint8_t i;
+	WMI_HOST_WLAN_PHY_MODE ch_mode;
+	WMI_NDP_CONFIRM_EVENTID_param_tlvs *event;
+	wmi_ndp_confirm_event_fixed_param *fixed_params;
+	size_t total_array_len;
+
+	event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data;
+	fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param;
+	WMI_LOGD("WMI_NDP_CONFIRM_EVENTID(0x%X) received. vdev %d, ndp_instance %d, rsp_code %d, reason_code: %d, num_active_ndps_on_peer: %d",
+		 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id,
+		 fixed_params->ndp_instance_id, fixed_params->rsp_code,
+		 fixed_params->reason_code,
+		 fixed_params->num_active_ndps_on_peer);
+	WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels);
+
+	if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) {
+		WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d",
+			 fixed_params->ndp_cfg_len, event->num_ndp_cfg);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len);
+
+	if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) {
+		WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d",
+			 fixed_params->ndp_app_info_len,
+			 event->num_ndp_app_info);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMI_LOGD("ndp_app_info - %d bytes",
+		 fixed_params->ndp_app_info_len);
+
+	if (fixed_params->ndp_cfg_len >
+			(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
+		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
+			 __func__, fixed_params->ndp_cfg_len);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	total_array_len = fixed_params->ndp_cfg_len +
+				sizeof(*fixed_params);
+
+	if (fixed_params->ndp_app_info_len >
+		(WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
+		WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
+			 __func__, fixed_params->ndp_app_info_len);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (fixed_params->num_ndp_channels > event->num_ndp_channel_list ||
+	    fixed_params->num_ndp_channels > event->num_nss_list) {
+		WMI_LOGE(FL("NDP Ch count %d greater than NDP Ch TLV len (%d) or NSS TLV len (%d)"),
+			 fixed_params->num_ndp_channels,
+			 event->num_ndp_channel_list,
+			 event->num_nss_list);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rsp->vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
+						     fixed_params->vdev_id,
+						     WLAN_NAN_ID);
+	if (!rsp->vdev) {
+		WMI_LOGE("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	rsp->ndp_instance_id = fixed_params->ndp_instance_id;
+	rsp->rsp_code = fixed_params->rsp_code;
+	rsp->reason_code = fixed_params->reason_code;
+	rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer;
+	rsp->num_channels = fixed_params->num_ndp_channels;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
+				   rsp->peer_ndi_mac_addr.bytes);
+	rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
+	qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
+		     rsp->ndp_info.ndp_app_info_len);
+
+	if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) {
+		WMI_LOGE(FL("too many channels"));
+		rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS;
+	}
+
+	for (i = 0; i < rsp->num_channels; i++) {
+		rsp->ch[i].channel = event->ndp_channel_list[i].mhz;
+		rsp->ch[i].nss = event->nss_list[i];
+		ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]);
+		rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle,
+								     ch_mode);
+		WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"),
+			 rsp->ch[i].channel,
+			 rsp->ch[i].ch_width,
+			 rsp->ch[i].nss);
+	}
+
+	if (event->ndp_transport_ip_param &&
+	    event->num_ndp_transport_ip_param) {
+		if (event->ndp_transport_ip_param->ipv6_addr_present) {
+			rsp->is_ipv6_addr_present = true;
+			qdf_mem_copy(rsp->ipv6_addr,
+				event->ndp_transport_ip_param->ipv6_intf_addr,
+				WMI_NDP_IPV6_INTF_ADDR_LEN);
+		}
+
+		if (event->ndp_transport_ip_param->trans_port_present) {
+			rsp->is_port_present = true;
+			rsp->port =
+			    event->ndp_transport_ip_param->transport_port;
+		}
+
+		if (event->ndp_transport_ip_param->trans_proto_present) {
+			rsp->is_protocol_present = true;
+			rsp->protocol =
+			    event->ndp_transport_ip_param->transport_protocol;
+		}
+	}
+	WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"),
+		 rsp->is_ipv6_addr_present, rsp->ipv6_addr);
+	WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present);
+	WMI_LOGD(FL("protocol: %d present: %d"),
+		 rsp->protocol, rsp->is_protocol_present);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle,
+			uint8_t *data, struct nan_datapath_responder_rsp *rsp)
+{
+	WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event;
+	wmi_ndp_responder_rsp_event_fixed_param  *fixed_params;
+
+	event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data;
+	fixed_params = event->fixed_param;
+
+	WMI_LOGD("WMI_NDP_RESPONDER_RSP_EVENTID(0x%X) received. vdev_id: %d, peer_mac_addr: %pM,transaction_id: %d, status_code %d, reason_code: %d, create_peer: %d",
+		 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id,
+		 rsp->peer_mac_addr.bytes, rsp->transaction_id,
+		 rsp->status, rsp->reason, rsp->create_peer);
+
+	rsp->vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
+						     fixed_params->vdev_id,
+						     WLAN_NAN_ID);
+	if (!rsp->vdev) {
+		WMI_LOGE("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	rsp->transaction_id = fixed_params->transaction_id;
+	rsp->reason = fixed_params->reason_code;
+	rsp->status = fixed_params->rsp_status;
+	rsp->create_peer = fixed_params->create_peer;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
+				   rsp->peer_mac_addr.bytes);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle,
+			uint8_t *data, struct nan_datapath_end_rsp_event *rsp)
+{
+	WMI_NDP_END_RSP_EVENTID_param_tlvs *event;
+	wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL;
+
+	event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data;
+	fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param;
+	WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d",
+		 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id,
+		 fixed_params->rsp_status, fixed_params->reason_code);
+
+	rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
+			wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
+	if (!rsp->vdev) {
+		WMI_LOGE("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	rsp->transaction_id = fixed_params->transaction_id;
+	rsp->reason = fixed_params->reason_code;
+	rsp->status = fixed_params->rsp_status;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle,
+		uint8_t *data, struct nan_datapath_end_indication_event **rsp)
+{
+	uint32_t i, buf_size;
+	wmi_ndp_end_indication *ind;
+	struct qdf_mac_addr peer_addr;
+	WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event;
+
+	event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data;
+	ind = event->ndp_end_indication_list;
+
+	if (event->num_ndp_end_indication_list == 0) {
+		WMI_LOGE("Error: Event ignored, 0 ndp instances");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMI_LOGD("number of ndp instances = %d",
+		 event->num_ndp_end_indication_list);
+
+	if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/
+						sizeof((*rsp)->ndp_map[0]))) {
+		WMI_LOGE("num_ndp_end_ind_list %d too large",
+			 event->num_ndp_end_indication_list);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list *
+			sizeof((*rsp)->ndp_map[0]);
+	*rsp = qdf_mem_malloc(buf_size);
+	if (!(*rsp)) {
+		WMI_LOGE("Failed to allocate memory");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	(*rsp)->num_ndp_ids = event->num_ndp_end_indication_list;
+	for (i = 0; i < (*rsp)->num_ndp_ids; i++) {
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
+					   peer_addr.bytes);
+		WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ",
+			 i, ind[i].type, ind[i].reason_code,
+			 ind[i].ndp_instance_id,
+			 ind[i].num_active_ndps_on_peer);
+		/* Add each instance entry to the list */
+		(*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id;
+		(*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id;
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
+			(*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes);
+		(*rsp)->ndp_map[i].num_active_ndp_sessions =
+			ind[i].num_active_ndps_on_peer;
+		(*rsp)->ndp_map[i].type = ind[i].type;
+		(*rsp)->ndp_map[i].reason_code = ind[i].reason_code;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle,
+		uint8_t *data, struct nan_datapath_sch_update_event *ind)
+{
+	uint8_t i;
+	WMI_HOST_WLAN_PHY_MODE ch_mode;
+	WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event;
+	wmi_ndl_schedule_update_fixed_param *fixed_params;
+
+	event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data;
+	fixed_params = event->fixed_param;
+
+	WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"),
+		 fixed_params->flags, fixed_params->num_channels,
+		 fixed_params->num_ndp_instances);
+
+	if (fixed_params->num_channels > event->num_ndl_channel_list ||
+	    fixed_params->num_channels > event->num_nss_list) {
+		WMI_LOGE(FL("Channel count %d greater than NDP Ch list TLV len (%d) or NSS list TLV len (%d)"),
+			 fixed_params->num_channels,
+			 event->num_ndl_channel_list,
+			 event->num_nss_list);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (fixed_params->num_ndp_instances > event->num_ndp_instance_list) {
+		WMI_LOGE(FL("NDP Instance count %d greater than NDP Instancei TLV len %d"),
+			 fixed_params->num_ndp_instances,
+			 event->num_ndp_instance_list);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ind->vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc,
+						     fixed_params->vdev_id,
+						     WLAN_NAN_ID);
+	if (!ind->vdev) {
+		WMI_LOGE("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ind->flags = fixed_params->flags;
+	ind->num_channels = fixed_params->num_channels;
+	ind->num_ndp_instances = fixed_params->num_ndp_instances;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr,
+				   ind->peer_addr.bytes);
+
+	if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) {
+		WMI_LOGE(FL("uint32 overflow"));
+		wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list,
+		     sizeof(uint32_t) * ind->num_ndp_instances);
+
+	if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) {
+		WMI_LOGE(FL("too many channels"));
+		ind->num_channels = NAN_CH_INFO_MAX_CHANNELS;
+	}
+
+	for (i = 0; i < ind->num_channels; i++) {
+		ind->ch[i].channel = event->ndl_channel_list[i].mhz;
+		ind->ch[i].nss = event->nss_list[i];
+		ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]);
+		ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle,
+								     ch_mode);
+		WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"),
+			 ind->ch[i].channel,
+			 ind->ch[i].ch_width,
+			 ind->ch[i].nss);
+	}
+
+	for (i = 0; i < fixed_params->num_ndp_instances; i++)
+		WMI_LOGD(FL("instance_id[%d]: %d"),
+			 i, event->ndp_instance_list[i]);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_nan_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv;
+	ops->send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv;
+	ops->send_ndp_end_req_cmd = nan_ndp_end_req_tlv;
+	ops->extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv;
+	ops->extract_ndp_ind = extract_ndp_ind_tlv;
+	ops->extract_ndp_confirm = extract_ndp_confirm_tlv;
+	ops->extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv;
+	ops->extract_ndp_end_rsp = extract_ndp_end_rsp_tlv;
+	ops->extract_ndp_end_ind = extract_ndp_end_ind_tlv;
+	ops->extract_ndp_sch_update = extract_ndp_sch_update_tlv;
+}

+ 153 - 0
wmi_unified_ocb_api.c

@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+/**
+ * DOC: Implement API's specific to DSRC component.
+ */
+
+#include <wmi_unified_priv.h>
+#include <wlan_ocb_public_structs.h>
+#include <wmi_unified_ocb_api.h>
+
+QDF_STATUS wmi_unified_ocb_start_timing_advert(struct wmi_unified *wmi_hdl,
+	struct ocb_timing_advert_param *timing_advert)
+{
+	if (wmi_hdl->ops->send_ocb_start_timing_advert_cmd)
+		return wmi_hdl->ops->send_ocb_start_timing_advert_cmd(wmi_hdl,
+							timing_advert);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_ocb_stop_timing_advert(struct wmi_unified *wmi_hdl,
+	struct ocb_timing_advert_param *timing_advert)
+{
+	if (wmi_hdl->ops->send_ocb_stop_timing_advert_cmd)
+		return wmi_hdl->ops->send_ocb_stop_timing_advert_cmd(wmi_hdl,
+							timing_advert);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_ocb_set_utc_time_cmd(struct wmi_unified *wmi_hdl,
+					    struct ocb_utc_param *utc)
+{
+	if (wmi_hdl->ops->send_ocb_set_utc_time_cmd)
+		return wmi_hdl->ops->send_ocb_set_utc_time_cmd(wmi_hdl, utc);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_ocb_get_tsf_timer(struct wmi_unified *wmi_hdl,
+					 struct ocb_get_tsf_timer_param *req)
+{
+	if (wmi_hdl->ops->send_ocb_get_tsf_timer_cmd)
+		return wmi_hdl->ops->send_ocb_get_tsf_timer_cmd(wmi_hdl,
+								req->vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_dcc_get_stats_cmd(struct wmi_unified *wmi_hdl,
+			struct ocb_dcc_get_stats_param *get_stats_param)
+{
+	if (wmi_hdl->ops->send_dcc_get_stats_cmd)
+		return wmi_hdl->ops->send_dcc_get_stats_cmd(wmi_hdl,
+							    get_stats_param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_dcc_clear_stats(struct wmi_unified *wmi_hdl,
+		struct ocb_dcc_clear_stats_param *clear_stats_param)
+{
+	if (wmi_hdl->ops->send_dcc_clear_stats_cmd)
+		return wmi_hdl->ops->send_dcc_clear_stats_cmd(wmi_hdl,
+				clear_stats_param->vdev_id,
+				clear_stats_param->dcc_stats_bitmap);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_dcc_update_ndl(struct wmi_unified *wmi_hdl,
+			struct ocb_dcc_update_ndl_param *update_ndl_param)
+{
+	if (wmi_hdl->ops->send_dcc_update_ndl_cmd)
+		return wmi_hdl->ops->send_dcc_update_ndl_cmd(wmi_hdl,
+					update_ndl_param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_ocb_set_config(struct wmi_unified *wmi_hdl,
+				      struct ocb_config *config)
+{
+	if (wmi_hdl->ops->send_ocb_set_config_cmd)
+		return wmi_hdl->ops->send_ocb_set_config_cmd(wmi_hdl,
+							     config);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_extract_ocb_set_channel_config_resp(struct wmi_unified *wmi_hdl,
+					void *evt_buf,
+					uint32_t *status)
+{
+	if (wmi_hdl->ops->extract_ocb_chan_config_resp)
+		return wmi_hdl->ops->extract_ocb_chan_config_resp(wmi_hdl,
+								  evt_buf,
+								  status);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_ocb_tsf_timer(struct wmi_unified *wmi_hdl,
+				     void *evt_buf,
+				     struct ocb_get_tsf_timer_response *resp)
+{
+	if (wmi_hdl->ops->extract_ocb_tsf_timer)
+		return wmi_hdl->ops->extract_ocb_tsf_timer(wmi_hdl,
+							   evt_buf,
+							   resp);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_dcc_update_ndl_resp(struct wmi_unified *wmi_hdl,
+		void *evt_buf, struct ocb_dcc_update_ndl_response *resp)
+{
+	if (wmi_hdl->ops->extract_dcc_update_ndl_resp)
+		return wmi_hdl->ops->extract_dcc_update_ndl_resp(wmi_hdl,
+								 evt_buf,
+								 resp);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_dcc_stats(struct wmi_unified *wmi_hdl,
+				 void *evt_buf,
+				 struct ocb_dcc_get_stats_response **resp)
+{
+	if (wmi_hdl->ops->extract_dcc_stats)
+		return wmi_hdl->ops->extract_dcc_stats(wmi_hdl,
+						       evt_buf,
+						       resp);
+
+	return QDF_STATUS_E_FAILURE;
+}
+

+ 791 - 0
wmi_unified_ocb_tlv.c

@@ -0,0 +1,791 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <osdep.h>
+#include <wmi.h>
+#include <wmi_unified_priv.h>
+#include <wlan_ocb_public_structs.h>
+#include <wmi_unified_ocb_api.h>
+
+/**
+ * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware
+ * @wmi_handle: pointer to the wmi handle
+ * @utc: pointer to the UTC time struct
+ *
+ * Return: 0 on succes
+ */
+static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle,
+						struct ocb_utc_param *utc)
+{
+	QDF_STATUS ret;
+	wmi_ocb_set_utc_time_cmd_fixed_param *cmd;
+	uint8_t *buf_ptr;
+	uint32_t len, i;
+	wmi_buf_t buf;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param));
+	cmd->vdev_id = utc->vdev_id;
+
+	for (i = 0; i < SIZE_UTC_TIME; i++)
+		WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]);
+
+	for (i = 0; i < SIZE_UTC_TIME_ERROR; i++)
+		WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]);
+
+	wmi_mtrace(WMI_OCB_SET_UTC_TIME_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_OCB_SET_UTC_TIME_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE(FL("Failed to set OCB UTC time"));
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement
+ *				   frames on a channel
+ * @wmi_handle: pointer to the wmi handle
+ * @timing_advert: pointer to the timing advertisement struct
+ *
+ * Return: 0 on succes
+ */
+static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
+				struct ocb_timing_advert_param *timing_advert)
+{
+	QDF_STATUS ret;
+	wmi_ocb_start_timing_advert_cmd_fixed_param *cmd;
+	uint8_t *buf_ptr;
+	uint32_t len, len_template;
+	wmi_buf_t buf;
+
+	len = sizeof(*cmd) +
+		     WMI_TLV_HDR_SIZE;
+
+	len_template = timing_advert->template_length;
+	/* Add padding to the template if needed */
+	if (len_template % 4 != 0)
+		len_template += 4 - (len_template % 4);
+	len += len_template;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_ocb_start_timing_advert_cmd_fixed_param));
+	cmd->vdev_id = timing_advert->vdev_id;
+	cmd->repeat_rate = timing_advert->repeat_rate;
+	cmd->channel_freq = timing_advert->chan_freq;
+	cmd->timestamp_offset = timing_advert->timestamp_offset;
+	cmd->time_value_offset = timing_advert->time_value_offset;
+	cmd->timing_advert_template_length = timing_advert->template_length;
+	buf_ptr += sizeof(*cmd);
+
+	/* Add the timing advert template */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       len_template);
+	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
+		     (uint8_t *)timing_advert->template_value,
+		     timing_advert->template_length);
+
+	wmi_mtrace(WMI_OCB_START_TIMING_ADVERT_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_OCB_START_TIMING_ADVERT_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE(FL("Failed to start OCB timing advert"));
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames
+ *				  on a channel
+ * @wmi_handle: pointer to the wmi handle
+ * @timing_advert: pointer to the timing advertisement struct
+ *
+ * Return: 0 on succes
+ */
+static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
+	struct ocb_timing_advert_param *timing_advert)
+{
+	QDF_STATUS ret;
+	wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd;
+	uint8_t *buf_ptr;
+	uint32_t len;
+	wmi_buf_t buf;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_ocb_stop_timing_advert_cmd_fixed_param));
+	cmd->vdev_id = timing_advert->vdev_id;
+	cmd->channel_freq = timing_advert->chan_freq;
+
+	wmi_mtrace(WMI_OCB_STOP_TIMING_ADVERT_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_OCB_STOP_TIMING_ADVERT_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE(FL("Failed to stop OCB timing advert"));
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val
+ * @wmi_handle: pointer to the wmi handle
+ * @request: pointer to the request
+ *
+ * Return: 0 on succes
+ */
+static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle,
+			  uint8_t vdev_id)
+{
+	QDF_STATUS ret;
+	wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd;
+	uint8_t *buf_ptr;
+	wmi_buf_t buf;
+	int32_t len;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+
+	cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr;
+	qdf_mem_zero(cmd, len);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_ocb_get_tsf_timer_cmd_fixed_param));
+	cmd->vdev_id = vdev_id;
+
+	/* Send the WMI command */
+	wmi_mtrace(WMI_OCB_GET_TSF_TIMER_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_OCB_GET_TSF_TIMER_CMDID);
+	/* If there is an error, set the completion event */
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats
+ * @wmi_handle: pointer to the wmi handle
+ * @get_stats_param: pointer to the dcc stats
+ *
+ * Return: 0 on succes
+ */
+static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle,
+		     struct ocb_dcc_get_stats_param *get_stats_param)
+{
+	QDF_STATUS ret;
+	wmi_dcc_get_stats_cmd_fixed_param *cmd;
+	wmi_dcc_channel_stats_request *channel_stats_array;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint32_t len;
+	uint32_t i;
+
+	/* Validate the input */
+	if (get_stats_param->request_array_len !=
+	    get_stats_param->channel_count * sizeof(*channel_stats_array)) {
+		WMI_LOGE(FL("Invalid parameter"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Allocate memory for the WMI command */
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
+		get_stats_param->request_array_len;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = wmi_buf_data(buf);
+	qdf_mem_zero(buf_ptr, len);
+
+	/* Populate the WMI command */
+	cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr;
+	buf_ptr += sizeof(*cmd);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+			   wmi_dcc_get_stats_cmd_fixed_param));
+	cmd->vdev_id = get_stats_param->vdev_id;
+	cmd->num_channels = get_stats_param->channel_count;
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       get_stats_param->request_array_len);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr;
+	qdf_mem_copy(channel_stats_array, get_stats_param->request_array,
+		     get_stats_param->request_array_len);
+	for (i = 0; i < cmd->num_channels; i++)
+		WMITLV_SET_HDR(&channel_stats_array[i].tlv_header,
+			       WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request,
+			       WMITLV_GET_STRUCT_TLVLEN(
+					wmi_dcc_channel_stats_request));
+
+	/* Send the WMI command */
+	wmi_mtrace(WMI_DCC_GET_STATS_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_DCC_GET_STATS_CMDID);
+
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats
+ * @wmi_handle: pointer to the wmi handle
+ * @vdev_id: vdev id
+ * @dcc_stats_bitmap: dcc status bitmap
+ *
+ * Return: 0 on succes
+ */
+static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle,
+				uint32_t vdev_id, uint32_t dcc_stats_bitmap)
+{
+	QDF_STATUS ret;
+	wmi_dcc_clear_stats_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint32_t len;
+
+	/* Allocate memory for the WMI command */
+	len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = wmi_buf_data(buf);
+	qdf_mem_zero(buf_ptr, len);
+
+	/* Populate the WMI command */
+	cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+			   wmi_dcc_clear_stats_cmd_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->dcc_stats_bitmap = dcc_stats_bitmap;
+
+	/* Send the WMI command */
+	wmi_mtrace(WMI_DCC_CLEAR_STATS_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_DCC_CLEAR_STATS_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE(FL("Failed to send the WMI command"));
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data
+ * @wmi_handle: pointer to the wmi handle
+ * @update_ndl_param: pointer to the request parameters
+ *
+ * Return: 0 on success
+ */
+static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle,
+		       struct ocb_dcc_update_ndl_param *update_ndl_param)
+{
+	QDF_STATUS qdf_status;
+	wmi_dcc_update_ndl_cmd_fixed_param *cmd;
+	wmi_dcc_ndl_chan *ndl_chan_array;
+	wmi_dcc_ndl_active_state_config *ndl_active_state_array;
+	uint32_t active_state_count;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint32_t len;
+	uint32_t i;
+
+	/* validate the input */
+	if (update_ndl_param->dcc_ndl_chan_list_len !=
+	    update_ndl_param->channel_count * sizeof(*ndl_chan_array)) {
+		WMI_LOGE(FL("Invalid parameter"));
+		return QDF_STATUS_E_INVAL;
+	}
+	active_state_count = 0;
+	ndl_chan_array = update_ndl_param->dcc_ndl_chan_list;
+	for (i = 0; i < update_ndl_param->channel_count; i++)
+		active_state_count +=
+			WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]);
+	if (update_ndl_param->dcc_ndl_active_state_list_len !=
+	    active_state_count * sizeof(*ndl_active_state_array)) {
+		WMI_LOGE(FL("Invalid parameter"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Allocate memory for the WMI command */
+	len = sizeof(*cmd) +
+		WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len +
+		WMI_TLV_HDR_SIZE +
+		update_ndl_param->dcc_ndl_active_state_list_len;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = wmi_buf_data(buf);
+	qdf_mem_zero(buf_ptr, len);
+
+	/* Populate the WMI command */
+	cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr;
+	buf_ptr += sizeof(*cmd);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+			   wmi_dcc_update_ndl_cmd_fixed_param));
+	cmd->vdev_id = update_ndl_param->vdev_id;
+	cmd->num_channel = update_ndl_param->channel_count;
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       update_ndl_param->dcc_ndl_chan_list_len);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr;
+	qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list,
+		     update_ndl_param->dcc_ndl_chan_list_len);
+	for (i = 0; i < cmd->num_channel; i++)
+		WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header,
+			       WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
+			       WMITLV_GET_STRUCT_TLVLEN(
+					wmi_dcc_ndl_chan));
+	buf_ptr += update_ndl_param->dcc_ndl_chan_list_len;
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       update_ndl_param->dcc_ndl_active_state_list_len);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	ndl_active_state_array = (wmi_dcc_ndl_active_state_config *)buf_ptr;
+	qdf_mem_copy(ndl_active_state_array,
+		     update_ndl_param->dcc_ndl_active_state_list,
+		     update_ndl_param->dcc_ndl_active_state_list_len);
+	for (i = 0; i < active_state_count; i++) {
+		WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header,
+			WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
+			WMITLV_GET_STRUCT_TLVLEN(
+			    wmi_dcc_ndl_active_state_config));
+	}
+	buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len;
+
+	/* Send the WMI command */
+	wmi_mtrace(WMI_DCC_UPDATE_NDL_CMDID, cmd->vdev_id, 0);
+	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
+					  WMI_DCC_UPDATE_NDL_CMDID);
+	/* If there is an error, set the completion event */
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status);
+		wmi_buf_free(buf);
+	}
+
+	return qdf_status;
+}
+
+/**
+ * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW
+ * @wmi_handle: pointer to the wmi handle
+ * @config: the OCB configuration
+ *
+ * Return: 0 on success
+ */
+static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle,
+					      struct ocb_config *config)
+{
+	QDF_STATUS ret;
+	wmi_ocb_set_config_cmd_fixed_param *cmd;
+	wmi_channel *chan;
+	wmi_ocb_channel *ocb_chan;
+	wmi_qos_parameter *qos_param;
+	wmi_dcc_ndl_chan *ndl_chan;
+	wmi_dcc_ndl_active_state_config *ndl_active_config;
+	wmi_ocb_schedule_element *sched_elem;
+	uint8_t *buf_ptr;
+	wmi_buf_t buf;
+	int32_t len;
+	int32_t i, j, active_state_count;
+
+	/*
+	 * Validate the dcc_ndl_chan_list_len and count the number of active
+	 * states. Validate dcc_ndl_active_state_list_len.
+	 */
+	active_state_count = 0;
+	if (config->dcc_ndl_chan_list_len) {
+		if (!config->dcc_ndl_chan_list ||
+			config->dcc_ndl_chan_list_len !=
+			config->channel_count * sizeof(wmi_dcc_ndl_chan)) {
+			WMI_LOGE(FL("NDL channel is invalid. List len: %d"),
+				 config->dcc_ndl_chan_list_len);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		for (i = 0, ndl_chan = config->dcc_ndl_chan_list;
+				i < config->channel_count; ++i, ++ndl_chan)
+			active_state_count +=
+				WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan);
+
+		if (active_state_count) {
+			if (!config->dcc_ndl_active_state_list ||
+				config->dcc_ndl_active_state_list_len !=
+				active_state_count *
+				sizeof(wmi_dcc_ndl_active_state_config)) {
+				WMI_LOGE(FL("NDL active state is invalid."));
+				return QDF_STATUS_E_INVAL;
+			}
+		}
+	}
+
+	len = sizeof(*cmd) +
+		WMI_TLV_HDR_SIZE + config->channel_count *
+			sizeof(wmi_channel) +
+		WMI_TLV_HDR_SIZE + config->channel_count *
+			sizeof(wmi_ocb_channel) +
+		WMI_TLV_HDR_SIZE + config->channel_count *
+			sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC +
+		WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len +
+		WMI_TLV_HDR_SIZE + active_state_count *
+			sizeof(wmi_dcc_ndl_active_state_config) +
+		WMI_TLV_HDR_SIZE + config->schedule_size *
+			sizeof(wmi_ocb_schedule_element);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param));
+	cmd->vdev_id = config->vdev_id;
+	cmd->channel_count = config->channel_count;
+	cmd->schedule_size = config->schedule_size;
+	cmd->flags = config->flags;
+	buf_ptr += sizeof(*cmd);
+
+	/* Add the wmi_channel info */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       config->channel_count * sizeof(wmi_channel));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	for (i = 0; i < config->channel_count; i++) {
+		chan = (wmi_channel *)buf_ptr;
+		WMITLV_SET_HDR(&chan->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_channel,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
+		chan->mhz = config->channels[i].chan_freq;
+		chan->band_center_freq1 = config->channels[i].chan_freq;
+		chan->band_center_freq2 = 0;
+		chan->info = 0;
+
+		WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode);
+		WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr);
+		WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr);
+		WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr);
+		WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr);
+		WMI_SET_CHANNEL_ANTENNA_MAX(chan,
+					    config->channels[i].antenna_max);
+
+		if (config->channels[i].bandwidth < 10)
+			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
+		else if (config->channels[i].bandwidth < 20)
+			WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
+		buf_ptr += sizeof(*chan);
+	}
+
+	/* Add the wmi_ocb_channel info */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       config->channel_count * sizeof(wmi_ocb_channel));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	for (i = 0; i < config->channel_count; i++) {
+		ocb_chan = (wmi_ocb_channel *)buf_ptr;
+		WMITLV_SET_HDR(&ocb_chan->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_ocb_channel,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel));
+		ocb_chan->bandwidth = config->channels[i].bandwidth;
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(
+					config->channels[i].mac_address.bytes,
+					&ocb_chan->mac_address);
+		buf_ptr += sizeof(*ocb_chan);
+	}
+
+	/* Add the wmi_qos_parameter info */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	/* WMI_MAX_NUM_AC parameters for each channel */
+	for (i = 0; i < config->channel_count; i++) {
+		for (j = 0; j < WMI_MAX_NUM_AC; j++) {
+			qos_param = (wmi_qos_parameter *)buf_ptr;
+			WMITLV_SET_HDR(&qos_param->tlv_header,
+				WMITLV_TAG_STRUC_wmi_qos_parameter,
+				WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter));
+			qos_param->aifsn =
+				config->channels[i].qos_params[j].aifsn;
+			qos_param->cwmin =
+				config->channels[i].qos_params[j].cwmin;
+			qos_param->cwmax =
+				config->channels[i].qos_params[j].cwmax;
+			buf_ptr += sizeof(*qos_param);
+		}
+	}
+
+	/* Add the wmi_dcc_ndl_chan (per channel) */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       config->dcc_ndl_chan_list_len);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	if (config->dcc_ndl_chan_list_len) {
+		ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr;
+		qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list,
+			     config->dcc_ndl_chan_list_len);
+		for (i = 0; i < config->channel_count; i++)
+			WMITLV_SET_HDR(&(ndl_chan[i].tlv_header),
+				WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
+				WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan));
+		buf_ptr += config->dcc_ndl_chan_list_len;
+	}
+
+	/* Add the wmi_dcc_ndl_active_state_config */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count *
+		       sizeof(wmi_dcc_ndl_active_state_config));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	if (active_state_count) {
+		ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr;
+		qdf_mem_copy(ndl_active_config,
+			config->dcc_ndl_active_state_list,
+			active_state_count * sizeof(*ndl_active_config));
+		for (i = 0; i < active_state_count; ++i)
+			WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header),
+			  WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
+			  WMITLV_GET_STRUCT_TLVLEN(
+				wmi_dcc_ndl_active_state_config));
+		buf_ptr += active_state_count *
+			sizeof(*ndl_active_config);
+	}
+
+	/* Add the wmi_ocb_schedule_element info */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		config->schedule_size * sizeof(wmi_ocb_schedule_element));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	for (i = 0; i < config->schedule_size; i++) {
+		sched_elem = (wmi_ocb_schedule_element *)buf_ptr;
+		WMITLV_SET_HDR(&sched_elem->tlv_header,
+			WMITLV_TAG_STRUC_wmi_ocb_schedule_element,
+			WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element));
+		sched_elem->channel_freq = config->schedule[i].chan_freq;
+		sched_elem->total_duration = config->schedule[i].total_duration;
+		sched_elem->guard_interval = config->schedule[i].guard_interval;
+		buf_ptr += sizeof(*sched_elem);
+	}
+
+	wmi_mtrace(WMI_OCB_SET_CONFIG_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_OCB_SET_CONFIG_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to set OCB config");
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp
+ * @wmi_handle: wmi handle
+ * @evt_buf: wmi event buffer
+ * @status: status buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle,
+						      void *evt_buf,
+						      uint32_t *status)
+{
+	WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs;
+	wmi_ocb_set_config_resp_event_fixed_param *fix_param;
+
+	param_tlvs = evt_buf;
+	fix_param = param_tlvs->fixed_param;
+
+	*status = fix_param->status;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer
+ * @wmi_handle: wmi handle
+ * @evt_buf: wmi event buffer
+ * @resp: response buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle,
+			void *evt_buf, struct ocb_get_tsf_timer_response *resp)
+{
+	WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs;
+	wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param;
+
+	param_tlvs = evt_buf;
+	fix_param = param_tlvs->fixed_param;
+	resp->vdev_id = fix_param->vdev_id;
+	resp->timer_high = fix_param->tsf_timer_high;
+	resp->timer_low = fix_param->tsf_timer_low;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer
+ * @wmi_handle: wmi handle
+ * @evt_buf: wmi event buffer
+ * @resp: response buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle,
+		void *evt_buf, struct ocb_dcc_update_ndl_response *resp)
+{
+	WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs;
+	wmi_dcc_update_ndl_resp_event_fixed_param *fix_param;
+
+	param_tlvs = evt_buf;
+	fix_param = param_tlvs->fixed_param;
+	resp->vdev_id = fix_param->vdev_id;
+	resp->status = fix_param->status;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer
+ * @wmi_handle: wmi handle
+ * @evt_buf: wmi event buffer
+ * @resp: response buffer
+ *
+ * Since length of stats is variable, buffer for DCC stats will be allocated
+ * in this function. The caller must free the buffer.
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle,
+		void *evt_buf, struct ocb_dcc_get_stats_response **resp)
+{
+	struct ocb_dcc_get_stats_response *response;
+	WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs;
+	wmi_dcc_get_stats_resp_event_fixed_param *fix_param;
+
+	param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf;
+	fix_param = param_tlvs->fixed_param;
+
+	/* Allocate and populate the response */
+	if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE -
+	    sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) {
+		WMI_LOGE("%s: too many channels:%d", __func__,
+			 fix_param->num_channels);
+		QDF_ASSERT(0);
+		*resp = NULL;
+		return QDF_STATUS_E_INVAL;
+	}
+	response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels *
+				  sizeof(wmi_dcc_ndl_stats_per_channel));
+	*resp = response;
+	if (!response)
+		return  QDF_STATUS_E_NOMEM;
+
+	response->vdev_id = fix_param->vdev_id;
+	response->num_channels = fix_param->num_channels;
+	response->channel_stats_array_len =
+		fix_param->num_channels *
+		sizeof(wmi_dcc_ndl_stats_per_channel);
+	response->channel_stats_array = ((uint8_t *)response) +
+					sizeof(*response);
+	qdf_mem_copy(response->channel_stats_array,
+		     param_tlvs->stats_per_channel_list,
+		     response->channel_stats_array_len);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_ocb_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv;
+	ops->send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv;
+	ops->send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv;
+	ops->send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv;
+	ops->send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv;
+	ops->send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv;
+	ops->send_ocb_stop_timing_advert_cmd =
+			send_ocb_stop_timing_advert_cmd_tlv;
+	ops->send_ocb_start_timing_advert_cmd =
+			send_ocb_start_timing_advert_cmd_tlv;
+	ops->extract_ocb_chan_config_resp =
+			extract_ocb_channel_config_resp_tlv;
+	ops->extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv;
+	ops->extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv;
+	ops->extract_dcc_stats = extract_ocb_dcc_stats_tlv;
+}

+ 117 - 0
wmi_unified_p2p_api.c

@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+/**
+ * DOC: Implement API's specific to P2P component.
+ */
+
+#include <wmi_unified_priv.h>
+#include <wmi_unified_p2p_api.h>
+
+QDF_STATUS wmi_unified_set_p2pgo_oppps_req(void *wmi_hdl,
+					   struct p2p_ps_params *oppps)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl;
+
+	if (wmi_handle->ops->send_set_p2pgo_oppps_req_cmd)
+		return wmi_handle->ops->send_set_p2pgo_oppps_req_cmd(wmi_handle,
+								     oppps);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_p2pgo_noa_req_cmd(void *wmi_hdl,
+					     struct p2p_ps_params *noa)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl;
+
+	if (wmi_handle->ops->send_set_p2pgo_noa_req_cmd)
+		return wmi_handle->ops->send_set_p2pgo_noa_req_cmd(wmi_handle,
+								   noa);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_p2p_noa_ev_param(void *wmi_hdl, void *evt_buf,
+					struct p2p_noa_info *param)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl;
+
+	if (!wmi_handle) {
+		WMI_LOGE("wmi handle is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (wmi_handle->ops->extract_p2p_noa_ev_param)
+		return wmi_handle->ops->extract_p2p_noa_ev_param(
+				wmi_handle, evt_buf, param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+QDF_STATUS wmi_unified_p2p_lo_start_cmd(void *wmi_hdl,
+					struct p2p_lo_start *param)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl;
+
+	if (!wmi_handle) {
+		WMI_LOGE("wmi handle is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (wmi_handle->ops->send_p2p_lo_start_cmd)
+		return wmi_handle->ops->send_p2p_lo_start_cmd(wmi_handle,
+							      param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_p2p_lo_stop_cmd(void *wmi_hdl, uint8_t vdev_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl;
+
+	if (!wmi_handle) {
+		WMI_LOGE("wmi handle is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (wmi_handle->ops->send_p2p_lo_stop_cmd)
+		return wmi_handle->ops->send_p2p_lo_stop_cmd(wmi_handle,
+							     vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_p2p_lo_stop_ev_param(void *wmi_hdl, void *evt_buf,
+					    struct p2p_lo_event *param)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl;
+
+	if (!wmi_handle) {
+		WMI_LOGE("wmi handle is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (wmi_handle->ops->extract_p2p_lo_stop_ev_param)
+		return wmi_handle->ops->extract_p2p_lo_stop_ev_param(
+				wmi_handle, evt_buf, param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* End of FEATURE_P2P_LISTEN_OFFLOAD*/
+

+ 411 - 0
wmi_unified_p2p_tlv.c

@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <osdep.h>
+#include <wmi.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_p2p_api.h>
+
+/**
+ * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw
+ * @wmi_handle: wmi handle
+ * @noa: p2p power save parameters
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle,
+						 struct p2p_ps_params *noa)
+{
+	wmi_p2p_set_noa_cmd_fixed_param *cmd;
+	wmi_p2p_noa_descriptor *noa_discriptor;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint16_t len;
+	QDF_STATUS status;
+	uint32_t duration;
+
+	WMI_LOGD("%s: Enter", __func__);
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_p2p_set_noa_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_p2p_set_noa_cmd_fixed_param));
+	duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration;
+	cmd->vdev_id = noa->session_id;
+	cmd->enable = (duration) ? true : false;
+	cmd->num_noa = 1;
+
+	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)),
+		       WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor));
+	noa_discriptor = (wmi_p2p_noa_descriptor *)(buf_ptr +
+						    sizeof
+						    (wmi_p2p_set_noa_cmd_fixed_param)
+						     + WMI_TLV_HDR_SIZE);
+	WMITLV_SET_HDR(&noa_discriptor->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor));
+	noa_discriptor->type_count = noa->count;
+	noa_discriptor->duration = duration;
+	noa_discriptor->interval = noa->interval;
+	noa_discriptor->start_time = 0;
+
+	WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d",
+		 cmd->vdev_id, noa->count, noa_discriptor->duration,
+		 noa->interval);
+	wmi_mtrace(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID");
+		wmi_buf_free(buf);
+	}
+
+end:
+	WMI_LOGD("%s: Exit", __func__);
+	return status;
+}
+
+/**
+ * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw
+ * @wmi_handle: wmi handle
+ * @noa: p2p opp power save parameters
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle,
+						   struct p2p_ps_params *oppps)
+{
+	wmi_p2p_set_oppps_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS status;
+
+	WMI_LOGD("%s: Enter", __func__);
+	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
+	if (!buf) {
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+					wmi_p2p_set_oppps_cmd_fixed_param));
+	cmd->vdev_id = oppps->session_id;
+	if (oppps->ctwindow)
+		WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd);
+
+	WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow);
+	WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d",
+		 cmd->vdev_id, oppps->ctwindow);
+	wmi_mtrace(WMI_P2P_SET_OPPPS_PARAM_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
+				      WMI_P2P_SET_OPPPS_PARAM_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID");
+		wmi_buf_free(buf);
+	}
+
+end:
+	WMI_LOGD("%s: Exit", __func__);
+	return status;
+}
+
+/**
+ * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param param: Pointer to hold p2p noa info
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS extract_p2p_noa_ev_param_tlv(
+	wmi_unified_t wmi_handle, void *evt_buf,
+	struct p2p_noa_info *param)
+{
+	WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs;
+	wmi_p2p_noa_event_fixed_param *fixed_param;
+	uint8_t i;
+	wmi_p2p_noa_info *wmi_noa_info;
+	uint8_t *buf_ptr;
+	uint32_t descriptors;
+
+	param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *)evt_buf;
+	if (!param_tlvs) {
+		WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!param) {
+		WMI_LOGE("noa information param is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fixed_param = param_tlvs->fixed_param;
+	buf_ptr = (uint8_t *) fixed_param;
+	buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param);
+	wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr);
+
+	if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) {
+		WMI_LOGE("%s: noa attr is not modified", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param->vdev_id = fixed_param->vdev_id;
+	param->index =
+		(uint8_t)WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info);
+	param->opps_ps =
+		(uint8_t)WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info);
+	param->ct_window =
+		(uint8_t)WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info);
+	descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info);
+	param->num_desc = (uint8_t)descriptors;
+	if (param->num_desc > WMI_P2P_MAX_NOA_DESCRIPTORS) {
+		WMI_LOGE("%s: invalid num desc:%d", __func__,
+			 param->num_desc);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u",
+		 __func__,
+		 param->index, param->opps_ps, param->ct_window,
+		 param->num_desc);
+	for (i = 0; i < param->num_desc; i++) {
+		param->noa_desc[i].type_count =
+			(uint8_t)wmi_noa_info->noa_descriptors[i].
+			type_count;
+		param->noa_desc[i].duration =
+			wmi_noa_info->noa_descriptors[i].duration;
+		param->noa_desc[i].interval =
+			wmi_noa_info->noa_descriptors[i].interval;
+		param->noa_desc[i].start_time =
+			wmi_noa_info->noa_descriptors[i].start_time;
+		WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
+			__func__, i, param->noa_desc[i].type_count,
+			param->noa_desc[i].duration,
+			param->noa_desc[i].interval,
+			param->noa_desc[i].start_time);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+/**
+ * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw
+ * @wmi_handle: wmi handle
+ * @param: p2p listen offload start parameters
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle,
+					    struct p2p_lo_start *param)
+{
+	wmi_buf_t buf;
+	wmi_p2p_lo_start_cmd_fixed_param *cmd;
+	int32_t len = sizeof(*cmd);
+	uint8_t *buf_ptr;
+	QDF_STATUS status;
+	int device_types_len_aligned;
+	int probe_resp_len_aligned;
+
+	if (!param) {
+		WMI_LOGE("lo start param is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id);
+
+	device_types_len_aligned =
+		qdf_roundup(param->dev_types_len,
+			    sizeof(uint32_t));
+	probe_resp_len_aligned =
+		qdf_roundup(param->probe_resp_len,
+			    sizeof(uint32_t));
+
+	len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
+			probe_resp_len_aligned;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
+		 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_lo_start_cmd_fixed_param));
+
+	cmd->vdev_id = param->vdev_id;
+	cmd->ctl_flags = param->ctl_flags;
+	cmd->channel = param->freq;
+	cmd->period = param->period;
+	cmd->interval = param->interval;
+	cmd->count = param->count;
+	cmd->device_types_len = param->dev_types_len;
+	cmd->prob_resp_len = param->probe_resp_len;
+
+	buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       device_types_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, param->device_types,
+		     param->dev_types_len);
+
+	buf_ptr += device_types_len_aligned;
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       probe_resp_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, param->probe_resp_tmplt,
+		     param->probe_resp_len);
+
+	WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__,
+		 cmd->channel, cmd->period, cmd->interval, cmd->count);
+
+	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_START_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle,
+				      buf, len,
+				      WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMI_LOGE("%s: Failed to send p2p lo start: %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+		return status;
+	}
+
+	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw
+ * @wmi_handle: wmi handle
+ * @param: p2p listen offload stop parameters
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle,
+					   uint8_t vdev_id)
+{
+	wmi_buf_t buf;
+	wmi_p2p_lo_stop_cmd_fixed_param *cmd;
+	int32_t len;
+	QDF_STATUS status;
+
+	WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id);
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_lo_stop_cmd_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+
+	WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__);
+
+	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle,
+				      buf, len,
+				      WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMI_LOGE("%s: Failed to send p2p lo stop: %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+		return status;
+	}
+
+	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop
+ * information from event
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param param: Pointer to hold p2p lo stop event information
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv(
+	wmi_unified_t wmi_handle, void *evt_buf,
+	struct p2p_lo_event *param)
+{
+	WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
+	wmi_p2p_lo_stopped_event_fixed_param *lo_param;
+
+	param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
+					evt_buf;
+	if (!param_tlvs) {
+		WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!param) {
+		WMI_LOGE("lo stop event param is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	lo_param = param_tlvs->fixed_param;
+	param->vdev_id = lo_param->vdev_id;
+	param->reason_code = lo_param->reason;
+	WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__,
+		 param->vdev_id, param->reason_code);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_p2p_listen_offload_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv;
+	ops->send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv;
+	ops->extract_p2p_lo_stop_ev_param =
+			extract_p2p_lo_stop_ev_param_tlv;
+}
+#endif /* FEATURE_P2P_LISTEN_OFFLOAD */
+
+void wmi_p2p_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv;
+	ops->send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv;
+	ops->extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv;
+	wmi_p2p_listen_offload_attach_tlv(wmi_handle);
+}
+

+ 179 - 80
wmi_unified_pmo_api.c

@@ -25,10 +25,36 @@
 #include "wmi_unified_pmo_api.h"
 #include "wlan_pmo_hw_filter_public_struct.h"
 
+#ifdef FEATURE_WLAN_D0WOW
+QDF_STATUS wmi_unified_d0wow_enable_send(void *wmi_hdl,
+					 uint8_t mac_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_d0wow_enable_cmd)
+		return wmi_handle->ops->send_d0wow_enable_cmd(wmi_handle,
+							      mac_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_d0wow_disable_send(void *wmi_hdl,
+					  uint8_t mac_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_d0wow_disable_cmd)
+		return wmi_handle->ops->send_d0wow_disable_cmd(wmi_handle,
+							       mac_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_WLAN_D0WOW */
+
 QDF_STATUS wmi_unified_add_wow_wakeup_event_cmd(void *wmi_hdl,
-					uint32_t vdev_id,
-					uint32_t *bitmap,
-					bool enable)
+						uint32_t vdev_id,
+						uint32_t *bitmap,
+						bool enable)
 {
 	struct wmi_unified *wmi_handle = (struct wmi_unified *) wmi_hdl;
 
@@ -57,6 +83,21 @@ QDF_STATUS wmi_unified_wow_patterns_to_fw_cmd(void *wmi_hdl,
 	return QDF_STATUS_E_FAILURE;
 }
 
+QDF_STATUS wmi_unified_enable_arp_ns_offload_cmd(void *wmi_hdl,
+			   struct pmo_arp_offload_params *arp_offload_req,
+			   struct pmo_ns_offload_params *ns_offload_req,
+			   uint8_t vdev_id)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+
+	if (wmi_handle->ops->send_enable_arp_ns_offload_cmd)
+		return wmi_handle->ops->send_enable_arp_ns_offload_cmd(
+				wmi_handle,
+				arp_offload_req, ns_offload_req, vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 QDF_STATUS wmi_unified_add_clear_mcbc_filter_cmd(void *wmi_hdl,
 				     uint8_t vdev_id,
 				     struct qdf_mac_addr multicast_addr,
@@ -84,22 +125,44 @@ QDF_STATUS wmi_unified_multiple_add_clear_mcbc_filter_cmd(void *wmi_hdl,
 	return QDF_STATUS_E_FAILURE;
 }
 
-#ifdef FEATURE_WLAN_RA_FILTERING
-QDF_STATUS wmi_unified_wow_sta_ra_filter_cmd(void *wmi_hdl,
-				uint8_t vdev_id, uint8_t default_pattern,
-				uint16_t rate_limit_interval)
+QDF_STATUS wmi_unified_conf_hw_filter_cmd(void *opaque_wmi,
+					  struct pmo_hw_filter_params *req)
 {
+	struct wmi_unified *wmi = opaque_wmi;
 
+	if (!wmi->ops->send_conf_hw_filter_cmd)
+		return QDF_STATUS_E_NOSUPPORT;
+
+	return wmi->ops->send_conf_hw_filter_cmd(wmi, req);
+}
+
+QDF_STATUS wmi_unified_send_gtk_offload_cmd(void *wmi_hdl, uint8_t vdev_id,
+					    struct pmo_gtk_req  *params,
+					    bool enable_offload,
+					    uint32_t gtk_offload_opcode)
+{
 	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
 
-	if (wmi_handle->ops->send_wow_sta_ra_filter_cmd)
-		return wmi_handle->ops->send_wow_sta_ra_filter_cmd(wmi_handle,
-			    vdev_id, default_pattern, rate_limit_interval);
+	if (wmi_handle->ops->send_gtk_offload_cmd)
+		return wmi_handle->ops->send_gtk_offload_cmd(wmi_handle,
+				vdev_id, params, enable_offload,
+				gtk_offload_opcode);
 
 	return QDF_STATUS_E_FAILURE;
+}
 
+QDF_STATUS wmi_unified_process_gtk_offload_getinfo_cmd(void *wmi_hdl,
+				uint8_t vdev_id,
+				uint64_t offload_req_opcode)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+
+	if (wmi_handle->ops->send_process_gtk_offload_getinfo_cmd)
+		return wmi_handle->ops->send_process_gtk_offload_getinfo_cmd(
+				wmi_handle, vdev_id, offload_req_opcode);
+
+	return QDF_STATUS_E_FAILURE;
 }
-#endif /* FEATURE_WLAN_RA_FILTERING */
 
 QDF_STATUS wmi_unified_enable_enhance_multicast_offload_cmd(
 		void *wmi_hdl, uint8_t vdev_id, bool action)
@@ -127,19 +190,22 @@ QDF_STATUS wmi_extract_gtk_rsp_event(void *wmi_hdl, void *evt_buf,
 	return QDF_STATUS_E_FAILURE;
 }
 
-
-QDF_STATUS wmi_unified_process_gtk_offload_getinfo_cmd(void *wmi_hdl,
-				uint8_t vdev_id,
-				uint64_t offload_req_opcode)
+#ifdef FEATURE_WLAN_RA_FILTERING
+QDF_STATUS wmi_unified_wow_sta_ra_filter_cmd(void *wmi_hdl,
+				uint8_t vdev_id, uint8_t default_pattern,
+				uint16_t rate_limit_interval)
 {
+
 	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
 
-	if (wmi_handle->ops->send_process_gtk_offload_getinfo_cmd)
-		return wmi_handle->ops->send_process_gtk_offload_getinfo_cmd(
-				wmi_handle, vdev_id, offload_req_opcode);
+	if (wmi_handle->ops->send_wow_sta_ra_filter_cmd)
+		return wmi_handle->ops->send_wow_sta_ra_filter_cmd(wmi_handle,
+			    vdev_id, default_pattern, rate_limit_interval);
 
 	return QDF_STATUS_E_FAILURE;
+
 }
+#endif /* FEATURE_WLAN_RA_FILTERING */
 
 QDF_STATUS wmi_unified_action_frame_patterns_cmd(void *wmi_hdl,
 		struct pmo_action_wakeup_set_params *action_params)
@@ -153,21 +219,68 @@ QDF_STATUS wmi_unified_action_frame_patterns_cmd(void *wmi_hdl,
 	return QDF_STATUS_E_FAILURE;
 }
 
-QDF_STATUS wmi_unified_send_gtk_offload_cmd(void *wmi_hdl, uint8_t vdev_id,
-					   struct pmo_gtk_req  *params,
-					   bool enable_offload,
-					   uint32_t gtk_offload_opcode)
+#ifdef FEATURE_WLAN_LPHB
+QDF_STATUS wmi_unified_lphb_config_hbenable_cmd(void *wmi_hdl,
+				wmi_hb_set_enable_cmd_fixed_param *params)
 {
 	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
 
-	if (wmi_handle->ops->send_gtk_offload_cmd)
-		return wmi_handle->ops->send_gtk_offload_cmd(wmi_handle,
-				vdev_id, params, enable_offload,
-				gtk_offload_opcode);
+	if (wmi_handle->ops->send_lphb_config_hbenable_cmd)
+		return wmi_handle->ops->send_lphb_config_hbenable_cmd(
+				wmi_handle, params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_lphb_config_tcp_params_cmd(void *wmi_hdl,
+		    wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+
+	if (wmi_handle->ops->send_lphb_config_tcp_params_cmd)
+		return wmi_handle->ops->send_lphb_config_tcp_params_cmd(
+				wmi_handle, lphb_conf_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_lphb_config_tcp_pkt_filter_cmd(void *wmi_hdl,
+		wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+
+	if (wmi_handle->ops->send_lphb_config_tcp_pkt_filter_cmd)
+		return wmi_handle->ops->send_lphb_config_tcp_pkt_filter_cmd(
+				wmi_handle, g_hb_tcp_filter_fp);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_lphb_config_udp_params_cmd(void *wmi_hdl,
+			wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+
+	if (wmi_handle->ops->send_lphb_config_udp_params_cmd)
+		return wmi_handle->ops->send_lphb_config_udp_params_cmd(
+				wmi_handle, lphb_conf_req);
 
 	return QDF_STATUS_E_FAILURE;
 }
 
+QDF_STATUS wmi_unified_lphb_config_udp_pkt_filter_cmd(void *wmi_hdl,
+		wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+
+	if (wmi_handle->ops->send_lphb_config_udp_pkt_filter_cmd)
+		return wmi_handle->ops->send_lphb_config_udp_pkt_filter_cmd(
+				wmi_handle, lphb_conf_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_WLAN_LPHB */
+
 #ifdef WLAN_FEATURE_PACKET_FILTERING
 QDF_STATUS wmi_unified_enable_disable_packet_filter_cmd(void *wmi_hdl,
 		uint8_t vdev_id, bool enable)
@@ -176,7 +289,7 @@ QDF_STATUS wmi_unified_enable_disable_packet_filter_cmd(void *wmi_hdl,
 
 	if (wmi_handle->ops->send_enable_disable_packet_filter_cmd)
 		return wmi_handle->ops->send_enable_disable_packet_filter_cmd(
-		wmi_handle, vdev_id, enable);
+				wmi_handle, vdev_id, enable);
 
 	return QDF_STATUS_E_FAILURE;
 }
@@ -193,92 +306,78 @@ QDF_STATUS wmi_unified_config_packet_filter_cmd(void *wmi_hdl,
 
 	return QDF_STATUS_E_FAILURE;
 }
-#endif
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
 
-QDF_STATUS wmi_unified_enable_arp_ns_offload_cmd(void *wmi_hdl,
-			   struct pmo_arp_offload_params *arp_offload_req,
-			   struct pmo_ns_offload_params *ns_offload_req,
-			   uint8_t vdev_id)
+QDF_STATUS wmi_unified_wow_delete_pattern_cmd(void *wmi_hdl, uint8_t ptrn_id,
+					uint8_t vdev_id)
 {
-	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
 
-	if (wmi_handle->ops->send_enable_arp_ns_offload_cmd)
-		return wmi_handle->ops->send_enable_arp_ns_offload_cmd(
-				wmi_handle,
-				arp_offload_req, ns_offload_req, vdev_id);
+	if (wmi_handle->ops->send_wow_delete_pattern_cmd)
+		return wmi_handle->ops->send_wow_delete_pattern_cmd(wmi_handle,
+								    ptrn_id,
+								    vdev_id);
 
 	return QDF_STATUS_E_FAILURE;
 }
 
-QDF_STATUS wmi_unified_conf_hw_filter_cmd(void *opaque_wmi,
-					  struct pmo_hw_filter_params *req)
+QDF_STATUS wmi_unified_host_wakeup_ind_to_fw_cmd(void *wmi_hdl)
 {
-	struct wmi_unified *wmi = opaque_wmi;
-
-	if (!wmi->ops->send_conf_hw_filter_cmd)
-		return QDF_STATUS_E_NOSUPPORT;
-
-	return wmi->ops->send_conf_hw_filter_cmd(wmi, req);
-}
-
-#ifdef FEATURE_WLAN_LPHB
-QDF_STATUS wmi_unified_lphb_config_hbenable_cmd(void *wmi_hdl,
-				wmi_hb_set_enable_cmd_fixed_param *params)
-{
-	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
 
-	if (wmi_handle->ops->send_lphb_config_hbenable_cmd)
-		return wmi_handle->ops->send_lphb_config_hbenable_cmd(
-				wmi_handle, params);
+	if (wmi_handle->ops->send_host_wakeup_ind_to_fw_cmd)
+		return wmi_handle->ops->send_host_wakeup_ind_to_fw_cmd(wmi_handle);
 
 	return QDF_STATUS_E_FAILURE;
 }
 
-QDF_STATUS wmi_unified_lphb_config_tcp_params_cmd(void *wmi_hdl,
-		    wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
+QDF_STATUS wmi_unified_wow_timer_pattern_cmd(void *wmi_hdl, uint8_t vdev_id,
+					     uint32_t cookie, uint32_t time)
 {
-	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
 
-	if (wmi_handle->ops->send_lphb_config_tcp_params_cmd)
-		return wmi_handle->ops->send_lphb_config_tcp_params_cmd(
-				wmi_handle, lphb_conf_req);
+	if (wmi_handle->ops->send_wow_timer_pattern_cmd)
+		return wmi_handle->ops->send_wow_timer_pattern_cmd(wmi_handle,
+							vdev_id, cookie, time);
 
 	return QDF_STATUS_E_FAILURE;
 }
 
-QDF_STATUS wmi_unified_lphb_config_tcp_pkt_filter_cmd(void *wmi_hdl,
-		wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+QDF_STATUS wmi_unified_enable_ext_wow_cmd(void *wmi_hdl,
+					  struct ext_wow_params *params)
 {
-	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
 
-	if (wmi_handle->ops->send_lphb_config_tcp_pkt_filter_cmd)
-		return wmi_handle->ops->send_lphb_config_tcp_pkt_filter_cmd(
-				wmi_handle, g_hb_tcp_filter_fp);
+	if (wmi_handle->ops->send_enable_ext_wow_cmd)
+		return wmi_handle->ops->send_enable_ext_wow_cmd(wmi_handle,
+								params);
 
 	return QDF_STATUS_E_FAILURE;
 }
 
-QDF_STATUS wmi_unified_lphb_config_udp_params_cmd(void *wmi_hdl,
-			wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
+QDF_STATUS wmi_unified_set_app_type2_params_in_fw_cmd(void *wmi_hdl,
+				struct app_type2_params *appType2Params)
 {
-	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
 
-	if (wmi_handle->ops->send_lphb_config_udp_params_cmd)
-		return wmi_handle->ops->send_lphb_config_udp_params_cmd(
-				wmi_handle, lphb_conf_req);
+	if (wmi_handle->ops->send_set_app_type2_params_in_fw_cmd)
+		return wmi_handle->ops->send_set_app_type2_params_in_fw_cmd(
+				wmi_handle, appType2Params);
 
 	return QDF_STATUS_E_FAILURE;
 }
 
-QDF_STATUS wmi_unified_lphb_config_udp_pkt_filter_cmd(void *wmi_hdl,
-		wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
+QDF_STATUS wmi_unified_app_type1_params_in_fw_cmd(void *wmi_hdl,
+				   struct app_type1_params *app_type1_params)
 {
-	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
 
-	if (wmi_handle->ops->send_lphb_config_udp_pkt_filter_cmd)
-		return wmi_handle->ops->send_lphb_config_udp_pkt_filter_cmd(
-				wmi_handle, lphb_conf_req);
+	if (wmi_handle->ops->send_app_type1_params_in_fw_cmd)
+		return wmi_handle->ops->send_app_type1_params_in_fw_cmd(
+				wmi_handle, app_type1_params);
 
 	return QDF_STATUS_E_FAILURE;
 }
-#endif /* FEATURE_WLAN_LPHB */
+#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
+

+ 1958 - 0
wmi_unified_pmo_tlv.c

@@ -0,0 +1,1958 @@
+
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <osdep.h>
+#include "wmi.h"
+#include "wmi_unified_priv.h"
+#include "wmi_unified_pmo_api.h"
+
+#ifdef FEATURE_WLAN_D0WOW
+/**
+ *  send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function
+ *  @param wmi_handle: handle to WMI.
+ *  @mac_id: radio context
+ *
+ *  Return: 0  on success  and  error code on failure.
+ */
+static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
+					    uint8_t mac_id)
+{
+	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	QDF_STATUS status;
+
+	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+			(wmi_d0_wow_enable_disable_cmd_fixed_param));
+
+	cmd->enable = true;
+
+	wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_D0_WOW_ENABLE_DISABLE_CMDID);
+	if (QDF_IS_STATUS_ERROR(status))
+		wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ *  send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function
+ *  @param wmi_handle: handle to WMI.
+ *  @mac_id: radio context
+ *
+ *  Return: 0  on success  and  error code on failure.
+ */
+static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle,
+					     uint8_t mac_id)
+{
+	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	QDF_STATUS status;
+
+	len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+			(wmi_d0_wow_enable_disable_cmd_fixed_param));
+
+	cmd->enable = false;
+
+	wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_D0_WOW_ENABLE_DISABLE_CMDID);
+	if (QDF_IS_STATUS_ERROR(status))
+		wmi_buf_free(buf);
+
+	return status;
+}
+
+void wmi_d0wow_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv;
+	ops->send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv;
+}
+#endif /* FEATURE_WLAN_D0WOW */
+
+/**
+ * send_add_wow_wakeup_event_cmd_tlv() -  Configures wow wakeup events.
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ * @enable: enable/disable
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle,
+						    uint32_t vdev_id,
+						    uint32_t *bitmap,
+						    bool enable)
+{
+	WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd;
+	uint16_t len;
+	wmi_buf_t buf;
+	int ret;
+
+	len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->is_add = enable;
+	qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) *
+		     WMI_WOW_MAX_EVENT_BM_LEN);
+
+	WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0],
+		 cmd->event_bitmaps[1], cmd->event_bitmaps[2],
+		 cmd->event_bitmaps[3], enable ? "enabled" : "disabled");
+
+	wmi_mtrace(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
+	if (ret) {
+		WMI_LOGE("Failed to config wow wakeup event");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW.
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @ptrn_id: pattern id
+ * @ptrn: pattern
+ * @ptrn_len: pattern length
+ * @ptrn_offset: pattern offset
+ * @mask: mask
+ * @mask_len: mask length
+ * @user: true for user configured pattern and false for default pattern
+ * @default_patterns: default patterns
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
+				uint8_t vdev_id, uint8_t ptrn_id,
+				const uint8_t *ptrn, uint8_t ptrn_len,
+				uint8_t ptrn_offset, const uint8_t *mask,
+				uint8_t mask_len, bool user,
+				uint8_t default_patterns)
+{
+	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
+	WOW_BITMAP_PATTERN_T *bitmap_pattern;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int32_t len;
+	int ret;
+
+	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
+		WMI_TLV_HDR_SIZE +
+		1 * sizeof(WOW_BITMAP_PATTERN_T) +
+		WMI_TLV_HDR_SIZE +
+		0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
+		WMI_TLV_HDR_SIZE +
+		0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
+		WMI_TLV_HDR_SIZE +
+		0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
+		WMI_TLV_HDR_SIZE +
+		0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
+	buf_ptr = (uint8_t *) cmd;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->pattern_id = ptrn_id;
+
+	cmd->pattern_type = WOW_BITMAP_PATTERN;
+	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(WOW_BITMAP_PATTERN_T));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr;
+
+	WMITLV_SET_HDR(&bitmap_pattern->tlv_header,
+		       WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T,
+		       WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T));
+
+	qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len);
+	qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len);
+
+	bitmap_pattern->pattern_offset = ptrn_offset;
+	bitmap_pattern->pattern_len = ptrn_len;
+
+	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE)
+		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE;
+
+	if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE)
+		bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE;
+
+	bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len;
+	bitmap_pattern->pattern_id = ptrn_id;
+
+	WMI_LOGD("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d",
+		 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len,
+		 bitmap_pattern->pattern_offset, user);
+	WMI_LOGD("Pattern : ");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   &bitmap_pattern->patternbuf[0],
+			   bitmap_pattern->pattern_len);
+
+	WMI_LOGD("Mask : ");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   &bitmap_pattern->bitmaskbuf[0],
+			   bitmap_pattern->pattern_len);
+
+	buf_ptr += sizeof(WOW_BITMAP_PATTERN_T);
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for pattern_info_timeout but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for ratelimit_interval with dummy data as this fix elem */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	*(uint32_t *) buf_ptr = 0;
+
+	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * fill_arp_offload_params_tlv() - Fill ARP offload data
+ * @wmi_handle: wmi handle
+ * @offload_req: offload request
+ * @buf_ptr: buffer pointer
+ *
+ * To fill ARP offload data to firmware
+ * when target goes to wow mode.
+ *
+ * Return: None
+ */
+static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle,
+		struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr)
+{
+
+	int i;
+	WMI_ARP_OFFLOAD_TUPLE *arp_tuple;
+	bool enable_or_disable = offload_req->enable;
+
+	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		(WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE)));
+	*buf_ptr += WMI_TLV_HDR_SIZE;
+	for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
+		arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr;
+		WMITLV_SET_HDR(&arp_tuple->tlv_header,
+			WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE,
+			WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE));
+
+		/* Fill data for ARP and NS in the first tupple for LA */
+		if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) {
+			/* Copy the target ip addr and flags */
+			arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
+			qdf_mem_copy(&arp_tuple->target_ipaddr,
+					offload_req->host_ipv4_addr,
+					WMI_IPV4_ADDR_LEN);
+			WMI_LOGD("ARPOffload IP4 address: %pI4",
+					offload_req->host_ipv4_addr);
+		}
+		*buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE);
+	}
+}
+
+#ifdef WLAN_NS_OFFLOAD
+/**
+ * fill_ns_offload_params_tlv() - Fill NS offload data
+ * @wmi|_handle: wmi handle
+ * @offload_req: offload request
+ * @buf_ptr: buffer pointer
+ *
+ * To fill NS offload data to firmware
+ * when target goes to wow mode.
+ *
+ * Return: None
+ */
+static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
+		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
+{
+
+	int i;
+	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
+
+	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE)));
+	*buf_ptr += WMI_TLV_HDR_SIZE;
+	for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) {
+		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
+		WMITLV_SET_HDR(&ns_tuple->tlv_header,
+			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
+			(sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE));
+
+		/*
+		 * Fill data only for NS offload in the first ARP tuple for LA
+		 */
+		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
+			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
+			/* Copy the target/solicitation/remote ip addr */
+			if (ns_req->target_ipv6_addr_valid[i])
+				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
+					&ns_req->target_ipv6_addr[i],
+					sizeof(WMI_IPV6_ADDR));
+			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
+				&ns_req->self_ipv6_addr[i],
+				sizeof(WMI_IPV6_ADDR));
+			if (ns_req->target_ipv6_addr_ac_type[i]) {
+				ns_tuple->flags |=
+					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
+			}
+			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
+				i, &ns_req->self_ipv6_addr[i],
+				&ns_req->target_ipv6_addr[i]);
+
+			/* target MAC is optional, check if it is valid,
+			 * if this is not valid, the target will use the known
+			 * local MAC address rather than the tuple
+			 */
+			WMI_CHAR_ARRAY_TO_MAC_ADDR(
+				ns_req->self_macaddr.bytes,
+				&ns_tuple->target_mac);
+			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
+				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
+				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
+			}
+		}
+		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
+	}
+}
+
+/**
+ * fill_nsoffload_ext_tlv() - Fill NS offload ext data
+ * @wmi: wmi handle
+ * @offload_req: offload request
+ * @buf_ptr: buffer pointer
+ *
+ * To fill extended NS offload extended data to firmware
+ * when target goes to wow mode.
+ *
+ * Return: None
+ */
+static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
+		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
+{
+	int i;
+	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
+	uint32_t count, num_ns_ext_tuples;
+
+	count = ns_req->num_ns_offload_count;
+	num_ns_ext_tuples = ns_req->num_ns_offload_count -
+		WMI_MAX_NS_OFFLOADS;
+
+	/* Populate extended NS offload tuples */
+	WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		(num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE)));
+	*buf_ptr += WMI_TLV_HDR_SIZE;
+	for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) {
+		ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr;
+		WMITLV_SET_HDR(&ns_tuple->tlv_header,
+			WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
+			(sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE));
+
+		/*
+		 * Fill data only for NS offload in the first ARP tuple for LA
+		 */
+		if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) {
+			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
+			/* Copy the target/solicitation/remote ip addr */
+			if (ns_req->target_ipv6_addr_valid[i])
+				qdf_mem_copy(&ns_tuple->target_ipaddr[0],
+					&ns_req->target_ipv6_addr[i],
+					sizeof(WMI_IPV6_ADDR));
+			qdf_mem_copy(&ns_tuple->solicitation_ipaddr,
+				&ns_req->self_ipv6_addr[i],
+				sizeof(WMI_IPV6_ADDR));
+			if (ns_req->target_ipv6_addr_ac_type[i]) {
+				ns_tuple->flags |=
+					WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST;
+			}
+			WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6",
+				i, &ns_req->self_ipv6_addr[i],
+				&ns_req->target_ipv6_addr[i]);
+
+			/* target MAC is optional, check if it is valid,
+			 * if this is not valid, the target will use the
+			 * known local MAC address rather than the tuple
+			 */
+			 WMI_CHAR_ARRAY_TO_MAC_ADDR(
+				ns_req->self_macaddr.bytes,
+				&ns_tuple->target_mac);
+			if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
+				(ns_tuple->target_mac.mac_addr47to32 != 0)) {
+				ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
+			}
+		}
+		*buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
+	}
+}
+#else
+static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle,
+		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
+{
+}
+
+static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle,
+		struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr)
+{
+}
+#endif
+
+/**
+ * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload
+ * @wma: wmi handle
+ * @arp_offload_req: arp offload request
+ * @ns_offload_req: ns offload request
+ * @arp_only: flag
+ *
+ * To configure ARP NS off load data to firmware
+ * when target goes to wow mode.
+ *
+ * Return: QDF Status
+ */
+static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle,
+			   struct pmo_arp_offload_params *arp_offload_req,
+			   struct pmo_ns_offload_params *ns_offload_req,
+			   uint8_t vdev_id)
+{
+	int32_t res;
+	WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
+	uint8_t *buf_ptr;
+	wmi_buf_t buf;
+	int32_t len;
+	uint32_t count = 0, num_ns_ext_tuples = 0;
+
+	count = ns_offload_req->num_ns_offload_count;
+
+	/*
+	 * TLV place holder size for array of NS tuples
+	 * TLV place holder size for array of ARP tuples
+	 */
+	len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) +
+		WMI_TLV_HDR_SIZE +
+		WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) +
+		WMI_TLV_HDR_SIZE +
+		WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE);
+
+	/*
+	 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate
+	 * extra length for extended NS offload tuples which follows ARP offload
+	 * tuples. Host needs to fill this structure in following format:
+	 * 2 NS ofload tuples
+	 * 2 ARP offload tuples
+	 * N numbers of extended NS offload tuples if HDD has given more than
+	 * 2 NS offload addresses
+	 */
+	if (count > WMI_MAX_NS_OFFLOADS) {
+		num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS;
+		len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples
+			   * sizeof(WMI_NS_OFFLOAD_TUPLE);
+	}
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param));
+	cmd->flags = 0;
+	cmd->vdev_id = vdev_id;
+	cmd->num_ns_ext_tuples = num_ns_ext_tuples;
+
+	WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id);
+
+	buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param);
+	fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr);
+	fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr);
+	if (num_ns_ext_tuples)
+		fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr);
+
+	wmi_mtrace(WMI_SET_ARP_NS_OFFLOAD_CMDID, cmd->vdev_id, 0);
+	res = wmi_unified_cmd_send(wmi_handle, buf, len,
+				     WMI_SET_ARP_NS_OFFLOAD_CMDID);
+	if (res) {
+		WMI_LOGE("Failed to enable ARP NDP/NSffload");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @multicastAddr: mcast address
+ * @clearList: clear list flag
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
+				     uint8_t vdev_id,
+				     struct qdf_mac_addr multicast_addr,
+				     bool clearList)
+{
+	WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd;
+	wmi_buf_t buf;
+	int err;
+
+	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf);
+	qdf_mem_zero(cmd, sizeof(*cmd));
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	       WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param,
+	       WMITLV_GET_STRUCT_TLVLEN
+	       (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param));
+	cmd->action =
+		(clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET);
+	cmd->vdev_id = vdev_id;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr);
+
+	WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM",
+		 cmd->action, vdev_id, clearList, multicast_addr.bytes);
+
+	wmi_mtrace(WMI_SET_MCASTBCAST_FILTER_CMDID, cmd->vdev_id, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf,
+				   sizeof(*cmd),
+				   WMI_SET_MCASTBCAST_FILTER_CMDID);
+	if (err) {
+		WMI_LOGE("Failed to send set_param cmd");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple  mcast filter
+ *						   command to fw
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @mcast_filter_params: mcast filter params
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv(
+				wmi_unified_t wmi_handle,
+				uint8_t vdev_id,
+				struct pmo_mcast_filter_params *filter_param)
+
+{
+	WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd;
+	uint8_t *buf_ptr;
+	wmi_buf_t buf;
+	int err;
+	int i;
+	uint8_t *mac_addr_src_ptr = NULL;
+	wmi_mac_addr *mac_addr_dst_ptr;
+	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
+		       sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *)
+		wmi_buf_data(buf);
+	qdf_mem_zero(cmd, sizeof(*cmd));
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	       WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param,
+	       WMITLV_GET_STRUCT_TLVLEN
+	       (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param));
+	cmd->operation =
+		((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE
+					: WMI_MULTIPLE_MCAST_FILTER_ADD);
+	cmd->vdev_id = vdev_id;
+	cmd->num_mcastaddrs = filter_param->multicast_addr_cnt;
+
+	buf_ptr += sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
+		       sizeof(wmi_mac_addr) *
+			       filter_param->multicast_addr_cnt);
+
+	if (filter_param->multicast_addr_cnt == 0)
+		goto send_cmd;
+
+	mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr;
+	mac_addr_dst_ptr = (wmi_mac_addr *)
+			(buf_ptr + WMI_TLV_HDR_SIZE);
+
+	for (i = 0; i < filter_param->multicast_addr_cnt; i++) {
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr);
+		mac_addr_src_ptr += ATH_MAC_LEN;
+		mac_addr_dst_ptr++;
+	}
+
+send_cmd:
+	wmi_mtrace(WMI_SET_MULTIPLE_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf,
+				   len,
+				   WMI_SET_MULTIPLE_MCAST_FILTER_CMDID);
+	if (err) {
+		WMI_LOGE("Failed to send set_param cmd");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi,
+					      struct pmo_hw_filter_params *req)
+{
+	QDF_STATUS status;
+	wmi_hw_data_filter_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+
+	if (!req) {
+		WMI_LOGE("req is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd));
+	if (!wmi_buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		  WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param,
+		  WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param));
+	cmd->vdev_id = req->vdev_id;
+	cmd->enable = req->enable;
+	/* Set all modes in case of disable */
+	if (!cmd->enable)
+		cmd->hw_filter_bitmap = ((uint32_t)~0U);
+	else
+		cmd->hw_filter_bitmap = req->mode_bitmap;
+
+	WMI_LOGD("Send %s hw filter mode: 0x%X for vdev id %d",
+		 req->enable ? "enable" : "disable", req->mode_bitmap,
+		 req->vdev_id);
+
+	wmi_mtrace(WMI_HW_DATA_FILTER_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd),
+				      WMI_HW_DATA_FILTER_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("Failed to configure hw filter");
+		wmi_buf_free(wmi_buf);
+	}
+
+	return status;
+}
+
+static void
+fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd,
+			  uint8_t vdev_id,
+			  struct pmo_gtk_req *params)
+{
+	uint8_t *buf_ptr;
+	wmi_gtk_offload_fils_tlv_param *ext_param;
+
+	buf_ptr = (uint8_t *) cmd + sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(*ext_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr;
+	WMITLV_SET_HDR(&ext_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				wmi_gtk_offload_fils_tlv_param));
+	ext_param->vdev_id = vdev_id;
+	ext_param->flags = cmd->flags;
+	ext_param->kek_len = params->kek_len;
+	qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len);
+	qdf_mem_copy(ext_param->KCK, params->kck,
+		     WMI_GTK_OFFLOAD_KCK_BYTES);
+	qdf_mem_copy(ext_param->replay_counter, &params->replay_counter,
+		     GTK_REPLAY_COUNTER_BYTES);
+}
+
+/**
+ * send_gtk_offload_cmd_tlv() - send GTK offload command to fw
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @params: GTK offload parameters
+ *
+ * Return: CDF status
+ */
+static
+QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
+				    struct pmo_gtk_req *params,
+				    bool enable_offload,
+				    uint32_t gtk_offload_opcode)
+{
+	int len;
+	wmi_buf_t buf;
+	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	WMI_LOGD("%s Enter", __func__);
+
+	len = sizeof(*cmd);
+
+	if (params->is_fils_connection)
+		len += WMI_TLV_HDR_SIZE +
+		       sizeof(wmi_gtk_offload_fils_tlv_param);
+
+	/* alloc wmi buffer */
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+
+	/* Request target to enable GTK offload */
+	if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) {
+		cmd->flags = gtk_offload_opcode;
+
+		/* Copy the keys and replay counter */
+		qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN);
+		qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY);
+		qdf_mem_copy(cmd->replay_counter, &params->replay_counter,
+			     GTK_REPLAY_COUNTER_BYTES);
+	} else {
+		cmd->flags = gtk_offload_opcode;
+	}
+	if (params->is_fils_connection)
+		fill_fils_tlv_params(cmd, vdev_id, params);
+
+	WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len);
+	/* send the wmi command */
+	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_GTK_OFFLOAD_CMDID)) {
+		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID");
+		wmi_buf_free(buf);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+out:
+	WMI_LOGD("%s Exit", __func__);
+	return status;
+}
+
+/**
+ * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw
+ * @wmi_handle: wmi handle
+ * @params: GTK offload params
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv(
+			wmi_unified_t wmi_handle,
+			uint8_t vdev_id,
+			uint64_t offload_req_opcode)
+{
+	int len;
+	wmi_buf_t buf;
+	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	len = sizeof(*cmd);
+
+	/* alloc wmi buffer */
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (WMI_GTK_OFFLOAD_CMD_fixed_param));
+
+	/* Request for GTK offload status */
+	cmd->flags = offload_req_opcode;
+	cmd->vdev_id = vdev_id;
+
+	/* send the wmi command */
+	wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_GTK_OFFLOAD_CMDID)) {
+		WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info");
+		wmi_buf_free(buf);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+out:
+	return status;
+}
+
+/**
+ * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @action: true for enable else false
+ *
+ * To enable enhance multicast offload to firmware
+ * when target goes to wow mode.
+ *
+ * Return: QDF Status
+ */
+
+static
+QDF_STATUS send_enable_enhance_multicast_offload_tlv(
+		wmi_unified_t wmi_handle,
+		uint8_t vdev_id, bool action)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf;
+	wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd;
+
+	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *)
+							wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_config_enhanced_mcast_filter_cmd_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+	cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED :
+			ENHANCED_MCAST_FILTER_ENABLED);
+	WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d",
+		__func__, action, vdev_id);
+	wmi_mtrace(WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+			sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID);
+	if (status != QDF_STATUS_SUCCESS) {
+		wmi_buf_free(buf);
+		WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID",
+			__func__);
+	}
+
+	return status;
+}
+
+/**
+ * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param hdr: Pointer to hold header
+ * @param bufp: Pointer to hold pointer to rx param buffer
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle,
+	void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len)
+{
+	WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param;
+	WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf;
+
+	param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf;
+	if (!param_buf) {
+		WMI_LOGE("gtk param_buf is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) {
+		WMI_LOGE("Invalid length for GTK status");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *)
+		param_buf->fixed_param;
+
+	if (fixed_param->vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
+		wmi_err_rl("Invalid vdev_id %u", fixed_param->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	gtk_rsp_param->vdev_id = fixed_param->vdev_id;
+	gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS;
+	gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt;
+	qdf_mem_copy(&gtk_rsp_param->replay_counter,
+		&fixed_param->replay_counter,
+		GTK_REPLAY_COUNTER_BYTES);
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+/**
+ * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle,
+						 uint8_t vdev_id,
+						 uint8_t default_pattern,
+						 uint16_t rate_limit_interval)
+{
+
+	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int32_t len;
+	int ret;
+
+	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
+	      WMI_TLV_HDR_SIZE +
+	      0 * sizeof(WOW_BITMAP_PATTERN_T) +
+	      WMI_TLV_HDR_SIZE +
+	      0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
+	      WMI_TLV_HDR_SIZE +
+	      0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
+	      WMI_TLV_HDR_SIZE +
+	      0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
+	      WMI_TLV_HDR_SIZE +
+	      0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
+	buf_ptr = (uint8_t *) cmd;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->pattern_id = default_pattern,
+	cmd->pattern_type = WOW_IPV6_RA_PATTERN;
+	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for pattern_info_timeout but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for ra_ratelimit_interval. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	*((uint32_t *) buf_ptr) = rate_limit_interval;
+
+	WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__,
+		 rate_limit_interval, vdev_id);
+
+	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_ra_filtering_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv;
+}
+#endif /* FEATURE_WLAN_RA_FILTERING */
+
+/**
+ * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params
+ * @wmi_handle: wmi handler
+ * @action_params: pointer to action_params
+ *
+ * Return: 0 for success, otherwise appropriate error code
+ */
+static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle,
+		struct pmo_action_wakeup_set_params *action_params)
+{
+	WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd;
+	wmi_buf_t buf;
+	int i;
+	int32_t err;
+	uint32_t len = 0, *cmd_args;
+	uint8_t *buf_ptr;
+
+	len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))
+				+ WMI_TLV_HDR_SIZE + sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf);
+	buf_ptr = (uint8_t *)cmd;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+				WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param));
+
+	cmd->vdev_id = action_params->vdev_id;
+	cmd->operation = action_params->operation;
+
+	for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++)
+		cmd->action_category_map[i] =
+				action_params->action_category_map[i];
+
+	buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		       (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	cmd_args = (uint32_t *) buf_ptr;
+	for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++)
+		cmd_args[i] = action_params->action_per_category[i];
+
+	wmi_mtrace(WMI_WOW_SET_ACTION_WAKE_UP_CMDID, cmd->vdev_id, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf,
+				   len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID);
+	if (err) {
+		WMI_LOGE("Failed to send ap_ps_egap cmd");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_LPHB
+/**
+ * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration
+ * @wmi_handle: wmi handle
+ * @lphb_conf_req: configuration info
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle,
+				wmi_hb_set_enable_cmd_fixed_param *params)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	uint8_t *buf_ptr;
+	wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp;
+	int len = sizeof(wmi_hb_set_enable_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&hb_enable_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_hb_set_enable_cmd_fixed_param));
+
+	/* fill in values */
+	hb_enable_fp->vdev_id = params->session;
+	hb_enable_fp->enable = params->enable;
+	hb_enable_fp->item = params->item;
+	hb_enable_fp->session = params->session;
+
+	wmi_mtrace(WMI_HB_SET_ENABLE_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_HB_SET_ENABLE_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration
+ * @wmi_handle: wmi handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle,
+	    wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	uint8_t *buf_ptr;
+	wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp;
+	int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_hb_set_tcp_params_cmd_fixed_param));
+
+	/* fill in values */
+	hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id;
+	hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip;
+	hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip;
+	hb_tcp_params_fp->seq = lphb_conf_req->seq;
+	hb_tcp_params_fp->src_port = lphb_conf_req->src_port;
+	hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port;
+	hb_tcp_params_fp->interval = lphb_conf_req->interval;
+	hb_tcp_params_fp->timeout = lphb_conf_req->timeout;
+	hb_tcp_params_fp->session = lphb_conf_req->session;
+	qdf_mem_copy(&hb_tcp_params_fp->gateway_mac,
+		     &lphb_conf_req->gateway_mac,
+		     sizeof(hb_tcp_params_fp->gateway_mac));
+
+	wmi_mtrace(WMI_HB_SET_TCP_PARAMS_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_HB_SET_TCP_PARAMS_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd
+ * @wmi_handle: wmi handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+static
+QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
+		wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	uint8_t *buf_ptr;
+	wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp;
+	int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	hb_tcp_filter_fp =
+		(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header,
+		WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param));
+
+	/* fill in values */
+	hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id;
+	hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length;
+	hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset;
+	hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session;
+	memcpy((void *)&hb_tcp_filter_fp->filter,
+	       (void *)&g_hb_tcp_filter_fp->filter,
+	       WMI_WLAN_HB_MAX_FILTER_SIZE);
+
+	wmi_mtrace(WMI_HB_SET_TCP_PKT_FILTER_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_HB_SET_TCP_PKT_FILTER_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB
+ * @wmi_handle: wmi handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle,
+		   wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	uint8_t *buf_ptr;
+	wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp;
+	int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_hb_set_udp_params_cmd_fixed_param));
+
+	/* fill in values */
+	hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id;
+	hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip;
+	hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip;
+	hb_udp_params_fp->src_port = lphb_conf_req->src_port;
+	hb_udp_params_fp->dst_port = lphb_conf_req->dst_port;
+	hb_udp_params_fp->interval = lphb_conf_req->interval;
+	hb_udp_params_fp->timeout = lphb_conf_req->timeout;
+	hb_udp_params_fp->session = lphb_conf_req->session;
+	qdf_mem_copy(&hb_udp_params_fp->gateway_mac,
+		     &lphb_conf_req->gateway_mac,
+		     sizeof(lphb_conf_req->gateway_mac));
+
+	wmi_mtrace(WMI_HB_SET_UDP_PARAMS_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_HB_SET_UDP_PARAMS_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command
+ * @wmi_handle: wmi handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+static
+QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
+		wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	uint8_t *buf_ptr;
+	wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp;
+	int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	hb_udp_filter_fp =
+		(wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header,
+		WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_hb_set_udp_pkt_filter_cmd_fixed_param));
+
+	/* fill in values */
+	hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id;
+	hb_udp_filter_fp->length = lphb_conf_req->length;
+	hb_udp_filter_fp->offset = lphb_conf_req->offset;
+	hb_udp_filter_fp->session = lphb_conf_req->session;
+	memcpy((void *)&hb_udp_filter_fp->filter,
+	       (void *)&lphb_conf_req->filter,
+	       WMI_WLAN_HB_MAX_FILTER_SIZE);
+
+	wmi_mtrace(WMI_HB_SET_UDP_PKT_FILTER_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_HB_SET_UDP_PKT_FILTER_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+void wmi_lphb_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_lphb_config_hbenable_cmd =
+		send_lphb_config_hbenable_cmd_tlv;
+	ops->send_lphb_config_tcp_params_cmd =
+		send_lphb_config_tcp_params_cmd_tlv;
+	ops->send_lphb_config_tcp_pkt_filter_cmd =
+		send_lphb_config_tcp_pkt_filter_cmd_tlv;
+	ops->send_lphb_config_udp_params_cmd =
+		send_lphb_config_udp_params_cmd_tlv;
+	ops->send_lphb_config_udp_pkt_filter_cmd =
+		send_lphb_config_udp_pkt_filter_cmd_tlv;
+}
+#endif /* FEATURE_WLAN_LPHB */
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/**
+ * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @enable: Flag to enable/disable packet filter
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv(
+		wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable)
+{
+	int32_t len;
+	int ret = 0;
+	wmi_buf_t buf;
+	WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd;
+
+	len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			WMI_PACKET_FILTER_ENABLE_CMD_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+	if (enable)
+		cmd->enable = PACKET_FILTER_SET_ENABLE;
+	else
+		cmd->enable = PACKET_FILTER_SET_DISABLE;
+
+	WMI_LOGE("%s: Packet filter enable %d for vdev_id %d",
+		 __func__, cmd->enable, vdev_id);
+
+	wmi_mtrace(WMI_PACKET_FILTER_ENABLE_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_PACKET_FILTER_ENABLE_CMDID);
+	if (ret) {
+		WMI_LOGE("Failed to send packet filter wmi cmd to fw");
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_config_packet_filter_cmd_tlv() - configure packet filter in target
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @rcv_filter_param: Packet filter parameters
+ * @filter_id: Filter id
+ * @enable: Flag to add/delete packet filter configuration
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle,
+		uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param,
+		uint8_t filter_id, bool enable)
+{
+	int len, i;
+	int err = 0;
+	wmi_buf_t buf;
+	WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd;
+
+	/* allocate the memory */
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+			       (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+	cmd->filter_id = filter_id;
+	if (enable)
+		cmd->filter_action = PACKET_FILTER_SET_ACTIVE;
+	else
+		cmd->filter_action = PACKET_FILTER_SET_INACTIVE;
+
+	if (enable) {
+		cmd->num_params = QDF_MIN(
+			WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER,
+			rcv_filter_param->num_params);
+		cmd->filter_type = rcv_filter_param->filter_type;
+		cmd->coalesce_time = rcv_filter_param->coalesce_time;
+
+		for (i = 0; i < cmd->num_params; i++) {
+			cmd->paramsData[i].proto_type =
+				rcv_filter_param->params_data[i].protocol_layer;
+			cmd->paramsData[i].cmp_type =
+				rcv_filter_param->params_data[i].compare_flag;
+			cmd->paramsData[i].data_length =
+				rcv_filter_param->params_data[i].data_length;
+			cmd->paramsData[i].data_offset =
+				rcv_filter_param->params_data[i].data_offset;
+			memcpy(&cmd->paramsData[i].compareData,
+				rcv_filter_param->params_data[i].compare_data,
+				sizeof(cmd->paramsData[i].compareData));
+			memcpy(&cmd->paramsData[i].dataMask,
+				rcv_filter_param->params_data[i].data_mask,
+				sizeof(cmd->paramsData[i].dataMask));
+		}
+	}
+
+	WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d",
+		 cmd->filter_action, cmd->filter_id, cmd->num_params);
+	/* send the command along with data */
+	wmi_mtrace(WMI_PACKET_FILTER_CONFIG_CMDID, cmd->vdev_id, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_PACKET_FILTER_CONFIG_CMDID);
+	if (err) {
+		WMI_LOGE("Failed to send pkt_filter cmd");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_packet_filtering_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_enable_disable_packet_filter_cmd =
+		send_enable_disable_packet_filter_cmd_tlv;
+	ops->send_config_packet_filter_cmd =
+		send_config_packet_filter_cmd_tlv;
+}
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+
+/**
+ * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target
+ * @wmi_handle: wmi handle
+ * @ptrn_id: pattern id
+ * @vdev_id: vdev id
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle,
+						  uint8_t ptrn_id,
+						  uint8_t vdev_id)
+{
+	WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	int ret;
+
+	len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				WMI_WOW_DEL_PATTERN_CMD_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->pattern_id = ptrn_id;
+	cmd->pattern_type = WOW_BITMAP_PATTERN;
+
+	WMI_LOGI("Deleting pattern id: %d vdev id %d in fw",
+		 cmd->pattern_id, vdev_id);
+
+	wmi_mtrace(WMI_WOW_DEL_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_WOW_DEL_WAKE_PATTERN_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw
+ * @wmi_handle: wmi handle
+ *
+ * Sends host wakeup indication to FW. On receiving this indication,
+ * FW will come out of WOW.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
+{
+	wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int32_t len;
+	int ret;
+
+	len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *)
+	      wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+			(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param));
+
+	wmi_mtrace(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
+	if (ret) {
+		WMI_LOGE("Failed to send host wakeup indication to fw");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return qdf_status;
+}
+
+/**
+ * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware
+ * will wake up host after specified time is elapsed
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @cookie: value to identify reason why host set up wake call.
+ * @time: time in ms
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle,
+				uint8_t vdev_id, uint32_t cookie, uint32_t time)
+{
+	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int32_t len;
+	int ret;
+
+	len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
+		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) +
+		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
+		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
+		WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
+		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) +
+		WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
+	buf_ptr = (uint8_t *) cmd;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+			(WMI_WOW_ADD_PATTERN_CMD_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->pattern_id = cookie,
+	cmd->pattern_type = WOW_TIMER_PATTERN;
+	buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	/* Fill TLV for pattern_info_timeout, and time value */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	*((uint32_t *) buf_ptr) = time;
+	buf_ptr += sizeof(uint32_t);
+
+	/* Fill TLV for ra_ratelimit_interval. with dummy 0 value */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	*((uint32_t *) buf_ptr) = 0;
+
+	WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d",
+		__func__, time, vdev_id);
+
+	wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				WMI_WOW_ADD_WAKE_PATTERN_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send wake timer pattern to fw",
+			__func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+/**
+ * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw
+ * @wmi_handle: wmi handle
+ * @params: ext wow params
+ *
+ * Return:0 for success or error code
+ */
+static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle,
+					      struct ext_wow_params *params)
+{
+	wmi_extwow_enable_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	int ret;
+
+	len = sizeof(wmi_extwow_enable_cmd_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_extwow_enable_cmd_fixed_param));
+
+	cmd->vdev_id = params->vdev_id;
+	cmd->type = params->type;
+	cmd->wakeup_pin_num = params->wakeup_pin_num;
+
+	WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x",
+		 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num);
+
+	wmi_mtrace(WMI_EXTWOW_ENABLE_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_EXTWOW_ENABLE_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+/**
+ * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw
+ * @wmi_handle: wmi handle
+ * @appType2Params: app type2 params
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
+			  struct app_type2_params *appType2Params)
+{
+	wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	int ret;
+
+	len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *)
+	      wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param,
+	       WMITLV_GET_STRUCT_TLVLEN
+			(wmi_extwow_set_app_type2_params_cmd_fixed_param));
+
+	cmd->vdev_id = appType2Params->vdev_id;
+
+	qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16);
+	cmd->rc4_key_len = appType2Params->rc4_key_len;
+
+	cmd->ip_id = appType2Params->ip_id;
+	cmd->ip_device_ip = appType2Params->ip_device_ip;
+	cmd->ip_server_ip = appType2Params->ip_server_ip;
+
+	cmd->tcp_src_port = appType2Params->tcp_src_port;
+	cmd->tcp_dst_port = appType2Params->tcp_dst_port;
+	cmd->tcp_seq = appType2Params->tcp_seq;
+	cmd->tcp_ack_seq = appType2Params->tcp_ack_seq;
+
+	cmd->keepalive_init = appType2Params->keepalive_init;
+	cmd->keepalive_min = appType2Params->keepalive_min;
+	cmd->keepalive_max = appType2Params->keepalive_max;
+	cmd->keepalive_inc = appType2Params->keepalive_inc;
+
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes,
+				   &cmd->gateway_mac);
+	cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
+	cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
+
+	WMI_LOGD("%s: vdev_id %d gateway_mac %pM "
+		 "rc4_key %.16s rc4_key_len %u "
+		 "ip_id %x ip_device_ip %x ip_server_ip %x "
+		 "tcp_src_port %u tcp_dst_port %u tcp_seq %u "
+		 "tcp_ack_seq %u keepalive_init %u keepalive_min %u "
+		 "keepalive_max %u keepalive_inc %u "
+		 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u",
+		 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes,
+		 cmd->rc4_key, cmd->rc4_key_len,
+		 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip,
+		 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq,
+		 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min,
+		 cmd->keepalive_max, cmd->keepalive_inc,
+		 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val);
+
+	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+/**
+ * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw
+ * @wmi_handle: wmi handle
+ * @app_type1_params: app type1 params
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
+				   struct app_type1_params *app_type1_params)
+{
+	wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	int ret;
+
+	len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *)
+	      wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	       WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param,
+	       WMITLV_GET_STRUCT_TLVLEN
+	       (wmi_extwow_set_app_type1_params_cmd_fixed_param));
+
+	cmd->vdev_id = app_type1_params->vdev_id;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes,
+				   &cmd->wakee_mac);
+	qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8);
+	cmd->ident_len = app_type1_params->id_length;
+	qdf_mem_copy(cmd->passwd, app_type1_params->password, 16);
+	cmd->passwd_len = app_type1_params->pass_length;
+
+	WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM "
+		 "identification_id %.8s id_length %u "
+		 "password %.16s pass_length %u",
+		 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes,
+		 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len);
+
+	wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_extwow_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv;
+	ops->send_set_app_type2_params_in_fw_cmd =
+		send_set_app_type2_params_in_fw_cmd_tlv;
+	ops->send_app_type1_params_in_fw_cmd =
+		send_app_type1_params_in_fw_cmd_tlv;
+}
+#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
+
+void wmi_pmo_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_add_wow_wakeup_event_cmd =
+		send_add_wow_wakeup_event_cmd_tlv;
+	ops->send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv;
+	ops->send_enable_arp_ns_offload_cmd =
+		send_enable_arp_ns_offload_cmd_tlv;
+	ops->send_add_clear_mcbc_filter_cmd =
+		send_add_clear_mcbc_filter_cmd_tlv;
+	ops->send_multiple_add_clear_mcbc_filter_cmd =
+		send_multiple_add_clear_mcbc_filter_cmd_tlv;
+	ops->send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv;
+	ops->send_gtk_offload_cmd = send_gtk_offload_cmd_tlv;
+	ops->send_process_gtk_offload_getinfo_cmd =
+		send_process_gtk_offload_getinfo_cmd_tlv;
+	ops->send_enable_enhance_multicast_offload_cmd =
+		send_enable_enhance_multicast_offload_tlv;
+	ops->extract_gtk_rsp_event = extract_gtk_rsp_event_tlv;
+	ops->send_action_frame_patterns_cmd =
+		send_action_frame_patterns_cmd_tlv;
+	ops->send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv;
+	ops->send_host_wakeup_ind_to_fw_cmd =
+		send_host_wakeup_ind_to_fw_cmd_tlv;
+	ops->send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv;
+
+	wmi_d0wow_attach_tlv(wmi_handle);
+	wmi_ra_filtering_attach_tlv(wmi_handle);
+	wmi_lphb_attach_tlv(wmi_handle);
+	wmi_packet_filtering_attach_tlv(wmi_handle);
+	wmi_extwow_attach_tlv(wmi_handle);
+}

+ 314 - 0
wmi_unified_roam_api.c

@@ -0,0 +1,314 @@
+
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <osdep.h>
+#include <wmi.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_roam_param.h>
+#include <wmi_unified_roam_api.h>
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+QDF_STATUS wmi_unified_set_gateway_params_cmd(void *wmi_hdl,
+					struct gateway_update_req_param *req)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_gateway_params_cmd)
+		return wmi_handle->ops->send_set_gateway_params_cmd(wmi_handle,
+								    req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+#ifdef FEATURE_RSSI_MONITOR
+QDF_STATUS wmi_unified_set_rssi_monitoring_cmd(void *wmi_hdl,
+					struct rssi_monitor_param *req)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_rssi_monitoring_cmd)
+		return wmi_handle->ops->send_set_rssi_monitoring_cmd(wmi_handle,
+								     req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_RSSI_MONITOR */
+
+QDF_STATUS wmi_unified_roam_scan_offload_rssi_thresh_cmd(void *wmi_hdl,
+					struct roam_offload_scan_rssi_params
+					*roam_req)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_offload_rssi_thresh_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_rssi_thresh_cmd(
+				wmi_handle, roam_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_mawc_params_cmd(
+			void *wmi_hdl, struct wmi_mawc_roam_params *params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_mawc_params_cmd)
+		return wmi_handle->ops->send_roam_mawc_params_cmd(wmi_handle,
+								  params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_scan_filter_cmd(void *wmi_hdl,
+				struct roam_scan_filter_params *roam_req)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_filter_cmd)
+		return wmi_handle->ops->send_roam_scan_filter_cmd(wmi_handle,
+								  roam_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS wmi_unified_plm_stop_cmd(void *wmi_hdl,
+			  const struct plm_req_params *plm)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_plm_stop_cmd)
+		return wmi_handle->ops->send_plm_stop_cmd(wmi_handle, plm);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_plm_start_cmd(void *wmi_hdl,
+			  const struct plm_req_params *plm,
+			  uint32_t *gchannel_list)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_plm_start_cmd)
+		return wmi_handle->ops->send_plm_start_cmd(wmi_handle,
+							   plm,
+							   gchannel_list);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS wmi_unified_set_ric_req_cmd(void *wmi_hdl, void *msg,
+		uint8_t is_add_ts)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_ric_req_cmd)
+		return wmi_handle->ops->send_set_ric_req_cmd(wmi_handle, msg,
+							     is_add_ts);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_synch_complete_cmd(void *wmi_hdl,
+		 uint8_t vdev_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_process_roam_synch_complete_cmd)
+		return wmi_handle->ops->send_process_roam_synch_complete_cmd(
+				wmi_handle, vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_invoke_cmd(void *wmi_hdl,
+				       struct wmi_roam_invoke_cmd *roaminvoke,
+				       uint32_t ch_hz)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_invoke_cmd)
+		return wmi_handle->ops->send_roam_invoke_cmd(wmi_handle,
+							     roaminvoke,
+							     ch_hz);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+QDF_STATUS wmi_unified_roam_scan_offload_mode_cmd(void *wmi_hdl,
+				wmi_start_scan_cmd_fixed_param *scan_cmd_fp,
+				struct roam_offload_scan_params *roam_req)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_offload_mode_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_mode_cmd(
+				wmi_handle, scan_cmd_fp, roam_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_send_roam_scan_offload_ap_cmd(void *wmi_hdl,
+					   struct ap_profile_params *ap_profile)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_offload_ap_profile_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_ap_profile_cmd(
+				  wmi_handle, ap_profile);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_scan_offload_cmd(void *wmi_hdl,
+					 uint32_t command, uint32_t vdev_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_offload_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_cmd(wmi_handle,
+								   command,
+								   vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_scan_offload_scan_period(void *wmi_hdl,
+					     uint32_t scan_period,
+					     uint32_t scan_age,
+					     uint32_t vdev_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_offload_scan_period_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_scan_period_cmd(wmi_handle,
+				  scan_period, scan_age, vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_scan_offload_chan_list_cmd(void *wmi_hdl,
+				   uint8_t chan_count,
+				   uint32_t *chan_list,
+				   uint8_t list_type, uint32_t vdev_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_offload_chan_list_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_chan_list_cmd(wmi_handle,
+				  chan_count, chan_list,
+				  list_type, vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_scan_offload_rssi_change_cmd(void *wmi_hdl,
+	uint32_t vdev_id,
+	int32_t rssi_change_thresh,
+	uint32_t bcn_rssi_weight,
+	uint32_t hirssi_delay_btw_scans)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_offload_rssi_change_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_rssi_change_cmd(wmi_handle,
+				  vdev_id, rssi_change_thresh,
+				  bcn_rssi_weight, hirssi_delay_btw_scans);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_per_roam_config(void *wmi_hdl,
+		struct wmi_per_roam_config_req *req_buf)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_per_roam_config_cmd)
+		return wmi_handle->ops->send_per_roam_config_cmd(wmi_handle,
+								 req_buf);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_send_limit_off_chan_cmd(void *wmi_hdl,
+		struct wmi_limit_off_chan_param *limit_off_chan_param)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_limit_off_chan_cmd)
+		return wmi_handle->ops->send_limit_off_chan_cmd(wmi_handle,
+				limit_off_chan_param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+QDF_STATUS wmi_unified_roam_send_hlp_cmd(void *wmi_hdl,
+					 struct hlp_params *req_buf)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_roam_scan_hlp_cmd)
+		return wmi_handle->ops->send_roam_scan_hlp_cmd(wmi_handle,
+							       req_buf);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* WLAN_FEATURE_FILS_SK */
+
+QDF_STATUS wmi_unified_send_btm_config(void *wmi_hdl,
+				       struct wmi_btm_config *params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_btm_config)
+		return wmi_handle->ops->send_btm_config(wmi_handle,
+							params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_offload_11k_cmd(void *wmi_hdl,
+				struct wmi_11k_offload_params *params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_offload_11k_cmd)
+		return wmi_handle->ops->send_offload_11k_cmd(wmi_handle,
+							     params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_invoke_neighbor_report_cmd(void *wmi_hdl,
+			struct wmi_invoke_neighbor_report_params *params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_invoke_neighbor_report_cmd)
+		return wmi_handle->ops->send_invoke_neighbor_report_cmd(
+				wmi_handle, params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+

+ 2224 - 0
wmi_unified_roam_tlv.c

@@ -0,0 +1,2224 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+/**
+ * DOC: Implement API's specific to roaming component.
+ */
+
+#include <wmi_unified_priv.h>
+#include <wmi_unified_roam_api.h>
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/**
+ * send_set_gateway_params_cmd_tlv() - set gateway parameters
+ * @wmi_handle: wmi handle
+ * @req: gateway parameter update request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and sends down the gateway configs down to the firmware
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
+				struct gateway_update_req_param *req)
+{
+	wmi_roam_subnet_change_config_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS ret;
+	int len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_roam_subnet_change_config_fixed_param));
+
+	cmd->vdev_id = req->session_id;
+	qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
+		     QDF_IPV4_ADDR_SIZE);
+	qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
+		     QDF_IPV6_ADDR_SIZE);
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
+				   &cmd->inet_gw_mac_addr);
+	cmd->max_retries = req->max_retries;
+	cmd->timeout = req->timeout;
+	cmd->num_skip_subnet_change_detection_bssid_list = 0;
+	cmd->flag = 0;
+	if (req->ipv4_addr_type)
+		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
+
+	if (req->ipv6_addr_type)
+		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
+
+	wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
+			 ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+void wmi_lfr_subnet_detection_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_gateway_params_cmd = send_set_gateway_params_cmd_tlv;
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+#ifdef FEATURE_RSSI_MONITOR
+/**
+ * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
+ * @wmi_handle: wmi handle
+ * @req: rssi monitoring request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and send down the rssi monitoring configs down to the firmware
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
+					struct rssi_monitor_param *req)
+{
+	wmi_rssi_breach_monitor_config_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS ret;
+	uint32_t len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_rssi_breach_monitor_config_fixed_param));
+
+	cmd->vdev_id = req->session_id;
+	cmd->request_id = req->request_id;
+	cmd->lo_rssi_reenable_hysteresis = 0;
+	cmd->hi_rssi_reenable_histeresis = 0;
+	cmd->min_report_interval = 0;
+	cmd->max_num_report = 1;
+	if (req->control) {
+		/* enable one threshold for each min/max */
+		cmd->enabled_bitmap = 0x09;
+		cmd->low_rssi_breach_threshold[0] = req->min_rssi;
+		cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
+	} else {
+		cmd->enabled_bitmap = 0;
+		cmd->low_rssi_breach_threshold[0] = 0;
+		cmd->hi_rssi_breach_threshold[0] = 0;
+	}
+
+	wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
+		wmi_buf_free(buf);
+	}
+
+	WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
+
+	return ret;
+}
+
+void wmi_rssi_monitor_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_rssi_monitoring_cmd = send_set_rssi_monitoring_cmd_tlv;
+}
+#endif /* FEATURE_RSSI_MONITOR */
+
+/**
+ * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
+ *                                                rssi threashold
+ * @wmi_handle: wmi handle
+ * @roam_req:   Roaming request buffer
+ *
+ * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,
+				struct roam_offload_scan_rssi_params *roam_req)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
+	wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
+	wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
+	wmi_roam_dense_thres_param *dense_thresholds = NULL;
+	wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
+
+	len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
+	len += sizeof(wmi_roam_scan_extended_threshold_param);
+	len += WMI_TLV_HDR_SIZE;
+	len += sizeof(wmi_roam_earlystop_rssi_thres_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
+	len += sizeof(wmi_roam_dense_thres_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
+	len += sizeof(wmi_roam_bg_scan_roaming_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	rssi_threshold_fp =
+		(wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
+		      WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
+		      WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_scan_rssi_threshold_fixed_param));
+	/* fill in threshold values */
+	rssi_threshold_fp->vdev_id = roam_req->session_id;
+	rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
+	rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
+	rssi_threshold_fp->hirssi_scan_max_count =
+			roam_req->hi_rssi_scan_max_count;
+	rssi_threshold_fp->hirssi_scan_delta =
+			roam_req->hi_rssi_scan_rssi_delta;
+	rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
+	rssi_threshold_fp->rssi_thresh_offset_5g =
+		roam_req->rssi_thresh_offset_5g;
+
+	buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_scan_extended_threshold_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr;
+
+	ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
+	if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
+		ext_thresholds->boost_threshold_5g =
+					roam_req->boost_threshold_5g;
+
+	ext_thresholds->boost_algorithm_5g =
+		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
+	ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
+	ext_thresholds->penalty_algorithm_5g =
+		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
+	ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
+	ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
+	ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
+	ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
+
+	WMITLV_SET_HDR(&ext_thresholds->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
+		WMITLV_GET_STRUCT_TLVLEN
+			(wmi_roam_scan_extended_threshold_param));
+	buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_earlystop_rssi_thres_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr;
+	early_stop_thresholds->roam_earlystop_thres_min =
+		roam_req->roam_earlystop_thres_min;
+	early_stop_thresholds->roam_earlystop_thres_max =
+		roam_req->roam_earlystop_thres_max;
+	WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_earlystop_rssi_thres_param));
+
+	buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_dense_thres_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr;
+	dense_thresholds->roam_dense_rssi_thres_offset =
+			roam_req->dense_rssi_thresh_offset;
+	dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
+	dense_thresholds->roam_dense_traffic_thres =
+			roam_req->traffic_threshold;
+	dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
+	WMITLV_SET_HDR(&dense_thresholds->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_dense_thres_param));
+
+	buf_ptr += sizeof(wmi_roam_dense_thres_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_bg_scan_roaming_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr;
+	bg_scan_params->roam_bg_scan_bad_rssi_thresh =
+		roam_req->bg_scan_bad_rssi_thresh;
+	bg_scan_params->roam_bg_scan_client_bitmap =
+		roam_req->bg_scan_client_bitmap;
+	bg_scan_params->bad_rssi_thresh_offset_2g =
+		roam_req->roam_bad_rssi_thresh_offset_2g;
+	bg_scan_params->flags = roam_req->flags;
+	WMITLV_SET_HDR(&bg_scan_params->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_roam_bg_scan_roaming_param));
+
+	wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
+		struct wmi_mawc_roam_params *params)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
+
+	len = sizeof(*wmi_roam_mawc_params);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	wmi_roam_mawc_params =
+		(wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_configure_mawc_cmd_fixed_param));
+	wmi_roam_mawc_params->vdev_id = params->vdev_id;
+	if (params->enable)
+		wmi_roam_mawc_params->enable = 1;
+	else
+		wmi_roam_mawc_params->enable = 0;
+	wmi_roam_mawc_params->traffic_load_threshold =
+		params->traffic_load_threshold;
+	wmi_roam_mawc_params->best_ap_rssi_threshold =
+		params->best_ap_rssi_threshold;
+	wmi_roam_mawc_params->rssi_stationary_high_adjust =
+		params->rssi_stationary_high_adjust;
+	wmi_roam_mawc_params->rssi_stationary_low_adjust =
+		params->rssi_stationary_low_adjust;
+	WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"),
+		wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
+		wmi_roam_mawc_params->traffic_load_threshold,
+		wmi_roam_mawc_params->best_ap_rssi_threshold,
+		wmi_roam_mawc_params->rssi_stationary_high_adjust,
+		wmi_roam_mawc_params->rssi_stationary_low_adjust);
+
+	wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
+			 status);
+		wmi_buf_free(buf);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
+ * @wmi_handle:     wmi handle
+ * @roam_req:       Request which contains the filters
+ *
+ * There are filters such as whitelist, blacklist and preferred
+ * list that need to be applied to the scan results to form the
+ * probable candidates for roaming.
+ *
+ * Return: Return success upon successfully passing the
+ *         parameters to the firmware, otherwise failure.
+ */
+static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
+				struct roam_scan_filter_params *roam_req)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	uint32_t i;
+	uint32_t len, blist_len = 0;
+	uint8_t *buf_ptr;
+	wmi_roam_filter_fixed_param *roam_filter;
+	uint8_t *bssid_src_ptr = NULL;
+	wmi_mac_addr *bssid_dst_ptr = NULL;
+	wmi_ssid *ssid_ptr = NULL;
+	uint32_t *bssid_preferred_factor_ptr = NULL;
+	wmi_roam_lca_disallow_config_tlv_param *blist_param;
+	wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
+
+	len = sizeof(wmi_roam_filter_fixed_param);
+
+	len += WMI_TLV_HDR_SIZE;
+	if (roam_req->num_bssid_black_list)
+		len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr);
+	len += WMI_TLV_HDR_SIZE;
+	if (roam_req->num_ssid_white_list)
+		len += roam_req->num_ssid_white_list * sizeof(wmi_ssid);
+	len += 2 * WMI_TLV_HDR_SIZE;
+	if (roam_req->num_bssid_preferred_list) {
+		len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr);
+		len += roam_req->num_bssid_preferred_list * sizeof(uint32_t);
+	}
+	len += WMI_TLV_HDR_SIZE;
+	if (roam_req->lca_disallow_config_present) {
+		len += sizeof(*blist_param);
+		blist_len = sizeof(*blist_param);
+	}
+
+	len += WMI_TLV_HDR_SIZE;
+	if (roam_req->num_rssi_rejection_ap)
+		len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+	roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&roam_filter->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
+	/* fill in fixed values */
+	roam_filter->vdev_id = roam_req->session_id;
+	roam_filter->flags = 0;
+	roam_filter->op_bitmap = roam_req->op_bitmap;
+	roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
+	roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
+	roam_filter->num_bssid_preferred_list =
+			roam_req->num_bssid_preferred_list;
+	roam_filter->num_rssi_rejection_ap =
+			roam_req->num_rssi_rejection_ap;
+	buf_ptr += sizeof(wmi_roam_filter_fixed_param);
+
+	WMITLV_SET_HDR((buf_ptr),
+		WMITLV_TAG_ARRAY_FIXED_STRUC,
+		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
+	bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
+	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < roam_req->num_bssid_black_list; i++) {
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
+		bssid_src_ptr += ATH_MAC_LEN;
+		bssid_dst_ptr++;
+	}
+	buf_ptr += WMI_TLV_HDR_SIZE +
+		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
+	WMITLV_SET_HDR((buf_ptr),
+		       WMITLV_TAG_ARRAY_FIXED_STRUC,
+		       (roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
+	ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < roam_req->num_ssid_white_list; i++) {
+		qdf_mem_copy(&ssid_ptr->ssid,
+			&roam_req->ssid_allowed_list[i].mac_ssid,
+			roam_req->ssid_allowed_list[i].length);
+		ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
+		ssid_ptr++;
+	}
+	buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
+							sizeof(wmi_ssid));
+	WMITLV_SET_HDR((buf_ptr),
+		WMITLV_TAG_ARRAY_FIXED_STRUC,
+		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
+	bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
+	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
+					   (wmi_mac_addr *)bssid_dst_ptr);
+		bssid_src_ptr += ATH_MAC_LEN;
+		bssid_dst_ptr++;
+	}
+	buf_ptr += WMI_TLV_HDR_SIZE +
+		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		(roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
+	bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
+		*bssid_preferred_factor_ptr =
+			roam_req->bssid_favored_factor[i];
+		bssid_preferred_factor_ptr++;
+	}
+	buf_ptr += WMI_TLV_HDR_SIZE +
+		(roam_req->num_bssid_preferred_list * sizeof(uint32_t));
+
+	WMITLV_SET_HDR(buf_ptr,
+			WMITLV_TAG_ARRAY_STRUC, blist_len);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	if (roam_req->lca_disallow_config_present) {
+		blist_param =
+			(wmi_roam_lca_disallow_config_tlv_param *) buf_ptr;
+		WMITLV_SET_HDR(&blist_param->tlv_header,
+			WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_roam_lca_disallow_config_tlv_param));
+
+		blist_param->disallow_duration = roam_req->disallow_duration;
+		blist_param->rssi_channel_penalization =
+				roam_req->rssi_channel_penalization;
+		blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
+		blist_param->disallow_lca_enable_source_bitmap =
+			(WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
+			WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
+		buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
+	}
+
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
+		rssi_rej =
+		(wmi_roam_rssi_rejection_oce_config_param *) buf_ptr;
+		WMITLV_SET_HDR(&rssi_rej->tlv_header,
+			WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+			wmi_roam_rssi_rejection_oce_config_param));
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(
+			roam_req->rssi_rejection_ap[i].bssid.bytes,
+			&rssi_rej->bssid);
+		rssi_rej->remaining_disallow_duration =
+			roam_req->rssi_rejection_ap[i].remaining_duration;
+		rssi_rej->requested_rssi =
+			(int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
+		buf_ptr +=
+			(sizeof(wmi_roam_rssi_rejection_oce_config_param));
+	}
+
+	wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_FILTER_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * send_plm_stop_cmd_tlv() - plm stop request
+ * @wmi_handle: wmi handle
+ * @plm: plm request parameters
+ *
+ * This function request FW to stop PLM.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
+			  const struct plm_req_params *plm)
+{
+	wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int ret;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf);
+
+	buf_ptr = (uint8_t *) cmd;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_vdev_plmreq_stop_cmd_fixed_param));
+
+	cmd->vdev_id = plm->session_id;
+
+	cmd->meas_token = plm->meas_token;
+	WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
+
+	wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_VDEV_PLMREQ_STOP_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_plm_start_cmd_tlv() - plm start request
+ * @wmi_handle: wmi handle
+ * @plm: plm request parameters
+ *
+ * This function request FW to start PLM.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
+			  const struct plm_req_params *plm,
+			  uint32_t *gchannel_list)
+{
+	wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
+	uint32_t *channel_list;
+	int32_t len;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint8_t count;
+	int ret;
+
+	/* TLV place holder for channel_list */
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+	len += sizeof(uint32_t) * plm->plm_num_ch;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf);
+
+	buf_ptr = (uint8_t *) cmd;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_vdev_plmreq_start_cmd_fixed_param));
+
+	cmd->vdev_id = plm->session_id;
+
+	cmd->meas_token = plm->meas_token;
+	cmd->dialog_token = plm->diag_token;
+	cmd->number_bursts = plm->num_bursts;
+	cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
+	cmd->off_duration = plm->meas_duration;
+	cmd->burst_cycle = plm->burst_len;
+	cmd->tx_power = plm->desired_tx_pwr;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
+	cmd->num_chans = plm->plm_num_ch;
+
+	buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
+
+	WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
+	WMI_LOGD("dialog_token: %d", cmd->dialog_token);
+	WMI_LOGD("number_bursts: %d", cmd->number_bursts);
+	WMI_LOGD("burst_interval: %d", cmd->burst_interval);
+	WMI_LOGD("off_duration: %d", cmd->off_duration);
+	WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
+	WMI_LOGD("tx_power: %d", cmd->tx_power);
+	WMI_LOGD("Number of channels : %d", cmd->num_chans);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		       (cmd->num_chans * sizeof(uint32_t)));
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	if (cmd->num_chans) {
+		channel_list = (uint32_t *) buf_ptr;
+		for (count = 0; count < cmd->num_chans; count++) {
+			channel_list[count] = plm->plm_ch_list[count];
+			if (channel_list[count] < WMI_NLO_FREQ_THRESH)
+				channel_list[count] =
+					gchannel_list[count];
+			WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
+		}
+		buf_ptr += cmd->num_chans * sizeof(uint32_t);
+	}
+
+	wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_VDEV_PLMREQ_START_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_ese_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_plm_stop_cmd = send_plm_stop_cmd_tlv;
+	ops->send_plm_start_cmd = send_plm_start_cmd_tlv;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/* send_set_ric_req_cmd_tlv() - set ric request element
+ * @wmi_handle: wmi handle
+ * @msg: message
+ * @is_add_ts: is addts required
+ *
+ * This function sets ric request element for 11r roaming.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
+			void *msg, uint8_t is_add_ts)
+{
+	wmi_ric_request_fixed_param *cmd;
+	wmi_ric_tspec *tspec_param;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	struct mac_tspec_ie *ptspecIE = NULL;
+	int32_t len = sizeof(wmi_ric_request_fixed_param) +
+		      WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+
+	cmd = (wmi_ric_request_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
+	if (is_add_ts)
+		cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id;
+	else
+		cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId;
+	cmd->num_ric_request = 1;
+	cmd->is_add_ric = is_add_ts;
+
+	buf_ptr += sizeof(wmi_ric_request_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	tspec_param = (wmi_ric_tspec *) buf_ptr;
+	WMITLV_SET_HDR(&tspec_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ric_tspec,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
+
+	if (is_add_ts)
+		ptspecIE = &(((struct add_ts_param *) msg)->tspec);
+	else
+		ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec);
+	if (ptspecIE) {
+		/* Fill the tsinfo in the format expected by firmware */
+#ifndef ANI_LITTLE_BIT_ENDIAN
+		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1,
+			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
+#else
+		qdf_mem_copy(((uint8_t *) &tspec_param->ts_info),
+			     ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
+#endif /* ANI_LITTLE_BIT_ENDIAN */
+
+		tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz;
+		tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz;
+		tspec_param->min_service_interval = ptspecIE->minSvcInterval;
+		tspec_param->max_service_interval = ptspecIE->maxSvcInterval;
+		tspec_param->inactivity_interval = ptspecIE->inactInterval;
+		tspec_param->suspension_interval = ptspecIE->suspendInterval;
+		tspec_param->svc_start_time = ptspecIE->svcStartTime;
+		tspec_param->min_data_rate = ptspecIE->minDataRate;
+		tspec_param->mean_data_rate = ptspecIE->meanDataRate;
+		tspec_param->peak_data_rate = ptspecIE->peakDataRate;
+		tspec_param->max_burst_size = ptspecIE->maxBurstSz;
+		tspec_param->delay_bound = ptspecIE->delayBound;
+		tspec_param->min_phy_rate = ptspecIE->minPhyRate;
+		tspec_param->surplus_bw_allowance = ptspecIE->surplusBw;
+		tspec_param->medium_time = 0;
+	}
+	WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
+
+	wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
+		WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
+			 __func__);
+		if (is_add_ts)
+			((struct add_ts_param *) msg)->status =
+					    QDF_STATUS_E_FAILURE;
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw.
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ *
+ * This function sends roam synch complete event to fw.
+ *
+ * Return: CDF STATUS
+ */
+static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
+		 uint8_t vdev_id)
+{
+	wmi_roam_synch_complete_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint8_t *buf_ptr;
+	uint16_t len;
+	len = sizeof(wmi_roam_synch_complete_fixed_param);
+
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf);
+	buf_ptr = (uint8_t *) cmd;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_synch_complete_fixed_param));
+	cmd->vdev_id = vdev_id;
+	wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_ROAM_SYNCH_COMPLETE)) {
+		WMI_LOGP("%s: failed to send roam synch confirmation",
+			 __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
+ * @wmi_handle: wma handle
+ * @roaminvoke: roam invoke command
+ *
+ * Send roam invoke command to fw for fastreassoc.
+ *
+ * Return: CDF STATUS
+ */
+static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
+		struct wmi_roam_invoke_cmd *roaminvoke,
+		uint32_t ch_hz)
+{
+	wmi_roam_invoke_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	u_int8_t *buf_ptr;
+	u_int16_t len, args_tlv_len;
+	uint32_t *channel_list;
+	wmi_mac_addr *bssid_list;
+	wmi_tlv_buf_len_param *buf_len_tlv;
+
+	/* Host sends only one channel and one bssid */
+	args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
+			sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
+			roundup(roaminvoke->frame_len, sizeof(uint32_t));
+	len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
+	buf_ptr = (u_int8_t *) cmd;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
+	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
+	cmd->vdev_id = roaminvoke->vdev_id;
+	cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
+	if (roaminvoke->is_same_bssid)
+		cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
+	WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid);
+
+	if (roaminvoke->frame_len) {
+		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
+		/* packing 1 beacon/probe_rsp frame with WMI cmd */
+		cmd->num_buf = 1;
+	} else {
+		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
+		cmd->num_buf = 0;
+	}
+
+	cmd->roam_ap_sel_mode = 0;
+	cmd->roam_delay = 0;
+	cmd->num_chan = 1;
+	cmd->num_bssid = 1;
+
+	buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		       (sizeof(u_int32_t)));
+	channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	*channel_list = ch_hz;
+	buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE;
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
+		       (sizeof(wmi_mac_addr)));
+	bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
+
+	/* move to next tlv i.e. bcn_prb_buf_list */
+	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
+		       sizeof(wmi_tlv_buf_len_param));
+
+	buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	buf_len_tlv->buf_len = roaminvoke->frame_len;
+
+	/* move to next tlv i.e. bcn_prb_frm */
+	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       roundup(roaminvoke->frame_len, sizeof(uint32_t)));
+
+	/* copy frame after the header */
+	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
+		     roaminvoke->frame_buf,
+		     roaminvoke->frame_len);
+
+	WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+			   buf_ptr + WMI_TLV_HDR_SIZE,
+			   roaminvoke->frame_len);
+	WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"),
+		    cmd->flags, cmd->roam_scan_mode,
+		    cmd->roam_ap_sel_mode, cmd->roam_delay,
+		    cmd->num_chan, cmd->num_bssid);
+	WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz);
+
+	wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_ROAM_INVOKE_CMDID)) {
+		WMI_LOGP("%s: failed to send roam invoke command", __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_ric_req_cmd = send_set_ric_req_cmd_tlv;
+	ops->send_process_roam_synch_complete_cmd =
+			send_process_roam_synch_complete_cmd_tlv;
+	ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv;
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+#if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
+ * @wmi_handle: wmi handle
+ * @roam_req: Roam scan offload params
+ * @buf_ptr: command buffer to send
+ * @fils_tlv_len: fils tlv length
+ *
+ * Return: Updated buffer pointer
+ */
+static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
+			     struct roam_offload_scan_params *roam_req,
+			     uint8_t *buf_ptr, uint32_t fils_tlv_len)
+{
+	wmi_roam_fils_offload_tlv_param *fils_tlv;
+	wmi_erp_info *erp_info;
+	struct roam_fils_params *roam_fils_params;
+
+	if (!roam_req->add_fils_tlv)
+		return buf_ptr;
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(*fils_tlv));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
+	WMITLV_SET_HDR(&fils_tlv->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_fils_offload_tlv_param));
+
+	roam_fils_params = &roam_req->roam_fils_params;
+	erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
+
+	erp_info->username_length = roam_fils_params->username_length;
+	qdf_mem_copy(erp_info->username, roam_fils_params->username,
+		     erp_info->username_length);
+
+	erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
+
+	erp_info->rRk_length = roam_fils_params->rrk_length;
+	qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
+		     erp_info->rRk_length);
+
+	erp_info->rIk_length = roam_fils_params->rik_length;
+	qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
+		     erp_info->rIk_length);
+
+	erp_info->realm_len = roam_fils_params->realm_len;
+	qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
+		     erp_info->realm_len);
+
+	buf_ptr += sizeof(*fils_tlv);
+	return buf_ptr;
+}
+#else
+static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
+				struct roam_offload_scan_params *roam_req,
+				uint8_t *buf_ptr, uint32_t fils_tlv_len)
+{
+	return buf_ptr;
+}
+#endif
+
+/**
+ * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
+ * @wmi_handle: wmi handle
+ * @scan_cmd_fp: start scan command ptr
+ * @roam_req: roam request param
+ *
+ * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
+ * of WMI_ROAM_SCAN_MODE.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
+				      wmi_start_scan_cmd_fixed_param *
+				      scan_cmd_fp,
+				      struct roam_offload_scan_params *roam_req)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	int auth_mode = roam_req->auth_mode;
+	roam_offload_param *req_offload_params =
+		&roam_req->roam_offload_params;
+	wmi_roam_offload_tlv_param *roam_offload_params;
+	wmi_roam_11i_offload_tlv_param *roam_offload_11i;
+	wmi_roam_11r_offload_tlv_param *roam_offload_11r;
+	wmi_roam_ese_offload_tlv_param *roam_offload_ese;
+	wmi_tlv_buf_len_param *assoc_ies;
+	uint32_t fils_tlv_len = 0;
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+	/* Need to create a buf with roam_scan command at
+	 * front and piggyback with scan command */
+	len = sizeof(wmi_roam_scan_mode_fixed_param) +
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	      (2 * WMI_TLV_HDR_SIZE) +
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+	      sizeof(wmi_start_scan_cmd_fixed_param);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	WMI_LOGD("auth_mode = %d", auth_mode);
+		if (roam_req->is_roam_req_valid &&
+				roam_req->roam_offload_enabled) {
+			len += sizeof(wmi_roam_offload_tlv_param);
+			len += WMI_TLV_HDR_SIZE;
+			if ((auth_mode != WMI_AUTH_NONE) &&
+				((auth_mode != WMI_AUTH_OPEN) ||
+				 (auth_mode == WMI_AUTH_OPEN &&
+				  roam_req->mdid.mdie_present &&
+				  roam_req->is_11r_assoc) ||
+				  roam_req->is_ese_assoc)) {
+				len += WMI_TLV_HDR_SIZE;
+				if (roam_req->is_ese_assoc)
+					len +=
+					sizeof(wmi_roam_ese_offload_tlv_param);
+				else if (auth_mode == WMI_AUTH_FT_RSNA ||
+					 auth_mode == WMI_AUTH_FT_RSNA_PSK ||
+					 (auth_mode == WMI_AUTH_OPEN &&
+					  roam_req->mdid.mdie_present &&
+					  roam_req->is_11r_assoc))
+					len +=
+					sizeof(wmi_roam_11r_offload_tlv_param);
+				else
+					len +=
+					sizeof(wmi_roam_11i_offload_tlv_param);
+			} else {
+				len += WMI_TLV_HDR_SIZE;
+			}
+
+			len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE)
+					+ roundup(roam_req->assoc_ie_length,
+					sizeof(uint32_t)));
+
+			if (roam_req->add_fils_tlv) {
+				fils_tlv_len = sizeof(
+					wmi_roam_fils_offload_tlv_param);
+				len += WMI_TLV_HDR_SIZE + fils_tlv_len;
+			}
+		} else {
+			if (roam_req->is_roam_req_valid)
+				WMI_LOGD("%s : roam offload = %d",
+					 __func__,
+					 roam_req->roam_offload_enabled);
+			else
+				WMI_LOGD("%s : roam_req is NULL", __func__);
+			len += (4 * WMI_TLV_HDR_SIZE);
+		}
+		if (roam_req->is_roam_req_valid &&
+				roam_req->roam_offload_enabled) {
+			roam_req->mode = roam_req->mode |
+				WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
+		}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE
+				|WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
+		len = sizeof(wmi_roam_scan_mode_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_scan_mode_fixed_param));
+
+	roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask =
+			roam_req->roam_trigger_reason_bitmask;
+	roam_scan_mode_fp->min_delay_btw_scans =
+			WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans);
+	roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
+	roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
+	if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE |
+			       WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
+		roam_scan_mode_fp->flags |=
+			WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
+		goto send_roam_scan_mode_cmd;
+	}
+
+	/* Fill in scan parameters suitable for roaming scan */
+	buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
+
+	qdf_mem_copy(buf_ptr, scan_cmd_fp,
+		     sizeof(wmi_start_scan_cmd_fixed_param));
+	/* Ensure there is no additional IEs */
+	scan_cmd_fp->ie_len = 0;
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_start_scan_cmd_fixed_param));
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
+	if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(wmi_roam_offload_tlv_param));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr;
+		WMITLV_SET_HDR(buf_ptr,
+			       WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
+			       WMITLV_GET_STRUCT_TLVLEN
+				       (wmi_roam_offload_tlv_param));
+		roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
+		roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
+		roam_offload_params->select_5g_margin =
+			roam_req->select_5ghz_margin;
+		roam_offload_params->handoff_delay_for_rx =
+			req_offload_params->ho_delay_for_rx;
+		roam_offload_params->max_mlme_sw_retries =
+			req_offload_params->roam_preauth_retry_count;
+		roam_offload_params->no_ack_timeout =
+			req_offload_params->roam_preauth_no_ack_timeout;
+		roam_offload_params->reassoc_failure_timeout =
+			roam_req->reassoc_failure_timeout;
+
+		/* Fill the capabilities */
+		roam_offload_params->capability =
+				req_offload_params->capability;
+		roam_offload_params->ht_caps_info =
+				req_offload_params->ht_caps_info;
+		roam_offload_params->ampdu_param =
+				req_offload_params->ampdu_param;
+		roam_offload_params->ht_ext_cap =
+				req_offload_params->ht_ext_cap;
+		roam_offload_params->ht_txbf = req_offload_params->ht_txbf;
+		roam_offload_params->asel_cap = req_offload_params->asel_cap;
+		roam_offload_params->qos_caps = req_offload_params->qos_caps;
+		roam_offload_params->qos_enabled =
+				req_offload_params->qos_enabled;
+		roam_offload_params->wmm_caps = req_offload_params->wmm_caps;
+		qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
+			     (uint8_t *)req_offload_params->mcsset,
+			     ROAM_OFFLOAD_NUM_MCS_SET);
+
+		buf_ptr += sizeof(wmi_roam_offload_tlv_param);
+		/* The TLV's are in the order of 11i, 11R, ESE. Hence,
+		 * they are filled in the same order.Depending on the
+		 * authentication type, the other mode TLV's are nullified
+		 * and only headers are filled.*/
+		if ((auth_mode != WMI_AUTH_NONE) &&
+		    ((auth_mode != WMI_AUTH_OPEN) ||
+		     (auth_mode == WMI_AUTH_OPEN
+		      && roam_req->mdid.mdie_present &&
+		      roam_req->is_11r_assoc) ||
+			roam_req->is_ese_assoc)) {
+			if (roam_req->is_ese_assoc) {
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       WMITLV_GET_STRUCT_TLVLEN(0));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       WMITLV_GET_STRUCT_TLVLEN(0));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					sizeof(wmi_roam_ese_offload_tlv_param));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				roam_offload_ese =
+				    (wmi_roam_ese_offload_tlv_param *) buf_ptr;
+				qdf_mem_copy(roam_offload_ese->krk,
+					     roam_req->krk,
+					     sizeof(roam_req->krk));
+				qdf_mem_copy(roam_offload_ese->btk,
+					     roam_req->btk,
+					     sizeof(roam_req->btk));
+				WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
+				WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
+				WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_ese_offload_tlv_param));
+				buf_ptr +=
+					sizeof(wmi_roam_ese_offload_tlv_param);
+			} else if (auth_mode == WMI_AUTH_FT_RSNA
+				   || auth_mode == WMI_AUTH_FT_RSNA_PSK
+				   || (auth_mode == WMI_AUTH_OPEN
+				       && roam_req->mdid.mdie_present &&
+				       roam_req->is_11r_assoc)) {
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       0);
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					sizeof(wmi_roam_11r_offload_tlv_param));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				roam_offload_11r =
+				    (wmi_roam_11r_offload_tlv_param *) buf_ptr;
+				roam_offload_11r->r0kh_id_len =
+					roam_req->rokh_id_length;
+				qdf_mem_copy(roam_offload_11r->r0kh_id,
+					     roam_req->rokh_id,
+					     roam_offload_11r->r0kh_id_len);
+				qdf_mem_copy(roam_offload_11r->psk_msk,
+					     roam_req->psk_pmk,
+					     sizeof(roam_req->psk_pmk));
+				roam_offload_11r->psk_msk_len =
+					roam_req->pmk_len;
+				roam_offload_11r->mdie_present =
+					roam_req->mdid.mdie_present;
+				roam_offload_11r->mdid =
+					roam_req->mdid.mobility_domain;
+				if (auth_mode == WMI_AUTH_OPEN) {
+					/* If FT-Open ensure pmk length
+					   and r0khid len are zero */
+					roam_offload_11r->r0kh_id_len = 0;
+					roam_offload_11r->psk_msk_len = 0;
+				}
+				WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
+				WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
+				WMITLV_GET_STRUCT_TLVLEN
+					(wmi_roam_11r_offload_tlv_param));
+				buf_ptr +=
+					sizeof(wmi_roam_11r_offload_tlv_param);
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       WMITLV_GET_STRUCT_TLVLEN(0));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMI_LOGD("psk_msk_len = %d",
+					roam_offload_11r->psk_msk_len);
+				if (roam_offload_11r->psk_msk_len)
+					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
+						QDF_TRACE_LEVEL_DEBUG,
+						roam_offload_11r->psk_msk,
+						roam_offload_11r->psk_msk_len);
+			} else {
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					sizeof(wmi_roam_11i_offload_tlv_param));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				roam_offload_11i =
+				     (wmi_roam_11i_offload_tlv_param *) buf_ptr;
+
+				if (roam_req->roam_key_mgmt_offload_enabled &&
+				    roam_req->fw_okc) {
+					WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
+						(roam_offload_11i->flags);
+					WMI_LOGI("LFR3:OKC enabled");
+				} else {
+					WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
+						(roam_offload_11i->flags);
+					WMI_LOGI("LFR3:OKC disabled");
+				}
+				if (roam_req->roam_key_mgmt_offload_enabled &&
+				    roam_req->fw_pmksa_cache) {
+					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED
+						(roam_offload_11i->flags);
+					WMI_LOGI("LFR3:PMKSA caching enabled");
+				} else {
+					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED
+						(roam_offload_11i->flags);
+					WMI_LOGI("LFR3:PMKSA caching disabled");
+				}
+
+				qdf_mem_copy(roam_offload_11i->pmk,
+					     roam_req->psk_pmk,
+					     sizeof(roam_req->psk_pmk));
+				roam_offload_11i->pmk_len = roam_req->pmk_len;
+				WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
+				WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
+				WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_11i_offload_tlv_param));
+				buf_ptr +=
+					sizeof(wmi_roam_11i_offload_tlv_param);
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       0);
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       0);
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMI_LOGD("pmk_len = %d",
+					roam_offload_11i->pmk_len);
+				if (roam_offload_11i->pmk_len)
+					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
+						QDF_TRACE_LEVEL_DEBUG,
+						roam_offload_11i->pmk,
+						roam_offload_11i->pmk_len);
+			}
+		} else {
+			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+				       WMITLV_GET_STRUCT_TLVLEN(0));
+			buf_ptr += WMI_TLV_HDR_SIZE;
+			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+				       WMITLV_GET_STRUCT_TLVLEN(0));
+			buf_ptr += WMI_TLV_HDR_SIZE;
+			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+				       WMITLV_GET_STRUCT_TLVLEN(0));
+			buf_ptr += WMI_TLV_HDR_SIZE;
+		}
+
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					sizeof(*assoc_ies));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+
+		assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr;
+		WMITLV_SET_HDR(&assoc_ies->tlv_header,
+			WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
+			WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
+		assoc_ies->buf_len = roam_req->assoc_ie_length;
+
+		buf_ptr += sizeof(*assoc_ies);
+
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+				roundup(assoc_ies->buf_len, sizeof(uint32_t)));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+
+		if (assoc_ies->buf_len != 0) {
+			qdf_mem_copy(buf_ptr, roam_req->assoc_ie,
+					assoc_ies->buf_len);
+		}
+		buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
+		buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req,
+						buf_ptr, fils_tlv_len);
+	} else {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+				WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+				WMITLV_GET_STRUCT_TLVLEN(0));
+	}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+send_roam_scan_mode_cmd:
+	wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_MODE);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE(
+		    "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d",
+			status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
+ * @wmi_handle: wmi handle
+ * @ap_profile_p: ap profile
+ * @vdev_id: vdev id
+ *
+ * Send WMI_ROAM_AP_PROFILE to firmware
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
+					    struct ap_profile_params *ap_profile)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
+	wmi_roam_cnd_scoring_param *score_param;
+	wmi_ap_profile *profile;
+
+	len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
+	len += sizeof(*score_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_ap_profile_fixed_param));
+	/* fill in threshold values */
+	roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
+	roam_ap_profile_fp->id = 0;
+	buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
+
+	profile = (wmi_ap_profile *)buf_ptr;
+	WMITLV_SET_HDR(&profile->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ap_profile,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
+	profile->flags = ap_profile->profile.flags;
+	profile->rssi_threshold = ap_profile->profile.rssi_threshold;
+	profile->ssid.ssid_len = ap_profile->profile.ssid.length;
+	qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid,
+		     profile->ssid.ssid_len);
+	profile->rsn_authmode = ap_profile->profile.rsn_authmode;
+	profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
+	profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
+	profile->rsn_mcastmgmtcipherset =
+				ap_profile->profile.rsn_mcastmgmtcipherset;
+	profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
+
+	WMI_LOGD("AP profile: flags %x rssi_threshold %d ssid:%.*s authmode %d uc cipher %d mc cipher %d mc mgmt cipher %d rssi abs thresh %d",
+		 profile->flags, profile->rssi_threshold,
+		 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid,
+		 profile->rsn_authmode, profile->rsn_ucastcipherset,
+		 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
+		 profile->rssi_abs_thresh);
+
+	buf_ptr += sizeof(wmi_ap_profile);
+
+	score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
+	WMITLV_SET_HDR(&score_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
+	score_param->disable_bitmap = ap_profile->param.disable_bitmap;
+	score_param->rssi_weightage_pcnt =
+			ap_profile->param.rssi_weightage;
+	score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
+	score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
+	score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
+	score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
+	score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
+	score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
+	score_param->esp_qbss_weightage_pcnt =
+			ap_profile->param.esp_qbss_weightage;
+	score_param->beamforming_weightage_pcnt =
+			ap_profile->param.beamforming_weightage;
+	score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
+	score_param->oce_wan_weightage_pcnt =
+			ap_profile->param.oce_wan_weightage;
+
+	WMI_LOGD("Score params weightage: disable_bitmap %x rssi %d ht %d vht %d he %d BW %d band %d NSS %d ESP %d BF %d PCL %d OCE WAN %d",
+		 score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
+		 score_param->ht_weightage_pcnt,
+		 score_param->vht_weightage_pcnt,
+		 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt,
+		 score_param->band_weightage_pcnt,
+		 score_param->nss_weightage_pcnt,
+		 score_param->esp_qbss_weightage_pcnt,
+		 score_param->beamforming_weightage_pcnt,
+		 score_param->pcl_weightage_pcnt,
+		 score_param->oce_wan_weightage_pcnt);
+
+	score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
+	score_param->band_scoring.score_pcnt =
+			ap_profile->param.band_index_score;
+	score_param->nss_scoring.score_pcnt =
+			ap_profile->param.nss_index_score;
+
+	WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x",
+		 score_param->bw_scoring.score_pcnt,
+		 score_param->band_scoring.score_pcnt,
+		 score_param->nss_scoring.score_pcnt);
+
+	score_param->rssi_scoring.best_rssi_threshold =
+		(-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
+	score_param->rssi_scoring.good_rssi_threshold =
+		(-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
+	score_param->rssi_scoring.bad_rssi_threshold =
+		(-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
+	score_param->rssi_scoring.good_rssi_pcnt =
+		ap_profile->param.rssi_scoring.good_rssi_pcnt;
+	score_param->rssi_scoring.bad_rssi_pcnt =
+		ap_profile->param.rssi_scoring.bad_rssi_pcnt;
+	score_param->rssi_scoring.good_bucket_size =
+		ap_profile->param.rssi_scoring.good_bucket_size;
+	score_param->rssi_scoring.bad_bucket_size =
+		ap_profile->param.rssi_scoring.bad_bucket_size;
+	score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
+		(-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
+
+	WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
+		 score_param->rssi_scoring.best_rssi_threshold,
+		 score_param->rssi_scoring.good_rssi_threshold,
+		 score_param->rssi_scoring.bad_rssi_threshold,
+		 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
+	WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
+		 score_param->rssi_scoring.good_rssi_pcnt,
+		 score_param->rssi_scoring.bad_rssi_pcnt,
+		 score_param->rssi_scoring.good_bucket_size,
+		 score_param->rssi_scoring.bad_bucket_size);
+
+	score_param->esp_qbss_scoring.num_slot =
+			ap_profile->param.esp_qbss_scoring.num_slot;
+	score_param->esp_qbss_scoring.score_pcnt3_to_0 =
+			ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
+	score_param->esp_qbss_scoring.score_pcnt7_to_4 =
+			ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
+	score_param->esp_qbss_scoring.score_pcnt11_to_8 =
+			ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
+	score_param->esp_qbss_scoring.score_pcnt15_to_12 =
+			ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
+
+	WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
+		 score_param->esp_qbss_scoring.num_slot,
+		 score_param->esp_qbss_scoring.score_pcnt3_to_0,
+		 score_param->esp_qbss_scoring.score_pcnt7_to_4,
+		 score_param->esp_qbss_scoring.score_pcnt11_to_8,
+		 score_param->esp_qbss_scoring.score_pcnt15_to_12);
+
+	score_param->oce_wan_scoring.num_slot =
+			ap_profile->param.oce_wan_scoring.num_slot;
+	score_param->oce_wan_scoring.score_pcnt3_to_0 =
+			ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
+	score_param->oce_wan_scoring.score_pcnt7_to_4 =
+			ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
+	score_param->oce_wan_scoring.score_pcnt11_to_8 =
+			ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
+	score_param->oce_wan_scoring.score_pcnt15_to_12 =
+			ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
+
+	WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
+		 score_param->oce_wan_scoring.num_slot,
+		 score_param->oce_wan_scoring.score_pcnt3_to_0,
+		 score_param->oce_wan_scoring.score_pcnt7_to_4,
+		 score_param->oce_wan_scoring.score_pcnt11_to_8,
+		 score_param->oce_wan_scoring.score_pcnt15_to_12);
+
+	wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_AP_PROFILE);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d",
+			status);
+		wmi_buf_free(buf);
+	}
+
+	WMI_LOGD("WMI --> WMI_ROAM_AP_PROFILE and other parameters");
+
+	return status;
+}
+
+/**
+ * send_roam_scan_offload_cmd_tlv() - set roam offload command
+ * @wmi_handle: wmi handle
+ * @command: command
+ * @vdev_id: vdev id
+ *
+ * This function set roam offload command to fw.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
+					 uint32_t command, uint32_t vdev_id)
+{
+	QDF_STATUS status;
+	wmi_roam_scan_cmd_fixed_param *cmd_fp;
+	wmi_buf_t buf = NULL;
+	int len;
+	uint8_t *buf_ptr;
+
+	len = sizeof(wmi_roam_scan_cmd_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+
+	cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
+	cmd_fp->vdev_id = vdev_id;
+	cmd_fp->command_arg = command;
+
+	wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_CMD);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d",
+			 status);
+		goto error;
+	}
+
+	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
+	return QDF_STATUS_SUCCESS;
+
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
+ * @wmi_handle: wmi handle
+ * @scan_period: scan period
+ * @scan_age: scan age
+ * @vdev_id: vdev id
+ *
+ * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle,
+					     uint32_t scan_period,
+					     uint32_t scan_age,
+					     uint32_t vdev_id)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_period_fixed_param *scan_period_fp;
+
+	/* Send scan period values */
+	len = sizeof(wmi_roam_scan_period_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&scan_period_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_scan_period_fixed_param));
+	/* fill in scan period values */
+	scan_period_fp->vdev_id = vdev_id;
+	scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */
+	scan_period_fp->roam_scan_age = scan_age;
+
+	wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_PERIOD);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d",
+			 status);
+		goto error;
+	}
+
+	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d",
+		 __func__, scan_period, scan_age);
+	return QDF_STATUS_SUCCESS;
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
+ * @wmi_handle: wmi handle
+ * @chan_count: channel count
+ * @chan_list: channel list
+ * @list_type: list type
+ * @vdev_id: vdev id
+ *
+ * Set roam offload channel list.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
+				   uint8_t chan_count,
+				   uint32_t *chan_list,
+				   uint8_t list_type, uint32_t vdev_id)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len, list_tlv_len;
+	int i;
+	uint8_t *buf_ptr;
+	wmi_roam_chan_list_fixed_param *chan_list_fp;
+	uint32_t *roam_chan_list_array;
+
+	if (chan_count == 0) {
+		WMI_LOGD("%s : invalid number of channels %d", __func__,
+			 chan_count);
+		return QDF_STATUS_E_EMPTY;
+	}
+	/* Channel list is a table of 2 TLV's */
+	list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t);
+	len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_chan_list_fixed_param));
+	chan_list_fp->vdev_id = vdev_id;
+	chan_list_fp->num_chan = chan_count;
+	if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) {
+		/* external app is controlling channel list */
+		chan_list_fp->chan_list_type =
+			WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
+	} else {
+		/* umac supplied occupied channel list in LFR */
+		chan_list_fp->chan_list_type =
+			WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
+	}
+
+	buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		       (chan_list_fp->num_chan * sizeof(uint32_t)));
+	roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
+	WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan);
+	for (i = 0; ((i < chan_list_fp->num_chan) &&
+		     (i < WMI_ROAM_MAX_CHANNELS)); i++) {
+		roam_chan_list_array[i] = chan_list[i];
+		WMI_LOGD("%d,", roam_chan_list_array[i]);
+	}
+
+	wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_CHAN_LIST);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d",
+			 status);
+		goto error;
+	}
+
+	WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__);
+	return QDF_STATUS_SUCCESS;
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
+ * @wmi_handle: wmi handle
+ * @rssi_change_thresh: RSSI Change threshold
+ * @bcn_rssi_weight: beacon RSSI weight
+ * @vdev_id: vdev id
+ *
+ * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
+	uint32_t vdev_id,
+	int32_t rssi_change_thresh,
+	uint32_t bcn_rssi_weight,
+	uint32_t hirssi_delay_btw_scans)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
+
+	/* Send rssi change parameters */
+	len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	rssi_change_fp =
+		(wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_scan_rssi_change_threshold_fixed_param));
+	/* fill in rssi change threshold (hysteresis) values */
+	rssi_change_fp->vdev_id = vdev_id;
+	rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
+	rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
+	rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
+
+	wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d",
+			 status);
+		goto error;
+	}
+
+	WMI_LOGD(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"),
+		 rssi_change_thresh, bcn_rssi_weight);
+	WMI_LOGD(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans);
+	return QDF_STATUS_SUCCESS;
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_per_roam_config_cmd_tlv() - set per roaming config to FW
+ * @wmi_handle: wmi handle
+ * @req_buf: per roam config buffer
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
+		struct wmi_per_roam_config_req *req_buf)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_per_config_fixed_param *wmi_per_config;
+
+	len = sizeof(wmi_roam_per_config_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	wmi_per_config =
+		(wmi_roam_per_config_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&wmi_per_config->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_roam_per_config_fixed_param));
+
+	/* fill in per roam config values */
+	wmi_per_config->vdev_id = req_buf->vdev_id;
+
+	wmi_per_config->enable = req_buf->per_config.enable;
+	wmi_per_config->high_rate_thresh =
+		(req_buf->per_config.tx_high_rate_thresh << 16) |
+		(req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
+	wmi_per_config->low_rate_thresh =
+		(req_buf->per_config.tx_low_rate_thresh << 16) |
+		(req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
+	wmi_per_config->pkt_err_rate_thresh_pct =
+		(req_buf->per_config.tx_rate_thresh_percnt << 16) |
+		(req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
+	wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
+	wmi_per_config->pkt_err_rate_mon_time =
+			(req_buf->per_config.tx_per_mon_time << 16) |
+			(req_buf->per_config.rx_per_mon_time & 0x0000ffff);
+	wmi_per_config->min_candidate_rssi =
+			req_buf->per_config.min_candidate_rssi;
+
+	/* Send per roam config parameters */
+	wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_PER_CONFIG_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d",
+			 status);
+		wmi_buf_free(buf);
+		return status;
+	}
+	WMI_LOGD(FL("per roam enable=%d, vdev=%d"),
+		 req_buf->per_config.enable, req_buf->vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
+ * configuration params
+ * @wmi_handle: wmi handler
+ * @limit_off_chan_param: pointer to wmi_off_chan_param
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static
+QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle,
+		struct wmi_limit_off_chan_param *limit_off_chan_param)
+{
+	wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len = sizeof(*cmd);
+	int err;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+			WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_vdev_limit_offchan_cmd_fixed_param));
+
+	cmd->vdev_id = limit_off_chan_param->vdev_id;
+
+	cmd->flags &= 0;
+	if (limit_off_chan_param->status)
+		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
+	if (limit_off_chan_param->skip_dfs_chans)
+		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
+
+	cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
+	cmd->rest_time = limit_off_chan_param->rest_time;
+
+	WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
+		 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
+		 cmd->rest_time);
+
+	wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf,
+				   len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
+	if (QDF_IS_STATUS_ERROR(err)) {
+		WMI_LOGE("Failed to send limit off chan cmd err=%d", err);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
+						  struct hlp_params *params)
+{
+	uint32_t len;
+	uint8_t *buf_ptr;
+	wmi_buf_t buf = NULL;
+	wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
+
+	len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
+	len += WMI_TLV_HDR_SIZE;
+	len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&hlp_params->tlv_header,
+		WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
+
+	hlp_params->vdev_id = params->vdev_id;
+	hlp_params->size = params->hlp_ie_len;
+	hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
+
+	buf_ptr += sizeof(*hlp_params);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       round_up(params->hlp_ie_len,
+		       sizeof(uint32_t)));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
+
+	WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"),
+		 hlp_params->vdev_id, hlp_params->size);
+	wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
+		WMI_LOGE(FL("Failed to send FILS HLP pkt cmd"));
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_fils_sk_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv;
+}
+#endif /* WLAN_FEATURE_FILS_SK */
+
+/*
+ * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
+ * @wmi_handle: wmi handle
+ * @params: pointer to wmi_btm_config
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
+					  struct wmi_btm_config *params)
+{
+
+	wmi_btm_config_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
+	cmd->vdev_id = params->vdev_id;
+	cmd->flags = params->btm_offload_config;
+	cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
+	cmd->solicited_timeout_ms = params->btm_solicited_timeout;
+	cmd->stick_time_seconds = params->btm_sticky_time;
+
+	wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+	    WMI_ROAM_BTM_CONFIG_CMDID)) {
+		WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID",
+			 __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
+ * @wmi_handle: wmi handler
+ * @params: pointer to 11k offload params
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
+				struct wmi_11k_offload_params *params)
+{
+	wmi_11k_offload_report_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS status;
+	uint8_t *buf_ptr;
+	wmi_neighbor_report_11k_offload_tlv_param
+					*neighbor_report_offload_params;
+	wmi_neighbor_report_offload *neighbor_report_offload;
+
+	uint32_t len = sizeof(*cmd);
+
+	if (params->offload_11k_bitmask &
+	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
+		len += WMI_TLV_HDR_SIZE +
+			sizeof(wmi_neighbor_report_11k_offload_tlv_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				wmi_11k_offload_report_fixed_param));
+
+	cmd->vdev_id = params->vdev_id;
+	cmd->offload_11k = params->offload_11k_bitmask;
+
+	if (params->offload_11k_bitmask &
+	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
+		buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
+
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			sizeof(wmi_neighbor_report_11k_offload_tlv_param));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+
+		neighbor_report_offload_params =
+			(wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
+		WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
+			WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_neighbor_report_11k_offload_tlv_param));
+
+		neighbor_report_offload = &neighbor_report_offload_params->
+			neighbor_rep_ofld_params;
+
+		neighbor_report_offload->time_offset =
+			params->neighbor_report_params.time_offset;
+		neighbor_report_offload->low_rssi_offset =
+			params->neighbor_report_params.low_rssi_offset;
+		neighbor_report_offload->bmiss_count_trigger =
+			params->neighbor_report_params.bmiss_count_trigger;
+		neighbor_report_offload->per_threshold_offset =
+			params->neighbor_report_params.per_threshold_offset;
+		neighbor_report_offload->neighbor_report_cache_timeout =
+			params->neighbor_report_params.
+			neighbor_report_cache_timeout;
+		neighbor_report_offload->max_neighbor_report_req_cap =
+			params->neighbor_report_params.
+			max_neighbor_report_req_cap;
+		neighbor_report_offload->ssid.ssid_len =
+			params->neighbor_report_params.ssid.length;
+		qdf_mem_copy(neighbor_report_offload->ssid.ssid,
+			&params->neighbor_report_params.ssid.mac_ssid,
+			neighbor_report_offload->ssid.ssid_len);
+	}
+
+	wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_11K_OFFLOAD_REPORT_CMDID);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMI_LOGE("%s: failed to send 11k offload command %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
+ * command
+ * @wmi_handle: wmi handler
+ * @params: pointer to neighbor report invoke params
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle,
+			struct wmi_invoke_neighbor_report_params *params)
+{
+	wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS status;
+	uint8_t *buf_ptr;
+	uint32_t len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
+		 WMITLV_GET_STRUCT_TLVLEN(
+			wmi_11k_offload_invoke_neighbor_report_fixed_param));
+
+	cmd->vdev_id = params->vdev_id;
+	cmd->flags = params->send_resp_to_host;
+
+	cmd->ssid.ssid_len = params->ssid.length;
+	qdf_mem_copy(cmd->ssid.ssid,
+		     &params->ssid.mac_ssid,
+		     cmd->ssid.ssid_len);
+
+	wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMI_LOGE("%s: failed to send invoke neighbor report command %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+void wmi_roam_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_roam_scan_offload_rssi_thresh_cmd =
+			send_roam_scan_offload_rssi_thresh_cmd_tlv;
+	ops->send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv;
+	ops->send_roam_scan_filter_cmd =
+			send_roam_scan_filter_cmd_tlv;
+	ops->send_roam_scan_offload_mode_cmd =
+			send_roam_scan_offload_mode_cmd_tlv;
+	ops->send_roam_scan_offload_ap_profile_cmd =
+			send_roam_scan_offload_ap_profile_cmd_tlv;
+	ops->send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv;
+	ops->send_roam_scan_offload_scan_period_cmd =
+			send_roam_scan_offload_scan_period_cmd_tlv;
+	ops->send_roam_scan_offload_chan_list_cmd =
+			send_roam_scan_offload_chan_list_cmd_tlv;
+	ops->send_roam_scan_offload_rssi_change_cmd =
+			send_roam_scan_offload_rssi_change_cmd_tlv;
+	ops->send_per_roam_config_cmd = send_per_roam_config_cmd_tlv;
+	ops->send_limit_off_chan_cmd = send_limit_off_chan_cmd_tlv;
+	ops->send_btm_config = send_btm_config_cmd_tlv;
+	ops->send_offload_11k_cmd = send_offload_11k_cmd_tlv;
+	ops->send_invoke_neighbor_report_cmd =
+			send_invoke_neighbor_report_cmd_tlv;
+
+	wmi_lfr_subnet_detection_attach_tlv(wmi_handle);
+	wmi_rssi_monitor_attach_tlv(wmi_handle);
+	wmi_ese_attach_tlv(wmi_handle);
+	wmi_roam_offload_attach_tlv(wmi_handle);
+	wmi_fils_sk_attach_tlv(wmi_handle);
+}
+

+ 491 - 0
wmi_unified_sta_api.c

@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+/**
+ * DOC: Implement API's specific to STA component.
+ */
+#include <wmi.h>
+#include "wmi_unified_priv.h"
+#include "wmi_unified_sta_api.h"
+
+QDF_STATUS wmi_unified_set_sta_sa_query_param_cmd(void *wmi_hdl,
+						  uint8_t vdev_id,
+						  uint32_t max_retries,
+						  uint32_t retry_interval)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_sta_sa_query_param_cmd)
+		return wmi_handle->ops->send_set_sta_sa_query_param_cmd(wmi_handle,
+						vdev_id, max_retries,
+						retry_interval);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_sta_keep_alive_cmd(void *wmi_hdl,
+					      struct sta_params *params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_sta_keep_alive_cmd)
+		return wmi_handle->ops->send_set_sta_keep_alive_cmd(wmi_handle,
+								    params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_vdev_set_gtx_cfg_cmd(void *wmi_hdl, uint32_t if_id,
+			struct wmi_gtx_config *gtx_info)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_vdev_set_gtx_cfg_cmd)
+		return wmi_handle->ops->send_vdev_set_gtx_cfg_cmd(wmi_handle,
+								  if_id,
+								  gtx_info);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_process_dhcp_ind(void *wmi_hdl,
+				wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_process_dhcp_ind_cmd)
+		return wmi_handle->ops->send_process_dhcp_ind_cmd(wmi_handle,
+								  ta_dhcp_ind);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_get_link_speed_cmd(void *wmi_hdl,
+					  wmi_mac_addr peer_macaddr)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_get_link_speed_cmd)
+		return wmi_handle->ops->send_get_link_speed_cmd(wmi_handle,
+								peer_macaddr);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_fw_profiling_data_cmd(void *wmi_hdl,
+			uint32_t cmd, uint32_t value1, uint32_t value2)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_fw_profiling_cmd)
+		return wmi_handle->ops->send_fw_profiling_cmd(wmi_handle,
+							      cmd,
+							      value1,
+							      value2);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_nat_keepalive_en_cmd(void *wmi_hdl, uint8_t vdev_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_nat_keepalive_en_cmd)
+		return wmi_handle->ops->send_nat_keepalive_en_cmd(wmi_handle,
+								  vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_wlm_latency_level_cmd(void *wmi_hdl,
+					struct wlm_latency_level_param *param)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_wlm_latency_level_cmd)
+		return wmi_handle->ops->send_wlm_latency_level_cmd(wmi_handle,
+								   param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_nan_req_cmd(void *wmi_hdl,
+			struct nan_req_params *nan_req)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_nan_req_cmd)
+		return wmi_handle->ops->send_nan_req_cmd(wmi_handle,
+							 nan_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_process_set_ie_info_cmd(void *wmi_hdl,
+				   struct vdev_ie_info_param *ie_info)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_process_set_ie_info_cmd)
+		return wmi_handle->ops->send_process_set_ie_info_cmd(wmi_handle,
+								     ie_info);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_base_macaddr_indicate_cmd(void *wmi_hdl,
+					 uint8_t *custom_addr)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_base_macaddr_indicate_cmd)
+		return wmi_handle->ops->send_set_base_macaddr_indicate_cmd(wmi_handle,
+			    custom_addr);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef CONVERGED_TDLS_ENABLE
+QDF_STATUS wmi_unified_set_tdls_offchan_mode_cmd(void *wmi_hdl,
+			      struct tdls_channel_switch_params *chan_switch_params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_tdls_offchan_mode_cmd)
+		return wmi_handle->ops->send_set_tdls_offchan_mode_cmd(wmi_handle,
+			    chan_switch_params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_update_fw_tdls_state_cmd(void *wmi_hdl,
+					 void *tdls_param, uint8_t tdls_state)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_update_fw_tdls_state_cmd)
+		return wmi_handle->ops->send_update_fw_tdls_state_cmd(wmi_handle,
+			    tdls_param, tdls_state);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_update_tdls_peer_state_cmd(void *wmi_hdl,
+			       struct tdls_peer_state_params *peerStateParams,
+				   uint32_t *ch_mhz)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_update_tdls_peer_state_cmd)
+		return wmi_handle->ops->send_update_tdls_peer_state_cmd(wmi_handle,
+			    peerStateParams, ch_mhz);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_vdev_tdls_ev_param(void *wmi_hdl, void *evt_buf,
+					  struct tdls_event_info *param)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl;
+
+	if (wmi_handle->ops->extract_vdev_tdls_ev_param)
+		return wmi_handle->ops->extract_vdev_tdls_ev_param(wmi_handle,
+				evt_buf, param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* CONVERGED_TDLS_ENABLE */
+
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS wmi_unified_encrypt_decrypt_send_cmd(void *wmi_hdl,
+				struct disa_encrypt_decrypt_req_params *params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_encrypt_decrypt_send_cmd)
+		return wmi_handle->ops->send_encrypt_decrypt_send_cmd(
+						wmi_handle,
+						params);
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_encrypt_decrypt_resp_params(void *wmi_hdl,
+			uint8_t *evt_buf,
+			struct disa_encrypt_decrypt_resp_params *resp)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+
+	if (wmi_handle->ops->extract_encrypt_decrypt_resp_event)
+		return wmi_handle->ops->extract_encrypt_decrypt_resp_event(
+				wmi_handle, evt_buf, resp);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* WLAN_FEATURE_DISA */
+
+QDF_STATUS wmi_unified_send_sar_limit_cmd(void *wmi_hdl,
+				struct sar_limit_cmd_params *params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_sar_limit_cmd)
+		return wmi_handle->ops->send_sar_limit_cmd(
+						wmi_handle,
+						params);
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_get_sar_limit_cmd(void *wmi_hdl)
+{
+	wmi_unified_t wmi_handle = wmi_hdl;
+
+	if (wmi_handle->ops->get_sar_limit_cmd)
+		return wmi_handle->ops->get_sar_limit_cmd(wmi_handle);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_extract_sar_limit_event(void *wmi_hdl,
+					       uint8_t *evt_buf,
+					       struct sar_limit_event *event)
+{
+	wmi_unified_t wmi_handle = wmi_hdl;
+
+	if (wmi_handle->ops->extract_sar_limit_event)
+		return wmi_handle->ops->extract_sar_limit_event(wmi_handle,
+								evt_buf,
+								event);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_extract_sar2_result_event(void *handle,
+						 uint8_t *event, uint32_t len)
+{
+	wmi_unified_t wmi_handle = handle;
+
+	if (wmi_handle->ops->extract_sar2_result_event)
+		return wmi_handle->ops->extract_sar2_result_event(wmi_handle,
+								  event,
+								  len);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_del_pmkid_cache(void *wmi_hdl,
+					struct wmi_unified_pmk_cache *req_buf)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_del_pmkid_cache_cmd)
+		return wmi_handle->ops->send_set_del_pmkid_cache_cmd(wmi_handle,
+								     req_buf);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_del_ts_cmd(void *wmi_hdl, uint8_t vdev_id,
+				  uint8_t ac)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_del_ts_cmd)
+		return wmi_handle->ops->send_del_ts_cmd(wmi_handle,
+							vdev_id, ac);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_aggr_qos_cmd(void *wmi_hdl,
+		      struct aggr_add_ts_param *aggr_qos_rsp_msg)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_aggr_qos_cmd)
+		return wmi_handle->ops->send_aggr_qos_cmd(wmi_handle,
+							  aggr_qos_rsp_msg);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_add_ts_cmd(void *wmi_hdl,
+		 struct add_ts_param *msg)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_add_ts_cmd)
+		return wmi_handle->ops->send_add_ts_cmd(wmi_handle,
+							msg);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_process_add_periodic_tx_ptrn_cmd(void *wmi_hdl,
+						struct periodic_tx_pattern  *
+						pAddPeriodicTxPtrnParams,
+						uint8_t vdev_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_process_add_periodic_tx_ptrn_cmd)
+		return wmi_handle->ops->send_process_add_periodic_tx_ptrn_cmd(
+				wmi_handle,
+				pAddPeriodicTxPtrnParams,
+				vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_process_del_periodic_tx_ptrn_cmd(void *wmi_hdl,
+						uint8_t vdev_id,
+						uint8_t pattern_id)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_process_del_periodic_tx_ptrn_cmd)
+		return wmi_handle->ops->send_process_del_periodic_tx_ptrn_cmd(
+				wmi_handle,
+				vdev_id,
+				pattern_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_auto_shutdown_timer_cmd(void *wmi_hdl,
+						  uint32_t timer_val)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_auto_shutdown_timer_cmd)
+		return wmi_handle->ops->send_set_auto_shutdown_timer_cmd(
+				wmi_handle,
+				timer_val);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_led_flashing_cmd(void *wmi_hdl,
+				struct flashing_req_params *flashing)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_led_flashing_cmd)
+		return wmi_handle->ops->send_set_led_flashing_cmd(wmi_handle,
+								  flashing);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_process_ch_avoid_update_cmd(void *wmi_hdl)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_process_ch_avoid_update_cmd)
+		return wmi_handle->ops->send_process_ch_avoid_update_cmd(
+				wmi_handle);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_pdev_set_pcl_cmd(void *wmi_hdl,
+				struct wmi_pcl_chan_weights *msg)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_pdev_set_pcl_cmd)
+		return wmi_handle->ops->send_pdev_set_pcl_cmd(wmi_handle, msg);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_soc_set_hw_mode_cmd(void *wmi_hdl,
+				uint32_t hw_mode_index)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_pdev_set_hw_mode_cmd)
+		return wmi_handle->ops->send_pdev_set_hw_mode_cmd(wmi_handle,
+				  hw_mode_index);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef WLAN_POLICY_MGR_ENABLE
+QDF_STATUS wmi_unified_pdev_set_dual_mac_config_cmd(void *wmi_hdl,
+		struct policy_mgr_dual_mac_config *msg)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_pdev_set_dual_mac_config_cmd)
+		return wmi_handle->ops->send_pdev_set_dual_mac_config_cmd(
+				wmi_handle,
+				msg);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* WLAN_POLICY_MGR_ENABLE */
+
+QDF_STATUS wmi_unified_send_adapt_dwelltime_params_cmd(void *wmi_hdl,
+			struct wmi_adaptive_dwelltime_params *dwelltime_params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_adapt_dwelltime_params_cmd)
+		return wmi_handle->ops->
+			send_adapt_dwelltime_params_cmd(wmi_handle,
+				  dwelltime_params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_send_dbs_scan_sel_params_cmd(void *wmi_hdl,
+			struct wmi_dbs_scan_sel_params *dbs_scan_params)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_dbs_scan_sel_params_cmd)
+		return wmi_handle->ops->
+			send_dbs_scan_sel_params_cmd(wmi_handle,
+						     dbs_scan_params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_arp_stats_req(void *wmi_hdl,
+					 struct set_arp_stats *req_buf)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_set_arp_stats_req_cmd)
+		return wmi_handle->ops->send_set_arp_stats_req_cmd(wmi_handle,
+								   req_buf);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_get_arp_stats_req(void *wmi_hdl,
+					 struct get_arp_stats *req_buf)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->send_get_arp_stats_req_cmd)
+		return wmi_handle->ops->send_get_arp_stats_req_cmd(wmi_handle,
+								   req_buf);
+
+	return QDF_STATUS_E_FAILURE;
+}
+

+ 2498 - 0
wmi_unified_sta_tlv.c

@@ -0,0 +1,2498 @@
+/*
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <osdep.h>
+#include "wmi.h"
+#include "wmi_version.h"
+#include "wmi_unified_priv.h"
+#include "wmi_unified_sta_param.h"
+#include "wmi_unified_sta_api.h"
+
+/**
+ * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @max_retries: max retries
+ * @retry_interval: retry interval
+ * This function sets sta query related parameters in fw.
+ *
+ * Return: QDF_STATUS_SUCCESS for success otherwise failure
+ */
+static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
+						      uint8_t vdev_id,
+						      uint32_t max_retries,
+						      uint32_t retry_interval)
+{
+	wmi_buf_t buf;
+	WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
+	int len;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+			(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+	cmd->sa_query_max_retry_count = max_retries;
+	cmd->sa_query_retry_interval = retry_interval;
+
+	WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
+		 vdev_id, retry_interval, max_retries);
+
+	wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
+		WMI_LOGE(FL("Failed to offload STA SA Query"));
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMI_LOGD(FL("Exit :"));
+	return 0;
+}
+
+/**
+ * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
+ * @wmi_handle: wmi handle
+ * @params: sta keep alive parameter
+ *
+ * This function sets keep alive related parameters in fw.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
+						  struct sta_params *params)
+{
+	wmi_buf_t buf;
+	WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
+	WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
+	uint8_t *buf_ptr;
+	int len;
+	QDF_STATUS ret;
+
+	WMI_LOGD("%s: Enter", __func__);
+
+	len = sizeof(*cmd) + sizeof(*arp_rsp);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
+	buf_ptr = (uint8_t *) cmd;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (WMI_STA_KEEPALIVE_CMD_fixed_param));
+	cmd->interval = params->timeperiod;
+	cmd->enable = (params->timeperiod) ? 1 : 0;
+	cmd->vdev_id = params->vdev_id;
+	WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id,
+		 params->timeperiod, params->method);
+	arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
+	WMITLV_SET_HDR(&arp_rsp->tlv_header,
+		       WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
+		       WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
+
+	if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) ||
+	    (params->method ==
+	     WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) {
+		if ((NULL == params->hostv4addr) ||
+			(NULL == params->destv4addr) ||
+			(NULL == params->destmac)) {
+			WMI_LOGE("%s: received null pointer, hostv4addr:%pK "
+				 "destv4addr:%pK destmac:%pK ", __func__,
+				 params->hostv4addr, params->destv4addr,
+				 params->destmac);
+			wmi_buf_free(buf);
+			return QDF_STATUS_E_FAILURE;
+		}
+		cmd->method = params->method;
+		qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
+			     WMI_IPV4_ADDR_LEN);
+		qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
+			     WMI_IPV4_ADDR_LEN);
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr);
+	} else {
+		cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
+	}
+
+	wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_STA_KEEPALIVE_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to set KeepAlive");
+		wmi_buf_free(buf);
+	}
+
+	WMI_LOGD("%s: Exit", __func__);
+	return ret;
+}
+
+/**
+ * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
+ * @wmi_handle: wmi handle
+ * @if_id: vdev id
+ * @gtx_info: GTX config params
+ *
+ * This function set GTX related params in firmware.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
+				  struct wmi_gtx_config *gtx_info)
+{
+	wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS ret;
+	int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_vdev_set_gtx_params_cmd_fixed_param));
+	cmd->vdev_id = if_id;
+
+	cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
+	cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
+	cmd->userGtxMask = gtx_info->gtx_usrcfg;
+	cmd->gtxPERThreshold = gtx_info->gtx_threshold;
+	cmd->gtxPERMargin = gtx_info->gtx_margin;
+	cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
+	cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
+	cmd->gtxBWMask = gtx_info->gtx_bwmask;
+
+	WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
+		 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
+		 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
+		 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
+		 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
+
+	wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_VDEV_SET_GTX_PARAMS_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to set GTX PARAMS");
+		wmi_buf_free(buf);
+	}
+	return ret;
+}
+
+/**
+ * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
+ * @wmi_handle: wmi handle
+ * @ta_dhcp_ind: DHCP indication parameter
+ *
+ * Return: CDF Status
+ */
+static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
+				wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	uint8_t *buf_ptr;
+	wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
+	int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_peer_set_param_cmd_fixed_param));
+
+	/* fill in values */
+	peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
+	peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
+	peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
+	qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
+		     &ta_dhcp_ind->peer_macaddr,
+		     sizeof(ta_dhcp_ind->peer_macaddr));
+
+	wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_PEER_SET_PARAM_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
+			 " returned Error %d", __func__, status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_get_link_speed_cmd_tlv() -send command to get linkspeed
+ * @wmi_handle: wmi handle
+ * @pLinkSpeed: link speed info
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
+					      wmi_mac_addr peer_macaddr)
+{
+	wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t len;
+	uint8_t *buf_ptr;
+
+	len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
+
+	cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	       WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
+	       WMITLV_GET_STRUCT_TLVLEN
+			(wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
+
+	/* Copy the peer macaddress to the wma buffer */
+	qdf_mem_copy(&cmd->peer_macaddr,
+		     &peer_macaddr,
+		     sizeof(peer_macaddr));
+
+	wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
+		WMI_LOGE("%s: failed to send link speed command", __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
+ * @wmi_handl: wmi handle
+ * @cmd: Profiling command index
+ * @value1: parameter1 value
+ * @value2: parameter2 value
+ *
+ * Return: QDF_STATUS_SUCCESS for success else error code
+ */
+static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
+			uint32_t cmd, uint32_t value1, uint32_t value2)
+{
+	wmi_buf_t buf;
+	int32_t len = 0;
+	int ret;
+	wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
+	wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
+	wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
+	wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
+
+	switch (cmd) {
+	case WMI_WLAN_PROFILE_TRIGGER_CMDID:
+		len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
+		buf = wmi_buf_alloc(wmi_handle, len);
+		if (!buf) {
+			return QDF_STATUS_E_NOMEM;
+		}
+		prof_trig_cmd =
+			(wmi_wlan_profile_trigger_cmd_fixed_param *)
+				wmi_buf_data(buf);
+		WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
+		     WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
+		     WMITLV_GET_STRUCT_TLVLEN
+				(wmi_wlan_profile_trigger_cmd_fixed_param));
+		prof_trig_cmd->enable = value1;
+		wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0);
+		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+					   WMI_WLAN_PROFILE_TRIGGER_CMDID);
+		if (ret) {
+			WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
+				 value1);
+			wmi_buf_free(buf);
+			return ret;
+		}
+		break;
+
+	case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
+		len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
+		buf = wmi_buf_alloc(wmi_handle, len);
+		if (!buf) {
+			return QDF_STATUS_E_NOMEM;
+		}
+		profile_getdata_cmd =
+			(wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
+				wmi_buf_data(buf);
+		WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
+		      WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
+		      WMITLV_GET_STRUCT_TLVLEN
+		      (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
+		wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+			   NO_SESSION, 0);
+		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
+		if (ret) {
+			WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
+				 value1, value2);
+			wmi_buf_free(buf);
+			return ret;
+		}
+		break;
+
+	case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
+		len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
+		buf = wmi_buf_alloc(wmi_handle, len);
+		if (!buf) {
+			return QDF_STATUS_E_NOMEM;
+		}
+		hist_intvl_cmd =
+			(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
+				wmi_buf_data(buf);
+		WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
+		      WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
+		      WMITLV_GET_STRUCT_TLVLEN
+		      (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
+		hist_intvl_cmd->profile_id = value1;
+		hist_intvl_cmd->value = value2;
+		wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+			   NO_SESSION, 0);
+		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
+		if (ret) {
+			WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
+				 value1, value2);
+			wmi_buf_free(buf);
+			return ret;
+		}
+		break;
+
+	case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
+		len =
+		sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
+		buf = wmi_buf_alloc(wmi_handle, len);
+		if (!buf) {
+			return QDF_STATUS_E_NOMEM;
+		}
+		profile_enable_cmd =
+			(wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
+				wmi_buf_data(buf);
+		WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
+		      WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
+		      WMITLV_GET_STRUCT_TLVLEN
+		      (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
+		profile_enable_cmd->profile_id = value1;
+		profile_enable_cmd->enable = value2;
+		wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+			   NO_SESSION, 0);
+		ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
+		if (ret) {
+			WMI_LOGE("enable cmd Failed for id %d value %d",
+				 value1, value2);
+			wmi_buf_free(buf);
+			return ret;
+		}
+		break;
+
+	default:
+		WMI_LOGD("%s: invalid profiling command", __func__);
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
+{
+	WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
+		wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
+		  WMITLV_GET_STRUCT_TLVLEN
+		  (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
+	wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
+		WMI_LOGP("%s: Failed to send NAT keepalive enable command",
+			 __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return 0;
+}
+
+static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
+				struct wlm_latency_level_param *params)
+{
+	wmi_wlm_config_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len = sizeof(*cmd);
+	static uint32_t ll[4] = {100, 60, 40, 20};
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_wlm_config_cmd_fixed_param));
+	cmd->vdev_id = params->vdev_id;
+	cmd->latency_level = params->wlm_latency_level;
+	cmd->ul_latency = ll[params->wlm_latency_level];
+	cmd->dl_latency = ll[params->wlm_latency_level];
+	cmd->flags = params->wlm_latency_flags;
+	wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_WLM_CONFIG_CMDID)) {
+		WMI_LOGE("%s: Failed to send setting latency config command",
+			 __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return 0;
+}
+
+/**
+ * send_nan_req_cmd_tlv() - to send nan request to target
+ * @wmi_handle: wmi handle
+ * @nan_req: request data which will be non-null
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
+			struct nan_req_params *nan_req)
+{
+	QDF_STATUS ret;
+	wmi_nan_cmd_param *cmd;
+	wmi_buf_t buf;
+	uint16_t len = sizeof(*cmd);
+	uint16_t nan_data_len, nan_data_len_aligned;
+	uint8_t *buf_ptr;
+
+	/*
+	 *    <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
+	 *    +------------+----------+-----------------------+--------------+
+	 *    | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data |
+	 *    +------------+----------+-----------------------+--------------+
+	 */
+	if (!nan_req) {
+		WMI_LOGE("%s:nan req is not valid", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	nan_data_len = nan_req->request_data_len;
+	nan_data_len_aligned = roundup(nan_req->request_data_len,
+				       sizeof(uint32_t));
+	if (nan_data_len_aligned < nan_req->request_data_len) {
+		WMI_LOGE("%s: integer overflow while rounding up data_len",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
+		WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (wmi_nan_cmd_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_nan_cmd_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
+	cmd->data_len = nan_req->request_data_len;
+	WMI_LOGD("%s: The data len value is %u",
+		 __func__, nan_req->request_data_len);
+	buf_ptr += sizeof(wmi_nan_cmd_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
+
+	wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_NAN_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("%s Failed to send set param command ret = %d",
+			 __func__, ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+#ifdef CONVERGED_TDLS_ENABLE
+/**
+ * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode
+ * @tdls_sw_mode: tdls_sw_mode
+ *
+ * This function returns wmi tdls offchannel mode
+ *
+ * Return: enum value of wmi tdls offchannel mode
+ */
+static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode)
+{
+	uint8_t off_chan_mode;
+
+	switch (tdls_sw_mode) {
+	case ENABLE_CHANSWITCH:
+		off_chan_mode = WMI_TDLS_ENABLE_OFFCHANNEL;
+		break;
+
+	case DISABLE_CHANSWITCH:
+		off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
+		break;
+
+	default:
+		WMI_LOGD(FL("unknown tdls_sw_mode %d"), tdls_sw_mode);
+		off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
+	}
+	return off_chan_mode;
+}
+
+/**
+ * tdls_get_wmi_offchannel_bw - Get WMI tdls off channel Bandwidth
+ * @tdls_sw_mode: tdls_sw_mode
+ *
+ * This function returns wmi tdls offchannel bandwidth
+ *
+ * Return: TDLS offchannel bandwidth
+ */
+static uint8_t tdls_get_wmi_offchannel_bw(uint16_t tdls_off_ch_bw_offset)
+{
+	uint8_t off_chan_bw;
+
+	switch (tdls_off_ch_bw_offset) {
+	case BW20:
+		off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
+		break;
+	case BW40_LOW_PRIMARY:
+	case BW40_HIGH_PRIMARY:
+		off_chan_bw = WMI_TDLS_OFFCHAN_40MHZ;
+		break;
+	case BW80:
+		off_chan_bw = WMI_TDLS_OFFCHAN_80MHZ;
+	case BWALL:
+		off_chan_bw = WMI_TDLS_OFFCHAN_160MHZ;
+	default:
+		WMI_LOGD(FL("unknown tdls_offchannel bw offset %d"),
+			 off_chan_bw);
+		off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
+	}
+	return off_chan_bw;
+}
+
+/**
+ * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
+ * @wmi_handle: wmi handle
+ * @chan_switch_params: Pointer to tdls channel switch parameter structure
+ *
+ * This function sets tdls off channel mode
+ *
+ * Return: 0 on success; Negative errno otherwise
+ */
+static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
+	      struct tdls_channel_switch_params *chan_switch_params)
+{
+	wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
+
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_FAILURE;
+	}
+	cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
+		wmi_buf_data(wmi_buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_tdls_set_offchan_mode_cmd_fixed_param));
+
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
+				&cmd->peer_macaddr);
+	cmd->vdev_id = chan_switch_params->vdev_id;
+	cmd->offchan_mode =
+		tdls_get_wmi_offchannel_mode(chan_switch_params->tdls_sw_mode);
+	cmd->is_peer_responder = chan_switch_params->is_responder;
+	cmd->offchan_num = chan_switch_params->tdls_off_ch;
+	cmd->offchan_bw_bitmap =
+		tdls_get_wmi_offchannel_bw(
+			chan_switch_params->tdls_off_ch_bw_offset);
+	cmd->offchan_oper_class = chan_switch_params->oper_class;
+
+	WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
+		 cmd->peer_macaddr.mac_addr31to0,
+		 cmd->peer_macaddr.mac_addr47to32);
+
+	WMI_LOGD(FL(
+		 "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
+		 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d"
+		  ),
+		 cmd->vdev_id,
+		 cmd->offchan_mode,
+		 cmd->offchan_num,
+		 cmd->offchan_bw_bitmap,
+		 cmd->is_peer_responder,
+		 cmd->offchan_oper_class);
+
+	wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+		WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
+		WMI_LOGP(FL("failed to send tdls off chan command"));
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
+ * @wmi_handle: wmi handle
+ * @pwmaTdlsparams: TDLS params
+ *
+ * Return: 0 for success or error code
+ */
+static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
+					 void *tdls_param, uint8_t tdls_state)
+{
+	wmi_tdls_set_state_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+
+	struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param;
+	uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
+
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_FAILURE;
+	}
+	cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		  WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
+		  WMITLV_GET_STRUCT_TLVLEN
+			(wmi_tdls_set_state_cmd_fixed_param));
+	cmd->vdev_id = wmi_tdls->vdev_id;
+	cmd->state = tdls_state;
+	cmd->notification_interval_ms = wmi_tdls->notification_interval_ms;
+	cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold;
+	cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold;
+	cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold;
+	cmd->rssi_delta = wmi_tdls->rssi_delta;
+	cmd->tdls_options = wmi_tdls->tdls_options;
+	cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window;
+	cmd->tdls_peer_traffic_response_timeout_ms =
+		wmi_tdls->peer_traffic_response_timeout;
+	cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask;
+	cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time;
+	cmd->tdls_puapsd_rx_frame_threshold =
+		wmi_tdls->puapsd_rx_frame_threshold;
+	cmd->teardown_notification_ms =
+		wmi_tdls->teardown_notification_ms;
+	cmd->tdls_peer_kickout_threshold =
+		wmi_tdls->tdls_peer_kickout_threshold;
+
+	WMI_LOGD("%s: tdls_state: %d, state: %d, "
+		 "notification_interval_ms: %d, "
+		 "tx_discovery_threshold: %d, "
+		 "tx_teardown_threshold: %d, "
+		 "rssi_teardown_threshold: %d, "
+		 "rssi_delta: %d, "
+		 "tdls_options: 0x%x, "
+		 "tdls_peer_traffic_ind_window: %d, "
+		 "tdls_peer_traffic_response_timeout: %d, "
+		 "tdls_puapsd_mask: 0x%x, "
+		 "tdls_puapsd_inactivity_time: %d, "
+		 "tdls_puapsd_rx_frame_threshold: %d, "
+		 "teardown_notification_ms: %d, "
+		 "tdls_peer_kickout_threshold: %d",
+		 __func__, tdls_state, cmd->state,
+		 cmd->notification_interval_ms,
+		 cmd->tx_discovery_threshold,
+		 cmd->tx_teardown_threshold,
+		 cmd->rssi_teardown_threshold,
+		 cmd->rssi_delta,
+		 cmd->tdls_options,
+		 cmd->tdls_peer_traffic_ind_window,
+		 cmd->tdls_peer_traffic_response_timeout_ms,
+		 cmd->tdls_puapsd_mask,
+		 cmd->tdls_puapsd_inactivity_time_ms,
+		 cmd->tdls_puapsd_rx_frame_threshold,
+		 cmd->teardown_notification_ms,
+		 cmd->tdls_peer_kickout_threshold);
+
+	wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_TDLS_SET_STATE_CMDID)) {
+		WMI_LOGP("%s: failed to send tdls set state command", __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
+ * @wmi_handle: wmi handle
+ * @peerStateParams: TDLS peer state params
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
+			       struct tdls_peer_state_params *peerStateParams,
+				   uint32_t *ch_mhz)
+{
+	wmi_tdls_peer_update_cmd_fixed_param *cmd;
+	wmi_tdls_peer_capabilities *peer_cap;
+	wmi_channel *chan_info;
+	wmi_buf_t wmi_buf;
+	uint8_t *buf_ptr;
+	uint32_t i;
+	int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
+		      sizeof(wmi_tdls_peer_capabilities);
+
+	len += WMI_TLV_HDR_SIZE +
+	       sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
+
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
+	cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_tdls_peer_update_cmd_fixed_param));
+
+	cmd->vdev_id = peerStateParams->vdevId;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr,
+				   &cmd->peer_macaddr);
+
+	cmd->peer_state = peerStateParams->peerState;
+
+	WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, "
+		 "peer_macaddr.mac_addr31to0: 0x%x, "
+		 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
+		 __func__, cmd->vdev_id, peerStateParams->peerMacAddr,
+		 cmd->peer_macaddr.mac_addr31to0,
+		 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
+
+	buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
+	peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
+	WMITLV_SET_HDR(&peer_cap->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
+
+	if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3)
+		WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
+	if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2)
+		WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
+	if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1)
+		WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
+	if (peerStateParams->peerCap.peerUapsdQueue & 0x01)
+		WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
+
+	/* Ack and More Data Ack are sent as 0, so no need to set
+	 * but fill SP
+	 */
+	WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap,
+				   peerStateParams->peerCap.peerMaxSp);
+
+	peer_cap->buff_sta_support =
+		peerStateParams->peerCap.peerBuffStaSupport;
+	peer_cap->off_chan_support =
+		peerStateParams->peerCap.peerOffChanSupport;
+	peer_cap->peer_curr_operclass =
+		peerStateParams->peerCap.peerCurrOperClass;
+	/* self curr operclass is not being used and so pass op class for
+	 * preferred off chan in it.
+	 */
+	peer_cap->self_curr_operclass =
+		peerStateParams->peerCap.opClassForPrefOffChan;
+	peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen;
+	peer_cap->peer_operclass_len =
+		peerStateParams->peerCap.peerOperClassLen;
+
+	WMI_LOGD("%s: peer_operclass_len: %d",
+		 __func__, peer_cap->peer_operclass_len);
+	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
+		peer_cap->peer_operclass[i] =
+			peerStateParams->peerCap.peerOperClass[i];
+		WMI_LOGD("%s: peer_operclass[%d]: %d",
+			 __func__, i, peer_cap->peer_operclass[i]);
+	}
+
+	peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder;
+	peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum;
+	peer_cap->pref_offchan_bw =
+		peerStateParams->peerCap.prefOffChanBandwidth;
+
+	WMI_LOGD
+		("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
+		 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
+		 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
+		 " %d, pref_offchan_bw: %d",
+		 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
+		 peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
+		 peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
+		 peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
+		 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw);
+
+	/* next fill variable size array of peer chan info */
+	buf_ptr += sizeof(wmi_tdls_peer_capabilities);
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_channel) *
+		       peerStateParams->peerCap.peerChanLen);
+	chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
+
+	for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
+		WMITLV_SET_HDR(&chan_info->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_channel,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
+		chan_info->mhz = ch_mhz[i];
+		chan_info->band_center_freq1 = chan_info->mhz;
+		chan_info->band_center_freq2 = 0;
+
+		WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
+
+		if (peerStateParams->peerCap.peerChan[i].dfsSet) {
+			WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
+			WMI_LOGI("chan[%d] DFS[%d]\n",
+				 peerStateParams->peerCap.peerChan[i].chanId,
+				 peerStateParams->peerCap.peerChan[i].dfsSet);
+		}
+
+		if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
+			WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
+		else
+			WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
+
+		WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
+					     peerStateParams->peerCap.
+					     peerChan[i].pwr);
+
+		WMI_SET_CHANNEL_REG_POWER(chan_info,
+					  peerStateParams->peerCap.peerChan[i].
+					  pwr);
+		WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
+			 peerStateParams->peerCap.peerChan[i].pwr);
+
+		chan_info++;
+	}
+
+	wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_TDLS_PEER_UPDATE_CMDID)) {
+		WMI_LOGE("%s: failed to send tdls peer update state command",
+			 __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param param: Pointer to hold vdev tdls param
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
+	void *evt_buf, struct tdls_event_info *param)
+{
+	WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
+	wmi_tdls_peer_event_fixed_param *evt;
+
+	param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
+	if (!param_buf) {
+		WMI_LOGE("%s: NULL param_buf", __func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	evt = param_buf->fixed_param;
+
+	qdf_mem_zero(param, sizeof(*param));
+
+	param->vdev_id = evt->vdev_id;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
+				   param->peermac.bytes);
+	switch (evt->peer_status) {
+	case WMI_TDLS_SHOULD_DISCOVER:
+		param->message_type = TDLS_SHOULD_DISCOVER;
+		break;
+	case WMI_TDLS_SHOULD_TEARDOWN:
+		param->message_type = TDLS_SHOULD_TEARDOWN;
+		break;
+	case WMI_TDLS_PEER_DISCONNECTED:
+		param->message_type = TDLS_PEER_DISCONNECTED;
+		break;
+	case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
+		param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
+		break;
+	default:
+		WMI_LOGE("%s: Discarding unknown tdls event %d from target",
+			 __func__, evt->peer_status);
+		return QDF_STATUS_E_INVAL;
+	};
+
+	switch (evt->peer_reason) {
+	case WMI_TDLS_TEARDOWN_REASON_TX:
+		param->peer_reason = TDLS_TEARDOWN_TX;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_RSSI:
+		param->peer_reason = TDLS_TEARDOWN_RSSI;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_SCAN:
+		param->peer_reason = TDLS_TEARDOWN_SCAN;
+		break;
+	case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
+		param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
+		param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
+		param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
+		param->peer_reason = TDLS_TEARDOWN_NO_RSP;
+		break;
+	case WMI_TDLS_ENTER_BUF_STA:
+		param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
+		break;
+	case WMI_TDLS_EXIT_BUF_STA:
+		param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
+		break;
+	case WMI_TDLS_ENTER_BT_BUSY_MODE:
+		param->peer_reason = TDLS_ENTER_BT_BUSY;
+		break;
+	case WMI_TDLS_EXIT_BT_BUSY_MODE:
+		param->peer_reason = TDLS_EXIT_BT_BUSY;
+		break;
+	case WMI_TDLS_SCAN_STARTED_EVENT:
+		param->peer_reason = TDLS_SCAN_STARTED;
+		break;
+	case WMI_TDLS_SCAN_COMPLETED_EVENT:
+		param->peer_reason = TDLS_SCAN_COMPLETED;
+		break;
+
+	default:
+		WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
+			 __func__, evt->peer_reason, evt->peer_status);
+		return QDF_STATUS_E_INVAL;
+	};
+
+	WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
+		 __func__, param->peermac.bytes, param->message_type,
+		 param->peer_reason, param->vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_tdls_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_tdls_offchan_mode_cmd =
+		send_set_tdls_offchan_mode_cmd_tlv;
+	ops->send_update_fw_tdls_state_cmd =
+		send_update_fw_tdls_state_cmd_tlv;
+	ops->send_update_tdls_peer_state_cmd =
+		send_update_tdls_peer_state_cmd_tlv;
+	ops->extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv;
+}
+#endif /* CONVERGED_TDLS_ENABLE */
+
+/*
+ * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
+ * @wmi_handle:    Pointer to WMi handle
+ * @ie_data:       Pointer for ie data
+ *
+ * This function sends IE information to firmware
+ *
+ * Return: QDF_STATUS_SUCCESS for success otherwise failure
+ *
+ */
+static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
+				   struct vdev_ie_info_param *ie_info)
+{
+	wmi_vdev_set_ie_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint32_t len, ie_len_aligned;
+	QDF_STATUS ret;
+
+	ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
+	/* Allocate memory for the WMI command */
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = wmi_buf_data(buf);
+	qdf_mem_zero(buf_ptr, len);
+
+	/* Populate the WMI command */
+	cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				wmi_vdev_set_ie_cmd_fixed_param));
+	cmd->vdev_id = ie_info->vdev_id;
+	cmd->ie_id = ie_info->ie_id;
+	cmd->ie_len = ie_info->length;
+	cmd->band = ie_info->band;
+
+	WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
+		    ie_info->length, ie_info->vdev_id);
+
+	buf_ptr += sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
+
+	wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_VDEV_SET_IE_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
+ * @wmi_handle: wmi handle
+ * @custom_addr: base mac address
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
+					 uint8_t *custom_addr)
+{
+	wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int err;
+
+	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
+	qdf_mem_zero(cmd, sizeof(*cmd));
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_pdev_set_base_macaddr_cmd_fixed_param));
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
+	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
+							WMI_HOST_PDEV_ID_SOC);
+	wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf,
+				   sizeof(*cmd),
+				   WMI_PDEV_SET_BASE_MACADDR_CMDID);
+	if (err) {
+		WMI_LOGE("Failed to send set_base_macaddr cmd");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_DISA
+/**
+ * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw
+ * @wmi_handle: wmi handle
+ * @params: encrypt/decrypt params
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static
+QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle,
+		struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params)
+{
+	wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint8_t *buf_ptr;
+	QDF_STATUS ret;
+	uint32_t len;
+
+	WMI_LOGD(FL("Send encrypt decrypt cmd"));
+
+	len = sizeof(*cmd) +
+		roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) +
+		WMI_TLV_HDR_SIZE;
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = wmi_buf_data(wmi_buf);
+	cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param));
+
+	cmd->vdev_id = encrypt_decrypt_params->vdev_id;
+	cmd->key_flag = encrypt_decrypt_params->key_flag;
+	cmd->key_idx = encrypt_decrypt_params->key_idx;
+	cmd->key_cipher = encrypt_decrypt_params->key_cipher;
+	cmd->key_len = encrypt_decrypt_params->key_len;
+	cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len;
+	cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len;
+
+	qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data,
+		     encrypt_decrypt_params->key_len);
+
+	qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header,
+		     MAX_MAC_HEADER_LEN);
+
+	cmd->data_len = encrypt_decrypt_params->data_len;
+
+	if (cmd->data_len) {
+		buf_ptr += sizeof(*cmd);
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+			       roundup(encrypt_decrypt_params->data_len,
+				       sizeof(uint32_t)));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data,
+			     encrypt_decrypt_params->data_len);
+	}
+
+	/* This conversion is to facilitate data to FW in little endian */
+	cmd->pn[5] = encrypt_decrypt_params->pn[0];
+	cmd->pn[4] = encrypt_decrypt_params->pn[1];
+	cmd->pn[3] = encrypt_decrypt_params->pn[2];
+	cmd->pn[2] = encrypt_decrypt_params->pn[3];
+	cmd->pn[1] = encrypt_decrypt_params->pn[4];
+	cmd->pn[0] = encrypt_decrypt_params->pn[5];
+
+	wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle,
+				   wmi_buf, len,
+				   WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret);
+		wmi_buf_free(wmi_buf);
+	}
+
+	return ret;
+}
+
+/**
+ * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp
+ *	params from event
+ * @wmi_handle: wmi handle
+ * @evt_buf: pointer to event buffer
+ * @resp: Pointer to hold resp parameters
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static
+QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle,
+	void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp)
+{
+	WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
+	wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
+
+	param_buf = evt_buf;
+	if (!param_buf) {
+		WMI_LOGE("encrypt decrypt resp evt_buf is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	data_event = param_buf->fixed_param;
+
+	resp->vdev_id = data_event->vdev_id;
+	resp->status = data_event->status;
+
+	if ((data_event->data_length > param_buf->num_enc80211_frame) ||
+	    (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE -
+	     sizeof(*data_event))) {
+		WMI_LOGE("FW msg data_len %d more than TLV hdr %d",
+			 data_event->data_length,
+			 param_buf->num_enc80211_frame);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	resp->data_len = data_event->data_length;
+
+	if (resp->data_len)
+		resp->data = (uint8_t *)param_buf->enc80211_frame;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_disa_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_encrypt_decrypt_send_cmd =
+		send_encrypt_decrypt_send_cmd_tlv;
+	ops->extract_encrypt_decrypt_resp_event =
+		extract_encrypt_decrypt_resp_event_tlv;
+}
+#endif /* WLAN_FEATURE_DISA */
+
+/**
+ * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
+ * @wmi_handle: wmi handle
+ * @params: sar limit params
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
+		struct sar_limit_cmd_params *sar_limit_params)
+{
+	wmi_buf_t buf;
+	QDF_STATUS qdf_status;
+	wmi_sar_limits_cmd_fixed_param *cmd;
+	int i;
+	uint8_t *buf_ptr;
+	wmi_sar_limit_cmd_row *wmi_sar_rows_list;
+	struct sar_limit_cmd_row *sar_rows_list;
+	uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+
+	len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_sar_limits_cmd_fixed_param));
+	cmd->sar_enable = sar_limit_params->sar_enable;
+	cmd->commit_limits = sar_limit_params->commit_limits;
+	cmd->num_limit_rows = sar_limit_params->num_limit_rows;
+
+	WMI_LOGD("no of sar rows = %d, len = %d",
+		 sar_limit_params->num_limit_rows, len);
+	buf_ptr += sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_sar_limit_cmd_row) *
+			      sar_limit_params->num_limit_rows);
+	if (cmd->num_limit_rows == 0)
+		goto send_sar_limits;
+
+	wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
+				(buf_ptr + WMI_TLV_HDR_SIZE);
+	sar_rows_list = sar_limit_params->sar_limit_row_list;
+
+	for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
+		WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
+		wmi_sar_rows_list->band_id = sar_rows_list->band_id;
+		wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
+		wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
+		wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
+		wmi_sar_rows_list->validity_bitmap =
+						sar_rows_list->validity_bitmap;
+		WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
+			 i, wmi_sar_rows_list->band_id,
+			 wmi_sar_rows_list->chain_id,
+			 wmi_sar_rows_list->mod_id,
+			 wmi_sar_rows_list->limit_value,
+			 wmi_sar_rows_list->validity_bitmap);
+		sar_rows_list++;
+		wmi_sar_rows_list++;
+	}
+send_sar_limits:
+	wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0);
+	qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
+					  WMI_SAR_LIMITS_CMDID);
+
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
+		wmi_buf_free(buf);
+	}
+
+end:
+	return qdf_status;
+}
+
+static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
+{
+	wmi_sar_get_limits_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t len;
+	QDF_STATUS status;
+
+	WMI_LOGD(FL("Enter"));
+
+	len = sizeof(*cmd);
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_sar_get_limits_cmd_fixed_param));
+
+	cmd->reserved = 0;
+
+	wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				      WMI_SAR_GET_LIMITS_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
+		wmi_buf_free(wmi_buf);
+	}
+
+	WMI_LOGD(FL("Exit"));
+
+	return status;
+}
+
+/**
+ * wmi_sar2_result_string() - return string conversion of sar2 result
+ * @result: sar2 result value
+ *
+ * This utility function helps log string conversion of sar2 result.
+ *
+ * Return: string conversion of sar 2 result, if match found;
+ *	   "Unknown response" otherwise.
+ */
+static const char *wmi_sar2_result_string(uint32_t result)
+{
+	switch (result) {
+	CASE_RETURN_STRING(WMI_SAR2_SUCCESS);
+	CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX);
+	CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX);
+	CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR);
+	CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE);
+	default:
+		return "Unknown response";
+	}
+}
+
+/**
+ * extract_sar2_result_event_tlv() -  process sar response event from FW.
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+static QDF_STATUS extract_sar2_result_event_tlv(void *handle,
+						uint8_t *event,
+						uint32_t len)
+{
+	wmi_sar2_result_event_fixed_param *sar2_fixed_param;
+
+	WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf =
+		(WMI_SAR2_RESULT_EVENTID_param_tlvs *)event;
+
+	if (!param_buf) {
+		WMI_LOGI("Invalid sar2 result event buffer");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	sar2_fixed_param = param_buf->fixed_param;
+	if (!sar2_fixed_param) {
+		WMI_LOGI("Invalid sar2 result event fixed param buffer");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMI_LOGI("SAR2 result: %s",
+		 wmi_sar2_result_string(sar2_fixed_param->result));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
+					      uint8_t *evt_buf,
+					      struct sar_limit_event *event)
+{
+	wmi_sar_get_limits_event_fixed_param *fixed_param;
+	WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
+	wmi_sar_get_limit_event_row *row_in;
+	struct sar_limit_event_row *row_out;
+	uint32_t row;
+
+	if (!evt_buf) {
+		WMI_LOGE(FL("input event is NULL"));
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!event) {
+		WMI_LOGE(FL("output event is NULL"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
+
+	fixed_param = param_buf->fixed_param;
+	if (!fixed_param) {
+		WMI_LOGE(FL("Invalid fixed param"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	event->sar_enable = fixed_param->sar_enable;
+	event->num_limit_rows = fixed_param->num_limit_rows;
+
+	if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
+		QDF_ASSERT(0);
+		WMI_LOGE(FL("Num rows %d exceeds max of %d"),
+			 event->num_limit_rows,
+			 MAX_SAR_LIMIT_ROWS_SUPPORTED);
+		event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
+	}
+
+	row_in = param_buf->sar_get_limits;
+	row_out = &event->sar_limit_row[0];
+	for (row = 0; row < event->num_limit_rows; row++) {
+		row_out->band_id = row_in->band_id;
+		row_out->chain_id = row_in->chain_id;
+		row_out->mod_id = row_in->mod_id;
+		row_out->limit_value = row_in->limit_value;
+		row_out++;
+		row_in++;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
+ * @wmi_handle: wmi handler
+ * @pmk_info: pointer to PMK cache entry
+ * @vdev_id: vdev id
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
+				struct wmi_unified_pmk_cache *pmk_info)
+{
+	wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS status;
+	uint8_t *buf_ptr;
+	wmi_pmk_cache *pmksa;
+	uint32_t len = sizeof(*cmd);
+
+	if (pmk_info->pmk_len)
+		len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
+		 WMITLV_GET_STRUCT_TLVLEN(
+			wmi_pdev_update_pmk_cache_cmd_fixed_param));
+
+	cmd->vdev_id = pmk_info->session_id;
+
+	/* If pmk_info->pmk_len is 0, this is a flush request */
+	if (!pmk_info->pmk_len) {
+		cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
+		cmd->num_cache = 0;
+		goto send_cmd;
+	}
+
+	cmd->num_cache = 1;
+	buf_ptr += sizeof(*cmd);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			sizeof(*pmksa));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	pmksa = (wmi_pmk_cache *)buf_ptr;
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
+			WMITLV_GET_STRUCT_TLVLEN
+				(wmi_pmk_cache));
+	pmksa->pmk_len = pmk_info->pmk_len;
+	qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
+	pmksa->pmkid_len = pmk_info->pmkid_len;
+	qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
+	qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
+	pmksa->ssid.ssid_len = pmk_info->ssid.length;
+	qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid),
+		     pmksa->ssid.ssid_len);
+	pmksa->cache_id = pmk_info->cache_id;
+	pmksa->cat_flag = pmk_info->cat_flag;
+	pmksa->action_flag = pmk_info->action_flag;
+
+send_cmd:
+	wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMI_LOGE("%s: failed to send set del pmkid cache command %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_del_ts_cmd_tlv() - send DELTS request to fw
+ * @wmi_handle: wmi handle
+ * @msg: delts params
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
+				uint8_t ac)
+{
+	wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_vdev_wmm_delts_cmd_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->ac = ac;
+
+	WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
+		 cmd->vdev_id, cmd->ac, __func__, __LINE__);
+	wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_VDEV_WMM_DELTS_CMDID)) {
+		WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
+ * @wmi_handle: handle to wmi
+ * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
+ *
+ * A function to handle WMI_AGGR_QOS_REQ. This will send out
+ * ADD_TS requestes to firmware in loop for all the ACs with
+ * active flow.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
+		      struct aggr_add_ts_param *aggr_qos_rsp_msg)
+{
+	int i = 0;
+	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
+		/* if flow in this AC is active */
+		if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
+			/*
+			 * as per implementation of wma_add_ts_req() we
+			 * are not waiting any response from firmware so
+			 * apart from sending ADDTS to firmware just send
+			 * success to upper layers
+			 */
+			aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
+
+			buf = wmi_buf_alloc(wmi_handle, len);
+			if (!buf) {
+				return QDF_STATUS_E_NOMEM;
+			}
+			cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
+				wmi_buf_data(buf);
+			WMITLV_SET_HDR(&cmd->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
+			       WMITLV_GET_STRUCT_TLVLEN
+				       (wmi_vdev_wmm_addts_cmd_fixed_param));
+			cmd->vdev_id = aggr_qos_rsp_msg->vdev_id;
+			cmd->ac =
+				WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
+					      traffic.userPrio);
+			cmd->medium_time_us =
+				aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
+			cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
+			WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
+				 __func__, __LINE__, cmd->vdev_id, cmd->ac,
+				 cmd->medium_time_us, cmd->downgrade_type);
+			wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
+			if (wmi_unified_cmd_send(wmi_handle, buf, len,
+						 WMI_VDEV_WMM_ADDTS_CMDID)) {
+				WMI_LOGP("%s: Failed to send vdev ADDTS command",
+					 __func__);
+				aggr_qos_rsp_msg->status[i] =
+							QDF_STATUS_E_FAILURE;
+				wmi_buf_free(buf);
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_add_ts_cmd_tlv() - send ADDTS request to fw
+ * @wmi_handle: wmi handle
+ * @msg: ADDTS params
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
+		 struct add_ts_param *msg)
+{
+	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	msg->status = QDF_STATUS_SUCCESS;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_vdev_wmm_addts_cmd_fixed_param));
+	cmd->vdev_id = msg->sme_session_id;
+	cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
+	cmd->medium_time_us = msg->tspec.mediumTime * 32;
+	cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
+	WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
+		 cmd->vdev_id, cmd->ac, cmd->medium_time_us,
+		 cmd->downgrade_type, __func__, __LINE__);
+	wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_VDEV_WMM_ADDTS_CMDID)) {
+		WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
+		msg->status = QDF_STATUS_E_FAILURE;
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn
+ * @wmi_handle: wmi handle
+ * @pAddPeriodicTxPtrnParams: tx ptrn params
+ *
+ * Retrun: CDF status
+ */
+static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
+						struct periodic_tx_pattern  *
+						pAddPeriodicTxPtrnParams,
+						uint8_t vdev_id)
+{
+	WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t len;
+	uint8_t *buf_ptr;
+	uint32_t ptrn_len, ptrn_len_aligned;
+	int j;
+
+	ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize;
+	ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
+	len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
+	      WMI_TLV_HDR_SIZE + ptrn_len_aligned;
+
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
+
+	cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	       WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
+	       WMITLV_GET_STRUCT_TLVLEN
+	       (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
+
+	/* Pass the pattern id to delete for the corresponding vdev id */
+	cmd->vdev_id = vdev_id;
+	cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId;
+	cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
+	cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize;
+
+	/* Pattern info */
+	buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
+	for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++)
+		WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
+
+	WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
+		 __func__, cmd->pattern_id, cmd->vdev_id);
+
+	wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
+		WMI_LOGE("%s: failed to add pattern set state command",
+			 __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ *
+ * Retrun: CDF status
+ */
+static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
+						uint8_t vdev_id,
+						uint8_t pattern_id)
+{
+	WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t len =
+		sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
+
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
+		wmi_buf_data(wmi_buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	       WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
+	       WMITLV_GET_STRUCT_TLVLEN
+	       (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
+
+	/* Pass the pattern id to delete for the corresponding vdev id */
+	cmd->vdev_id = vdev_id;
+	cmd->pattern_id = pattern_id;
+	WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
+		 __func__, cmd->pattern_id, cmd->vdev_id);
+
+	wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
+		WMI_LOGE("%s: failed to send del pattern command", __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
+ * @wmi_handle: wmi handle
+ * @timer_val: auto shutdown timer value
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
+						  uint32_t timer_val)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	uint8_t *buf_ptr;
+	wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
+	int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
+
+	WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
+		 __func__, timer_val);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	wmi_auto_sh_cmd =
+		(wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
+	wmi_auto_sh_cmd->timer_value = timer_val;
+
+	WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
+	       WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
+	       WMITLV_GET_STRUCT_TLVLEN
+	       (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
+
+	wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_set_led_flashing_cmd_tlv() - set led flashing in fw
+ * @wmi_handle: wmi handle
+ * @flashing: flashing request
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
+				struct flashing_req_params *flashing)
+{
+	wmi_set_led_flashing_cmd_fixed_param *cmd;
+	QDF_STATUS status;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_set_led_flashing_cmd_fixed_param));
+	cmd->pattern_id = flashing->pattern_id;
+	cmd->led_x0 = flashing->led_x0;
+	cmd->led_x1 = flashing->led_x1;
+
+	wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_PDEV_SET_LED_FLASHING_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
+			 " returned Error %d", __func__, status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
+ * @wmi_handle: wmi handle
+ * @ch_avoid_update_req: channel avoid update params
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	uint8_t *buf_ptr;
+	wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
+	int len = sizeof(wmi_chan_avoid_update_cmd_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
+	WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_chan_avoid_update_cmd_param));
+
+	wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_CHAN_AVOID_UPDATE_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("wmi_unified_cmd_send"
+			 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
+			 " returned Error %d", status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
+ * @wmi_handle: wmi handle
+ * @msg: PCL structure containing the PCL and the number of channels
+ *
+ * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
+ * firmware. The DBS Manager is the consumer of this information in the WLAN
+ * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
+ * to migrate to a new channel without host driver involvement. An example of
+ * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
+ * manage the channel selection without firmware involvement.
+ *
+ * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
+ * channel list. The weights corresponds to the channels sent in
+ * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
+ * weightage compared to the non PCL channels.
+ *
+ * Return: Success if the cmd is sent successfully to the firmware
+ */
+static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
+				struct wmi_pcl_chan_weights *msg)
+{
+	wmi_pdev_set_pcl_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint32_t *cmd_args, i, len;
+	uint32_t chan_len;
+
+	chan_len = msg->saved_num_chan;
+
+	len = sizeof(*cmd) +
+		WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
+	buf_ptr = (uint8_t *) cmd;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
+
+	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
+							WMI_HOST_PDEV_ID_SOC);
+	cmd->num_chan = chan_len;
+	WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan);
+
+	buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+			(chan_len * sizeof(uint32_t)));
+	cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < chan_len ; i++) {
+		cmd_args[i] = msg->weighed_valid_list[i];
+		WMI_LOGD("%s: chan:%d weight:%d", __func__,
+			 msg->saved_chan_list[i], cmd_args[i]);
+	}
+	wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_PDEV_SET_PCL_CMDID)) {
+		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
+ * @wmi_handle: wmi handle
+ * @msg: Structure containing the following parameters
+ *
+ * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
+ * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
+ *
+ * Provides notification to the WLAN firmware that host driver is requesting a
+ * HardWare (HW) Mode change. This command is needed to support iHelium in the
+ * configurations that include the Dual Band Simultaneous (DBS) feature.
+ *
+ * Return: Success if the cmd is sent successfully to the firmware
+ */
+static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle,
+						uint32_t hw_mode_index)
+{
+	wmi_pdev_set_hw_mode_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+
+	len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param));
+
+	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
+							WMI_HOST_PDEV_ID_SOC);
+	cmd->hw_mode_index = hw_mode_index;
+	WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
+
+	wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_PDEV_SET_HW_MODE_CMDID)) {
+		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID",
+			 __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_POLICY_MGR_ENABLE
+/**
+ * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
+ * @wmi_handle: wmi handle
+ * @msg: Dual MAC config parameters
+ *
+ * Configures WLAN firmware with the dual MAC features
+ *
+ * Return: QDF_STATUS. 0 on success.
+ */
+static
+QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
+		struct policy_mgr_dual_mac_config *msg)
+{
+	wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+
+	len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_pdev_set_mac_config_cmd_fixed_param));
+
+	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
+							WMI_HOST_PDEV_ID_SOC);
+	cmd->concurrent_scan_config_bits = msg->scan_config;
+	cmd->fw_mode_config_bits = msg->fw_mode_config;
+	WMI_LOGD("%s: scan_config:%x fw_mode_config:%x",
+		 __func__, msg->scan_config, msg->fw_mode_config);
+
+	wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
+		WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
+			 __func__);
+		wmi_buf_free(buf);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_policy_mgr_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_pdev_set_dual_mac_config_cmd =
+		send_pdev_set_dual_mac_config_cmd_tlv;
+}
+#endif /* WLAN_POLICY_MGR_ENABLE */
+
+/**
+ * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
+ * configuration params
+ * @wma_handle:  wma handler
+ * @dwelltime_params: pointer to dwelltime_params
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
+ */
+static
+QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
+		struct wmi_adaptive_dwelltime_params *dwelltime_params)
+{
+	wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
+	wmi_scan_adaptive_dwell_parameters_tlv *cmd;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int32_t err;
+	int len;
+
+	len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
+	len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&dwell_param->tlv_header,
+		WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+		(wmi_scan_adaptive_dwell_config_fixed_param));
+
+	dwell_param->enable = dwelltime_params->is_enabled;
+	buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
+		       WMITLV_GET_STRUCT_TLVLEN(
+		       wmi_scan_adaptive_dwell_parameters_tlv));
+
+	cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
+	cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
+	cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
+	cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
+	wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf,
+				   len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
+	if (err) {
+		WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
+ * configuration params
+ * @wmi_handle: wmi handler
+ * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
+ */
+static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
+			struct wmi_dbs_scan_sel_params *dbs_scan_params)
+{
+	wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
+	wmi_scan_dbs_duty_cycle_tlv_param *cmd;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	QDF_STATUS err;
+	uint32_t i;
+	int len;
+
+	len = sizeof(*dbs_scan_param);
+	len += WMI_TLV_HDR_SIZE;
+	len += dbs_scan_params->num_clients * sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_scan_dbs_duty_cycle_fixed_param));
+
+	dbs_scan_param->num_clients = dbs_scan_params->num_clients;
+	dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
+	buf_ptr += sizeof(*dbs_scan_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       (sizeof(*cmd) * dbs_scan_params->num_clients));
+	buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
+
+	for (i = 0; i < dbs_scan_params->num_clients; i++) {
+		cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
+		WMITLV_SET_HDR(&cmd->tlv_header,
+			WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
+			WMITLV_GET_STRUCT_TLVLEN(
+					wmi_scan_dbs_duty_cycle_tlv_param));
+		cmd->module_id = dbs_scan_params->module_id[i];
+		cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
+		cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
+		buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
+	}
+
+	wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf,
+				   len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
+	if (QDF_IS_STATUS_ERROR(err)) {
+		WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
+ * @wmi_handle: wmi handler
+ * @req_buf: set arp stats request buffer
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
+					  struct set_arp_stats *req_buf)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
+
+	len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
+	if (req_buf->pkt_type_bitmap) {
+		len += WMI_TLV_HDR_SIZE;
+		len += sizeof(wmi_vdev_set_connectivity_check_stats);
+	}
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	wmi_set_arp =
+		(wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_vdev_set_arp_stats_cmd_fixed_param));
+
+	/* fill in per roam config values */
+	wmi_set_arp->vdev_id = req_buf->vdev_id;
+
+	wmi_set_arp->set_clr = req_buf->flag;
+	wmi_set_arp->pkt_type = req_buf->pkt_type;
+	wmi_set_arp->ipv4 = req_buf->ip_addr;
+
+	WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
+		 wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
+		 wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
+
+	/*
+	 * pkt_type_bitmap should be non-zero to ensure
+	 * presence of additional stats.
+	 */
+	if (req_buf->pkt_type_bitmap) {
+		wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
+
+		buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
+		WMITLV_SET_HDR(buf_ptr,
+			       WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(wmi_vdev_set_connectivity_check_stats));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		wmi_set_connect_stats =
+			(wmi_vdev_set_connectivity_check_stats *)buf_ptr;
+		WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
+			WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
+			WMITLV_GET_STRUCT_TLVLEN(
+					wmi_vdev_set_connectivity_check_stats));
+		wmi_set_connect_stats->pkt_type_bitmap =
+						req_buf->pkt_type_bitmap;
+		wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
+		wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
+		wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
+
+		WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
+			 wmi_set_connect_stats->pkt_type_bitmap,
+			 wmi_set_connect_stats->tcp_src_port,
+			 wmi_set_connect_stats->tcp_dst_port,
+			 wmi_set_connect_stats->icmp_ipv4);
+	}
+
+	/* Send per roam config parameters */
+	wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_VDEV_SET_ARP_STAT_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
+			 status);
+		goto error;
+	}
+
+	WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"),
+		 req_buf->flag, req_buf->vdev_id);
+	return QDF_STATUS_SUCCESS;
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
+ * @wmi_handle: wmi handler
+ * @req_buf: get arp stats request buffer
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
+					  struct get_arp_stats *req_buf)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
+
+	len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	get_arp_stats =
+		(wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&get_arp_stats->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_vdev_get_arp_stats_cmd_fixed_param));
+
+	/* fill in arp stats req cmd values */
+	get_arp_stats->vdev_id = req_buf->vdev_id;
+
+	WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
+	/* Send per roam config parameters */
+	wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_VDEV_GET_ARP_STAT_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
+			 status);
+		goto error;
+	}
+
+	return QDF_STATUS_SUCCESS;
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+void wmi_sta_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_sta_sa_query_param_cmd =
+		send_set_sta_sa_query_param_cmd_tlv;
+	ops->send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv;
+	ops->send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv;
+	ops->send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv;
+	ops->send_get_link_speed_cmd = send_get_link_speed_cmd_tlv;
+	ops->send_fw_profiling_cmd = send_fw_profiling_cmd_tlv;
+	ops->send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv;
+	ops->send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv;
+	ops->send_nan_req_cmd = send_nan_req_cmd_tlv;
+	ops->send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv;
+	ops->send_set_base_macaddr_indicate_cmd =
+		 send_set_base_macaddr_indicate_cmd_tlv;
+	ops->send_sar_limit_cmd = send_sar_limit_cmd_tlv;
+	ops->get_sar_limit_cmd = get_sar_limit_cmd_tlv;
+	ops->extract_sar_limit_event = extract_sar_limit_event_tlv;
+	ops->extract_sar2_result_event = extract_sar2_result_event_tlv;
+	ops->send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv;
+	ops->send_del_ts_cmd = send_del_ts_cmd_tlv;
+	ops->send_aggr_qos_cmd = send_aggr_qos_cmd_tlv;
+	ops->send_add_ts_cmd = send_add_ts_cmd_tlv;
+	ops->send_process_add_periodic_tx_ptrn_cmd =
+		send_process_add_periodic_tx_ptrn_cmd_tlv;
+	ops->send_process_del_periodic_tx_ptrn_cmd =
+		send_process_del_periodic_tx_ptrn_cmd_tlv;
+	ops->send_set_auto_shutdown_timer_cmd =
+		send_set_auto_shutdown_timer_cmd_tlv;
+	ops->send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv;
+	ops->send_process_ch_avoid_update_cmd =
+		send_process_ch_avoid_update_cmd_tlv;
+	ops->send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv;
+	ops->send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv;
+	ops->send_adapt_dwelltime_params_cmd =
+		send_adapt_dwelltime_params_cmd_tlv;
+	ops->send_dbs_scan_sel_params_cmd =
+		send_dbs_scan_sel_params_cmd_tlv;
+	ops->send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv;
+	ops->send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv;
+
+	wmi_tdls_attach_tlv(wmi_handle);
+	wmi_disa_attach_tlv(wmi_handle);
+	wmi_policy_mgr_attach_tlv(wmi_handle);
+}
+

File diff suppressed because it is too large
+ 997 - 7956
wmi_unified_tlv.c


Some files were not shown because too many files changed in this diff