qcacld-3.0: Initial snapshot of ihelium wlan driver

qcacld-3.0: Initial snapshot of ihelium wlan driver
to match code-scanned SU Release 5.0.0.139. This is
open-source version of wlan for next Android release.

Change-Id: Icf598ca97da74f84bea607e4e902d1889806f507
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
new file mode 100644
index 0000000..065f2e3
--- /dev/null
+++ b/core/wma/src/wma_features.c
@@ -0,0 +1,7171 @@
+/*
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**
+ *  DOC:    wma_features.c
+ *  This file contains different features related functions like WoW,
+ *  Offloads, TDLS etc.
+ */
+
+/* Header files */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "ol_txrx_ctrl_api.h"
+#include "wlan_tgt_def_config.h"
+
+#include "cdf_nbuf.h"
+#include "cdf_types.h"
+#include "ol_txrx_api.h"
+#include "cdf_memory.h"
+#include "ol_txrx_types.h"
+#include "ol_txrx_peer_find.h"
+
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+#include "ol_fw.h"
+
+#include "dfs.h"
+#include "radar_filters.h"
+#include "wma_internal.h"
+
+#ifndef ARRAY_LENGTH
+#define ARRAY_LENGTH(a)         (sizeof(a) / sizeof((a)[0]))
+#endif
+
+#define WMA_WOW_STA_WAKE_UP_EVENTS ((1 << WOW_CSA_IE_EVENT) |\
+				(1 << WOW_CLIENT_KICKOUT_EVENT) |\
+				(1 << WOW_PATTERN_MATCH_EVENT) |\
+				(1 << WOW_MAGIC_PKT_RECVD_EVENT) |\
+				(1 << WOW_DEAUTH_RECVD_EVENT) |\
+				(1 << WOW_DISASSOC_RECVD_EVENT) |\
+				(1 << WOW_BMISS_EVENT) |\
+				(1 << WOW_GTK_ERR_EVENT) |\
+				(1 << WOW_BETTER_AP_EVENT) |\
+				(1 << WOW_HTT_EVENT) |\
+				(1 << WOW_RA_MATCH_EVENT) |\
+				(1 << WOW_NLO_DETECTED_EVENT) |\
+				(1 << WOW_EXTSCAN_EVENT))\
+
+#define WMA_WOW_SAP_WAKE_UP_EVENTS ((1 << WOW_PROBE_REQ_WPS_IE_EVENT) |\
+				(1 << WOW_PATTERN_MATCH_EVENT) |\
+				(1 << WOW_AUTH_REQ_EVENT) |\
+				(1 << WOW_ASSOC_REQ_EVENT) |\
+				(1 << WOW_DEAUTH_RECVD_EVENT) |\
+				(1 << WOW_DISASSOC_RECVD_EVENT) |\
+				(1 << WOW_HTT_EVENT))\
+
+static const uint8_t arp_ptrn[] = {0x08, 0x06};
+static const uint8_t arp_mask[] = {0xff, 0xff};
+static const uint8_t ns_ptrn[] = {0x86, 0xDD};
+static const uint8_t discvr_ptrn[] = {0xe0, 0x00, 0x00, 0xf8};
+static const uint8_t discvr_mask[] = {0xf0, 0x00, 0x00, 0xf8};
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+/**
+ * wma_post_auto_shutdown_msg() - to post auto shutdown event to sme
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_post_auto_shutdown_msg(void)
+{
+	tSirAutoShutdownEvtParams *auto_sh_evt;
+	CDF_STATUS cdf_status;
+	cds_msg_t sme_msg = { 0 };
+
+	auto_sh_evt = (tSirAutoShutdownEvtParams *)
+		      cdf_mem_malloc(sizeof(tSirAutoShutdownEvtParams));
+	if (!auto_sh_evt) {
+		WMA_LOGE(FL("No Mem"));
+		return -ENOMEM;
+	}
+
+	auto_sh_evt->shutdown_reason =
+		WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY;
+	sme_msg.type = eWNI_SME_AUTO_SHUTDOWN_IND;
+	sme_msg.bodyptr = auto_sh_evt;
+	sme_msg.bodyval = 0;
+
+	cdf_status = cds_mq_post_message(CDF_MODULE_ID_SME, &sme_msg);
+	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+		WMA_LOGE("Fail to post eWNI_SME_AUTO_SHUTDOWN_IND msg to SME");
+		cdf_mem_free(auto_sh_evt);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+/**
+ * wma_send_snr_request() - send request to fw to get RSSI stats
+ * @wma_handle: wma handle
+ * @pGetRssiReq: get RSSI request
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_send_snr_request(tp_wma_handle wma_handle,
+				void *pGetRssiReq)
+{
+	wmi_buf_t buf;
+	wmi_request_stats_cmd_fixed_param *cmd;
+	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
+	tAniGetRssiReq *pRssiBkUp = NULL;
+
+	/* command is in progess */
+	if (NULL != wma_handle->pGetRssiReq)
+		return CDF_STATUS_SUCCESS;
+
+	/* create a copy of csrRssiCallback to send rssi value
+	 * after wmi event
+	 */
+	if (pGetRssiReq) {
+		pRssiBkUp = cdf_mem_malloc(sizeof(tAniGetRssiReq));
+		if (!pRssiBkUp) {
+			WMA_LOGE("Failed to allocate memory for tAniGetRssiReq");
+			wma_handle->pGetRssiReq = NULL;
+			return CDF_STATUS_E_NOMEM;
+		}
+		cdf_mem_set(pRssiBkUp, sizeof(tAniGetRssiReq), 0);
+		pRssiBkUp->sessionId =
+			((tAniGetRssiReq *) pGetRssiReq)->sessionId;
+		pRssiBkUp->rssiCallback =
+			((tAniGetRssiReq *) pGetRssiReq)->rssiCallback;
+		pRssiBkUp->pDevContext =
+			((tAniGetRssiReq *) pGetRssiReq)->pDevContext;
+		wma_handle->pGetRssiReq = (void *)pRssiBkUp;
+	}
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+		cdf_mem_free(pRssiBkUp);
+		wma_handle->pGetRssiReq = NULL;
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_request_stats_cmd_fixed_param));
+	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
+	if (wmi_unified_cmd_send
+		    (wma_handle->wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) {
+		WMA_LOGE("Failed to send host stats request to fw");
+		wmi_buf_free(buf);
+		cdf_mem_free(pRssiBkUp);
+		wma_handle->pGetRssiReq = NULL;
+		return CDF_STATUS_E_FAILURE;
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_snr() - get RSSI from fw
+ * @psnr_req: request params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req)
+{
+	wmi_buf_t buf;
+	wmi_request_stats_cmd_fixed_param *cmd;
+	tAniGetSnrReq *psnr_req_bkp;
+	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
+	tp_wma_handle wma_handle = NULL;
+	struct wma_txrx_node *intr;
+
+	wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s : Failed to get wma_handle", __func__);
+		return CDF_STATUS_E_FAULT;
+	}
+
+	intr = &wma_handle->interfaces[psnr_req->sessionId];
+	/* command is in progess */
+	if (NULL != intr->psnr_req) {
+		WMA_LOGE("%s : previous snr request is pending", __func__);
+		return CDF_STATUS_SUCCESS;
+	}
+
+	psnr_req_bkp = cdf_mem_malloc(sizeof(tAniGetSnrReq));
+	if (!psnr_req_bkp) {
+		WMA_LOGE("Failed to allocate memory for tAniGetSnrReq");
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_set(psnr_req_bkp, sizeof(tAniGetSnrReq), 0);
+	psnr_req_bkp->staId = psnr_req->staId;
+	psnr_req_bkp->pDevContext = psnr_req->pDevContext;
+	psnr_req_bkp->snrCallback = psnr_req->snrCallback;
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+		cdf_mem_free(psnr_req_bkp);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
+	cmd->vdev_id = psnr_req->sessionId;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_request_stats_cmd_fixed_param));
+	cmd->stats_id = WMI_REQUEST_VDEV_STAT;
+	intr->psnr_req = (void *)psnr_req_bkp;
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+				 WMI_REQUEST_STATS_CMDID)) {
+		WMA_LOGE("Failed to send host stats request to fw");
+		wmi_buf_free(buf);
+		cdf_mem_free(psnr_req_bkp);
+		intr->psnr_req = NULL;
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_link_status_req() - process link status request from UMAC
+ * @wma: wma handle
+ * @pGetLinkStatus: get link params
+ *
+ * Return: none
+ */
+void wma_process_link_status_req(tp_wma_handle wma,
+				 tAniGetLinkStatus *pGetLinkStatus)
+{
+	wmi_buf_t buf;
+	wmi_request_stats_cmd_fixed_param *cmd;
+	uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
+	struct wma_txrx_node *iface =
+		&wma->interfaces[pGetLinkStatus->sessionId];
+
+	if (iface->plink_status_req) {
+		WMA_LOGE("%s:previous link status request is pending,deleting the new request",
+			__func__);
+		cdf_mem_free(pGetLinkStatus);
+		return;
+	}
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+		goto end;
+	}
+
+	iface->plink_status_req = pGetLinkStatus;
+	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_request_stats_cmd_fixed_param));
+	cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT;
+	cmd->vdev_id = pGetLinkStatus->sessionId;
+	if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				 WMI_REQUEST_STATS_CMDID)) {
+		WMA_LOGE("Failed to send WMI link  status request to fw");
+		wmi_buf_free(buf);
+		iface->plink_status_req = NULL;
+		goto end;
+	}
+
+	return;
+
+end:
+	wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY);
+}
+
+#ifdef FEATURE_WLAN_LPHB
+/**
+ * wma_lphb_conf_hbenable() - enable command of LPHB configuration requests
+ * @wma_handle: WMA handle
+ * @lphb_conf_req: configuration info
+ * @by_user: whether this call is from user or cached resent
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_lphb_conf_hbenable(tp_wma_handle wma_handle,
+				  tSirLPHBReq *lphb_conf_req, bool by_user)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	int status = 0;
+	tSirLPHBEnableStruct *ts_lphb_enable;
+	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);
+	int i;
+
+	if (lphb_conf_req == NULL) {
+		WMA_LOGE("%s : LPHB configuration is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	ts_lphb_enable = &(lphb_conf_req->params.lphbEnableReq);
+	WMA_LOGI("%s: WMA --> WMI_HB_SET_ENABLE enable=%d, item=%d, session=%d",
+		 __func__,
+		 ts_lphb_enable->enable,
+		 ts_lphb_enable->item, ts_lphb_enable->session);
+
+	if ((ts_lphb_enable->item != 1) && (ts_lphb_enable->item != 2)) {
+		WMA_LOGE("%s : LPHB configuration wrong item %d",
+			 __func__, ts_lphb_enable->item);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+		return CDF_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 = ts_lphb_enable->session;
+	hb_enable_fp->enable = ts_lphb_enable->enable;
+	hb_enable_fp->item = ts_lphb_enable->item;
+	hb_enable_fp->session = ts_lphb_enable->session;
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				      len, WMI_HB_SET_ENABLE_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_ENABLE returned Error %d",
+			status);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	if (by_user) {
+		/* target already configured, now cache command status */
+		if (ts_lphb_enable->enable) {
+			i = ts_lphb_enable->item - 1;
+			wma_handle->wow.lphb_cache[i].cmd
+				= LPHB_SET_EN_PARAMS_INDID;
+			wma_handle->wow.lphb_cache[i].params.lphbEnableReq.
+			enable = ts_lphb_enable->enable;
+			wma_handle->wow.lphb_cache[i].params.lphbEnableReq.
+			item = ts_lphb_enable->item;
+			wma_handle->wow.lphb_cache[i].params.lphbEnableReq.
+			session = ts_lphb_enable->session;
+
+			WMA_LOGI("%s: cached LPHB status in WMA context for item %d",
+				__func__, i);
+		} else {
+			cdf_mem_zero((void *)&wma_handle->wow.lphb_cache,
+				     sizeof(wma_handle->wow.lphb_cache));
+			WMA_LOGI("%s: cleared all cached LPHB status in WMA context",
+				__func__);
+		}
+	}
+
+	return CDF_STATUS_SUCCESS;
+error:
+	return cdf_status;
+}
+
+/**
+ * wma_lphb_conf_tcp_params() - set tcp params of LPHB configuration requests
+ * @wma_handle: wma handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_lphb_conf_tcp_params(tp_wma_handle wma_handle,
+				    tSirLPHBReq *lphb_conf_req)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	int status = 0;
+	tSirLPHBTcpParamStruct *ts_lphb_tcp_param;
+	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);
+
+	if (lphb_conf_req == NULL) {
+		WMA_LOGE("%s : LPHB configuration is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	ts_lphb_tcp_param = &(lphb_conf_req->params.lphbTcpParamReq);
+	WMA_LOGI("%s: WMA --> WMI_HB_SET_TCP_PARAMS srv_ip=%08x, dev_ip=%08x, src_port=%d, "
+		"dst_port=%d, timeout=%d, session=%d, gateway_mac=%02x:%02x:%02x:%02x:%02x:%02x, "
+		"timePeriodSec=%d, tcpSn=%d", __func__, ts_lphb_tcp_param->srv_ip,
+		ts_lphb_tcp_param->dev_ip, ts_lphb_tcp_param->src_port,
+		ts_lphb_tcp_param->dst_port, ts_lphb_tcp_param->timeout,
+		ts_lphb_tcp_param->session, ts_lphb_tcp_param->gateway_mac[0],
+		ts_lphb_tcp_param->gateway_mac[1],
+		ts_lphb_tcp_param->gateway_mac[2],
+		ts_lphb_tcp_param->gateway_mac[3],
+		ts_lphb_tcp_param->gateway_mac[4],
+		ts_lphb_tcp_param->gateway_mac[5],
+		ts_lphb_tcp_param->timePeriodSec, ts_lphb_tcp_param->tcpSn);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+		return CDF_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 = ts_lphb_tcp_param->session;
+	hb_tcp_params_fp->srv_ip = ts_lphb_tcp_param->srv_ip;
+	hb_tcp_params_fp->dev_ip = ts_lphb_tcp_param->dev_ip;
+	hb_tcp_params_fp->seq = ts_lphb_tcp_param->tcpSn;
+	hb_tcp_params_fp->src_port = ts_lphb_tcp_param->src_port;
+	hb_tcp_params_fp->dst_port = ts_lphb_tcp_param->dst_port;
+	hb_tcp_params_fp->interval = ts_lphb_tcp_param->timePeriodSec;
+	hb_tcp_params_fp->timeout = ts_lphb_tcp_param->timeout;
+	hb_tcp_params_fp->session = ts_lphb_tcp_param->session;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_tcp_param->gateway_mac,
+				   &hb_tcp_params_fp->gateway_mac);
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				      len, WMI_HB_SET_TCP_PARAMS_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d",
+			status);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return CDF_STATUS_SUCCESS;
+error:
+	return cdf_status;
+}
+
+/**
+ * wma_lphb_conf_tcp_pkt_filter() - configure tcp packet filter command of LPHB
+ * @wma_handle: wma handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_lphb_conf_tcp_pkt_filter(tp_wma_handle wma_handle,
+					tSirLPHBReq *lphb_conf_req)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	int status = 0;
+	tSirLPHBTcpFilterStruct *ts_lphb_tcp_filter;
+	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);
+
+	if (lphb_conf_req == NULL) {
+		WMA_LOGE("%s : LPHB configuration is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	ts_lphb_tcp_filter = &(lphb_conf_req->params.lphbTcpFilterReq);
+	WMA_LOGI("%s: WMA --> WMI_HB_SET_TCP_PKT_FILTER length=%d, offset=%d, session=%d, "
+		"filter=%2x:%2x:%2x:%2x:%2x:%2x ...", __func__,
+		ts_lphb_tcp_filter->length, ts_lphb_tcp_filter->offset,
+		ts_lphb_tcp_filter->session, ts_lphb_tcp_filter->filter[0],
+		ts_lphb_tcp_filter->filter[1], ts_lphb_tcp_filter->filter[2],
+		ts_lphb_tcp_filter->filter[3], ts_lphb_tcp_filter->filter[4],
+		ts_lphb_tcp_filter->filter[5]);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+		return CDF_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 = ts_lphb_tcp_filter->session;
+	hb_tcp_filter_fp->length = ts_lphb_tcp_filter->length;
+	hb_tcp_filter_fp->offset = ts_lphb_tcp_filter->offset;
+	hb_tcp_filter_fp->session = ts_lphb_tcp_filter->session;
+	memcpy((void *)&hb_tcp_filter_fp->filter,
+	       (void *)&ts_lphb_tcp_filter->filter,
+	       WMI_WLAN_HB_MAX_FILTER_SIZE);
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				      len, WMI_HB_SET_TCP_PKT_FILTER_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d",
+			status);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return CDF_STATUS_SUCCESS;
+error:
+	return cdf_status;
+}
+
+/**
+ * wma_lphb_conf_udp_params() - configure udp param command of LPHB
+ * @wma_handle: wma handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_lphb_conf_udp_params(tp_wma_handle wma_handle,
+				    tSirLPHBReq *lphb_conf_req)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	int status = 0;
+	tSirLPHBUdpParamStruct *ts_lphb_udp_param;
+	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);
+
+	if (lphb_conf_req == NULL) {
+		WMA_LOGE("%s : LPHB configuration is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	ts_lphb_udp_param = &(lphb_conf_req->params.lphbUdpParamReq);
+	WMA_LOGI("%s: WMA --> WMI_HB_SET_UDP_PARAMS srv_ip=%d, dev_ip=%d, src_port=%d, "
+		"dst_port=%d, interval=%d, timeout=%d, session=%d, "
+		"gateway_mac=%2x:%2x:%2x:%2x:%2x:%2x", __func__,
+		ts_lphb_udp_param->srv_ip, ts_lphb_udp_param->dev_ip,
+		ts_lphb_udp_param->src_port, ts_lphb_udp_param->dst_port,
+		ts_lphb_udp_param->interval, ts_lphb_udp_param->timeout,
+		ts_lphb_udp_param->session, ts_lphb_udp_param->gateway_mac[0],
+		ts_lphb_udp_param->gateway_mac[1],
+		ts_lphb_udp_param->gateway_mac[2],
+		ts_lphb_udp_param->gateway_mac[3],
+		ts_lphb_udp_param->gateway_mac[4],
+		ts_lphb_udp_param->gateway_mac[5]);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+		return CDF_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 = ts_lphb_udp_param->session;
+	hb_udp_params_fp->srv_ip = ts_lphb_udp_param->srv_ip;
+	hb_udp_params_fp->dev_ip = ts_lphb_udp_param->dev_ip;
+	hb_udp_params_fp->src_port = ts_lphb_udp_param->src_port;
+	hb_udp_params_fp->dst_port = ts_lphb_udp_param->dst_port;
+	hb_udp_params_fp->interval = ts_lphb_udp_param->interval;
+	hb_udp_params_fp->timeout = ts_lphb_udp_param->timeout;
+	hb_udp_params_fp->session = ts_lphb_udp_param->session;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_udp_param->gateway_mac,
+				   &hb_udp_params_fp->gateway_mac);
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				      len, WMI_HB_SET_UDP_PARAMS_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d",
+			status);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return CDF_STATUS_SUCCESS;
+error:
+	return cdf_status;
+}
+
+/**
+ * wma_lphb_conf_udp_pkt_filter() - configure udp pkt filter command of LPHB
+ * @wma_handle: wma handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_lphb_conf_udp_pkt_filter(tp_wma_handle wma_handle,
+					tSirLPHBReq *lphb_conf_req)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	int status = 0;
+	tSirLPHBUdpFilterStruct *ts_lphb_udp_filter;
+	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);
+
+	if (lphb_conf_req == NULL) {
+		WMA_LOGE("%s : LPHB configuration is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	ts_lphb_udp_filter = &(lphb_conf_req->params.lphbUdpFilterReq);
+	WMA_LOGI("%s: WMA --> WMI_HB_SET_UDP_PKT_FILTER length=%d, offset=%d, session=%d, "
+		"filter=%2x:%2x:%2x:%2x:%2x:%2x ...", __func__,
+		ts_lphb_udp_filter->length, ts_lphb_udp_filter->offset,
+		ts_lphb_udp_filter->session, ts_lphb_udp_filter->filter[0],
+		ts_lphb_udp_filter->filter[1], ts_lphb_udp_filter->filter[2],
+		ts_lphb_udp_filter->filter[3], ts_lphb_udp_filter->filter[4],
+		ts_lphb_udp_filter->filter[5]);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+		return CDF_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 = ts_lphb_udp_filter->session;
+	hb_udp_filter_fp->length = ts_lphb_udp_filter->length;
+	hb_udp_filter_fp->offset = ts_lphb_udp_filter->offset;
+	hb_udp_filter_fp->session = ts_lphb_udp_filter->session;
+	memcpy((void *)&hb_udp_filter_fp->filter,
+	       (void *)&ts_lphb_udp_filter->filter,
+	       WMI_WLAN_HB_MAX_FILTER_SIZE);
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				      len, WMI_HB_SET_UDP_PKT_FILTER_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d",
+			status);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return CDF_STATUS_SUCCESS;
+error:
+	return cdf_status;
+}
+
+/**
+ * wma_process_lphb_conf_req() - handle LPHB configuration requests
+ * @wma_handle: wma handle
+ * @lphb_conf_req: lphb config request
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_process_lphb_conf_req(tp_wma_handle wma_handle,
+				     tSirLPHBReq *lphb_conf_req)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+
+	if (lphb_conf_req == NULL) {
+		WMA_LOGE("%s : LPHB configuration is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGI("%s : LPHB configuration cmd id is %d", __func__,
+		 lphb_conf_req->cmd);
+	switch (lphb_conf_req->cmd) {
+	case LPHB_SET_EN_PARAMS_INDID:
+		cdf_status = wma_lphb_conf_hbenable(wma_handle,
+						    lphb_conf_req, true);
+		break;
+
+	case LPHB_SET_TCP_PARAMS_INDID:
+		cdf_status = wma_lphb_conf_tcp_params(wma_handle,
+						      lphb_conf_req);
+		break;
+
+	case LPHB_SET_TCP_PKT_FILTER_INDID:
+		cdf_status = wma_lphb_conf_tcp_pkt_filter(wma_handle,
+							  lphb_conf_req);
+		break;
+
+	case LPHB_SET_UDP_PARAMS_INDID:
+		cdf_status = wma_lphb_conf_udp_params(wma_handle,
+						      lphb_conf_req);
+		break;
+
+	case LPHB_SET_UDP_PKT_FILTER_INDID:
+		cdf_status = wma_lphb_conf_udp_pkt_filter(wma_handle,
+							  lphb_conf_req);
+		break;
+
+	case LPHB_SET_NETWORK_INFO_INDID:
+	default:
+		break;
+	}
+
+	cdf_mem_free(lphb_conf_req);
+	return cdf_status;
+}
+#endif /* FEATURE_WLAN_LPHB */
+
+/**
+ * wma_process_dhcp_ind() - process dhcp indication from SME
+ * @wma_handle: wma handle
+ * @ta_dhcp_ind: DHCP indication
+ *
+ * Return: CDF Status
+ */
+CDF_STATUS wma_process_dhcp_ind(tp_wma_handle wma_handle,
+				tAniDHCPInd *ta_dhcp_ind)
+{
+	uint8_t vdev_id;
+	int status = 0;
+	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);
+
+	if (!ta_dhcp_ind) {
+		WMA_LOGE("%s : DHCP indication is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (!wma_find_vdev_by_addr(wma_handle, ta_dhcp_ind->adapterMacAddr,
+				   &vdev_id)) {
+		WMA_LOGE("%s: Failed to find vdev id for DHCP indication",
+			 __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGI("%s: WMA --> WMI_PEER_SET_PARAM triggered by DHCP, "
+		 "msgType=%s,"
+		 "device_mode=%d, macAddr=" MAC_ADDRESS_STR,
+		 __func__,
+		 ta_dhcp_ind->msgType == WMA_DHCP_START_IND ?
+		 "WMA_DHCP_START_IND" : "WMA_DHCP_STOP_IND",
+		 ta_dhcp_ind->device_mode,
+		 MAC_ADDR_ARRAY(ta_dhcp_ind->peerMacAddr));
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+		return CDF_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 = vdev_id;
+	peer_set_param_fp->param_id = WMI_PEER_CRIT_PROTO_HINT_ENABLED;
+	if (WMA_DHCP_START_IND == ta_dhcp_ind->msgType)
+		peer_set_param_fp->param_value = 1;
+	else
+		peer_set_param_fp->param_value = 0;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(ta_dhcp_ind->peerMacAddr,
+				   &peer_set_param_fp->peer_macaddr);
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				      len, WMI_PEER_SET_PARAM_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
+			 " returned Error %d", __func__, status);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_chan_to_mode() - convert channel to phy mode
+ * @chan: channel number
+ * @chan_width: channel width
+ * @vht_capable: vht capable
+ * @dot11_mode: 802.11 mode
+ *
+ * Return: return phy mode
+ */
+WLAN_PHY_MODE wma_chan_to_mode(u8 chan, phy_ch_width chan_width,
+				      u8 vht_capable, u8 dot11_mode)
+{
+	WLAN_PHY_MODE phymode = MODE_UNKNOWN;
+
+	/* 2.4 GHz band */
+	if ((chan >= WMA_11G_CHANNEL_BEGIN) && (chan <= WMA_11G_CHANNEL_END)) {
+		switch (chan_width) {
+		case CH_WIDTH_20MHZ:
+			/* In case of no channel bonding, use dot11_mode
+			 * to set phy mode
+			 */
+			switch (dot11_mode) {
+			case WNI_CFG_DOT11_MODE_11A:
+				phymode = MODE_11A;
+				break;
+			case WNI_CFG_DOT11_MODE_11B:
+				phymode = MODE_11B;
+				break;
+			case WNI_CFG_DOT11_MODE_11G:
+				phymode = MODE_11G;
+				break;
+			case WNI_CFG_DOT11_MODE_11G_ONLY:
+				phymode = MODE_11GONLY;
+				break;
+			default:
+				/* Configure MODE_11NG_HT20 for
+				 * self vdev(for vht too)
+				 */
+				phymode = MODE_11NG_HT20;
+				break;
+			}
+			break;
+		case CH_WIDTH_40MHZ:
+			phymode = vht_capable ? MODE_11AC_VHT40 :
+						MODE_11NG_HT40;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* 5 GHz band */
+	if ((chan >= WMA_11A_CHANNEL_BEGIN) && (chan <= WMA_11A_CHANNEL_END)) {
+		switch (chan_width) {
+		case CH_WIDTH_20MHZ:
+			phymode = vht_capable ? MODE_11AC_VHT20 :
+						MODE_11NA_HT20;
+			break;
+		case CH_WIDTH_40MHZ:
+			phymode = vht_capable ? MODE_11AC_VHT40 :
+						MODE_11NA_HT40;
+			break;
+		case CH_WIDTH_80MHZ:
+			phymode = MODE_11AC_VHT80;
+			break;
+#if CONFIG_160MHZ_SUPPORT != 0
+		case CH_WIDTH_160MHZ:
+			phymode = MODE_11AC_VHT160;
+			break;
+		case CH_WIDTH_80P80MHZ:
+			phymode = MODE_11AC_VHT80_80;
+			break;
+#endif
+
+		default:
+			break;
+		}
+	}
+
+	/* 5.9 GHz Band */
+	if ((chan >= WMA_11P_CHANNEL_BEGIN) && (chan <= WMA_11P_CHANNEL_END))
+		/* Only Legacy Modulation Schemes are supported */
+		phymode = MODE_11A;
+
+	WMA_LOGD("%s: phymode %d channel %d ch_width %d vht_capable %d "
+		 "dot11_mode %d", __func__, phymode, chan,
+		 chan_width, vht_capable, dot11_mode);
+
+	return phymode;
+}
+
+/**
+ * wma_get_link_speed() -send command to get linkspeed
+ * @handle: wma handle
+ * @pLinkSpeed: link speed info
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_get_link_speed(WMA_HANDLE handle, tSirLinkSpeedInfo *pLinkSpeed)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t len;
+	uint8_t *buf_ptr;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue get link speed cmd",
+			 __func__);
+		return CDF_STATUS_E_INVAL;
+	}
+	if (!WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+				    WMI_SERVICE_ESTIMATE_LINKSPEED)) {
+		WMA_LOGE("%s: Linkspeed feature bit not enabled"
+			 " Sending value 0 as link speed.", __func__);
+		wma_send_link_speed(0);
+		return CDF_STATUS_E_FAILURE;
+	}
+	len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
+	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!wmi_buf) {
+		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+		return CDF_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 */
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(pLinkSpeed->peer_macaddr,
+				   &cmd->peer_macaddr);
+
+	WMA_LOGD("%s: pLinkSpeed->peerMacAddr: %pM, "
+		 "peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x",
+		 __func__, pLinkSpeed->peer_macaddr,
+		 cmd->peer_macaddr.mac_addr31to0,
+		 cmd->peer_macaddr.mac_addr47to32);
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+				 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
+		WMA_LOGE("%s: failed to send link speed command", __func__);
+		cdf_nbuf_free(wmi_buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_GREEN_AP
+
+/**
+ * wmi_unified_pdev_green_ap_ps_enable_cmd() - enable green ap powersave command
+ * @wmi_handle: wmi handle
+ * @value: value
+ *
+ * Return: 0 for success or error code
+ */
+int32_t wmi_unified_pdev_green_ap_ps_enable_cmd(wmi_unified_t wmi_handle,
+						       uint32_t value)
+{
+	wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	WMA_LOGD("Set Green AP PS val %d", value);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		WMA_LOGP("%s: Green AP PS Mem Alloc Failed", __func__);
+		return -ENOMEM;
+	}
+
+	cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_pdev_green_ap_ps_enable_cmd_fixed_param));
+	cmd->reserved0 = 0;
+	cmd->enable = value;
+
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) {
+		WMA_LOGE("Set Green AP PS param Failed val %d", value);
+		cdf_nbuf_free(buf);
+		return -EIO;
+	}
+	return 0;
+}
+#endif /* FEATURE_GREEN_AP */
+
+#ifdef FEATURE_WLAN_LPHB
+/**
+ * wma_lphb_handler() - send LPHB indication to SME
+ * @wma: wma handle
+ * @event: event handler
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_lphb_handler(tp_wma_handle wma, uint8_t *event)
+{
+	wmi_hb_ind_event_fixed_param *hb_fp;
+	tSirLPHBInd *slphb_indication;
+	CDF_STATUS cdf_status;
+	cds_msg_t sme_msg = { 0 };
+
+	hb_fp = (wmi_hb_ind_event_fixed_param *) event;
+	if (!hb_fp) {
+		WMA_LOGE("Invalid wmi_hb_ind_event_fixed_param buffer");
+		return -EINVAL;
+	}
+
+	WMA_LOGD("lphb indication received with vdev_id=%d, session=%d, reason=%d",
+		hb_fp->vdev_id, hb_fp->session, hb_fp->reason);
+
+	slphb_indication = (tSirLPHBInd *) cdf_mem_malloc(sizeof(tSirLPHBInd));
+
+	if (!slphb_indication) {
+		WMA_LOGE("Invalid LPHB indication buffer");
+		return -ENOMEM;
+	}
+
+	slphb_indication->sessionIdx = hb_fp->session;
+	slphb_indication->protocolType = hb_fp->reason;
+	slphb_indication->eventReason = hb_fp->reason;
+
+	sme_msg.type = eWNI_SME_LPHB_IND;
+	sme_msg.bodyptr = slphb_indication;
+	sme_msg.bodyval = 0;
+
+	cdf_status = cds_mq_post_message(CDF_MODULE_ID_SME, &sme_msg);
+	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+		WMA_LOGE("Fail to post eWNI_SME_LPHB_IND msg to SME");
+		cdf_mem_free(slphb_indication);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif /* FEATURE_WLAN_LPHB */
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+/**
+ * wma_wow_sta_ra_filter() - set RA filter pattern in fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: CDF status
+ */
+static CDF_STATUS wma_wow_sta_ra_filter(tp_wma_handle wma, uint8_t vdev_id)
+{
+
+	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
+	struct wma_txrx_node *iface;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int32_t len;
+	int ret;
+
+	iface = &wma->interfaces[vdev_id];
+
+	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(A_UINT32) + WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32);
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_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 = iface->num_wow_default_patterns++,
+	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(A_UINT32));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	*((A_UINT32 *) buf_ptr) = wma->RArateLimitInterval;
+
+	WMA_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__,
+		 wma->RArateLimitInterval, vdev_id);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to send RA rate limit to fw", __func__);
+		wmi_buf_free(buf);
+		iface->num_wow_default_patterns--;
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+
+}
+#endif /* FEATURE_WLAN_RA_FILTERING */
+
+/**
+ * wmi_unified_nat_keepalive_enable() - enable NAT keepalive filter
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: 0 for success or error code
+ */
+int wmi_unified_nat_keepalive_enable(tp_wma_handle wma, uint8_t vdev_id)
+{
+	WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	WMA_LOGD("%s: vdev_id %d", __func__, vdev_id);
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
+		return -ENOMEM;
+	}
+	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;
+	if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
+		WMA_LOGP("%s: Failed to send NAT keepalive enable command",
+			 __func__);
+		wmi_buf_free(buf);
+		return -EIO;
+	}
+	return 0;
+}
+
+/**
+ * wmi_unified_csa_offload_enable() - sen CSA offload enable command
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: 0 for success or error code
+ */
+int wmi_unified_csa_offload_enable(tp_wma_handle wma, uint8_t vdev_id)
+{
+	wmi_csa_offload_enable_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	WMA_LOGD("%s: vdev_id %d", __func__, vdev_id);
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
+		return -ENOMEM;
+	}
+	cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_csa_offload_enable_cmd_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE;
+	if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				 WMI_CSA_OFFLOAD_ENABLE_CMDID)) {
+		WMA_LOGP("%s: Failed to send CSA offload enable command",
+			 __func__);
+		wmi_buf_free(buf);
+		return -EIO;
+	}
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * wma_nan_rsp_event_handler() - Function is used to handle nan response
+ * @handle: wma handle
+ * @event_buf: event buffer
+ * @len: length of buffer
+ *
+ * Return: 0 for success or error code
+ */
+int wma_nan_rsp_event_handler(void *handle, uint8_t *event_buf,
+			      uint32_t len)
+{
+	WMI_NAN_EVENTID_param_tlvs *param_buf;
+	tSirNanEvent *nan_rsp_event;
+	wmi_nan_event_hdr *nan_rsp_event_hdr;
+	CDF_STATUS status;
+	cds_msg_t cds_msg;
+	uint8_t *buf_ptr;
+	uint32_t alloc_len;
+
+	/*
+	 * This is how received event_buf looks like
+	 *
+	 * <-------------------- event_buf ----------------------------------->
+	 *
+	 * <--wmi_nan_event_hdr--><---WMI_TLV_HDR_SIZE---><----- data -------->
+	 *
+	 * +-----------+---------+-----------------------+--------------------+
+	 * | tlv_header| data_len| WMITLV_TAG_ARRAY_BYTE | nan_rsp_event_data |
+	 * +-----------+---------+-----------------------+--------------------+
+	 */
+
+	WMA_LOGD("%s: Posting NaN response event to SME", __func__);
+	param_buf = (WMI_NAN_EVENTID_param_tlvs *) event_buf;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid nan response event buf", __func__);
+		return -EINVAL;
+	}
+	nan_rsp_event_hdr = param_buf->fixed_param;
+	buf_ptr = (uint8_t *) nan_rsp_event_hdr;
+	alloc_len = sizeof(tSirNanEvent);
+	alloc_len += nan_rsp_event_hdr->data_len;
+	nan_rsp_event = (tSirNanEvent *) cdf_mem_malloc(alloc_len);
+	if (NULL == nan_rsp_event) {
+		WMA_LOGE("%s: Memory allocation failure", __func__);
+		return -ENOMEM;
+	}
+
+	nan_rsp_event->event_data_len = nan_rsp_event_hdr->data_len;
+	cdf_mem_copy(nan_rsp_event->event_data, buf_ptr +
+		     sizeof(wmi_nan_event_hdr) + WMI_TLV_HDR_SIZE,
+		     nan_rsp_event->event_data_len);
+	cds_msg.type = eWNI_SME_NAN_EVENT;
+	cds_msg.bodyptr = (void *)nan_rsp_event;
+	cds_msg.bodyval = 0;
+
+	status = cds_mq_post_message(CDS_MQ_ID_SME, &cds_msg);
+	if (status != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to post NaN response event to SME",
+			 __func__);
+		cdf_mem_free(nan_rsp_event);
+		return -EFAULT;
+	}
+	WMA_LOGD("%s: NaN response event Posted to SME", __func__);
+	return 0;
+}
+#endif /* WLAN_FEATURE_NAN */
+
+/**
+ * wma_csa_offload_handler() - CSA event handler
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * This event is sent by firmware when it receives CSA IE.
+ *
+ * Return: 0 for success or error code
+ */
+int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_CSA_HANDLING_EVENTID_param_tlvs *param_buf;
+	wmi_csa_event_fixed_param *csa_event;
+	uint8_t bssid[IEEE80211_ADDR_LEN];
+	uint8_t vdev_id = 0;
+	uint8_t cur_chan = 0;
+	struct ieee80211_channelswitch_ie *csa_ie;
+	tpCSAOffloadParams csa_offload_event;
+	struct ieee80211_extendedchannelswitch_ie *xcsa_ie;
+	struct ieee80211_ie_wide_bw_switch *wb_ie;
+	struct wma_txrx_node *intr = wma->interfaces;
+
+	param_buf = (WMI_CSA_HANDLING_EVENTID_param_tlvs *) event;
+
+	WMA_LOGD("%s: Enter", __func__);
+	if (!param_buf) {
+		WMA_LOGE("Invalid csa event buffer");
+		return -EINVAL;
+	}
+	csa_event = param_buf->fixed_param;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->i_addr2, &bssid[0]);
+
+	if (wma_find_vdev_by_bssid(wma, bssid, &vdev_id) == NULL) {
+		WMA_LOGE("Invalid bssid received %s:%d", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	csa_offload_event = cdf_mem_malloc(sizeof(*csa_offload_event));
+	if (!csa_offload_event) {
+		WMA_LOGE("CDF MEM Alloc Failed for csa_offload_event");
+		return -EINVAL;
+	}
+
+	cdf_mem_zero(csa_offload_event, sizeof(*csa_offload_event));
+	cdf_mem_copy(csa_offload_event->bssId, &bssid, IEEE80211_ADDR_LEN);
+
+	if (csa_event->ies_present_flag & WMI_CSA_IE_PRESENT) {
+		csa_ie = (struct ieee80211_channelswitch_ie *)
+						(&csa_event->csa_ie[0]);
+		csa_offload_event->channel = csa_ie->newchannel;
+		csa_offload_event->switchmode = csa_ie->switchmode;
+	} else if (csa_event->ies_present_flag & WMI_XCSA_IE_PRESENT) {
+		xcsa_ie = (struct ieee80211_extendedchannelswitch_ie *)
+						(&csa_event->xcsa_ie[0]);
+		csa_offload_event->channel = xcsa_ie->newchannel;
+		csa_offload_event->switchmode = xcsa_ie->switchmode;
+	} else {
+		WMA_LOGE("CSA Event error: No CSA IE present");
+		cdf_mem_free(csa_offload_event);
+		return -EINVAL;
+	}
+
+	if (csa_event->ies_present_flag & WMI_WBW_IE_PRESENT) {
+		wb_ie = (struct ieee80211_ie_wide_bw_switch *)
+						(&csa_event->wb_ie[0]);
+		csa_offload_event->new_ch_width = wb_ie->new_ch_width;
+		csa_offload_event->new_ch_freq_seg1 = wb_ie->new_ch_freq_seg1;
+		csa_offload_event->new_ch_freq_seg2 = wb_ie->new_ch_freq_seg2;
+	}
+
+	csa_offload_event->ies_present_flag = csa_event->ies_present_flag;
+
+	WMA_LOGD("CSA: New Channel = %d BSSID:%pM",
+		 csa_offload_event->channel, csa_offload_event->bssId);
+
+	cur_chan = cds_freq_to_chan(intr[vdev_id].mhz);
+	/*
+	 * basic sanity check: requested channel should not be 0
+	 * and equal to home channel
+	 */
+	if ((0 == csa_offload_event->channel) ||
+	    (cur_chan == csa_offload_event->channel)) {
+		WMA_LOGE("CSA Event with channel %d. Ignore !!",
+			 csa_offload_event->channel);
+		cdf_mem_free(csa_offload_event);
+		return -EINVAL;
+	}
+	wma->interfaces[vdev_id].is_channel_switch = true;
+	wma_send_msg(wma, WMA_CSA_OFFLOAD_EVENT, (void *)csa_offload_event, 0);
+	return 0;
+}
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+/**
+ * wma_oem_capability_event_callback() - OEM capability event handler
+ * @handle: wma handle
+ * @datap: data ptr
+ * @len: data length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_oem_capability_event_callback(void *handle,
+				      uint8_t *datap, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_OEM_CAPABILITY_EVENTID_param_tlvs *param_buf;
+	uint8_t *data;
+	uint32_t datalen;
+	uint32_t *msg_subtype;
+	tStartOemDataRsp *pStartOemDataRsp;
+
+	param_buf = (WMI_OEM_CAPABILITY_EVENTID_param_tlvs *) datap;
+	if (!param_buf) {
+		WMA_LOGE("%s: Received NULL buf ptr from FW", __func__);
+		return -ENOMEM;
+	}
+
+	data = param_buf->data;
+	datalen = param_buf->num_data;
+
+	if (!data) {
+		WMA_LOGE("%s: Received NULL data from FW", __func__);
+		return -EINVAL;
+	}
+
+	/* wma puts 4 bytes prefix for msg subtype, so length
+	 * of data received from target should be 4 bytes less
+	 * then max allowed
+	 */
+	if (datalen > (OEM_DATA_RSP_SIZE - 4)) {
+		WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)",
+			 __func__, datalen, (OEM_DATA_RSP_SIZE - 4));
+		return -EINVAL;
+	}
+
+	pStartOemDataRsp = cdf_mem_malloc(sizeof(*pStartOemDataRsp));
+	if (!pStartOemDataRsp) {
+		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
+		return -ENOMEM;
+	}
+
+	cdf_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp));
+	msg_subtype = (uint32_t *) (&pStartOemDataRsp->oemDataRsp[0]);
+	*msg_subtype = WMI_OEM_CAPABILITY_RSP;
+	cdf_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen);
+
+	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP, data len (%d)",
+		 __func__, datalen);
+
+	wma_send_msg(wma, WMA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0);
+	return 0;
+}
+
+/**
+ * wma_oem_measurement_report_event_callback() - OEM measurement report handler
+ * @handle: wma handle
+ * @datap: data ptr
+ * @len: data length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_oem_measurement_report_event_callback(void *handle,
+					      uint8_t *datap,
+					      uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_OEM_MEASUREMENT_REPORT_EVENTID_param_tlvs *param_buf;
+	uint8_t *data;
+	uint32_t datalen;
+	uint32_t *msg_subtype;
+	tStartOemDataRsp *pStartOemDataRsp;
+
+	param_buf = (WMI_OEM_MEASUREMENT_REPORT_EVENTID_param_tlvs *) datap;
+	if (!param_buf) {
+		WMA_LOGE("%s: Received NULL buf ptr from FW", __func__);
+		return -ENOMEM;
+	}
+
+	data = param_buf->data;
+	datalen = param_buf->num_data;
+
+	if (!data) {
+		WMA_LOGE("%s: Received NULL data from FW", __func__);
+		return -EINVAL;
+	}
+
+	/* wma puts 4 bytes prefix for msg subtype, so length
+	 * of data received from target should be 4 bytes less
+	 * then max allowed
+	 */
+	if (datalen > (OEM_DATA_RSP_SIZE - 4)) {
+		WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)",
+			 __func__, datalen, (OEM_DATA_RSP_SIZE - 4));
+		return -EINVAL;
+	}
+
+	pStartOemDataRsp = cdf_mem_malloc(sizeof(*pStartOemDataRsp));
+	if (!pStartOemDataRsp) {
+		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
+		return -ENOMEM;
+	}
+
+	cdf_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp));
+	msg_subtype = (uint32_t *) (&pStartOemDataRsp->oemDataRsp[0]);
+	*msg_subtype = WMI_OEM_MEASUREMENT_RSP;
+	cdf_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen);
+
+	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP, data len (%d)",
+		 __func__, datalen);
+
+	wma_send_msg(wma, WMA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0);
+	return 0;
+}
+
+/**
+ * wma_oem_error_report_event_callback() - OEM error report handler
+ * @handle: wma handle
+ * @datap: data ptr
+ * @len: data length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_oem_error_report_event_callback(void *handle,
+					uint8_t *datap, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_OEM_ERROR_REPORT_EVENTID_param_tlvs *param_buf;
+	uint8_t *data;
+	uint32_t datalen;
+	uint32_t *msg_subtype;
+	tStartOemDataRsp *pStartOemDataRsp;
+
+	param_buf = (WMI_OEM_ERROR_REPORT_EVENTID_param_tlvs *) datap;
+	if (!param_buf) {
+		WMA_LOGE("%s: Received NULL buf ptr from FW", __func__);
+		return -ENOMEM;
+	}
+
+	data = param_buf->data;
+	datalen = param_buf->num_data;
+
+	if (!data) {
+		WMA_LOGE("%s: Received NULL data from FW", __func__);
+		return -EINVAL;
+	}
+
+	/* wma puts 4 bytes prefix for msg subtype, so length
+	 * of data received from target should be 4 bytes less
+	 * then max allowed
+	 */
+	if (datalen > (OEM_DATA_RSP_SIZE - 4)) {
+		WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)",
+			 __func__, datalen, (OEM_DATA_RSP_SIZE - 4));
+		return -EINVAL;
+	}
+
+	pStartOemDataRsp = cdf_mem_malloc(sizeof(*pStartOemDataRsp));
+	if (!pStartOemDataRsp) {
+		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
+		return -ENOMEM;
+	}
+
+	cdf_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp));
+	msg_subtype = (uint32_t *) (&pStartOemDataRsp->oemDataRsp[0]);
+	*msg_subtype = WMI_OEM_ERROR_REPORT_RSP;
+	cdf_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen);
+
+	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP, data len (%d)",
+		 __func__, datalen);
+
+	wma_send_msg(wma, WMA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0);
+	return 0;
+}
+
+/**
+ * wma_start_oem_data_req() - start OEM data request to target
+ * @wma_handle: wma handle
+ * @startOemDataReq: start request params
+ *
+ * Return: none
+ */
+void wma_start_oem_data_req(tp_wma_handle wma_handle,
+			    tStartOemDataReq *startOemDataReq)
+{
+	wmi_buf_t buf;
+	uint8_t *cmd;
+	int ret = 0;
+	uint32_t *msg_subtype;
+	tStartOemDataRsp *pStartOemDataRsp;
+
+	WMA_LOGD("%s: Send OEM Data Request to target", __func__);
+
+	if (!startOemDataReq) {
+		WMA_LOGE("%s: startOemDataReq is null", __func__);
+		goto out;
+	}
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not send Oem data request cmd",
+			 __func__);
+		return;
+	}
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle,
+			    (OEM_DATA_REQ_SIZE + WMI_TLV_HDR_SIZE));
+	if (!buf) {
+		WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+		goto out;
+	}
+
+	cmd = (uint8_t *) wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, OEM_DATA_REQ_SIZE);
+	cmd += WMI_TLV_HDR_SIZE;
+	cdf_mem_copy(cmd, &startOemDataReq->oemDataReq[0], OEM_DATA_REQ_SIZE);
+
+	WMA_LOGI("%s: Sending OEM Data Request to target, data len (%d)",
+		 __func__, OEM_DATA_REQ_SIZE);
+
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				   (OEM_DATA_REQ_SIZE +
+				    WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID);
+
+	if (ret != EOK) {
+		WMA_LOGE("%s:wmi cmd send failed", __func__);
+		cdf_nbuf_free(buf);
+	}
+
+out:
+	/* free oem data req buffer received from UMAC */
+	if (startOemDataReq)
+		cdf_mem_free(startOemDataReq);
+
+	/* Now send data resp back to PE/SME with message sub-type of
+	 * WMI_OEM_INTERNAL_RSP. This is required so that PE/SME clears
+	 * up pending active command. Later when desired oem response(s)
+	 * comes as wmi event from target then those shall be passed
+	 * to oem application
+	 */
+	pStartOemDataRsp = cdf_mem_malloc(sizeof(*pStartOemDataRsp));
+	if (!pStartOemDataRsp) {
+		WMA_LOGE("%s:failed to allocate memory for OEM Data Resp to PE",
+			 __func__);
+		return;
+	}
+	cdf_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp));
+	msg_subtype = (uint32_t *) (&pStartOemDataRsp->oemDataRsp[0]);
+	*msg_subtype = WMI_OEM_INTERNAL_RSP;
+
+	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP to clear up PE/SME pending cmd",
+		__func__);
+
+	wma_send_msg(wma_handle, WMA_START_OEM_DATA_RSP,
+		     (void *)pStartOemDataRsp, 0);
+
+	return;
+}
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+
+
+/**
+ * wma_unified_dfs_radar_rx_event_handler() - dfs radar rx event handler
+ * @handle: wma handle
+ * @data: data buffer
+ * @datalen: data length
+ *
+ * WMI handler for WMI_DFS_RADAR_EVENTID
+ * This handler is registered for handling
+ * filtered DFS Phyerror. This handler is
+ * will be invoked only when DFS Phyerr
+ * filtering offload is enabled.
+ *
+ * Return: 1 for Success and 0 for error
+ */
+static int wma_unified_dfs_radar_rx_event_handler(void *handle,
+						  uint8_t *data,
+						  uint32_t datalen)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	struct ieee80211com *ic;
+	struct ath_dfs *dfs;
+	struct dfs_event *event;
+	struct ieee80211_channel *chan;
+	int empty;
+	int do_check_chirp = 0;
+	int is_hw_chirp = 0;
+	int is_sw_chirp = 0;
+	int is_pri = 0;
+
+	WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlvs;
+	wmi_dfs_radar_event_fixed_param *radar_event;
+
+	ic = wma->dfs_ic;
+	if (NULL == ic) {
+		WMA_LOGE("%s: dfs_ic is  NULL ", __func__);
+		return 0;
+	}
+
+	dfs = (struct ath_dfs *)ic->ic_dfs;
+	param_tlvs = (WMI_DFS_RADAR_EVENTID_param_tlvs *) data;
+
+	if (NULL == dfs) {
+		WMA_LOGE("%s: dfs is  NULL ", __func__);
+		return 0;
+	}
+	/*
+	 * This parameter holds the number
+	 * of phyerror interrupts to the host
+	 * after the phyerrors have passed through
+	 * false detect filters in the firmware.
+	 */
+	dfs->dfs_phyerr_count++;
+
+	if (!param_tlvs) {
+		WMA_LOGE("%s: Received NULL data from FW", __func__);
+		return 0;
+	}
+
+	radar_event = param_tlvs->fixed_param;
+
+	cdf_mutex_acquire(&ic->chan_lock);
+	chan = ic->ic_curchan;
+	if (CHANNEL_STATE_DFS != cds_get_channel_state(chan->ic_ieee)) {
+		WMA_LOGE
+			("%s: Invalid DFS Phyerror event. Channel=%d is Non-DFS",
+			__func__, chan->ic_ieee);
+		cdf_mutex_release(&ic->chan_lock);
+		return 0;
+	}
+
+	cdf_mutex_release(&ic->chan_lock);
+	dfs->ath_dfs_stats.total_phy_errors++;
+
+	if (dfs->dfs_caps.ath_chip_is_bb_tlv) {
+		do_check_chirp = 1;
+		is_pri = 1;
+		is_hw_chirp = radar_event->pulse_is_chirp;
+
+		if ((uint32_t) dfs->dfs_phyerr_freq_min >
+		    radar_event->pulse_center_freq) {
+			dfs->dfs_phyerr_freq_min =
+				(int)radar_event->pulse_center_freq;
+		}
+
+		if (dfs->dfs_phyerr_freq_max <
+		    (int)radar_event->pulse_center_freq) {
+			dfs->dfs_phyerr_freq_max =
+				(int)radar_event->pulse_center_freq;
+		}
+	}
+
+	/*
+	 * Now, add the parsed, checked and filtered
+	 * radar phyerror event radar pulse event list.
+	 * This event will then be processed by
+	 * dfs_radar_processevent() to see if the pattern
+	 * of pulses in radar pulse list match any radar
+	 * singnature in the current regulatory domain.
+	 */
+
+	ATH_DFSEVENTQ_LOCK(dfs);
+	empty = STAILQ_EMPTY(&(dfs->dfs_eventq));
+	ATH_DFSEVENTQ_UNLOCK(dfs);
+	if (empty) {
+		return 0;
+	}
+	/*
+	 * Add the event to the list, if there's space.
+	 */
+	ATH_DFSEVENTQ_LOCK(dfs);
+	event = STAILQ_FIRST(&(dfs->dfs_eventq));
+	if (event == NULL) {
+		ATH_DFSEVENTQ_UNLOCK(dfs);
+		WMA_LOGE("%s: No more space left for queuing DFS Phyerror events",
+			__func__);
+		return 0;
+	}
+	STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list);
+	ATH_DFSEVENTQ_UNLOCK(dfs);
+	dfs->dfs_phyerr_queued_count++;
+	dfs->dfs_phyerr_w53_counter++;
+	event->re_dur = (uint8_t) radar_event->pulse_duration;
+	event->re_rssi = radar_event->rssi;
+	event->re_ts = radar_event->pulse_detect_ts & DFS_TSMASK;
+	event->re_full_ts = (((uint64_t) radar_event->upload_fullts_high) << 32)
+			    | radar_event->upload_fullts_low;
+
+	/*
+	 * Index of peak magnitude
+	 */
+	event->sidx = radar_event->peak_sidx;
+
+	/*
+	 * Handle chirp flags.
+	 */
+	if (do_check_chirp) {
+		event->re_flags |= DFS_EVENT_CHECKCHIRP;
+		if (is_hw_chirp) {
+			event->re_flags |= DFS_EVENT_HW_CHIRP;
+		}
+		if (is_sw_chirp) {
+			event->re_flags |= DFS_EVENT_SW_CHIRP;
+		}
+	}
+	/*
+	 * Correctly set which channel is being reported on
+	 */
+	if (is_pri) {
+		event->re_chanindex = (uint8_t) dfs->dfs_curchan_radindex;
+	} else {
+		if (dfs->dfs_extchan_radindex == -1) {
+			WMA_LOGI("%s phyerr on ext channel", __func__);
+		}
+		event->re_chanindex = (uint8_t) dfs->dfs_extchan_radindex;
+		WMA_LOGI("%s:New extension channel event is added to queue",
+			 __func__);
+	}
+
+	ATH_DFSQ_LOCK(dfs);
+
+	STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list);
+
+	empty = STAILQ_EMPTY(&dfs->dfs_radarq);
+
+	ATH_DFSQ_UNLOCK(dfs);
+
+	if (!empty && !dfs->ath_radar_tasksched) {
+		dfs->ath_radar_tasksched = 1;
+		OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0);
+	}
+
+	return 1;
+
+}
+
+/**
+ * wma_unified_phyerr_rx_event_handler() - phyerr event handler
+ * @handle: wma handle
+ * @data: data buffer
+ * @datalen: buffer length
+ *
+ * WMI Handler for WMI_PHYERR_EVENTID event from firmware.
+ * This handler is currently handling only DFS phy errors.
+ * This handler will be invoked only when the DFS phyerror
+ * filtering offload is disabled.
+ *
+ * Return:  1:Success, 0:Failure
+ */
+static int wma_unified_phyerr_rx_event_handler(void *handle,
+					       uint8_t *data, uint32_t datalen)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_PHYERR_EVENTID_param_tlvs *param_tlvs;
+	wmi_comb_phyerr_rx_hdr *pe_hdr;
+	uint8_t *bufp;
+	wmi_single_phyerr_rx_event *ev;
+	struct ieee80211com *ic = wma->dfs_ic;
+	cdf_size_t n;
+	A_UINT64 tsf64 = 0;
+	int phy_err_code = 0;
+	int error = 0;
+	tpAniSirGlobal mac_ctx =
+		(tpAniSirGlobal)cds_get_context(CDF_MODULE_ID_PE);
+	bool enable_log = false;
+
+	if (NULL == mac_ctx) {
+		WMA_LOGE("%s: mac_ctx is NULL", __func__);
+		return 0;
+	}
+	enable_log = mac_ctx->sap.enable_dfs_phy_error_logs;
+
+	param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *) data;
+
+	if (!param_tlvs) {
+		WMA_LOGE("%s: Received NULL data from FW", __func__);
+		return 0;
+	}
+
+	pe_hdr = param_tlvs->hdr;
+	if (pe_hdr == NULL) {
+		WMA_LOGE("%s: Received Data PE Header is NULL", __func__);
+		return 0;
+	}
+
+	/* Ensure it's at least the size of the header */
+	if (datalen < sizeof(*pe_hdr)) {
+		WMA_LOGE("%s:  Expected minimum size %zu, received %d",
+			 __func__, sizeof(*pe_hdr), datalen);
+		return 0;
+	}
+	if (pe_hdr->buf_len > DFS_MAX_BUF_LENGHT) {
+		WMA_LOGE("%s: Received Invalid Phyerror event buffer length = %d"
+			"Maximum allowed buf length = %d", __func__,
+			pe_hdr->buf_len, DFS_MAX_BUF_LENGHT);
+
+		return 0;
+	}
+
+	/*
+	 * Reconstruct the 64 bit event TSF. This isn't from the MAC, it's
+	 * at the time the event was sent to us, the TSF value will be
+	 * in the future.
+	 */
+	tsf64 = pe_hdr->tsf_l32;
+	tsf64 |= (((uint64_t) pe_hdr->tsf_u32) << 32);
+
+	/*
+	 * Loop over the bufp, extracting out phyerrors
+	 * wmi_unified_comb_phyerr_rx_event.bufp is a char pointer,
+	 * which isn't correct here - what we have received here
+	 * is an array of TLV-style PHY errors.
+	 */
+	n = 0;                  /* Start just after the header */
+	bufp = param_tlvs->bufp;
+	while (n < pe_hdr->buf_len) {
+		/* ensure there's at least space for the header */
+		if ((pe_hdr->buf_len - n) < sizeof(ev->hdr)) {
+			WMA_LOGE("%s: Not enough space.(datalen=%d, n=%zu, hdr=%zu bytes",
+				__func__, pe_hdr->buf_len, n, sizeof(ev->hdr));
+			error = 1;
+			break;
+		}
+		/*
+		 * Obtain a pointer to the beginning of the current event.
+		 * data[0] is the beginning of the WMI payload.
+		 */
+		ev = (wmi_single_phyerr_rx_event *) &bufp[n];
+
+		/*
+		 * Sanity check the buffer length of the event against
+		 * what we currently have.
+		 * Since buf_len is 32 bits, we check if it overflows
+		 * a large 32 bit value. It's not 0x7fffffff because
+		 * we increase n by (buf_len + sizeof(hdr)), which would
+		 * in itself cause n to overflow.
+		 * If "int" is 64 bits then this becomes a moot point.
+		 */
+		if (ev->hdr.buf_len > 0x7f000000) {
+			WMA_LOGE("%s:buf_len is garbage (0x%x)", __func__,
+				 ev->hdr.buf_len);
+			error = 1;
+			break;
+		}
+		if (n + ev->hdr.buf_len > pe_hdr->buf_len) {
+			WMA_LOGE("%s: buf_len exceeds available space n=%zu,"
+				 "buf_len=%d, datalen=%d",
+				 __func__, n, ev->hdr.buf_len, pe_hdr->buf_len);
+			error = 1;
+			break;
+		}
+		phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
+
+		/*
+		 * If the phyerror category matches,
+		 * pass radar events to the dfs pattern matching code.
+		 * Don't pass radar events with no buffer payload.
+		 */
+		if (phy_err_code == 0x5 || phy_err_code == 0x24) {
+			if (ev->hdr.buf_len > 0) {
+				/* Calling in to the DFS module to process the phyerr */
+				dfs_process_phyerr(ic, &ev->bufp[0],
+						   ev->hdr.buf_len,
+						   WMI_UNIFIED_RSSI_COMB_GET
+							   (&ev->hdr) & 0xff,
+						   /* Extension RSSI */
+						   WMI_UNIFIED_RSSI_COMB_GET
+							   (&ev->hdr) & 0xff,
+						   ev->hdr.tsf_timestamp,
+						   tsf64, enable_log);
+			}
+		}
+
+		/*
+		 * Advance the buffer pointer to the next PHY error.
+		 * buflen is the length of this payload, so we need to
+		 * advance past the current header _AND_ the payload.
+		 */
+		n += sizeof(*ev) + ev->hdr.buf_len;
+
+	} /*end while() */
+	if (error)
+		return 0;
+	else
+		return 1;
+}
+
+/**
+ * wma_register_dfs_event_handler() - register dfs event handler
+ * @wma_handle: wma handle
+ *
+ * Register appropriate dfs phyerror event handler
+ * based on phyerror filtering offload is enabled
+ * or disabled.
+ *
+ * Return: none
+ */
+void wma_register_dfs_event_handler(tp_wma_handle wma_handle)
+{
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s:wma_handle is NULL", __func__);
+		return;
+	}
+
+	if (false == wma_handle->dfs_phyerr_filter_offload) {
+		/*
+		 * Register the wma_unified_phyerr_rx_event_handler
+		 * for filtering offload disabled case to handle
+		 * the DFS phyerrors.
+		 */
+		WMA_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
+			 __func__);
+		wmi_unified_register_event_handler(wma_handle->wmi_handle,
+						   WMI_PHYERR_EVENTID,
+						   wma_unified_phyerr_rx_event_handler);
+		WMA_LOGD("%s: WMI_PHYERR_EVENTID event handler registered",
+			 __func__);
+	} else {
+		WMA_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
+			 __func__);
+		wmi_unified_register_event_handler(wma_handle->wmi_handle,
+						   WMI_DFS_RADAR_EVENTID,
+						   wma_unified_dfs_radar_rx_event_handler);
+		WMA_LOGD("%s:WMI_DFS_RADAR_EVENTID event handler registered",
+			 __func__);
+	}
+
+	return;
+}
+
+
+/**
+ * wma_unified_dfs_phyerr_filter_offload_enable() - enable dfs phyerr filter
+ * @wma_handle: wma handle
+ *
+ * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
+ * WMI_DFS_PHYERR_FILTER_DIS_CMDID command
+ * to firmware based on phyerr filtering
+ * offload status.
+ *
+ * Return: 1 success, 0 failure
+ */
+int
+wma_unified_dfs_phyerr_filter_offload_enable(tp_wma_handle wma_handle)
+{
+	wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd;
+	wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd;
+	wmi_buf_t buf;
+	uint16_t len;
+	int ret;
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s:wma_handle is NULL", __func__);
+		return 0;
+	}
+
+	if (false == wma_handle->dfs_phyerr_filter_offload) {
+		WMA_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
+			 __func__);
+		len = sizeof(*disable_phyerr_offload_cmd);
+		buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+		if (!buf) {
+			WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+			return 0;
+		}
+		disable_phyerr_offload_cmd =
+			(wmi_dfs_phyerr_filter_dis_cmd_fixed_param *)
+			wmi_buf_data(buf);
+
+		WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param,
+			       WMITLV_GET_STRUCT_TLVLEN
+				       (wmi_dfs_phyerr_filter_dis_cmd_fixed_param));
+
+		/*
+		 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID
+		 * to the firmware to disable the phyerror
+		 * filtering offload.
+		 */
+		ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+					   WMI_DFS_PHYERR_FILTER_DIS_CMDID);
+		if (ret < 0) {
+			WMA_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d",
+				__func__, ret);
+			wmi_buf_free(buf);
+			return 0;
+		}
+		WMA_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success",
+			 __func__);
+	} else {
+		WMA_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
+			 __func__);
+
+		len = sizeof(*enable_phyerr_offload_cmd);
+		buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+		if (!buf) {
+			WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+			return 0;
+		}
+
+		enable_phyerr_offload_cmd =
+			(wmi_dfs_phyerr_filter_ena_cmd_fixed_param *)
+			wmi_buf_data(buf);
+
+		WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param,
+			       WMITLV_GET_STRUCT_TLVLEN
+				       (wmi_dfs_phyerr_filter_ena_cmd_fixed_param));
+
+		/*
+		 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID
+		 * to the firmware to enable the phyerror
+		 * filtering offload.
+		 */
+		ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+					   WMI_DFS_PHYERR_FILTER_ENA_CMDID);
+
+		if (ret < 0) {
+			WMA_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_ENA_CMDID ret=%d",
+				__func__, ret);
+			wmi_buf_free(buf);
+			return 0;
+		}
+		WMA_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success",
+			 __func__);
+	}
+
+	return 1;
+}
+
+#if !defined(REMOVE_PKT_LOG)
+/**
+ * wma_pktlog_wmi_send_cmd() - send pktlog enable/disable command to target
+ * @handle: wma handle
+ * @params: pktlog params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle,
+				   struct ath_pktlog_wmi_params *params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_PKTLOG_EVENT PKTLOG_EVENT;
+	WMI_CMD_ID CMD_ID;
+	wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
+	wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd;
+	int len = 0;
+	wmi_buf_t buf;
+
+	/*Check if packet log is enabled in cfg.ini */
+	if (!cds_is_packet_log_enabled()) {
+		WMA_LOGE("%s:pkt log is not enabled in cfg.ini", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	PKTLOG_EVENT = params->pktlog_event;
+	CMD_ID = params->cmd_id;
+
+	switch (CMD_ID) {
+	case WMI_PDEV_PKTLOG_ENABLE_CMDID:
+		len = sizeof(*cmd);
+		buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+		if (!buf) {
+			WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+			return CDF_STATUS_E_NOMEM;
+		}
+		cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *)
+			wmi_buf_data(buf);
+		WMITLV_SET_HDR(&cmd->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
+			       WMITLV_GET_STRUCT_TLVLEN
+				       (wmi_pdev_pktlog_enable_cmd_fixed_param));
+		cmd->evlist = PKTLOG_EVENT;
+		if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+					 WMI_PDEV_PKTLOG_ENABLE_CMDID)) {
+			WMA_LOGE("failed to send pktlog enable cmdid");
+			goto wmi_send_failed;
+		}
+		break;
+	case WMI_PDEV_PKTLOG_DISABLE_CMDID:
+		len = sizeof(*disable_cmd);
+		buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+		if (!buf) {
+			WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+			return CDF_STATUS_E_NOMEM;
+		}
+		disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *)
+			      wmi_buf_data(buf);
+		WMITLV_SET_HDR(&disable_cmd->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
+			       WMITLV_GET_STRUCT_TLVLEN
+				       (wmi_pdev_pktlog_disable_cmd_fixed_param));
+		disable_cmd->reserved0 = 0;
+		if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+					 WMI_PDEV_PKTLOG_DISABLE_CMDID)) {
+			WMA_LOGE("failed to send pktlog disable cmdid");
+			goto wmi_send_failed;
+		}
+		break;
+	default:
+		WMA_LOGD("%s: invalid PKTLOG command", __func__);
+		break;
+	}
+
+	return CDF_STATUS_SUCCESS;
+
+wmi_send_failed:
+	wmi_buf_free(buf);
+	return CDF_STATUS_E_FAILURE;
+}
+#endif /* REMOVE_PKT_LOG */
+
+static void wma_send_status_to_suspend_ind(tp_wma_handle wma, bool suspended)
+{
+	tSirReadyToSuspendInd *ready_to_suspend;
+	CDF_STATUS status;
+	cds_msg_t cds_msg;
+	uint8_t len;
+
+	WMA_LOGD("Posting ready to suspend indication to umac");
+
+	len = sizeof(tSirReadyToSuspendInd);
+	ready_to_suspend = (tSirReadyToSuspendInd *) cdf_mem_malloc(len);
+
+	if (NULL == ready_to_suspend) {
+		WMA_LOGE("%s: Memory allocation failure", __func__);
+		return;
+	}
+
+	ready_to_suspend->mesgType = eWNI_SME_READY_TO_SUSPEND_IND;
+	ready_to_suspend->mesgLen = len;
+	ready_to_suspend->suspended = suspended;
+
+	cds_msg.type = eWNI_SME_READY_TO_SUSPEND_IND;
+	cds_msg.bodyptr = (void *)ready_to_suspend;
+	cds_msg.bodyval = 0;
+
+	status = cds_mq_post_message(CDS_MQ_ID_SME, &cds_msg);
+	if (status != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to post ready to suspend");
+		cdf_mem_free(ready_to_suspend);
+	}
+}
+
+/**
+ * wma_wow_wake_reason_str() -  Converts wow wakeup reason code to text format
+ * @wake_reason - WOW wake reason
+ *
+ * Return: reason code in string format
+ */
+static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason)
+{
+	switch (wake_reason) {
+	case WOW_REASON_UNSPECIFIED:
+		return "UNSPECIFIED";
+	case WOW_REASON_NLOD:
+		return "NLOD";
+	case WOW_REASON_AP_ASSOC_LOST:
+		return "AP_ASSOC_LOST";
+	case WOW_REASON_LOW_RSSI:
+		return "LOW_RSSI";
+	case WOW_REASON_DEAUTH_RECVD:
+		return "DEAUTH_RECVD";
+	case WOW_REASON_DISASSOC_RECVD:
+		return "DISASSOC_RECVD";
+	case WOW_REASON_GTK_HS_ERR:
+		return "GTK_HS_ERR";
+	case WOW_REASON_EAP_REQ:
+		return "EAP_REQ";
+	case WOW_REASON_FOURWAY_HS_RECV:
+		return "FOURWAY_HS_RECV";
+	case WOW_REASON_TIMER_INTR_RECV:
+		return "TIMER_INTR_RECV";
+	case WOW_REASON_PATTERN_MATCH_FOUND:
+		return "PATTERN_MATCH_FOUND";
+	case WOW_REASON_RECV_MAGIC_PATTERN:
+		return "RECV_MAGIC_PATTERN";
+	case WOW_REASON_P2P_DISC:
+		return "P2P_DISC";
+#ifdef FEATURE_WLAN_LPHB
+	case WOW_REASON_WLAN_HB:
+		return "WLAN_HB";
+#endif /* FEATURE_WLAN_LPHB */
+
+	case WOW_REASON_CSA_EVENT:
+		return "CSA_EVENT";
+	case WOW_REASON_PROBE_REQ_WPS_IE_RECV:
+		return "PROBE_REQ_RECV";
+	case WOW_REASON_AUTH_REQ_RECV:
+		return "AUTH_REQ_RECV";
+	case WOW_REASON_ASSOC_REQ_RECV:
+		return "ASSOC_REQ_RECV";
+	case WOW_REASON_HTT_EVENT:
+		return "WOW_REASON_HTT_EVENT";
+#ifdef FEATURE_WLAN_RA_FILTERING
+	case WOW_REASON_RA_MATCH:
+		return "WOW_REASON_RA_MATCH";
+#endif /* FEATURE_WLAN_RA_FILTERING */
+	case WOW_REASON_BEACON_RECV:
+		return "WOW_REASON_IBSS_BEACON_RECV";
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	case WOW_REASON_HOST_AUTO_SHUTDOWN:
+		return "WOW_REASON_HOST_AUTO_SHUTDOWN";
+#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	case WOW_REASON_ROAM_HO:
+		return "WOW_REASON_ROAM_HO";
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+#ifdef FEATURE_WLAN_EXTSCAN
+	case WOW_REASON_EXTSCAN:
+		return "WOW_REASON_EXTSCAN";
+#endif
+	case WOW_REASON_RSSI_BREACH_EVENT:
+		return "WOW_REASON_RSSI_BREACH_EVENT";
+	}
+	return "unknown";
+}
+
+/**
+ * wma_wow_wake_up_stats_display() - display wow wake up stats
+ * @wma: Pointer to wma handle
+ *
+ * Return: none
+ */
+static void wma_wow_wake_up_stats_display(tp_wma_handle wma)
+{
+	WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d",
+		wma->wow_ucast_wake_up_count,
+		wma->wow_bcast_wake_up_count,
+		wma->wow_ipv4_mcast_wake_up_count,
+		wma->wow_ipv6_mcast_wake_up_count,
+		wma->wow_ipv6_mcast_ra_stats,
+		wma->wow_ipv6_mcast_ns_stats,
+		wma->wow_ipv6_mcast_na_stats,
+		wma->wow_pno_match_wake_up_count,
+		wma->wow_pno_complete_wake_up_count,
+		wma->wow_gscan_wake_up_count,
+		wma->wow_low_rssi_wake_up_count,
+		wma->wow_rssi_breach_wake_up_count);
+
+	return;
+}
+
+/**
+ * wma_wow_ipv6_mcast_stats() - ipv6 mcast wake up stats
+ * @wma: Pointer to wma handle
+ * @data: Pointer to pattern match data
+ *
+ * Return: none
+ */
+static void wma_wow_ipv6_mcast_stats(tp_wma_handle wma, uint8_t *data)
+{
+	static const uint8_t ipv6_mcast[] = {0x86, 0xDD};
+
+	if (!memcmp(ipv6_mcast, (data + WMA_ETHER_TYPE_OFFSET),
+						sizeof(ipv6_mcast))) {
+		if (WMA_ICMP_V6_HEADER_TYPE ==
+			*(data + WMA_ICMP_V6_HEADER_OFFSET)) {
+			if (WMA_ICMP_V6_RA_TYPE ==
+				*(data + WMA_ICMP_V6_TYPE_OFFSET))
+				wma->wow_ipv6_mcast_ra_stats++;
+			else if (WMA_ICMP_V6_NS_TYPE ==
+				*(data + WMA_ICMP_V6_TYPE_OFFSET))
+				wma->wow_ipv6_mcast_ns_stats++;
+			else if (WMA_ICMP_V6_NA_TYPE ==
+				*(data + WMA_ICMP_V6_TYPE_OFFSET))
+				wma->wow_ipv6_mcast_na_stats++;
+			else
+				WMA_LOGA("ICMP V6 type : 0x%x",
+					*(data + WMA_ICMP_V6_TYPE_OFFSET));
+		} else {
+			WMA_LOGA("ICMP_V6 header 0x%x",
+				*(data + WMA_ICMP_V6_HEADER_OFFSET));
+		}
+	} else {
+		WMA_LOGA("Ethertype x%x:0x%x",
+			*(data + WMA_ETHER_TYPE_OFFSET),
+			*(data + WMA_ETHER_TYPE_OFFSET + 1));
+	}
+
+	return;
+}
+
+/**
+ * wma_wow_wake_up_stats() - maintain wow pattern match wake up stats
+ * @wma: Pointer to wma handle
+ * @data: Pointer to pattern match data
+ * @len: Pattern match data length
+ * @event: Wake up event
+ *
+ * Return: none
+ */
+static void wma_wow_wake_up_stats(tp_wma_handle wma, uint8_t *data,
+	int32_t len, WOW_WAKE_REASON_TYPE event)
+{
+	switch (event) {
+
+	case WOW_REASON_PATTERN_MATCH_FOUND:
+		if (WMA_BCAST_MAC_ADDR == *data) {
+			wma->wow_bcast_wake_up_count++;
+		} else if (WMA_MCAST_IPV4_MAC_ADDR == *data) {
+			wma->wow_ipv4_mcast_wake_up_count++;
+		} else if (WMA_MCAST_IPV6_MAC_ADDR == *data) {
+			wma->wow_ipv6_mcast_wake_up_count++;
+			if (len > WMA_ICMP_V6_TYPE_OFFSET)
+				wma_wow_ipv6_mcast_stats(wma, data);
+			else
+				WMA_LOGA("ICMP_V6 data len %d", len);
+		} else {
+			wma->wow_ucast_wake_up_count++;
+		}
+		break;
+
+	case WOW_REASON_RA_MATCH:
+		wma->wow_ipv6_mcast_ra_stats++;
+		break;
+
+	case WOW_REASON_NLOD:
+		wma->wow_pno_match_wake_up_count++;
+		break;
+
+	case WOW_REASON_NLO_SCAN_COMPLETE:
+		wma->wow_pno_complete_wake_up_count++;
+		break;
+
+	case WOW_REASON_LOW_RSSI:
+		wma->wow_low_rssi_wake_up_count++;
+		break;
+
+	case WOW_REASON_EXTSCAN:
+		wma->wow_gscan_wake_up_count++;
+		break;
+
+	case WOW_REASON_RSSI_BREACH_EVENT:
+		wma->wow_rssi_breach_wake_up_count++;
+		break;
+
+	default:
+		WMA_LOGE("Unknown wake up reason");
+		break;
+	}
+
+	wma_wow_wake_up_stats_display(wma);
+	return;
+}
+
+/**
+ * wma_wow_wakeup_host_event() - wakeup host event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: buffer length
+ *
+ * Handler to catch wow wakeup host event. This event will have
+ * reason why the firmware has woken the host.
+ *
+ * Return: 0 for success or error
+ */
+int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
+			      uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *param_buf;
+	WOW_EVENT_INFO_fixed_param *wake_info;
+#ifdef FEATURE_WLAN_SCAN_PNO
+	struct wma_txrx_node *node;
+#endif /* FEATURE_WLAN_SCAN_PNO */
+	uint32_t wake_lock_duration = 0;
+	uint32_t wow_buf_pkt_len = 0;
+
+	param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid wow wakeup host event buf");
+		return -EINVAL;
+	}
+
+	wake_info = param_buf->fixed_param;
+
+	WMA_LOGA("WOW wakeup host event received (reason: %s(%d)) for vdev %d",
+		 wma_wow_wake_reason_str(wake_info->wake_reason),
+		 wake_info->wake_reason, wake_info->vdev_id);
+
+	cdf_event_set(&wma->wma_resume_event);
+
+	switch (wake_info->wake_reason) {
+	case WOW_REASON_AUTH_REQ_RECV:
+		wake_lock_duration = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT;
+		break;
+
+	case WOW_REASON_ASSOC_REQ_RECV:
+		wake_lock_duration = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION;
+		break;
+
+	case WOW_REASON_DEAUTH_RECVD:
+		wake_lock_duration = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION;
+		break;
+
+	case WOW_REASON_DISASSOC_RECVD:
+		wake_lock_duration = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION;
+		break;
+
+	case WOW_REASON_AP_ASSOC_LOST:
+		wake_lock_duration = WMA_BMISS_EVENT_WAKE_LOCK_DURATION;
+		WMA_LOGA("Beacon miss indication on vdev %x",
+			 wake_info->vdev_id);
+		wma_beacon_miss_handler(wma, wake_info->vdev_id);
+		break;
+#ifdef FEATURE_WLAN_RA_FILTERING
+	case WOW_REASON_RA_MATCH:
+		wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_RA_MATCH);
+		break;
+#endif /* FEATURE_WLAN_RA_FILTERING */
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	case WOW_REASON_HOST_AUTO_SHUTDOWN:
+		wake_lock_duration = WMA_AUTO_SHUTDOWN_WAKE_LOCK_DURATION;
+		WMA_LOGA("Received WOW Auto Shutdown trigger in suspend");
+		if (wma_post_auto_shutdown_msg())
+			return -EINVAL;
+		break;
+#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
+#ifdef FEATURE_WLAN_SCAN_PNO
+	case WOW_REASON_NLOD:
+		wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_NLOD);
+		node = &wma->interfaces[wake_info->vdev_id];
+		if (node) {
+			WMA_LOGD("NLO match happened");
+			node->nlo_match_evt_received = true;
+			cdf_wake_lock_timeout_acquire(&wma->pno_wake_lock,
+					WMA_PNO_MATCH_WAKE_LOCK_TIMEOUT,
+					WIFI_POWER_EVENT_WAKELOCK_PNO);
+		}
+		break;
+#endif /* FEATURE_WLAN_SCAN_PNO */
+
+	case WOW_REASON_CSA_EVENT:
+	{
+		WMI_CSA_HANDLING_EVENTID_param_tlvs param;
+		WMA_LOGD("Host woken up because of CSA IE");
+		param.fixed_param = (wmi_csa_event_fixed_param *)
+				    (((uint8_t *) wake_info)
+				     + sizeof(WOW_EVENT_INFO_fixed_param)
+				     + WOW_CSA_EVENT_OFFSET);
+		wma_csa_offload_handler(handle, (uint8_t *) &param,
+					sizeof(param));
+	}
+	break;
+
+#ifdef FEATURE_WLAN_LPHB
+	case WOW_REASON_WLAN_HB:
+		wma_lphb_handler(wma, (uint8_t *) param_buf->hb_indevt);
+		break;
+#endif /* FEATURE_WLAN_LPHB */
+
+	case WOW_REASON_HTT_EVENT:
+		break;
+	case WOW_REASON_PATTERN_MATCH_FOUND:
+		wma_wow_wake_up_stats_display(wma);
+		WMA_LOGD("Wake up for Rx packet, dump starting from ethernet hdr");
+		if (param_buf->wow_packet_buffer) {
+			/* First 4-bytes of wow_packet_buffer is the length */
+			cdf_mem_copy((uint8_t *) &wow_buf_pkt_len,
+				     param_buf->wow_packet_buffer, 4);
+			wma_wow_wake_up_stats(wma,
+				param_buf->wow_packet_buffer + 4,
+				wow_buf_pkt_len,
+				WOW_REASON_PATTERN_MATCH_FOUND);
+			cdf_trace_hex_dump(CDF_MODULE_ID_WMA,
+					   CDF_TRACE_LEVEL_DEBUG,
+					   param_buf->wow_packet_buffer + 4,
+					   wow_buf_pkt_len);
+		} else {
+			WMA_LOGE("No wow packet buffer present");
+		}
+		break;
+
+	case WOW_REASON_LOW_RSSI:
+	{
+		/* WOW_REASON_LOW_RSSI is used for all roaming events.
+		 * WMI_ROAM_REASON_BETTER_AP, WMI_ROAM_REASON_BMISS,
+		 * WMI_ROAM_REASON_SUITABLE_AP will be handled by
+		 * wma_roam_event_callback().
+		 */
+		WMI_ROAM_EVENTID_param_tlvs param;
+		wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_LOW_RSSI);
+		if (param_buf->wow_packet_buffer) {
+			/* Roam event is embedded in wow_packet_buffer */
+			WMA_LOGD("Host woken up because of roam event");
+			cdf_mem_copy((uint8_t *) &wow_buf_pkt_len,
+				     param_buf->wow_packet_buffer, 4);
+			WMA_LOGD("wow_packet_buffer dump");
+			cdf_trace_hex_dump(CDF_MODULE_ID_WMA,
+					   CDF_TRACE_LEVEL_DEBUG,
+					   param_buf->wow_packet_buffer,
+					   wow_buf_pkt_len);
+			if (wow_buf_pkt_len >= sizeof(param)) {
+				param.fixed_param =
+					(wmi_roam_event_fixed_param *)
+					(param_buf->wow_packet_buffer + 4);
+				wma_roam_event_callback(handle,
+							(uint8_t *) &
+							param,
+							sizeof(param));
+			} else {
+				WMA_LOGE("Wrong length for roam event = %d bytes",
+					wow_buf_pkt_len);
+			}
+		} else {
+			/* No wow_packet_buffer means a better AP beacon
+			 * will follow in a later event.
+			 */
+			WMA_LOGD("Host woken up because of better AP beacon");
+		}
+		break;
+	}
+	case WOW_REASON_CLIENT_KICKOUT_EVENT:
+		{
+		WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs param;
+		if (param_buf->wow_packet_buffer) {
+		    /* station kickout event embedded in wow_packet_buffer */
+		    WMA_LOGD("Host woken up because of sta_kickout event");
+		    cdf_mem_copy((u_int8_t *) &wow_buf_pkt_len,
+				param_buf->wow_packet_buffer, 4);
+		    WMA_LOGD("wow_packet_buffer dump");
+				cdf_trace_hex_dump(CDF_MODULE_ID_WMA,
+				CDF_TRACE_LEVEL_DEBUG,
+				param_buf->wow_packet_buffer, wow_buf_pkt_len);
+		    if (wow_buf_pkt_len >= sizeof(param)) {
+			param.fixed_param = (wmi_peer_sta_kickout_event_fixed_param *)
+					(param_buf->wow_packet_buffer + 4);
+			wma_peer_sta_kickout_event_handler(handle,
+					(u_int8_t *)&param, sizeof(param));
+		    } else {
+			WMA_LOGE("Wrong length for sta_kickout event = %d bytes",
+					wow_buf_pkt_len);
+		    }
+		} else {
+		    WMA_LOGD("No wow_packet_buffer present");
+		}
+		break;
+	}
+#ifdef FEATURE_WLAN_EXTSCAN
+	case WOW_REASON_EXTSCAN:
+		WMA_LOGD("Host woken up because of extscan reason");
+		wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_EXTSCAN);
+		if (param_buf->wow_packet_buffer) {
+			wow_buf_pkt_len =
+				*(uint32_t *)param_buf->wow_packet_buffer;
+			wma_extscan_wow_event_callback(handle,
+				(u_int8_t *)(param_buf->wow_packet_buffer + 4),
+				wow_buf_pkt_len);
+		} else
+			WMA_LOGE("wow_packet_buffer is empty");
+		break;
+#endif
+	case WOW_REASON_RSSI_BREACH_EVENT:
+		{
+			WMI_RSSI_BREACH_EVENTID_param_tlvs param;
+
+			wma_wow_wake_up_stats(wma, NULL, 0,
+				WOW_REASON_RSSI_BREACH_EVENT);
+			WMA_LOGD("Host woken up because of rssi breach reason");
+			/* rssi breach event is embedded in wow_packet_buffer */
+			if (param_buf->wow_packet_buffer) {
+				cdf_mem_copy((u_int8_t *) &wow_buf_pkt_len,
+					param_buf->wow_packet_buffer, 4);
+				if (wow_buf_pkt_len >= sizeof(param)) {
+					param.fixed_param =
+					(wmi_rssi_breach_event_fixed_param *)
+					(param_buf->wow_packet_buffer + 4);
+					wma_rssi_breached_event_handler(handle,
+							(u_int8_t *)&param,
+							sizeof(param));
+				} else {
+					WMA_LOGE("%s: Wrong length: %d bytes",
+						__func__, wow_buf_pkt_len);
+				}
+			} else
+			    WMA_LOGD("No wow_packet_buffer present");
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (wake_lock_duration) {
+		cdf_wake_lock_timeout_acquire(&wma->wow_wake_lock,
+					      wake_lock_duration,
+					      WIFI_POWER_EVENT_WAKELOCK_WOW);
+		WMA_LOGA("Holding %d msec wake_lock", wake_lock_duration);
+	}
+
+	return 0;
+}
+
+/**
+ * wma_pdev_resume_event_handler() - PDEV resume event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: buffer length
+ *
+ * Return: 0 for success or error
+ */
+int wma_pdev_resume_event_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	WMA_LOGA("Received PDEV resume event");
+
+	cdf_event_set(&wma->wma_resume_event);
+
+	return 0;
+}
+/**
+ * wma_set_wow_bus_suspend() - set suspend flag
+ * @wma: wma handle
+ * @val: value
+ *
+ * Return: none
+ */
+static inline void wma_set_wow_bus_suspend(tp_wma_handle wma, int val)
+{
+
+	cdf_atomic_set(&wma->is_wow_bus_suspended, val);
+}
+
+
+
+/**
+ * wma_add_wow_wakeup_event() -  Configures wow wakeup events.
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ * @enable: enable/disable
+ *
+ * Return: CDF status
+ */
+static CDF_STATUS wma_add_wow_wakeup_event(tp_wma_handle wma,
+					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(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_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;
+	cmd->event_bitmap = bitmap;
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
+	if (ret) {
+		WMA_LOGE("Failed to config wow wakeup event");
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("Wakeup pattern 0x%x %s in fw", bitmap,
+		 enable ? "enabled" : "disabled");
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_send_wow_patterns_to_fw() - Sends WOW patterns to FW.
+ * @wma: wma 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
+ *
+ * Return: CDF status
+ */
+static CDF_STATUS wma_send_wow_patterns_to_fw(tp_wma_handle wma,
+				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)
+{
+	WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
+	WOW_BITMAP_PATTERN_T *bitmap_pattern;
+	struct wma_txrx_node *iface;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int32_t len;
+	int ret;
+
+	iface = &wma->interfaces[vdev_id];
+
+	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(A_UINT32) + WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32);
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_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;
+	/*
+	 * For user configured wow pattern use pattern id sent by HDD
+	 * and for default wow patterns generate pattern id internally
+	 */
+	if (user)
+		cmd->pattern_id = ptrn_id;
+	else
+		cmd->pattern_id = iface->num_wow_default_patterns++;
+
+	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));
+
+	cdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len);
+	cdf_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;
+
+	WMA_LOGI("vdev id : %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);
+
+	WMA_LOGI("Pattern : ");
+	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_INFO,
+		&bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len);
+
+	WMA_LOGI("Mask : ");
+	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_INFO,
+		&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 ra_ratelimit_interval with dummy data as this fix elem */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(A_UINT32));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	*(A_UINT32 *) buf_ptr = 0;
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_WOW_ADD_WAKE_PATTERN_CMDID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to send wow ptrn to fw", __func__);
+		wmi_buf_free(buf);
+		if (!user)
+			iface->num_wow_default_patterns--;
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (user)
+		iface->num_wow_user_patterns++;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_wow_ap() - set WOW patterns in ap mode
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Configures default WOW pattern for the given vdev_id which is in AP mode.
+ *
+ * Return: CDF status
+ */
+static CDF_STATUS wma_wow_ap(tp_wma_handle wma, uint8_t vdev_id)
+{
+	CDF_STATUS ret;
+	uint8_t arp_offset = 20;
+	uint8_t mac_mask[IEEE80211_ADDR_LEN];
+
+	/* Setup unicast pkt pattern */
+	cdf_mem_set(&mac_mask, IEEE80211_ADDR_LEN, 0xFF);
+	ret = wma_send_wow_patterns_to_fw(wma, vdev_id, 0,
+				wma->interfaces[vdev_id].addr,
+				IEEE80211_ADDR_LEN, 0, mac_mask,
+				IEEE80211_ADDR_LEN, false);
+	if (ret != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to add WOW unicast pattern ret %d", ret);
+		return ret;
+	}
+
+	/*
+	 * Setup all ARP pkt pattern. This is dummy pattern hence the length
+	 * is zero
+	 */
+	ret = wma_send_wow_patterns_to_fw(wma, vdev_id, 0,
+			arp_ptrn, 0, arp_offset, arp_mask, 0, false);
+	if (ret != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to add WOW ARP pattern ret %d", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+/**
+ * wma_wow_sta() - set WOW patterns in sta mode
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Configures default WOW pattern for the given vdev_id which is in sta mode.
+ *
+ * Return: CDF status
+ */
+static CDF_STATUS wma_wow_sta(tp_wma_handle wma, uint8_t vdev_id)
+{
+	uint8_t arp_offset = 12;
+	uint8_t discvr_offset = 30;
+	uint8_t mac_mask[IEEE80211_ADDR_LEN];
+	CDF_STATUS ret = CDF_STATUS_SUCCESS;
+
+	/* Setup unicast pkt pattern */
+	cdf_mem_set(&mac_mask, IEEE80211_ADDR_LEN, 0xFF);
+	ret = wma_send_wow_patterns_to_fw(wma, vdev_id, 0,
+				wma->interfaces[vdev_id].addr,
+				IEEE80211_ADDR_LEN, 0, mac_mask,
+				IEEE80211_ADDR_LEN, false);
+	if (ret != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to add WOW unicast pattern ret %d", ret);
+		return ret;
+	}
+
+	/*
+	 * Setup multicast pattern for mDNS 224.0.0.251,
+	 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
+	 */
+	if (wma->ssdp) {
+		ret = wma_send_wow_patterns_to_fw(wma, vdev_id, 0,
+				discvr_ptrn, sizeof(discvr_ptrn), discvr_offset,
+				discvr_mask, sizeof(discvr_ptrn), false);
+		if (ret != CDF_STATUS_SUCCESS) {
+			WMA_LOGE("Failed to add WOW mDNS/SSDP/LLMNR pattern");
+			return ret;
+		}
+	} else
+		WMA_LOGD("mDNS, SSDP, LLMNR patterns are disabled from ini");
+
+	/* when arp offload or ns offloaded is disabled
+	 * from ini file, configure broad cast arp pattern
+	 * to fw, so that host can wake up
+	 */
+	if (!(wma->ol_ini_info & 0x1)) {
+		/* Setup all ARP pkt pattern */
+		ret = wma_send_wow_patterns_to_fw(wma, vdev_id, 0,
+				arp_ptrn, sizeof(arp_ptrn), arp_offset,
+				arp_mask, sizeof(arp_mask), false);
+		if (ret != CDF_STATUS_SUCCESS) {
+			WMA_LOGE("Failed to add WOW ARP pattern");
+			return ret;
+		}
+	}
+
+	/* for NS or NDP offload packets */
+	if (!(wma->ol_ini_info & 0x2)) {
+		/* Setup all NS pkt pattern */
+		ret = wma_send_wow_patterns_to_fw(wma, vdev_id, 0,
+				ns_ptrn, sizeof(arp_ptrn), arp_offset,
+				arp_mask, sizeof(arp_mask), false);
+		if (ret != CDF_STATUS_SUCCESS) {
+			WMA_LOGE("Failed to add WOW NS pattern");
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * wma_register_wow_default_patterns() - register default wow patterns with fw
+ * @handle: Pointer to wma handle
+ * @vdev_id: vdev id
+ *
+ * WoW default wake up pattern rule is:
+ *  - For STA & P2P CLI mode register for same STA specific wow patterns
+ *  - For SAP/P2P GO & IBSS mode register for same SAP specific wow patterns
+ *
+ * Return: none
+ */
+void wma_register_wow_default_patterns(WMA_HANDLE handle, uint8_t vdev_id)
+{
+	tp_wma_handle wma = handle;
+	struct wma_txrx_node *iface;
+
+	if (vdev_id > wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id %d", vdev_id);
+		return;
+	}
+	iface = &wma->interfaces[vdev_id];
+
+	if (iface->ptrn_match_enable) {
+		if (wma_is_vdev_in_ap_mode(wma, vdev_id)
+#ifdef QCA_IBSS_SUPPORT
+			||
+			wma_is_vdev_in_ibss_mode(wma, vdev_id)
+#endif
+			) {
+			/* Configure SAP/GO/IBSS mode default wow patterns */
+			WMA_LOGI("Config SAP specific default wow patterns vdev_id %d",
+				 vdev_id);
+			wma_wow_ap(wma, vdev_id);
+		} else {
+			/* Configure STA/P2P CLI mode default wow patterns */
+			WMA_LOGI("Config STA specific default wow patterns vdev_id %d",
+				vdev_id);
+			wma_wow_sta(wma, vdev_id);
+			if (wma->IsRArateLimitEnabled) {
+				WMA_LOGI("Config STA RA limit wow patterns vdev_id %d",
+					vdev_id);
+				wma_wow_sta_ra_filter(wma, vdev_id);
+			}
+		}
+	}
+
+	return;
+}
+
+/**
+ * wma_register_wow_wakeup_events() - register vdev specific wake events with fw
+ * @handle: Pointer to wma handle
+ * @vdev_id: vdev Id
+ * @vdev_type: vdev type
+ * @vdev_subtype: vdev sub type
+ *
+ * WoW wake up event rule is following:
+ * 1) STA mode and P2P CLI mode wake up events are same
+ * 2) SAP mode and P2P GO mode wake up events are same
+ * 3) IBSS mode wake events are same as STA mode plus WOW_BEACON_EVENT
+ *
+ * Return: none
+ */
+void wma_register_wow_wakeup_events(WMA_HANDLE handle,
+				uint8_t vdev_id,
+				uint8_t vdev_type,
+				uint8_t vdev_subtype)
+{
+	tp_wma_handle wma = handle;
+	uint32_t event_bitmap;
+
+	WMA_LOGI("vdev_type %d vdev_subtype %d vdev_id %d", vdev_type,
+			vdev_subtype, vdev_id);
+
+	if ((WMI_VDEV_TYPE_STA == vdev_type) ||
+		((WMI_VDEV_TYPE_AP == vdev_type) &&
+		 (WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE == vdev_subtype))) {
+		/* Configure STA/P2P CLI mode specific default wake up events */
+		event_bitmap = WMA_WOW_STA_WAKE_UP_EVENTS;
+		WMA_LOGI("STA specific default wake up event 0x%x vdev id %d",
+			event_bitmap, vdev_id);
+	} else if (WMI_VDEV_TYPE_IBSS == vdev_type) {
+		/* Configure IBSS mode specific default wake up events */
+		event_bitmap = (WMA_WOW_STA_WAKE_UP_EVENTS |
+				(1 << WOW_BEACON_EVENT));
+		WMA_LOGI("IBSS specific default wake up event 0x%x vdev id %d",
+			event_bitmap, vdev_id);
+	} else if (WMI_VDEV_TYPE_AP == vdev_type) {
+		/* Configure SAP/GO mode specific default wake up events */
+		event_bitmap = WMA_WOW_SAP_WAKE_UP_EVENTS;
+		WMA_LOGI("SAP specific default wake up event 0x%x vdev id %d",
+			event_bitmap, vdev_id);
+	} else {
+		WMA_LOGE("unknown type %d subtype %d", vdev_type, vdev_subtype);
+		return;
+	}
+
+	wma_add_wow_wakeup_event(wma, vdev_id, event_bitmap, true);
+
+	return;
+}
+
+/**
+ * wma_enable_disable_wakeup_event() -  Configures wow wakeup events
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ * @enable: enable/disable
+ *
+ * Return: none
+ */
+void wma_enable_disable_wakeup_event(WMA_HANDLE handle,
+				uint32_t vdev_id,
+				uint32_t bitmap,
+				bool enable)
+{
+	tp_wma_handle wma = handle;
+
+	WMA_LOGI("vdev_id %d wake up event 0x%x enable %d",
+		vdev_id, bitmap, enable);
+	wma_add_wow_wakeup_event(wma, vdev_id, bitmap, enable);
+}
+
+/**
+ * wma_enable_wow_in_fw() - wnable wow in fw
+ * @wma: wma handle
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle)
+{
+	tp_wma_handle wma = handle;
+	wmi_wow_enable_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	int ret;
+	struct ol_softc *scn;
+	int host_credits;
+	int wmi_pending_cmds;
+#ifdef CONFIG_CNSS
+	tpAniSirGlobal pMac = cds_get_context(CDF_MODULE_ID_PE);
+
+	if (NULL == pMac) {
+		WMA_LOGE("%s: Unable to get PE context", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+#endif /* CONFIG_CNSS */
+
+	len = sizeof(wmi_wow_enable_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_wow_enable_cmd_fixed_param));
+	cmd->enable = true;
+	if (hif_can_suspend_link())
+		cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED;
+	else
+		cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED;
+
+	WMA_LOGI("suspend type: %s",
+		cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ?
+		"WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED");
+
+	cdf_event_reset(&wma->target_suspend);
+	wma->wow_nack = 0;
+
+	host_credits = wmi_get_host_credits(wma->wmi_handle);
+	wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle);
+
+	WMA_LOGD("Credits:%d; Pending_Cmds: %d",
+		 host_credits, wmi_pending_cmds);
+
+	if (host_credits < WMI_WOW_REQUIRED_CREDITS) {
+		WMA_LOGE("%s: Host Doesn't have enough credits to Post WMI_WOW_ENABLE_CMDID! "
+			"Credits:%d, pending_cmds:%d\n", __func__, host_credits,
+			wmi_pending_cmds);
+#ifndef QCA_WIFI_3_0_EMU
+		goto error;
+#endif
+	}
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_WOW_ENABLE_CMDID);
+	if (ret) {
+		WMA_LOGE("Failed to enable wow in fw");
+		goto error;
+	}
+
+	wmi_set_target_suspend(wma->wmi_handle, true);
+
+	if (cdf_wait_single_event(&wma->target_suspend,
+				  WMA_TGT_SUSPEND_COMPLETE_TIMEOUT)
+	    != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to receive WoW Enable Ack from FW");
+		WMA_LOGE("Credits:%d; Pending_Cmds: %d",
+			 wmi_get_host_credits(wma->wmi_handle),
+			 wmi_get_pending_cmds(wma->wmi_handle));
+#ifdef CONFIG_CNSS
+		if (pMac->sme.enableSelfRecovery) {
+			cds_trigger_recovery();
+		} else {
+			CDF_BUG(0);
+		}
+#else
+		CDF_BUG(0);
+#endif /* CONFIG_CNSS */
+		wmi_set_target_suspend(wma->wmi_handle, false);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (wma->wow_nack) {
+		WMA_LOGE("FW not ready to WOW");
+		wmi_set_target_suspend(wma->wmi_handle, false);
+		return CDF_STATUS_E_AGAIN;
+	}
+
+	host_credits = wmi_get_host_credits(wma->wmi_handle);
+	wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle);
+
+	if (host_credits < WMI_WOW_REQUIRED_CREDITS) {
+		WMA_LOGE("%s: No Credits after HTC ACK:%d, pending_cmds:%d, "
+			 "cannot resume back", __func__, host_credits,
+			 wmi_pending_cmds);
+		htc_dump_counter_info(wma->htc_handle);
+		if (!cds_is_logp_in_progress())
+			CDF_BUG(0);
+		else
+			WMA_LOGE("%s: SSR in progress, ignore no credit issue",
+				 __func__);
+	}
+
+	WMA_LOGD("WOW enabled successfully in fw: credits:%d"
+		 "pending_cmds: %d", host_credits, wmi_pending_cmds);
+
+	scn = cds_get_context(CDF_MODULE_ID_HIF);
+
+	if (scn == NULL) {
+		WMA_LOGE("%s: Failed to get HIF context", __func__);
+		CDF_ASSERT(0);
+		return CDF_STATUS_E_FAULT;
+	}
+
+	htc_cancel_deferred_target_sleep(scn);
+
+	wma->wow.wow_enable_cmd_sent = true;
+
+	return CDF_STATUS_SUCCESS;
+
+error:
+	wmi_buf_free(buf);
+	return CDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wma_resume_req() - clear configured wow patterns in fw
+ * @wma: wma handle
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_resume_req(tp_wma_handle wma)
+{
+	wma->no_of_resume_ind++;
+
+	if (wma->no_of_resume_ind < wma_get_vdev_count(wma))
+		return CDF_STATUS_SUCCESS;
+
+	wma->no_of_resume_ind = 0;
+
+	/* Reset the DTIM Parameters */
+	wma_set_resume_dtim(wma);
+	/* need to reset if hif_pci_suspend_fails */
+	wma_set_wow_bus_suspend(wma, 0);
+	/* unpause the vdev if left paused and hif_pci_suspend fails */
+	wma_unpause_vdev(wma);
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_wow_delete_pattern() - delete wow pattern in target
+ * @wma: wma handle
+ * @ptrn_id: pattern id
+ * @vdev_id: vdev id
+ * @user: true for user pattern and false for default pattern
+ *
+ * Return: CDF status
+ */
+static CDF_STATUS wma_wow_delete_pattern(tp_wma_handle wma, uint8_t ptrn_id,
+					uint8_t vdev_id, bool user)
+{
+	WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd;
+	struct wma_txrx_node *iface;
+	wmi_buf_t buf;
+	int32_t len;
+	int ret;
+
+	len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param);
+
+	iface = &wma->interfaces[vdev_id];
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_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;
+
+	WMA_LOGI("Deleting pattern id: %d vdev id %d in fw",
+		cmd->pattern_id, vdev_id);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_WOW_DEL_WAKE_PATTERN_CMDID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to delete wow ptrn from fw", __func__);
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (user)
+		iface->num_wow_user_patterns--;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_wow_add_pattern() - add wow pattern in target
+ * @wma: wma handle
+ * @ptrn: wow pattern
+ *
+ * This function does following:
+ * 1) Delete all default patterns of the vdev
+ * 2) Add received wow patterns for given vdev in target.
+ *
+ * Target is responsible for caching wow patterns accross multiple
+ * suspend/resumes until the pattern is deleted by user
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_wow_add_pattern(tp_wma_handle wma, struct wow_add_pattern *ptrn)
+{
+	uint8_t id;
+	uint8_t bit_to_check, pos;
+	struct wma_txrx_node *iface;
+	CDF_STATUS ret = CDF_STATUS_SUCCESS;
+	uint8_t new_mask[SIR_WOWL_BCAST_PATTERN_MAX_SIZE];
+
+	if (ptrn->session_id > wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id (%d)", ptrn->session_id);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	iface = &wma->interfaces[ptrn->session_id];
+
+	/* clear all default patterns cofigured by wma */
+	for (id = 0; id < iface->num_wow_default_patterns; id++)
+		wma_wow_delete_pattern(wma, id, ptrn->session_id, false);
+
+	iface->num_wow_default_patterns = 0;
+
+	WMA_LOGI("Add user passed wow pattern id %d vdev id %d",
+		ptrn->pattern_id, ptrn->session_id);
+	/*
+	 * Convert received pattern mask value from bit representation
+	 * to byte representation.
+	 *
+	 * For example, received value from umac,
+	 *
+	 *      Mask value    : A1 (equivalent binary is "1010 0001")
+	 *      Pattern value : 12:00:13:00:00:00:00:44
+	 *
+	 * The value which goes to FW after the conversion from this
+	 * function (1 in mask value will become FF and 0 will
+	 * become 00),
+	 *
+	 *      Mask value    : FF:00:FF:00:0:00:00:FF
+	 *      Pattern value : 12:00:13:00:00:00:00:44
+	 */
+	cdf_mem_zero(new_mask, sizeof(new_mask));
+	for (pos = 0; pos < ptrn->pattern_size; pos++) {
+		bit_to_check = (WMA_NUM_BITS_IN_BYTE - 1) -
+			       (pos % WMA_NUM_BITS_IN_BYTE);
+		bit_to_check = 0x1 << bit_to_check;
+		if (ptrn->pattern_mask[pos / WMA_NUM_BITS_IN_BYTE] &
+							bit_to_check)
+			new_mask[pos] = WMA_WOW_PTRN_MASK_VALID;
+	}
+
+	ret = wma_send_wow_patterns_to_fw(wma, ptrn->session_id,
+			ptrn->pattern_id,
+			ptrn->pattern, ptrn->pattern_size,
+			ptrn->pattern_byte_offset, new_mask,
+			ptrn->pattern_size, true);
+	if (ret != CDF_STATUS_SUCCESS)
+		WMA_LOGE("Failed to add wow pattern %d", ptrn->pattern_id);
+
+	return ret;
+}
+
+/**
+ * wma_wow_delete_user_pattern() - delete user configured wow pattern in target
+ * @wma: wma handle
+ * @ptrn: wow pattern
+ *
+ * This function does following:
+ * 1) Deletes a particular user configured wow pattern in target
+ * 2) After deleting all user wow patterns add default wow patterns
+ *    specific to that vdev.
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_wow_delete_user_pattern(tp_wma_handle wma,
+					struct wow_delete_pattern *pattern)
+{
+	struct wma_txrx_node *iface;
+
+	if (pattern->session_id > wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id %d", pattern->session_id);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	iface = &wma->interfaces[pattern->session_id];
+	if (iface->num_wow_user_patterns <= 0) {
+		WMA_LOGE("No valid user pattern. Num user pattern %u vdev %d",
+			iface->num_wow_user_patterns, pattern->session_id);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	WMA_LOGI("Delete user passed wow pattern id %d total user pattern %d",
+		pattern->pattern_id, iface->num_wow_user_patterns);
+
+	wma_wow_delete_pattern(wma, pattern->pattern_id,
+				pattern->session_id, true);
+
+	/* configure default patterns once all user patterns are deleted */
+	if (!iface->num_wow_user_patterns)
+		wma_register_wow_default_patterns(wma, pattern->session_id);
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_wow_enter() - store enable/disable status for pattern
+ * @wma: wma handle
+ * @info: wow parameters
+ *
+ * Records pattern enable/disable status locally. This choice will
+ * take effect when the driver enter into suspend state.
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_wow_enter(tp_wma_handle wma, tpSirHalWowlEnterParams info)
+{
+	struct wma_txrx_node *iface;
+
+	WMA_LOGD("wow enable req received for vdev id: %d", info->sessionId);
+
+	if (info->sessionId > wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id (%d)", info->sessionId);
+		cdf_mem_free(info);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	iface = &wma->interfaces[info->sessionId];
+	iface->ptrn_match_enable = info->ucPatternFilteringEnable ?
+				   true : false;
+	wma->wow.magic_ptrn_enable = info->ucMagicPktEnable ? true : false;
+	wma->wow.deauth_enable = info->ucWowDeauthRcv ? true : false;
+	wma->wow.disassoc_enable = info->ucWowDeauthRcv ? true : false;
+	wma->wow.bmiss_enable = info->ucWowMaxMissedBeacons ? true : false;
+
+	cdf_mem_free(info);
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_wow_exit() - clear all wma states
+ * @wma: wma handle
+ * @info: wow params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_wow_exit(tp_wma_handle wma, tpSirHalWowlExitParams info)
+{
+	struct wma_txrx_node *iface;
+
+	WMA_LOGD("wow disable req received for vdev id: %d", info->sessionId);
+
+	if (info->sessionId > wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id (%d)", info->sessionId);
+		cdf_mem_free(info);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	iface = &wma->interfaces[info->sessionId];
+	iface->ptrn_match_enable = false;
+	wma->wow.magic_ptrn_enable = false;
+	cdf_mem_free(info);
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_suspend_req() -  Handles suspend indication request received from umac.
+ * @wma: wma handle
+ * @info: suspend params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_suspend_req(tp_wma_handle wma, tpSirWlanSuspendParam info)
+{
+	struct wma_txrx_node *iface;
+	bool connected = false, pno_in_progress = false;
+	uint8_t i;
+	bool extscan_in_progress = false;
+
+	wma->no_of_suspend_ind++;
+
+	if (info->sessionId > wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id (%d)", info->sessionId);
+		cdf_mem_free(info);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	iface = &wma->interfaces[info->sessionId];
+	if (!iface) {
+		WMA_LOGD("vdev %d node is not found", info->sessionId);
+		cdf_mem_free(info);
+		return CDF_STATUS_SUCCESS;
+	}
+
+	if (!wma->wow.magic_ptrn_enable && !iface->ptrn_match_enable) {
+		cdf_mem_free(info);
+
+		if (wma->no_of_suspend_ind == wma_get_vdev_count(wma)) {
+			WMA_LOGD("Both magic and pattern byte match are disabled");
+			wma->no_of_suspend_ind = 0;
+			goto send_ready_to_suspend;
+		}
+
+		return CDF_STATUS_SUCCESS;
+	}
+
+	iface->conn_state = (info->connectedState) ? true : false;
+
+	/*
+	 * Once WOW is enabled in FW, host can't send anymore
+	 * data to fw. umac sends suspend indication on each
+	 * vdev during platform suspend. WMA has to wait until
+	 * suspend indication received on last vdev before
+	 * enabling wow in fw.
+	 */
+	if (wma->no_of_suspend_ind < wma_get_vdev_count(wma)) {
+		cdf_mem_free(info);
+		return CDF_STATUS_SUCCESS;
+	}
+
+	wma->no_of_suspend_ind = 0;
+	wma->wow.gtk_pdev_enable = 0;
+	/*
+	 * Enable WOW if any one of the condition meets,
+	 *  1) Is any one of vdev in beaconning mode (in AP mode) ?
+	 *  2) Is any one of vdev in connected state (in STA mode) ?
+	 *  3) Is PNO in progress in any one of vdev ?
+	 *  4) Is Extscan in progress in any one of vdev ?
+	 */
+	for (i = 0; i < wma->max_bssid; i++) {
+		if ((wma_is_vdev_in_ap_mode(wma, i)
+#ifdef QCA_IBSS_SUPPORT
+		     || wma_is_vdev_in_ibss_mode(wma, i)
+#endif /* QCA_IBSS_SUPPORT */
+		     ) && wma->interfaces[i].vdev_up &&
+		    WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+					   WMI_SERVICE_BEACON_OFFLOAD)) {
+			WMA_LOGD("vdev %d is in beaconning mode, enabling wow",
+				 i);
+			goto enable_wow;
+		}
+	}
+	for (i = 0; i < wma->max_bssid; i++) {
+		if (wma->interfaces[i].conn_state) {
+			connected = true;
+			break;
+		}
+#ifdef FEATURE_WLAN_SCAN_PNO
+		if (wma->interfaces[i].pno_in_progress) {
+			WMA_LOGD("PNO is in progress, enabling wow");
+			pno_in_progress = true;
+			break;
+		}
+#endif /* FEATURE_WLAN_SCAN_PNO */
+#ifdef FEATURE_WLAN_EXTSCAN
+		if (wma->interfaces[i].extscan_in_progress) {
+			WMA_LOGD("Extscan is in progress, enabling wow");
+			extscan_in_progress = true;
+			break;
+		}
+#endif
+	}
+	for (i = 0; i < wma->max_bssid; i++) {
+		wma->wow.gtk_pdev_enable |= wma->wow.gtk_err_enable[i];
+		WMA_LOGD("VDEV_ID:%d, gtk_err_enable[%d]:%d, gtk_pdev_enable:%d", i,
+			i, wma->wow.gtk_err_enable[i], wma->wow.gtk_pdev_enable);
+	}
+
+	if (!connected && !pno_in_progress && !extscan_in_progress) {
+		WMA_LOGD("All vdev are in disconnected state and pno/extscan is not in progress, skipping wow");
+		cdf_mem_free(info);
+		goto send_ready_to_suspend;
+	}
+
+enable_wow:
+	WMA_LOGE("WOW Suspend");
+
+	/*
+	 * At this point, suspend indication is received on
+	 * last vdev. It's the time to enable wow in fw.
+	 */
+#ifdef FEATURE_WLAN_LPHB
+	/* LPHB cache, if any item was enabled, should be
+	 * applied.
+	 */
+	WMA_LOGD("%s: checking LPHB cache", __func__);
+	for (i = 0; i < 2; i++) {
+		if (wma->wow.lphb_cache[i].params.lphbEnableReq.enable) {
+			WMA_LOGD("%s: LPHB cache for item %d is marked as enable",
+				__func__, i + 1);
+			wma_lphb_conf_hbenable(wma, &(wma->wow.lphb_cache[i]),
+					       false);
+		}
+	}
+#endif /* FEATURE_WLAN_LPHB */
+
+	wma->wow.wow_enable = true;
+	wma->wow.wow_enable_cmd_sent = false;
+
+	cdf_mem_free(info);
+
+send_ready_to_suspend:
+	/* Set the Suspend DTIM Parameters */
+	wma_set_suspend_dtim(wma);
+	wma_send_status_to_suspend_ind(wma, true);
+
+	/* to handle race between hif_pci_suspend and
+	 * unpause/pause tx handler
+	 */
+	wma_set_wow_bus_suspend(wma, 1);
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_send_host_wakeup_ind_to_fw() - send wakeup ind to fw
+ * @wma: wma handle
+ *
+ * Sends host wakeup indication to FW. On receiving this indication,
+ * FW will come out of WOW.
+ *
+ * Return: CDF status
+ */
+static CDF_STATUS wma_send_host_wakeup_ind_to_fw(tp_wma_handle wma)
+{
+	wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	int32_t len;
+	int ret;
+#ifdef CONFIG_CNSS
+	tpAniSirGlobal pMac = cds_get_context(CDF_MODULE_ID_PE);
+	if (NULL == pMac) {
+		WMA_LOGE("%s: Unable to get PE context", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+#endif /* CONFIG_CNSS */
+
+	len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param);
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_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));
+
+	cdf_event_reset(&wma->wma_resume_event);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
+	if (ret) {
+		WMA_LOGE("Failed to send host wakeup indication to fw");
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("Host wakeup indication sent to fw");
+
+	cdf_status = cdf_wait_single_event(&(wma->wma_resume_event),
+					   WMA_RESUME_TIMEOUT);
+	if (CDF_STATUS_SUCCESS != cdf_status) {
+		WMA_LOGP("%s: Timeout waiting for resume event from FW",
+			 __func__);
+		WMA_LOGP("%s: Pending commands %d credits %d", __func__,
+			 wmi_get_pending_cmds(wma->wmi_handle),
+			 wmi_get_host_credits(wma->wmi_handle));
+		if (!cds_is_logp_in_progress()) {
+#ifdef CONFIG_CNSS
+			if (pMac->sme.enableSelfRecovery) {
+				cds_trigger_recovery();
+			} else {
+				CDF_BUG(0);
+			}
+#else
+			CDF_BUG(0);
+#endif /* CONFIG_CNSS */
+		} else {
+			WMA_LOGE("%s: SSR in progress, ignore resume timeout",
+				 __func__);
+		}
+	} else {
+		WMA_LOGD("Host wakeup received");
+	}
+
+	if (CDF_STATUS_SUCCESS == cdf_status)
+		wmi_set_target_suspend(wma->wmi_handle, false);
+
+	return cdf_status;
+}
+
+/**
+ * wma_disable_wow_in_fw() -  Disable wow in PCIe resume context.
+ * @handle: wma handle
+ *
+ * Return: 0 for success or error code
+ */
+CDF_STATUS wma_disable_wow_in_fw(WMA_HANDLE handle)
+{
+	tp_wma_handle wma = handle;
+	CDF_STATUS ret;
+
+	if (!wma->wow.wow_enable || !wma->wow.wow_enable_cmd_sent)
+		return CDF_STATUS_SUCCESS;
+
+	ret = wma_send_host_wakeup_ind_to_fw(wma);
+
+	if (ret != CDF_STATUS_SUCCESS)
+		return ret;
+
+	wma->wow.wow_enable = false;
+	wma->wow.wow_enable_cmd_sent = false;
+
+	/* To allow the tx pause/unpause events */
+	wma_set_wow_bus_suspend(wma, 0);
+	/* Unpause the vdev as we are resuming */
+	wma_unpause_vdev(wma);
+
+	return ret;
+}
+
+#ifdef WLAN_FEATURE_LPSS
+/**
+ * wma_is_lpass_enabled() - check if lpass is enabled
+ * @handle: Pointer to wma handle
+ *
+ * WoW is needed if LPASS or NaN feature is enabled in INI because
+ * target can't wake up itself if its put in PDEV suspend when LPASS
+ * or NaN features are supported
+ *
+ * Return: true if lpass is enabled else false
+ */
+bool static wma_is_lpass_enabled(tp_wma_handle wma)
+{
+	if (wma->is_lpass_enabled)
+		return true;
+	else
+		return false;
+}
+#else
+bool static wma_is_lpass_enabled(tp_wma_handle wma)
+{
+	return false;
+}
+#endif
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * wma_is_nan_enabled() - check if NaN is enabled
+ * @handle: Pointer to wma handle
+ *
+ * WoW is needed if LPASS or NaN feature is enabled in INI because
+ * target can't wake up itself if its put in PDEV suspend when LPASS
+ * or NaN features are supported
+ *
+ * Return: true if NaN is enabled else false
+ */
+bool static wma_is_nan_enabled(tp_wma_handle wma)
+{
+	if (wma->is_nan_enabled)
+		return true;
+	else
+		return false;
+}
+#else
+bool static wma_is_nan_enabled(tp_wma_handle wma)
+{
+	return false;
+}
+#endif
+
+/**
+ * wma_is_wow_mode_selected() - check if wow needs to be enabled in fw
+ * @handle: Pointer to wma handle
+ *
+ * If lpass is enabled then always do wow else check wow_enable config
+ *
+ * Return: true is wow mode is needed else false
+ */
+int wma_is_wow_mode_selected(WMA_HANDLE handle)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	if (wma_is_lpass_enabled(wma)) {
+		WMA_LOGD("LPASS is enabled select WoW");
+		return true;
+	} else if (wma_is_nan_enabled(wma)) {
+		WMA_LOGD("NAN is enabled select WoW");
+		return true;
+	} else {
+		WMA_LOGD("WoW enable %d", wma->wow.wow_enable);
+		return wma->wow.wow_enable;
+	}
+}
+
+/**
+ * wma_del_ts_req() - send DELTS request to fw
+ * @wma: wma handle
+ * @msg: delts params
+ *
+ * Return: none
+ */
+void wma_del_ts_req(tp_wma_handle wma, tDelTsParams *msg)
+{
+	wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
+		goto err;
+	}
+	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 = msg->sessionId;
+	cmd->ac = TID_TO_WME_AC(msg->userPrio);
+
+	WMA_LOGD("Delts vdev:%d, ac:%d, %s:%d",
+		 cmd->vdev_id, cmd->ac, __FUNCTION__, __LINE__);
+	if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				 WMI_VDEV_WMM_DELTS_CMDID)) {
+		WMA_LOGP("%s: Failed to send vdev DELTS command", __func__);
+		cdf_nbuf_free(buf);
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (msg->setRICparams == true)
+		wma_set_ric_req(wma, msg, false);
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+err:
+	cdf_mem_free(msg);
+}
+
+/**
+ * wma_aggr_qos_req() - send aggr qos request to fw
+ * @wma: handle to wma
+ * @pAggrQosRspMsg - combined struct for all ADD_TS requests.
+ *
+ * A function to handle WMA_AGGR_QOS_REQ. This will send out
+ * ADD_TS requestes to firmware in loop for all the ACs with
+ * active flow.
+ *
+ * Return: none
+ */
+void wma_aggr_qos_req(tp_wma_handle wma,
+		      tAggrAddTsParams *pAggrQosRspMsg)
+{
+	int i = 0;
+	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+	for (i = 0; i < HAL_QOS_NUM_AC_MAX; i++) {
+		/* if flow in this AC is active */
+		if (((1 << i) & pAggrQosRspMsg->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
+			 */
+			pAggrQosRspMsg->status[i] = CDF_STATUS_SUCCESS;
+
+			buf = wmi_buf_alloc(wma->wmi_handle, len);
+			if (!buf) {
+				WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
+				goto aggr_qos_exit;
+			}
+			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 = pAggrQosRspMsg->sessionId;
+			cmd->ac =
+				TID_TO_WME_AC(pAggrQosRspMsg->tspec[i].tsinfo.
+					      traffic.userPrio);
+			cmd->medium_time_us =
+				pAggrQosRspMsg->tspec[i].mediumTime * 32;
+			cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
+			WMA_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);
+			if (wmi_unified_cmd_send
+				    (wma->wmi_handle, buf, len,
+				    WMI_VDEV_WMM_ADDTS_CMDID)) {
+				WMA_LOGP("%s: Failed to send vdev ADDTS command",
+					__func__);
+				pAggrQosRspMsg->status[i] =
+					CDF_STATUS_E_FAILURE;
+				cdf_nbuf_free(buf);
+			}
+		}
+	}
+
+aggr_qos_exit:
+	/* send reponse to upper layers from here only. */
+	wma_send_msg(wma, WMA_AGGR_QOS_RSP, pAggrQosRspMsg, 0);
+}
+
+/**
+ * wma_add_ts_req() - send ADDTS request to fw
+ * @wma: wma handle
+ * @msg: ADDTS params
+ *
+ * Return: none
+ */
+void wma_add_ts_req(tp_wma_handle wma, tAddTsParams *msg)
+{
+	wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len = sizeof(*cmd);
+
+#ifdef FEATURE_WLAN_ESE
+	/*
+	 * msmt_interval is in unit called TU (1 TU = 1024 us)
+	 * max value of msmt_interval cannot make resulting
+	 * interval_miliseconds overflow 32 bit
+	 */
+	uint32_t intervalMiliseconds;
+	ol_txrx_pdev_handle pdev = cds_get_context(CDF_MODULE_ID_TXRX);
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		goto err;
+	}
+
+	intervalMiliseconds = (msg->tsm_interval * 1024) / 1000;
+
+	ol_tx_set_compute_interval(pdev, intervalMiliseconds);
+#endif /* FEATURE_WLAN_ESE */
+	msg->status = CDF_STATUS_SUCCESS;
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
+		goto err;
+	}
+	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 = TID_TO_WME_AC(msg->tspec.tsinfo.traffic.userPrio);
+	cmd->medium_time_us = msg->tspec.mediumTime * 32;
+	cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
+	WMA_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__);
+	if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				 WMI_VDEV_WMM_ADDTS_CMDID)) {
+		WMA_LOGP("%s: Failed to send vdev ADDTS command", __func__);
+		msg->status = CDF_STATUS_E_FAILURE;
+		cdf_nbuf_free(buf);
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (msg->setRICparams == true)
+		wma_set_ric_req(wma, msg, true);
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+err:
+	wma_send_msg(wma, WMA_ADD_TS_RSP, msg, 0);
+}
+
+/**
+ * wma_enable_disable_packet_filter() - enable/disable packet filter in target
+ * @wma: Pointer to wma handle
+ * @vdev_id: vdev id
+ * @enable: Flag to enable/disable packet filter
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_enable_disable_packet_filter(tp_wma_handle wma,
+					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(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return -ENOMEM;
+	}
+
+	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;
+
+	WMA_LOGE("%s: Packet filter enable %d for vdev_id %d",
+		__func__, cmd->enable, vdev_id);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+			 WMI_PACKET_FILTER_ENABLE_CMDID);
+	if (ret)
+		WMA_LOGE("Failed to send packet filter wmi cmd to fw");
+
+	return ret;
+}
+
+/**
+ * wma_config_packet_filter() - configure packet filter in target
+ * @wma: Pointer to wma handle
+ * @vdev_id: vdev id
+ * @rcv_filter_param: Packet filter parameters
+ * @filter_id: Filter id
+ * @enable: Flag to add/delete packet filter configuration
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_config_packet_filter(tp_wma_handle wma,
+		uint8_t vdev_id, tSirRcvPktFilterCfgType *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(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("Failed to allocate buffer to send set_param cmd");
+		return -ENOMEM;
+	}
+
+	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 = CDF_MIN(
+					WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER,
+					rcv_filter_param->numFieldParams);
+		cmd->filter_type = rcv_filter_param->filterType;
+		cmd->coalesce_time = rcv_filter_param->coalesceTime;
+
+		for (i = 0; i < cmd->num_params; i++) {
+			cmd->paramsData[i].proto_type =
+				rcv_filter_param->paramsData[i].protocolLayer;
+			cmd->paramsData[i].cmp_type =
+				rcv_filter_param->paramsData[i].cmpFlag;
+			cmd->paramsData[i].data_length =
+				rcv_filter_param->paramsData[i].dataLength;
+			cmd->paramsData[i].data_offset =
+				rcv_filter_param->paramsData[i].dataOffset;
+			memcpy(&cmd->paramsData[i].compareData,
+				rcv_filter_param->paramsData[i].compareData,
+				sizeof(cmd->paramsData[i].compareData));
+			memcpy(&cmd->paramsData[i].dataMask,
+				rcv_filter_param->paramsData[i].dataMask,
+				sizeof(cmd->paramsData[i].dataMask));
+		}
+	}
+
+	WMA_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 */
+	err = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				WMI_PACKET_FILTER_CONFIG_CMDID);
+	if (err) {
+		WMA_LOGE("Failed to send pkt_filter cmd");
+		wmi_buf_free(buf);
+		return -EIO;
+	}
+
+	/* Enable packet filter */
+	if (enable)
+		wma_enable_disable_packet_filter(wma, vdev_id, true);
+
+	return 0;
+}
+
+/**
+ * wma_process_receive_filter_set_filter_req() - enable packet filter
+ * @wma_handle: wma handle
+ * @rcv_filter_param: filter params
+ *
+ * Return: 0 for success or error code
+ */
+int wma_process_receive_filter_set_filter_req(tp_wma_handle wma,
+				tSirRcvPktFilterCfgType *rcv_filter_param)
+{
+	int ret = 0;
+	uint8_t vdev_id;
+
+	/* Get the vdev id */
+	if (!wma_find_vdev_by_bssid(wma, rcv_filter_param->bssId, &vdev_id)) {
+		WMA_LOGE("vdev handle is invalid for %pM",
+			rcv_filter_param->bssId);
+		return -EINVAL;
+	}
+
+	ret = wma_config_packet_filter(wma, vdev_id, rcv_filter_param,
+				rcv_filter_param->filterId, true);
+
+	return ret;
+}
+
+/**
+ * wma_process_receive_filter_clear_filter_req() - disable packet filter
+ * @wma_handle: wma handle
+ * @rcv_clear_param: filter params
+ *
+ * Return: 0 for success or error code
+ */
+int wma_process_receive_filter_clear_filter_req(tp_wma_handle wma,
+				tSirRcvFltPktClearParam *rcv_clear_param)
+{
+	int ret = 0;
+	uint8_t vdev_id;
+
+	/* Get the vdev id */
+	if (!wma_find_vdev_by_bssid(wma, rcv_clear_param->bssId, &vdev_id)) {
+		WMA_LOGE("vdev handle is invalid for %pM", rcv_clear_param->bssId);
+		return -EINVAL;
+	}
+
+	ret = wma_config_packet_filter(wma, vdev_id, NULL,
+			rcv_clear_param->filterId, false);
+
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_ESE
+
+#define TSM_DELAY_HISTROGRAM_BINS 4
+/**
+ * wma_process_tsm_stats_req() - process tsm stats request
+ * @wma_handler - handle to wma
+ * @pTsmStatsMsg - TSM stats struct that needs to be populated and
+ *         passed in message.
+ *
+ * A parallel function to WMA_ProcessTsmStatsReq for pronto. This
+ * function fetches stats from data path APIs and post
+ * WMA_TSM_STATS_RSP msg back to LIM.
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler,
+				     void *pTsmStatsMsg)
+{
+	uint8_t counter;
+	uint32_t queue_delay_microsec = 0;
+	uint32_t tx_delay_microsec = 0;
+	uint16_t packet_count = 0;
+	uint16_t packet_loss_count = 0;
+	tpAniTrafStrmMetrics pTsmMetric = NULL;
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+	tpAniGetTsmStatsReq pStats = (tpAniGetTsmStatsReq) pTsmStatsMsg;
+	tpAniGetTsmStatsRsp pTsmRspParams = NULL;
+#else
+	tpTSMStats pStats = (tpTSMStats) pTsmStatsMsg;
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+	int tid = pStats->tid;
+	/*
+	 * The number of histrogram bin report by data path api are different
+	 * than required by TSM, hence different (6) size array used
+	 */
+	uint16_t bin_values[QCA_TX_DELAY_HIST_REPORT_BINS] = { 0, };
+
+	ol_txrx_pdev_handle pdev = cds_get_context(CDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		cdf_mem_free(pTsmStatsMsg);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	/* get required values from data path APIs */
+	ol_tx_delay(pdev, &queue_delay_microsec, &tx_delay_microsec, tid);
+	ol_tx_delay_hist(pdev, bin_values, tid);
+	ol_tx_packet_count(pdev, &packet_count, &packet_loss_count, tid);
+
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+	pTsmRspParams =
+		(tpAniGetTsmStatsRsp) cdf_mem_malloc(sizeof(tAniGetTsmStatsRsp));
+	if (NULL == pTsmRspParams) {
+		CDF_TRACE(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_ERROR,
+			  "%s: CDF MEM Alloc Failure", __func__);
+		CDF_ASSERT(0);
+		cdf_mem_free(pTsmStatsMsg);
+		return CDF_STATUS_E_NOMEM;
+	}
+	pTsmRspParams->staId = pStats->staId;
+	pTsmRspParams->rc = eSIR_FAILURE;
+	pTsmRspParams->tsmStatsReq = pStats;
+	pTsmMetric = &pTsmRspParams->tsmMetrics;
+#else
+	pTsmMetric = (tpAniTrafStrmMetrics)&(pStats->tsmMetrics);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+	/* populate pTsmMetric */
+	pTsmMetric->UplinkPktQueueDly = queue_delay_microsec;
+	/* store only required number of bin values */
+	for (counter = 0; counter < TSM_DELAY_HISTROGRAM_BINS; counter++) {
+		pTsmMetric->UplinkPktQueueDlyHist[counter] =
+			bin_values[counter];
+	}
+	pTsmMetric->UplinkPktTxDly = tx_delay_microsec;
+	pTsmMetric->UplinkPktLoss = packet_loss_count;
+	pTsmMetric->UplinkPktCount = packet_count;
+
+	/*
+	 * No need to populate roaming delay and roaming count as they are
+	 * being populated just before sending IAPP frame out
+	 */
+	/* post this message to LIM/PE */
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+	wma_send_msg(wma_handler, WMA_TSM_STATS_RSP, (void *)pTsmRspParams, 0);
+#else
+	wma_send_msg(wma_handler, WMA_TSM_STATS_RSP, (void *)pTsmStatsMsg, 0);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+	return CDF_STATUS_SUCCESS;
+}
+
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * wma_add_clear_mcbc_filter() - set mcast filter command to fw
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ * @multicastAddr: mcast address
+ * @clearList: clear list flag
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_add_clear_mcbc_filter(tp_wma_handle wma_handle, uint8_t vdev_id,
+				     tSirMacAddr multicastAddr, bool clearList)
+{
+	WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd;
+	wmi_buf_t buf;
+	int err;
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
+	if (!buf) {
+		WMA_LOGE("Failed to allocate buffer to send set_param cmd");
+		return -ENOMEM;
+	}
+
+	cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf);
+	cdf_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(multicastAddr, &cmd->mcastbdcastaddr);
+	err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				   sizeof(*cmd),
+				   WMI_SET_MCASTBCAST_FILTER_CMDID);
+	if (err) {
+		WMA_LOGE("Failed to send set_param cmd");
+		cdf_mem_free(buf);
+		return -EIO;
+	}
+	WMA_LOGD("Action:%d; vdev_id:%d; clearList:%d\n",
+		 cmd->action, vdev_id, clearList);
+	WMA_LOGD("MCBC MAC Addr: %0x:%0x:%0x:%0x:%0x:%0x\n",
+		 multicastAddr[0], multicastAddr[1], multicastAddr[2],
+		 multicastAddr[3], multicastAddr[4], multicastAddr[5]);
+	return 0;
+}
+
+/**
+ * wma_process_mcbc_set_filter_req() - process mcbc set filter request
+ * @wma_handle: wma handle
+ * @mcbc_param: mcbc params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_process_mcbc_set_filter_req(tp_wma_handle wma_handle,
+					   tSirRcvFltMcAddrList * mcbc_param)
+{
+	uint8_t vdev_id = 0;
+	int i;
+
+	if (mcbc_param->ulMulticastAddrCnt <= 0) {
+		WMA_LOGE("Number of multicast addresses is 0");
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (!wma_find_vdev_by_addr
+		    (wma_handle, mcbc_param->selfMacAddr, &vdev_id)) {
+		WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
+			 mcbc_param->bssId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* set mcbc_param->action to clear MCList and reset
+	 * to configure the MCList in FW
+	 */
+
+	for (i = 0; i < mcbc_param->ulMulticastAddrCnt; i++) {
+		wma_add_clear_mcbc_filter(wma_handle, vdev_id,
+					  mcbc_param->multicastAddr[i],
+					  (mcbc_param->action == 0));
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+#define GTK_OFFLOAD_ENABLE      0
+#define GTK_OFFLOAD_DISABLE     1
+
+/**
+ * wma_gtk_offload_status_event() - GTK offload status event handler
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_gtk_offload_status_event(void *handle, uint8_t *event,
+				 uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *status;
+	WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf;
+	tpSirGtkOffloadGetInfoRspParams resp;
+	cds_msg_t cds_msg;
+	uint8_t *bssid;
+
+	WMA_LOGD("%s Enter", __func__);
+
+	param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("param_buf is NULL");
+		return -EINVAL;
+	}
+
+	status = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) param_buf->fixed_param;
+
+	if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) {
+		WMA_LOGE("Invalid length for GTK status");
+		return -EINVAL;
+	}
+	bssid = wma_find_bssid_by_vdev_id(wma, status->vdev_id);
+	if (!bssid) {
+		WMA_LOGE("invalid bssid for vdev id %d", status->vdev_id);
+		return -ENOENT;
+	}
+
+	resp = cdf_mem_malloc(sizeof(*resp));
+	if (!resp) {
+		WMA_LOGE("%s: Failed to alloc response", __func__);
+		return -ENOMEM;
+	}
+	cdf_mem_zero(resp, sizeof(*resp));
+	resp->mesgType = eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP;
+	resp->mesgLen = sizeof(*resp);
+	resp->ulStatus = CDF_STATUS_SUCCESS;
+	resp->ulTotalRekeyCount = status->refresh_cnt;
+	/* TODO: Is the total rekey count and GTK rekey count same? */
+	resp->ulGTKRekeyCount = status->refresh_cnt;
+
+	cdf_mem_copy(&resp->ullKeyReplayCounter, &status->replay_counter,
+		     GTK_REPLAY_COUNTER_BYTES);
+
+	cdf_mem_copy(resp->bssId, bssid, IEEE80211_ADDR_LEN);
+
+#ifdef IGTK_OFFLOAD
+	/* TODO: Is the refresh count same for GTK and IGTK? */
+	resp->ulIGTKRekeyCount = status->refresh_cnt;
+#endif /* IGTK_OFFLOAD */
+
+	cds_msg.type = eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP;
+	cds_msg.bodyptr = (void *)resp;
+	cds_msg.bodyval = 0;
+
+	if (cds_mq_post_message(CDS_MQ_ID_SME, (cds_msg_t *) &cds_msg)
+	    != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to post GTK response to SME");
+		cdf_mem_free(resp);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("GTK: got target status with replay counter "
+		 "%02x%02x%02x%02x%02x%02x%02x%02x. vdev %d "
+		 "Refresh GTK %d times exchanges since last set operation",
+		 status->replay_counter[0],
+		 status->replay_counter[1],
+		 status->replay_counter[2],
+		 status->replay_counter[3],
+		 status->replay_counter[4],
+		 status->replay_counter[5],
+		 status->replay_counter[6],
+		 status->replay_counter[7],
+		 status->vdev_id, status->refresh_cnt);
+
+	WMA_LOGD("%s Exit", __func__);
+
+	return 0;
+}
+
+/**
+ * wma_send_gtk_offload_req() - send GTK offload command to fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @params: GTK offload parameters
+ *
+ * Return: CDF status
+ */
+static CDF_STATUS wma_send_gtk_offload_req(tp_wma_handle wma, uint8_t vdev_id,
+					   tpSirGtkOffloadParams params)
+{
+	int len;
+	wmi_buf_t buf;
+	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	WMA_LOGD("%s Enter", __func__);
+
+	len = sizeof(*cmd);
+
+	/* alloc wmi buffer */
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
+		status = CDF_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 (params->ulFlags == GTK_OFFLOAD_ENABLE) {
+		cmd->flags = GTK_OFFLOAD_ENABLE_OPCODE;
+		wma->wow.gtk_err_enable[vdev_id] = true;
+
+		/* Copy the keys and replay counter */
+		cdf_mem_copy(cmd->KCK, params->aKCK, GTK_OFFLOAD_KCK_BYTES);
+		cdf_mem_copy(cmd->KEK, params->aKEK, GTK_OFFLOAD_KEK_BYTES);
+		cdf_mem_copy(cmd->replay_counter, &params->ullKeyReplayCounter,
+			     GTK_REPLAY_COUNTER_BYTES);
+	} else {
+		wma->wow.gtk_err_enable[vdev_id] = false;
+		cmd->flags = GTK_OFFLOAD_DISABLE_OPCODE;
+	}
+
+	/* send the wmi command */
+	if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				 WMI_GTK_OFFLOAD_CMDID)) {
+		WMA_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID");
+		wmi_buf_free(buf);
+		status = CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("VDEVID: %d, GTK_FLAGS: x%x", vdev_id, cmd->flags);
+out:
+	WMA_LOGD("%s Exit", __func__);
+	return status;
+}
+
+/**
+ * wma_process_gtk_offload_req() - process GTK offload req from umac
+ * @handle: wma handle
+ * @params: GTK offload params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_process_gtk_offload_req(tp_wma_handle wma,
+				       tpSirGtkOffloadParams params)
+{
+	uint8_t vdev_id;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	WMA_LOGD("%s Enter", __func__);
+
+	/* Get the vdev id */
+	if (!wma_find_vdev_by_bssid(wma, params->bssId, &vdev_id)) {
+		WMA_LOGE("vdev handle is invalid for %pM", params->bssId);
+		status = CDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	/* Validate vdev id */
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("invalid vdev_id %d for %pM", vdev_id, params->bssId);
+		status = CDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	if ((params->ulFlags == GTK_OFFLOAD_ENABLE) &&
+	    (wma->wow.gtk_err_enable[vdev_id] == true)) {
+		WMA_LOGE("%s GTK Offload already enabled. Disable it first "
+			 "vdev_id %d", __func__, vdev_id);
+		params->ulFlags = GTK_OFFLOAD_DISABLE;
+		status = wma_send_gtk_offload_req(wma, vdev_id, params);
+		if (status != CDF_STATUS_SUCCESS) {
+			WMA_LOGE("%s Failed to disable GTK Offload", __func__);
+			goto out;
+		}
+		WMA_LOGD("%s Enable GTK Offload again with updated inputs",
+			 __func__);
+		params->ulFlags = GTK_OFFLOAD_ENABLE;
+	}
+	status = wma_send_gtk_offload_req(wma, vdev_id, params);
+out:
+	cdf_mem_free(params);
+	WMA_LOGD("%s Exit", __func__);
+	return status;
+}
+
+/**
+ * wma_process_gtk_offload_getinfo_req() - send GTK offload cmd to fw
+ * @wma: wma handle
+ * @params: GTK offload params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_process_gtk_offload_getinfo_req(tp_wma_handle wma,
+				tpSirGtkOffloadGetInfoRspParams params)
+{
+	uint8_t vdev_id;
+	int len;
+	wmi_buf_t buf;
+	WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	WMA_LOGD("%s Enter", __func__);
+
+	/* Get the vdev id */
+	if (!wma_find_vdev_by_bssid(wma, params->bssId, &vdev_id)) {
+		WMA_LOGE("vdev handle is invalid for %pM", params->bssId);
+		status = CDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	len = sizeof(*cmd);
+
+	/* alloc wmi buffer */
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
+		status = CDF_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 = GTK_OFFLOAD_REQUEST_STATUS_OPCODE;
+	cmd->vdev_id = vdev_id;
+
+	/* send the wmi command */
+	if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				 WMI_GTK_OFFLOAD_CMDID)) {
+		WMA_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info");
+		wmi_buf_free(buf);
+		status = CDF_STATUS_E_FAILURE;
+	}
+out:
+	cdf_mem_free(params);
+	WMA_LOGD("%s Exit", __func__);
+	return status;
+}
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+
+/**
+ * wma_enable_arp_ns_offload() - enable ARP NS offload
+ * @wma: wma handle
+ * @tpSirHostOffloadReq: offload request
+ * @bArpOnly: flag
+ *
+ * To configure ARP NS off load data to firmware
+ * when target goes to wow mode.
+ *
+ * Return: CDF Status
+ */
+CDF_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma,
+					    tpSirHostOffloadReq
+					    pHostOffloadParams, bool bArpOnly)
+{
+	int32_t i;
+	int32_t res;
+	WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
+	WMI_NS_OFFLOAD_TUPLE *ns_tuple;
+	WMI_ARP_OFFLOAD_TUPLE *arp_tuple;
+	A_UINT8 *buf_ptr;
+	wmi_buf_t buf;
+	int32_t len;
+	uint8_t vdev_id;
+	uint32_t count = 0, num_ns_ext_tuples = 0;
+
+	/* Get the vdev id */
+	if (!wma_find_vdev_by_bssid(wma, pHostOffloadParams->bssId, &vdev_id)) {
+		WMA_LOGE("vdev handle is invalid for %pM",
+			 pHostOffloadParams->bssId);
+		cdf_mem_free(pHostOffloadParams);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	if (!wma->interfaces[vdev_id].vdev_up) {
+
+		WMA_LOGE("vdev %d is not up skipping arp/ns offload", vdev_id);
+		cdf_mem_free(pHostOffloadParams);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (!bArpOnly)
+		count = pHostOffloadParams->num_ns_offload_count;
+
+
+	len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + WMI_TLV_HDR_SIZE +       /* TLV place holder size for array of NS tuples */
+	      WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + WMI_TLV_HDR_SIZE +   /* TLV place holder size for array of ARP tuples */
+	      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 (!bArpOnly && 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(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+		cdf_mem_free(pHostOffloadParams);
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (A_UINT8 *) 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;
+	if (!bArpOnly)
+		cmd->num_ns_ext_tuples = num_ns_ext_tuples;
+
+	WMA_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id);
+
+	/* Have copy of arp info to send along with NS, Since FW expects
+	 * both ARP and NS info in single cmd */
+	if (bArpOnly)
+		cdf_mem_copy(&wma->mArpInfo, pHostOffloadParams,
+			     sizeof(tSirHostOffloadReq));
+
+	buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param);
+	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 (!bArpOnly &&
+		    ((pHostOffloadParams->enableOrDisable & SIR_OFFLOAD_ENABLE))) {
+			ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
+
+#ifdef WLAN_NS_OFFLOAD
+			/*Copy the target/solicitation/remote ip addr */
+			if (pHostOffloadParams->nsOffloadInfo.
+			    targetIPv6AddrValid[i])
+				A_MEMCPY(&ns_tuple->target_ipaddr[0],
+					 &pHostOffloadParams->nsOffloadInfo.
+					 targetIPv6Addr[i],
+					 sizeof(WMI_IPV6_ADDR));
+			A_MEMCPY(&ns_tuple->solicitation_ipaddr,
+				 &pHostOffloadParams->nsOffloadInfo.
+				 selfIPv6Addr[i], sizeof(WMI_IPV6_ADDR));
+			WMA_LOGD("NS solicitedIp: %pI6, targetIp: %pI6",
+				 &pHostOffloadParams->nsOffloadInfo.selfIPv6Addr[i],
+				 &pHostOffloadParams->nsOffloadInfo.
+				 targetIPv6Addr[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(pHostOffloadParams->
+						   nsOffloadInfo.selfMacAddr,
+						   &ns_tuple->target_mac);
+#endif /* WLAN_NS_OFFLOAD */
+			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);
+	}
+
+	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 ((wma->mArpInfo.enableOrDisable & SIR_OFFLOAD_ENABLE)
+		    && (i == 0)) {
+			/*Copy the target ip addr and flags */
+			arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
+			A_MEMCPY(&arp_tuple->target_ipaddr,
+				 wma->mArpInfo.params.hostIpv4Addr,
+				 SIR_IPV4_ADDR_LEN);
+			WMA_LOGD("ARPOffload IP4 address: %pI4",
+				 wma->mArpInfo.params.hostIpv4Addr);
+		}
+		buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE);
+	}
+
+	/* 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;
+
+	if (num_ns_ext_tuples) {
+		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 (!bArpOnly  &&
+				((pHostOffloadParams->enableOrDisable & SIR_OFFLOAD_ENABLE))) {
+				ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
+#ifdef WLAN_NS_OFFLOAD
+				/*Copy the target/solicitation/remote ip addr */
+				if (pHostOffloadParams->nsOffloadInfo.targetIPv6AddrValid[i])
+					A_MEMCPY(&ns_tuple->target_ipaddr[0],
+						&pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[i],
+						sizeof(WMI_IPV6_ADDR));
+				A_MEMCPY(&ns_tuple->solicitation_ipaddr,
+					&pHostOffloadParams->nsOffloadInfo.selfIPv6Addr[i],
+					sizeof(WMI_IPV6_ADDR));
+				WMA_LOGD("Index %d NS solicitedIp: %pI6, targetIp: %pI6", i,
+					&pHostOffloadParams->nsOffloadInfo.selfIPv6Addr[i],
+					&pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[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(pHostOffloadParams->nsOffloadInfo.selfMacAddr,
+					&ns_tuple->target_mac);
+#endif
+				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);
+		}
+	}
+
+	res = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				     WMI_SET_ARP_NS_OFFLOAD_CMDID);
+	if (res) {
+		WMA_LOGE("Failed to enable ARP NDP/NSffload");
+		wmi_buf_free(buf);
+		cdf_mem_free(pHostOffloadParams);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	cdf_mem_free(pHostOffloadParams);
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_add_periodic_tx_ptrn_ind - add periodic tx ptrn
+ * @handle: wma handle
+ * @pAddPeriodicTxPtrnParams: tx ptrn params
+ *
+ * Retrun: CDF status
+ */
+CDF_STATUS wma_process_add_periodic_tx_ptrn_ind(WMA_HANDLE handle,
+						tSirAddPeriodicTxPtrn *
+						pAddPeriodicTxPtrnParams)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t len;
+	uint8_t vdev_id;
+	uint8_t *buf_ptr;
+	uint32_t ptrn_len, ptrn_len_aligned;
+	int j;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue fw add pattern cmd",
+			 __func__);
+		return CDF_STATUS_E_INVAL;
+	}
+	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(wma_handle->wmi_handle, len);
+	if (!wmi_buf) {
+		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+		return CDF_STATUS_E_NOMEM;
+	}
+	if (!wma_find_vdev_by_addr(wma_handle,
+				   pAddPeriodicTxPtrnParams->macAddress,
+				   &vdev_id)) {
+		WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
+			 pAddPeriodicTxPtrnParams->macAddress);
+		cdf_nbuf_free(wmi_buf);
+		return CDF_STATUS_E_INVAL;
+	}
+	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;
+	cdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
+	for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) {
+		WMA_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
+	}
+	WMA_LOGD("%s: Add ptrn id: %d vdev_id: %d",
+		 __func__, cmd->pattern_id, cmd->vdev_id);
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+				 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
+		WMA_LOGE("%s: failed to add pattern set state command",
+			 __func__);
+		cdf_nbuf_free(wmi_buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_del_periodic_tx_ptrn_ind - del periodic tx ptrn
+ * @handle: wma handle
+ * @pDelPeriodicTxPtrnParams: tx ptrn params
+ *
+ * Retrun: CDF status
+ */
+CDF_STATUS wma_process_del_periodic_tx_ptrn_ind(WMA_HANDLE handle,
+						tSirDelPeriodicTxPtrn *
+						pDelPeriodicTxPtrnParams)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint8_t vdev_id;
+	uint32_t len =
+		sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue Del Pattern cmd",
+			 __func__);
+		return CDF_STATUS_E_INVAL;
+	}
+	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!wmi_buf) {
+		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+		return CDF_STATUS_E_NOMEM;
+	}
+	if (!wma_find_vdev_by_addr(wma_handle,
+				   pDelPeriodicTxPtrnParams->macAddress,
+				   &vdev_id)) {
+		WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
+			 pDelPeriodicTxPtrnParams->macAddress);
+		cdf_nbuf_free(wmi_buf);
+		return CDF_STATUS_E_INVAL;
+	}
+	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 = pDelPeriodicTxPtrnParams->ucPtrnId;
+	WMA_LOGD("%s: Del ptrn id: %d vdev_id: %d",
+		 __func__, cmd->pattern_id, cmd->vdev_id);
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+				 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
+		WMA_LOGE("%s: failed to send del pattern command", __func__);
+		cdf_nbuf_free(wmi_buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_STATS_EXT
+/**
+ * wma_stats_ext_req() - request ext stats from fw
+ * @wma_ptr: wma handle
+ * @preq: stats ext params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_stats_ext_req(void *wma_ptr, tpStatsExtRequest preq)
+{
+	int32_t ret;
+	tp_wma_handle wma = (tp_wma_handle) wma_ptr;
+	wmi_req_stats_ext_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint16_t len;
+	uint8_t *buf_ptr;
+
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len;
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+		return -ENOMEM;
+	}
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_req_stats_ext_cmd_fixed_param));
+	cmd->vdev_id = preq->vdev_id;
+	cmd->data_len = preq->request_data_len;
+
+	WMA_LOGD("%s: The data len value is %u and vdev id set is %u ",
+		 __func__, preq->request_data_len, preq->vdev_id);
+
+	buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len);
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	cdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_REQUEST_STATS_EXT_CMDID);
+	if (ret != EOK) {
+		WMA_LOGE("%s: Failed to send notify cmd ret = %d", __func__,
+			 ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+#endif /* WLAN_FEATURE_STATS_EXT */
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+/**
+ * wma_send_status_of_ext_wow() - send ext wow status to SME
+ * @wma: wma handle
+ * @status: status
+ *
+ * Return: none
+ */
+static void wma_send_status_of_ext_wow(tp_wma_handle wma, bool status)
+{
+	tSirReadyToExtWoWInd *ready_to_extwow;
+	CDF_STATUS vstatus;
+	cds_msg_t cds_msg;
+	uint8_t len;
+
+	WMA_LOGD("Posting ready to suspend indication to umac");
+
+	len = sizeof(tSirReadyToExtWoWInd);
+	ready_to_extwow = (tSirReadyToExtWoWInd *) cdf_mem_malloc(len);
+
+	if (NULL == ready_to_extwow) {
+		WMA_LOGE("%s: Memory allocation failure", __func__);
+		return;
+	}
+
+	ready_to_extwow->mesgType = eWNI_SME_READY_TO_EXTWOW_IND;
+	ready_to_extwow->mesgLen = len;
+	ready_to_extwow->status = status;
+
+	cds_msg.type = eWNI_SME_READY_TO_EXTWOW_IND;
+	cds_msg.bodyptr = (void *)ready_to_extwow;
+	cds_msg.bodyval = 0;
+
+	vstatus = cds_mq_post_message(CDS_MQ_ID_SME, &cds_msg);
+	if (vstatus != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to post ready to suspend");
+		cdf_mem_free(ready_to_extwow);
+	}
+}
+
+/**
+ * wma_enable_ext_wow() - enable ext wow in fw
+ * @wma: wma handle
+ * @params: ext wow params
+ *
+ * Return:0 for success or error code
+ */
+int wma_enable_ext_wow(tp_wma_handle wma, tpSirExtWoWParams 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(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_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;
+
+	WMA_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x",
+		 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_EXTWOW_ENABLE_CMDID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to set EXTWOW Enable", __func__);
+		wmi_buf_free(buf);
+		wma_send_status_of_ext_wow(wma, false);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	wma_send_status_of_ext_wow(wma, true);
+	return CDF_STATUS_SUCCESS;
+
+}
+
+/**
+ * wma_set_app_type1_params_in_fw() - set app type1 params in fw
+ * @wma: wma handle
+ * @appType1Params: app type1 params
+ *
+ * Return: CDF status
+ */
+int wma_set_app_type1_params_in_fw(tp_wma_handle wma,
+				   tpSirAppType1Params appType1Params)
+{
+	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(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_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 = appType1Params->vdev_id;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(appType1Params->wakee_mac_addr,
+				   &cmd->wakee_mac);
+	cdf_mem_copy(cmd->ident, appType1Params->identification_id, 8);
+	cmd->ident_len = appType1Params->id_length;
+	cdf_mem_copy(cmd->passwd, appType1Params->password, 16);
+	cmd->passwd_len = appType1Params->pass_length;
+
+	WMA_LOGD("%s: vdev_id %d wakee_mac_addr %pM "
+		 "identification_id %.8s id_length %u "
+		 "password %.16s pass_length %u",
+		 __func__, cmd->vdev_id, appType1Params->wakee_mac_addr,
+		 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_set_app_type2_params_in_fw() - set app type2 params in fw
+ * @wma: wma handle
+ * @appType2Params: app type2 params
+ *
+ * Return: CDF status
+ */
+int wma_set_app_type2_params_in_fw(tp_wma_handle wma,
+					  tpSirAppType2Params 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(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return CDF_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;
+
+	cdf_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,
+				   &cmd->gateway_mac);
+	cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
+	cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
+
+	WMA_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,
+		 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);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__);
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+
+}
+#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+/**
+ * wma_auto_shutdown_event_handler() - process auto shutdown timer trigger
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_auto_shutdown_event_handler(void *handle, uint8_t *event,
+				    uint32_t len)
+{
+	wmi_host_auto_shutdown_event_fixed_param *wmi_auto_sh_evt;
+	WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *param_buf =
+		(WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *)
+		event;
+
+	if (!param_buf || !param_buf->fixed_param) {
+		WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__,
+			 __LINE__);
+		return -EINVAL;
+	}
+
+	wmi_auto_sh_evt = param_buf->fixed_param;
+
+	if (wmi_auto_sh_evt->shutdown_reason
+	    != WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY) {
+		WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__,
+			 __LINE__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s:%d: Auto Shutdown Evt: %d", __func__, __LINE__,
+		 wmi_auto_sh_evt->shutdown_reason);
+	return wma_post_auto_shutdown_msg();
+}
+
+/**
+ * wma_set_auto_shutdown_timer_req() - sets auto shutdown timer in firmware
+ * @wma: wma handle
+ * @auto_sh_cmd: auto shutdown timer value
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,
+						  tSirAutoShutdownCmdParams *
+						  auto_sh_cmd)
+{
+	int status = 0;
+	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);
+
+	if (auto_sh_cmd == NULL) {
+		WMA_LOGE("%s : Invalid Autoshutdown cfg cmd", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
+		 __func__, auto_sh_cmd->timer_val);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+		return CDF_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 = auto_sh_cmd->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));
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				      len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * wma_nan_req() - to send nan request to target
+ * @wma: wma_handle
+ * @nan_req: request data which will be non-null
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_nan_req(void *wma_ptr, tpNanRequest nan_req)
+{
+	int ret;
+	tp_wma_handle wma_handle = (tp_wma_handle) wma_ptr;
+	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) {
+		WMA_LOGE("%s:nan req is not valid", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+	nan_data_len = nan_req->request_data_len;
+	nan_data_len_aligned = roundup(nan_req->request_data_len,
+				       sizeof(uint32_t));
+	len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+		return CDF_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;
+	WMA_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;
+	cdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
+
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+				   WMI_NAN_CMDID);
+	if (ret != EOK) {
+		WMA_LOGE("%s Failed to send set param command ret = %d",
+			 __func__, ret);
+		wmi_buf_free(buf);
+	}
+	return ret;
+}
+#endif /* WLAN_FEATURE_NAN */
+
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wma_process_dhcpserver_offload() - enable DHCP server offload
+ * @wma_handle: wma handle
+ * @pDhcpSrvOffloadInfo: DHCP server offload info
+ *
+ * Return: 0 for success or error code
+ */
+int wma_process_dhcpserver_offload(tp_wma_handle wma_handle,
+					  tSirDhcpSrvOffloadInfo *
+					  pDhcpSrvOffloadInfo)
+{
+	wmi_set_dhcp_server_offload_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int err;
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
+	if (!buf) {
+		WMA_LOGE("Failed to allocate buffer to send "
+			 "set_dhcp_server_offload cmd");
+		return -ENOMEM;
+	}
+
+	cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf);
+	cdf_mem_zero(cmd, sizeof(*cmd));
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_set_dhcp_server_offload_cmd_fixed_param));
+	cmd->vdev_id = pDhcpSrvOffloadInfo->vdev_id;
+	cmd->enable = pDhcpSrvOffloadInfo->dhcpSrvOffloadEnabled;
+	cmd->num_client = pDhcpSrvOffloadInfo->dhcpClientNum;
+	cmd->srv_ipv4 = pDhcpSrvOffloadInfo->dhcpSrvIP;
+	cmd->start_lsb = 0;
+	err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				   sizeof(*cmd),
+				   WMI_SET_DHCP_SERVER_OFFLOAD_CMDID);
+	if (err) {
+		WMA_LOGE("Failed to send set_dhcp_server_offload cmd");
+		wmi_buf_free(buf);
+		return -EIO;
+	}
+	WMA_LOGD("Set dhcp server offload to vdevId %d",
+		 pDhcpSrvOffloadInfo->vdev_id);
+	return 0;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+/**
+ * wma_set_led_flashing() - set led flashing in fw
+ * @wma_handle: wma handle
+ * @flashing: flashing request
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_set_led_flashing(tp_wma_handle wma_handle,
+				tSirLedFlashingReq *flashing)
+{
+	wmi_set_led_flashing_cmd_fixed_param *cmd;
+	int status = 0;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue cmd"));
+		return CDF_STATUS_E_INVAL;
+	}
+	if (!flashing) {
+		WMA_LOGE(FL("invalid parameter: flashing"));
+		return CDF_STATUS_E_INVAL;
+	}
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGP(FL("wmi_buf_alloc failed"));
+		return -ENOMEM;
+	}
+	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;
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+				      WMI_PDEV_SET_LED_FLASHING_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
+			 " returned Error %d", __func__, status);
+		return CDF_STATUS_E_FAILURE;
+	}
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_GPIO_LED_FLASHING */
+
+#ifdef FEATURE_WLAN_CH_AVOID
+/**
+ * wma_channel_avoid_evt_handler() -  process channel to avoid event from FW.
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_channel_avoid_evt_handler(void *handle, uint8_t *event,
+				  uint32_t len)
+{
+	wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param;
+	wmi_avoid_freq_range_desc *afr_desc;
+	uint32_t num_freq_ranges, freq_range_idx;
+	tSirChAvoidIndType *sca_indication;
+	CDF_STATUS cdf_status;
+	cds_msg_t sme_msg = { 0 };
+	WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf =
+		(WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) event;
+
+	if (!param_buf) {
+		WMA_LOGE("Invalid channel avoid event buffer");
+		return -EINVAL;
+	}
+
+	afr_fixed_param = param_buf->fixed_param;
+	if (!afr_fixed_param) {
+		WMA_LOGE("Invalid channel avoid event fixed param buffer");
+		return -EINVAL;
+	}
+
+	num_freq_ranges =
+		(afr_fixed_param->num_freq_ranges >
+		 SIR_CH_AVOID_MAX_RANGE) ? SIR_CH_AVOID_MAX_RANGE :
+		afr_fixed_param->num_freq_ranges;
+
+	WMA_LOGD("Channel avoid event received with %d ranges",
+		 num_freq_ranges);
+	for (freq_range_idx = 0; freq_range_idx < num_freq_ranges;
+	     freq_range_idx++) {
+		afr_desc = (wmi_avoid_freq_range_desc *)
+				((void *)param_buf->avd_freq_range +
+				freq_range_idx * sizeof(wmi_avoid_freq_range_desc));
+
+		WMA_LOGD("range %d: tlv id = %u, start freq = %u,  end freq = %u",
+			freq_range_idx, afr_desc->tlv_header, afr_desc->start_freq,
+			afr_desc->end_freq);
+	}
+
+	sca_indication = (tSirChAvoidIndType *)
+			 cdf_mem_malloc(sizeof(tSirChAvoidIndType));
+	if (!sca_indication) {
+		WMA_LOGE("Invalid channel avoid indication buffer");
+		return -EINVAL;
+	}
+
+	sca_indication->avoid_range_count = num_freq_ranges;
+	for (freq_range_idx = 0; freq_range_idx < num_freq_ranges;
+	     freq_range_idx++) {
+		afr_desc = (wmi_avoid_freq_range_desc *)
+				((void *)param_buf->avd_freq_range +
+				freq_range_idx * sizeof(wmi_avoid_freq_range_desc));
+		sca_indication->avoid_freq_range[freq_range_idx].start_freq =
+			afr_desc->start_freq;
+		sca_indication->avoid_freq_range[freq_range_idx].end_freq =
+			afr_desc->end_freq;
+	}
+
+	sme_msg.type = eWNI_SME_CH_AVOID_IND;
+	sme_msg.bodyptr = sca_indication;
+	sme_msg.bodyval = 0;
+
+	cdf_status = cds_mq_post_message(CDF_MODULE_ID_SME, &sme_msg);
+	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+		WMA_LOGE("Fail to post eWNI_SME_CH_AVOID_IND msg to SME");
+		cdf_mem_free(sca_indication);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_process_ch_avoid_update_req() - handles channel avoid update request
+ * @wma_handle: wma handle
+ * @ch_avoid_update_req: channel avoid update params
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle,
+					   tSirChAvoidUpdateReq *
+					   ch_avoid_update_req)
+{
+	int status = 0;
+	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);
+
+	if (ch_avoid_update_req == NULL) {
+		WMA_LOGE("%s : ch_avoid_update_req is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGI("%s: WMA --> WMI_CHAN_AVOID_UPDATE", __func__);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+		return CDF_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));
+
+	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
+				      len, WMI_CHAN_AVOID_UPDATE_CMDID);
+	if (status != EOK) {
+		WMA_LOGE("wmi_unified_cmd_send"
+			 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
+			 " returned Error %d", status);
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGI("%s: WMA --> WMI_CHAN_AVOID_UPDATE sent through WMI",
+		 __func__);
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+/**
+ * wma_set_reg_domain() - set reg domain
+ * @clientCtxt: client context
+ * @regId: reg id
+ *
+ * Return: CDF status
+ */
+CDF_STATUS wma_set_reg_domain(void *clientCtxt, v_REGDOMAIN_t regId)
+{
+	if (CDF_STATUS_SUCCESS !=
+	    cds_set_reg_domain(clientCtxt, regId))
+		return CDF_STATUS_E_INVAL;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_send_regdomain_info_to_fw() - send regdomain info to fw
+ * @reg_dmn: reg domain
+ * @regdmn2G: 2G reg domain
+ * @regdmn5G: 5G reg domain
+ * @ctl2G: 2G test limit
+ * @ctl5G: 5G test limit
+ *
+ * Return: none
+ */
+void wma_send_regdomain_info_to_fw(uint32_t reg_dmn, uint16_t regdmn2G,
+				   uint16_t regdmn5G, int8_t ctl2G,
+				   int8_t ctl5G)
+{
+	wmi_buf_t buf;
+	wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
+	int32_t len = sizeof(*cmd);
+	tp_wma_handle wma = cds_get_context(CDF_MODULE_ID_WMA);
+	int32_t cck_mask_val = 0;
+	int ret = 0;
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma context is NULL", __func__);
+		return;
+	}
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
+		return;
+	}
+	cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_pdev_set_regdomain_cmd_fixed_param));
+	cmd->reg_domain = reg_dmn;
+	cmd->reg_domain_2G = regdmn2G;
+	cmd->reg_domain_5G = regdmn5G;
+	cmd->conformance_test_limit_2G = ctl2G;
+	cmd->conformance_test_limit_5G = ctl5G;
+
+	if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
+		WMA_LOGP("%s: Failed to send pdev set regdomain command",
+			 __func__);
+		cdf_nbuf_free(buf);
+	}
+
+	if ((((reg_dmn & ~COUNTRY_ERD_FLAG) == CTRY_JAPAN) ||
+	     ((reg_dmn & ~COUNTRY_ERD_FLAG) == CTRY_KOREA_ROC)) &&
+	    (true == wma->tx_chain_mask_cck))
+		cck_mask_val = 1;
+
+	cck_mask_val |= (wma->self_gen_frm_pwr << 16);
+	ret = wmi_unified_pdev_set_param(wma->wmi_handle,
+					 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK,
+					 cck_mask_val);
+	if (ret)
+		WMA_LOGE("failed to set PDEV tx_chain_mask_cck %d",
+			 ret);
+
+	return;
+}
+
+/**
+ * wma_bus_suspend() - handles bus suspend request from hdd
+ *
+ * Calls the appropriate handler based on configuration and event
+ *
+ * Return: 0 for success or error code
+ */
+int wma_bus_suspend(void)
+{
+	WMA_HANDLE handle = cds_get_context(CDF_MODULE_ID_WMA);
+	if (NULL == handle) {
+		WMA_LOGE("%s: wma context is NULL", __func__);
+		return -EFAULT;
+	}
+
+	WMA_LOGE("%s: wow mode selected %d", __func__,
+	       wma_is_wow_mode_selected(handle));
+
+	if (wma_check_scan_in_progress(handle)) {
+		WMA_LOGE("%s: Scan in progress. Aborting suspend", __func__);
+		return -EBUSY;
+	}
+
+	if (wma_is_wow_mode_selected(handle))
+		return cdf_status_to_os_return(wma_enable_wow_in_fw(handle));
+
+	return wma_suspend_target(handle, 0);
+}
+
+/**
+ * wma_bus_resume() - handles bus resume request from hdd
+ * @handle: valid wma handle
+ *
+ * Calls the appropriate handler based on configuration
+ *
+ * Return: 0 for success or error code
+ */
+int wma_bus_resume(void)
+{
+	WMA_HANDLE handle = cds_get_context(CDF_MODULE_ID_WMA);
+	int wow_mode;
+	if (NULL == handle) {
+		WMA_LOGE("%s: wma context is NULL", __func__);
+		return -EFAULT;
+	}
+
+	wow_mode = wma_is_wow_mode_selected(handle);
+	WMA_LOGE("%s: wow mode %d", __func__, wow_mode);
+
+	if (!wow_mode)
+		return wma_resume_target(handle);
+
+	return cdf_status_to_os_return(wma_disable_wow_in_fw(handle));
+}
+
+/**
+ * wma_suspend_target() - suspend target
+ * @handle: wma handle
+ * @disable_target_intr: disable target interrupt
+ *
+ * Return: 0 for success or error code
+ */
+int wma_suspend_target(WMA_HANDLE handle, int disable_target_intr)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	wmi_pdev_suspend_cmd_fixed_param *cmd;
+	wmi_buf_t wmibuf;
+	uint32_t len = sizeof(*cmd);
+	struct ol_softc *scn;
+	int ret;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("WMA is closed. can not issue suspend cmd");
+		return -EINVAL;
+	}
+	/*
+	 * send the comand to Target to ignore the
+	 * PCIE reset so as to ensure that Host and target
+	 * states are in sync
+	 */
+	wmibuf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (wmibuf == NULL)
+		return -ENOMEM;
+
+	cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_pdev_suspend_cmd_fixed_param));
+	if (disable_target_intr) {
+		cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR;
+	} else {
+		cmd->suspend_opt = WMI_PDEV_SUSPEND;
+	}
+	cdf_event_reset(&wma_handle->target_suspend);
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, wmibuf, len,
+				 WMI_PDEV_SUSPEND_CMDID);
+	if (ret < 0) {
+		cdf_nbuf_free(wmibuf);
+		return ret;
+	}
+
+	wmi_set_target_suspend(wma_handle->wmi_handle, true);
+
+	if (cdf_wait_single_event(&wma_handle->target_suspend,
+				  WMA_TGT_SUSPEND_COMPLETE_TIMEOUT)
+	    != CDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to get ACK from firmware for pdev suspend");
+		wmi_set_target_suspend(wma_handle->wmi_handle, false);
+		return -EFAULT;
+	}
+
+	scn = cds_get_context(CDF_MODULE_ID_HIF);
+
+	if (scn == NULL) {
+		WMA_LOGE("%s: Failed to get HIF context", __func__);
+		CDF_ASSERT(0);
+		return -EFAULT;
+	}
+
+	htc_cancel_deferred_target_sleep(scn);
+
+	return 0;
+}
+
+/**
+ * wma_target_suspend_acknowledge() - update target susspend status
+ * @context: wma context
+ *
+ * Return: none
+ */
+void wma_target_suspend_acknowledge(void *context)
+{
+	tp_wma_handle wma = cds_get_context(CDF_MODULE_ID_WMA);
+	int wow_nack = *((int *)context);
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma is NULL", __func__);
+		return;
+	}
+
+	wma->wow_nack = wow_nack;
+	cdf_event_set(&wma->target_suspend);
+	if (wow_nack)
+		cdf_wake_lock_timeout_acquire(&wma->wow_wake_lock,
+					      WMA_WAKE_LOCK_TIMEOUT,
+					      WIFI_POWER_EVENT_WAKELOCK_WOW);
+}
+
+/**
+ * wma_resume_target() - resume target
+ * @handle: wma handle
+ *
+ * Return: 0 for success or error code
+ */
+int wma_resume_target(WMA_HANDLE handle)
+{
+	int ret;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	wmi_buf_t wmibuf;
+	wmi_pdev_resume_cmd_fixed_param *cmd;
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+#ifdef CONFIG_CNSS
+	tpAniSirGlobal pMac = cds_get_context(CDF_MODULE_ID_PE);
+	if (NULL == pMac) {
+		WMA_LOGE("%s: Unable to get PE context", __func__);
+		return -EINVAL;
+	}
+#endif /* CONFIG_CNSS */
+
+	wmibuf = wmi_buf_alloc(wma->wmi_handle, sizeof(*cmd));
+	if (wmibuf == NULL) {
+		return -ENOMEM;
+	}
+	cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_pdev_resume_cmd_fixed_param));
+	cmd->reserved0 = 0;
+	cdf_event_reset(&wma->wma_resume_event);
+	ret = wmi_unified_cmd_send(wma->wmi_handle, wmibuf, sizeof(*cmd),
+				   WMI_PDEV_RESUME_CMDID);
+	if (ret != EOK) {
+		WMA_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command");
+		wmi_buf_free(wmibuf);
+	}
+
+	cdf_status = cdf_wait_single_event(&(wma->wma_resume_event),
+			WMA_RESUME_TIMEOUT);
+	if (CDF_STATUS_SUCCESS != cdf_status) {
+		WMA_LOGP("%s: Timeout waiting for resume event from FW",
+			__func__);
+		WMA_LOGP("%s: Pending commands %d credits %d", __func__,
+			wmi_get_pending_cmds(wma->wmi_handle),
+			wmi_get_host_credits(wma->wmi_handle));
+		if (!cds_is_logp_in_progress()) {
+#ifdef CONFIG_CNSS
+			if (pMac->sme.enableSelfRecovery) {
+				cds_trigger_recovery();
+			} else {
+				CDF_BUG(0);
+			}
+#else
+			CDF_BUG(0);
+#endif /* CONFIG_CNSS */
+		} else {
+			WMA_LOGE("%s: SSR in progress, ignore resume timeout",
+				__func__);
+		}
+	} else {
+		WMA_LOGD("Host wakeup received");
+	}
+
+	if (CDF_STATUS_SUCCESS == cdf_status)
+		wmi_set_target_suspend(wma->wmi_handle, false);
+
+	return ret;
+}
+
+/**
+ * wma_get_modeselect() - get modeSelect flag based on phy_capability
+ * @wma: wma handle
+ * @modeSelect: mode Select
+ *
+ * Return: none
+ */
+void wma_get_modeselect(tp_wma_handle wma, uint32_t *modeSelect)
+{
+
+	switch (wma->phy_capability) {
+	case WMI_11G_CAPABILITY:
+	case WMI_11NG_CAPABILITY:
+		*modeSelect &= ~(REGDMN_MODE_11A | REGDMN_MODE_TURBO |
+				 REGDMN_MODE_108A | REGDMN_MODE_11A_HALF_RATE |
+				 REGDMN_MODE_11A_QUARTER_RATE |
+				 REGDMN_MODE_11NA_HT20 |
+				 REGDMN_MODE_11NA_HT40PLUS |
+				 REGDMN_MODE_11NA_HT40MINUS |
+				 REGDMN_MODE_11AC_VHT20 |
+				 REGDMN_MODE_11AC_VHT40PLUS |
+				 REGDMN_MODE_11AC_VHT40MINUS |
+				 REGDMN_MODE_11AC_VHT80);
+		break;
+	case WMI_11A_CAPABILITY:
+	case WMI_11NA_CAPABILITY:
+	case WMI_11AC_CAPABILITY:
+		*modeSelect &= ~(REGDMN_MODE_11B | REGDMN_MODE_11G |
+				 REGDMN_MODE_108G | REGDMN_MODE_11NG_HT20 |
+				 REGDMN_MODE_11NG_HT40PLUS |
+				 REGDMN_MODE_11NG_HT40MINUS |
+				 REGDMN_MODE_11AC_VHT20_2G |
+				 REGDMN_MODE_11AC_VHT40_2G |
+				 REGDMN_MODE_11AC_VHT80_2G);
+		break;
+	}
+}
+
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * wma_tdls_event_handler() - handle TDLS event
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_tdls_event_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf = NULL;
+	wmi_tdls_peer_event_fixed_param *peer_event = NULL;
+	tSirTdlsEventnotify *tdls_event;
+
+	if (!event) {
+		WMA_LOGE("%s: event param null", __func__);
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("%s: received null buf from target", __func__);
+		return -EINVAL;
+	}
+
+	peer_event = param_buf->fixed_param;
+	if (!peer_event) {
+		WMA_LOGE("%s: received null event data from target", __func__);
+		return -EINVAL;
+	}
+
+	tdls_event = (tSirTdlsEventnotify *)
+		     cdf_mem_malloc(sizeof(*tdls_event));
+	if (!tdls_event) {
+		WMA_LOGE("%s: failed to allocate memory for tdls_event",
+			 __func__);
+		return -ENOMEM;
+	}
+
+	tdls_event->sessionId = peer_event->vdev_id;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_event->peer_macaddr,
+				   tdls_event->peerMac);
+
+	switch (peer_event->peer_status) {
+	case WMI_TDLS_SHOULD_DISCOVER:
+		tdls_event->messageType = WMA_TDLS_SHOULD_DISCOVER_CMD;
+		break;
+	case WMI_TDLS_SHOULD_TEARDOWN:
+		tdls_event->messageType = WMA_TDLS_SHOULD_TEARDOWN_CMD;
+		break;
+	case WMI_TDLS_PEER_DISCONNECTED:
+		tdls_event->messageType = WMA_TDLS_PEER_DISCONNECTED_CMD;
+		break;
+	default:
+		WMA_LOGE("%s: Discarding unknown tdls event(%d) from target",
+			 __func__, peer_event->peer_status);
+		return -EINVAL;
+	}
+
+	switch (peer_event->peer_reason) {
+	case WMI_TDLS_TEARDOWN_REASON_TX:
+		tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_TX;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_RSSI:
+		tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_RSSI;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_SCAN:
+		tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_SCAN;
+		break;
+	case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
+		tdls_event->peer_reason =
+			eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
+		tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
+		tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_BAD_PTR;
+		break;
+	case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
+		tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE;
+		break;
+	default:
+		WMA_LOGE("%s: unknown reason(%d) in tdls event(%d) from target",
+			 __func__, peer_event->peer_reason,
+			 peer_event->peer_status);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s: sending msg to umac, messageType: 0x%x, "
+		 "for peer: %pM, reason: %d, smesessionId: %d",
+		 __func__, tdls_event->messageType, tdls_event->peerMac,
+		 tdls_event->peer_reason, tdls_event->sessionId);
+
+	wma_send_msg(wma, tdls_event->messageType, (void *)tdls_event, 0);
+	return 0;
+}
+
+/**
+ * wma_set_tdls_offchan_mode() - set tdls off channel mode
+ * @handle: wma 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
+ */
+int wma_set_tdls_offchan_mode(WMA_HANDLE handle,
+			      tdls_chan_switch_params *chan_switch_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	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);
+	int ret = 0;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE(FL(
+			    "WMA is closed, can not issue tdls off channel cmd"
+			 ));
+		ret = -EINVAL;
+		goto end;
+	}
+	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!wmi_buf) {
+		WMA_LOGE(FL("wmi_buf_alloc failed"));
+		ret = -ENOMEM;
+		goto end;
+	}
+	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 = 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 = chan_switch_params->tdls_off_ch_bw_offset;
+	cmd->offchan_oper_class = chan_switch_params->oper_class;
+
+	WMA_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
+		 cmd->peer_macaddr.mac_addr31to0,
+		 cmd->peer_macaddr.mac_addr47to32);
+
+	WMA_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);
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+		WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
+		WMA_LOGP(FL("failed to send tdls off chan command"));
+		cdf_nbuf_free(wmi_buf);
+		ret = -EIO;
+	}
+
+end:
+	if (chan_switch_params)
+		cdf_mem_free(chan_switch_params);
+	return ret;
+}
+
+/**
+ * wma_update_fw_tdls_state() - send enable/disable tdls for a vdev
+ * @wma: wma handle
+ * @pwmaTdlsparams: TDLS params
+ *
+ * Return: 0 for sucess or error code
+ */
+int wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	wmi_tdls_set_state_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	t_wma_tdls_mode tdls_mode;
+	t_wma_tdls_params *wma_tdls = (t_wma_tdls_params *) pwmaTdlsparams;
+	uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
+	int ret = 0;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue fw tdls state cmd",
+			 __func__);
+		ret = -EINVAL;
+		goto end_fw_tdls_state;
+	}
+
+	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!wmi_buf) {
+		WMA_LOGE("%s: wmai_buf_alloc failed", __func__);
+		ret = ENOMEM;
+		goto end_fw_tdls_state;
+	}
+	tdls_mode = wma_tdls->tdls_state;
+	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 = wma_tdls->vdev_id;
+
+	if (WMA_TDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode) {
+		cmd->state = WMI_TDLS_ENABLE_PASSIVE;
+	} else if (WMA_TDLS_SUPPORT_ENABLED == tdls_mode) {
+		cmd->state = WMI_TDLS_ENABLE_ACTIVE;
+	} else {
+		cmd->state = WMI_TDLS_DISABLE;
+	}
+
+	cmd->notification_interval_ms = wma_tdls->notification_interval_ms;
+	cmd->tx_discovery_threshold = wma_tdls->tx_discovery_threshold;
+	cmd->tx_teardown_threshold = wma_tdls->tx_teardown_threshold;
+	cmd->rssi_teardown_threshold = wma_tdls->rssi_teardown_threshold;
+	cmd->rssi_delta = wma_tdls->rssi_delta;
+	cmd->tdls_options = wma_tdls->tdls_options;
+	cmd->tdls_peer_traffic_ind_window = wma_tdls->peer_traffic_ind_window;
+	cmd->tdls_peer_traffic_response_timeout_ms =
+		wma_tdls->peer_traffic_response_timeout;
+	cmd->tdls_puapsd_mask = wma_tdls->puapsd_mask;
+	cmd->tdls_puapsd_inactivity_time_ms = wma_tdls->puapsd_inactivity_time;
+	cmd->tdls_puapsd_rx_frame_threshold =
+		wma_tdls->puapsd_rx_frame_threshold;
+
+	WMA_LOGD("%s: tdls_mode: %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 ",
+		 __func__, tdls_mode, 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);
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+				 WMI_TDLS_SET_STATE_CMDID)) {
+		WMA_LOGP("%s: failed to send tdls set state command", __func__);
+		cdf_nbuf_free(wmi_buf);
+		ret = -EIO;
+		goto end_fw_tdls_state;
+	}
+	WMA_LOGD("%s: vdev_id %d", __func__, wma_tdls->vdev_id);
+
+end_fw_tdls_state:
+	if (pwmaTdlsparams)
+		cdf_mem_free(pwmaTdlsparams);
+	return ret;
+}
+
+/**
+ * wma_update_tdls_peer_state() - update TDLS peer state
+ * @handle: wma handle
+ * @peerStateParams: TDLS peer state params
+ *
+ * Return: 0 for success or error code
+ */
+int wma_update_tdls_peer_state(WMA_HANDLE handle,
+			       tTdlsPeerStateParams *peerStateParams)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	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;
+	ol_txrx_pdev_handle pdev;
+	uint8_t peer_id;
+	struct ol_txrx_peer_t *peer;
+	int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
+		      sizeof(wmi_tdls_peer_capabilities);
+	int ret = 0;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
+		ret = -EINVAL;
+		goto end_tdls_peer_state;
+	}
+
+	/* peer capability info is valid only when peer state is connected */
+	if (WMA_TDLS_PEER_STATE_CONNECTED != peerStateParams->peerState) {
+		cdf_mem_zero(&peerStateParams->peerCap,
+			     sizeof(tTdlsPeerCapParams));
+	}
+
+	len += WMI_TLV_HDR_SIZE +
+	       sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
+
+	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!wmi_buf) {
+		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+		ret = ENOMEM;
+		goto end_tdls_peer_state;
+	}
+
+	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);
+
+	switch (peerStateParams->peerState) {
+	case WMA_TDLS_PEER_STATE_PEERING:
+		cmd->peer_state = WMI_TDLS_PEER_STATE_PEERING;
+		break;
+	case WMA_TDLS_PEER_STATE_CONNECTED:
+		cmd->peer_state = WMI_TDLS_PEER_STATE_CONNECTED;
+		break;
+	case WMA_TDLS_PEER_STATE_TEARDOWN:
+		cmd->peer_state = WMI_TDLS_PEER_STATE_TEARDOWN;
+		break;
+	}
+
+	WMA_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;
+
+	WMA_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];
+		WMA_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;
+
+	WMA_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 =
+			cds_chan_to_freq(peerStateParams->peerCap.peerChan[i].
+					 chanId);
+		chan_info->band_center_freq1 = chan_info->mhz;
+		chan_info->band_center_freq2 = 0;
+
+		WMA_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);
+			WMA_LOGI("chan[%d] DFS[%d]\n",
+				 peerStateParams->peerCap.peerChan[i].chanId,
+				 peerStateParams->peerCap.peerChan[i].dfsSet);
+		}
+
+		if (chan_info->mhz < WMA_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);
+		WMA_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
+			 peerStateParams->peerCap.peerChan[i].pwr);
+
+		chan_info++;
+	}
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+				 WMI_TDLS_PEER_UPDATE_CMDID)) {
+		WMA_LOGE("%s: failed to send tdls peer update state command",
+			 __func__);
+		cdf_nbuf_free(wmi_buf);
+		ret = -EIO;
+		goto end_tdls_peer_state;
+	}
+
+	/* in case of teardown, remove peer from fw */
+	if (WMA_TDLS_PEER_STATE_TEARDOWN == peerStateParams->peerState) {
+		pdev = cds_get_context(CDF_MODULE_ID_TXRX);
+		if (!pdev) {
+			WMA_LOGE("%s: Failed to find pdev", __func__);
+			ret = -EIO;
+			goto end_tdls_peer_state;
+		}
+
+		peer = ol_txrx_find_peer_by_addr(pdev,
+						 peerStateParams->peerMacAddr,
+						 &peer_id);
+		if (!peer) {
+			WMA_LOGE("%s: Failed to get peer handle using peer mac %pM",
+				__func__, peerStateParams->peerMacAddr);
+			ret = -EIO;
+			goto end_tdls_peer_state;
+		}
+
+		WMA_LOGD("%s: calling wma_remove_peer for peer " MAC_ADDRESS_STR
+			 " vdevId: %d", __func__,
+			 MAC_ADDR_ARRAY(peer->mac_addr.raw),
+			 peerStateParams->vdevId);
+		wma_remove_peer(wma_handle, peer->mac_addr.raw,
+				peerStateParams->vdevId, peer, false);
+	}
+
+end_tdls_peer_state:
+	if (peerStateParams)
+		cdf_mem_free(peerStateParams);
+	return ret;
+}
+#endif /* FEATURE_WLAN_TDLS */
+
+
+/**
+ * wma_dfs_attach() - Attach DFS methods to the umac state.
+ * @dfs_ic: ieee80211com ptr
+ *
+ * Return: Return ieee80211com ptr with updated info
+ */
+struct ieee80211com *wma_dfs_attach(struct ieee80211com *dfs_ic)
+{
+	/*Allocate memory for dfs_ic before passing it up to dfs_attach() */
+	dfs_ic = (struct ieee80211com *)
+		 os_malloc(NULL, sizeof(struct ieee80211com), GFP_ATOMIC);
+	if (dfs_ic == NULL) {
+		WMA_LOGE("%s:Allocation of dfs_ic failed %zu",
+			 __func__, sizeof(struct ieee80211com));
+		return NULL;
+	}
+	OS_MEMZERO(dfs_ic, sizeof(struct ieee80211com));
+	/* DFS pattern matching hooks */
+	dfs_ic->ic_dfs_attach = ol_if_dfs_attach;
+	dfs_ic->ic_dfs_disable = ol_if_dfs_disable;
+	dfs_ic->ic_find_channel = ieee80211_find_channel;
+	dfs_ic->ic_dfs_enable = ol_if_dfs_enable;
+	dfs_ic->ic_ieee2mhz = ieee80211_ieee2mhz;
+
+	/* Hardware facing hooks */
+	dfs_ic->ic_get_ext_busy = ol_if_dfs_get_ext_busy;
+	dfs_ic->ic_get_mib_cycle_counts_pct =
+		ol_if_dfs_get_mib_cycle_counts_pct;
+	dfs_ic->ic_get_TSF64 = ol_if_get_tsf64;
+
+	/* NOL related hooks */
+	dfs_ic->ic_dfs_usenol = ol_if_dfs_usenol;
+	/*
+	 * Hooks from wma/dfs/ back
+	 * into the PE/SME
+	 * and shared DFS code
+	 */
+	dfs_ic->ic_dfs_notify_radar = ieee80211_mark_dfs;
+	cdf_mutex_init(&dfs_ic->chan_lock);
+	/* Initializes DFS Data Structures and queues */
+	dfs_attach(dfs_ic);
+
+	return dfs_ic;
+}
+
+/**
+ * wma_dfs_detach() - Detach DFS methods
+ * @dfs_ic: ieee80211com ptr
+ *
+ * Return: none
+ */
+void wma_dfs_detach(struct ieee80211com *dfs_ic)
+{
+	dfs_detach(dfs_ic);
+
+	cdf_mutex_destroy(&dfs_ic->chan_lock);
+	if (NULL != dfs_ic->ic_curchan) {
+		OS_FREE(dfs_ic->ic_curchan);
+		dfs_ic->ic_curchan = NULL;
+	}
+
+	OS_FREE(dfs_ic);
+}
+
+/**
+ * wma_dfs_configure() - configure dfs
+ * @ic: ieee80211com ptr
+ *
+ * Configures Radar Filters during
+ * vdev start/channel change/regulatory domain
+ * change.This Configuration enables to program
+ * the DFS pattern matching module.
+ *
+ * Return: none
+ */
+void wma_dfs_configure(struct ieee80211com *ic)
+{
+	struct ath_dfs_radar_tab_info rinfo;
+	int dfsdomain;
+	int radar_enabled_status = 0;
+	if (ic == NULL) {
+		WMA_LOGE("%s: DFS ic is Invalid", __func__);
+		return;
+	}
+
+	dfsdomain = ic->current_dfs_regdomain;
+
+	/* Fetch current radar patterns from the lmac */
+	OS_MEMZERO(&rinfo, sizeof(rinfo));
+
+	/*
+	 * Look up the current DFS
+	 * regulatory domain and decide
+	 * which radar pulses to use.
+	 */
+	switch (dfsdomain) {
+	case DFS_FCC_DOMAIN:
+		WMA_LOGI("%s: DFS-FCC domain", __func__);
+		rinfo.dfsdomain = DFS_FCC_DOMAIN;
+		rinfo.dfs_radars = dfs_fcc_radars;
+		rinfo.numradars = CDF_ARRAY_SIZE(dfs_fcc_radars);
+		rinfo.b5pulses = dfs_fcc_bin5pulses;
+		rinfo.numb5radars = CDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
+		break;
+	case DFS_ETSI_DOMAIN:
+		WMA_LOGI("%s: DFS-ETSI domain", __func__);
+		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
+		rinfo.dfs_radars = dfs_etsi_radars;
+		rinfo.numradars = CDF_ARRAY_SIZE(dfs_etsi_radars);
+		rinfo.b5pulses = NULL;
+		rinfo.numb5radars = 0;
+		break;
+	case DFS_MKK4_DOMAIN:
+		WMA_LOGI("%s: DFS-MKK4 domain", __func__);
+		rinfo.dfsdomain = DFS_MKK4_DOMAIN;
+		rinfo.dfs_radars = dfs_mkk4_radars;
+		rinfo.numradars = CDF_ARRAY_SIZE(dfs_mkk4_radars);
+		rinfo.b5pulses = dfs_jpn_bin5pulses;
+		rinfo.numb5radars = CDF_ARRAY_SIZE(dfs_jpn_bin5pulses);
+		break;
+	default:
+		WMA_LOGI("%s: DFS-UNINT domain", __func__);
+		rinfo.dfsdomain = DFS_UNINIT_DOMAIN;
+		rinfo.dfs_radars = NULL;
+		rinfo.numradars = 0;
+		rinfo.b5pulses = NULL;
+		rinfo.numb5radars = 0;
+		break;
+	}
+
+	rinfo.dfs_pri_multiplier = ic->dfs_pri_multiplier;
+
+	/*
+	 * Set the regulatory domain,
+	 * radar pulse table and enable
+	 * radar events if required.
+	 * dfs_radar_enable() returns
+	 * 0 on success and non-zero
+	 * failure.
+	 */
+	radar_enabled_status = dfs_radar_enable(ic, &rinfo);
+	if (radar_enabled_status != DFS_STATUS_SUCCESS) {
+		WMA_LOGE("%s[%d]: DFS- Radar Detection Enabling Failed",
+			 __func__, __LINE__);
+	}
+}
+
+/**
+ * wma_dfs_configure_channel() - configure DFS channel
+ * @dfs_ic: ieee80211com ptr
+ * @chan: wmi channel
+ * @chanmode: channel mode
+ * @ req: vdev start request
+ *
+ * Set the Channel parameters in to DFS module
+ * Also,configure the DFS radar filters for
+ * matching the DFS phyerrors.
+ *
+ * Return: ieee80211 channel / NULL for error
+ */
+struct ieee80211_channel *wma_dfs_configure_channel(struct ieee80211com *dfs_ic,
+						    wmi_channel *chan,
+						    WLAN_PHY_MODE chanmode,
+						    struct wma_vdev_start_req
+						    *req)
+{
+	if (dfs_ic == NULL) {
+		WMA_LOGE("%s: DFS ic is Invalid", __func__);
+		return NULL;
+	}
+	dfs_ic->ic_curchan = (struct ieee80211_channel *)os_malloc(NULL,
+					sizeof(struct ieee80211_channel),
+								   GFP_ATOMIC);
+	if (dfs_ic->ic_curchan == NULL) {
+		WMA_LOGE("%s: allocation of dfs_ic->ic_curchan failed %zu",
+			 __func__, sizeof(struct ieee80211_channel));
+		return NULL;
+	}
+	OS_MEMZERO(dfs_ic->ic_curchan, sizeof(struct ieee80211_channel));
+
+	dfs_ic->ic_curchan->ic_ieee = req->chan;
+	dfs_ic->ic_curchan->ic_freq = chan->mhz;
+	dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg1 = chan->band_center_freq1;
+	dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg2 = chan->band_center_freq2;
+	dfs_ic->ic_curchan->ic_pri_freq_center_freq_mhz_separation =
+					dfs_ic->ic_curchan->ic_freq -
+				dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg1;
+
+	if ((dfs_ic->ic_curchan->ic_ieee >= WMA_11A_CHANNEL_BEGIN) &&
+	    (dfs_ic->ic_curchan->ic_ieee <= WMA_11A_CHANNEL_END)) {
+		dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_5GHZ;
+	}
+	if (CH_WIDTH_80MHZ == req->chan_width) {
+		dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_VHT80;
+	}
+	if (CH_WIDTH_40MHZ == req->chan_width) {
+		if (req->chan < req->ch_center_freq_seg0)
+			dfs_ic->ic_curchan->ic_flags |= (req->vht_capable ?
+					IEEE80211_CHAN_VHT40PLUS :
+					IEEE80211_CHAN_HT40PLUS);
+		else
+			dfs_ic->ic_curchan->ic_flags |= (req->vht_capable ?
+					IEEE80211_CHAN_VHT40MINUS :
+					IEEE80211_CHAN_HT40MINUS);
+	} else if (CH_WIDTH_20MHZ == req->chan_width) {
+		dfs_ic->ic_curchan->ic_flags |=
+			(req->vht_capable ? IEEE80211_CHAN_VHT20 :
+						IEEE80211_CHAN_HT20);
+	}
+	dfs_ic->ic_curchan->ic_flagext |= IEEE80211_CHAN_DFS;
+
+	if (req->oper_mode == BSS_OPERATIONAL_MODE_AP) {
+		dfs_ic->ic_opmode = IEEE80211_M_HOSTAP;
+		dfs_ic->vdev_id = req->vdev_id;
+	}
+
+	dfs_ic->dfs_pri_multiplier = req->dfs_pri_multiplier;
+
+	/*
+	 * Configuring the DFS with current channel and the radar filters
+	 */
+	wma_dfs_configure(dfs_ic);
+	WMA_LOGI("%s: DFS- CHANNEL CONFIGURED", __func__);
+	return dfs_ic->ic_curchan;
+}
+
+
+/**
+ * wma_set_dfs_region() - set DFS region
+ * @wma: wma handle
+ *
+ * Configure the DFS region for DFS radar filter initialization
+ *
+ * Return: none
+ */
+void wma_set_dfs_region(tp_wma_handle wma, uint8_t dfs_region)
+{
+	/* dfs information is passed */
+	if (dfs_region > DFS_MKK4_DOMAIN || dfs_region == DFS_UNINIT_DOMAIN)
+		/* assign DFS_FCC_DOMAIN as default domain*/
+		wma->dfs_ic->current_dfs_regdomain = DFS_FCC_DOMAIN;
+	else
+		wma->dfs_ic->current_dfs_regdomain = dfs_region;
+
+	WMA_LOGI("%s: DFS Region Domain: %d", __func__,
+			 wma->dfs_ic->current_dfs_regdomain);
+}
+
+/**
+ * wma_get_channels() - prepare dfs radar channel list
+ * @ichan: channel
+ * @chan_list: return channel list
+ *
+ * Return: return number of channels
+ */
+int wma_get_channels(struct ieee80211_channel *ichan,
+		     struct wma_dfs_radar_channel_list *chan_list)
+{
+	uint8_t center_chan = cds_freq_to_chan(ichan->ic_vhtop_ch_freq_seg1);
+
+	chan_list->nchannels = 0;
+
+	if (IEEE80211_IS_CHAN_11AC_VHT80(ichan)) {
+		chan_list->nchannels = 4;
+		chan_list->channels[0] = center_chan - 6;
+		chan_list->channels[1] = center_chan - 2;
+		chan_list->channels[2] = center_chan + 2;
+		chan_list->channels[3] = center_chan + 6;
+	} else if (IEEE80211_IS_CHAN_11N_HT40(ichan) ||
+		   IEEE80211_IS_CHAN_11AC_VHT40(ichan)) {
+		chan_list->nchannels = 2;
+		chan_list->channels[0] = center_chan - 2;
+		chan_list->channels[1] = center_chan + 2;
+	} else {
+		chan_list->nchannels = 1;
+		chan_list->channels[0] = center_chan;
+	}
+
+	return chan_list->nchannels;
+}
+
+
+/**
+ * wma_dfs_indicate_radar() - Indicate Radar to SAP/HDD
+ * @ic: ieee80211com ptr
+ * @ichan: ieee 80211 channel
+ *
+ * Return: 0 for success or error code
+ */
+int wma_dfs_indicate_radar(struct ieee80211com *ic,
+			   struct ieee80211_channel *ichan)
+{
+	tp_wma_handle wma;
+	void *hdd_ctx;
+	struct wma_dfs_radar_indication *radar_event;
+	struct wma_dfs_radar_ind wma_radar_event;
+	tpAniSirGlobal pmac = NULL;
+
+	wma = cds_get_context(CDF_MODULE_ID_WMA);
+	if (wma == NULL) {
+		WMA_LOGE("%s: DFS- Invalid wma", __func__);
+		return -ENOENT;
+	}
+
+	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
+	pmac = (tpAniSirGlobal)
+		cds_get_context(CDF_MODULE_ID_PE);
+
+	if (!pmac) {
+		WMA_LOGE("%s: Invalid MAC handle", __func__);
+		return -ENOENT;
+	}
+
+	if (wma->dfs_ic != ic) {
+		WMA_LOGE("%s:DFS- Invalid WMA handle", __func__);
+		return -ENOENT;
+	}
+	radar_event = (struct wma_dfs_radar_indication *)
+		      cdf_mem_malloc(sizeof(struct wma_dfs_radar_indication));
+	if (radar_event == NULL) {
+		WMA_LOGE("%s:DFS- Invalid radar_event", __func__);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Do not post multiple Radar events on the same channel.
+	 * But, when DFS test mode is enabled, allow multiple dfs
+	 * radar events to be posted on the same channel.
+	 */
+	if ((ichan->ic_ieee != (wma->dfs_ic->last_radar_found_chan)) ||
+	    (pmac->sap.SapDfsInfo.disable_dfs_ch_switch == true)) {
+		wma->dfs_ic->last_radar_found_chan = ichan->ic_ieee;
+		/* Indicate the radar event to HDD to stop the netif Tx queues */
+		wma_radar_event.ieee_chan_number = ichan->ic_ieee;
+		wma_radar_event.chan_freq = ichan->ic_freq;
+		wma_radar_event.dfs_radar_status = WMA_DFS_RADAR_FOUND;
+		wma->dfs_radar_indication_cb(hdd_ctx, &wma_radar_event);
+		WMA_LOGE("%s:DFS- RADAR INDICATED TO HDD", __func__);
+
+		/*
+		 * Indicate to the radar event to SAP to
+		 * select a new channel and set CSA IE
+		 */
+		radar_event->vdev_id = ic->vdev_id;
+		wma_get_channels(ichan, &radar_event->chan_list);
+		radar_event->dfs_radar_status = WMA_DFS_RADAR_FOUND;
+		radar_event->use_nol = ic->ic_dfs_usenol(ic);
+		wma_send_msg(wma, WMA_DFS_RADAR_IND, (void *)radar_event, 0);
+		WMA_LOGE("%s:DFS- WMA_DFS_RADAR_IND Message Posted", __func__);
+	}
+
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_MEMDUMP
+/*
+ * wma_process_fw_mem_dump_req() - Function to request fw memory dump from
+ *                                 firmware
+ * @wma:                Pointer to WMA handle
+ * @mem_dump_req:       Pointer for mem_dump_req
+ *
+ * This function sends memory dump request to firmware
+ *
+ * Return: CDF_STATUS_SUCCESS for success otherwise failure
+ *
+ */
+CDF_STATUS wma_process_fw_mem_dump_req(tp_wma_handle wma,
+					struct fw_dump_req *mem_dump_req)
+{
+	wmi_get_fw_mem_dump_fixed_param *cmd;
+	wmi_fw_mem_dump *dump_params;
+	struct fw_dump_seg_req *seg_req;
+	int32_t len;
+	wmi_buf_t buf;
+	u_int8_t *buf_ptr;
+	int ret, loop;
+
+	if (!mem_dump_req || !wma) {
+		WMA_LOGE(FL("input pointer is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * len = sizeof(fixed param) that includes tlv header +
+	 *       tlv header for array of struc +
+	 *       sizeof (each struct)
+	 */
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+	len += mem_dump_req->num_seg * sizeof(wmi_fw_mem_dump);
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+
+	if (!buf) {
+		WMA_LOGE(FL("Failed allocate wmi buffer"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+	cdf_mem_zero(buf_ptr, len);
+	cmd = (wmi_get_fw_mem_dump_fixed_param *) buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_get_fw_mem_dump_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_get_fw_mem_dump_fixed_param));
+
+	cmd->request_id = mem_dump_req->request_id;
+	cmd->num_fw_mem_dump_segs = mem_dump_req->num_seg;
+
+	/* TLV indicating array of structures to follow */
+	buf_ptr += sizeof(wmi_get_fw_mem_dump_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_fw_mem_dump) *
+		       cmd->num_fw_mem_dump_segs);
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	dump_params = (wmi_fw_mem_dump *) buf_ptr;
+
+	WMA_LOGI(FL("request_id:%d num_seg:%d"),
+		    mem_dump_req->request_id, mem_dump_req->num_seg);
+	for (loop = 0; loop < cmd->num_fw_mem_dump_segs; loop++) {
+		seg_req = (struct fw_dump_seg_req *)
+			  ((uint8_t *)(mem_dump_req->segment) +
+			    loop * sizeof(*seg_req));
+		WMITLV_SET_HDR(&dump_params->tlv_header,
+			    WMITLV_TAG_STRUC_wmi_fw_mem_dump_params,
+			    WMITLV_GET_STRUCT_TLVLEN(wmi_fw_mem_dump));
+		dump_params->seg_id = seg_req->seg_id;
+		dump_params->seg_start_addr_lo = seg_req->seg_start_addr_lo;
+		dump_params->seg_start_addr_hi = seg_req->seg_start_addr_hi;
+		dump_params->seg_length = seg_req->seg_length;
+		dump_params->dest_addr_lo = seg_req->dst_addr_lo;
+		dump_params->dest_addr_hi = seg_req->dst_addr_hi;
+		WMA_LOGI(FL("seg_number:%d"), loop);
+		WMA_LOGI(FL("seg_id:%d start_addr_lo:0x%x start_addr_hi:0x%x"),
+			 dump_params->seg_id, dump_params->seg_start_addr_lo,
+			 dump_params->seg_start_addr_hi);
+		WMA_LOGI(FL("seg_length:%d dst_addr_lo:0x%x dst_addr_hi:0x%x"),
+			 dump_params->seg_length, dump_params->dest_addr_lo,
+			 dump_params->dest_addr_hi);
+		dump_params++;
+	}
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_GET_FW_MEM_DUMP_CMDID);
+	if (ret) {
+		WMA_LOGE(FL("Failed to send get firmware mem dump request"));
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGI(FL("Get firmware mem dump request sent successfully"));
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_fw_mem_dump_rsp() - send fw mem dump response to SME
+ *
+ * @req_id - request id.
+ * @status - copy status from the firmware.
+ *
+ * This function is called by the memory dump response handler to
+ * indicate SME that firmware dump copy is complete
+ *
+ * Return: CDF_STATUS
+ */
+static CDF_STATUS wma_fw_mem_dump_rsp(uint32_t req_id, uint32_t status)
+{
+	struct fw_dump_rsp *dump_rsp;
+	cds_msg_t sme_msg = {0};
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+
+	dump_rsp = cdf_mem_malloc(sizeof(*dump_rsp));
+
+	if (!dump_rsp) {
+		WMA_LOGE(FL("Memory allocation failed."));
+		cdf_status = CDF_STATUS_E_NOMEM;
+		return cdf_status;
+	}
+
+	WMA_LOGI(FL("FW memory dump copy complete status: %d for request: %d"),
+		 status, req_id);
+
+	dump_rsp->request_id = req_id;
+	dump_rsp->dump_complete = status;
+
+	sme_msg.type = eWNI_SME_FW_DUMP_IND;
+	sme_msg.bodyptr = dump_rsp;
+	sme_msg.bodyval = 0;
+
+	cdf_status = cds_mq_post_message(CDF_MODULE_ID_SME, &sme_msg);
+	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+		WMA_LOGE(FL("Fail to post fw mem dump ind msg"));
+		cdf_mem_free(dump_rsp);
+	}
+
+	return cdf_status;
+}
+
+/**
+ * wma_fw_mem_dump_event_handler() - handles fw memory dump event
+ *
+ * @handle: pointer to wma handle.
+ * @cmd_param_info: pointer to TLV info received in the event.
+ * @len: length of data in @cmd_param_info
+ *
+ * This function is a handler for firmware memory dump event.
+ *
+ * Return: integer (0 for success and error code otherwise)
+ */
+int wma_fw_mem_dump_event_handler(void *handle, u_int8_t *cmd_param_info,
+					 u_int32_t len)
+{
+	WMI_UPDATE_FW_MEM_DUMP_EVENTID_param_tlvs *param_buf;
+	wmi_update_fw_mem_dump_fixed_param *event;
+	CDF_STATUS status;
+
+	param_buf =
+	    (WMI_UPDATE_FW_MEM_DUMP_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGA("%s: Invalid stats event", __func__);
+		return -EINVAL;
+	}
+
+	event = param_buf->fixed_param;
+
+	status = wma_fw_mem_dump_rsp(event->request_id,
+					 event->fw_mem_dump_complete);
+	if (CDF_STATUS_SUCCESS != status) {
+		WMA_LOGE("Error posting FW MEM DUMP RSP.");
+		return -EINVAL;
+	}
+
+	WMA_LOGI("FW MEM DUMP RSP posted successfully");
+	return 0;
+}
+#endif /* WLAN_FEATURE_MEMDUMP */
+
+/*
+ * wma_process_set_ie_info() - Function to send IE info to firmware
+ * @wma:                Pointer to WMA handle
+ * @ie_data:       Pointer for ie data
+ *
+ * This function sends IE information to firmware
+ *
+ * Return: CDF_STATUS_SUCCESS for success otherwise failure
+ *
+ */
+CDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
+				   struct vdev_ie_info *ie_info)
+{
+	wmi_vdev_set_ie_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint32_t len, ie_len_aligned;
+	int ret;
+
+	if (!ie_info || !wma) {
+		WMA_LOGE(FL("input pointer is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/* Validate the input */
+	if (ie_info->length  <= 0) {
+		WMA_LOGE(FL("Invalid IE length"));
+		return CDF_STATUS_E_INVAL;
+	}
+
+	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(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGE(FL("wmi_buf_alloc failed"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = wmi_buf_data(buf);
+	cdf_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;
+
+	WMA_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;
+
+	cdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_VDEV_SET_IE_CMDID);
+	if (ret != EOK) {
+		WMA_LOGE(FL("Failed to send set IE command ret = %d"), ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+